123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947 |
- diff -Nur linux-2.6.33/arch/mips/boot/compressed/dbg.c linux-lemote/arch/mips/boot/compressed/dbg.c
- --- linux-2.6.33/arch/mips/boot/compressed/dbg.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/boot/compressed/dbg.c 2010-03-06 16:42:59.000000000 +0100
- @@ -9,7 +9,7 @@
- #include <linux/init.h>
- #include <linux/types.h>
-
- -void __attribute__ ((weak)) putc(char c)
- +void __weak putc(char c)
- {
- }
-
- diff -Nur linux-2.6.33/arch/mips/boot/compressed/decompress.c linux-lemote/arch/mips/boot/compressed/decompress.c
- --- linux-2.6.33/arch/mips/boot/compressed/decompress.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/boot/compressed/decompress.c 2010-03-06 16:42:59.000000000 +0100
- @@ -5,8 +5,8 @@
- * Author: Matt Porter <mporter@mvista.com> Derived from
- * arch/ppc/boot/prep/misc.c
- *
- - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Copyright (C) 2009 Lemote, Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/boot/compressed/ld.script linux-lemote/arch/mips/boot/compressed/ld.script
- --- linux-2.6.33/arch/mips/boot/compressed/ld.script 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/boot/compressed/ld.script 2010-03-06 16:42:59.000000000 +0100
- @@ -2,7 +2,7 @@
- * ld.script for compressed kernel support of MIPS
- *
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- */
-
- OUTPUT_ARCH(mips)
- @@ -29,8 +29,8 @@
- __image_end = .;
- CONSTRUCTORS
- }
- - .sdata : { *(.sdata) }
- - . = ALIGN(4);
- + .sdata : { *(.sdata) }
- + . = ALIGN(4);
- _edata = .; /* End of data section */
-
- /* BSS */
- diff -Nur linux-2.6.33/arch/mips/boot/compressed/Makefile linux-lemote/arch/mips/boot/compressed/Makefile
- --- linux-2.6.33/arch/mips/boot/compressed/Makefile 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/boot/compressed/Makefile 2010-03-06 16:42:59.000000000 +0100
- @@ -9,7 +9,7 @@
- # modified by Cort (cort@cs.nmt.edu)
- #
- # Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
- -# Author: Wu Zhangjin <wuzj@lemote.com>
- +# Author: Wu Zhangjin <wuzhangjin@gmail.com>
- #
-
- # compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE
- @@ -27,15 +27,17 @@
- KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
-
- KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
- - -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \
- + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
-
- KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
- - -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \
- - -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE)
- + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
- + -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
-
- obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
-
- +ifdef CONFIG_DEBUG_ZBOOT
- obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
- +endif
-
- OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
- $(obj)/vmlinux.bin: $(KBUILD_IMAGE)
- diff -Nur linux-2.6.33/arch/mips/configs/fuloong2e_defconfig linux-lemote/arch/mips/configs/fuloong2e_defconfig
- --- linux-2.6.33/arch/mips/configs/fuloong2e_defconfig 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/configs/fuloong2e_defconfig 2010-03-06 16:42:59.000000000 +0100
- @@ -1,7 +1,7 @@
- #
- # Automatically generated make config: don't edit
- -# Linux kernel version: 2.6.32-rc4
- -# Fri Oct 16 13:18:01 2009
- +# Linux kernel version: 2.6.33
- +# Mon Mar 1 23:44:14 2010
- #
- CONFIG_MIPS=y
-
- @@ -27,6 +27,7 @@
- # CONFIG_PNX8550_STB810 is not set
- # CONFIG_PMC_MSP is not set
- # CONFIG_PMC_YOSEMITE is not set
- +# CONFIG_POWERTV is not set
- # CONFIG_SGI_IP22 is not set
- # CONFIG_SGI_IP27 is not set
- # CONFIG_SGI_IP28 is not set
- @@ -49,6 +50,8 @@
- # CONFIG_ALCHEMY_GPIO_INDIRECT is not set
- CONFIG_ARCH_SPARSEMEM_ENABLE=y
- CONFIG_LEMOTE_FULOONG2E=y
- +# CONFIG_LEMOTE_MACH2F is not set
- +CONFIG_LOONGSON_UART_BASE=y
- CONFIG_RWSEM_GENERIC_SPINLOCK=y
- # CONFIG_ARCH_HAS_ILOG2_U32 is not set
- # CONFIG_ARCH_HAS_ILOG2_U64 is not set
- @@ -67,7 +70,6 @@
- CONFIG_CSRC_R4K=y
- CONFIG_DMA_NONCOHERENT=y
- CONFIG_DMA_NEED_PCI_MAP_STATE=y
- -CONFIG_EARLY_PRINTK=y
- CONFIG_SYS_HAS_EARLY_PRINTK=y
- CONFIG_I8259=y
- # CONFIG_NO_IOPORT is not set
- @@ -84,6 +86,7 @@
- # CPU selection
- #
- CONFIG_CPU_LOONGSON2E=y
- +# CONFIG_CPU_LOONGSON2F is not set
- # CONFIG_CPU_MIPS32_R1 is not set
- # CONFIG_CPU_MIPS32_R2 is not set
- # CONFIG_CPU_MIPS64_R1 is not set
- @@ -106,7 +109,6 @@
- # CONFIG_CPU_SB1 is not set
- # CONFIG_CPU_CAVIUM_OCTEON is not set
- CONFIG_SYS_SUPPORTS_ZBOOT=y
- -CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
- CONFIG_CPU_LOONGSON2=y
- CONFIG_SYS_HAS_CPU_LOONGSON2E=y
- CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
- @@ -134,7 +136,6 @@
- CONFIG_GENERIC_IRQ_PROBE=y
- CONFIG_CPU_SUPPORTS_HIGHMEM=y
- CONFIG_SYS_SUPPORTS_HIGHMEM=y
- -CONFIG_ARCH_FLATMEM_ENABLE=y
- CONFIG_ARCH_POPULATES_NODE_MAP=y
- CONFIG_SELECT_MEMORY_MODEL=y
- # CONFIG_FLATMEM_MANUAL is not set
- @@ -143,23 +144,18 @@
- CONFIG_SPARSEMEM=y
- CONFIG_HAVE_MEMORY_PRESENT=y
- CONFIG_SPARSEMEM_STATIC=y
- -
- -#
- -# Memory hotplug is currently incompatible with Software Suspend
- -#
- CONFIG_PAGEFLAGS_EXTENDED=y
- CONFIG_SPLIT_PTLOCK_CPUS=4
- CONFIG_PHYS_ADDR_T_64BIT=y
- CONFIG_ZONE_DMA_FLAG=0
- CONFIG_VIRT_TO_BUS=y
- -CONFIG_HAVE_MLOCK=y
- -CONFIG_HAVE_MLOCKED_PAGE_BIT=y
- # CONFIG_KSM is not set
- CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
- CONFIG_TICK_ONESHOT=y
- CONFIG_NO_HZ=y
- CONFIG_HIGH_RES_TIMERS=y
- CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
- +CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK=y
- # CONFIG_HZ_48 is not set
- # CONFIG_HZ_100 is not set
- # CONFIG_HZ_128 is not set
- @@ -190,9 +186,11 @@
- CONFIG_HAVE_KERNEL_GZIP=y
- CONFIG_HAVE_KERNEL_BZIP2=y
- CONFIG_HAVE_KERNEL_LZMA=y
- +CONFIG_HAVE_KERNEL_LZO=y
- CONFIG_KERNEL_GZIP=y
- # CONFIG_KERNEL_BZIP2 is not set
- # CONFIG_KERNEL_LZMA is not set
- +# CONFIG_KERNEL_LZO is not set
- CONFIG_SWAP=y
- CONFIG_SYSVIPC=y
- CONFIG_SYSVIPC_SYSCTL=y
- @@ -208,6 +206,7 @@
- #
- CONFIG_TREE_RCU=y
- # CONFIG_TREE_PREEMPT_RCU is not set
- +# CONFIG_TINY_RCU is not set
- # CONFIG_RCU_TRACE is not set
- CONFIG_RCU_FANOUT=64
- # CONFIG_RCU_FANOUT_EXACT is not set
- @@ -217,8 +216,7 @@
- CONFIG_LOG_BUF_SHIFT=14
- # CONFIG_GROUP_SCHED is not set
- # CONFIG_CGROUPS is not set
- -CONFIG_SYSFS_DEPRECATED=y
- -CONFIG_SYSFS_DEPRECATED_V2=y
- +# CONFIG_SYSFS_DEPRECATED_V2 is not set
- # CONFIG_RELAY is not set
- CONFIG_NAMESPACES=y
- # CONFIG_UTS_NS is not set
- @@ -268,6 +266,7 @@
- #
- # CONFIG_GCOV_KERNEL is not set
- CONFIG_SLOW_WORK=y
- +# CONFIG_SLOW_WORK_DEBUG is not set
- CONFIG_HAVE_GENERIC_DMA_COHERENT=y
- CONFIG_SLABINFO=y
- CONFIG_RT_MUTEXES=y
- @@ -287,14 +286,41 @@
- # IO Schedulers
- #
- CONFIG_IOSCHED_NOOP=y
- -CONFIG_IOSCHED_AS=y
- CONFIG_IOSCHED_DEADLINE=y
- CONFIG_IOSCHED_CFQ=y
- -# CONFIG_DEFAULT_AS is not set
- # CONFIG_DEFAULT_DEADLINE is not set
- CONFIG_DEFAULT_CFQ=y
- # CONFIG_DEFAULT_NOOP is not set
- CONFIG_DEFAULT_IOSCHED="cfq"
- +# CONFIG_INLINE_SPIN_TRYLOCK is not set
- +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
- +# CONFIG_INLINE_SPIN_LOCK is not set
- +# CONFIG_INLINE_SPIN_LOCK_BH is not set
- +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
- +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
- +CONFIG_INLINE_SPIN_UNLOCK=y
- +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
- +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
- +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
- +# CONFIG_INLINE_READ_TRYLOCK is not set
- +# CONFIG_INLINE_READ_LOCK is not set
- +# CONFIG_INLINE_READ_LOCK_BH is not set
- +# CONFIG_INLINE_READ_LOCK_IRQ is not set
- +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
- +CONFIG_INLINE_READ_UNLOCK=y
- +# CONFIG_INLINE_READ_UNLOCK_BH is not set
- +CONFIG_INLINE_READ_UNLOCK_IRQ=y
- +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
- +# CONFIG_INLINE_WRITE_TRYLOCK is not set
- +# CONFIG_INLINE_WRITE_LOCK is not set
- +# CONFIG_INLINE_WRITE_LOCK_BH is not set
- +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
- +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
- +CONFIG_INLINE_WRITE_UNLOCK=y
- +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
- +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
- +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
- +# CONFIG_MUTEX_SPIN_ON_OWNER is not set
- CONFIG_FREEZER=y
-
- #
- @@ -340,7 +366,6 @@
- CONFIG_PM_STD_PARTITION="/dev/hda3"
- # CONFIG_PM_RUNTIME is not set
- CONFIG_NET=y
- -CONFIG_COMPAT_NETLINK_MESSAGES=y
-
- #
- # Networking options
- @@ -491,10 +516,6 @@
- # CONFIG_AF_RXRPC is not set
- CONFIG_WIRELESS=y
- # CONFIG_CFG80211 is not set
- -CONFIG_CFG80211_DEFAULT_PS_VALUE=0
- -CONFIG_WIRELESS_OLD_REGULATORY=y
- -CONFIG_WIRELESS_EXT=y
- -CONFIG_WIRELESS_EXT_SYSFS=y
- # CONFIG_LIB80211 is not set
-
- #
- @@ -617,6 +638,10 @@
- # CONFIG_BLK_DEV_COW_COMMON is not set
- CONFIG_BLK_DEV_LOOP=y
- CONFIG_BLK_DEV_CRYPTOLOOP=m
- +
- +#
- +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
- +#
- # CONFIG_BLK_DEV_NBD is not set
- # CONFIG_BLK_DEV_SX8 is not set
- # CONFIG_BLK_DEV_UB is not set
- @@ -755,7 +780,7 @@
- #
-
- #
- -# See the help texts for more information.
- +# The newer stack is recommended.
- #
- # CONFIG_FIREWIRE is not set
- # CONFIG_IEEE1394 is not set
- @@ -798,6 +823,7 @@
- # CONFIG_SMC91X is not set
- # CONFIG_DM9000 is not set
- # CONFIG_ETHOC is not set
- +# CONFIG_SMSC911X is not set
- # CONFIG_NET_VENDOR_RACAL is not set
- # CONFIG_DNET is not set
- # CONFIG_NET_TULIP is not set
- @@ -888,8 +914,10 @@
- # CONFIG_BE2NET is not set
- # CONFIG_TR is not set
- CONFIG_WLAN=y
- -# CONFIG_WLAN_PRE80211 is not set
- -# CONFIG_WLAN_80211 is not set
- +# CONFIG_ATMEL is not set
- +# CONFIG_PRISM54 is not set
- +# CONFIG_USB_ZD1201 is not set
- +# CONFIG_HOSTAP is not set
-
- #
- # Enable WiMAX (Networking options) to see the WiMAX drivers
- @@ -926,6 +954,7 @@
- # CONFIG_NETCONSOLE is not set
- # CONFIG_NETPOLL is not set
- # CONFIG_NET_POLL_CONTROLLER is not set
- +# CONFIG_VMXNET3 is not set
- # CONFIG_ISDN is not set
- # CONFIG_PHONE is not set
-
- @@ -935,6 +964,7 @@
- CONFIG_INPUT=y
- CONFIG_INPUT_FF_MEMLESS=y
- # CONFIG_INPUT_POLLDEV is not set
- +# CONFIG_INPUT_SPARSEKMAP is not set
-
- #
- # Userland interfaces
- @@ -992,6 +1022,7 @@
- # CONFIG_SERIO_PCIPS2 is not set
- CONFIG_SERIO_LIBPS2=y
- # CONFIG_SERIO_RAW is not set
- +# CONFIG_SERIO_ALTERA_PS2 is not set
- # CONFIG_GAMEPORT is not set
-
- #
- @@ -1078,11 +1109,6 @@
- # CONFIG_I2C_TINY_USB is not set
-
- #
- -# Graphics adapter I2C/DDC channel drivers
- -#
- -# CONFIG_I2C_VOODOO3 is not set
- -
- -#
- # Other I2C/SMBus bus drivers
- #
- # CONFIG_I2C_ELEKTOR is not set
- @@ -1093,7 +1119,6 @@
- #
- # Miscellaneous I2C Chip support
- #
- -# CONFIG_DS1682 is not set
- # CONFIG_SENSORS_TSL2550 is not set
- # CONFIG_I2C_DEBUG_CORE is not set
- # CONFIG_I2C_DEBUG_ALGO is not set
- @@ -1125,7 +1150,6 @@
- # CONFIG_HTC_PASIC3 is not set
- # CONFIG_MFD_TMIO is not set
- # CONFIG_MFD_WM8400 is not set
- -# CONFIG_MFD_WM831X is not set
- # CONFIG_MFD_WM8350_I2C is not set
- # CONFIG_MFD_PCF50633 is not set
- # CONFIG_AB3100_CORE is not set
- @@ -1271,6 +1295,7 @@
- # CONFIG_SND_OXYGEN is not set
- # CONFIG_SND_CS4281 is not set
- # CONFIG_SND_CS46XX is not set
- +# CONFIG_SND_CS5535AUDIO is not set
- # CONFIG_SND_CTXFI is not set
- # CONFIG_SND_DARLA20 is not set
- # CONFIG_SND_GINA20 is not set
- @@ -1482,6 +1507,7 @@
- # TI VLYNQ
- #
- # CONFIG_STAGING is not set
- +CONFIG_MIPS_PLATFORM_DEVICES=y
-
- #
- # File systems
- @@ -1522,8 +1548,8 @@
- # CONFIG_QUOTA is not set
- CONFIG_AUTOFS_FS=y
- CONFIG_AUTOFS4_FS=y
- -CONFIG_FUSE_FS=y
- -# CONFIG_CUSE is not set
- +CONFIG_FUSE_FS=m
- +CONFIG_CUSE=m
-
- #
- # Caches
- @@ -1700,6 +1726,11 @@
- # CONFIG_RCU_CPU_STALL_DETECTOR is not set
- CONFIG_SYSCTL_SYSCALL_CHECK=y
- CONFIG_NOP_TRACER=y
- +CONFIG_HAVE_FUNCTION_TRACER=y
- +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
- +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
- +CONFIG_HAVE_DYNAMIC_FTRACE=y
- +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
- CONFIG_RING_BUFFER=y
- CONFIG_EVENT_TRACING=y
- CONFIG_CONTEXT_SWITCH_TRACER=y
- @@ -1710,6 +1741,7 @@
- # CONFIG_DYNAMIC_DEBUG is not set
- # CONFIG_SAMPLES is not set
- CONFIG_HAVE_ARCH_KGDB=y
- +CONFIG_EARLY_PRINTK=y
- # CONFIG_CMDLINE_BOOL is not set
-
- #
- @@ -1718,7 +1750,11 @@
- # CONFIG_KEYS is not set
- # CONFIG_SECURITY is not set
- # CONFIG_SECURITYFS is not set
- -CONFIG_SECURITY_FILE_CAPABILITIES=y
- +# CONFIG_DEFAULT_SECURITY_SELINUX is not set
- +# CONFIG_DEFAULT_SECURITY_SMACK is not set
- +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
- +CONFIG_DEFAULT_SECURITY_DAC=y
- +CONFIG_DEFAULT_SECURITY=""
- CONFIG_CRYPTO=y
-
- #
- diff -Nur linux-2.6.33/arch/mips/configs/lemote2f_defconfig linux-lemote/arch/mips/configs/lemote2f_defconfig
- --- linux-2.6.33/arch/mips/configs/lemote2f_defconfig 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/configs/lemote2f_defconfig 2010-03-06 16:42:59.000000000 +0100
- @@ -1,7 +1,7 @@
- #
- # Automatically generated make config: don't edit
- -# Linux kernel version: 2.6.32-rc6
- -# Mon Nov 9 23:42:42 2009
- +# Linux kernel version: 2.6.33
- +# Mon Mar 1 23:36:53 2010
- #
- CONFIG_MIPS=y
-
- @@ -27,6 +27,7 @@
- # CONFIG_PNX8550_STB810 is not set
- # CONFIG_PMC_MSP is not set
- # CONFIG_PMC_YOSEMITE is not set
- +# CONFIG_POWERTV is not set
- # CONFIG_SGI_IP22 is not set
- # CONFIG_SGI_IP27 is not set
- # CONFIG_SGI_IP28 is not set
- @@ -51,6 +52,9 @@
- # CONFIG_LEMOTE_FULOONG2E is not set
- CONFIG_LEMOTE_MACH2F=y
- CONFIG_CS5536=y
- +CONFIG_CS5536_MFGPT=y
- +CONFIG_LOONGSON_SUSPEND=y
- +CONFIG_LOONGSON_UART_BASE=y
- CONFIG_RWSEM_GENERIC_SPINLOCK=y
- # CONFIG_ARCH_HAS_ILOG2_U32 is not set
- # CONFIG_ARCH_HAS_ILOG2_U64 is not set
- @@ -63,13 +67,8 @@
- CONFIG_GENERIC_CMOS_UPDATE=y
- CONFIG_SCHED_OMIT_FRAME_POINTER=y
- CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
- -CONFIG_CEVT_R4K_LIB=y
- -CONFIG_CEVT_R4K=y
- -CONFIG_CSRC_R4K_LIB=y
- -CONFIG_CSRC_R4K=y
- CONFIG_DMA_NONCOHERENT=y
- CONFIG_DMA_NEED_PCI_MAP_STATE=y
- -CONFIG_EARLY_PRINTK=y
- CONFIG_SYS_HAS_EARLY_PRINTK=y
- CONFIG_I8259=y
- # CONFIG_NO_IOPORT is not set
- @@ -109,13 +108,15 @@
- # CONFIG_CPU_SB1 is not set
- # CONFIG_CPU_CAVIUM_OCTEON is not set
- CONFIG_SYS_SUPPORTS_ZBOOT=y
- -CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
- CONFIG_CPU_LOONGSON2=y
- CONFIG_SYS_HAS_CPU_LOONGSON2F=y
- CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
- CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
- CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
- CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
- +CONFIG_CPU_SUPPORTS_CPUFREQ=y
- +CONFIG_CPU_SUPPORTS_ADDRWINCFG=y
- +CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED=y
-
- #
- # Kernel type
- @@ -137,7 +138,6 @@
- CONFIG_GENERIC_IRQ_PROBE=y
- CONFIG_CPU_SUPPORTS_HIGHMEM=y
- CONFIG_SYS_SUPPORTS_HIGHMEM=y
- -CONFIG_ARCH_FLATMEM_ENABLE=y
- CONFIG_ARCH_POPULATES_NODE_MAP=y
- CONFIG_SELECT_MEMORY_MODEL=y
- # CONFIG_FLATMEM_MANUAL is not set
- @@ -146,17 +146,11 @@
- CONFIG_SPARSEMEM=y
- CONFIG_HAVE_MEMORY_PRESENT=y
- CONFIG_SPARSEMEM_STATIC=y
- -
- -#
- -# Memory hotplug is currently incompatible with Software Suspend
- -#
- CONFIG_PAGEFLAGS_EXTENDED=y
- CONFIG_SPLIT_PTLOCK_CPUS=4
- CONFIG_PHYS_ADDR_T_64BIT=y
- CONFIG_ZONE_DMA_FLAG=0
- CONFIG_VIRT_TO_BUS=y
- -CONFIG_HAVE_MLOCK=y
- -CONFIG_HAVE_MLOCKED_PAGE_BIT=y
- # CONFIG_KSM is not set
- CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
- CONFIG_TICK_ONESHOT=y
- @@ -175,7 +169,7 @@
- # CONFIG_PREEMPT_NONE is not set
- # CONFIG_PREEMPT_VOLUNTARY is not set
- CONFIG_PREEMPT=y
- -# CONFIG_KEXEC is not set
- +CONFIG_KEXEC=y
- # CONFIG_SECCOMP is not set
- CONFIG_LOCKDEP_SUPPORT=y
- CONFIG_STACKTRACE_SUPPORT=y
- @@ -194,9 +188,11 @@
- CONFIG_HAVE_KERNEL_GZIP=y
- CONFIG_HAVE_KERNEL_BZIP2=y
- CONFIG_HAVE_KERNEL_LZMA=y
- -# CONFIG_KERNEL_GZIP is not set
- +CONFIG_HAVE_KERNEL_LZO=y
- +CONFIG_KERNEL_GZIP=y
- # CONFIG_KERNEL_BZIP2 is not set
- -CONFIG_KERNEL_LZMA=y
- +# CONFIG_KERNEL_LZMA is not set
- +# CONFIG_KERNEL_LZO is not set
- CONFIG_SWAP=y
- CONFIG_SYSVIPC=y
- CONFIG_SYSVIPC_SYSCTL=y
- @@ -211,6 +207,7 @@
- #
- CONFIG_TREE_RCU=y
- # CONFIG_TREE_PREEMPT_RCU is not set
- +# CONFIG_TINY_RCU is not set
- # CONFIG_RCU_TRACE is not set
- CONFIG_RCU_FANOUT=64
- # CONFIG_RCU_FANOUT_EXACT is not set
- @@ -220,11 +217,15 @@
- CONFIG_LOG_BUF_SHIFT=15
- # CONFIG_GROUP_SCHED is not set
- # CONFIG_CGROUPS is not set
- -CONFIG_SYSFS_DEPRECATED=y
- -CONFIG_SYSFS_DEPRECATED_V2=y
- +# CONFIG_SYSFS_DEPRECATED_V2 is not set
- # CONFIG_RELAY is not set
- # CONFIG_NAMESPACES is not set
- -# CONFIG_BLK_DEV_INITRD is not set
- +CONFIG_BLK_DEV_INITRD=y
- +CONFIG_INITRAMFS_SOURCE=""
- +CONFIG_RD_GZIP=y
- +CONFIG_RD_BZIP2=y
- +CONFIG_RD_LZMA=y
- +# CONFIG_RD_LZO is not set
- # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
- CONFIG_SYSCTL=y
- CONFIG_ANON_INODES=y
- @@ -251,21 +252,24 @@
- #
- CONFIG_VM_EVENT_COUNTERS=y
- CONFIG_PCI_QUIRKS=y
- -CONFIG_SLUB_DEBUG=y
- +# CONFIG_SLUB_DEBUG is not set
- CONFIG_COMPAT_BRK=y
- # CONFIG_SLAB is not set
- CONFIG_SLUB=y
- # CONFIG_SLOB is not set
- -# CONFIG_PROFILING is not set
- +CONFIG_PROFILING=y
- +CONFIG_TRACEPOINTS=y
- +CONFIG_OPROFILE=m
- CONFIG_HAVE_OPROFILE=y
- CONFIG_HAVE_SYSCALL_WRAPPERS=y
-
- #
- # GCOV-based kernel profiling
- #
- -# CONFIG_SLOW_WORK is not set
- +# CONFIG_GCOV_KERNEL is not set
- +CONFIG_SLOW_WORK=y
- +# CONFIG_SLOW_WORK_DEBUG is not set
- CONFIG_HAVE_GENERIC_DMA_COHERENT=y
- -CONFIG_SLABINFO=y
- CONFIG_RT_MUTEXES=y
- CONFIG_BASE_SMALL=0
- CONFIG_MODULES=y
- @@ -283,14 +287,41 @@
- # IO Schedulers
- #
- CONFIG_IOSCHED_NOOP=y
- -CONFIG_IOSCHED_AS=y
- -CONFIG_IOSCHED_DEADLINE=y
- +CONFIG_IOSCHED_DEADLINE=m
- CONFIG_IOSCHED_CFQ=y
- -# CONFIG_DEFAULT_AS is not set
- # CONFIG_DEFAULT_DEADLINE is not set
- CONFIG_DEFAULT_CFQ=y
- # CONFIG_DEFAULT_NOOP is not set
- CONFIG_DEFAULT_IOSCHED="cfq"
- +# CONFIG_INLINE_SPIN_TRYLOCK is not set
- +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
- +# CONFIG_INLINE_SPIN_LOCK is not set
- +# CONFIG_INLINE_SPIN_LOCK_BH is not set
- +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
- +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
- +# CONFIG_INLINE_SPIN_UNLOCK is not set
- +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
- +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
- +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
- +# CONFIG_INLINE_READ_TRYLOCK is not set
- +# CONFIG_INLINE_READ_LOCK is not set
- +# CONFIG_INLINE_READ_LOCK_BH is not set
- +# CONFIG_INLINE_READ_LOCK_IRQ is not set
- +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
- +# CONFIG_INLINE_READ_UNLOCK is not set
- +# CONFIG_INLINE_READ_UNLOCK_BH is not set
- +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
- +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
- +# CONFIG_INLINE_WRITE_TRYLOCK is not set
- +# CONFIG_INLINE_WRITE_LOCK is not set
- +# CONFIG_INLINE_WRITE_LOCK_BH is not set
- +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
- +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
- +# CONFIG_INLINE_WRITE_UNLOCK is not set
- +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
- +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
- +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
- +# CONFIG_MUTEX_SPIN_ON_OWNER is not set
- CONFIG_FREEZER=y
-
- #
- @@ -300,7 +331,7 @@
- CONFIG_PCI=y
- CONFIG_PCI_DOMAINS=y
- # CONFIG_ARCH_SUPPORTS_MSI is not set
- -CONFIG_PCI_LEGACY=y
- +# CONFIG_PCI_LEGACY is not set
- # CONFIG_PCI_STUB is not set
- # CONFIG_PCI_IOV is not set
- CONFIG_ISA=y
- @@ -314,7 +345,7 @@
- CONFIG_BINFMT_ELF=y
- # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
- # CONFIG_HAVE_AOUT is not set
- -# CONFIG_BINFMT_MISC is not set
- +CONFIG_BINFMT_MISC=m
- CONFIG_MIPS32_COMPAT=y
- CONFIG_COMPAT=y
- CONFIG_SYSVIPC_COMPAT=y
- @@ -335,7 +366,33 @@
- CONFIG_HIBERNATION_NVS=y
- CONFIG_HIBERNATION=y
- CONFIG_PM_STD_PARTITION="/dev/hda3"
- -# CONFIG_PM_RUNTIME is not set
- +CONFIG_PM_RUNTIME=y
- +CONFIG_MIPS_EXTERNAL_TIMER=y
- +CONFIG_MIPS_CPUFREQ=y
- +
- +#
- +# CPU Frequency scaling
- +#
- +CONFIG_CPU_FREQ=y
- +CONFIG_CPU_FREQ_TABLE=y
- +CONFIG_CPU_FREQ_DEBUG=y
- +CONFIG_CPU_FREQ_STAT=m
- +CONFIG_CPU_FREQ_STAT_DETAILS=y
- +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
- +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
- +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
- +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
- +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
- +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
- +CONFIG_CPU_FREQ_GOV_POWERSAVE=m
- +CONFIG_CPU_FREQ_GOV_USERSPACE=m
- +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
- +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
- +
- +#
- +# CPUFreq processor drivers
- +#
- +CONFIG_LOONGSON2_CPUFREQ=m
- CONFIG_NET=y
- CONFIG_COMPAT_NETLINK_MESSAGES=y
-
- @@ -346,11 +403,12 @@
- CONFIG_PACKET_MMAP=y
- CONFIG_UNIX=y
- CONFIG_XFRM=y
- -# CONFIG_XFRM_USER is not set
- +CONFIG_XFRM_USER=m
- # CONFIG_XFRM_SUB_POLICY is not set
- # CONFIG_XFRM_MIGRATE is not set
- # CONFIG_XFRM_STATISTICS is not set
- -# CONFIG_NET_KEY is not set
- +CONFIG_NET_KEY=m
- +# CONFIG_NET_KEY_MIGRATE is not set
- CONFIG_INET=y
- CONFIG_IP_MULTICAST=y
- CONFIG_IP_ADVANCED_ROUTER=y
- @@ -361,12 +419,13 @@
- CONFIG_IP_ROUTE_MULTIPATH=y
- CONFIG_IP_ROUTE_VERBOSE=y
- # CONFIG_IP_PNP is not set
- -# CONFIG_NET_IPIP is not set
- -# CONFIG_NET_IPGRE is not set
- +CONFIG_NET_IPIP=m
- +CONFIG_NET_IPGRE=m
- +# CONFIG_NET_IPGRE_BROADCAST is not set
- CONFIG_IP_MROUTE=y
- CONFIG_IP_PIMSM_V1=y
- CONFIG_IP_PIMSM_V2=y
- -# CONFIG_ARPD is not set
- +CONFIG_ARPD=y
- CONFIG_SYN_COOKIES=y
- # CONFIG_INET_AH is not set
- # CONFIG_INET_ESP is not set
- @@ -399,30 +458,34 @@
- # CONFIG_DEFAULT_WESTWOOD is not set
- # CONFIG_DEFAULT_RENO is not set
- CONFIG_DEFAULT_TCP_CONG="bic"
- -# CONFIG_TCP_MD5SIG is not set
- +CONFIG_TCP_MD5SIG=y
- CONFIG_IPV6=m
- CONFIG_IPV6_PRIVACY=y
- -# CONFIG_IPV6_ROUTER_PREF is not set
- +CONFIG_IPV6_ROUTER_PREF=y
- +# CONFIG_IPV6_ROUTE_INFO is not set
- # CONFIG_IPV6_OPTIMISTIC_DAD is not set
- # CONFIG_INET6_AH is not set
- # CONFIG_INET6_ESP is not set
- # CONFIG_INET6_IPCOMP is not set
- # CONFIG_IPV6_MIP6 is not set
- # CONFIG_INET6_XFRM_TUNNEL is not set
- -# CONFIG_INET6_TUNNEL is not set
- +CONFIG_INET6_TUNNEL=m
- CONFIG_INET6_XFRM_MODE_TRANSPORT=m
- CONFIG_INET6_XFRM_MODE_TUNNEL=m
- CONFIG_INET6_XFRM_MODE_BEET=m
- # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
- CONFIG_IPV6_SIT=m
- +# CONFIG_IPV6_SIT_6RD is not set
- CONFIG_IPV6_NDISC_NODETYPE=y
- -# CONFIG_IPV6_TUNNEL is not set
- -# CONFIG_IPV6_MULTIPLE_TABLES is not set
- +CONFIG_IPV6_TUNNEL=m
- +CONFIG_IPV6_MULTIPLE_TABLES=y
- +CONFIG_IPV6_SUBTREES=y
- # CONFIG_IPV6_MROUTE is not set
- CONFIG_NETWORK_SECMARK=y
- CONFIG_NETFILTER=y
- # CONFIG_NETFILTER_DEBUG is not set
- CONFIG_NETFILTER_ADVANCED=y
- +CONFIG_BRIDGE_NETFILTER=y
-
- #
- # Core Netfilter Configuration
- @@ -446,17 +509,22 @@
- #
- # CONFIG_IP6_NF_QUEUE is not set
- # CONFIG_IP6_NF_IPTABLES is not set
- +# CONFIG_BRIDGE_NF_EBTABLES is not set
- # CONFIG_IP_DCCP is not set
- # CONFIG_IP_SCTP is not set
- # CONFIG_RDS is not set
- # CONFIG_TIPC is not set
- # CONFIG_ATM is not set
- -# CONFIG_BRIDGE is not set
- +CONFIG_STP=m
- +CONFIG_BRIDGE=m
- # CONFIG_NET_DSA is not set
- -# CONFIG_VLAN_8021Q is not set
- +CONFIG_VLAN_8021Q=m
- +# CONFIG_VLAN_8021Q_GVRP is not set
- # CONFIG_DECNET is not set
- +CONFIG_LLC=m
- # CONFIG_LLC2 is not set
- -# CONFIG_IPX is not set
- +CONFIG_IPX=m
- +# CONFIG_IPX_INTERN is not set
- # CONFIG_ATALK is not set
- # CONFIG_X25 is not set
- # CONFIG_LAPB is not set
- @@ -518,26 +586,64 @@
- # Network testing
- #
- # CONFIG_NET_PKTGEN is not set
- +# CONFIG_NET_DROP_MONITOR is not set
- # CONFIG_HAMRADIO is not set
- # CONFIG_CAN is not set
- # CONFIG_IRDA is not set
- -# CONFIG_BT is not set
- +CONFIG_BT=m
- +CONFIG_BT_L2CAP=m
- +CONFIG_BT_SCO=m
- +CONFIG_BT_RFCOMM=m
- +CONFIG_BT_RFCOMM_TTY=y
- +CONFIG_BT_BNEP=m
- +CONFIG_BT_BNEP_MC_FILTER=y
- +CONFIG_BT_BNEP_PROTO_FILTER=y
- +CONFIG_BT_HIDP=m
- +
- +#
- +# Bluetooth device drivers
- +#
- +CONFIG_BT_HCIBTUSB=m
- +# CONFIG_BT_HCIBTSDIO is not set
- +# CONFIG_BT_HCIUART is not set
- +# CONFIG_BT_HCIBCM203X is not set
- +# CONFIG_BT_HCIBPA10X is not set
- +CONFIG_BT_HCIBFUSB=m
- +CONFIG_BT_HCIVHCI=m
- +# CONFIG_BT_MRVL is not set
- +# CONFIG_BT_ATH3K is not set
- # CONFIG_AF_RXRPC is not set
- CONFIG_FIB_RULES=y
- CONFIG_WIRELESS=y
- -# CONFIG_CFG80211 is not set
- -CONFIG_CFG80211_DEFAULT_PS_VALUE=0
- -# CONFIG_WIRELESS_OLD_REGULATORY is not set
- CONFIG_WIRELESS_EXT=y
- +CONFIG_WEXT_CORE=y
- +CONFIG_WEXT_PROC=y
- +CONFIG_WEXT_PRIV=y
- +CONFIG_CFG80211=m
- +# CONFIG_NL80211_TESTMODE is not set
- +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
- +# CONFIG_CFG80211_REG_DEBUG is not set
- +CONFIG_CFG80211_DEFAULT_PS=y
- +# CONFIG_CFG80211_DEBUGFS is not set
- +# CONFIG_WIRELESS_OLD_REGULATORY is not set
- +CONFIG_CFG80211_WEXT=y
- CONFIG_WIRELESS_EXT_SYSFS=y
- -# CONFIG_LIB80211 is not set
- -
- -#
- -# CFG80211 needs to be enabled for MAC80211
- -#
- +CONFIG_LIB80211=m
- +CONFIG_LIB80211_DEBUG=y
- +CONFIG_MAC80211=m
- +# CONFIG_MAC80211_RC_PID is not set
- +CONFIG_MAC80211_RC_MINSTREL=y
- +# CONFIG_MAC80211_RC_DEFAULT_PID is not set
- +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
- +CONFIG_MAC80211_RC_DEFAULT="minstrel"
- +# CONFIG_MAC80211_MESH is not set
- +CONFIG_MAC80211_LEDS=y
- +# CONFIG_MAC80211_DEBUGFS is not set
- +# CONFIG_MAC80211_DEBUG_MENU is not set
- # CONFIG_WIMAX is not set
- CONFIG_RFKILL=m
- -# CONFIG_RFKILL_INPUT is not set
- +CONFIG_RFKILL_LEDS=y
- +CONFIG_RFKILL_INPUT=y
- # CONFIG_NET_9P is not set
-
- #
- @@ -555,7 +661,7 @@
- CONFIG_FIRMWARE_IN_KERNEL=y
- CONFIG_EXTRA_FIRMWARE=""
- # CONFIG_SYS_HYPERVISOR is not set
- -# CONFIG_CONNECTOR is not set
- +CONFIG_CONNECTOR=m
- # CONFIG_MTD is not set
- # CONFIG_PARPORT is not set
- # CONFIG_PNP is not set
- @@ -566,7 +672,8 @@
- # CONFIG_BLK_DEV_UMEM is not set
- # CONFIG_BLK_DEV_COW_COMMON is not set
- CONFIG_BLK_DEV_LOOP=y
- -CONFIG_BLK_DEV_CRYPTOLOOP=y
- +CONFIG_BLK_DEV_CRYPTOLOOP=m
- +# CONFIG_BLK_DEV_DRBD is not set
- # CONFIG_BLK_DEV_NBD is not set
- # CONFIG_BLK_DEV_SX8 is not set
- # CONFIG_BLK_DEV_UB is not set
- @@ -577,19 +684,7 @@
- # CONFIG_CDROM_PKTCDVD is not set
- # CONFIG_ATA_OVER_ETH is not set
- # CONFIG_BLK_DEV_HD is not set
- -CONFIG_MISC_DEVICES=y
- -# CONFIG_PHANTOM is not set
- -# CONFIG_SGI_IOC4 is not set
- -# CONFIG_TIFM_CORE is not set
- -# CONFIG_ENCLOSURE_SERVICES is not set
- -# CONFIG_HP_ILO is not set
- -# CONFIG_C2PORT is not set
- -
- -#
- -# EEPROM support
- -#
- -# CONFIG_EEPROM_93CX6 is not set
- -# CONFIG_CB710_CORE is not set
- +# CONFIG_MISC_DEVICES is not set
- CONFIG_HAVE_IDE=y
- CONFIG_IDE=y
-
- @@ -619,8 +714,7 @@
- #
- CONFIG_BLK_DEV_IDEPCI=y
- # CONFIG_IDEPCI_PCIBUS_ORDER is not set
- -# CONFIG_BLK_DEV_OFFBOARD is not set
- -CONFIG_BLK_DEV_GENERIC=y
- +# CONFIG_BLK_DEV_GENERIC is not set
- # CONFIG_BLK_DEV_OPTI621 is not set
- CONFIG_BLK_DEV_IDEDMA_PCI=y
- # CONFIG_BLK_DEV_AEC62XX is not set
- @@ -700,7 +794,29 @@
- # CONFIG_SCSI_DH is not set
- # CONFIG_SCSI_OSD_INITIATOR is not set
- # CONFIG_ATA is not set
- -# CONFIG_MD is not set
- +CONFIG_MD=y
- +CONFIG_BLK_DEV_MD=m
- +CONFIG_MD_LINEAR=m
- +CONFIG_MD_RAID0=m
- +CONFIG_MD_RAID1=m
- +CONFIG_MD_RAID10=m
- +CONFIG_MD_RAID456=m
- +CONFIG_MD_RAID6_PQ=m
- +# CONFIG_ASYNC_RAID6_TEST is not set
- +CONFIG_MD_MULTIPATH=m
- +CONFIG_MD_FAULTY=m
- +CONFIG_BLK_DEV_DM=m
- +CONFIG_DM_DEBUG=y
- +CONFIG_DM_CRYPT=m
- +CONFIG_DM_SNAPSHOT=m
- +CONFIG_DM_MIRROR=m
- +CONFIG_DM_LOG_USERSPACE=m
- +CONFIG_DM_ZERO=m
- +CONFIG_DM_MULTIPATH=m
- +CONFIG_DM_MULTIPATH_QL=m
- +CONFIG_DM_MULTIPATH_ST=m
- +CONFIG_DM_DELAY=m
- +CONFIG_DM_UEVENT=y
- # CONFIG_FUSION is not set
-
- #
- @@ -712,19 +828,19 @@
- #
-
- #
- -# See the help texts for more information.
- +# The newer stack is recommended.
- #
- # CONFIG_FIREWIRE is not set
- # CONFIG_IEEE1394 is not set
- # CONFIG_I2O is not set
- CONFIG_NETDEVICES=y
- # CONFIG_IFB is not set
- -# CONFIG_DUMMY is not set
- +CONFIG_DUMMY=m
- # CONFIG_BONDING is not set
- # CONFIG_MACVLAN is not set
- # CONFIG_EQUALIZER is not set
- -# CONFIG_TUN is not set
- -# CONFIG_VETH is not set
- +CONFIG_TUN=m
- +CONFIG_VETH=m
- # CONFIG_ARCNET is not set
- # CONFIG_PHYLIB is not set
- CONFIG_NET_ETHERNET=y
- @@ -738,6 +854,7 @@
- # CONFIG_SMC91X is not set
- # CONFIG_DM9000 is not set
- # CONFIG_ETHOC is not set
- +# CONFIG_SMSC911X is not set
- # CONFIG_NET_VENDOR_RACAL is not set
- # CONFIG_DNET is not set
- # CONFIG_NET_TULIP is not set
- @@ -767,9 +884,9 @@
- # CONFIG_NATSEMI is not set
- # CONFIG_NE2K_PCI is not set
- # CONFIG_8139CP is not set
- -CONFIG_8139TOO=y
- +CONFIG_8139TOO=m
- # CONFIG_8139TOO_PIO is not set
- -CONFIG_8139TOO_TUNE_TWISTER=y
- +# CONFIG_8139TOO_TUNE_TWISTER is not set
- # CONFIG_8139TOO_8129 is not set
- # CONFIG_8139_OLD_RX_RESET is not set
- # CONFIG_R6040 is not set
- @@ -794,7 +911,8 @@
- # CONFIG_NS83820 is not set
- # CONFIG_HAMACHI is not set
- # CONFIG_YELLOWFIN is not set
- -CONFIG_R8169=y
- +CONFIG_R8169=m
- +CONFIG_R8169_VLAN=y
- # CONFIG_SIS190 is not set
- # CONFIG_SKGE is not set
- # CONFIG_SKY2 is not set
- @@ -810,15 +928,31 @@
- # CONFIG_NETDEV_10000 is not set
- # CONFIG_TR is not set
- CONFIG_WLAN=y
- -CONFIG_WLAN_PRE80211=y
- -# CONFIG_STRIP is not set
- -# CONFIG_WAVELAN is not set
- -CONFIG_WLAN_80211=y
- -# CONFIG_LIBERTAS is not set
- +# CONFIG_LIBERTAS_THINFIRM is not set
- # CONFIG_ATMEL is not set
- +# CONFIG_AT76C50X_USB is not set
- # CONFIG_PRISM54 is not set
- # CONFIG_USB_ZD1201 is not set
- +# CONFIG_USB_NET_RNDIS_WLAN is not set
- +# CONFIG_RTL8180 is not set
- +CONFIG_RTL8187B=m
- +# CONFIG_ADM8211 is not set
- +# CONFIG_MAC80211_HWSIM is not set
- +# CONFIG_MWL8K is not set
- +# CONFIG_ATH_COMMON is not set
- +# CONFIG_B43 is not set
- +# CONFIG_B43LEGACY is not set
- # CONFIG_HOSTAP is not set
- +# CONFIG_IPW2100 is not set
- +# CONFIG_IPW2200 is not set
- +# CONFIG_IWLWIFI is not set
- +# CONFIG_IWM is not set
- +# CONFIG_LIBERTAS is not set
- +# CONFIG_HERMES is not set
- +# CONFIG_P54_COMMON is not set
- +# CONFIG_RT2X00 is not set
- +# CONFIG_WL12XX is not set
- +# CONFIG_ZD1211RW is not set
-
- #
- # Enable WiMAX (Networking options) to see the WiMAX drivers
- @@ -831,17 +965,39 @@
- # CONFIG_USB_KAWETH is not set
- # CONFIG_USB_PEGASUS is not set
- # CONFIG_USB_RTL8150 is not set
- -# CONFIG_USB_USBNET is not set
- +CONFIG_USB_USBNET=m
- +CONFIG_USB_NET_AX8817X=m
- +CONFIG_USB_NET_CDCETHER=m
- +CONFIG_USB_NET_CDC_EEM=m
- +# CONFIG_USB_NET_DM9601 is not set
- +# CONFIG_USB_NET_SMSC95XX is not set
- +# CONFIG_USB_NET_GL620A is not set
- +CONFIG_USB_NET_NET1080=m
- +# CONFIG_USB_NET_PLUSB is not set
- +# CONFIG_USB_NET_MCS7830 is not set
- +# CONFIG_USB_NET_RNDIS_HOST is not set
- +CONFIG_USB_NET_CDC_SUBSET=m
- +# CONFIG_USB_ALI_M5632 is not set
- +# CONFIG_USB_AN2720 is not set
- +CONFIG_USB_BELKIN=y
- +CONFIG_USB_ARMLINUX=y
- +# CONFIG_USB_EPSON2888 is not set
- +# CONFIG_USB_KC2190 is not set
- +CONFIG_USB_NET_ZAURUS=m
- # CONFIG_USB_HSO is not set
- +# CONFIG_USB_NET_INT51X1 is not set
- # CONFIG_WAN is not set
- # CONFIG_FDDI is not set
- # CONFIG_HIPPI is not set
- # CONFIG_PPP is not set
- # CONFIG_SLIP is not set
- # CONFIG_NET_FC is not set
- -# CONFIG_NETCONSOLE is not set
- -# CONFIG_NETPOLL is not set
- -# CONFIG_NET_POLL_CONTROLLER is not set
- +CONFIG_NETCONSOLE=m
- +CONFIG_NETCONSOLE_DYNAMIC=y
- +CONFIG_NETPOLL=y
- +# CONFIG_NETPOLL_TRAP is not set
- +CONFIG_NET_POLL_CONTROLLER=y
- +# CONFIG_VMXNET3 is not set
- # CONFIG_ISDN is not set
- # CONFIG_PHONE is not set
-
- @@ -849,25 +1005,26 @@
- # Input device support
- #
- CONFIG_INPUT=y
- -# CONFIG_INPUT_FF_MEMLESS is not set
- -# CONFIG_INPUT_POLLDEV is not set
- +CONFIG_INPUT_FF_MEMLESS=m
- +CONFIG_INPUT_POLLDEV=m
- +CONFIG_INPUT_SPARSEKMAP=m
-
- #
- # Userland interfaces
- #
- -CONFIG_INPUT_MOUSEDEV=y
- +CONFIG_INPUT_MOUSEDEV=m
- CONFIG_INPUT_MOUSEDEV_PSAUX=y
- CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
- CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
- # CONFIG_INPUT_JOYDEV is not set
- -CONFIG_INPUT_EVDEV=y
- +CONFIG_INPUT_EVDEV=m
- # CONFIG_INPUT_EVBUG is not set
-
- #
- # Input Device Drivers
- #
- CONFIG_INPUT_KEYBOARD=y
- -CONFIG_KEYBOARD_ATKBD=y
- +CONFIG_KEYBOARD_ATKBD=m
- # CONFIG_KEYBOARD_LKKBD is not set
- # CONFIG_KEYBOARD_NEWTON is not set
- # CONFIG_KEYBOARD_OPENCORES is not set
- @@ -875,7 +1032,7 @@
- # CONFIG_KEYBOARD_SUNKBD is not set
- # CONFIG_KEYBOARD_XTKBD is not set
- CONFIG_INPUT_MOUSE=y
- -CONFIG_MOUSE_PS2=y
- +CONFIG_MOUSE_PS2=m
- # CONFIG_MOUSE_PS2_ALPS is not set
- # CONFIG_MOUSE_PS2_LOGIPS2PP is not set
- CONFIG_MOUSE_PS2_SYNAPTICS=y
- @@ -884,7 +1041,7 @@
- # CONFIG_MOUSE_PS2_SENTELIC is not set
- # CONFIG_MOUSE_PS2_TOUCHKIT is not set
- # CONFIG_MOUSE_SERIAL is not set
- -# CONFIG_MOUSE_APPLETOUCH is not set
- +CONFIG_MOUSE_APPLETOUCH=m
- # CONFIG_MOUSE_BCM5974 is not set
- # CONFIG_MOUSE_INPORT is not set
- # CONFIG_MOUSE_LOGIBM is not set
- @@ -904,6 +1061,7 @@
- # CONFIG_SERIO_PCIPS2 is not set
- CONFIG_SERIO_LIBPS2=y
- # CONFIG_SERIO_RAW is not set
- +# CONFIG_SERIO_ALTERA_PS2 is not set
- # CONFIG_GAMEPORT is not set
-
- #
- @@ -915,27 +1073,13 @@
- CONFIG_HW_CONSOLE=y
- # CONFIG_VT_HW_CONSOLE_BINDING is not set
- CONFIG_DEVKMEM=y
- -CONFIG_SERIAL_NONSTANDARD=y
- -# CONFIG_COMPUTONE is not set
- -# CONFIG_ROCKETPORT is not set
- -# CONFIG_CYCLADES is not set
- -# CONFIG_DIGIEPCA is not set
- -# CONFIG_MOXA_INTELLIO is not set
- -# CONFIG_MOXA_SMARTIO is not set
- -# CONFIG_ISI is not set
- -# CONFIG_SYNCLINKMP is not set
- -# CONFIG_SYNCLINK_GT is not set
- -# CONFIG_N_HDLC is not set
- -# CONFIG_RISCOM8 is not set
- -# CONFIG_SPECIALIX is not set
- -# CONFIG_STALDRV is not set
- +# CONFIG_SERIAL_NONSTANDARD is not set
- # CONFIG_NOZOMI is not set
-
- #
- # Serial drivers
- #
- -CONFIG_SERIAL_8250=y
- -CONFIG_SERIAL_8250_CONSOLE=y
- +CONFIG_SERIAL_8250=m
- # CONFIG_SERIAL_8250_PCI is not set
- CONFIG_SERIAL_8250_NR_UARTS=16
- CONFIG_SERIAL_8250_RUNTIME_UARTS=4
- @@ -953,8 +1097,7 @@
- #
- # Non-8250 serial port support
- #
- -CONFIG_SERIAL_CORE=y
- -CONFIG_SERIAL_CORE_CONSOLE=y
- +CONFIG_SERIAL_CORE=m
- # CONFIG_SERIAL_JSM is not set
- CONFIG_UNIX98_PTYS=y
- # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
- @@ -963,7 +1106,6 @@
- # CONFIG_IPMI_HANDLER is not set
- CONFIG_HW_RANDOM=y
- # CONFIG_HW_RANDOM_TIMERIOMEM is not set
- -CONFIG_RTC=y
- # CONFIG_DTLK is not set
- # CONFIG_R3964 is not set
- # CONFIG_APPLICOM is not set
- @@ -978,7 +1120,10 @@
- #
- # CONFIG_PPS is not set
- # CONFIG_W1 is not set
- -# CONFIG_POWER_SUPPLY is not set
- +CONFIG_POWER_SUPPLY=m
- +# CONFIG_POWER_SUPPLY_DEBUG is not set
- +# CONFIG_PDA_POWER is not set
- +# CONFIG_BATTERY_DS2760 is not set
- CONFIG_HWMON=y
- # CONFIG_HWMON_VID is not set
- # CONFIG_HWMON_DEBUG_CHIP is not set
- @@ -1033,14 +1178,18 @@
- #
- # Multimedia drivers
- #
- +CONFIG_IR_CORE=m
- +CONFIG_VIDEO_IR=m
- # CONFIG_MEDIA_ATTACH is not set
- CONFIG_VIDEO_V4L2=m
- CONFIG_VIDEO_V4L1=m
- +CONFIG_VIDEOBUF_GEN=m
- +CONFIG_VIDEOBUF_VMALLOC=m
- CONFIG_VIDEO_CAPTURE_DRIVERS=y
- # CONFIG_VIDEO_ADV_DEBUG is not set
- # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
- CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
- -# CONFIG_VIDEO_VIVI is not set
- +CONFIG_VIDEO_VIVI=m
- # CONFIG_VIDEO_PMS is not set
- # CONFIG_VIDEO_CPIA is not set
- # CONFIG_VIDEO_CPIA2 is not set
- @@ -1049,52 +1198,55 @@
- CONFIG_USB_VIDEO_CLASS=m
- CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
- CONFIG_USB_GSPCA=m
- -# CONFIG_USB_M5602 is not set
- -# CONFIG_USB_STV06XX is not set
- +CONFIG_USB_M5602=m
- +CONFIG_USB_STV06XX=m
- # CONFIG_USB_GL860 is not set
- -# CONFIG_USB_GSPCA_CONEX is not set
- -# CONFIG_USB_GSPCA_ETOMS is not set
- -# CONFIG_USB_GSPCA_FINEPIX is not set
- +CONFIG_USB_GSPCA_CONEX=m
- +CONFIG_USB_GSPCA_ETOMS=m
- +CONFIG_USB_GSPCA_FINEPIX=m
- # CONFIG_USB_GSPCA_JEILINJ is not set
- -# CONFIG_USB_GSPCA_MARS is not set
- -# CONFIG_USB_GSPCA_MR97310A is not set
- -# CONFIG_USB_GSPCA_OV519 is not set
- -# CONFIG_USB_GSPCA_OV534 is not set
- -# CONFIG_USB_GSPCA_PAC207 is not set
- -# CONFIG_USB_GSPCA_PAC7311 is not set
- -# CONFIG_USB_GSPCA_SN9C20X is not set
- -# CONFIG_USB_GSPCA_SONIXB is not set
- -# CONFIG_USB_GSPCA_SONIXJ is not set
- -# CONFIG_USB_GSPCA_SPCA500 is not set
- -# CONFIG_USB_GSPCA_SPCA501 is not set
- -# CONFIG_USB_GSPCA_SPCA505 is not set
- -# CONFIG_USB_GSPCA_SPCA506 is not set
- -# CONFIG_USB_GSPCA_SPCA508 is not set
- -# CONFIG_USB_GSPCA_SPCA561 is not set
- -# CONFIG_USB_GSPCA_SQ905 is not set
- -# CONFIG_USB_GSPCA_SQ905C is not set
- -# CONFIG_USB_GSPCA_STK014 is not set
- -# CONFIG_USB_GSPCA_SUNPLUS is not set
- -# CONFIG_USB_GSPCA_T613 is not set
- -# CONFIG_USB_GSPCA_TV8532 is not set
- -# CONFIG_USB_GSPCA_VC032X is not set
- -# CONFIG_USB_GSPCA_ZC3XX is not set
- +CONFIG_USB_GSPCA_MARS=m
- +CONFIG_USB_GSPCA_MR97310A=m
- +CONFIG_USB_GSPCA_OV519=m
- +CONFIG_USB_GSPCA_OV534=m
- +CONFIG_USB_GSPCA_PAC207=m
- +# CONFIG_USB_GSPCA_PAC7302 is not set
- +CONFIG_USB_GSPCA_PAC7311=m
- +CONFIG_USB_GSPCA_SN9C20X=m
- +CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
- +CONFIG_USB_GSPCA_SONIXB=m
- +CONFIG_USB_GSPCA_SONIXJ=m
- +CONFIG_USB_GSPCA_SPCA500=m
- +CONFIG_USB_GSPCA_SPCA501=m
- +CONFIG_USB_GSPCA_SPCA505=m
- +CONFIG_USB_GSPCA_SPCA506=m
- +CONFIG_USB_GSPCA_SPCA508=m
- +CONFIG_USB_GSPCA_SPCA561=m
- +CONFIG_USB_GSPCA_SQ905=m
- +CONFIG_USB_GSPCA_SQ905C=m
- +CONFIG_USB_GSPCA_STK014=m
- +# CONFIG_USB_GSPCA_STV0680 is not set
- +CONFIG_USB_GSPCA_SUNPLUS=m
- +CONFIG_USB_GSPCA_T613=m
- +CONFIG_USB_GSPCA_TV8532=m
- +CONFIG_USB_GSPCA_VC032X=m
- +CONFIG_USB_GSPCA_ZC3XX=m
- # CONFIG_VIDEO_HDPVR is not set
- # CONFIG_USB_VICAM is not set
- # CONFIG_USB_IBMCAM is not set
- # CONFIG_USB_KONICAWC is not set
- # CONFIG_USB_QUICKCAM_MESSENGER is not set
- -# CONFIG_USB_ET61X251 is not set
- +CONFIG_USB_ET61X251=m
- # CONFIG_USB_OV511 is not set
- # CONFIG_USB_SE401 is not set
- -# CONFIG_USB_SN9C102 is not set
- +CONFIG_USB_SN9C102=m
- # CONFIG_USB_STV680 is not set
- -# CONFIG_USB_ZC0301 is not set
- +CONFIG_USB_ZC0301=m
- # CONFIG_USB_PWC is not set
- CONFIG_USB_PWC_INPUT_EVDEV=y
- -# CONFIG_USB_ZR364XX is not set
- -# CONFIG_USB_STKWEBCAM is not set
- -# CONFIG_USB_S2255 is not set
- +CONFIG_USB_ZR364XX=m
- +CONFIG_USB_STKWEBCAM=m
- +CONFIG_USB_S2255=m
- # CONFIG_RADIO_ADAPTERS is not set
- # CONFIG_DAB is not set
-
- @@ -1132,6 +1284,7 @@
- # CONFIG_FB_CYBER2000 is not set
- # CONFIG_FB_ASILIANT is not set
- # CONFIG_FB_IMSTT is not set
- +# CONFIG_FB_UVESA is not set
- # CONFIG_FB_S1D13XXX is not set
- # CONFIG_FB_NVIDIA is not set
- # CONFIG_FB_RIVA is not set
- @@ -1161,7 +1314,7 @@
- CONFIG_BACKLIGHT_LCD_SUPPORT=y
- # CONFIG_LCD_CLASS_DEVICE is not set
- CONFIG_BACKLIGHT_CLASS_DEVICE=y
- -CONFIG_BACKLIGHT_GENERIC=y
- +CONFIG_BACKLIGHT_GENERIC=m
-
- #
- # Display device support
- @@ -1188,33 +1341,45 @@
- CONFIG_FONT_SUN8x16=y
- CONFIG_FONT_SUN12x22=y
- CONFIG_FONT_10x18=y
- -CONFIG_LOGO=y
- -# CONFIG_LOGO_LINUX_MONO is not set
- -# CONFIG_LOGO_LINUX_VGA16 is not set
- -CONFIG_LOGO_LINUX_CLUT224=y
- +# CONFIG_LOGO is not set
- CONFIG_SOUND=m
- -# CONFIG_SOUND_OSS_CORE is not set
- +CONFIG_SOUND_OSS_CORE=y
- +CONFIG_SOUND_OSS_CORE_PRECLAIM=y
- CONFIG_SND=m
- CONFIG_SND_TIMER=m
- CONFIG_SND_PCM=m
- -# CONFIG_SND_SEQUENCER is not set
- -# CONFIG_SND_MIXER_OSS is not set
- -# CONFIG_SND_PCM_OSS is not set
- -# CONFIG_SND_HRTIMER is not set
- -# CONFIG_SND_RTCTIMER is not set
- +CONFIG_SND_HWDEP=m
- +CONFIG_SND_RAWMIDI=m
- +CONFIG_SND_SEQUENCER=m
- +CONFIG_SND_SEQ_DUMMY=m
- +CONFIG_SND_OSSEMUL=y
- +CONFIG_SND_MIXER_OSS=m
- +CONFIG_SND_PCM_OSS=m
- +CONFIG_SND_PCM_OSS_PLUGINS=y
- +CONFIG_SND_SEQUENCER_OSS=y
- +CONFIG_SND_HRTIMER=m
- +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
- # CONFIG_SND_DYNAMIC_MINORS is not set
- -# CONFIG_SND_SUPPORT_OLD_API is not set
- -# CONFIG_SND_VERBOSE_PROCFS is not set
- +CONFIG_SND_SUPPORT_OLD_API=y
- +CONFIG_SND_VERBOSE_PROCFS=y
- # CONFIG_SND_VERBOSE_PRINTK is not set
- # CONFIG_SND_DEBUG is not set
- CONFIG_SND_VMASTER=y
- -# CONFIG_SND_RAWMIDI_SEQ is not set
- +CONFIG_SND_RAWMIDI_SEQ=m
- # CONFIG_SND_OPL3_LIB_SEQ is not set
- # CONFIG_SND_OPL4_LIB_SEQ is not set
- # CONFIG_SND_SBAWE_SEQ is not set
- # CONFIG_SND_EMU10K1_SEQ is not set
- +CONFIG_SND_MPU401_UART=m
- CONFIG_SND_AC97_CODEC=m
- -# CONFIG_SND_DRIVERS is not set
- +CONFIG_SND_DRIVERS=y
- +CONFIG_SND_DUMMY=m
- +CONFIG_SND_VIRMIDI=m
- +# CONFIG_SND_MTPAV is not set
- +CONFIG_SND_SERIAL_U16550=m
- +CONFIG_SND_MPU401=m
- +CONFIG_SND_AC97_POWER_SAVE=y
- +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=10
- CONFIG_SND_PCI=y
- # CONFIG_SND_AD1889 is not set
- # CONFIG_SND_ALS300 is not set
- @@ -1281,7 +1446,10 @@
- # CONFIG_SND_VX222 is not set
- # CONFIG_SND_YMFPCI is not set
- # CONFIG_SND_MIPS is not set
- -# CONFIG_SND_USB is not set
- +CONFIG_SND_USB=y
- +CONFIG_SND_USB_AUDIO=m
- +CONFIG_SND_USB_CAIAQ=m
- +CONFIG_SND_USB_CAIAQ_INPUT=y
- # CONFIG_SND_SOC is not set
- # CONFIG_SOUND_PRIME is not set
- CONFIG_AC97_BUS=m
- @@ -1299,32 +1467,41 @@
- #
- # Special HID drivers
- #
- -# CONFIG_HID_A4TECH is not set
- -# CONFIG_HID_APPLE is not set
- -# CONFIG_HID_BELKIN is not set
- -# CONFIG_HID_CHERRY is not set
- -# CONFIG_HID_CHICONY is not set
- -# CONFIG_HID_CYPRESS is not set
- -# CONFIG_HID_DRAGONRISE is not set
- -# CONFIG_HID_EZKEY is not set
- -# CONFIG_HID_KYE is not set
- -# CONFIG_HID_GYRATION is not set
- -# CONFIG_HID_TWINHAN is not set
- -# CONFIG_HID_KENSINGTON is not set
- -# CONFIG_HID_LOGITECH is not set
- -# CONFIG_HID_MICROSOFT is not set
- -# CONFIG_HID_MONTEREY is not set
- -# CONFIG_HID_NTRIG is not set
- -# CONFIG_HID_PANTHERLORD is not set
- -# CONFIG_HID_PETALYNX is not set
- -# CONFIG_HID_SAMSUNG is not set
- -# CONFIG_HID_SONY is not set
- -# CONFIG_HID_SUNPLUS is not set
- -# CONFIG_HID_GREENASIA is not set
- -# CONFIG_HID_SMARTJOYPLUS is not set
- -# CONFIG_HID_TOPSEED is not set
- -# CONFIG_HID_THRUSTMASTER is not set
- -# CONFIG_HID_ZEROPLUS is not set
- +CONFIG_HID_A4TECH=m
- +CONFIG_HID_APPLE=m
- +CONFIG_HID_BELKIN=m
- +CONFIG_HID_CHERRY=m
- +CONFIG_HID_CHICONY=m
- +CONFIG_HID_CYPRESS=m
- +CONFIG_HID_DRAGONRISE=m
- +CONFIG_DRAGONRISE_FF=y
- +CONFIG_HID_EZKEY=m
- +CONFIG_HID_KYE=m
- +CONFIG_HID_GYRATION=m
- +CONFIG_HID_TWINHAN=m
- +CONFIG_HID_KENSINGTON=m
- +CONFIG_HID_LOGITECH=m
- +CONFIG_LOGITECH_FF=y
- +CONFIG_LOGIRUMBLEPAD2_FF=y
- +CONFIG_HID_MICROSOFT=m
- +CONFIG_HID_MONTEREY=m
- +CONFIG_HID_NTRIG=m
- +CONFIG_HID_PANTHERLORD=m
- +CONFIG_PANTHERLORD_FF=y
- +CONFIG_HID_PETALYNX=m
- +CONFIG_HID_SAMSUNG=m
- +CONFIG_HID_SONY=m
- +CONFIG_HID_SUNPLUS=m
- +CONFIG_HID_GREENASIA=m
- +CONFIG_GREENASIA_FF=y
- +CONFIG_HID_SMARTJOYPLUS=m
- +CONFIG_SMARTJOYPLUS_FF=y
- +CONFIG_HID_TOPSEED=m
- +CONFIG_HID_THRUSTMASTER=m
- +CONFIG_THRUSTMASTER_FF=y
- +CONFIG_HID_WACOM=m
- +CONFIG_HID_ZEROPLUS=m
- +CONFIG_ZEROPLUS_FF=y
- CONFIG_USB_SUPPORT=y
- CONFIG_USB_ARCH_HAS_HCD=y
- CONFIG_USB_ARCH_HAS_OHCI=y
- @@ -1336,15 +1513,15 @@
- #
- # Miscellaneous USB options
- #
- -CONFIG_USB_DEVICEFS=y
- +# CONFIG_USB_DEVICEFS is not set
- # CONFIG_USB_DEVICE_CLASS is not set
- CONFIG_USB_DYNAMIC_MINORS=y
- CONFIG_USB_SUSPEND=y
- # CONFIG_USB_OTG is not set
- CONFIG_USB_OTG_WHITELIST=y
- # CONFIG_USB_OTG_BLACKLIST_HUB is not set
- -CONFIG_USB_MON=y
- -# CONFIG_USB_WUSB is not set
- +CONFIG_USB_MON=m
- +CONFIG_USB_WUSB=m
- # CONFIG_USB_WUSB_CBAF is not set
-
- #
- @@ -1366,14 +1543,15 @@
- CONFIG_USB_UHCI_HCD=m
- # CONFIG_USB_SL811_HCD is not set
- # CONFIG_USB_R8A66597_HCD is not set
- -# CONFIG_USB_WHCI_HCD is not set
- -# CONFIG_USB_HWA_HCD is not set
- +CONFIG_USB_WHCI_HCD=m
- +CONFIG_USB_HWA_HCD=m
- +# CONFIG_USB_GADGET_MUSB_HDRC is not set
-
- #
- # USB Device Class drivers
- #
- CONFIG_USB_ACM=m
- -# CONFIG_USB_PRINTER is not set
- +CONFIG_USB_PRINTER=m
- CONFIG_USB_WDM=m
- # CONFIG_USB_TMC is not set
-
- @@ -1397,7 +1575,7 @@
- # CONFIG_USB_STORAGE_ONETOUCH is not set
- # CONFIG_USB_STORAGE_KARMA is not set
- # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
- -# CONFIG_USB_LIBUSUAL is not set
- +CONFIG_USB_LIBUSUAL=y
-
- #
- # USB Imaging devices
- @@ -1467,7 +1645,7 @@
- # CONFIG_USB_LEGOTOWER is not set
- # CONFIG_USB_LCD is not set
- # CONFIG_USB_BERRY_CHARGE is not set
- -# CONFIG_USB_LED is not set
- +CONFIG_USB_LED=m
- # CONFIG_USB_CYPRESS_CY7C63 is not set
- # CONFIG_USB_CYTHERM is not set
- # CONFIG_USB_IDMOUSE is not set
- @@ -1480,19 +1658,136 @@
- # CONFIG_USB_TEST is not set
- # CONFIG_USB_ISIGHTFW is not set
- # CONFIG_USB_VST is not set
- -# CONFIG_USB_GADGET is not set
- +CONFIG_USB_GADGET=m
- +# CONFIG_USB_GADGET_DEBUG_FILES is not set
- +# CONFIG_USB_GADGET_DEBUG_FS is not set
- +CONFIG_USB_GADGET_VBUS_DRAW=2
- +CONFIG_USB_GADGET_SELECTED=y
- +# CONFIG_USB_GADGET_AT91 is not set
- +# CONFIG_USB_GADGET_ATMEL_USBA is not set
- +# CONFIG_USB_GADGET_FSL_USB2 is not set
- +# CONFIG_USB_GADGET_LH7A40X is not set
- +# CONFIG_USB_GADGET_OMAP is not set
- +# CONFIG_USB_GADGET_PXA25X is not set
- +# CONFIG_USB_GADGET_R8A66597 is not set
- +# CONFIG_USB_GADGET_PXA27X is not set
- +# CONFIG_USB_GADGET_S3C_HSOTG is not set
- +# CONFIG_USB_GADGET_IMX is not set
- +# CONFIG_USB_GADGET_S3C2410 is not set
- +CONFIG_USB_GADGET_M66592=y
- +CONFIG_USB_M66592=m
- +# CONFIG_USB_GADGET_AMD5536UDC is not set
- +# CONFIG_USB_GADGET_FSL_QE is not set
- +# CONFIG_USB_GADGET_CI13XXX is not set
- +# CONFIG_USB_GADGET_NET2280 is not set
- +# CONFIG_USB_GADGET_GOKU is not set
- +# CONFIG_USB_GADGET_LANGWELL is not set
- +# CONFIG_USB_GADGET_DUMMY_HCD is not set
- +CONFIG_USB_GADGET_DUALSPEED=y
- +# CONFIG_USB_ZERO is not set
- +# CONFIG_USB_AUDIO is not set
- +# CONFIG_USB_ETH is not set
- +# CONFIG_USB_GADGETFS is not set
- +# CONFIG_USB_FILE_STORAGE is not set
- +# CONFIG_USB_MASS_STORAGE is not set
- +# CONFIG_USB_G_SERIAL is not set
- +# CONFIG_USB_MIDI_GADGET is not set
- +# CONFIG_USB_G_PRINTER is not set
- +# CONFIG_USB_CDC_COMPOSITE is not set
- +# CONFIG_USB_G_MULTI is not set
-
- #
- # OTG and related infrastructure
- #
- # CONFIG_NOP_USB_XCEIV is not set
- -# CONFIG_UWB is not set
- -# CONFIG_MMC is not set
- +CONFIG_UWB=m
- +CONFIG_UWB_HWA=m
- +CONFIG_UWB_WHCI=m
- +# CONFIG_UWB_WLP is not set
- +# CONFIG_UWB_I1480U is not set
- +CONFIG_MMC=m
- +# CONFIG_MMC_DEBUG is not set
- +# CONFIG_MMC_UNSAFE_RESUME is not set
- +
- +#
- +# MMC/SD/SDIO Card Drivers
- +#
- +CONFIG_MMC_BLOCK=m
- +CONFIG_MMC_BLOCK_BOUNCE=y
- +# CONFIG_SDIO_UART is not set
- +# CONFIG_MMC_TEST is not set
- +
- +#
- +# MMC/SD/SDIO Host Controller Drivers
- +#
- +# CONFIG_MMC_SDHCI is not set
- +# CONFIG_MMC_AT91 is not set
- +# CONFIG_MMC_ATMELMCI is not set
- +# CONFIG_MMC_TIFM_SD is not set
- +# CONFIG_MMC_CB710 is not set
- +# CONFIG_MMC_VIA_SDMMC is not set
- # CONFIG_MEMSTICK is not set
- -# CONFIG_NEW_LEDS is not set
- +CONFIG_NEW_LEDS=y
- +CONFIG_LEDS_CLASS=m
- +
- +#
- +# LED drivers
- +#
- +
- +#
- +# LED Triggers
- +#
- +CONFIG_LEDS_TRIGGERS=y
- +# CONFIG_LEDS_TRIGGER_TIMER is not set
- +# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
- +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
- +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
- +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
- +
- +#
- +# iptables trigger is under Netfilter config (LED target)
- +#
- # CONFIG_ACCESSIBILITY is not set
- # CONFIG_INFINIBAND is not set
- -# CONFIG_RTC_CLASS is not set
- +CONFIG_RTC_LIB=y
- +CONFIG_RTC_CLASS=y
- +CONFIG_RTC_HCTOSYS=y
- +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
- +# CONFIG_RTC_DEBUG is not set
- +
- +#
- +# RTC interfaces
- +#
- +CONFIG_RTC_INTF_SYSFS=y
- +CONFIG_RTC_INTF_PROC=y
- +CONFIG_RTC_INTF_DEV=y
- +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
- +# CONFIG_RTC_DRV_TEST is not set
- +
- +#
- +# SPI RTC drivers
- +#
- +
- +#
- +# Platform RTC drivers
- +#
- +CONFIG_RTC_DRV_CMOS=y
- +# CONFIG_RTC_DRV_DS1286 is not set
- +# CONFIG_RTC_DRV_DS1511 is not set
- +# CONFIG_RTC_DRV_DS1553 is not set
- +# CONFIG_RTC_DRV_DS1742 is not set
- +# CONFIG_RTC_DRV_STK17TA8 is not set
- +# CONFIG_RTC_DRV_M48T86 is not set
- +# CONFIG_RTC_DRV_M48T35 is not set
- +# CONFIG_RTC_DRV_M48T59 is not set
- +# CONFIG_RTC_DRV_MSM6242 is not set
- +# CONFIG_RTC_DRV_BQ4802 is not set
- +# CONFIG_RTC_DRV_RP5C01 is not set
- +# CONFIG_RTC_DRV_V3020 is not set
- +
- +#
- +# on-CPU RTC drivers
- +#
- # CONFIG_DMADEVICES is not set
- # CONFIG_AUXDISPLAY is not set
- # CONFIG_UIO is not set
- @@ -1504,22 +1799,21 @@
- # CONFIG_STAGING_EXCLUDE_BUILD is not set
- # CONFIG_ET131X is not set
- # CONFIG_USB_IP_COMMON is not set
- +# CONFIG_W35UND is not set
- # CONFIG_PRISM2_USB is not set
- # CONFIG_ECHO is not set
- +# CONFIG_OTUS is not set
- # CONFIG_COMEDI is not set
- # CONFIG_ASUS_OLED is not set
- # CONFIG_ALTERA_PCIE_CHDMA is not set
- -# CONFIG_RTL8187SE is not set
- +# CONFIG_R8187SE is not set
- # CONFIG_RTL8192SU is not set
- +# CONFIG_RTL8192U is not set
- # CONFIG_RTL8192E is not set
- # CONFIG_INPUT_MIMIO is not set
- # CONFIG_TRANZPORT is not set
-
- #
- -# Android
- -#
- -
- -#
- # Qualcomm MSM Camera And Video
- #
-
- @@ -1527,7 +1821,6 @@
- # Camera Sensor Selection
- #
- # CONFIG_INPUT_GPIO is not set
- -# CONFIG_DST is not set
- # CONFIG_POHMELFS is not set
- # CONFIG_B3DFG is not set
- # CONFIG_PLAN9AUTH is not set
- @@ -1544,28 +1837,57 @@
- #
- # CONFIG_RAR_REGISTER is not set
- # CONFIG_IIO is not set
- +# CONFIG_RAMZSWAP is not set
- +# CONFIG_BATMAN_ADV is not set
- +# CONFIG_STRIP is not set
- +# CONFIG_WAVELAN is not set
- CONFIG_FB_SM7XX=y
- -CONFIG_FB_SM7XX_ACCEL=y
- +CONFIG_MIPS_PLATFORM_DEVICES=y
- +CONFIG_LEMOTE_YEELOONG2F=m
- +CONFIG_LEMOTE_LYNLOONG2F=m
-
- #
- # File systems
- #
- -# CONFIG_EXT2_FS is not set
- +CONFIG_EXT2_FS=m
- +# CONFIG_EXT2_FS_XATTR is not set
- +# CONFIG_EXT2_FS_XIP is not set
- CONFIG_EXT3_FS=y
- # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
- CONFIG_EXT3_FS_XATTR=y
- CONFIG_EXT3_FS_POSIX_ACL=y
- CONFIG_EXT3_FS_SECURITY=y
- -# CONFIG_EXT4_FS is not set
- +CONFIG_EXT4_FS=y
- +CONFIG_EXT4_FS_XATTR=y
- +# CONFIG_EXT4_FS_POSIX_ACL is not set
- +# CONFIG_EXT4_FS_SECURITY is not set
- +# CONFIG_EXT4_DEBUG is not set
- CONFIG_JBD=y
- +# CONFIG_JBD_DEBUG is not set
- +CONFIG_JBD2=y
- +# CONFIG_JBD2_DEBUG is not set
- CONFIG_FS_MBCACHE=y
- -# CONFIG_REISERFS_FS is not set
- -# CONFIG_JFS_FS is not set
- +CONFIG_REISERFS_FS=m
- +# CONFIG_REISERFS_CHECK is not set
- +CONFIG_REISERFS_PROC_INFO=y
- +CONFIG_REISERFS_FS_XATTR=y
- +# CONFIG_REISERFS_FS_POSIX_ACL is not set
- +# CONFIG_REISERFS_FS_SECURITY is not set
- +CONFIG_JFS_FS=m
- +CONFIG_JFS_POSIX_ACL=y
- +# CONFIG_JFS_SECURITY is not set
- +# CONFIG_JFS_DEBUG is not set
- +# CONFIG_JFS_STATISTICS is not set
- CONFIG_FS_POSIX_ACL=y
- -# CONFIG_XFS_FS is not set
- +CONFIG_XFS_FS=m
- +CONFIG_XFS_QUOTA=y
- +CONFIG_XFS_POSIX_ACL=y
- +# CONFIG_XFS_RT is not set
- +# CONFIG_XFS_DEBUG is not set
- # CONFIG_GFS2_FS is not set
- # CONFIG_OCFS2_FS is not set
- -# CONFIG_BTRFS_FS is not set
- +CONFIG_BTRFS_FS=m
- +# CONFIG_BTRFS_FS_POSIX_ACL is not set
- # CONFIG_NILFS2_FS is not set
- CONFIG_FILE_LOCKING=y
- CONFIG_FSNOTIFY=y
- @@ -1575,17 +1897,26 @@
- CONFIG_QUOTA=y
- # CONFIG_QUOTA_NETLINK_INTERFACE is not set
- CONFIG_PRINT_QUOTA_WARNING=y
- +CONFIG_QUOTA_TREE=m
- # CONFIG_QFMT_V1 is not set
- -# CONFIG_QFMT_V2 is not set
- +CONFIG_QFMT_V2=m
- CONFIG_QUOTACTL=y
- -# CONFIG_AUTOFS_FS is not set
- -# CONFIG_AUTOFS4_FS is not set
- -# CONFIG_FUSE_FS is not set
- +CONFIG_AUTOFS_FS=m
- +CONFIG_AUTOFS4_FS=m
- +CONFIG_FUSE_FS=m
- +CONFIG_CUSE=m
-
- #
- # Caches
- #
- -# CONFIG_FSCACHE is not set
- +CONFIG_FSCACHE=m
- +# CONFIG_FSCACHE_STATS is not set
- +# CONFIG_FSCACHE_HISTOGRAM is not set
- +# CONFIG_FSCACHE_DEBUG is not set
- +# CONFIG_FSCACHE_OBJECT_LIST is not set
- +CONFIG_CACHEFILES=m
- +# CONFIG_CACHEFILES_DEBUG is not set
- +# CONFIG_CACHEFILES_HISTOGRAM is not set
-
- #
- # CD-ROM/DVD Filesystems
- @@ -1599,11 +1930,13 @@
- # DOS/FAT/NT Filesystems
- #
- CONFIG_FAT_FS=m
- -# CONFIG_MSDOS_FS is not set
- +CONFIG_MSDOS_FS=m
- CONFIG_VFAT_FS=m
- CONFIG_FAT_DEFAULT_CODEPAGE=437
- CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
- -# CONFIG_NTFS_FS is not set
- +CONFIG_NTFS_FS=m
- +# CONFIG_NTFS_DEBUG is not set
- +CONFIG_NTFS_RW=y
-
- #
- # Pseudo filesystems
- @@ -1616,23 +1949,60 @@
- CONFIG_TMPFS=y
- # CONFIG_TMPFS_POSIX_ACL is not set
- # CONFIG_HUGETLB_PAGE is not set
- -# CONFIG_CONFIGFS_FS is not set
- -# CONFIG_MISC_FILESYSTEMS is not set
- +CONFIG_CONFIGFS_FS=m
- +CONFIG_MISC_FILESYSTEMS=y
- +# CONFIG_ADFS_FS is not set
- +# CONFIG_AFFS_FS is not set
- +# CONFIG_ECRYPT_FS is not set
- +# CONFIG_HFS_FS is not set
- +# CONFIG_HFSPLUS_FS is not set
- +# CONFIG_BEFS_FS is not set
- +# CONFIG_BFS_FS is not set
- +# CONFIG_EFS_FS is not set
- +CONFIG_CRAMFS=m
- +CONFIG_SQUASHFS=m
- +CONFIG_SQUASHFS_EMBEDDED=y
- +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
- +# CONFIG_VXFS_FS is not set
- +# CONFIG_MINIX_FS is not set
- +# CONFIG_OMFS_FS is not set
- +# CONFIG_HPFS_FS is not set
- +# CONFIG_QNX4FS_FS is not set
- +CONFIG_ROMFS_FS=m
- +CONFIG_ROMFS_BACKED_BY_BLOCK=y
- +# CONFIG_ROMFS_BACKED_BY_MTD is not set
- +# CONFIG_ROMFS_BACKED_BY_BOTH is not set
- +CONFIG_ROMFS_ON_BLOCK=y
- +# CONFIG_SYSV_FS is not set
- +# CONFIG_UFS_FS is not set
- CONFIG_NETWORK_FILESYSTEMS=y
- CONFIG_NFS_FS=m
- CONFIG_NFS_V3=y
- CONFIG_NFS_V3_ACL=y
- # CONFIG_NFS_V4 is not set
- -# CONFIG_NFSD is not set
- +# CONFIG_NFS_FSCACHE is not set
- +CONFIG_NFSD=m
- +CONFIG_NFSD_V3=y
- +# CONFIG_NFSD_V3_ACL is not set
- +CONFIG_NFSD_V4=y
- CONFIG_LOCKD=m
- CONFIG_LOCKD_V4=y
- +CONFIG_EXPORTFS=m
- CONFIG_NFS_ACL_SUPPORT=m
- CONFIG_NFS_COMMON=y
- CONFIG_SUNRPC=m
- -# CONFIG_RPCSEC_GSS_KRB5 is not set
- +CONFIG_SUNRPC_GSS=m
- +CONFIG_RPCSEC_GSS_KRB5=m
- # CONFIG_RPCSEC_GSS_SPKM3 is not set
- # CONFIG_SMB_FS is not set
- -# CONFIG_CIFS is not set
- +CONFIG_CIFS=m
- +# CONFIG_CIFS_STATS is not set
- +# CONFIG_CIFS_WEAK_PW_HASH is not set
- +# CONFIG_CIFS_UPCALL is not set
- +# CONFIG_CIFS_XATTR is not set
- +# CONFIG_CIFS_DEBUG2 is not set
- +# CONFIG_CIFS_DFS_UPCALL is not set
- +# CONFIG_CIFS_EXPERIMENTAL is not set
- # CONFIG_NCP_FS is not set
- # CONFIG_CODA_FS is not set
- # CONFIG_AFS_FS is not set
- @@ -1643,177 +2013,205 @@
- # CONFIG_PARTITION_ADVANCED is not set
- CONFIG_MSDOS_PARTITION=y
- CONFIG_NLS=y
- -CONFIG_NLS_DEFAULT="utf-8"
- -# CONFIG_NLS_CODEPAGE_437 is not set
- -# CONFIG_NLS_CODEPAGE_737 is not set
- -# CONFIG_NLS_CODEPAGE_775 is not set
- -# CONFIG_NLS_CODEPAGE_850 is not set
- -# CONFIG_NLS_CODEPAGE_852 is not set
- -# CONFIG_NLS_CODEPAGE_855 is not set
- -# CONFIG_NLS_CODEPAGE_857 is not set
- -# CONFIG_NLS_CODEPAGE_860 is not set
- -# CONFIG_NLS_CODEPAGE_861 is not set
- -# CONFIG_NLS_CODEPAGE_862 is not set
- -# CONFIG_NLS_CODEPAGE_863 is not set
- -# CONFIG_NLS_CODEPAGE_864 is not set
- -# CONFIG_NLS_CODEPAGE_865 is not set
- -# CONFIG_NLS_CODEPAGE_866 is not set
- -# CONFIG_NLS_CODEPAGE_869 is not set
- -# CONFIG_NLS_CODEPAGE_936 is not set
- -# CONFIG_NLS_CODEPAGE_950 is not set
- -# CONFIG_NLS_CODEPAGE_932 is not set
- -# CONFIG_NLS_CODEPAGE_949 is not set
- -# CONFIG_NLS_CODEPAGE_874 is not set
- -# CONFIG_NLS_ISO8859_8 is not set
- -# CONFIG_NLS_CODEPAGE_1250 is not set
- -# CONFIG_NLS_CODEPAGE_1251 is not set
- -# CONFIG_NLS_ASCII is not set
- -# CONFIG_NLS_ISO8859_1 is not set
- -# CONFIG_NLS_ISO8859_2 is not set
- -# CONFIG_NLS_ISO8859_3 is not set
- -# CONFIG_NLS_ISO8859_4 is not set
- -# CONFIG_NLS_ISO8859_5 is not set
- -# CONFIG_NLS_ISO8859_6 is not set
- -# CONFIG_NLS_ISO8859_7 is not set
- -# CONFIG_NLS_ISO8859_9 is not set
- -# CONFIG_NLS_ISO8859_13 is not set
- -# CONFIG_NLS_ISO8859_14 is not set
- -# CONFIG_NLS_ISO8859_15 is not set
- -# CONFIG_NLS_KOI8_R is not set
- -# CONFIG_NLS_KOI8_U is not set
- -# CONFIG_NLS_UTF8 is not set
- +CONFIG_NLS_DEFAULT="utf8"
- +CONFIG_NLS_CODEPAGE_437=m
- +CONFIG_NLS_CODEPAGE_737=m
- +CONFIG_NLS_CODEPAGE_775=m
- +CONFIG_NLS_CODEPAGE_850=m
- +CONFIG_NLS_CODEPAGE_852=m
- +CONFIG_NLS_CODEPAGE_855=m
- +CONFIG_NLS_CODEPAGE_857=m
- +CONFIG_NLS_CODEPAGE_860=m
- +CONFIG_NLS_CODEPAGE_861=m
- +CONFIG_NLS_CODEPAGE_862=m
- +CONFIG_NLS_CODEPAGE_863=m
- +CONFIG_NLS_CODEPAGE_864=m
- +CONFIG_NLS_CODEPAGE_865=m
- +CONFIG_NLS_CODEPAGE_866=m
- +CONFIG_NLS_CODEPAGE_869=m
- +CONFIG_NLS_CODEPAGE_936=m
- +CONFIG_NLS_CODEPAGE_950=m
- +CONFIG_NLS_CODEPAGE_932=m
- +CONFIG_NLS_CODEPAGE_949=m
- +CONFIG_NLS_CODEPAGE_874=m
- +CONFIG_NLS_ISO8859_8=m
- +CONFIG_NLS_CODEPAGE_1250=m
- +CONFIG_NLS_CODEPAGE_1251=m
- +CONFIG_NLS_ASCII=m
- +CONFIG_NLS_ISO8859_1=m
- +CONFIG_NLS_ISO8859_2=m
- +CONFIG_NLS_ISO8859_3=m
- +CONFIG_NLS_ISO8859_4=m
- +CONFIG_NLS_ISO8859_5=m
- +CONFIG_NLS_ISO8859_6=m
- +CONFIG_NLS_ISO8859_7=m
- +CONFIG_NLS_ISO8859_9=m
- +CONFIG_NLS_ISO8859_13=m
- +CONFIG_NLS_ISO8859_14=m
- +CONFIG_NLS_ISO8859_15=m
- +CONFIG_NLS_KOI8_R=m
- +CONFIG_NLS_KOI8_U=m
- +CONFIG_NLS_UTF8=y
- # CONFIG_DLM is not set
-
- #
- # Kernel hacking
- #
- CONFIG_TRACE_IRQFLAGS_SUPPORT=y
- -CONFIG_PRINTK_TIME=y
- +# CONFIG_PRINTK_TIME is not set
- CONFIG_ENABLE_WARN_DEPRECATED=y
- CONFIG_ENABLE_MUST_CHECK=y
- CONFIG_FRAME_WARN=1024
- # CONFIG_MAGIC_SYSRQ is not set
- CONFIG_STRIP_ASM_SYMS=y
- # CONFIG_UNUSED_SYMBOLS is not set
- -# CONFIG_DEBUG_FS is not set
- +CONFIG_DEBUG_FS=y
- # CONFIG_HEADERS_CHECK is not set
- # CONFIG_DEBUG_KERNEL is not set
- -# CONFIG_SLUB_DEBUG_ON is not set
- -# CONFIG_SLUB_STATS is not set
- +CONFIG_STACKTRACE=y
- # CONFIG_DEBUG_MEMORY_INIT is not set
- # CONFIG_RCU_CPU_STALL_DETECTOR is not set
- -CONFIG_SYSCTL_SYSCALL_CHECK=y
- +# CONFIG_SYSCTL_SYSCALL_CHECK is not set
- +CONFIG_NOP_TRACER=y
- +CONFIG_HAVE_FUNCTION_TRACER=y
- +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
- +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
- +CONFIG_HAVE_DYNAMIC_FTRACE=y
- +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
- +CONFIG_RING_BUFFER=y
- +CONFIG_EVENT_TRACING=y
- +CONFIG_CONTEXT_SWITCH_TRACER=y
- +CONFIG_RING_BUFFER_ALLOW_SWAP=y
- +CONFIG_TRACING=y
- CONFIG_TRACING_SUPPORT=y
- # CONFIG_FTRACE is not set
- +# CONFIG_DYNAMIC_DEBUG is not set
- # CONFIG_SAMPLES is not set
- CONFIG_HAVE_ARCH_KGDB=y
- +CONFIG_EARLY_PRINTK=y
- # CONFIG_CMDLINE_BOOL is not set
-
- #
- # Security options
- #
- -# CONFIG_KEYS is not set
- +CONFIG_KEYS=y
- +CONFIG_KEYS_DEBUG_PROC_KEYS=y
- # CONFIG_SECURITY is not set
- # CONFIG_SECURITYFS is not set
- -# CONFIG_SECURITY_FILE_CAPABILITIES is not set
- +# CONFIG_DEFAULT_SECURITY_SELINUX is not set
- +# CONFIG_DEFAULT_SECURITY_SMACK is not set
- +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
- +CONFIG_DEFAULT_SECURITY_DAC=y
- +CONFIG_DEFAULT_SECURITY=""
- +CONFIG_XOR_BLOCKS=m
- +CONFIG_ASYNC_CORE=m
- +CONFIG_ASYNC_MEMCPY=m
- +CONFIG_ASYNC_XOR=m
- +CONFIG_ASYNC_PQ=m
- +CONFIG_ASYNC_RAID6_RECOV=m
- CONFIG_CRYPTO=y
-
- #
- # Crypto core or helper
- #
- +CONFIG_CRYPTO_FIPS=y
- CONFIG_CRYPTO_ALGAPI=y
- CONFIG_CRYPTO_ALGAPI2=y
- +CONFIG_CRYPTO_AEAD=m
- CONFIG_CRYPTO_AEAD2=y
- -CONFIG_CRYPTO_BLKCIPHER=y
- +CONFIG_CRYPTO_BLKCIPHER=m
- CONFIG_CRYPTO_BLKCIPHER2=y
- +CONFIG_CRYPTO_HASH=y
- CONFIG_CRYPTO_HASH2=y
- +CONFIG_CRYPTO_RNG=m
- CONFIG_CRYPTO_RNG2=y
- CONFIG_CRYPTO_PCOMP=y
- -CONFIG_CRYPTO_MANAGER=y
- +CONFIG_CRYPTO_MANAGER=m
- CONFIG_CRYPTO_MANAGER2=y
- -# CONFIG_CRYPTO_GF128MUL is not set
- -# CONFIG_CRYPTO_NULL is not set
- +CONFIG_CRYPTO_GF128MUL=m
- +CONFIG_CRYPTO_NULL=m
- CONFIG_CRYPTO_WORKQUEUE=y
- -# CONFIG_CRYPTO_CRYPTD is not set
- -# CONFIG_CRYPTO_AUTHENC is not set
- -# CONFIG_CRYPTO_TEST is not set
- +CONFIG_CRYPTO_CRYPTD=m
- +CONFIG_CRYPTO_AUTHENC=m
- +CONFIG_CRYPTO_TEST=m
-
- #
- # Authenticated Encryption with Associated Data
- #
- -# CONFIG_CRYPTO_CCM is not set
- -# CONFIG_CRYPTO_GCM is not set
- -# CONFIG_CRYPTO_SEQIV is not set
- +CONFIG_CRYPTO_CCM=m
- +CONFIG_CRYPTO_GCM=m
- +CONFIG_CRYPTO_SEQIV=m
-
- #
- # Block modes
- #
- -CONFIG_CRYPTO_CBC=y
- -# CONFIG_CRYPTO_CTR is not set
- +CONFIG_CRYPTO_CBC=m
- +CONFIG_CRYPTO_CTR=m
- # CONFIG_CRYPTO_CTS is not set
- -# CONFIG_CRYPTO_ECB is not set
- -# CONFIG_CRYPTO_LRW is not set
- -# CONFIG_CRYPTO_PCBC is not set
- -# CONFIG_CRYPTO_XTS is not set
- +CONFIG_CRYPTO_ECB=m
- +CONFIG_CRYPTO_LRW=m
- +CONFIG_CRYPTO_PCBC=m
- +CONFIG_CRYPTO_XTS=m
-
- #
- # Hash modes
- #
- -# CONFIG_CRYPTO_HMAC is not set
- -# CONFIG_CRYPTO_XCBC is not set
- +CONFIG_CRYPTO_HMAC=m
- +CONFIG_CRYPTO_XCBC=m
- # CONFIG_CRYPTO_VMAC is not set
-
- #
- # Digest
- #
- -# CONFIG_CRYPTO_CRC32C is not set
- -# CONFIG_CRYPTO_GHASH is not set
- -# CONFIG_CRYPTO_MD4 is not set
- -# CONFIG_CRYPTO_MD5 is not set
- -# CONFIG_CRYPTO_MICHAEL_MIC is not set
- -# CONFIG_CRYPTO_RMD128 is not set
- -# CONFIG_CRYPTO_RMD160 is not set
- -# CONFIG_CRYPTO_RMD256 is not set
- -# CONFIG_CRYPTO_RMD320 is not set
- -# CONFIG_CRYPTO_SHA1 is not set
- -# CONFIG_CRYPTO_SHA256 is not set
- -# CONFIG_CRYPTO_SHA512 is not set
- -# CONFIG_CRYPTO_TGR192 is not set
- -# CONFIG_CRYPTO_WP512 is not set
- +CONFIG_CRYPTO_CRC32C=m
- +CONFIG_CRYPTO_GHASH=m
- +CONFIG_CRYPTO_MD4=m
- +CONFIG_CRYPTO_MD5=y
- +CONFIG_CRYPTO_MICHAEL_MIC=m
- +CONFIG_CRYPTO_RMD128=m
- +CONFIG_CRYPTO_RMD160=m
- +CONFIG_CRYPTO_RMD256=m
- +CONFIG_CRYPTO_RMD320=m
- +CONFIG_CRYPTO_SHA1=m
- +CONFIG_CRYPTO_SHA256=m
- +CONFIG_CRYPTO_SHA512=m
- +CONFIG_CRYPTO_TGR192=m
- +CONFIG_CRYPTO_WP512=m
-
- #
- # Ciphers
- #
- -# CONFIG_CRYPTO_AES is not set
- -# CONFIG_CRYPTO_ANUBIS is not set
- -# CONFIG_CRYPTO_ARC4 is not set
- -# CONFIG_CRYPTO_BLOWFISH is not set
- -# CONFIG_CRYPTO_CAMELLIA is not set
- -# CONFIG_CRYPTO_CAST5 is not set
- -# CONFIG_CRYPTO_CAST6 is not set
- -# CONFIG_CRYPTO_DES is not set
- -# CONFIG_CRYPTO_FCRYPT is not set
- -# CONFIG_CRYPTO_KHAZAD is not set
- -# CONFIG_CRYPTO_SALSA20 is not set
- -# CONFIG_CRYPTO_SEED is not set
- -# CONFIG_CRYPTO_SERPENT is not set
- -# CONFIG_CRYPTO_TEA is not set
- -# CONFIG_CRYPTO_TWOFISH is not set
- +CONFIG_CRYPTO_AES=m
- +CONFIG_CRYPTO_ANUBIS=m
- +CONFIG_CRYPTO_ARC4=m
- +CONFIG_CRYPTO_BLOWFISH=m
- +CONFIG_CRYPTO_CAMELLIA=m
- +CONFIG_CRYPTO_CAST5=m
- +CONFIG_CRYPTO_CAST6=m
- +CONFIG_CRYPTO_DES=m
- +CONFIG_CRYPTO_FCRYPT=m
- +CONFIG_CRYPTO_KHAZAD=m
- +CONFIG_CRYPTO_SALSA20=m
- +CONFIG_CRYPTO_SEED=m
- +CONFIG_CRYPTO_SERPENT=m
- +CONFIG_CRYPTO_TEA=m
- +CONFIG_CRYPTO_TWOFISH=m
- +CONFIG_CRYPTO_TWOFISH_COMMON=m
-
- #
- # Compression
- #
- -# CONFIG_CRYPTO_DEFLATE is not set
- -# CONFIG_CRYPTO_ZLIB is not set
- -# CONFIG_CRYPTO_LZO is not set
- +CONFIG_CRYPTO_DEFLATE=m
- +CONFIG_CRYPTO_ZLIB=m
- +CONFIG_CRYPTO_LZO=m
-
- #
- # Random Number Generation
- #
- -# CONFIG_CRYPTO_ANSI_CPRNG is not set
- +CONFIG_CRYPTO_ANSI_CPRNG=m
- CONFIG_CRYPTO_HW=y
- # CONFIG_CRYPTO_DEV_HIFN_795X is not set
- -# CONFIG_BINARY_PRINTF is not set
- +CONFIG_BINARY_PRINTF=y
-
- #
- # Library routines
- @@ -1821,14 +2219,20 @@
- CONFIG_BITREVERSE=y
- CONFIG_GENERIC_FIND_LAST_BIT=y
- # CONFIG_CRC_CCITT is not set
- -# CONFIG_CRC16 is not set
- +CONFIG_CRC16=y
- CONFIG_CRC_T10DIF=y
- # CONFIG_CRC_ITU_T is not set
- CONFIG_CRC32=y
- # CONFIG_CRC7 is not set
- -# CONFIG_LIBCRC32C is not set
- +CONFIG_LIBCRC32C=m
- CONFIG_AUDIT_GENERIC=y
- -CONFIG_ZLIB_INFLATE=m
- +CONFIG_ZLIB_INFLATE=y
- +CONFIG_ZLIB_DEFLATE=m
- +CONFIG_LZO_COMPRESS=m
- +CONFIG_LZO_DECOMPRESS=m
- +CONFIG_DECOMPRESS_GZIP=y
- +CONFIG_DECOMPRESS_BZIP2=y
- +CONFIG_DECOMPRESS_LZMA=y
- CONFIG_HAS_IOMEM=y
- CONFIG_HAS_IOPORT=y
- CONFIG_HAS_DMA=y
- diff -Nur linux-2.6.33/arch/mips/include/asm/ftrace.h linux-lemote/arch/mips/include/asm/ftrace.h
- --- linux-2.6.33/arch/mips/include/asm/ftrace.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/ftrace.h 2010-03-06 16:43:00.000000000 +0100
- @@ -4,7 +4,7 @@
- * more details.
- *
- * Copyright (C) 2009 DSLab, Lanzhou University, China
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- */
-
- #ifndef _ASM_MIPS_FTRACE_H
- 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
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-03-06 16:43:00.000000000 +0100
- @@ -3,7 +3,7 @@
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- - * Copyright (C) 2009 Wu Zhangjin <wuzj@lemote.com>
- + * Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
- * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
- * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
- *
- 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
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-03-06 16:43:00.000000000 +0100
- @@ -301,5 +301,40 @@
- /* GPIO : I/O SPACE; REG : 32BITS */
- #define GPIOL_OUT_VAL 0x00
- #define GPIOL_OUT_EN 0x04
- +#define GPIOL_OUT_AUX1_SEL 0x10
- +/* SMB : I/O SPACE, REG : 8BITS WIDTH */
- +#define SMB_SDA 0x00
- +#define SMB_STS 0x01
- +#define SMB_STS_SLVSTP (1 << 7)
- +#define SMB_STS_SDAST (1 << 6)
- +#define SMB_STS_BER (1 << 5)
- +#define SMB_STS_NEGACK (1 << 4)
- +#define SMB_STS_STASTR (1 << 3)
- +#define SMB_STS_NMATCH (1 << 2)
- +#define SMB_STS_MASTER (1 << 1)
- +#define SMB_STS_XMIT (1 << 0)
- +#define SMB_CTRL_STS 0x02
- +#define SMB_CSTS_TGSTL (1 << 5)
- +#define SMB_CSTS_TSDA (1 << 4)
- +#define SMB_CSTS_GCMTCH (1 << 3)
- +#define SMB_CSTS_MATCH (1 << 2)
- +#define SMB_CSTS_BB (1 << 1)
- +#define SMB_CSTS_BUSY (1 << 0)
- +#define SMB_CTRL1 0x03
- +#define SMB_CTRL1_STASTRE (1 << 7)
- +#define SMB_CTRL1_NMINTE (1 << 6)
- +#define SMB_CTRL1_GCMEN (1 << 5)
- +#define SMB_CTRL1_ACK (1 << 4)
- +#define SMB_CTRL1_RSVD (1 << 3)
- +#define SMB_CTRL1_INTEN (1 << 2)
- +#define SMB_CTRL1_STOP (1 << 1)
- +#define SMB_CTRL1_START (1 << 0)
- +#define SMB_ADDR 0x04
- +#define SMB_ADDR_SAEN (1 << 7)
- +#define SMB_CONTROLLER_ADDR (0xef << 0)
- +#define SMB_CTRL2 0x05
- +#define SMB_FREQ (0x20 << 1)
- +#define SMB_ENABLE (0x01 << 0)
- +#define SMB_CTRL3 0x06
-
- #endif /* _CS5536_H */
- 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
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-03-06 16:43:00.000000000 +0100
- @@ -32,4 +32,9 @@
- #define MFGPT0_CNT (MFGPT_BASE + 4)
- #define MFGPT0_SETUP (MFGPT_BASE + 6)
-
- +#define MFGPT2_CMP1 (MFGPT_BASE + 0x10)
- +#define MFGPT2_CMP2 (MFGPT_BASE + 0x12)
- +#define MFGPT2_CNT (MFGPT_BASE + 0x14)
- +#define MFGPT2_SETUP (MFGPT_BASE + 0x16)
- +
- #endif /*!_CS5536_MFGPT_H */
- 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
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h 2010-03-06 16:43:00.000000000 +0100
- @@ -2,7 +2,7 @@
- * the read/write interfaces for Virtual Support Module(VSM)
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- */
-
- #ifndef _CS5536_VSM_H
- 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
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 2010-03-06 16:43:00.000000000 +0100
- @@ -0,0 +1,191 @@
- +/*
- + * KB3310B Embedded Controller
- + *
- + * Copyright (C) 2008 Lemote Inc.
- + * Author: liujl <liujl@lemote.com>, 2008-03-14
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef _EC_KB3310B_H
- +#define _EC_KB3310B_H
- +
- +extern unsigned char ec_read(unsigned short addr);
- +extern void ec_write(unsigned short addr, unsigned char val);
- +extern int ec_query_seq(unsigned char cmd);
- +extern int ec_query_event_num(void);
- +extern int ec_get_event_num(void);
- +
- +typedef int (*sci_handler) (int status);
- +extern sci_handler yeeloong_report_lid_status;
- +
- +#define SCI_IRQ_NUM 0x0A
- +
- +/*
- + * The following registers are determined by the EC index configuration.
- + * 1, fill the PORT_HIGH as EC register high part.
- + * 2, fill the PORT_LOW as EC register low part.
- + * 3, fill the PORT_DATA as EC register write data or get the data from it.
- + */
- +#define EC_IO_PORT_HIGH 0x0381
- +#define EC_IO_PORT_LOW 0x0382
- +#define EC_IO_PORT_DATA 0x0383
- +
- +/*
- + * EC delay time is 500us for register and status access
- + */
- +#define EC_REG_DELAY 500 /* unit : us */
- +#define EC_CMD_TIMEOUT 0x1000
- +
- +/*
- + * EC access port for SCI communication
- + */
- +#define EC_CMD_PORT 0x66
- +#define EC_STS_PORT 0x66
- +#define EC_DAT_PORT 0x62
- +#define CMD_INIT_IDLE_MODE 0xdd
- +#define CMD_EXIT_IDLE_MODE 0xdf
- +#define CMD_INIT_RESET_MODE 0xd8
- +#define CMD_REBOOT_SYSTEM 0x8c
- +#define CMD_GET_EVENT_NUM 0x84
- +#define CMD_PROGRAM_PIECE 0xda
- +
- +/* Temperature & Fan registers */
- +#define REG_TEMPERATURE_VALUE 0xF458
- +#define REG_FAN_AUTO_MAN_SWITCH 0xF459
- +#define BIT_FAN_AUTO 0
- +#define BIT_FAN_MANUAL 1
- +#define REG_FAN_CONTROL 0xF4D2
- +#define BIT_FAN_CONTROL_ON (1 << 0)
- +#define BIT_FAN_CONTROL_OFF (0 << 0)
- +#define REG_FAN_STATUS 0xF4DA
- +#define BIT_FAN_STATUS_ON (1 << 0)
- +#define BIT_FAN_STATUS_OFF (0 << 0)
- +#define REG_FAN_SPEED_HIGH 0xFE22
- +#define REG_FAN_SPEED_LOW 0xFE23
- +#define REG_FAN_SPEED_LEVEL 0xF4CC
- +/* Fan speed divider */
- +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
- +
- +/* Battery registers */
- +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
- +#define REG_BAT_DESIGN_CAP_LOW 0xF77E
- +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
- +#define REG_BAT_FULLCHG_CAP_LOW 0xF781
- +#define REG_BAT_DESIGN_VOL_HIGH 0xF782
- +#define REG_BAT_DESIGN_VOL_LOW 0xF783
- +#define REG_BAT_CURRENT_HIGH 0xF784
- +#define REG_BAT_CURRENT_LOW 0xF785
- +#define REG_BAT_VOLTAGE_HIGH 0xF786
- +#define REG_BAT_VOLTAGE_LOW 0xF787
- +#define REG_BAT_TEMPERATURE_HIGH 0xF788
- +#define REG_BAT_TEMPERATURE_LOW 0xF789
- +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
- +#define REG_BAT_RELATIVE_CAP_LOW 0xF493
- +#define REG_BAT_VENDOR 0xF4C4
- +#define FLAG_BAT_VENDOR_SANYO 0x01
- +#define FLAG_BAT_VENDOR_SIMPLO 0x02
- +#define REG_BAT_CELL_COUNT 0xF4C6
- +#define FLAG_BAT_CELL_3S1P 0x03
- +#define FLAG_BAT_CELL_3S2P 0x06
- +#define REG_BAT_CHARGE 0xF4A2
- +#define FLAG_BAT_CHARGE_DISCHARGE 0x01
- +#define FLAG_BAT_CHARGE_CHARGE 0x02
- +#define FLAG_BAT_CHARGE_ACPOWER 0x00
- +#define REG_BAT_STATUS 0xF4B0
- +#define BIT_BAT_STATUS_LOW (1 << 5)
- +#define BIT_BAT_STATUS_DESTROY (1 << 2)
- +#define BIT_BAT_STATUS_FULL (1 << 1)
- +#define BIT_BAT_STATUS_IN (1 << 0)
- +#define REG_BAT_CHARGE_STATUS 0xF4B1
- +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
- +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
- +#define REG_BAT_STATE 0xF482
- +#define BIT_BAT_STATE_CHARGING (1 << 1)
- +#define BIT_BAT_STATE_DISCHARGING (1 << 0)
- +#define REG_BAT_POWER 0xF440
- +#define BIT_BAT_POWER_S3 (1 << 2)
- +#define BIT_BAT_POWER_ON (1 << 1)
- +#define BIT_BAT_POWER_ACIN (1 << 0)
- +
- +/* Audio: rd/wr */
- +#define REG_AUDIO_VOLUME 0xF46C
- +#define REG_AUDIO_MUTE 0xF4E7
- +#define REG_AUDIO_BEEP 0xF4D0
- +/* USB port power or not: rd/wr */
- +#define REG_USB0_FLAG 0xF461
- +#define REG_USB1_FLAG 0xF462
- +#define REG_USB2_FLAG 0xF463
- +#define BIT_USB_FLAG_ON 1
- +#define BIT_USB_FLAG_OFF 0
- +/* LID */
- +#define REG_LID_DETECT 0xF4BD
- +#define BIT_LID_DETECT_ON 1
- +#define BIT_LID_DETECT_OFF 0
- +/* CRT */
- +#define REG_CRT_DETECT 0xF4AD
- +#define BIT_CRT_DETECT_PLUG 1
- +#define BIT_CRT_DETECT_UNPLUG 0
- +/* LCD backlight brightness adjust: 9 levels */
- +#define REG_DISPLAY_BRIGHTNESS 0xF4F5
- +/* Black screen Status */
- +#define BIT_DISPLAY_LCD_ON 1
- +#define BIT_DISPLAY_LCD_OFF 0
- +/* LCD backlight control: off/restore */
- +#define REG_BACKLIGHT_CTRL 0xF7BD
- +#define BIT_BACKLIGHT_ON 1
- +#define BIT_BACKLIGHT_OFF 0
- +/* Reset the machine auto-clear: rd/wr */
- +#define REG_RESET 0xF4EC
- +#define BIT_RESET_ON 1
- +/* Light the led: rd/wr */
- +#define REG_LED 0xF4C8
- +#define BIT_LED_RED_POWER (1 << 0)
- +#define BIT_LED_ORANGE_POWER (1 << 1)
- +#define BIT_LED_GREEN_CHARGE (1 << 2)
- +#define BIT_LED_RED_CHARGE (1 << 3)
- +#define BIT_LED_NUMLOCK (1 << 4)
- +/* Test led mode, all led on/off */
- +#define REG_LED_TEST 0xF4C2
- +#define BIT_LED_TEST_IN 1
- +#define BIT_LED_TEST_OUT 0
- +/* Camera on/off */
- +#define REG_CAMERA_STATUS 0xF46A
- +#define BIT_CAMERA_STATUS_ON 1
- +#define BIT_CAMERA_STATUS_OFF 0
- +#define REG_CAMERA_CONTROL 0xF7B7
- +#define BIT_CAMERA_CONTROL_OFF 0
- +#define BIT_CAMERA_CONTROL_ON 1
- +/* Wlan Status */
- +#define REG_WLAN 0xF4FA
- +#define BIT_WLAN_ON 1
- +#define BIT_WLAN_OFF 0
- +#define REG_DISPLAY_LCD 0xF79F
- +
- +/* SCI Event Number from EC */
- +enum {
- + EVENT_LID = 0x23, /* Turn on/off LID */
- + EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
- + EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
- + EVENT_OVERTEMP, /* Over-temperature happened */
- + EVENT_CRT_DETECT, /* CRT is connected */
- + EVENT_CAMERA, /* Camera on/off */
- + EVENT_USB_OC2, /* USB2 Over Current occurred */
- + EVENT_USB_OC0, /* USB0 Over Current occurred */
- + EVENT_BLACK_SCREEN, /* Turn on/off backlight */
- + EVENT_AUDIO_MUTE, /* Mute on/off */
- + EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
- + EVENT_AC_BAT, /* AC & Battery relative issue */
- + EVENT_AUDIO_VOLUME, /* Volume adjust */
- + EVENT_WLAN, /* Wlan on/off */
- +};
- +
- +#define EVENT_START EVENT_LID
- +#define EVENT_END EVENT_WLAN
- +
- +#endif /* !_EC_KB3310B_H */
- diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/loongson.h linux-lemote/arch/mips/include/asm/mach-loongson/loongson.h
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/loongson.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/loongson.h 2010-03-06 16:43:00.000000000 +0100
- @@ -1,12 +1,11 @@
- /*
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- - *
- */
-
- #ifndef __ASM_MACH_LOONGSON_LOONGSON_H
- @@ -23,7 +22,7 @@
- extern void mach_prepare_shutdown(void);
-
- /* environment arguments from bootloader */
- -extern unsigned long bus_clock, cpu_clock_freq;
- +extern unsigned long cpu_clock_freq;
- extern unsigned long memsize, highmemsize;
-
- /* loongson-specific command line, env and memory initialization */
- @@ -43,6 +42,12 @@
- #endif
- }
-
- +/*
- + * Copy kernel command line from arcs_cmdline
- + */
- +#include <asm/setup.h>
- +extern char loongson_cmdline[COMMAND_LINE_SIZE];
- +
- /* irq operation functions */
- extern void bonito_irqdispatch(void);
- extern void __init bonito_irq_init(void);
- diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/machine.h linux-lemote/arch/mips/include/asm/mach-loongson/machine.h
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/machine.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/machine.h 2010-03-06 16:43:00.000000000 +0100
- @@ -1,6 +1,6 @@
- /*
- - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Copyright (C) 2009 Lemote, Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/mem.h linux-lemote/arch/mips/include/asm/mach-loongson/mem.h
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/mem.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/mem.h 2010-03-06 16:43:00.000000000 +0100
- @@ -1,6 +1,6 @@
- /*
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/include/asm/mach-loongson/pci.h linux-lemote/arch/mips/include/asm/mach-loongson/pci.h
- --- linux-2.6.33/arch/mips/include/asm/mach-loongson/pci.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/mach-loongson/pci.h 2010-03-06 16:43:00.000000000 +0100
- @@ -1,23 +1,12 @@
- /*
- * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
- - * Copyright (c) 2009 Wu Zhangjin <wuzj@lemote.com>
- + * Copyright (c) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it
- * and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your
- * option) any later version.
- - *
- - * This program is distributed in the hope that it will be
- - * useful, but WITHOUT ANY WARRANTY; without even the implied
- - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- - * PURPOSE. See the GNU General Public License for more
- - * details.
- - *
- - * You should have received a copy of the GNU General Public
- - * License along with this program; if not, write to the Free
- - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
- - * 02139, USA.
- */
-
- #ifndef __ASM_MACH_LOONGSON_PCI_H_
- diff -Nur linux-2.6.33/arch/mips/include/asm/stackframe.h linux-lemote/arch/mips/include/asm/stackframe.h
- --- linux-2.6.33/arch/mips/include/asm/stackframe.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/include/asm/stackframe.h 2010-03-06 16:43:00.000000000 +0100
- @@ -121,6 +121,25 @@
- .endm
- #else
- .macro get_saved_sp /* Uniprocessor variation */
- + /*
- + * clear BTB(branch target buffer), forbid RAS(row address
- + * strobe) to make cpu execute predictively via
- + * loongson2-specific 64bit diagnostic register
- + */
- +#ifdef CONFIG_CPU_LOONGSON2F
- + move k0, ra
- + jal 1f
- + nop
- +1: jal 1f
- + nop
- +1: jal 1f
- + nop
- +1: jal 1f
- + nop
- +1: move ra, k0
- + li k0, 3
- + mtc0 k0, $22
- +#endif
- #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
- lui k1, %hi(kernelsp)
- #else
- diff -Nur linux-2.6.33/arch/mips/Kconfig linux-lemote/arch/mips/Kconfig
- --- linux-2.6.33/arch/mips/Kconfig 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/Kconfig 2010-03-06 16:42:59.000000000 +0100
- @@ -180,7 +180,7 @@
-
- config MACH_LOONGSON
- bool "Loongson family of machines"
- - select SYS_SUPPORTS_ZBOOT_UART16550
- + select SYS_SUPPORTS_ZBOOT
- help
- This enables the support of Loongson family of machines.
-
- @@ -1934,6 +1934,18 @@
- source "kernel/time/Kconfig"
-
- #
- +# High Resolution sched_clock() Configuration
- +#
- +
- +config CPU_HAS_FIXED_C0_COUNT
- + bool
- +
- +config CPU_SUPPORTS_HR_SCHED_CLOCK
- + bool
- + depends on CPU_HAS_FIXED_C0_COUNT || !CPU_FREQ
- + default y
- +
- +#
- # Timer Interrupt Frequency Configuration
- #
-
- diff -Nur linux-2.6.33/arch/mips/Kconfig.debug linux-lemote/arch/mips/Kconfig.debug
- --- linux-2.6.33/arch/mips/Kconfig.debug 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/Kconfig.debug 2010-03-06 16:42:59.000000000 +0100
- @@ -102,4 +102,22 @@
- arch/mips/include/asm/debug.h for debugging macros.
- If unsure, say N.
-
- +config DEBUG_ZBOOT
- + bool "Enable compressed kernel support debugging"
- + depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
- + help
- + If you want to add compressed kernel support to a new board, and the
- + board supports uart16550 compatible serial port, please select
- + SYS_SUPPORTS_ZBOOT_UART16550 for your board and enable this option to
- + debug it.
- +
- + If your board doesn't support uart16550 compatible serial port, you
- + can try to select SYS_SUPPORTS_ZBOOT and use the other methods to
- + debug it. for example, add a new serial port support just as
- + arch/mips/boot/compressed/uart-16550.c does.
- +
- + After the compressed kernel support works, please disable this option
- + to reduce the kernel image size and speed up the booting procedure a
- + little.
- +
- endmenu
- diff -Nur linux-2.6.33/arch/mips/kernel/cpufreq/loongson2_clock.c linux-lemote/arch/mips/kernel/cpufreq/loongson2_clock.c
- --- linux-2.6.33/arch/mips/kernel/cpufreq/loongson2_clock.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/kernel/cpufreq/loongson2_clock.c 2010-03-06 16:43:01.000000000 +0100
- @@ -164,3 +164,7 @@
- spin_unlock_irqrestore(&loongson2_wait_lock, flags);
- }
- EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
- +
- +MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
- +MODULE_DESCRIPTION("cpuclock driver of Loongson2F");
- +MODULE_LICENSE("GPL");
- diff -Nur linux-2.6.33/arch/mips/kernel/csrc-r4k.c linux-lemote/arch/mips/kernel/csrc-r4k.c
- --- linux-2.6.33/arch/mips/kernel/csrc-r4k.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/kernel/csrc-r4k.c 2010-03-06 16:43:01.000000000 +0100
- @@ -6,10 +6,66 @@
- * Copyright (C) 2007 by Ralf Baechle
- */
- #include <linux/clocksource.h>
- +#include <linux/cnt32_to_63.h>
- #include <linux/init.h>
- +#include <linux/timer.h>
-
- #include <asm/time.h>
-
- +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
- +/*
- + * MIPS sched_clock implementation.
- + *
- + * Because the hardware timer period is quite short and because cnt32_to_63()
- + * needs to be called at least once per half period to work properly, a kernel
- + * timer is set up to ensure this requirement is always met.
- + *
- + * Please refer to include/linux/cnt32_to_63.h and arch/arm/plat-orion/time.c
- + */
- +#define CLOCK2NS_SCALE_FACTOR 8
- +
- +static unsigned long clock2ns_scale __read_mostly;
- +
- +unsigned long long notrace sched_clock(void)
- +{
- + unsigned long long v = cnt32_to_63(read_c0_count());
- + return (v * clock2ns_scale) >> CLOCK2NS_SCALE_FACTOR;
- +}
- +
- +static struct timer_list cnt32_to_63_keepwarm_timer;
- +
- +static void cnt32_to_63_keepwarm(unsigned long data)
- +{
- + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
- + sched_clock();
- +}
- +#endif
- +
- +static inline void setup_hres_sched_clock(unsigned long clock)
- +{
- +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
- + unsigned long long v;
- + unsigned long data;
- +
- + v = NSEC_PER_SEC;
- + v <<= CLOCK2NS_SCALE_FACTOR;
- + v += clock/2;
- + do_div(v, clock);
- + /*
- + * We want an even value to automatically clear the top bit
- + * returned by cnt32_to_63() without an additional run time
- + * instruction. So if the LSB is 1 then round it up.
- + */
- + if (v & 1)
- + v++;
- + clock2ns_scale = v;
- +
- + data = 0x80000000UL / clock * HZ;
- + setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
- + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
- +#endif
- +}
- +
- static cycle_t c0_hpt_read(struct clocksource *cs)
- {
- return read_c0_count();
- @@ -27,6 +83,8 @@
- if (!cpu_has_counter || !mips_hpt_frequency)
- return -ENXIO;
-
- + setup_hres_sched_clock(mips_hpt_frequency);
- +
- /* Calculate a somewhat reasonable rating value */
- clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
-
- diff -Nur linux-2.6.33/arch/mips/kernel/ftrace.c linux-lemote/arch/mips/kernel/ftrace.c
- --- linux-2.6.33/arch/mips/kernel/ftrace.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/kernel/ftrace.c 2010-03-06 16:43:01.000000000 +0100
- @@ -3,7 +3,7 @@
- *
- * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
- * Copyright (C) 2009 DSLab, Lanzhou University, China
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * Thanks goes to Steven Rostedt for writing the original x86 version.
- */
- diff -Nur linux-2.6.33/arch/mips/kernel/mcount.S linux-lemote/arch/mips/kernel/mcount.S
- --- linux-2.6.33/arch/mips/kernel/mcount.S 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/kernel/mcount.S 2010-03-06 16:43:01.000000000 +0100
- @@ -6,7 +6,7 @@
- * more details.
- *
- * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- */
-
- #include <asm/regdef.h>
- diff -Nur linux-2.6.33/arch/mips/kernel/time.c linux-lemote/arch/mips/kernel/time.c
- --- linux-2.6.33/arch/mips/kernel/time.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/kernel/time.c 2010-03-06 16:43:01.000000000 +0100
- @@ -119,6 +119,11 @@
-
- void __init time_init(void)
- {
- +#ifdef CONFIG_HR_SCHED_CLOCK
- + if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
- + write_c0_count(0);
- +#endif
- +
- plat_time_init();
-
- if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cmdline.c linux-lemote/arch/mips/loongson/common/cmdline.c
- --- linux-2.6.33/arch/mips/loongson/common/cmdline.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cmdline.c 2010-03-06 16:43:01.000000000 +0100
- @@ -10,23 +10,27 @@
- * Author: Fuxin Zhang, zhangfx@lemote.com
- *
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
- +#include <linux/module.h>
- #include <asm/bootinfo.h>
-
- #include <loongson.h>
-
- -int prom_argc;
- -/* pmon passes arguments in 32bit pointers */
- -int *_prom_argv;
- +/* the kernel command line copied from arcs_cmdline */
- +char loongson_cmdline[COMMAND_LINE_SIZE];
- +EXPORT_SYMBOL(loongson_cmdline);
-
- void __init prom_init_cmdline(void)
- {
- + int prom_argc;
- + /* pmon passes arguments in 32bit pointers */
- + int *_prom_argv;
- int i;
- long l;
-
- @@ -51,4 +55,26 @@
- strcat(arcs_cmdline, " root=/dev/hda1");
-
- prom_init_machtype();
- +
- + /* append machine specific command line */
- + switch (mips_machtype) {
- + case MACH_LEMOTE_LL2F:
- + if ((strstr(arcs_cmdline, "video=")) == NULL)
- + strcat(arcs_cmdline, " video=sisfb:1360x768-16@60");
- + break;
- + case MACH_LEMOTE_FL2F:
- + if ((strstr(arcs_cmdline, "ide_core.ignore_cable=")) == NULL)
- + strcat(arcs_cmdline, " ide_core.ignore_cable=0");
- + break;
- + case MACH_LEMOTE_ML2F7:
- + /* Mengloong-2F has a 800x480 screen */
- + if ((strstr(arcs_cmdline, "vga=")) == NULL)
- + strcat(arcs_cmdline, " vga=0x313");
- + break;
- + default:
- + break;
- + }
- +
- + /* copy arcs_cmdline into loongson_cmdline */
- + strncpy(loongson_cmdline, arcs_cmdline, COMMAND_LINE_SIZE);
- }
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_acc.c
- --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-03-06 16:43:01.000000000 +0100
- @@ -5,7 +5,7 @@
- * Author : jlliu, liujl@lemote.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ehci.c
- --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-03-06 16:43:01.000000000 +0100
- @@ -5,7 +5,7 @@
- * Author : jlliu, liujl@lemote.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ide.c
- --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-03-06 16:43:01.000000000 +0100
- @@ -5,7 +5,7 @@
- * Author : jlliu, liujl@lemote.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_isa.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_isa.c
- --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-03-06 16:43:01.000000000 +0100
- @@ -5,7 +5,7 @@
- * Author : jlliu, liujl@lemote.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
- --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c 2010-03-06 16:43:01.000000000 +0100
- @@ -5,7 +5,7 @@
- * Author: Yanhua, yanh@lemote.com
- *
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu zhangjin, wuzj@lemote.com
- + * Author: Wu zhangjin, wuzhangjin@gmail.com
- *
- * Reference: AMD Geode(TM) CS5536 Companion Device Data Book
- *
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ohci.c
- --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-03-06 16:43:01.000000000 +0100
- @@ -5,7 +5,7 @@
- * Author : jlliu, liujl@lemote.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_pci.c linux-lemote/arch/mips/loongson/common/cs5536/cs5536_pci.c
- --- linux-2.6.33/arch/mips/loongson/common/cs5536/cs5536_pci.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/cs5536/cs5536_pci.c 2010-03-06 16:43:01.000000000 +0100
- @@ -5,7 +5,7 @@
- * Author : jlliu, liujl@lemote.com
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/early_printk.c linux-lemote/arch/mips/loongson/common/early_printk.c
- --- linux-2.6.33/arch/mips/loongson/common/early_printk.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/early_printk.c 2010-03-06 16:43:01.000000000 +0100
- @@ -2,7 +2,7 @@
- *
- * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
- * Copyright (c) 2009 Lemote Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/env.c linux-lemote/arch/mips/loongson/common/env.c
- --- linux-2.6.33/arch/mips/loongson/common/env.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/env.c 2010-03-06 16:43:01.000000000 +0100
- @@ -9,8 +9,8 @@
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- *
- - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- @@ -23,13 +23,10 @@
-
- #include <loongson.h>
-
- -unsigned long bus_clock, cpu_clock_freq;
- +unsigned long cpu_clock_freq;
- EXPORT_SYMBOL(cpu_clock_freq);
- unsigned long memsize, highmemsize;
-
- -/* pmon passes arguments in 32bit pointers */
- -int *_prom_envp;
- -
- #define parse_even_earlier(res, option, p) \
- do { \
- if (strncmp(option, (char *)p, strlen(option)) == 0) \
- @@ -39,6 +36,10 @@
-
- void __init prom_init_env(void)
- {
- + /* pmon passes arguments in 32bit pointers */
- + int *_prom_envp;
- + unsigned long bus_clock;
- + unsigned int processor_id;
- long l;
-
- /* firmware arguments are initialized in head.S */
- @@ -55,6 +56,22 @@
- }
- if (memsize == 0)
- memsize = 256;
- + if (bus_clock == 0)
- + bus_clock = 66000000;
- + if (cpu_clock_freq == 0) {
- + processor_id = (¤t_cpu_data)->processor_id;
- + switch (processor_id & PRID_REV_MASK) {
- + case PRID_REV_LOONGSON2E:
- + cpu_clock_freq = 533080000;
- + break;
- + case PRID_REV_LOONGSON2F:
- + cpu_clock_freq = 797000000;
- + break;
- + default:
- + cpu_clock_freq = 100000000;
- + break;
- + }
- + }
-
- pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n",
- bus_clock, cpu_clock_freq, memsize, highmemsize);
- diff -Nur linux-2.6.33/arch/mips/loongson/common/init.c linux-lemote/arch/mips/loongson/common/init.c
- --- linux-2.6.33/arch/mips/loongson/common/init.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/init.c 2010-03-06 16:43:01.000000000 +0100
- @@ -1,6 +1,6 @@
- /*
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/machtype.c linux-lemote/arch/mips/loongson/common/machtype.c
- --- linux-2.6.33/arch/mips/loongson/common/machtype.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/machtype.c 2010-03-06 16:43:01.000000000 +0100
- @@ -1,6 +1,6 @@
- /*
- - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org>
- *
- @@ -35,6 +35,10 @@
- return system_types[mips_machtype];
- }
-
- +void __weak __init mach_prom_init_machtype(void)
- +{
- +}
- +
- void __init prom_init_machtype(void)
- {
- char *p, str[MACHTYPE_LEN];
- @@ -43,8 +47,10 @@
- mips_machtype = LOONGSON_MACHTYPE;
-
- p = strstr(arcs_cmdline, "machtype=");
- - if (!p)
- + if (!p) {
- + mach_prom_init_machtype();
- return;
- + }
- p += strlen("machtype=");
- strncpy(str, p, MACHTYPE_LEN);
- p = strstr(str, " ");
- diff -Nur linux-2.6.33/arch/mips/loongson/common/Makefile linux-lemote/arch/mips/loongson/common/Makefile
- --- linux-2.6.33/arch/mips/loongson/common/Makefile 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/Makefile 2010-03-06 16:43:01.000000000 +0100
- @@ -23,3 +23,9 @@
- #
-
- obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
- +
- +# Enable RTC Class support
- +#
- +# please enable CONFIG_RTC_DRV_CMOS
- +#
- +obj-$(CONFIG_RTC_DRV_CMOS) += rtc.o
- diff -Nur linux-2.6.33/arch/mips/loongson/common/mem.c linux-lemote/arch/mips/loongson/common/mem.c
- --- linux-2.6.33/arch/mips/loongson/common/mem.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/mem.c 2010-03-06 16:43:01.000000000 +0100
- @@ -16,10 +16,11 @@
-
- void __init prom_init_memory(void)
- {
- - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
- + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
- +
- + add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
- + 20), BOOT_MEM_RESERVED);
-
- - add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
- - 20), BOOT_MEM_RESERVED);
- #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
- {
- int bit;
- diff -Nur linux-2.6.33/arch/mips/loongson/common/mtd.c linux-lemote/arch/mips/loongson/common/mtd.c
- --- linux-2.6.33/arch/mips/loongson/common/mtd.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/mtd.c 2010-03-06 16:43:01.000000000 +0100
- @@ -0,0 +1,91 @@
- +/*
- + * Driver for flushing/dumping ROM of PMON on loongson family machines
- + *
- + * Copyright (C) 2008-2009 Lemote Inc.
- + * Author: Yan Hua <yanh@lemote.com>
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + */
- +
- +#include <linux/module.h>
- +#include <linux/types.h>
- +#include <linux/kernel.h>
- +#include <linux/init.h>
- +#include <linux/mtd/mtd.h>
- +#include <linux/mtd/map.h>
- +#include <linux/mtd/partitions.h>
- +
- +#include <asm/io.h>
- +
- +#include <loongson.h>
- +
- +#define FLASH_PHYS_ADDR LOONGSON_BOOT_BASE
- +#define FLASH_SIZE 0x080000
- +
- +#define FLASH_PARTITION0_ADDR 0x00000000
- +#define FLASH_PARTITION0_SIZE 0x00080000
- +
- +struct map_info flash_map = {
- + .name = "flash device",
- + .size = FLASH_SIZE,
- + .bankwidth = 1,
- +};
- +
- +struct mtd_partition flash_parts[] = {
- + {
- + .name = "Bootloader",
- + .offset = FLASH_PARTITION0_ADDR,
- + .size = FLASH_PARTITION0_SIZE},
- +};
- +
- +#define PARTITION_COUNT ARRAY_SIZE(flash_parts)
- +
- +static struct mtd_info *mymtd;
- +
- +int __init init_flash(void)
- +{
- + printk(KERN_NOTICE "flash device: %x at %x\n",
- + FLASH_SIZE, FLASH_PHYS_ADDR);
- +
- + flash_map.phys = FLASH_PHYS_ADDR;
- + flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE);
- +
- + if (!flash_map.virt) {
- + printk(KERN_NOTICE "Failed to ioremap\n");
- + return -EIO;
- + }
- +
- + simple_map_init(&flash_map);
- +
- + mymtd = do_map_probe("cfi_probe", &flash_map);
- + if (mymtd) {
- + add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT);
- + printk(KERN_NOTICE "pmon flash device initialized\n");
- + return 0;
- + }
- +
- + iounmap((void *)flash_map.virt);
- + return -ENXIO;
- +}
- +
- +static void __exit cleanup_flash(void)
- +{
- + if (mymtd) {
- + del_mtd_partitions(mymtd);
- + map_destroy(mymtd);
- + }
- + if (flash_map.virt) {
- + iounmap((void *)flash_map.virt);
- + flash_map.virt = 0;
- + }
- +}
- +
- +module_init(init_flash);
- +module_exit(cleanup_flash);
- +
- +MODULE_LICENSE("GPL");
- +MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
- +MODULE_DESCRIPTION("MTD driver for pmon flushing/dumping");
- diff -Nur linux-2.6.33/arch/mips/loongson/common/platform.c linux-lemote/arch/mips/loongson/common/platform.c
- --- linux-2.6.33/arch/mips/loongson/common/platform.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/platform.c 2010-03-06 16:43:01.000000000 +0100
- @@ -1,6 +1,6 @@
- /*
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/pm.c linux-lemote/arch/mips/loongson/common/pm.c
- --- linux-2.6.33/arch/mips/loongson/common/pm.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/pm.c 2010-03-06 16:43:01.000000000 +0100
- @@ -2,7 +2,7 @@
- * loongson-specific suspend support
- *
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- diff -Nur linux-2.6.33/arch/mips/loongson/common/reset.c linux-lemote/arch/mips/loongson/common/reset.c
- --- linux-2.6.33/arch/mips/loongson/common/reset.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/reset.c 2010-03-06 16:43:01.000000000 +0100
- @@ -6,8 +6,8 @@
- *
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- - * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
- - * Author: Zhangjin Wu, wuzj@lemote.com
- + * Copyright (C) 2009 Lemote, Inc.
- + * Author: Zhangjin Wu, wuzhangjin@gmail.com
- */
- #include <linux/init.h>
- #include <linux/pm.h>
- @@ -21,22 +21,39 @@
- /* do preparation for reboot */
- mach_prepare_reboot();
-
- - /* reboot via jumping to boot base address */
- + /* reboot via jumping to boot base address
- + *
- + * ".set noat" and ".set at" are used to ensure the address not
- + * polluted by the binutils patch. the patch will try to change the
- + * jumping address to "addr & 0xcfffffff" via the at register, which is
- + * really wrong for 0xbfc00000:
- + */
- +
- + __asm__ __volatile__(".set noat\n");
- ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
- + __asm__ __volatile__(".set at\n");
- }
-
- -static void loongson_halt(void)
- +static void loongson_poweroff(void)
- {
- mach_prepare_shutdown();
- - while (1)
- - ;
- + unreachable();
- +}
- +
- +static void loongson_halt(void)
- +{
- + pr_notice("** You can safely turn off the power ** !\n");
- + while (1) {
- + if (cpu_wait)
- + cpu_wait();
- + }
- }
-
- static int __init mips_reboot_setup(void)
- {
- _machine_restart = loongson_restart;
- _machine_halt = loongson_halt;
- - pm_power_off = loongson_halt;
- + pm_power_off = loongson_poweroff;
-
- return 0;
- }
- diff -Nur linux-2.6.33/arch/mips/loongson/common/rtc.c linux-lemote/arch/mips/loongson/common/rtc.c
- --- linux-2.6.33/arch/mips/loongson/common/rtc.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/rtc.c 2010-03-06 16:43:01.000000000 +0100
- @@ -0,0 +1,43 @@
- +/*
- + * Registration of Loongson RTC platform device.
- + *
- + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
- + * Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#include <linux/init.h>
- +#include <linux/ioport.h>
- +#include <linux/mc146818rtc.h>
- +#include <linux/platform_device.h>
- +
- +static struct resource rtc_cmos_resource[] = {
- + {
- + .start = RTC_PORT(0),
- + .end = RTC_PORT(1),
- + .flags = IORESOURCE_IO,
- + },
- + {
- + .start = RTC_IRQ,
- + .end = RTC_IRQ,
- + .flags = IORESOURCE_IRQ,
- + },
- +};
- +
- +static struct platform_device rtc_cmos_device = {
- + .name = "rtc_cmos",
- + .id = -1,
- + .num_resources = ARRAY_SIZE(rtc_cmos_resource),
- + .resource = rtc_cmos_resource
- +};
- +
- +static __init int rtc_cmos_init(void)
- +{
- + return platform_device_register(&rtc_cmos_device);
- +}
- +
- +device_initcall(rtc_cmos_init);
- diff -Nur linux-2.6.33/arch/mips/loongson/common/serial.c linux-lemote/arch/mips/loongson/common/serial.c
- --- linux-2.6.33/arch/mips/loongson/common/serial.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/serial.c 2010-03-06 16:43:01.000000000 +0100
- @@ -7,7 +7,7 @@
- *
- * Copyright (C) 2009 Lemote, Inc.
- * Author: Yan hua (yanhua@lemote.com)
- - * Author: Wu Zhangjin (wuzj@lemote.com)
- + * Author: Wu Zhangjin (wuzhangjin@gmail.com)
- */
-
- #include <linux/io.h>
- diff -Nur linux-2.6.33/arch/mips/loongson/common/time.c linux-lemote/arch/mips/loongson/common/time.c
- --- linux-2.6.33/arch/mips/loongson/common/time.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/time.c 2010-03-06 16:43:01.000000000 +0100
- @@ -2,8 +2,8 @@
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- *
- - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/common/uart_base.c linux-lemote/arch/mips/loongson/common/uart_base.c
- --- linux-2.6.33/arch/mips/loongson/common/uart_base.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/common/uart_base.c 2010-03-06 16:43:01.000000000 +0100
- @@ -1,6 +1,6 @@
- /*
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/fuloong-2e/reset.c linux-lemote/arch/mips/loongson/fuloong-2e/reset.c
- --- linux-2.6.33/arch/mips/loongson/fuloong-2e/reset.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/fuloong-2e/reset.c 2010-03-06 16:43:01.000000000 +0100
- @@ -1,8 +1,8 @@
- /* Board-specific reboot/shutdown routines
- * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
- *
- - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.c
- --- linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-03-06 16:43:01.000000000 +0100
- @@ -14,7 +14,7 @@
- #include <linux/spinlock.h>
- #include <linux/delay.h>
-
- -#include "ec_kb3310b.h"
- +#include <ec_kb3310b.h>
-
- static DEFINE_SPINLOCK(index_access_lock);
- static DEFINE_SPINLOCK(port_access_lock);
- @@ -76,12 +76,9 @@
- }
-
- if (timeout <= 0) {
- - printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
- + pr_err("%s: deadable error : timeout...\n", __func__);
- ret = -EINVAL;
- - } else
- - printk(KERN_INFO
- - "(%x/%d)ec issued command %d status : 0x%x\n",
- - timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
- + }
-
- spin_unlock_irqrestore(&port_access_lock, flags);
-
- @@ -118,8 +115,7 @@
- udelay(EC_REG_DELAY);
- }
- if (timeout <= 0) {
- - pr_info("%s: get event number timeout.\n", __func__);
- -
- + pr_err("%s: get event number timeout.\n", __func__);
- return -EINVAL;
- }
- value = inb(EC_DAT_PORT);
- diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.h
- --- linux-2.6.33/arch/mips/loongson/lemote-2f/ec_kb3310b.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/lemote-2f/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
- @@ -1,188 +0,0 @@
- -/*
- - * KB3310B Embedded Controller
- - *
- - * Copyright (C) 2008 Lemote Inc.
- - * Author: liujl <liujl@lemote.com>, 2008-03-14
- - *
- - * This program is free software; you can redistribute it and/or modify
- - * it under the terms of the GNU General Public License as published by
- - * the Free Software Foundation; either version 2 of the License, or
- - * (at your option) any later version.
- - */
- -
- -#ifndef _EC_KB3310B_H
- -#define _EC_KB3310B_H
- -
- -extern unsigned char ec_read(unsigned short addr);
- -extern void ec_write(unsigned short addr, unsigned char val);
- -extern int ec_query_seq(unsigned char cmd);
- -extern int ec_query_event_num(void);
- -extern int ec_get_event_num(void);
- -
- -typedef int (*sci_handler) (int status);
- -extern sci_handler yeeloong_report_lid_status;
- -
- -#define SCI_IRQ_NUM 0x0A
- -
- -/*
- - * The following registers are determined by the EC index configuration.
- - * 1, fill the PORT_HIGH as EC register high part.
- - * 2, fill the PORT_LOW as EC register low part.
- - * 3, fill the PORT_DATA as EC register write data or get the data from it.
- - */
- -#define EC_IO_PORT_HIGH 0x0381
- -#define EC_IO_PORT_LOW 0x0382
- -#define EC_IO_PORT_DATA 0x0383
- -
- -/*
- - * EC delay time is 500us for register and status access
- - */
- -#define EC_REG_DELAY 500 /* unit : us */
- -#define EC_CMD_TIMEOUT 0x1000
- -
- -/*
- - * EC access port for SCI communication
- - */
- -#define EC_CMD_PORT 0x66
- -#define EC_STS_PORT 0x66
- -#define EC_DAT_PORT 0x62
- -#define CMD_INIT_IDLE_MODE 0xdd
- -#define CMD_EXIT_IDLE_MODE 0xdf
- -#define CMD_INIT_RESET_MODE 0xd8
- -#define CMD_REBOOT_SYSTEM 0x8c
- -#define CMD_GET_EVENT_NUM 0x84
- -#define CMD_PROGRAM_PIECE 0xda
- -
- -/* temperature & fan registers */
- -#define REG_TEMPERATURE_VALUE 0xF458
- -#define REG_FAN_AUTO_MAN_SWITCH 0xF459
- -#define BIT_FAN_AUTO 0
- -#define BIT_FAN_MANUAL 1
- -#define REG_FAN_CONTROL 0xF4D2
- -#define BIT_FAN_CONTROL_ON (1 << 0)
- -#define BIT_FAN_CONTROL_OFF (0 << 0)
- -#define REG_FAN_STATUS 0xF4DA
- -#define BIT_FAN_STATUS_ON (1 << 0)
- -#define BIT_FAN_STATUS_OFF (0 << 0)
- -#define REG_FAN_SPEED_HIGH 0xFE22
- -#define REG_FAN_SPEED_LOW 0xFE23
- -#define REG_FAN_SPEED_LEVEL 0xF4CC
- -/* fan speed divider */
- -#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
- -
- -/* battery registers */
- -#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
- -#define REG_BAT_DESIGN_CAP_LOW 0xF77E
- -#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
- -#define REG_BAT_FULLCHG_CAP_LOW 0xF781
- -#define REG_BAT_DESIGN_VOL_HIGH 0xF782
- -#define REG_BAT_DESIGN_VOL_LOW 0xF783
- -#define REG_BAT_CURRENT_HIGH 0xF784
- -#define REG_BAT_CURRENT_LOW 0xF785
- -#define REG_BAT_VOLTAGE_HIGH 0xF786
- -#define REG_BAT_VOLTAGE_LOW 0xF787
- -#define REG_BAT_TEMPERATURE_HIGH 0xF788
- -#define REG_BAT_TEMPERATURE_LOW 0xF789
- -#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
- -#define REG_BAT_RELATIVE_CAP_LOW 0xF493
- -#define REG_BAT_VENDOR 0xF4C4
- -#define FLAG_BAT_VENDOR_SANYO 0x01
- -#define FLAG_BAT_VENDOR_SIMPLO 0x02
- -#define REG_BAT_CELL_COUNT 0xF4C6
- -#define FLAG_BAT_CELL_3S1P 0x03
- -#define FLAG_BAT_CELL_3S2P 0x06
- -#define REG_BAT_CHARGE 0xF4A2
- -#define FLAG_BAT_CHARGE_DISCHARGE 0x01
- -#define FLAG_BAT_CHARGE_CHARGE 0x02
- -#define FLAG_BAT_CHARGE_ACPOWER 0x00
- -#define REG_BAT_STATUS 0xF4B0
- -#define BIT_BAT_STATUS_LOW (1 << 5)
- -#define BIT_BAT_STATUS_DESTROY (1 << 2)
- -#define BIT_BAT_STATUS_FULL (1 << 1)
- -#define BIT_BAT_STATUS_IN (1 << 0)
- -#define REG_BAT_CHARGE_STATUS 0xF4B1
- -#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
- -#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
- -#define REG_BAT_STATE 0xF482
- -#define BIT_BAT_STATE_CHARGING (1 << 1)
- -#define BIT_BAT_STATE_DISCHARGING (1 << 0)
- -#define REG_BAT_POWER 0xF440
- -#define BIT_BAT_POWER_S3 (1 << 2)
- -#define BIT_BAT_POWER_ON (1 << 1)
- -#define BIT_BAT_POWER_ACIN (1 << 0)
- -
- -/* other registers */
- -/* Audio: rd/wr */
- -#define REG_AUDIO_VOLUME 0xF46C
- -#define REG_AUDIO_MUTE 0xF4E7
- -#define REG_AUDIO_BEEP 0xF4D0
- -/* USB port power or not: rd/wr */
- -#define REG_USB0_FLAG 0xF461
- -#define REG_USB1_FLAG 0xF462
- -#define REG_USB2_FLAG 0xF463
- -#define BIT_USB_FLAG_ON 1
- -#define BIT_USB_FLAG_OFF 0
- -/* LID */
- -#define REG_LID_DETECT 0xF4BD
- -#define BIT_LID_DETECT_ON 1
- -#define BIT_LID_DETECT_OFF 0
- -/* CRT */
- -#define REG_CRT_DETECT 0xF4AD
- -#define BIT_CRT_DETECT_PLUG 1
- -#define BIT_CRT_DETECT_UNPLUG 0
- -/* LCD backlight brightness adjust: 9 levels */
- -#define REG_DISPLAY_BRIGHTNESS 0xF4F5
- -/* Black screen Status */
- -#define BIT_DISPLAY_LCD_ON 1
- -#define BIT_DISPLAY_LCD_OFF 0
- -/* LCD backlight control: off/restore */
- -#define REG_BACKLIGHT_CTRL 0xF7BD
- -#define BIT_BACKLIGHT_ON 1
- -#define BIT_BACKLIGHT_OFF 0
- -/* Reset the machine auto-clear: rd/wr */
- -#define REG_RESET 0xF4EC
- -#define BIT_RESET_ON 1
- -/* Light the led: rd/wr */
- -#define REG_LED 0xF4C8
- -#define BIT_LED_RED_POWER (1 << 0)
- -#define BIT_LED_ORANGE_POWER (1 << 1)
- -#define BIT_LED_GREEN_CHARGE (1 << 2)
- -#define BIT_LED_RED_CHARGE (1 << 3)
- -#define BIT_LED_NUMLOCK (1 << 4)
- -/* Test led mode, all led on/off */
- -#define REG_LED_TEST 0xF4C2
- -#define BIT_LED_TEST_IN 1
- -#define BIT_LED_TEST_OUT 0
- -/* Camera on/off */
- -#define REG_CAMERA_STATUS 0xF46A
- -#define BIT_CAMERA_STATUS_ON 1
- -#define BIT_CAMERA_STATUS_OFF 0
- -#define REG_CAMERA_CONTROL 0xF7B7
- -#define BIT_CAMERA_CONTROL_OFF 0
- -#define BIT_CAMERA_CONTROL_ON 1
- -/* Wlan Status */
- -#define REG_WLAN 0xF4FA
- -#define BIT_WLAN_ON 1
- -#define BIT_WLAN_OFF 0
- -#define REG_DISPLAY_LCD 0xF79F
- -
- -/* SCI Event Number from EC */
- -enum {
- - EVENT_LID = 0x23, /* LID open/close */
- - EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
- - EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
- - EVENT_OVERTEMP, /* Over-temperature happened */
- - EVENT_CRT_DETECT, /* CRT is connected */
- - EVENT_CAMERA, /* Camera on/off */
- - EVENT_USB_OC2, /* USB2 Over Current occurred */
- - EVENT_USB_OC0, /* USB0 Over Current occurred */
- - EVENT_BLACK_SCREEN, /* Turn on/off backlight */
- - EVENT_AUDIO_MUTE, /* Mute on/off */
- - EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
- - EVENT_AC_BAT, /* AC & Battery relative issue */
- - EVENT_AUDIO_VOLUME, /* Volume adjust */
- - EVENT_WLAN, /* Wlan on/off */
- - EVENT_END
- -};
- -
- -#endif /* !_EC_KB3310B_H */
- diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/machtype.c linux-lemote/arch/mips/loongson/lemote-2f/machtype.c
- --- linux-2.6.33/arch/mips/loongson/lemote-2f/machtype.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/lemote-2f/machtype.c 2010-03-06 16:43:01.000000000 +0100
- @@ -0,0 +1,45 @@
- +/*
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + */
- +#include <asm/bootinfo.h>
- +
- +#include <loongson.h>
- +
- +void __init mach_prom_init_machtype(void)
- +{
- + /* We share the same kernel image file among Lemote 2F family
- + * of machines, and provide the machtype= kernel command line
- + * to users to indicate their machine, this command line will
- + * be passed by the latest PMON automatically. and fortunately,
- + * up to now, we can get the machine type from the PMON_VER=
- + * commandline directly except the NAS machine, In the old
- + * machines, this will help the users a lot.
- + *
- + * If no "machtype=" passed, get machine type from "PMON_VER=".
- + * PMON_VER=LM8089 Lemote 8.9'' netbook
- + * LM8101 Lemote 10.1'' netbook
- + * (The above two netbooks have the same kernel support)
- + * LM6XXX Lemote FuLoong(2F) box series
- + * LM9XXX Lemote LynLoong PC series
- + */
- + if (strstr(arcs_cmdline, "PMON_VER=LM")) {
- + if (strstr(arcs_cmdline, "PMON_VER=LM8"))
- + mips_machtype = MACH_LEMOTE_YL2F89;
- + else if (strstr(arcs_cmdline, "PMON_VER=LM6"))
- + mips_machtype = MACH_LEMOTE_FL2F;
- + else if (strstr(arcs_cmdline, "PMON_VER=LM9"))
- + mips_machtype = MACH_LEMOTE_LL2F;
- + else
- + mips_machtype = MACH_LEMOTE_NAS;
- +
- + strcat(arcs_cmdline, " machtype=");
- + strcat(arcs_cmdline, get_system_type());
- + strcat(arcs_cmdline, " ");
- + }
- +}
- diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/Makefile linux-lemote/arch/mips/loongson/lemote-2f/Makefile
- --- linux-2.6.33/arch/mips/loongson/lemote-2f/Makefile 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/lemote-2f/Makefile 2010-03-06 16:43:01.000000000 +0100
- @@ -2,7 +2,7 @@
- # Makefile for lemote loongson2f family machines
- #
-
- -obj-y += irq.o reset.o ec_kb3310b.o
- +obj-y += machtype.o irq.o reset.o ec_kb3310b.o platform.o
-
- #
- # Suspend Support
- diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/platform.c linux-lemote/arch/mips/loongson/lemote-2f/platform.c
- --- linux-2.6.33/arch/mips/loongson/lemote-2f/platform.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/lemote-2f/platform.c 2010-03-06 16:43:01.000000000 +0100
- @@ -0,0 +1,48 @@
- +/*
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + */
- +
- +#include <linux/err.h>
- +#include <linux/platform_device.h>
- +
- +#include <asm/bootinfo.h>
- +
- +static struct platform_device yeeloong_pdev = {
- + .name = "yeeloong_laptop",
- + .id = -1,
- +};
- +
- +static struct platform_device lynloong_pdev = {
- + .name = "lynloong_pc",
- + .id = -1,
- +};
- +
- +static int __init lemote2f_platform_init(void)
- +{
- + struct platform_device *pdev = NULL;
- +
- + switch (mips_machtype) {
- + case MACH_LEMOTE_YL2F89:
- + pdev = &yeeloong_pdev;
- + break;
- + case MACH_LEMOTE_LL2F:
- + pdev = &lynloong_pdev;
- + break;
- + default:
- + break;
- +
- + }
- +
- + if (pdev != NULL)
- + return platform_device_register(pdev);
- +
- + return -ENODEV;
- +}
- +
- +arch_initcall(lemote2f_platform_init);
- diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/pm.c linux-lemote/arch/mips/loongson/lemote-2f/pm.c
- --- linux-2.6.33/arch/mips/loongson/lemote-2f/pm.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/lemote-2f/pm.c 2010-03-06 16:43:01.000000000 +0100
- @@ -2,7 +2,7 @@
- * Lemote loongson2f family machines' specific suspend support
- *
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- @@ -23,7 +23,7 @@
- #include <loongson.h>
-
- #include <cs5536/cs5536_mfgpt.h>
- -#include "ec_kb3310b.h"
- +#include <ec_kb3310b.h>
-
- #define I8042_KBD_IRQ 1
- #define I8042_CTR_KBDINT 0x01
- @@ -100,7 +100,7 @@
- if (irq < 0)
- return 0;
-
- - printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
- + pr_info("%s: irq = %d\n", __func__, irq);
-
- if (irq == I8042_KBD_IRQ)
- return 1;
- diff -Nur linux-2.6.33/arch/mips/loongson/lemote-2f/reset.c linux-lemote/arch/mips/loongson/lemote-2f/reset.c
- --- linux-2.6.33/arch/mips/loongson/lemote-2f/reset.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/loongson/lemote-2f/reset.c 2010-03-06 16:43:01.000000000 +0100
- @@ -3,7 +3,7 @@
- * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
- *
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- @@ -20,7 +20,7 @@
- #include <loongson.h>
-
- #include <cs5536/cs5536.h>
- -#include "ec_kb3310b.h"
- +#include <ec_kb3310b.h>
-
- static void reset_cpu(void)
- {
- @@ -32,6 +32,7 @@
- }
-
- /* reset support for fuloong2f */
- +DEFINE_SPINLOCK(msr_lock);
-
- static void fl2f_reboot(void)
- {
- @@ -46,9 +47,13 @@
- */
- {
- u32 hi, lo;
- + unsigned long flags;
- +
- + spin_lock_irqsave(&msr_lock, flags);
- _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
- lo |= 0x00000001;
- _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
- + spin_unlock_irqrestore(&msr_lock, flags);
- }
- }
-
- @@ -56,9 +61,13 @@
- {
- u32 hi, lo, val;
- int gpio_base;
- + unsigned long flags;
-
- /* get gpio base */
- + spin_lock_irqsave(&msr_lock, flags);
- _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
- + spin_unlock_irqrestore(&msr_lock, flags);
- +
- gpio_base = lo & 0xff00;
-
- /* make cs5536 gpio13 output enable */
- diff -Nur linux-2.6.33/arch/mips/Makefile linux-lemote/arch/mips/Makefile
- --- linux-2.6.33/arch/mips/Makefile 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/Makefile 2010-03-06 16:42:59.000000000 +0100
- @@ -135,7 +135,10 @@
- cflags-$(CONFIG_CPU_LOONGSON2E) += \
- $(call cc-option,-march=loongson2e,-march=r4600)
- cflags-$(CONFIG_CPU_LOONGSON2F) += \
- - $(call cc-option,-march=loongson2f,-march=r4600)
- + $(call cc-option,-march=loongson2f,-march=r4600) \
- + $(call as-option,-Wa$(comma)-mfix-ls2f-kernel,) \
- + $(call as-option,-Wa$(comma)-mfix-loongson2f-nop,) \
- + $(call as-option,-Wa$(comma)-mfix-loongson2f-jump,)
-
- cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
- -Wa,-mips32 -Wa,--trap
- @@ -332,11 +335,11 @@
- #
- # Loongson family
- #
- -core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/
- +core-$(CONFIG_MACH_LOONGSON) += arch/mips/loongson/
- cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
- -mno-branch-likely
- -load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
- -load-$(CONFIG_LEMOTE_MACH2F) +=0xffffffff80200000
- +load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
- +load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
-
- #
- # MIPS Malta board
- diff -Nur linux-2.6.33/arch/mips/oprofile/common.c linux-lemote/arch/mips/oprofile/common.c
- --- linux-2.6.33/arch/mips/oprofile/common.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/oprofile/common.c 2010-03-06 16:43:01.000000000 +0100
- @@ -14,9 +14,9 @@
-
- #include "op_impl.h"
-
- -extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak));
- -extern struct op_mips_model op_model_rm9000_ops __attribute__((weak));
- -extern struct op_mips_model op_model_loongson2_ops __attribute__((weak));
- +extern struct op_mips_model op_model_mipsxx_ops __weak;
- +extern struct op_mips_model op_model_rm9000_ops __weak;
- +extern struct op_mips_model op_model_loongson2_ops __weak;
-
- static struct op_mips_model *model;
-
- diff -Nur linux-2.6.33/arch/mips/oprofile/op_model_loongson2.c linux-lemote/arch/mips/oprofile/op_model_loongson2.c
- --- linux-2.6.33/arch/mips/oprofile/op_model_loongson2.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/oprofile/op_model_loongson2.c 2010-03-06 16:43:01.000000000 +0100
- @@ -3,7 +3,7 @@
- *
- * Copyright (C) 2009 Lemote Inc.
- * Author: Yanhua <yanh@lemote.com>
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- diff -Nur linux-2.6.33/arch/mips/pci/fixup-lemote2f.c linux-lemote/arch/mips/pci/fixup-lemote2f.c
- --- linux-2.6.33/arch/mips/pci/fixup-lemote2f.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/pci/fixup-lemote2f.c 2010-03-06 16:43:01.000000000 +0100
- @@ -131,7 +131,7 @@
-
- /* Serial short detect enable */
- _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
- - _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 2) | (1 << 3), lo);
- + _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo);
-
- /* setting the USB2.0 micro frame length */
- pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
- diff -Nur linux-2.6.33/arch/mips/pci/ops-loongson2.c linux-lemote/arch/mips/pci/ops-loongson2.c
- --- linux-2.6.33/arch/mips/pci/ops-loongson2.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/pci/ops-loongson2.c 2010-03-06 16:43:01.000000000 +0100
- @@ -1,13 +1,11 @@
- /*
- - * fuloong2e specific PCI support.
- - *
- * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
- * All rights reserved.
- * Authors: Carsten Langgaard <carstenl@mips.com>
- * Maciej W. Rozycki <macro@mips.com>
- *
- * Copyright (C) 2009 Lemote Inc.
- - * Author: Wu Zhangjin <wuzj@lemote.com>
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- diff -Nur linux-2.6.33/arch/mips/power/cpu.c linux-lemote/arch/mips/power/cpu.c
- --- linux-2.6.33/arch/mips/power/cpu.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/power/cpu.c 2010-03-06 16:43:01.000000000 +0100
- @@ -3,9 +3,9 @@
- *
- * Licensed under the GPLv2
- *
- - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- + * Copyright (C) 2009 Lemote Inc.
- * Author: Hu Hongbing <huhb@lemote.com>
- - * Wu Zhangjin <wuzj@lemote.com>
- + * Wu Zhangjin <wuzhangjin@gmail.com>
- */
- #include <asm/suspend.h>
- #include <asm/fpu.h>
- diff -Nur linux-2.6.33/arch/mips/power/hibernate.S linux-lemote/arch/mips/power/hibernate.S
- --- linux-2.6.33/arch/mips/power/hibernate.S 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/mips/power/hibernate.S 2010-03-06 16:43:01.000000000 +0100
- @@ -3,9 +3,9 @@
- *
- * Licensed under the GPLv2
- *
- - * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
- + * Copyright (C) 2009 Lemote Inc.
- * Author: Hu Hongbing <huhb@lemote.com>
- - * Wu Zhangjin <wuzj@lemote.com>
- + * Wu Zhangjin <wuzhangjin@gmail.com>
- */
- #include <asm/asm-offsets.h>
- #include <asm/page.h>
- diff -Nur linux-2.6.33/arch/powerpc/include/asm/prom.h linux-lemote/arch/powerpc/include/asm/prom.h
- --- linux-2.6.33/arch/powerpc/include/asm/prom.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/arch/powerpc/include/asm/prom.h 2010-03-06 16:43:03.000000000 +0100
- @@ -23,21 +23,8 @@
- #include <asm/irq.h>
- #include <asm/atomic.h>
-
- -#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
- -#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
- -
- -#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
- -#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
- -#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
- -
- -extern struct device_node *of_chosen;
- -
- #define HAVE_ARCH_DEVTREE_FIXUPS
-
- -/* For updating the device tree at runtime */
- -extern void of_attach_node(struct device_node *);
- -extern void of_detach_node(struct device_node *);
- -
- #ifdef CONFIG_PPC32
- /*
- * PCI <-> OF matching functions
- @@ -52,11 +39,6 @@
- extern void pci_create_OF_bus_map(void);
- #endif
-
- -extern struct resource *request_OF_resource(struct device_node* node,
- - int index, const char* name_postfix);
- -extern int release_OF_resource(struct device_node* node, int index);
- -
- -
- /*
- * OF address retreival & translation
- */
- diff -Nur linux-2.6.33/drivers/ide/ide-iops.c linux-lemote/drivers/ide/ide-iops.c
- --- linux-2.6.33/drivers/ide/ide-iops.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/ide/ide-iops.c 2010-03-06 16:43:16.000000000 +0100
- @@ -27,6 +27,8 @@
- #include <asm/uaccess.h>
- #include <asm/io.h>
-
- +#include <asm/bootinfo.h>
- +
- void SELECT_MASK(ide_drive_t *drive, int mask)
- {
- const struct ide_port_ops *port_ops = drive->hwif->port_ops;
- @@ -300,6 +302,9 @@
- {
- const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
-
- + if (mips_machtype != MACH_LEMOTE_YL2F89)
- + return;
- +
- for (list = nien_quirk_list; *list != NULL; list++)
- if (strstr(m, *list) != NULL) {
- drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
- diff -Nur linux-2.6.33/drivers/net/wireless/Kconfig linux-lemote/drivers/net/wireless/Kconfig
- --- linux-2.6.33/drivers/net/wireless/Kconfig 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/Kconfig 2010-03-06 16:43:20.000000000 +0100
- @@ -267,7 +267,7 @@
-
- config RTL8187
- tristate "Realtek 8187 and 8187B USB support"
- - depends on MAC80211 && USB
- + depends on MAC80211 && USB && !LEMOTE_MACH2F
- select EEPROM_93CX6
- ---help---
- This is a driver for RTL8187 and RTL8187B based cards.
- @@ -294,6 +294,19 @@
- depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
- default y
-
- +config RTL8187B
- + tristate "Realtek 8187B wifi support for yeeloong2f laptop"
- + depends on MAC80211 && USB && LEMOTE_MACH2F
- + depends on RFKILL || !RFKILL
- + select CRYPTO
- + select WIRELESS_EXT
- + select WEXT_PRIV
- + ---help---
- + This is a driver for RTL8187B based cards, this driver is especially
- + for yeeloon2f laptop.
- +
- + Thanks to Realtek for their support!
- +
- config ADM8211
- tristate "ADMtek ADM8211 support"
- depends on MAC80211 && PCI && EXPERIMENTAL
- diff -Nur linux-2.6.33/drivers/net/wireless/Makefile linux-lemote/drivers/net/wireless/Makefile
- --- linux-2.6.33/drivers/net/wireless/Makefile 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/Makefile 2010-03-06 16:43:20.000000000 +0100
- @@ -24,6 +24,7 @@
- obj-$(CONFIG_ZD1211RW) += zd1211rw/
- obj-$(CONFIG_RTL8180) += rtl818x/
- obj-$(CONFIG_RTL8187) += rtl818x/
- +obj-$(CONFIG_RTL8187B) += rtl8187b/
-
- # 16-bit wireless PCMCIA client drivers
- obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/dot11d.h linux-lemote/drivers/net/wireless/rtl8187b/dot11d.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/dot11d.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/dot11d.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,102 @@
- +#ifndef __INC_DOT11D_H
- +#define __INC_DOT11D_H
- +
- +#include "ieee80211/ieee80211.h"
- +
- +//#define ENABLE_DOT11D
- +
- +//#define DOT11D_MAX_CHNL_NUM 83
- +
- +typedef struct _CHNL_TXPOWER_TRIPLE {
- + u8 FirstChnl;
- + u8 NumChnls;
- + u8 MaxTxPowerInDbm;
- +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
- +
- +typedef enum _DOT11D_STATE {
- + DOT11D_STATE_NONE = 0,
- + DOT11D_STATE_LEARNED,
- + DOT11D_STATE_DONE,
- +}DOT11D_STATE;
- +
- +typedef struct _RT_DOT11D_INFO {
- + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
- +
- + bool bEnabled; // dot11MultiDomainCapabilityEnabled
- +
- + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- + u8 CountryIeBuf[MAX_IE_LEN];
- + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- + u8 CountryIeWatchdog;
- +
- + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
- + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
- + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
- +
- + DOT11D_STATE State;
- +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
- +#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 )
- +#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])
- +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
- +
- +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
- +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
- +
- +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
- +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
- +
- +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- + FALSE : \
- + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
- +
- +#define CIE_WATCHDOG_TH 1
- +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
- +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
- +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
- +
- +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
- +
- +
- +void
- +Dot11d_Init(
- + struct ieee80211_device *dev
- + );
- +
- +void
- +Dot11d_Reset(
- + struct ieee80211_device *dev
- + );
- +
- +void
- +Dot11d_UpdateCountryIe(
- + struct ieee80211_device *dev,
- + u8 * pTaddr,
- + u16 CoutryIeLen,
- + u8 * pCoutryIe
- + );
- +
- +u8
- +DOT11D_GetMaxTxPwrInDbm(
- + struct ieee80211_device *dev,
- + u8 Channel
- + );
- +
- +void
- +DOT11D_ScanComplete(
- + struct ieee80211_device * dev
- + );
- +
- +int IsLegalChannel(
- + struct ieee80211_device * dev,
- + u8 channel
- +);
- +
- +int ToLegalChannel(
- + struct ieee80211_device * dev,
- + u8 channel
- +);
- +
- +void dump_chnl_map(u8 * channel_map);
- +#endif // #ifndef __INC_DOT11D_H
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/arc4.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/arc4.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,103 @@
- +/*
- + * Cryptographic API
- + *
- + * ARC4 Cipher Algorithm
- + *
- + * Jon Oberheide <jon@oberheide.org>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + *
- + */
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include "rtl_crypto.h"
- +
- +#define ARC4_MIN_KEY_SIZE 1
- +#define ARC4_MAX_KEY_SIZE 256
- +#define ARC4_BLOCK_SIZE 1
- +
- +struct arc4_ctx {
- + u8 S[256];
- + u8 x, y;
- +};
- +
- +static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
- +{
- + struct arc4_ctx *ctx = ctx_arg;
- + int i, j = 0, k = 0;
- +
- + ctx->x = 1;
- + ctx->y = 0;
- +
- + for(i = 0; i < 256; i++)
- + ctx->S[i] = i;
- +
- + for(i = 0; i < 256; i++)
- + {
- + u8 a = ctx->S[i];
- + j = (j + in_key[k] + a) & 0xff;
- + ctx->S[i] = ctx->S[j];
- + ctx->S[j] = a;
- + if(++k >= key_len)
- + k = 0;
- + }
- +
- + return 0;
- +}
- +
- +static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
- +{
- + struct arc4_ctx *ctx = ctx_arg;
- +
- + u8 *const S = ctx->S;
- + u8 x = ctx->x;
- + u8 y = ctx->y;
- + u8 a, b;
- +
- + a = S[x];
- + y = (y + a) & 0xff;
- + b = S[y];
- + S[x] = b;
- + S[y] = a;
- + x = (x + 1) & 0xff;
- + *out++ = *in ^ S[(a + b) & 0xff];
- +
- + ctx->x = x;
- + ctx->y = y;
- +}
- +
- +static struct crypto_alg arc4_alg = {
- + .cra_name = "arc4",
- + .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
- + .cra_blocksize = ARC4_BLOCK_SIZE,
- + .cra_ctxsize = sizeof(struct arc4_ctx),
- + .cra_module = THIS_MODULE,
- + .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
- + .cra_u = { .cipher = {
- + .cia_min_keysize = ARC4_MIN_KEY_SIZE,
- + .cia_max_keysize = ARC4_MAX_KEY_SIZE,
- + .cia_setkey = arc4_set_key,
- + .cia_encrypt = arc4_crypt,
- + .cia_decrypt = arc4_crypt } }
- +};
- +
- +static int __init arc4_init(void)
- +{
- + return crypto_register_alg(&arc4_alg);
- +}
- +
- +
- +static void __exit arc4_exit(void)
- +{
- + crypto_unregister_alg(&arc4_alg);
- +}
- +
- +module_init(arc4_init);
- +module_exit(arc4_exit);
- +
- +MODULE_LICENSE("GPL");
- +MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
- +MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,244 @@
- +#ifdef ENABLE_DOT11D
- +//-----------------------------------------------------------------------------
- +// File:
- +// Dot11d.c
- +//
- +// Description:
- +// Implement 802.11d.
- +//
- +//-----------------------------------------------------------------------------
- +
- +#include "dot11d.h"
- +
- +void
- +Dot11d_Init(struct ieee80211_device *ieee)
- +{
- + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
- +
- + pDot11dInfo->bEnabled = 0;
- +
- + pDot11dInfo->State = DOT11D_STATE_NONE;
- + pDot11dInfo->CountryIeLen = 0;
- + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- + RESET_CIE_WATCHDOG(ieee);
- +
- + //printk("Dot11d_Init()\n");
- +}
- +
- +//
- +// Description:
- +// Reset to the state as we are just entering a regulatory domain.
- +//
- +void
- +Dot11d_Reset(struct ieee80211_device *ieee)
- +{
- + u32 i;
- + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
- +
- + // Clear old channel map
- + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- + // Set new channel map
- + for (i=1; i<=11; i++) {
- + (pDot11dInfo->channel_map)[i] = 1;
- + }
- + for (i=12; i<=14; i++) {
- + (pDot11dInfo->channel_map)[i] = 2;
- + }
- +
- + pDot11dInfo->State = DOT11D_STATE_NONE;
- + pDot11dInfo->CountryIeLen = 0;
- + RESET_CIE_WATCHDOG(ieee);
- +
- + //printk("Dot11d_Reset()\n");
- +}
- +
- +//
- +// Description:
- +// Update country IE from Beacon or Probe Resopnse
- +// and configure PHY for operation in the regulatory domain.
- +//
- +// TODO:
- +// Configure Tx power.
- +//
- +// Assumption:
- +// 1. IS_DOT11D_ENABLE() is TRUE.
- +// 2. Input IE is an valid one.
- +//
- +void
- +Dot11d_UpdateCountryIe(
- + struct ieee80211_device *dev,
- + u8 * pTaddr,
- + u16 CoutryIeLen,
- + u8 * pCoutryIe
- + )
- +{
- + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- + u8 i, j, NumTriples, MaxChnlNum;
- + PCHNL_TXPOWER_TRIPLE pTriple;
- +
- + if((CoutryIeLen - 3)%3 != 0)
- + {
- + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- + Dot11d_Reset(dev);
- + return;
- + }
- +
- + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- + MaxChnlNum = 0;
- + NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
- + pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
- + for(i = 0; i < NumTriples; i++)
- + {
- + if(MaxChnlNum >= pTriple->FirstChnl)
- + { // It is not in a monotonically increasing order, so stop processing.
- + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- + Dot11d_Reset(dev);
- + return;
- + }
- + if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
- + { // It is not a valid set of channel id, so stop processing.
- + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
- + Dot11d_Reset(dev);
- + return;
- + }
- +
- + for(j = 0 ; j < pTriple->NumChnls; j++)
- + {
- + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
- + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
- + MaxChnlNum = pTriple->FirstChnl + j;
- + }
- +
- + pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
- + }
- +#if 1
- + //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
- + printk("Channel List:");
- + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
- + if(pDot11dInfo->channel_map[i] > 0)
- + printk(" %d", i);
- + printk("\n");
- +#endif
- +
- + UPDATE_CIE_SRC(dev, pTaddr);
- +
- + pDot11dInfo->CountryIeLen = CoutryIeLen;
- + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
- + pDot11dInfo->State = DOT11D_STATE_LEARNED;
- +}
- +
- +void dump_chnl_map(u8 * channel_map)
- +{
- + int i;
- + printk("Channel List:");
- + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
- + if(channel_map[i] > 0)
- + printk(" %d(%d)", i, channel_map[i]);
- + printk("\n");
- +}
- +
- +u8
- +DOT11D_GetMaxTxPwrInDbm(
- + struct ieee80211_device *dev,
- + u8 Channel
- + )
- +{
- + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- + u8 MaxTxPwrInDbm = 255;
- +
- + if(MAX_CHANNEL_NUMBER < Channel)
- + {
- + printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
- + return MaxTxPwrInDbm;
- + }
- + if(pDot11dInfo->channel_map[Channel])
- + {
- + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
- + }
- +
- + return MaxTxPwrInDbm;
- +}
- +
- +
- +void
- +DOT11D_ScanComplete(
- + struct ieee80211_device * dev
- + )
- +{
- + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- +
- + switch(pDot11dInfo->State)
- + {
- + case DOT11D_STATE_LEARNED:
- + pDot11dInfo->State = DOT11D_STATE_DONE;
- + break;
- +
- + case DOT11D_STATE_DONE:
- + if( GET_CIE_WATCHDOG(dev) == 0 )
- + { // Reset country IE if previous one is gone.
- + Dot11d_Reset(dev);
- + }
- + break;
- + case DOT11D_STATE_NONE:
- + break;
- + }
- +}
- +
- +int IsLegalChannel(
- + struct ieee80211_device * dev,
- + u8 channel
- +)
- +{
- + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- +
- + if(MAX_CHANNEL_NUMBER < channel)
- + {
- + printk("IsLegalChannel(): Invalid Channel\n");
- + return 0;
- + }
- + if(pDot11dInfo->channel_map[channel] > 0)
- + return 1;
- + return 0;
- +}
- +
- +int ToLegalChannel(
- + struct ieee80211_device * dev,
- + u8 channel
- +)
- +{
- + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- + u8 default_chn = 0;
- + u32 i = 0;
- +
- + for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
- + {
- + if(pDot11dInfo->channel_map[i] > 0)
- + {
- + default_chn = i;
- + break;
- + }
- + }
- +
- + if(MAX_CHANNEL_NUMBER < channel)
- + {
- + printk("IsLegalChannel(): Invalid Channel\n");
- + return default_chn;
- + }
- +
- + if(pDot11dInfo->channel_map[channel] > 0)
- + return channel;
- +
- + return default_chn;
- +}
- +
- +EXPORT_SYMBOL(Dot11d_Init);
- +EXPORT_SYMBOL(Dot11d_Reset);
- +EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
- +EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
- +EXPORT_SYMBOL(DOT11D_ScanComplete);
- +EXPORT_SYMBOL(IsLegalChannel);
- +EXPORT_SYMBOL(ToLegalChannel);
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,102 @@
- +#ifndef __INC_DOT11D_H
- +#define __INC_DOT11D_H
- +
- +#include "ieee80211.h"
- +
- +//#define ENABLE_DOT11D
- +
- +//#define DOT11D_MAX_CHNL_NUM 83
- +
- +typedef struct _CHNL_TXPOWER_TRIPLE {
- + u8 FirstChnl;
- + u8 NumChnls;
- + u8 MaxTxPowerInDbm;
- +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
- +
- +typedef enum _DOT11D_STATE {
- + DOT11D_STATE_NONE = 0,
- + DOT11D_STATE_LEARNED,
- + DOT11D_STATE_DONE,
- +}DOT11D_STATE;
- +
- +typedef struct _RT_DOT11D_INFO {
- + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
- +
- + bool bEnabled; // dot11MultiDomainCapabilityEnabled
- +
- + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- + u8 CountryIeBuf[MAX_IE_LEN];
- + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- + u8 CountryIeWatchdog;
- +
- + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
- + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
- + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
- +
- + DOT11D_STATE State;
- +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
- +#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 )
- +#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])
- +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
- +
- +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
- +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
- +
- +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
- +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
- +
- +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- + FALSE : \
- + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
- +
- +#define CIE_WATCHDOG_TH 1
- +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
- +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
- +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
- +
- +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
- +
- +
- +void
- +Dot11d_Init(
- + struct ieee80211_device *dev
- + );
- +
- +void
- +Dot11d_Reset(
- + struct ieee80211_device *dev
- + );
- +
- +void
- +Dot11d_UpdateCountryIe(
- + struct ieee80211_device *dev,
- + u8 * pTaddr,
- + u16 CoutryIeLen,
- + u8 * pCoutryIe
- + );
- +
- +u8
- +DOT11D_GetMaxTxPwrInDbm(
- + struct ieee80211_device *dev,
- + u8 Channel
- + );
- +
- +void
- +DOT11D_ScanComplete(
- + struct ieee80211_device * dev
- + );
- +
- +int IsLegalChannel(
- + struct ieee80211_device * dev,
- + u8 channel
- +);
- +
- +int ToLegalChannel(
- + struct ieee80211_device * dev,
- + u8 channel
- +);
- +
- +void dump_chnl_map(u8 * channel_map);
- +#endif // #ifndef __INC_DOT11D_H
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,275 @@
- +/*
- + * Host AP crypto routines
- + *
- + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- + * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation. See README and COPYING for
- + * more details.
- + *
- + */
- +
- +//#include <linux/config.h>
- +#include <linux/version.h>
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/slab.h>
- +#include <asm/string.h>
- +#include <asm/errno.h>
- +
- +#include "ieee80211.h"
- +
- +MODULE_AUTHOR("Jouni Malinen");
- +MODULE_DESCRIPTION("HostAP crypto");
- +MODULE_LICENSE("GPL");
- +
- +struct ieee80211_crypto_alg {
- + struct list_head list;
- + struct ieee80211_crypto_ops *ops;
- +};
- +
- +
- +struct ieee80211_crypto {
- + struct list_head algs;
- + spinlock_t lock;
- +};
- +
- +static struct ieee80211_crypto *hcrypt;
- +
- +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
- + int force)
- +{
- + struct list_head *ptr, *n;
- + struct ieee80211_crypt_data *entry;
- +
- + for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
- + ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
- + entry = list_entry(ptr, struct ieee80211_crypt_data, list);
- +
- + if (atomic_read(&entry->refcnt) != 0 && !force)
- + continue;
- +
- + list_del(ptr);
- +
- + if (entry->ops) {
- + entry->ops->deinit(entry->priv);
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- + module_put(entry->ops->owner);
- +#else
- + __MOD_DEC_USE_COUNT(entry->ops->owner);
- +#endif
- + }
- + kfree(entry);
- + }
- +}
- +
- +void ieee80211_crypt_deinit_handler(unsigned long data)
- +{
- + struct ieee80211_device *ieee = (struct ieee80211_device *)data;
- + unsigned long flags;
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- + ieee80211_crypt_deinit_entries(ieee, 0);
- + if (!list_empty(&ieee->crypt_deinit_list)) {
- + printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
- + "deletion list\n", ieee->dev->name);
- + ieee->crypt_deinit_timer.expires = jiffies + HZ;
- + add_timer(&ieee->crypt_deinit_timer);
- + }
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- +}
- +
- +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- + struct ieee80211_crypt_data **crypt)
- +{
- + struct ieee80211_crypt_data *tmp;
- + unsigned long flags;
- +
- + if (*crypt == NULL)
- + return;
- +
- + tmp = *crypt;
- + *crypt = NULL;
- +
- + /* must not run ops->deinit() while there may be pending encrypt or
- + * decrypt operations. Use a list of delayed deinits to avoid needing
- + * locking. */
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- + list_add(&tmp->list, &ieee->crypt_deinit_list);
- + if (!timer_pending(&ieee->crypt_deinit_timer)) {
- + ieee->crypt_deinit_timer.expires = jiffies + HZ;
- + add_timer(&ieee->crypt_deinit_timer);
- + }
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +}
- +
- +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
- +{
- + unsigned long flags;
- + struct ieee80211_crypto_alg *alg;
- +
- + if (hcrypt == NULL)
- + return -1;
- +
- + alg = kmalloc(sizeof(*alg), GFP_KERNEL);
- + if (alg == NULL)
- + return -ENOMEM;
- +
- + memset(alg, 0, sizeof(*alg));
- + alg->ops = ops;
- +
- + spin_lock_irqsave(&hcrypt->lock, flags);
- + list_add(&alg->list, &hcrypt->algs);
- + spin_unlock_irqrestore(&hcrypt->lock, flags);
- +
- + printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
- + ops->name);
- +
- + return 0;
- +}
- +
- +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
- +{
- + unsigned long flags;
- + struct list_head *ptr;
- + struct ieee80211_crypto_alg *del_alg = NULL;
- +
- + if (hcrypt == NULL)
- + return -1;
- +
- + spin_lock_irqsave(&hcrypt->lock, flags);
- + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- + struct ieee80211_crypto_alg *alg =
- + (struct ieee80211_crypto_alg *) ptr;
- + if (alg->ops == ops) {
- + list_del(&alg->list);
- + del_alg = alg;
- + break;
- + }
- + }
- + spin_unlock_irqrestore(&hcrypt->lock, flags);
- +
- + if (del_alg) {
- + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- + "'%s'\n", ops->name);
- + kfree(del_alg);
- + }
- +
- + return del_alg ? 0 : -1;
- +}
- +
- +
- +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
- +{
- + unsigned long flags;
- + struct list_head *ptr;
- + struct ieee80211_crypto_alg *found_alg = NULL;
- +
- + if (hcrypt == NULL)
- + return NULL;
- +
- + spin_lock_irqsave(&hcrypt->lock, flags);
- + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- + struct ieee80211_crypto_alg *alg =
- + (struct ieee80211_crypto_alg *) ptr;
- + if (strcmp(alg->ops->name, name) == 0) {
- + found_alg = alg;
- + break;
- + }
- + }
- + spin_unlock_irqrestore(&hcrypt->lock, flags);
- +
- + if (found_alg)
- + return found_alg->ops;
- + else
- + return NULL;
- +}
- +
- +
- +static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
- +static void ieee80211_crypt_null_deinit(void *priv) {}
- +
- +static struct ieee80211_crypto_ops ieee80211_crypt_null = {
- + .name = "NULL",
- + .init = ieee80211_crypt_null_init,
- + .deinit = ieee80211_crypt_null_deinit,
- + .encrypt_mpdu = NULL,
- + .decrypt_mpdu = NULL,
- + .encrypt_msdu = NULL,
- + .decrypt_msdu = NULL,
- + .set_key = NULL,
- + .get_key = NULL,
- + .extra_prefix_len = 0,
- + .extra_postfix_len = 0,
- + .owner = THIS_MODULE,
- +};
- +
- +
- +int __init ieee80211_crypto_init(void)
- +{
- + int ret = -ENOMEM;
- +
- + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
- + if (!hcrypt)
- + goto out;
- +
- + memset(hcrypt, 0, sizeof(*hcrypt));
- + INIT_LIST_HEAD(&hcrypt->algs);
- + spin_lock_init(&hcrypt->lock);
- +
- + ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
- + if (ret < 0) {
- + kfree(hcrypt);
- + hcrypt = NULL;
- + }
- +out:
- + return ret;
- +}
- +
- +
- +void __exit ieee80211_crypto_deinit(void)
- +{
- + struct list_head *ptr, *n;
- +
- + if (hcrypt == NULL)
- + return;
- +
- + for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
- + ptr = n, n = ptr->next) {
- + struct ieee80211_crypto_alg *alg =
- + (struct ieee80211_crypto_alg *) ptr;
- + list_del(ptr);
- + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- + "'%s' (deinit)\n", alg->ops->name);
- + kfree(alg);
- + }
- +
- + kfree(hcrypt);
- +}
- +
- +#if 0
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
- +EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
- +EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
- +
- +EXPORT_SYMBOL(ieee80211_register_crypto_ops);
- +EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
- +EXPORT_SYMBOL(ieee80211_get_crypto_ops);
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries);
- +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler);
- +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit);
- +
- +EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops);
- +EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops);
- +EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops);
- +#endif
- +
- +module_init(ieee80211_crypto_init);
- +module_exit(ieee80211_crypto_deinit);
- +#endif
- 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
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,524 @@
- +/*
- + * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
- + *
- + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation. See README and COPYING for
- + * more details.
- + */
- +
- +//#include <linux/config.h>
- +#include <linux/version.h>
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/slab.h>
- +#include <linux/random.h>
- +#include <linux/skbuff.h>
- +#include <linux/netdevice.h>
- +#include <linux/if_ether.h>
- +#include <linux/if_arp.h>
- +#include <asm/string.h>
- +#include <linux/wireless.h>
- +
- +#include "ieee80211.h"
- +
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- +#include "rtl_crypto.h"
- +#else
- +#include <linux/crypto.h>
- +#endif
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + #include <asm/scatterlist.h>
- +#else
- + #include <linux/scatterlist.h>
- +#endif
- +
- +//#include <asm/scatterlist.h>
- +
- +MODULE_AUTHOR("Jouni Malinen");
- +MODULE_DESCRIPTION("Host AP crypt: CCMP");
- +MODULE_LICENSE("GPL");
- +
- +#define AES_BLOCK_LEN 16
- +#define CCMP_HDR_LEN 8
- +#define CCMP_MIC_LEN 8
- +#define CCMP_TK_LEN 16
- +#define CCMP_PN_LEN 6
- +
- +struct ieee80211_ccmp_data {
- + u8 key[CCMP_TK_LEN];
- + int key_set;
- +
- + u8 tx_pn[CCMP_PN_LEN];
- + u8 rx_pn[CCMP_PN_LEN];
- +
- + u32 dot11RSNAStatsCCMPFormatErrors;
- + u32 dot11RSNAStatsCCMPReplays;
- + u32 dot11RSNAStatsCCMPDecryptErrors;
- +
- + int key_idx;
- +
- + struct crypto_tfm *tfm;
- +
- + /* scratch buffers for virt_to_page() (crypto API) */
- + u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
- + tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
- + u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
- +};
- +
- +void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
- + const u8 pt[16], u8 ct[16])
- +{
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + struct scatterlist src, dst;
- +
- + src.page = virt_to_page(pt);
- + src.offset = offset_in_page(pt);
- + src.length = AES_BLOCK_LEN;
- +
- + dst.page = virt_to_page(ct);
- + dst.offset = offset_in_page(ct);
- + dst.length = AES_BLOCK_LEN;
- +
- + crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
- + #else
- + crypto_cipher_encrypt_one((void*)tfm, ct, pt);
- + #endif
- +}
- +
- +static void * ieee80211_ccmp_init(int key_idx)
- +{
- + struct ieee80211_ccmp_data *priv;
- +
- + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
- + if (priv == NULL)
- + goto fail;
- + memset(priv, 0, sizeof(*priv));
- + priv->key_idx = key_idx;
- +
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + priv->tfm = crypto_alloc_tfm("aes", 0);
- + if (priv->tfm == NULL) {
- + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
- + "crypto API aes\n");
- + goto fail;
- + }
- + #else
- + priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- + if (IS_ERR(priv->tfm)) {
- + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
- + "crypto API aes\n");
- + priv->tfm = NULL;
- + goto fail;
- + }
- + #endif
- + return priv;
- +
- +fail:
- + if (priv) {
- + if (priv->tfm)
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + crypto_free_tfm(priv->tfm);
- + #else
- + crypto_free_cipher((void*)priv->tfm);
- + #endif
- + kfree(priv);
- + }
- +
- + return NULL;
- +}
- +
- +
- +static void ieee80211_ccmp_deinit(void *priv)
- +{
- + struct ieee80211_ccmp_data *_priv = priv;
- + if (_priv && _priv->tfm)
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + crypto_free_tfm(_priv->tfm);
- + #else
- + crypto_free_cipher((void*)_priv->tfm);
- + #endif
- + kfree(priv);
- +}
- +
- +
- +static inline void xor_block(u8 *b, u8 *a, size_t len)
- +{
- + int i;
- + for (i = 0; i < len; i++)
- + b[i] ^= a[i];
- +}
- +
- +#ifndef JOHN_CCMP
- +static void ccmp_init_blocks(struct crypto_tfm *tfm,
- + struct ieee80211_hdr *hdr,
- + u8 *pn, size_t dlen, u8 *b0, u8 *auth,
- + u8 *s0)
- +{
- + u8 *pos, qc = 0;
- + size_t aad_len;
- + u16 fc;
- + int a4_included, qc_included;
- + u8 aad[2 * AES_BLOCK_LEN];
- +
- + fc = le16_to_cpu(hdr->frame_ctl);
- + a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
- + /*
- + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- + (WLAN_FC_GET_STYPE(fc) & 0x08));
- + */
- + // fixed by David :2006.9.6
- + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- + (WLAN_FC_GET_STYPE(fc) & 0x80));
- + aad_len = 22;
- + if (a4_included)
- + aad_len += 6;
- + if (qc_included) {
- + pos = (u8 *) &hdr->addr4;
- + if (a4_included)
- + pos += 6;
- + qc = *pos & 0x0f;
- + aad_len += 2;
- + }
- + /* CCM Initial Block:
- + * Flag (Include authentication header, M=3 (8-octet MIC),
- + * L=1 (2-octet Dlen))
- + * Nonce: 0x00 | A2 | PN
- + * Dlen */
- + b0[0] = 0x59;
- + b0[1] = qc;
- + memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
- + memcpy(b0 + 8, pn, CCMP_PN_LEN);
- + b0[14] = (dlen >> 8) & 0xff;
- + b0[15] = dlen & 0xff;
- +
- + /* AAD:
- + * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- + * A1 | A2 | A3
- + * SC with bits 4..15 (seq#) masked to zero
- + * A4 (if present)
- + * QC (if present)
- + */
- + pos = (u8 *) hdr;
- + aad[0] = 0; /* aad_len >> 8 */
- + aad[1] = aad_len & 0xff;
- + aad[2] = pos[0] & 0x8f;
- + aad[3] = pos[1] & 0xc7;
- + memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
- + pos = (u8 *) &hdr->seq_ctl;
- + aad[22] = pos[0] & 0x0f;
- + aad[23] = 0; /* all bits masked */
- + memset(aad + 24, 0, 8);
- + if (a4_included)
- + memcpy(aad + 24, hdr->addr4, ETH_ALEN);
- + if (qc_included) {
- + aad[a4_included ? 30 : 24] = qc;
- + /* rest of QC masked */
- + }
- +
- + /* Start with the first block and AAD */
- + ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
- + xor_block(auth, aad, AES_BLOCK_LEN);
- + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- + xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
- + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- + b0[0] &= 0x07;
- + b0[14] = b0[15] = 0;
- + ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
- +}
- +#endif
- +
- +static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
- +{
- + struct ieee80211_ccmp_data *key = priv;
- + int data_len, i;
- + u8 *pos;
- + struct ieee80211_hdr *hdr;
- +#ifndef JOHN_CCMP
- + int blocks, last, len;
- + u8 *mic;
- + u8 *b0 = key->tx_b0;
- + u8 *b = key->tx_b;
- + u8 *e = key->tx_e;
- + u8 *s0 = key->tx_s0;
- +#endif
- + if (skb_headroom(skb) < CCMP_HDR_LEN ||
- + skb_tailroom(skb) < CCMP_MIC_LEN ||
- + skb->len < hdr_len)
- + return -1;
- +
- + data_len = skb->len - hdr_len;
- + pos = skb_push(skb, CCMP_HDR_LEN);
- + memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
- + pos += hdr_len;
- +// mic = skb_put(skb, CCMP_MIC_LEN);
- +
- + i = CCMP_PN_LEN - 1;
- + while (i >= 0) {
- + key->tx_pn[i]++;
- + if (key->tx_pn[i] != 0)
- + break;
- + i--;
- + }
- +
- + *pos++ = key->tx_pn[5];
- + *pos++ = key->tx_pn[4];
- + *pos++ = 0;
- + *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
- + *pos++ = key->tx_pn[3];
- + *pos++ = key->tx_pn[2];
- + *pos++ = key->tx_pn[1];
- + *pos++ = key->tx_pn[0];
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- +#ifndef JOHN_CCMP
- + //mic is moved to here by john
- + mic = skb_put(skb, CCMP_MIC_LEN);
- +
- + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
- +
- + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- + last = data_len % AES_BLOCK_LEN;
- +
- + for (i = 1; i <= blocks; i++) {
- + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- + /* Authentication */
- + xor_block(b, pos, len);
- + ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
- + /* Encryption, with counter */
- + b0[14] = (i >> 8) & 0xff;
- + b0[15] = i & 0xff;
- + ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
- + xor_block(pos, e, len);
- + pos += len;
- + }
- +
- + for (i = 0; i < CCMP_MIC_LEN; i++)
- + mic[i] = b[i] ^ s0[i];
- +#endif
- + return 0;
- +}
- +
- +
- +static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
- +{
- + struct ieee80211_ccmp_data *key = priv;
- + u8 keyidx, *pos;
- + struct ieee80211_hdr *hdr;
- + u8 pn[6];
- +#ifndef JOHN_CCMP
- + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
- + u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
- + u8 *b0 = key->rx_b0;
- + u8 *b = key->rx_b;
- + u8 *a = key->rx_a;
- + int i, blocks, last, len;
- +#endif
- + if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
- + key->dot11RSNAStatsCCMPFormatErrors++;
- + return -1;
- + }
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- + pos = skb->data + hdr_len;
- + keyidx = pos[3];
- + if (!(keyidx & (1 << 5))) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "CCMP: received packet without ExtIV"
- + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
- + }
- + key->dot11RSNAStatsCCMPFormatErrors++;
- + return -2;
- + }
- + keyidx >>= 6;
- + if (key->key_idx != keyidx) {
- + printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
- + "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
- + return -6;
- + }
- + if (!key->key_set) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
- + " with keyid=%d that does not have a configured"
- + " key\n", MAC_ARG(hdr->addr2), keyidx);
- + }
- + return -3;
- + }
- +
- + pn[0] = pos[7];
- + pn[1] = pos[6];
- + pn[2] = pos[5];
- + pn[3] = pos[4];
- + pn[4] = pos[1];
- + pn[5] = pos[0];
- + pos += 8;
- +#if 0
- + if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
- + " previous PN %02x%02x%02x%02x%02x%02x "
- + "received PN %02x%02x%02x%02x%02x%02x\n",
- + MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
- + MAC_ARG(pn));
- + }
- + key->dot11RSNAStatsCCMPReplays++;
- + return -4;
- + }
- +#endif
- +#ifndef JOHN_CCMP
- + ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
- + xor_block(mic, b, CCMP_MIC_LEN);
- +
- + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- + last = data_len % AES_BLOCK_LEN;
- +
- + for (i = 1; i <= blocks; i++) {
- + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- + /* Decrypt, with counter */
- + b0[14] = (i >> 8) & 0xff;
- + b0[15] = i & 0xff;
- + ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
- + xor_block(pos, b, len);
- + /* Authentication */
- + xor_block(a, pos, len);
- + ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
- + pos += len;
- + }
- +
- + if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "CCMP: decrypt failed: STA="
- + MAC_FMT "\n", MAC_ARG(hdr->addr2));
- + }
- + key->dot11RSNAStatsCCMPDecryptErrors++;
- + return -5;
- + }
- +
- + memcpy(key->rx_pn, pn, CCMP_PN_LEN);
- +
- +#endif
- + /* Remove hdr and MIC */
- + memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
- + skb_pull(skb, CCMP_HDR_LEN);
- + skb_trim(skb, skb->len - CCMP_MIC_LEN);
- +
- + return keyidx;
- +}
- +
- +
- +static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
- +{
- + struct ieee80211_ccmp_data *data = priv;
- + int keyidx;
- + struct crypto_tfm *tfm = data->tfm;
- +
- + keyidx = data->key_idx;
- + memset(data, 0, sizeof(*data));
- + data->key_idx = keyidx;
- + data->tfm = tfm;
- + if (len == CCMP_TK_LEN) {
- + memcpy(data->key, key, CCMP_TK_LEN);
- + data->key_set = 1;
- + if (seq) {
- + data->rx_pn[0] = seq[5];
- + data->rx_pn[1] = seq[4];
- + data->rx_pn[2] = seq[3];
- + data->rx_pn[3] = seq[2];
- + data->rx_pn[4] = seq[1];
- + data->rx_pn[5] = seq[0];
- + }
- + crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN);
- + } else if (len == 0)
- + data->key_set = 0;
- + else
- + return -1;
- +
- + return 0;
- +}
- +
- +
- +static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
- +{
- + struct ieee80211_ccmp_data *data = priv;
- +
- + if (len < CCMP_TK_LEN)
- + return -1;
- +
- + if (!data->key_set)
- + return 0;
- + memcpy(key, data->key, CCMP_TK_LEN);
- +
- + if (seq) {
- + seq[0] = data->tx_pn[5];
- + seq[1] = data->tx_pn[4];
- + seq[2] = data->tx_pn[3];
- + seq[3] = data->tx_pn[2];
- + seq[4] = data->tx_pn[1];
- + seq[5] = data->tx_pn[0];
- + }
- +
- + return CCMP_TK_LEN;
- +}
- +
- +
- +static char * ieee80211_ccmp_print_stats(char *p, void *priv)
- +{
- + struct ieee80211_ccmp_data *ccmp = priv;
- + p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
- + "tx_pn=%02x%02x%02x%02x%02x%02x "
- + "rx_pn=%02x%02x%02x%02x%02x%02x "
- + "format_errors=%d replays=%d decrypt_errors=%d\n",
- + ccmp->key_idx, ccmp->key_set,
- + MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
- + ccmp->dot11RSNAStatsCCMPFormatErrors,
- + ccmp->dot11RSNAStatsCCMPReplays,
- + ccmp->dot11RSNAStatsCCMPDecryptErrors);
- +
- + return p;
- +}
- +
- +void ieee80211_ccmp_null(void)
- +{
- + // printk("============>%s()\n", __FUNCTION__);
- + return;
- +}
- +static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
- + .name = "CCMP",
- + .init = ieee80211_ccmp_init,
- + .deinit = ieee80211_ccmp_deinit,
- + .encrypt_mpdu = ieee80211_ccmp_encrypt,
- + .decrypt_mpdu = ieee80211_ccmp_decrypt,
- + .encrypt_msdu = NULL,
- + .decrypt_msdu = NULL,
- + .set_key = ieee80211_ccmp_set_key,
- + .get_key = ieee80211_ccmp_get_key,
- + .print_stats = ieee80211_ccmp_print_stats,
- + .extra_prefix_len = CCMP_HDR_LEN,
- + .extra_postfix_len = CCMP_MIC_LEN,
- + .owner = THIS_MODULE,
- +};
- +
- +
- +int __init ieee80211_crypto_ccmp_init(void)
- +{
- + return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
- +}
- +
- +
- +void __exit ieee80211_crypto_ccmp_exit(void)
- +{
- + ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
- +}
- +#if 0
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_ccmp_null);
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
- +#endif
- +
- +module_init(ieee80211_crypto_ccmp_init);
- +module_exit(ieee80211_crypto_ccmp_exit);
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,91 @@
- +/*
- + * Original code based on Host AP (software wireless LAN access point) driver
- + * for Intersil Prism2/2.5/3.
- + *
- + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- + * <jkmaline@cc.hut.fi>
- + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- + *
- + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- + * <jketreno@linux.intel.com>
- + *
- + * Copyright (c) 2004, Intel Corporation
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation. See README and COPYING for
- + * more details.
- + */
- +
- +/*
- + * This file defines the interface to the ieee80211 crypto module.
- + */
- +#ifndef IEEE80211_CRYPT_H
- +#define IEEE80211_CRYPT_H
- +
- +#include <linux/skbuff.h>
- +
- +struct ieee80211_crypto_ops {
- + const char *name;
- +
- + /* init new crypto context (e.g., allocate private data space,
- + * select IV, etc.); returns NULL on failure or pointer to allocated
- + * private data on success */
- + void * (*init)(int keyidx);
- +
- + /* deinitialize crypto context and free allocated private data */
- + void (*deinit)(void *priv);
- +
- + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
- + * value from decrypt_mpdu is passed as the keyidx value for
- + * decrypt_msdu. skb must have enough head and tail room for the
- + * encryption; if not, error will be returned; these functions are
- + * called for all MPDUs (i.e., fragments).
- + */
- + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
- + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
- +
- + /* These functions are called for full MSDUs, i.e. full frames.
- + * These can be NULL if full MSDU operations are not needed. */
- + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
- + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
- + void *priv);
- +
- + int (*set_key)(void *key, int len, u8 *seq, void *priv);
- + int (*get_key)(void *key, int len, u8 *seq, void *priv);
- +
- + /* procfs handler for printing out key information and possible
- + * statistics */
- + char * (*print_stats)(char *p, void *priv);
- +
- + /* maximum number of bytes added by encryption; encrypt buf is
- + * allocated with extra_prefix_len bytes, copy of in_buf, and
- + * extra_postfix_len; encrypt need not use all this space, but
- + * the result must start at the beginning of the buffer and correct
- + * length must be returned */
- + int extra_prefix_len, extra_postfix_len;
- +
- + struct module *owner;
- +};
- +
- +struct ieee80211_crypt_data {
- + struct list_head list; /* delayed deletion list */
- + struct ieee80211_crypto_ops *ops;
- + void *priv;
- + atomic_t refcnt;
- +};
- +
- +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
- +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
- +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
- +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
- +void ieee80211_crypt_deinit_handler(unsigned long);
- +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- + struct ieee80211_crypt_data **crypt);
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
- +#define crypto_alloc_tfm crypto_alloc_tfm_rtl
- +#define crypto_free_tfm crypto_free_tfm_rtl
- +#endif
- +
- +#endif
- 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
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,996 @@
- +/*
- + * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
- + *
- + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation. See README and COPYING for
- + * more details.
- + */
- +
- +//#include <linux/config.h>
- +#include <linux/version.h>
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/slab.h>
- +#include <linux/random.h>
- +#include <linux/skbuff.h>
- +#include <linux/netdevice.h>
- +#include <linux/if_ether.h>
- +#include <linux/if_arp.h>
- +#include <asm/string.h>
- +
- +#include "ieee80211.h"
- +
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- +#include "rtl_crypto.h"
- +#else
- +#include <linux/crypto.h>
- +#endif
- +//#include <asm/scatterlist.h>
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + #include <asm/scatterlist.h>
- +#else
- + #include <linux/scatterlist.h>
- +#endif
- +
- +#include <linux/crc32.h>
- +
- +MODULE_AUTHOR("Jouni Malinen");
- +MODULE_DESCRIPTION("Host AP crypt: TKIP");
- +MODULE_LICENSE("GPL");
- +
- +struct ieee80211_tkip_data {
- +#define TKIP_KEY_LEN 32
- + u8 key[TKIP_KEY_LEN];
- + int key_set;
- +
- + u32 tx_iv32;
- + u16 tx_iv16;
- + u16 tx_ttak[5];
- + int tx_phase1_done;
- +
- + u32 rx_iv32;
- + u16 rx_iv16;
- + u16 rx_ttak[5];
- + int rx_phase1_done;
- + u32 rx_iv32_new;
- + u16 rx_iv16_new;
- +
- + u32 dot11RSNAStatsTKIPReplays;
- + u32 dot11RSNAStatsTKIPICVErrors;
- + u32 dot11RSNAStatsTKIPLocalMICFailures;
- +
- + int key_idx;
- +
- + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
- + struct crypto_blkcipher *rx_tfm_arc4;
- + struct crypto_hash *rx_tfm_michael;
- + struct crypto_blkcipher *tx_tfm_arc4;
- + struct crypto_hash *tx_tfm_michael;
- + #endif
- +
- + struct crypto_tfm *tfm_arc4;
- + struct crypto_tfm *tfm_michael;
- +
- + /* scratch buffers for virt_to_page() (crypto API) */
- + u8 rx_hdr[16], tx_hdr[16];
- +};
- +
- +static void * ieee80211_tkip_init(int key_idx)
- +{
- + struct ieee80211_tkip_data *priv;
- +
- + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
- + if (priv == NULL)
- + goto fail;
- + memset(priv, 0, sizeof(*priv));
- + priv->key_idx = key_idx;
- +
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
- + if (priv->tfm_arc4 == NULL) {
- + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- + "crypto API arc4\n");
- + goto fail;
- + }
- +
- + priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
- + if (priv->tfm_michael == NULL) {
- + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- + "crypto API michael_mic\n");
- + goto fail;
- + }
- +
- + #else
- + priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- + CRYPTO_ALG_ASYNC);
- + if (IS_ERR(priv->tx_tfm_arc4)) {
- + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- + "crypto API arc4\n");
- + priv->tx_tfm_arc4 = NULL;
- + goto fail;
- + }
- +
- + priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- + CRYPTO_ALG_ASYNC);
- + if (IS_ERR(priv->tx_tfm_michael)) {
- + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- + "crypto API michael_mic\n");
- + priv->tx_tfm_michael = NULL;
- + goto fail;
- + }
- +
- + priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- + CRYPTO_ALG_ASYNC);
- + if (IS_ERR(priv->rx_tfm_arc4)) {
- + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- + "crypto API arc4\n");
- + priv->rx_tfm_arc4 = NULL;
- + goto fail;
- + }
- +
- + priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- + CRYPTO_ALG_ASYNC);
- + if (IS_ERR(priv->rx_tfm_michael)) {
- + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- + "crypto API michael_mic\n");
- + priv->rx_tfm_michael = NULL;
- + goto fail;
- + }
- + #endif
- + return priv;
- +
- +fail:
- + if (priv) {
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + if (priv->tfm_michael)
- + crypto_free_tfm(priv->tfm_michael);
- + if (priv->tfm_arc4)
- + crypto_free_tfm(priv->tfm_arc4);
- + #else
- + if (priv->tx_tfm_michael)
- + crypto_free_hash(priv->tx_tfm_michael);
- + if (priv->tx_tfm_arc4)
- + crypto_free_blkcipher(priv->tx_tfm_arc4);
- + if (priv->rx_tfm_michael)
- + crypto_free_hash(priv->rx_tfm_michael);
- + if (priv->rx_tfm_arc4)
- + crypto_free_blkcipher(priv->rx_tfm_arc4);
- + #endif
- + kfree(priv);
- + }
- +
- + return NULL;
- +}
- +
- +
- +static void ieee80211_tkip_deinit(void *priv)
- +{
- + struct ieee80211_tkip_data *_priv = priv;
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + if (_priv && _priv->tfm_michael)
- + crypto_free_tfm(_priv->tfm_michael);
- + if (_priv && _priv->tfm_arc4)
- + crypto_free_tfm(_priv->tfm_arc4);
- + #else
- + if (_priv) {
- + if (_priv->tx_tfm_michael)
- + crypto_free_hash(_priv->tx_tfm_michael);
- + if (_priv->tx_tfm_arc4)
- + crypto_free_blkcipher(_priv->tx_tfm_arc4);
- + if (_priv->rx_tfm_michael)
- + crypto_free_hash(_priv->rx_tfm_michael);
- + if (_priv->rx_tfm_arc4)
- + crypto_free_blkcipher(_priv->rx_tfm_arc4);
- + }
- + #endif
- + kfree(priv);
- +}
- +
- +
- +static inline u16 RotR1(u16 val)
- +{
- + return (val >> 1) | (val << 15);
- +}
- +
- +
- +static inline u8 Lo8(u16 val)
- +{
- + return val & 0xff;
- +}
- +
- +
- +static inline u8 Hi8(u16 val)
- +{
- + return val >> 8;
- +}
- +
- +
- +static inline u16 Lo16(u32 val)
- +{
- + return val & 0xffff;
- +}
- +
- +
- +static inline u16 Hi16(u32 val)
- +{
- + return val >> 16;
- +}
- +
- +
- +static inline u16 Mk16(u8 hi, u8 lo)
- +{
- + return lo | (((u16) hi) << 8);
- +}
- +
- +
- +static inline u16 Mk16_le(u16 *v)
- +{
- + return le16_to_cpu(*v);
- +}
- +
- +
- +static const u16 Sbox[256] =
- +{
- + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
- +};
- +
- +
- +static inline u16 _S_(u16 v)
- +{
- + u16 t = Sbox[Hi8(v)];
- + return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
- +}
- +
- +#ifndef JOHN_TKIP
- +#define PHASE1_LOOP_COUNT 8
- +
- +static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
- +{
- + int i, j;
- +
- + /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
- + TTAK[0] = Lo16(IV32);
- + TTAK[1] = Hi16(IV32);
- + TTAK[2] = Mk16(TA[1], TA[0]);
- + TTAK[3] = Mk16(TA[3], TA[2]);
- + TTAK[4] = Mk16(TA[5], TA[4]);
- +
- + for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
- + j = 2 * (i & 1);
- + TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
- + TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
- + TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
- + TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
- + TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
- + }
- +}
- +
- +
- +static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
- + u16 IV16)
- +{
- + /* Make temporary area overlap WEP seed so that the final copy can be
- + * avoided on little endian hosts. */
- + u16 *PPK = (u16 *) &WEPSeed[4];
- +
- + /* Step 1 - make copy of TTAK and bring in TSC */
- + PPK[0] = TTAK[0];
- + PPK[1] = TTAK[1];
- + PPK[2] = TTAK[2];
- + PPK[3] = TTAK[3];
- + PPK[4] = TTAK[4];
- + PPK[5] = TTAK[4] + IV16;
- +
- + /* Step 2 - 96-bit bijective mixing using S-box */
- + PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
- + PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
- + PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
- + PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
- + PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
- + PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
- +
- + PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
- + PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
- + PPK[2] += RotR1(PPK[1]);
- + PPK[3] += RotR1(PPK[2]);
- + PPK[4] += RotR1(PPK[3]);
- + PPK[5] += RotR1(PPK[4]);
- +
- + /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
- + * WEPSeed[0..2] is transmitted as WEP IV */
- + WEPSeed[0] = Hi8(IV16);
- + WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
- + WEPSeed[2] = Lo8(IV16);
- + WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
- +
- +#ifdef __BIG_ENDIAN
- + {
- + int i;
- + for (i = 0; i < 6; i++)
- + PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
- + }
- +#endif
- +}
- +#endif
- +static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
- +{
- + struct ieee80211_tkip_data *tkey = priv;
- + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
- + struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
- + #endif
- + int len;
- + u8 *pos;
- + struct ieee80211_hdr *hdr;
- +#ifndef JOHN_TKIP
- + u8 rc4key[16],*icv;
- + u32 crc;
- + struct scatterlist sg;
- +#endif
- + #if(LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,21))
- + int ret;
- + #endif
- +
- + if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
- + skb->len < hdr_len)
- + return -1;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- +#if 0
- +printk("@@ tkey\n");
- +printk("%x|", ((u32*)tkey->key)[0]);
- +printk("%x|", ((u32*)tkey->key)[1]);
- +printk("%x|", ((u32*)tkey->key)[2]);
- +printk("%x|", ((u32*)tkey->key)[3]);
- +printk("%x|", ((u32*)tkey->key)[4]);
- +printk("%x|", ((u32*)tkey->key)[5]);
- +printk("%x|", ((u32*)tkey->key)[6]);
- +printk("%x\n", ((u32*)tkey->key)[7]);
- +#endif
- +
- +#ifndef JOHN_TKIP
- + if (!tkey->tx_phase1_done) {
- + tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
- + tkey->tx_iv32);
- + tkey->tx_phase1_done = 1;
- + }
- + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
- +
- +#else
- + tkey->tx_phase1_done = 1;
- +#endif /*JOHN_TKIP*/
- +
- + len = skb->len - hdr_len;
- + pos = skb_push(skb, 8);
- + memmove(pos, pos + 8, hdr_len);
- + pos += hdr_len;
- +
- +#ifdef JOHN_TKIP
- + *pos++ = Hi8(tkey->tx_iv16);
- + *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
- + *pos++ = Lo8(tkey->tx_iv16);
- +#else
- + *pos++ = rc4key[0];
- + *pos++ = rc4key[1];
- + *pos++ = rc4key[2];
- +#endif
- + *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
- + *pos++ = tkey->tx_iv32 & 0xff;
- + *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
- + *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
- + *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
- +#ifndef JOHN_TKIP
- + icv = skb_put(skb, 4);
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- + crc = ~crc32_le(~0, pos, len);
- +#else
- + crc = ~ether_crc_le(len, pos);
- +#endif
- + icv[0] = crc;
- + icv[1] = crc >> 8;
- + icv[2] = crc >> 16;
- + icv[3] = crc >> 24;
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = len + 4;
- + crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
- + #else
- + crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = len + 4;
- + #else
- + sg_init_one(&sg, pos, len + 4);
- + #endif
- + ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
- + #endif
- +#endif
- + tkey->tx_iv16++;
- + if (tkey->tx_iv16 == 0) {
- + tkey->tx_phase1_done = 0;
- + tkey->tx_iv32++;
- + }
- +#ifndef JOHN_TKIP
- + #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
- + return 0;
- + #else
- + return ret;
- + #endif
- +#else
- + return 0;
- +#endif
- +}
- +
- +static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
- +{
- + struct ieee80211_tkip_data *tkey = priv;
- + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
- + struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
- + #endif
- + u8 keyidx, *pos;
- + u32 iv32;
- + u16 iv16;
- + struct ieee80211_hdr *hdr;
- +#ifndef JOHN_TKIP
- + u8 icv[4];
- + u32 crc;
- + struct scatterlist sg;
- + u8 rc4key[16];
- + int plen;
- +#endif
- + if (skb->len < hdr_len + 8 + 4)
- + return -1;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- + pos = skb->data + hdr_len;
- + keyidx = pos[3];
- + if (!(keyidx & (1 << 5))) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
- + }
- + return -2;
- + }
- + keyidx >>= 6;
- + if (tkey->key_idx != keyidx) {
- + printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
- + "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
- + return -6;
- + }
- + if (!tkey->key_set) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
- + " with keyid=%d that does not have a configured"
- + " key\n", MAC_ARG(hdr->addr2), keyidx);
- + }
- + return -3;
- + }
- + iv16 = (pos[0] << 8) | pos[2];
- + iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
- + pos += 8;
- +#ifndef JOHN_TKIP
- +#if 0
- + if (iv32 < tkey->rx_iv32 ||
- + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
- + " previous TSC %08x%04x received TSC "
- + "%08x%04x\n", MAC_ARG(hdr->addr2),
- + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
- + }
- + tkey->dot11RSNAStatsTKIPReplays++;
- + return -4;
- + }
- +#endif
- + if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
- + tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
- + tkey->rx_phase1_done = 1;
- + }
- + tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
- +
- + plen = skb->len - hdr_len - 12;
- + #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
- + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = plen + 4;
- + crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
- + #else
- + crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
- + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = plen + 4;
- + #else
- + sg_init_one(&sg, pos, plen + 4);
- + #endif
- + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG ": TKIP: failed to decrypt "
- + "received packet from " MAC_FMT "\n",
- + MAC_ARG(hdr->addr2));
- + }
- + return -7;
- + }
- + #endif
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- + crc = ~crc32_le(~0, pos, plen);
- +#else
- + crc = ~ether_crc_le(plen, pos);
- +#endif
- + icv[0] = crc;
- + icv[1] = crc >> 8;
- + icv[2] = crc >> 16;
- + icv[3] = crc >> 24;
- + if (memcmp(icv, pos + plen, 4) != 0) {
- + if (iv32 != tkey->rx_iv32) {
- + /* Previously cached Phase1 result was already lost, so
- + * it needs to be recalculated for the next packet. */
- + tkey->rx_phase1_done = 0;
- + }
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- + MAC_FMT "\n", MAC_ARG(hdr->addr2));
- + }
- + tkey->dot11RSNAStatsTKIPICVErrors++;
- + return -5;
- + }
- +
- +#endif /* JOHN_TKIP */
- +
- + /* Update real counters only after Michael MIC verification has
- + * completed */
- + tkey->rx_iv32_new = iv32;
- + tkey->rx_iv16_new = iv16;
- +
- + /* Remove IV and ICV */
- + memmove(skb->data + 8, skb->data, hdr_len);
- + skb_pull(skb, 8);
- + skb_trim(skb, skb->len - 4);
- +
- +//john's test
- +#ifdef JOHN_DUMP
- +if( ((u16*)skb->data)[0] & 0x4000){
- + printk("@@ rx decrypted skb->data");
- + int i;
- + for(i=0;i<skb->len;i++){
- + if( (i%24)==0 ) printk("\n");
- + printk("%2x ", ((u8*)skb->data)[i]);
- + }
- + printk("\n");
- +}
- +#endif /*JOHN_DUMP*/
- + return keyidx;
- +}
- +
- +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- +static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
- + u8 *data, size_t data_len, u8 *mic)
- +{
- + struct scatterlist sg[2];
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + struct hash_desc desc;
- + int ret=0;
- +#endif
- + if (tkey->tfm_michael == NULL) {
- + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- + return -1;
- + }
- + sg[0].page = virt_to_page(hdr);
- + sg[0].offset = offset_in_page(hdr);
- + sg[0].length = 16;
- +
- + sg[1].page = virt_to_page(data);
- + sg[1].offset = offset_in_page(data);
- + sg[1].length = data_len;
- +
- + //crypto_digest_init(tkey->tfm_michael);
- + //crypto_digest_setkey(tkey->tfm_michael, key, 8);
- + //crypto_digest_update(tkey->tfm_michael, sg, 2);
- + //crypto_digest_final(tkey->tfm_michael, mic);
- +
- + //return 0;
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + crypto_digest_init(tkey->tfm_michael);
- + crypto_digest_setkey(tkey->tfm_michael, key, 8);
- + crypto_digest_update(tkey->tfm_michael, sg, 2);
- + crypto_digest_final(tkey->tfm_michael, mic);
- +
- + return 0;
- +#else
- +if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
- + return -1;
- +
- +// return 0;
- + desc.tfm = tkey->tfm_michael;
- + desc.flags = 0;
- + ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
- + return ret;
- +#endif
- +}
- +#else
- +static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
- + u8 * data, size_t data_len, u8 * mic)
- +{
- + struct hash_desc desc;
- + struct scatterlist sg[2];
- +
- + if (tfm_michael == NULL) {
- + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- + return -1;
- + }
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- + sg[0].page = virt_to_page(hdr);
- + sg[0].offset = offset_in_page(hdr);
- + sg[0].length = 16;
- +
- + sg[1].page = virt_to_page(data);
- + sg[1].offset = offset_in_page(data);
- + sg[1].length = data_len;
- +#else
- + sg_init_table(sg, 2);
- + sg_set_buf(&sg[0], hdr, 16);
- + sg_set_buf(&sg[1], data, data_len);
- +#endif
- + if (crypto_hash_setkey(tfm_michael, key, 8))
- + return -1;
- +
- + desc.tfm = tfm_michael;
- + desc.flags = 0;
- + return crypto_hash_digest(&desc, sg, data_len + 16, mic);
- +}
- +#endif
- +
- +
- +
- +static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
- +{
- + struct ieee80211_hdr *hdr11;
- +
- + hdr11 = (struct ieee80211_hdr *) skb->data;
- + switch (le16_to_cpu(hdr11->frame_ctl) &
- + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- + case IEEE80211_FCTL_TODS:
- + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- + break;
- + case IEEE80211_FCTL_FROMDS:
- + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- + memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
- + break;
- + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- + memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
- + break;
- + case 0:
- + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- + break;
- + }
- +
- + hdr[12] = 0; /* priority */
- +
- + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
- +}
- +
- +
- +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
- +{
- + struct ieee80211_tkip_data *tkey = priv;
- + u8 *pos;
- + struct ieee80211_hdr *hdr;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- +
- + if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
- + printk(KERN_DEBUG "Invalid packet for Michael MIC add "
- + "(tailroom=%d hdr_len=%d skb->len=%d)\n",
- + skb_tailroom(skb), hdr_len, skb->len);
- + return -1;
- + }
- +
- + michael_mic_hdr(skb, tkey->tx_hdr);
- +
- + // { david, 2006.9.1
- + // fix the wpa process with wmm enabled.
- + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
- + tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
- + }
- + // }
- + pos = skb_put(skb, 8);
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
- + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- + #else
- + if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
- + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- + #endif
- + return -1;
- +
- + return 0;
- +}
- +
- +
- +#if WIRELESS_EXT >= 18
- +static void ieee80211_michael_mic_failure(struct net_device *dev,
- + struct ieee80211_hdr *hdr,
- + int keyidx)
- +{
- + union iwreq_data wrqu;
- + struct iw_michaelmicfailure ev;
- +
- + /* TODO: needed parameters: count, keyid, key type, TSC */
- + memset(&ev, 0, sizeof(ev));
- + ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
- + if (hdr->addr1[0] & 0x01)
- + ev.flags |= IW_MICFAILURE_GROUP;
- + else
- + ev.flags |= IW_MICFAILURE_PAIRWISE;
- + ev.src_addr.sa_family = ARPHRD_ETHER;
- + memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
- + memset(&wrqu, 0, sizeof(wrqu));
- + wrqu.data.length = sizeof(ev);
- + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
- +}
- +#elif WIRELESS_EXT >= 15
- +static void ieee80211_michael_mic_failure(struct net_device *dev,
- + struct ieee80211_hdr *hdr,
- + int keyidx)
- +{
- + union iwreq_data wrqu;
- + char buf[128];
- +
- + /* TODO: needed parameters: count, keyid, key type, TSC */
- + sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
- + MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
- + MAC_ARG(hdr->addr2));
- + memset(&wrqu, 0, sizeof(wrqu));
- + wrqu.data.length = strlen(buf);
- + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
- +}
- +#else /* WIRELESS_EXT >= 15 */
- +static inline void ieee80211_michael_mic_failure(struct net_device *dev,
- + struct ieee80211_hdr *hdr,
- + int keyidx)
- +{
- +}
- +#endif /* WIRELESS_EXT >= 15 */
- +
- +
- +static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
- + int hdr_len, void *priv)
- +{
- + struct ieee80211_tkip_data *tkey = priv;
- + u8 mic[8];
- + struct ieee80211_hdr *hdr;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- +
- + if (!tkey->key_set)
- + return -1;
- +
- + michael_mic_hdr(skb, tkey->rx_hdr);
- + // { david, 2006.9.1
- + // fix the wpa process with wmm enabled.
- + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
- + tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
- + }
- + // }
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
- + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- + #else
- + if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- + #endif
- + return -1;
- + if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- + struct ieee80211_hdr *hdr;
- + hdr = (struct ieee80211_hdr *) skb->data;
- + printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- + "MSDU from " MAC_FMT " keyidx=%d\n",
- + skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
- + keyidx);
- + if (skb->dev)
- + ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
- + tkey->dot11RSNAStatsTKIPLocalMICFailures++;
- + return -1;
- + }
- +
- + /* Update TSC counters for RX now that the packet verification has
- + * completed. */
- + tkey->rx_iv32 = tkey->rx_iv32_new;
- + tkey->rx_iv16 = tkey->rx_iv16_new;
- +
- + skb_trim(skb, skb->len - 8);
- +
- + return 0;
- +}
- +
- +
- +static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
- +{
- + struct ieee80211_tkip_data *tkey = priv;
- + int keyidx;
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + struct crypto_tfm *tfm = tkey->tfm_michael;
- + struct crypto_tfm *tfm2 = tkey->tfm_arc4;
- + #else
- + struct crypto_hash *tfm = tkey->tx_tfm_michael;
- + struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
- + struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
- + struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
- + #endif
- +
- + keyidx = tkey->key_idx;
- + memset(tkey, 0, sizeof(*tkey));
- + tkey->key_idx = keyidx;
- +
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + tkey->tfm_michael = tfm;
- + tkey->tfm_arc4 = tfm2;
- + #else
- + tkey->tx_tfm_michael = tfm;
- + tkey->tx_tfm_arc4 = tfm2;
- + tkey->rx_tfm_michael = tfm3;
- + tkey->rx_tfm_arc4 = tfm4;
- + #endif
- +
- + if (len == TKIP_KEY_LEN) {
- + memcpy(tkey->key, key, TKIP_KEY_LEN);
- + tkey->key_set = 1;
- + tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
- + if (seq) {
- + tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
- + (seq[3] << 8) | seq[2];
- + tkey->rx_iv16 = (seq[1] << 8) | seq[0];
- + }
- + } else if (len == 0)
- + tkey->key_set = 0;
- + else
- + return -1;
- +
- + return 0;
- +}
- +
- +
- +static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
- +{
- + struct ieee80211_tkip_data *tkey = priv;
- +
- + if (len < TKIP_KEY_LEN)
- + return -1;
- +
- + if (!tkey->key_set)
- + return 0;
- + memcpy(key, tkey->key, TKIP_KEY_LEN);
- +
- + if (seq) {
- + /* Return the sequence number of the last transmitted frame. */
- + u16 iv16 = tkey->tx_iv16;
- + u32 iv32 = tkey->tx_iv32;
- + if (iv16 == 0)
- + iv32--;
- + iv16--;
- + seq[0] = tkey->tx_iv16;
- + seq[1] = tkey->tx_iv16 >> 8;
- + seq[2] = tkey->tx_iv32;
- + seq[3] = tkey->tx_iv32 >> 8;
- + seq[4] = tkey->tx_iv32 >> 16;
- + seq[5] = tkey->tx_iv32 >> 24;
- + }
- +
- + return TKIP_KEY_LEN;
- +}
- +
- +
- +static char * ieee80211_tkip_print_stats(char *p, void *priv)
- +{
- + struct ieee80211_tkip_data *tkip = priv;
- + p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
- + "tx_pn=%02x%02x%02x%02x%02x%02x "
- + "rx_pn=%02x%02x%02x%02x%02x%02x "
- + "replays=%d icv_errors=%d local_mic_failures=%d\n",
- + tkip->key_idx, tkip->key_set,
- + (tkip->tx_iv32 >> 24) & 0xff,
- + (tkip->tx_iv32 >> 16) & 0xff,
- + (tkip->tx_iv32 >> 8) & 0xff,
- + tkip->tx_iv32 & 0xff,
- + (tkip->tx_iv16 >> 8) & 0xff,
- + tkip->tx_iv16 & 0xff,
- + (tkip->rx_iv32 >> 24) & 0xff,
- + (tkip->rx_iv32 >> 16) & 0xff,
- + (tkip->rx_iv32 >> 8) & 0xff,
- + tkip->rx_iv32 & 0xff,
- + (tkip->rx_iv16 >> 8) & 0xff,
- + tkip->rx_iv16 & 0xff,
- + tkip->dot11RSNAStatsTKIPReplays,
- + tkip->dot11RSNAStatsTKIPICVErrors,
- + tkip->dot11RSNAStatsTKIPLocalMICFailures);
- + return p;
- +}
- +
- +
- +static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
- + .name = "TKIP",
- + .init = ieee80211_tkip_init,
- + .deinit = ieee80211_tkip_deinit,
- + .encrypt_mpdu = ieee80211_tkip_encrypt,
- + .decrypt_mpdu = ieee80211_tkip_decrypt,
- + .encrypt_msdu = ieee80211_michael_mic_add,
- + .decrypt_msdu = ieee80211_michael_mic_verify,
- + .set_key = ieee80211_tkip_set_key,
- + .get_key = ieee80211_tkip_get_key,
- + .print_stats = ieee80211_tkip_print_stats,
- + .extra_prefix_len = 4 + 4, /* IV + ExtIV */
- + .extra_postfix_len = 8 + 4, /* MIC + ICV */
- + .owner = THIS_MODULE,
- +};
- +
- +
- +int __init ieee80211_crypto_tkip_init(void)
- +{
- + return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
- +}
- +
- +
- +void __exit ieee80211_crypto_tkip_exit(void)
- +{
- + ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
- +}
- +
- +
- +void ieee80211_tkip_null(void)
- +{
- +// printk("============>%s()\n", __FUNCTION__);
- + return;
- +}
- +
- +#if 0
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_tkip_null);
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
- +#endif
- +
- +
- +module_init(ieee80211_crypto_tkip_init);
- +module_exit(ieee80211_crypto_tkip_exit);
- +#endif
- 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
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,383 @@
- +/*
- + * Host AP crypt: host-based WEP encryption implementation for Host AP driver
- + *
- + * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation. See README and COPYING for
- + * more details.
- + */
- +
- +//#include <linux/config.h>
- +#include <linux/version.h>
- +#include <linux/module.h>
- +#include <linux/init.h>
- +#include <linux/slab.h>
- +#include <linux/random.h>
- +#include <linux/skbuff.h>
- +#include <asm/string.h>
- +
- +#include "ieee80211.h"
- +
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- +#include "rtl_crypto.h"
- +#else
- +#include <linux/crypto.h>
- +#endif
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + #include <asm/scatterlist.h>
- +#else
- + #include <linux/scatterlist.h>
- +#endif
- +//#include <asm/scatterlist.h>
- +#include <linux/crc32.h>
- +
- +MODULE_AUTHOR("Jouni Malinen");
- +MODULE_DESCRIPTION("Host AP crypt: WEP");
- +MODULE_LICENSE("GPL");
- +
- +
- +struct prism2_wep_data {
- + u32 iv;
- +#define WEP_KEY_LEN 13
- + u8 key[WEP_KEY_LEN + 1];
- + u8 key_len;
- + u8 key_idx;
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + struct crypto_tfm *tfm;
- + #else
- + struct crypto_blkcipher *tx_tfm;
- + struct crypto_blkcipher *rx_tfm;
- + #endif
- +};
- +
- +
- +static void * prism2_wep_init(int keyidx)
- +{
- + struct prism2_wep_data *priv;
- +
- + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
- + if (priv == NULL)
- + goto fail;
- + memset(priv, 0, sizeof(*priv));
- + priv->key_idx = keyidx;
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + priv->tfm = crypto_alloc_tfm("arc4", 0);
- + if (priv->tfm == NULL) {
- + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- + "crypto API arc4\n");
- + goto fail;
- + }
- + #else
- + priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- + if (IS_ERR(priv->tx_tfm)) {
- + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- + "crypto API arc4\n");
- + priv->tx_tfm = NULL;
- + goto fail;
- + }
- + priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- + if (IS_ERR(priv->rx_tfm)) {
- + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
- + "crypto API arc4\n");
- + priv->rx_tfm = NULL;
- + goto fail;
- + }
- + #endif
- +
- + /* start WEP IV from a random value */
- + get_random_bytes(&priv->iv, 4);
- +
- + return priv;
- +
- +fail:
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + if (priv) {
- + if (priv->tfm)
- + crypto_free_tfm(priv->tfm);
- + kfree(priv);
- + }
- + #else
- + if (priv) {
- + if (priv->tx_tfm)
- + crypto_free_blkcipher(priv->tx_tfm);
- + if (priv->rx_tfm)
- + crypto_free_blkcipher(priv->rx_tfm);
- + kfree(priv);
- + }
- + #endif
- + return NULL;
- +}
- +
- +
- +static void prism2_wep_deinit(void *priv)
- +{
- + struct prism2_wep_data *_priv = priv;
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + if (_priv && _priv->tfm)
- + crypto_free_tfm(_priv->tfm);
- + #else
- + if (_priv) {
- + if (_priv->tx_tfm)
- + crypto_free_blkcipher(_priv->tx_tfm);
- + if (_priv->rx_tfm)
- + crypto_free_blkcipher(_priv->rx_tfm);
- + }
- + #endif
- + kfree(priv);
- +}
- +
- +
- +/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- + * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- + * so the payload length increases with 8 bytes.
- + *
- + * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- + */
- +static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
- +{
- + struct prism2_wep_data *wep = priv;
- +#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
- + struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
- +#endif
- + u32 klen, len;
- + u8 key[WEP_KEY_LEN + 3];
- + u8 *pos;
- +#ifndef JOHN_HWSEC
- + u32 crc;
- + u8 *icv;
- + struct scatterlist sg;
- +#endif
- + if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
- + skb->len < hdr_len)
- + return -1;
- +
- + len = skb->len - hdr_len;
- + pos = skb_push(skb, 4);
- + memmove(pos, pos + 4, hdr_len);
- + pos += hdr_len;
- +
- + klen = 3 + wep->key_len;
- +
- + wep->iv++;
- +
- + /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
- + * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
- + * can be used to speedup attacks, so avoid using them. */
- + if ((wep->iv & 0xff00) == 0xff00) {
- + u8 B = (wep->iv >> 16) & 0xff;
- + if (B >= 3 && B < klen)
- + wep->iv += 0x0100;
- + }
- +
- + /* Prepend 24-bit IV to RC4 key and TX frame */
- + *pos++ = key[0] = (wep->iv >> 16) & 0xff;
- + *pos++ = key[1] = (wep->iv >> 8) & 0xff;
- + *pos++ = key[2] = wep->iv & 0xff;
- + *pos++ = wep->key_idx << 6;
- +
- + /* Copy rest of the WEP key (the secret part) */
- + memcpy(key + 3, wep->key, wep->key_len);
- +
- +#ifndef JOHN_HWSEC
- + /* Append little-endian CRC32 and encrypt it to produce ICV */
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- + crc = ~crc32_le(~0, pos, len);
- +#else
- + crc = ~ether_crc_le(len, pos);
- +#endif
- + icv = skb_put(skb, 4);
- + icv[0] = crc;
- + icv[1] = crc >> 8;
- + icv[2] = crc >> 16;
- + icv[3] = crc >> 24;
- +
- + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + crypto_cipher_setkey(wep->tfm, key, klen);
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = len + 4;
- + crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
- +
- + return 0;
- + #else
- + crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
- + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = len + 4;
- + #else
- + sg_init_one(&sg, pos, len + 4);
- + #endif
- + return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
- + #endif
- +#endif /* JOHN_HWSEC */
- + return 0;
- +}
- +
- +
- +/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
- + * the frame: IV (4 bytes), encrypted payload (including SNAP header),
- + * ICV (4 bytes). len includes both IV and ICV.
- + *
- + * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
- + * failure. If frame is OK, IV and ICV will be removed.
- + */
- +static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
- +{
- + struct prism2_wep_data *wep = priv;
- + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
- + struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
- + #endif
- + u32 klen, plen;
- + u8 key[WEP_KEY_LEN + 3];
- + u8 keyidx, *pos;
- +#ifndef JOHN_HWSEC
- + u32 crc;
- + u8 icv[4];
- + struct scatterlist sg;
- +#endif
- + if (skb->len < hdr_len + 8)
- + return -1;
- +
- + pos = skb->data + hdr_len;
- + key[0] = *pos++;
- + key[1] = *pos++;
- + key[2] = *pos++;
- + keyidx = *pos++ >> 6;
- + if (keyidx != wep->key_idx)
- + return -1;
- +
- + klen = 3 + wep->key_len;
- +
- + /* Copy rest of the WEP key (the secret part) */
- + memcpy(key + 3, wep->key, wep->key_len);
- +
- + /* Apply RC4 to data and compute CRC32 over decrypted data */
- + plen = skb->len - hdr_len - 8;
- +#ifndef JOHN_HWSEC
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
- + crypto_cipher_setkey(wep->tfm, key, klen);
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = plen + 4;
- + crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
- +#else
- + crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
- + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
- + sg.page = virt_to_page(pos);
- + sg.offset = offset_in_page(pos);
- + sg.length = plen + 4;
- + #else
- + sg_init_one(&sg, pos, plen + 4);
- + #endif
- + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
- + return -7;
- +#endif
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- + crc = ~crc32_le(~0, pos, plen);
- +#else
- + crc = ~ether_crc_le(plen, pos);
- +#endif
- + icv[0] = crc;
- + icv[1] = crc >> 8;
- + icv[2] = crc >> 16;
- + icv[3] = crc >> 24;
- +
- + if (memcmp(icv, pos + plen, 4) != 0) {
- + /* ICV mismatch - drop frame */
- + return -2;
- + }
- +#endif /* JOHN_HWSEC */
- +
- + /* Remove IV and ICV */
- + memmove(skb->data + 4, skb->data, hdr_len);
- + skb_pull(skb, 4);
- + skb_trim(skb, skb->len - 4);
- + return 0;
- +}
- +
- +
- +static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
- +{
- + struct prism2_wep_data *wep = priv;
- +
- + if (len < 0 || len > WEP_KEY_LEN)
- + return -1;
- +
- + memcpy(wep->key, key, len);
- + wep->key_len = len;
- +
- + return 0;
- +}
- +
- +
- +static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
- +{
- + struct prism2_wep_data *wep = priv;
- +
- + if (len < wep->key_len)
- + return -1;
- +
- + memcpy(key, wep->key, wep->key_len);
- +
- + return wep->key_len;
- +}
- +
- +
- +static char * prism2_wep_print_stats(char *p, void *priv)
- +{
- + struct prism2_wep_data *wep = priv;
- + p += sprintf(p, "key[%d] alg=WEP len=%d\n",
- + wep->key_idx, wep->key_len);
- + return p;
- +}
- +
- +
- +static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
- + .name = "WEP",
- + .init = prism2_wep_init,
- + .deinit = prism2_wep_deinit,
- + .encrypt_mpdu = prism2_wep_encrypt,
- + .decrypt_mpdu = prism2_wep_decrypt,
- + .encrypt_msdu = NULL,
- + .decrypt_msdu = NULL,
- + .set_key = prism2_wep_set_key,
- + .get_key = prism2_wep_get_key,
- + .print_stats = prism2_wep_print_stats,
- + .extra_prefix_len = 4, /* IV */
- + .extra_postfix_len = 4, /* ICV */
- + .owner = THIS_MODULE,
- +};
- +
- +
- +int __init ieee80211_crypto_wep_init(void)
- +{
- + return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
- +}
- +
- +
- +void __exit ieee80211_crypto_wep_exit(void)
- +{
- + ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
- +}
- +
- +
- +void ieee80211_wep_null(void)
- +{
- +// printk("============>%s()\n", __FUNCTION__);
- + return;
- +}
- +#if 0
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_wep_null);
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
- +#endif
- +
- +module_init(ieee80211_crypto_wep_init);
- +module_exit(ieee80211_crypto_wep_exit);
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,1903 @@
- +/*
- + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
- + * remains copyright by the original authors
- + *
- + * Portions of the merged code are based on Host AP (software wireless
- + * LAN access point) driver for Intersil Prism2/2.5/3.
- + *
- + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- + * <jkmaline@cc.hut.fi>
- + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- + *
- + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- + * <jketreno@linux.intel.com>
- + * Copyright (c) 2004, Intel Corporation
- + *
- + * Modified for Realtek's wi-fi cards by Andrea Merello
- + * <andreamrl@tiscali.it>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation. See README and COPYING for
- + * more details.
- + */
- +#ifndef IEEE80211_H
- +#define IEEE80211_H
- +#include <linux/if_ether.h> /* ETH_ALEN */
- +#include <linux/kernel.h> /* ARRAY_SIZE */
- +#include <linux/version.h>
- +#include <linux/module.h>
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +#include <linux/jiffies.h>
- +#else
- +#include <linux/jffs.h>
- +#include <linux/tqueue.h>
- +#endif
- +#include <linux/timer.h>
- +#include <linux/sched.h>
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
- +#include <linux/wireless.h>
- +#endif
- +/*
- +#ifndef bool
- +#define bool int
- +#endif
- +
- +#ifndef true
- +#define true 1
- +#endif
- +
- +#ifndef false
- +#define false 0
- +#endif
- +*/
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
- +#ifndef bool
- +typedef enum{false = 0, true} bool;
- +#endif
- +#endif
- +//#ifdef JOHN_HWSEC
- +#define KEY_TYPE_NA 0x0
- +#define KEY_TYPE_WEP40 0x1
- +#define KEY_TYPE_TKIP 0x2
- +#define KEY_TYPE_CCMP 0x4
- +#define KEY_TYPE_WEP104 0x5
- +//#endif
- +
- +
- +#define aSifsTime 10
- +
- +#define MGMT_QUEUE_NUM 5
- +
- +
- +#define IEEE_CMD_SET_WPA_PARAM 1
- +#define IEEE_CMD_SET_WPA_IE 2
- +#define IEEE_CMD_SET_ENCRYPTION 3
- +#define IEEE_CMD_MLME 4
- +
- +#define IEEE_PARAM_WPA_ENABLED 1
- +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
- +#define IEEE_PARAM_DROP_UNENCRYPTED 3
- +#define IEEE_PARAM_PRIVACY_INVOKED 4
- +#define IEEE_PARAM_AUTH_ALGS 5
- +#define IEEE_PARAM_IEEE_802_1X 6
- +//It should consistent with the driver_XXX.c
- +// David, 2006.9.26
- +#define IEEE_PARAM_WPAX_SELECT 7
- +//Added for notify the encryption type selection
- +// David, 2006.9.26
- +#define IEEE_PROTO_WPA 1
- +#define IEEE_PROTO_RSN 2
- +//Added for notify the encryption type selection
- +// David, 2006.9.26
- +#define IEEE_WPAX_USEGROUP 0
- +#define IEEE_WPAX_WEP40 1
- +#define IEEE_WPAX_TKIP 2
- +#define IEEE_WPAX_WRAP 3
- +#define IEEE_WPAX_CCMP 4
- +#define IEEE_WPAX_WEP104 5
- +
- +#define IEEE_KEY_MGMT_IEEE8021X 1
- +#define IEEE_KEY_MGMT_PSK 2
- +
- +
- +
- +#define IEEE_MLME_STA_DEAUTH 1
- +#define IEEE_MLME_STA_DISASSOC 2
- +
- +
- +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
- +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
- +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
- +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
- +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
- +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
- +
- +
- +#define IEEE_CRYPT_ALG_NAME_LEN 16
- +
- +//#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
- +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
- +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
- +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
- +////////////////////////////////
- +// added for kernel conflict under FC5
- +#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
- +#define free_ieee80211 free_ieee80211_rtl
- +#define alloc_ieee80211 alloc_ieee80211_rtl
- +///////////////////////////////
- +//#endif
- +#define ieee80211_rx ieee80211_rx_rtl
- +#define ieee80211_wake_queue ieee80211_wake_queue_rtl
- +#define ieee80211_stop_queue ieee80211_stop_queue_rtl
- +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
- +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
- +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
- +
- +#define ieee80211_start_scan ieee80211_start_scan_rtl
- +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
- +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
- +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
- +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
- +typedef struct ieee_param {
- + u32 cmd;
- + u8 sta_addr[ETH_ALEN];
- + union {
- + struct {
- + u8 name;
- + u32 value;
- + } wpa_param;
- + struct {
- + u32 len;
- + u8 reserved[32];
- + u8 data[0];
- + } wpa_ie;
- + struct{
- + int command;
- + int reason_code;
- + } mlme;
- + struct {
- + u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
- + u8 set_tx;
- + u32 err;
- + u8 idx;
- + u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- + u16 key_len;
- + u8 key[0];
- + } crypt;
- +
- + } u;
- +}ieee_param;
- +
- +
- +#if WIRELESS_EXT < 17
- +#define IW_QUAL_QUAL_INVALID 0x10
- +#define IW_QUAL_LEVEL_INVALID 0x20
- +#define IW_QUAL_NOISE_INVALID 0x40
- +#define IW_QUAL_QUAL_UPDATED 0x1
- +#define IW_QUAL_LEVEL_UPDATED 0x2
- +#define IW_QUAL_NOISE_UPDATED 0x4
- +#endif
- +
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
- +static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
- +{
- + task->routine = func;
- + task->data = data;
- + //task->next = NULL;
- + INIT_LIST_HEAD(&task->list);
- + task->sync = 0;
- +}
- +#endif
- +
- +// linux under 2.6.9 release may not support it, so modify it for common use
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
- +//#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
- +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
- +static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
- +{
- + unsigned long timeout = MSECS(msecs) + 1;
- +
- + while (timeout) {
- + set_current_state(TASK_UNINTERRUPTIBLE);
- + timeout = schedule_timeout(timeout);
- + }
- + return timeout;
- +}
- +#else
- +#define MSECS(t) msecs_to_jiffies(t)
- +#define msleep_interruptible_rtl msleep_interruptible
- +#endif
- +
- +#define IEEE80211_DATA_LEN 2304
- +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
- + 6.2.1.1.2.
- +
- + The figure in section 7.1.2 suggests a body size of up to 2312
- + bytes is allowed, which is a bit confusing, I suspect this
- + represents the 2304 bytes of real data, plus a possible 8 bytes of
- + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
- +
- +
- +#define IEEE80211_HLEN 30
- +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
- +
- +/* this is stolen and modified from the madwifi driver*/
- +#define IEEE80211_FC0_TYPE_MASK 0x0c
- +#define IEEE80211_FC0_TYPE_DATA 0x08
- +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
- +#define IEEE80211_FC0_SUBTYPE_QOS 0x80
- +
- +#define IEEE80211_QOS_HAS_SEQ(fc) \
- + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
- + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
- +
- +/* this is stolen from ipw2200 driver */
- +#define IEEE_IBSS_MAC_HASH_SIZE 31
- +#define IEEE_MESH_MAC_HASH_SIZE 31
- +struct ieee_ibss_seq {
- + u8 mac[ETH_ALEN];
- + u16 seq_num[17];
- + u16 frag_num[17];
- + unsigned long packet_time[17];
- + struct list_head list;
- +};
- +
- +struct ieee_mesh_seq {
- + u8 mac[ETH_ALEN];
- + u16 seq_num;
- + u16 frag_num;
- + unsigned long packet_time;
- + struct list_head list;
- +};
- +
- +struct ieee80211_hdr {
- + u16 frame_ctl;
- + u16 duration_id;
- + u8 addr1[ETH_ALEN];
- + u8 addr2[ETH_ALEN];
- + u8 addr3[ETH_ALEN];
- + u16 seq_ctl;
- + u8 addr4[ETH_ALEN];
- +} __attribute__ ((packed));
- +
- +struct ieee80211_hdr_QOS {
- + u16 frame_ctl;
- + u16 duration_id;
- + u8 addr1[ETH_ALEN];
- + u8 addr2[ETH_ALEN];
- + u8 addr3[ETH_ALEN];
- + u16 seq_ctl;
- + u8 addr4[ETH_ALEN];
- + u16 QOS_ctl;
- +} __attribute__ ((packed));
- +
- +struct ieee80211_hdr_3addr {
- + u16 frame_ctl;
- + u16 duration_id;
- + u8 addr1[ETH_ALEN];
- + u8 addr2[ETH_ALEN];
- + u8 addr3[ETH_ALEN];
- + u16 seq_ctl;
- +} __attribute__ ((packed));
- +
- +struct ieee80211_hdr_3addr_QOS {
- + u16 frame_ctl;
- + u16 duration_id;
- + u8 addr1[ETH_ALEN];
- + u8 addr2[ETH_ALEN];
- + u8 addr3[ETH_ALEN];
- + u16 seq_ctl;
- + u16 QOS_ctl;
- +} __attribute__ ((packed));
- +
- +enum eap_type {
- + EAP_PACKET = 0,
- + EAPOL_START,
- + EAPOL_LOGOFF,
- + EAPOL_KEY,
- + EAPOL_ENCAP_ASF_ALERT
- +};
- +
- +//by lizhaoming for LED 2008.6.23 from r8187_led.h
- +#ifdef LED
- +typedef enum _LED_CTL_MODE {
- + LED_CTL_POWER_ON,
- + LED_CTL_POWER_OFF,
- + LED_CTL_LINK,
- + LED_CTL_NO_LINK,
- + LED_CTL_TX,
- + LED_CTL_RX,
- + LED_CTL_SITE_SURVEY,
- +} LED_CTL_MODE;
- +#endif
- +
- +static const char *eap_types[] = {
- + [EAP_PACKET] = "EAP-Packet",
- + [EAPOL_START] = "EAPOL-Start",
- + [EAPOL_LOGOFF] = "EAPOL-Logoff",
- + [EAPOL_KEY] = "EAPOL-Key",
- + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
- +};
- +
- +static inline const char *eap_get_type(int type)
- +{
- + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
- +}
- +
- +struct eapol {
- + u8 snap[6];
- + u16 ethertype;
- + u8 version;
- + u8 type;
- + u16 length;
- +} __attribute__ ((packed));
- +
- +#define IEEE80211_3ADDR_LEN 24
- +#define IEEE80211_4ADDR_LEN 30
- +#define IEEE80211_FCS_LEN 4
- +
- +#define MIN_FRAG_THRESHOLD 256U
- +#define MAX_FRAG_THRESHOLD 2346U
- +
- +/* Frame control field constants */
- +#define IEEE80211_FCTL_VERS 0x0002
- +#define IEEE80211_FCTL_FTYPE 0x000c
- +#define IEEE80211_FCTL_STYPE 0x00f0
- +#define IEEE80211_FCTL_TODS 0x0100
- +#define IEEE80211_FCTL_FROMDS 0x0200
- +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
- +#define IEEE80211_FCTL_MOREFRAGS 0x0400
- +#define IEEE80211_FCTL_RETRY 0x0800
- +#define IEEE80211_FCTL_PM 0x1000
- +#define IEEE80211_FCTL_MOREDATA 0x2000
- +#define IEEE80211_FCTL_WEP 0x4000
- +#define IEEE80211_FCTL_ORDER 0x8000
- +
- +#define IEEE80211_FTYPE_MGMT 0x0000
- +#define IEEE80211_FTYPE_CTL 0x0004
- +#define IEEE80211_FTYPE_DATA 0x0008
- +
- +/* management */
- +#define IEEE80211_STYPE_ASSOC_REQ 0x0000
- +#define IEEE80211_STYPE_ASSOC_RESP 0x0010
- +#define IEEE80211_STYPE_REASSOC_REQ 0x0020
- +#define IEEE80211_STYPE_REASSOC_RESP 0x0030
- +#define IEEE80211_STYPE_PROBE_REQ 0x0040
- +#define IEEE80211_STYPE_PROBE_RESP 0x0050
- +#define IEEE80211_STYPE_BEACON 0x0080
- +#define IEEE80211_STYPE_ATIM 0x0090
- +#define IEEE80211_STYPE_DISASSOC 0x00A0
- +#define IEEE80211_STYPE_AUTH 0x00B0
- +#define IEEE80211_STYPE_DEAUTH 0x00C0
- +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
- +
- +/* control */
- +#define IEEE80211_STYPE_PSPOLL 0x00A0
- +#define IEEE80211_STYPE_RTS 0x00B0
- +#define IEEE80211_STYPE_CTS 0x00C0
- +#define IEEE80211_STYPE_ACK 0x00D0
- +#define IEEE80211_STYPE_CFEND 0x00E0
- +#define IEEE80211_STYPE_CFENDACK 0x00F0
- +
- +/* data */
- +#define IEEE80211_STYPE_DATA 0x0000
- +#define IEEE80211_STYPE_DATA_CFACK 0x0010
- +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
- +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
- +#define IEEE80211_STYPE_NULLFUNC 0x0040
- +#define IEEE80211_STYPE_CFACK 0x0050
- +#define IEEE80211_STYPE_CFPOLL 0x0060
- +#define IEEE80211_STYPE_CFACKPOLL 0x0070
- +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
- +#define IEEE80211_STYPE_QOS_NULL 0x00C0
- +
- +
- +#define IEEE80211_SCTL_FRAG 0x000F
- +#define IEEE80211_SCTL_SEQ 0xFFF0
- +
- +
- +/* debug macros */
- +
- +#ifdef CONFIG_IEEE80211_DEBUG
- +extern u32 ieee80211_debug_level;
- +#define IEEE80211_DEBUG(level, fmt, args...) \
- +do { if (ieee80211_debug_level & (level)) \
- + printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
- + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
- +#else
- +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
- +#endif /* CONFIG_IEEE80211_DEBUG */
- +
- +/*
- + * To use the debug system;
- + *
- + * If you are defining a new debug classification, simply add it to the #define
- + * list here in the form of:
- + *
- + * #define IEEE80211_DL_xxxx VALUE
- + *
- + * shifting value to the left one bit from the previous entry. xxxx should be
- + * the name of the classification (for example, WEP)
- + *
- + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- + * to send output to that classification.
- + *
- + * To add your debug level to the list of levels seen when you perform
- + *
- + * % cat /proc/net/ipw/debug_level
- + *
- + * you simply need to add your entry to the ipw_debug_levels array.
- + *
- + * If you do not see debug_level in /proc/net/ipw then you do not have
- + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
- + *
- + */
- +
- +#define IEEE80211_DL_INFO (1<<0)
- +#define IEEE80211_DL_WX (1<<1)
- +#define IEEE80211_DL_SCAN (1<<2)
- +#define IEEE80211_DL_STATE (1<<3)
- +#define IEEE80211_DL_MGMT (1<<4)
- +#define IEEE80211_DL_FRAG (1<<5)
- +#define IEEE80211_DL_EAP (1<<6)
- +#define IEEE80211_DL_DROP (1<<7)
- +
- +#define IEEE80211_DL_TX (1<<8)
- +#define IEEE80211_DL_RX (1<<9)
- +
- +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
- +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
- +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
- +
- +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
- +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
- +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
- +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
- +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
- +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
- +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
- +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
- +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
- +#include <linux/netdevice.h>
- +#include <linux/wireless.h>
- +#include <linux/if_arp.h> /* ARPHRD_ETHER */
- +
- +#ifndef WIRELESS_SPY
- +#define WIRELESS_SPY // enable iwspy support
- +#endif
- +#include <net/iw_handler.h> // new driver API
- +
- +#ifndef ETH_P_PAE
- +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
- +#endif /* ETH_P_PAE */
- +
- +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
- +
- +#ifndef ETH_P_80211_RAW
- +#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
- +#endif
- +
- +/* IEEE 802.11 defines */
- +
- +#define P80211_OUI_LEN 3
- +
- +struct ieee80211_snap_hdr {
- +
- + u8 dsap; /* always 0xAA */
- + u8 ssap; /* always 0xAA */
- + u8 ctrl; /* always 0x03 */
- + u8 oui[P80211_OUI_LEN]; /* organizational universal id */
- +
- +} __attribute__ ((packed));
- +
- +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
- +
- +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
- +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
- +
- +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
- +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
- +
- +/* Authentication algorithms */
- +#define WLAN_AUTH_OPEN 0
- +#define WLAN_AUTH_SHARED_KEY 1
- +
- +#define WLAN_AUTH_CHALLENGE_LEN 128
- +
- +#define WLAN_CAPABILITY_BSS (1<<0)
- +#define WLAN_CAPABILITY_IBSS (1<<1)
- +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
- +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
- +#define WLAN_CAPABILITY_PRIVACY (1<<4)
- +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
- +#define WLAN_CAPABILITY_PBCC (1<<6)
- +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
- +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
- +
- +/* Status codes */
- +#define WLAN_STATUS_SUCCESS 0
- +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
- +#define WLAN_STATUS_CAPS_UNSUPPORTED 10
- +#define WLAN_STATUS_REASSOC_NO_ASSOC 11
- +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
- +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
- +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
- +#define WLAN_STATUS_CHALLENGE_FAIL 15
- +#define WLAN_STATUS_AUTH_TIMEOUT 16
- +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
- +#define WLAN_STATUS_ASSOC_DENIED_RATES 18
- +/* 802.11b */
- +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
- +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
- +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
- +
- +/* Reason codes */
- +#define WLAN_REASON_UNSPECIFIED 1
- +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
- +#define WLAN_REASON_DEAUTH_LEAVING 3
- +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
- +#define WLAN_REASON_DISASSOC_AP_BUSY 5
- +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
- +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
- +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
- +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
- +
- +
- +/* Information Element IDs */
- +#define WLAN_EID_SSID 0
- +#define WLAN_EID_SUPP_RATES 1
- +#define WLAN_EID_FH_PARAMS 2
- +#define WLAN_EID_DS_PARAMS 3
- +#define WLAN_EID_CF_PARAMS 4
- +#define WLAN_EID_TIM 5
- +#define WLAN_EID_IBSS_PARAMS 6
- +#define WLAN_EID_CHALLENGE 16
- +#define WLAN_EID_RSN 48
- +#define WLAN_EID_GENERIC 221
- +
- +#define IEEE80211_MGMT_HDR_LEN 24
- +#define IEEE80211_DATA_HDR3_LEN 24
- +#define IEEE80211_DATA_HDR4_LEN 30
- +
- +
- +#define IEEE80211_STATMASK_SIGNAL (1<<0)
- +#define IEEE80211_STATMASK_RSSI (1<<1)
- +#define IEEE80211_STATMASK_NOISE (1<<2)
- +#define IEEE80211_STATMASK_RATE (1<<3)
- +#define IEEE80211_STATMASK_WEMASK 0x7
- +
- +
- +#define IEEE80211_CCK_MODULATION (1<<0)
- +#define IEEE80211_OFDM_MODULATION (1<<1)
- +
- +#define IEEE80211_24GHZ_BAND (1<<0)
- +#define IEEE80211_52GHZ_BAND (1<<1)
- +
- +#define IEEE80211_CCK_RATE_LEN 4
- +#define IEEE80211_CCK_RATE_1MB 0x02
- +#define IEEE80211_CCK_RATE_2MB 0x04
- +#define IEEE80211_CCK_RATE_5MB 0x0B
- +#define IEEE80211_CCK_RATE_11MB 0x16
- +#define IEEE80211_OFDM_RATE_LEN 8
- +#define IEEE80211_OFDM_RATE_6MB 0x0C
- +#define IEEE80211_OFDM_RATE_9MB 0x12
- +#define IEEE80211_OFDM_RATE_12MB 0x18
- +#define IEEE80211_OFDM_RATE_18MB 0x24
- +#define IEEE80211_OFDM_RATE_24MB 0x30
- +#define IEEE80211_OFDM_RATE_36MB 0x48
- +#define IEEE80211_OFDM_RATE_48MB 0x60
- +#define IEEE80211_OFDM_RATE_54MB 0x6C
- +#define IEEE80211_BASIC_RATE_MASK 0x80
- +
- +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
- +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
- +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
- +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
- +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
- +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
- +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
- +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
- +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
- +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
- +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
- +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
- +
- +#define IEEE80211_CCK_RATES_MASK 0x0000000F
- +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
- + IEEE80211_CCK_RATE_2MB_MASK)
- +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
- + IEEE80211_CCK_RATE_5MB_MASK | \
- + IEEE80211_CCK_RATE_11MB_MASK)
- +
- +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
- +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
- + IEEE80211_OFDM_RATE_12MB_MASK | \
- + IEEE80211_OFDM_RATE_24MB_MASK)
- +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
- + IEEE80211_OFDM_RATE_9MB_MASK | \
- + IEEE80211_OFDM_RATE_18MB_MASK | \
- + IEEE80211_OFDM_RATE_36MB_MASK | \
- + IEEE80211_OFDM_RATE_48MB_MASK | \
- + IEEE80211_OFDM_RATE_54MB_MASK)
- +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
- + IEEE80211_CCK_DEFAULT_RATES_MASK)
- +
- +#define IEEE80211_NUM_OFDM_RATES 8
- +#define IEEE80211_NUM_CCK_RATES 4
- +#define IEEE80211_OFDM_SHIFT_MASK_A 4
- +
- +
- +
- +
- +/* NOTE: This data is for statistical purposes; not all hardware provides this
- + * information for frames received. Not setting these will not cause
- + * any adverse affects. */
- +struct ieee80211_rx_stats {
- + u32 mac_time[2];
- + u8 signalstrength;
- + s8 rssi;
- + u8 signal;
- + u8 noise;
- + u16 rate; /* in 100 kbps */
- + u8 received_channel;
- + u8 control;
- + u8 mask;
- + u8 freq;
- + u16 len;
- + u8 nic_type;
- +};
- +
- +/* IEEE 802.11 requires that STA supports concurrent reception of at least
- + * three fragmented frames. This define can be increased to support more
- + * concurrent frames, but it should be noted that each entry can consume about
- + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
- +#define IEEE80211_FRAG_CACHE_LEN 4
- +
- +struct ieee80211_frag_entry {
- + unsigned long first_frag_time;
- + unsigned int seq;
- + unsigned int last_frag;
- + struct sk_buff *skb;
- + u8 src_addr[ETH_ALEN];
- + u8 dst_addr[ETH_ALEN];
- +};
- +
- +struct ieee80211_stats {
- + unsigned int tx_unicast_frames;
- + unsigned int tx_multicast_frames;
- + unsigned int tx_fragments;
- + unsigned int tx_unicast_octets;
- + unsigned int tx_multicast_octets;
- + unsigned int tx_deferred_transmissions;
- + unsigned int tx_single_retry_frames;
- + unsigned int tx_multiple_retry_frames;
- + unsigned int tx_retry_limit_exceeded;
- + unsigned int tx_discards;
- + unsigned int rx_unicast_frames;
- + unsigned int rx_multicast_frames;
- + unsigned int rx_fragments;
- + unsigned int rx_unicast_octets;
- + unsigned int rx_multicast_octets;
- + unsigned int rx_fcs_errors;
- + unsigned int rx_discards_no_buffer;
- + unsigned int tx_discards_wrong_sa;
- + unsigned int rx_discards_undecryptable;
- + unsigned int rx_message_in_msg_fragments;
- + unsigned int rx_message_in_bad_msg_fragments;
- +};
- +
- +struct ieee80211_softmac_stats{
- + unsigned int rx_ass_ok;
- + unsigned int rx_ass_err;
- + unsigned int rx_probe_rq;
- + unsigned int tx_probe_rs;
- + unsigned int tx_beacons;
- + unsigned int rx_auth_rq;
- + unsigned int rx_auth_rs_ok;
- + unsigned int rx_auth_rs_err;
- + unsigned int tx_auth_rq;
- + unsigned int no_auth_rs;
- + unsigned int no_ass_rs;
- + unsigned int tx_ass_rq;
- + unsigned int rx_ass_rq;
- + unsigned int tx_probe_rq;
- + unsigned int reassoc;
- + unsigned int swtxstop;
- + unsigned int swtxawake;
- +};
- +
- +struct ieee80211_device;
- +
- +#include "ieee80211_crypt.h"
- +
- +#define SEC_KEY_1 (1<<0)
- +#define SEC_KEY_2 (1<<1)
- +#define SEC_KEY_3 (1<<2)
- +#define SEC_KEY_4 (1<<3)
- +#define SEC_ACTIVE_KEY (1<<4)
- +#define SEC_AUTH_MODE (1<<5)
- +#define SEC_UNICAST_GROUP (1<<6)
- +#define SEC_LEVEL (1<<7)
- +#define SEC_ENABLED (1<<8)
- +
- +#define SEC_LEVEL_0 0 /* None */
- +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
- +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
- +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
- +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
- +
- +#define WEP_KEYS 4
- +#define WEP_KEY_LEN 13
- +#define ALG_KEY_LEN 32
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +#define MAX_MP 16
- +#endif
- +struct ieee80211_security {
- + u16 active_key:2,
- + enabled:1,
- + auth_mode:2,
- + auth_algo:4,
- + unicast_uses_group:1;
- + u8 key_sizes[WEP_KEYS];
- + u8 keys[WEP_KEYS][ALG_KEY_LEN];
- + u8 level;
- + u16 flags;
- +} __attribute__ ((packed));
- +
- +
- +/*
- +
- + 802.11 data frame from AP
- +
- + ,-------------------------------------------------------------------.
- +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- + |------|------|---------|---------|---------|------|---------|------|
- +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
- + | | tion | (BSSID) | | | ence | data | |
- + `-------------------------------------------------------------------'
- +
- +Total: 28-2340 bytes
- +
- +*/
- +
- +struct ieee80211_header_data {
- + u16 frame_ctl;
- + u16 duration_id;
- + u8 addr1[6];
- + u8 addr2[6];
- + u8 addr3[6];
- + u16 seq_ctrl;
- +};
- +
- +#define BEACON_PROBE_SSID_ID_POSITION 12
- +
- +/* Management Frame Information Element Types */
- +#define MFIE_TYPE_SSID 0
- +#define MFIE_TYPE_RATES 1
- +#define MFIE_TYPE_FH_SET 2
- +#define MFIE_TYPE_DS_SET 3
- +#define MFIE_TYPE_CF_SET 4
- +#define MFIE_TYPE_TIM 5
- +#define MFIE_TYPE_IBSS_SET 6
- +#define MFIE_TYPE_COUNTRY 7
- +#define MFIE_TYPE_CHALLENGE 16
- +#define MFIE_TYPE_ERP 42
- +#define MFIE_TYPE_RSN 48
- +#define MFIE_TYPE_RATES_EX 50
- +#define MFIE_TYPE_GENERIC 221
- +
- +#ifdef ENABLE_DOT11D
- +typedef enum
- +{
- + COUNTRY_CODE_FCC = 0,
- + COUNTRY_CODE_IC = 1,
- + COUNTRY_CODE_ETSI = 2,
- + COUNTRY_CODE_SPAIN = 3,
- + COUNTRY_CODE_FRANCE = 4,
- + COUNTRY_CODE_MKK = 5,
- + COUNTRY_CODE_MKK1 = 6,
- + COUNTRY_CODE_ISRAEL = 7,
- + COUNTRY_CODE_TELEC = 8,
- + COUNTRY_CODE_GLOBAL_DOMAIN = 9,
- + COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
- +}country_code_type_t;
- +#endif
- +
- +
- +struct ieee80211_info_element_hdr {
- + u8 id;
- + u8 len;
- +} __attribute__ ((packed));
- +
- +struct ieee80211_info_element {
- + u8 id;
- + u8 len;
- + u8 data[0];
- +} __attribute__ ((packed));
- +
- +/*
- + * These are the data types that can make up management packets
- + *
- + u16 auth_algorithm;
- + u16 auth_sequence;
- + u16 beacon_interval;
- + u16 capability;
- + u8 current_ap[ETH_ALEN];
- + u16 listen_interval;
- + struct {
- + u16 association_id:14, reserved:2;
- + } __attribute__ ((packed));
- + u32 time_stamp[2];
- + u16 reason;
- + u16 status;
- +*/
- +
- +#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
- +#define IEEE80211_DEFAULT_BASIC_RATE 10
- +#define IEEE80211_DEFAULT_MESHID "802.11s"
- +#define IEEE80211_DEFAULT_MESH_CHAN 1
- +
- +struct ieee80211_authentication {
- + struct ieee80211_header_data header;
- + u16 algorithm;
- + u16 transaction;
- + u16 status;
- + //struct ieee80211_info_element_hdr info_element;
- +} __attribute__ ((packed));
- +
- +
- +struct ieee80211_probe_response {
- + struct ieee80211_header_data header;
- + u32 time_stamp[2];
- + u16 beacon_interval;
- + u16 capability;
- + struct ieee80211_info_element info_element;
- +} __attribute__ ((packed));
- +
- +struct ieee80211_probe_request {
- + struct ieee80211_header_data header;
- + /*struct ieee80211_info_element info_element;*/
- +} __attribute__ ((packed));
- +
- +struct ieee80211_assoc_request_frame {
- + struct ieee80211_hdr_3addr header;
- + u16 capability;
- + u16 listen_interval;
- + //u8 current_ap[ETH_ALEN];
- + struct ieee80211_info_element_hdr info_element;
- +} __attribute__ ((packed));
- +
- +struct ieee80211_assoc_response_frame {
- + struct ieee80211_hdr_3addr header;
- + u16 capability;
- + u16 status;
- + u16 aid;
- + struct ieee80211_info_element info_element; /* supported rates */
- +} __attribute__ ((packed));
- +
- +
- +struct ieee80211_txb {
- + u8 nr_frags;
- + u8 encrypted;
- + u16 reserved;
- + u16 frag_size;
- + u16 payload_size;
- + struct sk_buff *fragments[0];
- +};
- +
- +struct ieee80211_wmm_ac_param {
- + u8 ac_aci_acm_aifsn;
- + u8 ac_ecwmin_ecwmax;
- + u16 ac_txop_limit;
- +};
- +
- +struct ieee80211_wmm_ts_info {
- + u8 ac_dir_tid;
- + u8 ac_up_psb;
- + u8 reserved;
- +} __attribute__ ((packed));
- +
- +struct ieee80211_wmm_tspec_elem {
- + struct ieee80211_wmm_ts_info ts_info;
- + u16 norm_msdu_size;
- + u16 max_msdu_size;
- + u32 min_serv_inter;
- + u32 max_serv_inter;
- + u32 inact_inter;
- + u32 suspen_inter;
- + u32 serv_start_time;
- + u32 min_data_rate;
- + u32 mean_data_rate;
- + u32 peak_data_rate;
- + u32 max_burst_size;
- + u32 delay_bound;
- + u32 min_phy_rate;
- + u16 surp_band_allow;
- + u16 medium_time;
- +}__attribute__((packed));
- +
- +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
- +#define MAX_SP_Len (WMM_all_frame << 4)
- +#define IEEE80211_QOS_TID 0x0f
- +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
- +
- +/* SWEEP TABLE ENTRIES NUMBER*/
- +#define MAX_SWEEP_TAB_ENTRIES 42
- +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
- +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
- + * only use 8, and then use extended rates for the remaining supported
- + * rates. Other APs, however, stick all of their supported rates on the
- + * main rates information element... */
- +#define MAX_RATES_LENGTH ((u8)12)
- +#define MAX_RATES_EX_LENGTH ((u8)16)
- +#define MAX_NETWORK_COUNT 128
- +#ifdef ENABLE_DOT11D
- +#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
- +#define MAX_IE_LEN 0xFF //+YJ,080625
- +#else
- +#define MAX_CHANNEL_NUMBER 161
- +#endif
- +
- +//#define IEEE80211_SOFTMAC_SCAN_TIME 400
- +#define IEEE80211_SOFTMAC_SCAN_TIME 100//lzm mod 081209
- +//(HZ / 2)
- +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
- +
- +#define CRC_LENGTH 4U
- +
- +#define MAX_WPA_IE_LEN 64
- +
- +#define NETWORK_EMPTY_ESSID (1<<0)
- +#define NETWORK_HAS_OFDM (1<<1)
- +#define NETWORK_HAS_CCK (1<<2)
- +
- +#define IEEE80211_DTIM_MBCAST 4
- +#define IEEE80211_DTIM_UCAST 2
- +#define IEEE80211_DTIM_VALID 1
- +#define IEEE80211_DTIM_INVALID 0
- +
- +#define IEEE80211_PS_DISABLED 0
- +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
- +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
- +
- +//added by David for QoS 2006/6/30
- +//#define WMM_Hang_8187
- +#ifdef WMM_Hang_8187
- +#undef WMM_Hang_8187
- +#endif
- +
- +#define WME_AC_BE 0x00
- +#define WME_AC_BK 0x01
- +#define WME_AC_VI 0x02
- +#define WME_AC_VO 0x03
- +#define WME_ACI_MASK 0x03
- +#define WME_AIFSN_MASK 0x03
- +#define WME_AC_PRAM_LEN 16
- +
- +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
- +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
- +#define UP2AC(up) ( \
- + ((up) < 1) ? WME_AC_BE : \
- + ((up) < 3) ? WME_AC_BK : \
- + ((up) < 4) ? WME_AC_BE : \
- + ((up) < 6) ? WME_AC_VI : \
- + WME_AC_VO)
- +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
- +#define AC2UP(_ac) ( \
- + ((_ac) == WME_AC_VO) ? 6 : \
- + ((_ac) == WME_AC_VI) ? 5 : \
- + ((_ac) == WME_AC_BK) ? 1 : \
- + 0)
- +
- +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
- +struct ether_header {
- + u8 ether_dhost[ETHER_ADDR_LEN];
- + u8 ether_shost[ETHER_ADDR_LEN];
- + u16 ether_type;
- +} __attribute__((packed));
- +
- +#ifndef ETHERTYPE_PAE
- +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
- +#endif
- +#ifndef ETHERTYPE_IP
- +#define ETHERTYPE_IP 0x0800 /* IP protocol */
- +#endif
- +
- +struct ieee80211_network {
- + /* These entries are used to identify a unique network */
- + u8 bssid[ETH_ALEN];
- + u8 channel;
- + /* Ensure null-terminated for any debug msgs */
- + u8 ssid[IW_ESSID_MAX_SIZE + 1];
- + u8 ssid_len;
- +
- + /* These are network statistics */
- + struct ieee80211_rx_stats stats;
- + u16 capability;
- + u8 rates[MAX_RATES_LENGTH];
- + u8 rates_len;
- + u8 rates_ex[MAX_RATES_EX_LENGTH];
- + u8 rates_ex_len;
- + unsigned long last_scanned;
- + u8 mode;
- + u8 flags;
- + u32 last_associate;
- + u32 time_stamp[2];
- + u16 beacon_interval;
- + u16 listen_interval;
- + u16 atim_window;
- + u8 wpa_ie[MAX_WPA_IE_LEN];
- + size_t wpa_ie_len;
- + u8 rsn_ie[MAX_WPA_IE_LEN];
- + size_t rsn_ie_len;
- + u8 dtim_period;
- + u8 dtim_data;
- + u32 last_dtim_sta_time[2];
- +#ifdef _RTL8187_EXT_PATCH_
- + void *ext_entry;
- +#endif
- + struct list_head list;
- + //appeded for QoS
- + u8 wmm_info;
- + struct ieee80211_wmm_ac_param wmm_param[4];
- + u8 QoS_Enable;
- + u8 SignalStrength;
- +#ifdef THOMAS_TURBO
- + u8 Turbo_Enable;//enable turbo mode, added by thomas
- +#endif
- +
- +#ifdef ENABLE_DOT11D
- + u16 CountryIeLen;
- + u8 CountryIeBuf[MAX_IE_LEN];
- +#endif
- +
- +};
- +
- +enum ieee80211_state {
- +
- + /* the card is not linked at all */
- + IEEE80211_NOLINK = 0,
- +
- + /* IEEE80211_ASSOCIATING* are for BSS client mode
- + * the driver shall not perform RX filtering unless
- + * the state is LINKED.
- + * The driver shall just check for the state LINKED and
- + * defaults to NOLINK for ALL the other states (including
- + * LINKED_SCANNING)
- + */
- +
- + /* the association procedure will start (wq scheduling)*/
- + IEEE80211_ASSOCIATING,
- + IEEE80211_ASSOCIATING_RETRY,
- +
- + /* the association procedure is sending AUTH request*/
- + IEEE80211_ASSOCIATING_AUTHENTICATING,
- +
- + /* the association procedure has successfully authentcated
- + * and is sending association request
- + */
- + IEEE80211_ASSOCIATING_AUTHENTICATED,
- +
- + /* the link is ok. the card associated to a BSS or linked
- + * to a ibss cell or acting as an AP and creating the bss
- + */
- + IEEE80211_LINKED,
- +
- + /* same as LINKED, but the driver shall apply RX filter
- + * rules as we are in NO_LINK mode. As the card is still
- + * logically linked, but it is doing a syncro site survey
- + * then it will be back to LINKED state.
- + */
- + IEEE80211_LINKED_SCANNING,
- +//by amy for mesh
- + IEEE80211_MESH_SCANNING,
- + IEEE80211_MESH_LINKED,
- +//by amy for mesh
- +
- +};
- +
- +#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
- +#define DEFAULT_FTS 2346
- +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
- +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
- +
- +
- +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
- +extern inline int is_multicast_ether_addr(const u8 *addr)
- +{
- + return ((addr[0] != 0xff) && (0x01 & addr[0]));
- +}
- +#endif
- +
- +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
- +extern inline int is_broadcast_ether_addr(const u8 *addr)
- +{
- + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
- + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
- +}
- +#endif
- +
- +#define CFG_IEEE80211_RESERVE_FCS (1<<0)
- +#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
- +
- +typedef struct tx_pending_t{
- + int frag;
- + struct ieee80211_txb *txb;
- +}tx_pending_t;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +struct ieee80211_crypt_data_list{
- + u8 used;
- + u8 mac_addr[ETH_ALEN]; //record mac_add
- + struct ieee80211_crypt_data *crypt[WEP_KEYS];
- +}__attribute__((packed));
- +
- +#endif
- +
- +struct ieee80211_device {
- + struct net_device *dev;
- +
- + /* Bookkeeping structures */
- + struct net_device_stats stats;
- + struct ieee80211_stats ieee_stats;
- + struct ieee80211_softmac_stats softmac_stats;
- +
- + /* Probe / Beacon management */
- + struct list_head network_free_list;
- + struct list_head network_list;
- + struct ieee80211_network *networks;
- + int scans;
- + int scan_age;
- +
- + int iw_mode; /* operating mode (IW_MODE_*) */
- +#ifdef _RTL8187_EXT_PATCH_
- + int iw_ext_mode; // if iw_mode == iw_ext_mode, do ext_patch_**();
- +#endif
- +
- + spinlock_t lock;
- + spinlock_t wpax_suitlist_lock;
- +
- + int tx_headroom; /* Set to size of any additional room needed at front
- + * of allocated Tx SKBs */
- + u32 config;
- +
- + /* WEP and other encryption related settings at the device level */
- + int open_wep; /* Set to 1 to allow unencrypted frames */
- +
- + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
- + * WEP key changes */
- +
- + /* If the host performs {en,de}cryption, then set to 1 */
- + int host_encrypt;
- + int host_decrypt;
- + int ieee802_1x; /* is IEEE 802.1X used */
- +
- + /* WPA data */
- + int wpa_enabled;
- + int drop_unencrypted;
- + int tkip_countermeasures;
- + int privacy_invoked;
- + size_t wpa_ie_len;
- + u8 *wpa_ie;
- +
- +//#ifdef JOHN_TKIP
- + u8 ap_mac_addr[6];
- + u16 pairwise_key_type;
- + u16 broadcast_key_type;
- +//#endif
- + struct list_head crypt_deinit_list;
- +#ifdef _RTL8187_EXT_PATCH_
- + struct ieee80211_crypt_data_list* cryptlist[MAX_MP];
- +#else
- + struct ieee80211_crypt_data *crypt[WEP_KEYS];
- +#endif
- + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
- + struct timer_list crypt_deinit_timer;
- +
- + int bcrx_sta_key; /* use individual keys to override default keys even
- + * with RX of broad/multicast frames */
- +
- + /* Fragmentation structures */
- + // each streaming contain a entry
- + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
- + unsigned int frag_next_idx[17];
- + u16 fts; /* Fragmentation Threshold */
- +
- + /* This stores infos for the current network.
- + * Either the network we are associated in INFRASTRUCTURE
- + * or the network that we are creating in MASTER mode.
- + * ad-hoc is a mixture ;-).
- + * Note that in infrastructure mode, even when not associated,
- + * fields bssid and essid may be valid (if wpa_set and essid_set
- + * are true) as thy carry the value set by the user via iwconfig
- + */
- + struct ieee80211_network current_network;
- +
- +
- + enum ieee80211_state state;
- +
- + int short_slot;
- + int mode; /* A, B, G */
- + int modulation; /* CCK, OFDM */
- + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
- + int abg_true; /* ABG flag */
- +
- + /* used for forcing the ibss workqueue to terminate
- + * without wait for the syncro scan to terminate
- + */
- + short sync_scan_hurryup;
- +
- +#ifdef ENABLE_DOT11D
- + void * pDot11dInfo;
- + bool bGlobalDomain;
- + bool bWorldWide13;//lzm add 20081205
- +
- + // For Liteon Ch12~13 passive scan
- + u8 MinPassiveChnlNum;
- + u8 IbssStartChnl;
- +#else
- + /* map of allowed channels. 0 is dummy */
- + // FIXME: remeber to default to a basic channel plan depending of the PHY type
- + int channel_map[MAX_CHANNEL_NUMBER+1];
- +#endif
- +
- + int rate; /* current rate */
- + int basic_rate;
- + //FIXME: pleace callback, see if redundant with softmac_features
- + short active_scan;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +// short ch_lock;
- + short meshScanMode;
- +#endif
- + /* this contains flags for selectively enable softmac support */
- + u16 softmac_features;
- +
- + /* if the sequence control field is not filled by HW */
- + u16 seq_ctrl[5];
- +
- + /* association procedure transaction sequence number */
- + u16 associate_seq;
- +
- + /* AID for RTXed association responses */
- + u16 assoc_id;
- +
- + /* power save mode related*/
- + short ps;
- + short sta_sleep;
- + int ps_timeout;
- + struct tasklet_struct ps_task;
- + u32 ps_th;
- + u32 ps_tl;
- +
- + short raw_tx;
- + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- + short queue_stop;
- + short scanning;
- + short scan_watchdog;//lzm add 081215 for roaming
- + short proto_started;
- +
- + struct semaphore wx_sem;
- + struct semaphore scan_sem;
- + struct semaphore ips_sem;
- + spinlock_t mgmt_tx_lock;
- + spinlock_t beacon_lock;
- + spinlock_t beaconflag_lock;
- + short beacon_txing;
- +
- + short wap_set;
- + short ssid_set;
- +
- + u8 wpax_type_set; //{added by David, 2006.9.28}
- + u32 wpax_type_notify; //{added by David, 2006.9.26}
- +
- + /* QoS related flag */
- + char init_wmmparam_flag;
- +
- + /* for discarding duplicated packets in IBSS */
- + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
- +
- + /* for discarding duplicated packets in Mesh */ //added by david 2008.2.28/
- + struct list_head mesh_mac_hash[IEEE_MESH_MAC_HASH_SIZE];
- +
- + /* for discarding duplicated packets in BSS */
- + u16 last_rxseq_num[17]; /* rx seq previous per-tid */
- + u16 last_rxfrag_num[17];/* tx frag previous per-tid */
- + unsigned long last_packet_time[17];
- +
- + /* for PS mode */
- + unsigned long last_rx_ps_time;
- +
- + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
- + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
- + int mgmt_queue_head;
- + int mgmt_queue_tail;
- +//by amy for ps
- + bool bInactivePs;
- + bool actscanning;
- + u16 ListenInterval;
- + u32 NumRxData;
- + unsigned long NumRxDataInPeriod; //YJ,add,080828
- + unsigned long NumRxBcnInPeriod; //YJ,add,080828
- +//by amy for ps
- + short meshid_set;
- + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- + struct tx_pending_t tx_pending;
- +
- + /* used if IEEE_SOFTMAC_ASSOCIATE is set */
- + struct timer_list associate_timer;
- +
- + /* used if IEEE_SOFTMAC_BEACONS is set */
- + struct timer_list beacon_timer;
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + struct work_struct associate_complete_wq;
- +// struct work_struct associate_retry_wq;
- +// struct work_struct start_ibss_wq;
- + struct work_struct associate_procedure_wq;
- + struct work_struct ips_leave_wq; //YJ,add,081230,for IPS
- + bool bHwRadioOff;//by lizhaoming
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + struct delayed_work softmac_scan_wq;
- + struct delayed_work start_ibss_wq;
- + struct delayed_work associate_retry_wq;
- +//by amy for rate adaptive
- + struct delayed_work rate_adapter_wq;
- +//by amy for rate adaptive
- + struct delayed_work watch_dog_wq;
- + struct delayed_work hw_dig_wq;
- + struct delayed_work tx_pw_wq;
- +
- +#ifdef SW_ANTE_DIVERSITY
- + struct delayed_work SwAntennaWorkItem;
- +#endif
- +
- +#else
- + struct work_struct softmac_scan_wq;
- + struct work_struct start_ibss_wq;
- + struct work_struct associate_retry_wq;
- +//by amy for rate adaptive
- + struct work_struct rate_adapter_wq;
- +//by amy for rate adaptive
- + struct work_struct watch_dog_wq;
- + struct work_struct hw_dig_wq;
- + struct work_struct tx_pw_wq;
- +
- +#ifdef SW_ANTE_DIVERSITY
- + struct work_struct SwAntennaWorkItem;
- +#endif
- +
- +#endif
- +
- +//struct work_struct softmac_scan_wq;
- + struct work_struct wx_sync_scan_wq;
- + struct work_struct wmm_param_update_wq;
- +#ifdef _RTL8187_EXT_PATCH_
- + struct work_struct ext_stop_scan_wq;
- + struct work_struct ext_send_beacon_wq;
- +#endif
- + struct workqueue_struct *wq;
- +#else
- + /* used for periodly scan */
- + struct timer_list scan_timer;
- +
- + struct tq_struct associate_complete_wq;
- + struct tq_struct associate_retry_wq;
- + struct tq_struct start_ibss_wq;
- + struct tq_struct associate_procedure_wq;
- + struct tq_struct ips_leave_wq; //YJ,add,081230,for IPS
- + struct tq_struct softmac_scan_wq;
- + struct tq_struct wx_sync_scan_wq;
- + struct tq_struct wmm_param_update_wq;
- +#ifdef _RTL8187_EXT_PATCH_
- + struct tq_struct ext_stop_scan_wq;
- + struct tq_struct ext_send_beacon_wq;
- +#endif
- +#endif
- +
- + /* Callback functions */
- + void (*set_security)(struct net_device *dev,
- + struct ieee80211_security *sec);
- +
- + /* Used to TX data frame by using txb structs.
- + * this is not used if in the softmac_features
- + * is set the flag IEEE_SOFTMAC_TX_QUEUE
- + */
- + int (*hard_start_xmit)(struct ieee80211_txb *txb,
- + struct net_device *dev);
- +
- + int (*reset_port)(struct net_device *dev);
- +
- + /* Softmac-generated frames (mamagement) are TXed via this
- + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
- + * not set. As some cards may have different HW queues that
- + * one might want to use for data and management frames
- + * the option to have two callbacks might be useful.
- + * This fucntion can't sleep.
- + */
- + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
- + struct net_device *dev);
- +
- + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
- + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
- + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
- + * then also management frames are sent via this callback.
- + * This function can't sleep.
- + */
- + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
- + struct net_device *dev,int rate);
- +
- + /* stops the HW queue for DATA frames. Useful to avoid
- + * waste time to TX data frame when we are reassociating
- + * This function can sleep.
- + */
- + void (*data_hard_stop)(struct net_device *dev);
- +
- + /* OK this is complementar to data_poll_hard_stop */
- + void (*data_hard_resume)(struct net_device *dev);
- +
- + /* ask to the driver to retune the radio .
- + * This function can sleep. the driver should ensure
- + * the radio has been swithced before return.
- + */
- + void (*set_chan)(struct net_device *dev,short ch);
- +
- + /* These are not used if the ieee stack takes care of
- + * scanning (IEEE_SOFTMAC_SCAN feature set).
- + * In this case only the set_chan is used.
- + *
- + * The syncro version is similar to the start_scan but
- + * does not return until all channels has been scanned.
- + * this is called in user context and should sleep,
- + * it is called in a work_queue when swithcing to ad-hoc mode
- + * or in behalf of iwlist scan when the card is associated
- + * and root user ask for a scan.
- + * the fucntion stop_scan should stop both the syncro and
- + * background scanning and can sleep.
- + * The fucntion start_scan should initiate the background
- + * scanning and can't sleep.
- + */
- + void (*scan_syncro)(struct net_device *dev);
- + void (*start_scan)(struct net_device *dev);
- + void (*stop_scan)(struct net_device *dev);
- +
- + /* indicate the driver that the link state is changed
- + * for example it may indicate the card is associated now.
- + * Driver might be interested in this to apply RX filter
- + * rules or simply light the LINK led
- + */
- + void (*link_change)(struct net_device *dev);
- +
- + /* these two function indicates to the HW when to start
- + * and stop to send beacons. This is used when the
- + * IEEE_SOFTMAC_BEACONS is not set. For now the
- + * stop_send_bacons is NOT guaranteed to be called only
- + * after start_send_beacons.
- + */
- + void (*start_send_beacons) (struct net_device *dev);
- + void (*stop_send_beacons) (struct net_device *dev);
- +
- + /* power save mode related */
- + void (*sta_wake_up) (struct net_device *dev);
- + void (*ps_request_tx_ack) (struct net_device *dev);
- + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
- + short (*ps_is_queue_empty) (struct net_device *dev);
- +
- +//by lizhaoming for LED 2008.6.23
- +#ifdef LED
- + void (*ieee80211_led_contorl) (struct net_device *dev, LED_CTL_MODE LedAction);
- +#endif
- +#ifdef CONFIG_IPS
- + void (*ieee80211_ips_leave) (struct net_device *dev);
- +#endif
- + /* QoS related */
- + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
- + //void (*wmm_param_update) (struct ieee80211_device *ieee);
- +
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +
- + /// ieee80211_softmac.c
- + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
- +
- + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
- + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
- +
- + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
- +
- + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
- + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
- +
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
- + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
- +
- + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
- +
- + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- +//by amy for mesh
- + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
- +//by amy for mesh
- + // ieee80211_rx.c
- + // rz
- + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
- + unsigned int(*ext_patch_ieee80211_process_probe_response_1)(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
- +
- + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
- + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
- +
- + // success(return 0) is responsible to free skb
- + 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);
- +
- + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- + // Check whether or not accept the incoming frame. return 0: not accept, >0: accept
- + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
- +
- + // return > 0 is success. 0 when failed
- + // success(return >0) is responsible to free skb
- + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- +
- + /* added by david for setting acl dynamically */
- + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
- +
- + // int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
- +
- + // ieee80211_tx.c
- +
- + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
- + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
- +
- +
- +#endif // _RTL8187_EXT_PATCH_
- +
- + /* This must be the last item so that it points to the data
- + * allocated beyond this structure by alloc_ieee80211 */
- + u8 priv[0];
- +};
- +
- +#define IEEE_A (1<<0)
- +#define IEEE_B (1<<1)
- +#define IEEE_G (1<<2)
- +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
- +
- +/* Generate a 802.11 header */
- +
- +/* Uses the channel change callback directly
- + * instead of [start/stop] scan callbacks
- + */
- +#define IEEE_SOFTMAC_SCAN (1<<2)
- +
- +/* Perform authentication and association handshake */
- +#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
- +
- +/* Generate probe requests */
- +#define IEEE_SOFTMAC_PROBERQ (1<<4)
- +
- +/* Generate respones to probe requests */
- +#define IEEE_SOFTMAC_PROBERS (1<<5)
- +
- +/* The ieee802.11 stack will manages the netif queue
- + * wake/stop for the driver, taking care of 802.11
- + * fragmentation. See softmac.c for details. */
- +#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
- +
- +/* Uses only the softmac_data_hard_start_xmit
- + * even for TX management frames.
- + */
- +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
- +
- +/* Generate beacons. The stack will enqueue beacons
- + * to the card
- + */
- +#define IEEE_SOFTMAC_BEACONS (1<<6)
- +#ifdef _RTL8187_EXT_PATCH_
- +extern inline int ieee80211_find_MP(struct ieee80211_device* ieee, const u8* addr, u8 set)
- +{
- + int i=0;
- + for (i=1; i<MAX_MP; i++)
- + {
- + if ((ieee->cryptlist[i]->used == 0)&&set)
- + {//entry is empty
- + memcpy(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN);
- + ieee->cryptlist[i]->used = 1;
- + return i;
- + }
- + else if (0 == memcmp(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN)) //find matched entry
- + {
- + return i;
- + }
- + }
- + return -1;
- +}
- +#endif
- +
- +
- +
- +static inline void *ieee80211_priv(struct net_device *dev)
- +{
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + return ((struct ieee80211_device *)netdev_priv(dev))->priv;
- +#else
- + return ((struct ieee80211_device *)dev->priv)->priv;
- +#endif
- +}
- +
- +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
- +{
- + /* Single white space is for Linksys APs */
- + if (essid_len == 1 && essid[0] == ' ')
- + return 1;
- +
- + /* Otherwise, if the entire essid is 0, we assume it is hidden */
- + while (essid_len) {
- + essid_len--;
- + if (essid[essid_len] != '\0')
- + return 0;
- + }
- +
- + return 1;
- +}
- +
- +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
- +{
- + /*
- + * It is possible for both access points and our device to support
- + * combinations of modes, so as long as there is one valid combination
- + * of ap/device supported modes, then return success
- + *
- + */
- + if ((mode & IEEE_A) &&
- + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
- + (ieee->freq_band & IEEE80211_52GHZ_BAND))
- + return 1;
- +
- + if ((mode & IEEE_G) &&
- + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
- + (ieee->freq_band & IEEE80211_24GHZ_BAND))
- + return 1;
- +
- + if ((mode & IEEE_B) &&
- + (ieee->modulation & IEEE80211_CCK_MODULATION) &&
- + (ieee->freq_band & IEEE80211_24GHZ_BAND))
- + return 1;
- +
- + return 0;
- +}
- +
- +extern inline int ieee80211_get_hdrlen(u16 fc)
- +{
- + int hdrlen = 24;
- +
- + switch (WLAN_FC_GET_TYPE(fc)) {
- + case IEEE80211_FTYPE_DATA:
- + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- + hdrlen = 30; /* Addr4 */
- + if(IEEE80211_QOS_HAS_SEQ(fc))
- + hdrlen += 2; /* QOS ctrl*/
- + break;
- + case IEEE80211_FTYPE_CTL:
- + switch (WLAN_FC_GET_STYPE(fc)) {
- + case IEEE80211_STYPE_CTS:
- + case IEEE80211_STYPE_ACK:
- + hdrlen = 10;
- + break;
- + default:
- + hdrlen = 16;
- + break;
- + }
- + break;
- + }
- +
- + return hdrlen;
- +}
- +
- +
- +
- +/* ieee80211.c */
- +extern void free_ieee80211(struct net_device *dev);
- +extern struct net_device *alloc_ieee80211(int sizeof_priv);
- +
- +extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
- +
- +/* ieee80211_tx.c */
- +
- +extern int ieee80211_encrypt_fragment(
- + struct ieee80211_device *ieee,
- + struct sk_buff *frag,
- + int hdr_len);
- +
- +extern int ieee80211_xmit(struct sk_buff *skb,
- + struct net_device *dev);
- +extern void ieee80211_txb_free(struct ieee80211_txb *);
- +
- +
- +/* ieee80211_rx.c */
- +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- + struct ieee80211_rx_stats *rx_stats);
- +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- + struct ieee80211_hdr *header,
- + struct ieee80211_rx_stats *stats);
- +
- +/* ieee80211_wx.c */
- +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *key);
- +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *key);
- +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *key);
- +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data* wrqu, char *extra);
- +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + struct iw_param *data, char *extra);
- +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra);
- +
- +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
- +/* ieee80211_softmac.c */
- +extern short ieee80211_is_54g(struct ieee80211_network net);
- +extern short ieee80211_is_shortslot(struct ieee80211_network net);
- +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
- + struct ieee80211_rx_stats *rx_stats, u16 type,
- + u16 stype);
- +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
- +
- +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
- +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
- +extern void ieee80211_start_bss(struct ieee80211_device *ieee);
- +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
- +extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
- +extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
- +extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
- +extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
- +extern void ieee80211_disassociate(struct ieee80211_device *ieee);
- +extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
- +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
- +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
- +extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
- +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
- +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
- +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
- +extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
- +extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
- +extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
- +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
- +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
- +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
- +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
- +extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
- +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
- +extern void ieee80211_start_scan(struct ieee80211_device *ieee);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +extern void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb);
- +extern void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat);
- +extern void ieee80211_associate_step1(struct ieee80211_device *ieee);
- +extern void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason);
- +extern void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type);
- +extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
- +extern struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
- +extern int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_network *network, struct ieee80211_rx_stats *stats);
- +extern struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, int gfp_mask);
- +extern void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee);
- +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);
- +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);
- +extern int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src);
- +#endif
- +
- +/* ieee80211_crypt_ccmp&tkip&wep.c */
- +extern void ieee80211_tkip_null(void);
- +extern void ieee80211_wep_null(void);
- +extern void ieee80211_ccmp_null(void);
- +/* ieee80211_softmac_wx.c */
- +
- +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *ext);
- +
- +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *awrq,
- + char *extra);
- +
- +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
- +
- +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra);
- +
- +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra);
- +
- +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b);
- +
- +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b);
- +
- +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- + struct iw_request_info *a,
- + union iwreq_data *wrqu, char *extra);
- +
- +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b);
- +
- +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b);
- +
- +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b);
- +
- +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
- +#else
- + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
- +#endif
- +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra);
- +
- +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra);
- +
- +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra);
- +
- +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra);
- +
- +extern const long ieee80211_wlan_frequencies[];
- +
- +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
- +{
- + ieee->scans++;
- +}
- +
- +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
- +{
- + return ieee->scans;
- +}
- +
- +static inline const char *escape_essid(const char *essid, u8 essid_len) {
- + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- + const char *s = essid;
- + char *d = escaped;
- +
- + if (ieee80211_is_empty_essid(essid, essid_len)) {
- + memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- + return escaped;
- + }
- +
- + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
- + while (essid_len--) {
- + if (*s == '\0') {
- + *d++ = '\\';
- + *d++ = '0';
- + s++;
- + } else {
- + *d++ = *s++;
- + }
- + }
- + *d = '\0';
- + return escaped;
- +}
- +#endif /* IEEE80211_H */
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,385 @@
- +/*******************************************************************************
- +
- + Copyright(c) 2004 Intel Corporation. All rights reserved.
- +
- + Portions of this file are based on the WEP enablement code provided by the
- + Host AP project hostap-drivers v0.1.3
- + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- + <jkmaline@cc.hut.fi>
- + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- +
- + This program is free software; you can redistribute it and/or modify it
- + under the terms of version 2 of the GNU General Public License as
- + published by the Free Software Foundation.
- +
- + This program is distributed in the hope that it will be useful, but WITHOUT
- + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + more details.
- +
- + You should have received a copy of the GNU General Public License along with
- + this program; if not, write to the Free Software Foundation, Inc., 59
- + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- +
- + The full GNU General Public License is included in this distribution in the
- + file called LICENSE.
- +
- + Contact Information:
- + James P. Ketrenos <ipw2100-admin@linux.intel.com>
- + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- +
- +*******************************************************************************/
- +
- +#include <linux/compiler.h>
- +//#include <linux/config.h>
- +#include <linux/errno.h>
- +#include <linux/if_arp.h>
- +#include <linux/in6.h>
- +#include <linux/in.h>
- +#include <linux/ip.h>
- +#include <linux/kernel.h>
- +#include <linux/module.h>
- +#include <linux/netdevice.h>
- +#include <linux/pci.h>
- +#include <linux/proc_fs.h>
- +#include <linux/skbuff.h>
- +#include <linux/slab.h>
- +#include <linux/tcp.h>
- +#include <linux/types.h>
- +#include <linux/version.h>
- +#include <linux/wireless.h>
- +#include <linux/etherdevice.h>
- +#include <asm/uaccess.h>
- +#include <net/arp.h>
- +
- +#include "ieee80211.h"
- +
- +MODULE_DESCRIPTION("802.11 data/management/control stack");
- +MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
- +MODULE_LICENSE("GPL");
- +
- +#define DRV_NAME "ieee80211"
- +
- +static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
- +{
- + if (ieee->networks)
- + return 0;
- +
- + ieee->networks = kmalloc(
- + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
- + GFP_KERNEL);
- + if (!ieee->networks) {
- + printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
- + ieee->dev->name);
- + return -ENOMEM;
- + }
- +
- + memset(ieee->networks, 0,
- + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
- +
- + return 0;
- +}
- +
- +static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
- +{
- + if (!ieee->networks)
- + return;
- + kfree(ieee->networks);
- + ieee->networks = NULL;
- +}
- +
- +static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
- +{
- + int i;
- +
- + INIT_LIST_HEAD(&ieee->network_free_list);
- + INIT_LIST_HEAD(&ieee->network_list);
- + for (i = 0; i < MAX_NETWORK_COUNT; i++)
- + list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
- +}
- +
- +
- +struct net_device *alloc_ieee80211(int sizeof_priv)
- +{
- + struct ieee80211_device *ieee;
- + struct net_device *dev;
- + int i,err;
- +
- + IEEE80211_DEBUG_INFO("Initializing...\n");
- +
- + dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
- + if (!dev) {
- + IEEE80211_ERROR("Unable to network device.\n");
- + goto failed;
- + }
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- + ieee = netdev_priv(dev);
- +#else
- + ieee = (struct ieee80211_device *)dev->priv;
- +#endif
- +
- + ieee->dev = dev;
- +
- + err = ieee80211_networks_allocate(ieee);
- + if (err) {
- + IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
- + err);
- + goto failed;
- + }
- + ieee80211_networks_initialize(ieee);
- +
- + /* Default fragmentation threshold is maximum payload size */
- + ieee->fts = DEFAULT_FTS;
- + ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
- + ieee->open_wep = 1;
- +
- + /* Default to enabling full open WEP with host based encrypt/decrypt */
- + ieee->host_encrypt = 1;
- + ieee->host_decrypt = 1;
- + ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
- +
- + INIT_LIST_HEAD(&ieee->crypt_deinit_list);
- + init_timer(&ieee->crypt_deinit_timer);
- + ieee->crypt_deinit_timer.data = (unsigned long)ieee;
- + ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
- +
- + spin_lock_init(&ieee->lock);
- + spin_lock_init(&ieee->wpax_suitlist_lock);
- +
- + ieee->wpax_type_set = 0;
- + ieee->wpa_enabled = 0;
- + ieee->tkip_countermeasures = 0;
- + ieee->drop_unencrypted = 0;
- + ieee->privacy_invoked = 0;
- + ieee->ieee802_1x = 1;
- + ieee->raw_tx = 0;
- +#ifdef _RTL8187_EXT_PATCH_
- + for (i=0; i<MAX_MP; i++)
- + {
- + ieee->cryptlist[i] = (struct ieee80211_crypt_data_list*) kmalloc(sizeof(struct ieee80211_crypt_data_list), GFP_KERNEL);
- + if (NULL == ieee->cryptlist[i])
- + {
- + printk("error kmalloc cryptlist\n");
- + goto failed;
- + }
- + memset(ieee->cryptlist[i], 0, sizeof(struct ieee80211_crypt_data_list));
- +
- + }
- +#endif
- + ieee80211_softmac_init(ieee);
- +
- + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
- + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
- +
- + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++)
- + INIT_LIST_HEAD(&ieee->mesh_mac_hash[i]);
- +
- + for (i = 0; i < 17; i++) {
- + ieee->last_rxseq_num[i] = -1;
- + ieee->last_rxfrag_num[i] = -1;
- + ieee->last_packet_time[i] = 0;
- + }
- +#if 1 //added these to autoload encryption module. WB
- + ieee80211_tkip_null();
- + ieee80211_wep_null();
- + ieee80211_ccmp_null();
- +#endif
- + return dev;
- +
- + failed:
- +#ifdef _RTL8187_EXT_PATCH_
- + for (i=0; i<MAX_MP; i++)
- + {
- + if (ieee->cryptlist[i]==NULL){
- + continue;
- + }
- + kfree(ieee->cryptlist[i]);
- + ieee->cryptlist[i] = NULL;
- +
- + }
- +#endif
- + if (dev)
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- + free_netdev(dev);
- +#else
- + kfree(dev);
- +#endif
- + return NULL;
- +}
- +
- +
- +void free_ieee80211(struct net_device *dev)
- +{
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- + struct ieee80211_device *ieee = netdev_priv(dev);
- +#else
- + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
- +#endif
- + int i;//,j;
- + struct list_head *p, *q;
- +
- +
- + ieee80211_softmac_free(ieee);
- + del_timer_sync(&ieee->crypt_deinit_timer);
- + ieee80211_crypt_deinit_entries(ieee, 1);
- +#if 1
- + ieee80211_tkip_null();
- + ieee80211_wep_null();
- + ieee80211_ccmp_null();
- +#endif
- + for (i = 0; i < WEP_KEYS; i++) {
- +#ifdef _RTL8187_EXT_PATCH_
- +{
- + // int j;
- + for (j=0;j<MAX_MP; j++){
- + if (ieee->cryptlist[j] == NULL)
- + continue;
- + struct ieee80211_crypt_data *crypt = ieee->cryptlist[j]->crypt[i];
- +#else
- + struct ieee80211_crypt_data *crypt = ieee->crypt[i];
- +#endif
- + if (crypt) {
- + if (crypt->ops) {
- + crypt->ops->deinit(crypt->priv);
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- + module_put(crypt->ops->owner);
- +#else
- + __MOD_DEC_USE_COUNT(crypt->ops->owner);
- +#endif
- + }
- + kfree(crypt);
- +#ifdef _RTL8187_EXT_PATCH_
- + ieee->cryptlist[j]->crypt[i] = NULL;
- + //kfree(ieee->cryptlist[j]);
- + //ieee->cryptlist[j] = NULL;
- +#else
- + ieee->crypt[i] = NULL;
- +#endif
- + }
- +#ifdef _RTL8187_EXT_PATCH_
- + }
- + }
- +#endif
- +}
- +#ifdef _RTL8187_EXT_PATCH_
- +for(j=0;j<MAX_MP;j++)
- + {
- + if (ieee->cryptlist[j])
- + {
- + kfree(ieee->cryptlist[j]);
- + ieee->cryptlist[j] = NULL;
- + }
- + }
- +
- + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++) {
- + list_for_each_safe(p, q, &ieee->mesh_mac_hash[i]) {
- + kfree(list_entry(p, struct ieee_mesh_seq, list));
- + list_del(p);
- + }
- + }
- +#endif
- + ieee80211_networks_free(ieee);
- +
- + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
- + list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
- + kfree(list_entry(p, struct ieee_ibss_seq, list));
- + list_del(p);
- + }
- + }
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- + free_netdev(dev);
- +#else
- + kfree(dev);
- +#endif
- +}
- +
- +#ifdef CONFIG_IEEE80211_DEBUG
- +
- +static int debug = 0;
- +u32 ieee80211_debug_level = 0;
- +struct proc_dir_entry *ieee80211_proc = NULL;
- +
- +static int show_debug_level(char *page, char **start, off_t offset,
- + int count, int *eof, void *data)
- +{
- + return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
- +}
- +
- +static int store_debug_level(struct file *file, const char *buffer,
- + unsigned long count, void *data)
- +{
- + char buf[] = "0x00000000";
- + unsigned long len = min(sizeof(buf) - 1, (u32)count);
- + char *p = (char *)buf;
- + unsigned long val;
- +
- + if (copy_from_user(buf, buffer, len))
- + return count;
- + buf[len] = 0;
- + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
- + p++;
- + if (p[0] == 'x' || p[0] == 'X')
- + p++;
- + val = simple_strtoul(p, &p, 16);
- + } else
- + val = simple_strtoul(p, &p, 10);
- + if (p == buf)
- + printk(KERN_INFO DRV_NAME
- + ": %s is not in hex or decimal form.\n", buf);
- + else
- + ieee80211_debug_level = val;
- +
- + return strnlen(buf, count);
- +}
- +
- +static int __init ieee80211_init(void)
- +{
- + struct proc_dir_entry *e;
- +
- + ieee80211_debug_level = debug;
- + ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
- + if (ieee80211_proc == NULL) {
- + IEEE80211_ERROR("Unable to create " DRV_NAME
- + " proc directory\n");
- + return -EIO;
- + }
- + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
- + ieee80211_proc);
- + if (!e) {
- + remove_proc_entry(DRV_NAME, proc_net);
- + ieee80211_proc = NULL;
- + return -EIO;
- + }
- + e->read_proc = show_debug_level;
- + e->write_proc = store_debug_level;
- + e->data = NULL;
- +
- + return 0;
- +}
- +
- +static void __exit ieee80211_exit(void)
- +{
- + if (ieee80211_proc) {
- + remove_proc_entry("debug_level", ieee80211_proc);
- + remove_proc_entry(DRV_NAME, proc_net);
- + ieee80211_proc = NULL;
- + }
- +}
- +
- +#include <linux/moduleparam.h>
- +module_param(debug, int, 0444);
- +MODULE_PARM_DESC(debug, "debug output mask");
- +
- +
- +module_exit(ieee80211_exit);
- +module_init(ieee80211_init);
- +#endif
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(alloc_ieee80211);
- +EXPORT_SYMBOL(free_ieee80211);
- +#else
- +EXPORT_SYMBOL_NOVERS(alloc_ieee80211);
- +EXPORT_SYMBOL_NOVERS(free_ieee80211);
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,2074 @@
- +/*
- + * Original code based Host AP (software wireless LAN access point) driver
- + * for Intersil Prism2/2.5/3 - hostap.o module, common routines
- + *
- + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- + * <jkmaline@cc.hut.fi>
- + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- + * Copyright (c) 2004, Intel Corporation
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation. See README and COPYING for
- + * more details.
- + ******************************************************************************
- +
- + Few modifications for Realtek's Wi-Fi drivers by
- + Andrea Merello <andreamrl@tiscali.it>
- +
- + A special thanks goes to Realtek for their support !
- +
- +******************************************************************************/
- +
- +
- +#include <linux/compiler.h>
- +//#include <linux/config.h>
- +#include <linux/errno.h>
- +#include <linux/if_arp.h>
- +#include <linux/in6.h>
- +#include <linux/in.h>
- +#include <linux/ip.h>
- +#include <linux/kernel.h>
- +#include <linux/module.h>
- +#include <linux/netdevice.h>
- +#include <linux/pci.h>
- +#include <linux/proc_fs.h>
- +#include <linux/skbuff.h>
- +#include <linux/slab.h>
- +#include <linux/tcp.h>
- +#include <linux/types.h>
- +#include <linux/version.h>
- +#include <linux/wireless.h>
- +#include <linux/etherdevice.h>
- +#include <asm/uaccess.h>
- +#include <linux/ctype.h>
- +
- +#include "ieee80211.h"
- +#ifdef ENABLE_DOT11D
- +#include "dot11d.h"
- +#endif
- +
- +static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
- + struct sk_buff *skb,
- + struct ieee80211_rx_stats *rx_stats)
- +{
- + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- + u16 fc = le16_to_cpu(hdr->frame_ctl);
- +
- + skb->dev = ieee->dev;
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
- + skb_reset_mac_header(skb);
- +#else
- + skb->mac.raw = skb->data;
- +#endif
- +
- + //skb->mac.raw = skb->data;
- + skb_pull(skb, ieee80211_get_hdrlen(fc));
- + skb->pkt_type = PACKET_OTHERHOST;
- + skb->protocol = __constant_htons(ETH_P_80211_RAW);
- + memset(skb->cb, 0, sizeof(skb->cb));
- + netif_rx(skb);
- +}
- +
- +
- +/* Called only as a tasklet (software IRQ) */
- +static struct ieee80211_frag_entry *
- +ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
- + unsigned int frag, u8 tid,u8 *src, u8 *dst)
- +{
- + struct ieee80211_frag_entry *entry;
- + int i;
- +
- + for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
- + entry = &ieee->frag_cache[tid][i];
- + if (entry->skb != NULL &&
- + time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
- + IEEE80211_DEBUG_FRAG(
- + "expiring fragment cache entry "
- + "seq=%u last_frag=%u\n",
- + entry->seq, entry->last_frag);
- + dev_kfree_skb_any(entry->skb);
- + entry->skb = NULL;
- + }
- +
- + if (entry->skb != NULL && entry->seq == seq &&
- + (entry->last_frag + 1 == frag || frag == -1) &&
- + memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
- + memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
- + return entry;
- + }
- +
- + return NULL;
- +}
- +
- +/* Called only as a tasklet (software IRQ) */
- +static struct sk_buff *
- +ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- + struct ieee80211_hdr *hdr)
- +{
- + struct sk_buff *skb = NULL;
- + u16 fc = le16_to_cpu(hdr->frame_ctl);
- + u16 sc = le16_to_cpu(hdr->seq_ctl);
- + unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
- + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- + struct ieee80211_frag_entry *entry;
- + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
- + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
- + u8 tid;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + {
- + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
- + }
- + else
- +#endif
- + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
- + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
- + tid = UP2AC(tid);
- + tid ++;
- + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
- + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
- + tid = UP2AC(tid);
- + tid ++;
- + } else {
- + tid = 0;
- + }
- +
- + if (frag == 0) {
- + /* Reserve enough space to fit maximum frame length */
- + skb = dev_alloc_skb(ieee->dev->mtu +
- + sizeof(struct ieee80211_hdr) +
- + 8 /* LLC */ +
- + 2 /* alignment */ +
- + 8 /* WEP */ +
- + ETH_ALEN /* WDS */ +
- + (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
- + if (skb == NULL)
- + return NULL;
- +
- + entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
- + ieee->frag_next_idx[tid]++;
- + if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
- + ieee->frag_next_idx[tid] = 0;
- +
- + if (entry->skb != NULL)
- + dev_kfree_skb_any(entry->skb);
- +
- + entry->first_frag_time = jiffies;
- + entry->seq = seq;
- + entry->last_frag = frag;
- + entry->skb = skb;
- + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
- + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
- + } else {
- + /* received a fragment of a frame for which the head fragment
- + * should have already been received */
- + entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
- + hdr->addr1);
- + if (entry != NULL) {
- + entry->last_frag = frag;
- + skb = entry->skb;
- + }
- + }
- +
- + return skb;
- +}
- +
- +
- +/* Called only as a tasklet (software IRQ) */
- +static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
- + struct ieee80211_hdr *hdr)
- +{
- + u16 fc = le16_to_cpu(hdr->frame_ctl);
- + u16 sc = le16_to_cpu(hdr->seq_ctl);
- + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- + struct ieee80211_frag_entry *entry;
- + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
- + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
- + u8 tid;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + {
- + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
- + }
- + else
- +#endif
- + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
- + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
- + tid = UP2AC(tid);
- + tid ++;
- + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
- + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
- + tid = UP2AC(tid);
- + tid ++;
- + } else {
- + tid = 0;
- + }
- +
- + entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
- + hdr->addr1);
- +
- + if (entry == NULL) {
- + IEEE80211_DEBUG_FRAG(
- + "could not invalidate fragment cache "
- + "entry (seq=%u)\n", seq);
- + return -1;
- + }
- +
- + entry->skb = NULL;
- + return 0;
- +}
- +
- +
- +
- +/* ieee80211_rx_frame_mgtmt
- + *
- + * Responsible for handling management control frames
- + *
- + * Called by ieee80211_rx */
- +static inline int
- +ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
- + struct ieee80211_rx_stats *rx_stats, u16 type,
- + u16 stype)
- +{
- + /* On the struct stats definition there is written that
- + * this is not mandatory.... but seems that the probe
- + * response parser uses it
- + */
- + struct ieee80211_hdr * hdr = (struct ieee80211_hdr*)skb->data;
- + rx_stats->len = skb->len;
- + ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
- +
- + if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN)))
- + {
- + dev_kfree_skb_any(skb);
- + return 0;
- + }
- +
- + ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
- +
- + dev_kfree_skb_any(skb);
- +
- + return 0;
- +
- + #ifdef NOT_YET
- + if (ieee->iw_mode == IW_MODE_MASTER) {
- + printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
- + ieee->dev->name);
- + return 0;
- +/*
- + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
- + skb->data);*/
- + }
- +
- + if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
- + if (stype == WLAN_FC_STYPE_BEACON &&
- + ieee->iw_mode == IW_MODE_MASTER) {
- + struct sk_buff *skb2;
- + /* Process beacon frames also in kernel driver to
- + * update STA(AP) table statistics */
- + skb2 = skb_clone(skb, GFP_ATOMIC);
- + if (skb2)
- + hostap_rx(skb2->dev, skb2, rx_stats);
- + }
- +
- + /* send management frames to the user space daemon for
- + * processing */
- + ieee->apdevstats.rx_packets++;
- + ieee->apdevstats.rx_bytes += skb->len;
- + prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
- + return 0;
- + }
- +
- + if (ieee->iw_mode == IW_MODE_MASTER) {
- + if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
- + printk(KERN_DEBUG "%s: unknown management frame "
- + "(type=0x%02x, stype=0x%02x) dropped\n",
- + skb->dev->name, type, stype);
- + return -1;
- + }
- +
- + hostap_rx(skb->dev, skb, rx_stats);
- + return 0;
- + }
- +
- + printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
- + "received in non-Host AP mode\n", skb->dev->name);
- + return -1;
- + #endif
- +}
- +
- +
- +
- +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
- +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
- +static unsigned char rfc1042_header[] =
- +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
- +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
- +static unsigned char bridge_tunnel_header[] =
- +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
- +/* No encapsulation header if EtherType < 0x600 (=length) */
- +
- +/* Called by ieee80211_rx_frame_decrypt */
- +static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
- + struct sk_buff *skb, size_t hdrlen)
- +{
- + struct net_device *dev = ieee->dev;
- + u16 fc, ethertype;
- + struct ieee80211_hdr *hdr;
- + u8 *pos;
- +
- + if (skb->len < 24)
- + return 0;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- + fc = le16_to_cpu(hdr->frame_ctl);
- +
- + /* check that the frame is unicast frame to us */
- + if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- + IEEE80211_FCTL_TODS &&
- + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
- + memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
- + /* ToDS frame with own addr BSSID and DA */
- + } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- + IEEE80211_FCTL_FROMDS &&
- + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
- + /* FromDS frame with own addr as DA */
- + } else
- + return 0;
- +
- + if (skb->len < 24 + 8)
- + return 0;
- +
- + /* check for port access entity Ethernet type */
- +// pos = skb->data + 24;
- + pos = skb->data + hdrlen;
- + ethertype = (pos[6] << 8) | pos[7];
- + if (ethertype == ETH_P_PAE)
- + return 1;
- +
- + return 0;
- +}
- +
- +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
- +static inline int
- +ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
- + struct ieee80211_crypt_data *crypt)
- +{
- + struct ieee80211_hdr *hdr;
- + int res, hdrlen;
- +
- + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
- + return 0;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
- + {
- + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
- + }
- + else
- +#endif
- + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
- +
- +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- + if (ieee->tkip_countermeasures &&
- + strcmp(crypt->ops->name, "TKIP") == 0) {
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- + "received packet from " MAC_FMT "\n",
- + ieee->dev->name, MAC_ARG(hdr->addr2));
- + }
- + return -1;
- + }
- +#endif
- +
- + atomic_inc(&crypt->refcnt);
- + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
- + atomic_dec(&crypt->refcnt);
- + if (res < 0) {
- + IEEE80211_DEBUG_DROP(
- + "decryption failed (SA=" MAC_FMT
- + ") res=%d\n", MAC_ARG(hdr->addr2), res);
- + if (res == -2)
- + IEEE80211_DEBUG_DROP("Decryption failed ICV "
- + "mismatch (key %d)\n",
- + skb->data[hdrlen + 3] >> 6);
- + ieee->ieee_stats.rx_discards_undecryptable++;
- + return -1;
- + }
- +
- + return res;
- +}
- +
- +
- +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
- +static inline int
- +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
- + int keyidx, struct ieee80211_crypt_data *crypt)
- +{
- + struct ieee80211_hdr *hdr;
- + int res, hdrlen;
- +
- + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
- + return 0;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
- + {
- + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
- + }
- + else
- +#endif
- + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
- +
- + atomic_inc(&crypt->refcnt);
- + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
- + atomic_dec(&crypt->refcnt);
- + if (res < 0) {
- + printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- + " (SA=" MAC_FMT " keyidx=%d)\n",
- + ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
- + return -1;
- + }
- +
- + return 0;
- +}
- +
- +
- +/* this function is stolen from ipw2200 driver*/
- +#define IEEE_PACKET_RETRY_TIME (5*HZ)
- +static int is_duplicate_packet(struct ieee80211_device *ieee,
- + struct ieee80211_hdr *header)
- +{
- + u16 fc = le16_to_cpu(header->frame_ctl);
- + u16 sc = le16_to_cpu(header->seq_ctl);
- + u16 seq = WLAN_GET_SEQ_SEQ(sc);
- + u16 frag = WLAN_GET_SEQ_FRAG(sc);
- + u16 *last_seq, *last_frag;
- + unsigned long *last_time;
- + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
- + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
- + u8 tid;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + {
- + tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
- + }
- + else
- +#endif
- + //TO2DS and QoS
- + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
- + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
- + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
- + tid = UP2AC(tid);
- + tid ++;
- + } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
- + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
- + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
- + tid = UP2AC(tid);
- + tid ++;
- + } else { // no QoS
- + tid = 0;
- + }
- +
- + switch (ieee->iw_mode) {
- + case IW_MODE_ADHOC:
- + {
- + struct list_head *p;
- + struct ieee_ibss_seq *entry = NULL;
- + u8 *mac = header->addr2;
- + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
- + //for (pos = (head)->next; pos != (head); pos = pos->next)
- + __list_for_each(p, &ieee->ibss_mac_hash[index]) {
- + entry = list_entry(p, struct ieee_ibss_seq, list);
- + if (!memcmp(entry->mac, mac, ETH_ALEN))
- + break;
- + }
- + // if (memcmp(entry->mac, mac, ETH_ALEN)){
- + if (p == &ieee->ibss_mac_hash[index]) {
- + entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
- + if (!entry) {
- + printk(KERN_WARNING "Cannot malloc new mac entry\n");
- + return 0;
- + }
- + memcpy(entry->mac, mac, ETH_ALEN);
- + entry->seq_num[tid] = seq;
- + entry->frag_num[tid] = frag;
- + entry->packet_time[tid] = jiffies;
- + list_add(&entry->list, &ieee->ibss_mac_hash[index]);
- + return 0;
- + }
- + last_seq = &entry->seq_num[tid];
- + last_frag = &entry->frag_num[tid];
- + last_time = &entry->packet_time[tid];
- + break;
- + }
- +
- + case IW_MODE_INFRA:
- + last_seq = &ieee->last_rxseq_num[tid];
- + last_frag = &ieee->last_rxfrag_num[tid];
- + last_time = &ieee->last_packet_time[tid];
- +
- + break;
- + default:
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + {
- +#if 0
- + printk("==============> tid = %d\n", tid);
- + last_seq = &ieee->last_rxseq_num[tid];
- + last_frag = &ieee->last_rxfrag_num[tid];
- + last_time = &ieee->last_packet_time[tid];
- +#else
- + struct list_head *p;
- + struct ieee_mesh_seq *entry = NULL;
- + u8 *mac = header->addr2;
- + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
- +
- + __list_for_each(p, &ieee->mesh_mac_hash[index]) {
- + entry = list_entry(p, struct ieee_mesh_seq, list);
- + if (!memcmp(entry->mac, mac, ETH_ALEN))
- + break;
- + }
- + if (p == &ieee->mesh_mac_hash[index]) {
- + entry = kmalloc(sizeof(struct ieee_mesh_seq), GFP_ATOMIC);
- + if (!entry) {
- + printk(KERN_WARNING "Cannot malloc new mac entry for mesh\n");
- + return 0;
- + }
- + memcpy(entry->mac, mac, ETH_ALEN);
- + entry->seq_num = seq;
- + entry->frag_num = frag;
- + entry->packet_time = jiffies;
- + list_add(&entry->list, &ieee->mesh_mac_hash[index]);
- + return 0;
- + }
- + last_seq = &entry->seq_num;
- + last_frag = &entry->frag_num;
- + last_time = &entry->packet_time;
- +#endif
- + break;
- + }
- + else
- +#endif
- + return 0;
- + }
- +
- +// if(tid != 0) {
- +// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
- +// }
- + if ((*last_seq == seq) &&
- + time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
- + if (*last_frag == frag){
- + //printk(KERN_WARNING "[1] go drop!\n");
- + goto drop;
- +
- + }
- + if (*last_frag + 1 != frag)
- + /* out-of-order fragment */
- + //printk(KERN_WARNING "[2] go drop!\n");
- + goto drop;
- + } else
- + *last_seq = seq;
- +
- + *last_frag = frag;
- + *last_time = jiffies;
- + return 0;
- +
- +drop:
- +// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
- +// printk("DUP\n");
- +
- + return 1;
- +}
- +#ifdef JUST_FOR_87SEMESH
- +#define ActionHeadLen 30
- +#define WIFI_MESH_TYPE IEEE80211_FTYPE_DATA
- +#define WIFI_11S_MESH_ACTION 0x00A0
- +#endif
- +
- +/* All received frames are sent to this function. @skb contains the frame in
- + * IEEE 802.11 format, i.e., in the format it was sent over air.
- + * This function is called only as a tasklet (software IRQ). */
- +int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- + struct ieee80211_rx_stats *rx_stats)
- +{
- + struct net_device *dev = ieee->dev;
- + struct ieee80211_hdr *hdr;
- + //struct ieee80211_hdr_3addr_QOS *hdr;
- +
- + size_t hdrlen;
- + u16 fc, type, stype, sc;
- + struct net_device_stats *stats;
- + unsigned int frag;
- + u8 *payload;
- + u16 ethertype;
- +#ifdef NOT_YET
- + struct net_device *wds = NULL;
- + struct sk_buff *skb2 = NULL;
- + struct net_device *wds = NULL;
- + int frame_authorized = 0;
- + int from_assoc_ap = 0;
- + void *sta = NULL;
- +#endif
- +// u16 QOS_ctl = 0;
- + u8 dst[ETH_ALEN];
- + u8 src[ETH_ALEN];
- + u8 bssid[ETH_ALEN];
- + struct ieee80211_crypt_data *crypt = NULL;
- + int keyidx = 0;
- +
- + //Added for mesh by Lawrence.
- + //u8 status;
- + //u32 flags;
- +
- + // cheat the the hdr type
- + hdr = (struct ieee80211_hdr *)skb->data;
- + stats = &ieee->stats;
- +
- + if (skb->len < 10) {
- + printk(KERN_INFO "%s: SKB length < 10\n",
- + dev->name);
- + goto rx_dropped;
- + }
- +#if 0
- +//{added by david for filter the packet listed in the filter table
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
- + {
- + if(!ieee->ext_patch_ieee80211_acl_query(ieee, hdr->addr2))
- + goto rx_dropped;
- + }
- +#endif
- +//}
- +#endif
- + fc = le16_to_cpu(hdr->frame_ctl);
- + type = WLAN_FC_GET_TYPE(fc);
- + stype = WLAN_FC_GET_STYPE(fc);
- +
- + //Because 87se's bad feature,do more handle.
- +#ifdef JUST_FOR_87SEMESH
- +
- +u8 tmphead[ActionHeadLen];
- + if(type ==WIFI_MESH_TYPE && stype== WIFI_11S_MESH_ACTION )
- + //head=sizeof(struct ieee80211_hdr)=30
- + {
- + memset(tmphead,0,ActionHeadLen);
- + memcpy(tmphead,skb->data,ActionHeadLen);
- +
- + skb_pull(skb,ActionHeadLen+2);
- + memcpy(skb_push(skb,ActionHeadLen),tmphead,ActionHeadLen);
- + hdr = (struct ieee80211_hdr *)skb->data;
- + }
- +
- +#endif
- + sc = le16_to_cpu(hdr->seq_ctl);
- +
- + frag = WLAN_GET_SEQ_FRAG(sc);
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
- + {
- + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
- + if(skb->len < hdrlen)
- + goto rx_dropped;
- + }
- + else
- +#endif
- + hdrlen = ieee80211_get_hdrlen(fc);
- +
- +#ifdef NOT_YET
- +#if WIRELESS_EXT > 15
- + /* Put this code here so that we avoid duplicating it in all
- + * Rx paths. - Jean II */
- +#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
- + /* If spy monitoring on */
- + if (iface->spy_data.spy_number > 0) {
- + struct iw_quality wstats;
- + wstats.level = rx_stats->signal;
- + wstats.noise = rx_stats->noise;
- + wstats.updated = 6; /* No qual value */
- + /* Update spy records */
- + wireless_spy_update(dev, hdr->addr2, &wstats);
- + }
- +#endif /* IW_WIRELESS_SPY */
- +#endif /* WIRELESS_EXT > 15 */
- + hostap_update_rx_stats(local->ap, hdr, rx_stats);
- +#endif
- +
- +#if WIRELESS_EXT > 15
- + if (ieee->iw_mode == IW_MODE_MONITOR) {
- + ieee80211_monitor_rx(ieee, skb, rx_stats);
- + stats->rx_packets++;
- + stats->rx_bytes += skb->len;
- + return 1;
- + }
- +#endif
- + if (ieee->host_decrypt) {
- + int idx = 0;
- + if (skb->len >= hdrlen + 3)
- + idx = skb->data[hdrlen + 3] >> 6;
- +#ifdef _RTL8187_EXT_PATCH_
- +
- + crypt = ieee->cryptlist[0]->crypt[idx];
- +#if 0
- + {
- + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2);
- + if (i == -1)
- + {
- + printk("error find entry in entry list\n");
- + goto rx_dropped;
- + }
- + //printk("%s():"MAC_FMT", find in index:%d", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
- + crypt = ieee->cryptlist[i]->crypt[idx];
- + }
- +#endif
- +#else
- + crypt = ieee->crypt[idx];
- +#endif
- +
- +#ifdef NOT_YET
- + sta = NULL;
- +
- + /* Use station specific key to override default keys if the
- + * receiver address is a unicast address ("individual RA"). If
- + * bcrx_sta_key parameter is set, station specific key is used
- + * even with broad/multicast targets (this is against IEEE
- + * 802.11, but makes it easier to use different keys with
- + * stations that do not support WEP key mapping). */
- +
- + if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
- + (void) hostap_handle_sta_crypto(local, hdr, &crypt,
- + &sta);
- +#endif
- +
- + /* allow NULL decrypt to indicate an station specific override
- + * for default encryption */
- + if (crypt && (crypt->ops == NULL ||
- + crypt->ops->decrypt_mpdu == NULL))
- + crypt = NULL;
- +
- + if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
- + /* This seems to be triggered by some (multicast?)
- + * frames from other than current BSS, so just drop the
- + * frames silently instead of filling system log with
- + * these reports. */
- + IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- + " (SA=" MAC_FMT ")\n",
- + MAC_ARG(hdr->addr2));
- + ieee->ieee_stats.rx_discards_undecryptable++;
- + goto rx_dropped;
- + }
- + }
- +
- + if (skb->len < IEEE80211_DATA_HDR3_LEN)
- + goto rx_dropped;
- +
- + // if QoS enabled, should check the sequence for each of the AC
- + if (is_duplicate_packet(ieee, hdr))
- + goto rx_dropped;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire )
- + ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb );
- +#endif
- +
- + if (type == IEEE80211_FTYPE_MGMT) {
- +
- + #if 0
- + if ( stype == IEEE80211_STYPE_AUTH &&
- + fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
- + (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
- + {
- + printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
- + "from " MAC_FMT "\n", dev->name,
- + MAC_ARG(hdr->addr2));
- + /* TODO: could inform hostapd about this so that it
- + * could send auth failure report */
- + goto rx_dropped;
- + }
- + #endif
- +
- +
- + if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
- + goto rx_dropped;
- + else
- + goto rx_exit;
- + }
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
- + {
- + if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
- + {
- + goto rx_exit;
- + }
- + }
- +#endif
- +
- + /* Data frame - extract src/dst addresses */
- + switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- + case IEEE80211_FCTL_FROMDS:
- + memcpy(dst, hdr->addr1, ETH_ALEN);
- + memcpy(src, hdr->addr3, ETH_ALEN);
- + memcpy(bssid, hdr->addr2, ETH_ALEN);
- + break;
- + case IEEE80211_FCTL_TODS:
- + memcpy(dst, hdr->addr3, ETH_ALEN);
- + memcpy(src, hdr->addr2, ETH_ALEN);
- + memcpy(bssid, hdr->addr1, ETH_ALEN);
- + break;
- + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- + if (skb->len < IEEE80211_DATA_HDR4_LEN)
- + goto rx_dropped;
- + memcpy(dst, hdr->addr3, ETH_ALEN);
- + memcpy(src, hdr->addr4, ETH_ALEN);
- + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
- + break;
- + case 0:
- + memcpy(dst, hdr->addr1, ETH_ALEN);
- + memcpy(src, hdr->addr2, ETH_ALEN);
- + memcpy(bssid, hdr->addr3, ETH_ALEN);
- + break;
- + }
- +
- +#ifdef NOT_YET
- + if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
- + goto rx_dropped;
- + if (wds) {
- + skb->dev = dev = wds;
- + stats = hostap_get_stats(dev);
- + }
- +
- + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
- + (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
- + ieee->stadev &&
- + memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
- + /* Frame from BSSID of the AP for which we are a client */
- + skb->dev = dev = ieee->stadev;
- + stats = hostap_get_stats(dev);
- + from_assoc_ap = 1;
- + }
- +#endif
- +
- + dev->last_rx = jiffies;
- +
- +#ifdef NOT_YET
- + if ((ieee->iw_mode == IW_MODE_MASTER ||
- + ieee->iw_mode == IW_MODE_REPEAT) &&
- + !from_assoc_ap) {
- + switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
- + wds != NULL)) {
- + case AP_RX_CONTINUE_NOT_AUTHORIZED:
- + frame_authorized = 0;
- + break;
- + case AP_RX_CONTINUE:
- + frame_authorized = 1;
- + break;
- + case AP_RX_DROP:
- + goto rx_dropped;
- + case AP_RX_EXIT:
- + goto rx_exit;
- + }
- + }
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
- + {
- + if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
- + goto rx_dropped;
- + }
- + else
- +#endif
- + /* Nullfunc frames may have PS-bit set, so they must be passed to
- + * hostap_handle_sta_rx() before being dropped here. */
- + if (stype != IEEE80211_STYPE_DATA &&
- + stype != IEEE80211_STYPE_DATA_CFACK &&
- + stype != IEEE80211_STYPE_DATA_CFPOLL &&
- + stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
- + stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
- + ) {
- + if (stype != IEEE80211_STYPE_NULLFUNC)
- + IEEE80211_DEBUG_DROP(
- + "RX: dropped data frame "
- + "with no data (type=0x%02x, "
- + "subtype=0x%02x, len=%d)\n",
- + type, stype, skb->len);
- + goto rx_dropped;
- + }
- +
- + if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
- + goto rx_dropped;
- +
- + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
- +#ifdef _RTL8187_EXT_PATCH_
- + if (ieee->host_decrypt && crypt) {
- + int idx = 0;
- + if (skb->len >= hdrlen + 3)
- + idx = skb->data[hdrlen + 3] >> 6;
- + if (ieee->iw_ext_mode == ieee->iw_mode) //if in mesh mode
- + {
- + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2, 0);
- + if (i == -1)
- + {
- + printk("error find entry in entry list\n");
- + goto rx_dropped;
- + }
- + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
- + if (ieee->cryptlist[i]&&ieee->cryptlist[i]->crypt[idx])
- + crypt = ieee->cryptlist[i]->crypt[idx];
- +
- + else
- + crypt = NULL;
- + }
- + else
- + crypt = ieee->cryptlist[0]->crypt[idx];
- + }
- +#endif
- +
- + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
- + goto rx_dropped;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- +
- + /* skb: hdr + (possibly fragmented) plaintext payload */
- + // PR: FIXME: hostap has additional conditions in the "if" below:
- + // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- + if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
- + int flen;
- + struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
- + IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
- +
- + if (!frag_skb) {
- + IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
- + "Rx cannot get skb from fragment "
- + "cache (morefrag=%d seq=%u frag=%u)\n",
- + (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- + WLAN_GET_SEQ_SEQ(sc), frag);
- + goto rx_dropped;
- + }
- + flen = skb->len;
- + if (frag != 0)
- + flen -= hdrlen;
- +
- + if (frag_skb->tail + flen > frag_skb->end) {
- + printk(KERN_WARNING "%s: host decrypted and "
- + "reassembled frame did not fit skb\n",
- + dev->name);
- + ieee80211_frag_cache_invalidate(ieee, hdr);
- + goto rx_dropped;
- + }
- +
- + if (frag == 0) {
- + /* copy first fragment (including full headers) into
- + * beginning of the fragment cache skb */
- + memcpy(skb_put(frag_skb, flen), skb->data, flen);
- + } else {
- + /* append frame payload to the end of the fragment
- + * cache skb */
- + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
- + flen);
- + }
- + dev_kfree_skb_any(skb);
- + skb = NULL;
- +
- + if (fc & IEEE80211_FCTL_MOREFRAGS) {
- + /* more fragments expected - leave the skb in fragment
- + * cache for now; it will be delivered to upper layers
- + * after all fragments have been received */
- + goto rx_exit;
- + }
- +
- + /* this was the last fragment and the frame will be
- + * delivered, so remove skb from fragment cache */
- + skb = frag_skb;
- + hdr = (struct ieee80211_hdr *) skb->data;
- + ieee80211_frag_cache_invalidate(ieee, hdr);
- + }
- +
- + /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
- + * encrypted/authenticated */
- + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- + ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
- + goto rx_dropped;
- +
- + hdr = (struct ieee80211_hdr *) skb->data;
- + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
- + if (/*ieee->ieee802_1x &&*/
- + ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- +
- +#ifdef CONFIG_IEEE80211_DEBUG
- + /* pass unencrypted EAPOL frames even if encryption is
- + * configured */
- + struct eapol *eap = (struct eapol *)(skb->data +
- + 24);
- + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- + eap_get_type(eap->type));
- +#endif
- + } else {
- + IEEE80211_DEBUG_DROP(
- + "encryption configured, but RX "
- + "frame not encrypted (SA=" MAC_FMT ")\n",
- + MAC_ARG(hdr->addr2));
- + goto rx_dropped;
- + }
- + }
- +
- +#ifdef CONFIG_IEEE80211_DEBUG
- + if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
- + ieee80211_is_eapol_frame(ieee, skb)) {
- + struct eapol *eap = (struct eapol *)(skb->data +
- + 24);
- + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- + eap_get_type(eap->type));
- + }
- +#endif
- +
- + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
- + !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- + IEEE80211_DEBUG_DROP(
- + "dropped unencrypted RX data "
- + "frame from " MAC_FMT
- + " (drop_unencrypted=1)\n",
- + MAC_ARG(hdr->addr2));
- + goto rx_dropped;
- + }
- +/*
- + if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- + printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
- + }
- +*/
- + /* skb: hdr + (possible reassembled) full plaintext payload */
- + payload = skb->data + hdrlen;
- + ethertype = (payload[6] << 8) | payload[7];
- +
- +#ifdef NOT_YET
- + /* If IEEE 802.1X is used, check whether the port is authorized to send
- + * the received frame. */
- + if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
- + if (ethertype == ETH_P_PAE) {
- + printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
- + dev->name);
- + if (ieee->hostapd && ieee->apdev) {
- + /* Send IEEE 802.1X frames to the user
- + * space daemon for processing */
- + prism2_rx_80211(ieee->apdev, skb, rx_stats,
- + PRISM2_RX_MGMT);
- + ieee->apdevstats.rx_packets++;
- + ieee->apdevstats.rx_bytes += skb->len;
- + goto rx_exit;
- + }
- + } else if (!frame_authorized) {
- + printk(KERN_DEBUG "%s: dropped frame from "
- + "unauthorized port (IEEE 802.1X): "
- + "ethertype=0x%04x\n",
- + dev->name, ethertype);
- + goto rx_dropped;
- + }
- + }
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
- + {
- + if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
- + {
- + stats->rx_packets++;
- + stats->rx_bytes += skb->len;
- + goto rx_exit;
- + }
- + else
- + goto rx_dropped;
- + }
- +#endif
- + ieee->NumRxDataInPeriod++;
- +// ieee->NumRxOkTotal++;
- + /* convert hdr + possible LLC headers into Ethernet header */
- + if (skb->len - hdrlen >= 8 &&
- + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
- + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- + /* remove RFC1042 or Bridge-Tunnel encapsulation and
- + * replace EtherType */
- + skb_pull(skb, hdrlen + SNAP_SIZE);
- + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- + } else {
- + u16 len;
- + /* Leave Ethernet header part of hdr and full payload */
- + skb_pull(skb, hdrlen);
- + len = htons(skb->len);
- + memcpy(skb_push(skb, 2), &len, 2);
- + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- + }
- +
- +#ifdef NOT_YET
- + if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- + IEEE80211_FCTL_TODS) &&
- + skb->len >= ETH_HLEN + ETH_ALEN) {
- + /* Non-standard frame: get addr4 from its bogus location after
- + * the payload */
- + memcpy(skb->data + ETH_ALEN,
- + skb->data + skb->len - ETH_ALEN, ETH_ALEN);
- + skb_trim(skb, skb->len - ETH_ALEN);
- + }
- +#endif
- +
- + stats->rx_packets++;
- + stats->rx_bytes += skb->len;
- +
- +#ifdef NOT_YET
- + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
- + ieee->ap->bridge_packets) {
- + if (dst[0] & 0x01) {
- + /* copy multicast frame both to the higher layers and
- + * to the wireless media */
- + ieee->ap->bridged_multicast++;
- + skb2 = skb_clone(skb, GFP_ATOMIC);
- + if (skb2 == NULL)
- + printk(KERN_DEBUG "%s: skb_clone failed for "
- + "multicast frame\n", dev->name);
- + } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
- + /* send frame directly to the associated STA using
- + * wireless media and not passing to higher layers */
- + ieee->ap->bridged_unicast++;
- + skb2 = skb;
- + skb = NULL;
- + }
- + }
- +
- + if (skb2 != NULL) {
- + /* send to wireless media */
- + skb2->protocol = __constant_htons(ETH_P_802_3);
- + skb2->mac.raw = skb2->nh.raw = skb2->data;
- + /* skb2->nh.raw = skb2->data + ETH_HLEN; */
- + skb2->dev = dev;
- + dev_queue_xmit(skb2);
- + }
- +
- +#endif
- + if (skb) {
- + //printk("0skb_len(%d)\n", skb->len);
- + skb->protocol = eth_type_trans(skb, dev);
- + memset(skb->cb, 0, sizeof(skb->cb));
- + skb->dev = dev;
- + skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
- + //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
- + ieee->last_rx_ps_time = jiffies;
- + //printk("1skb_len(%d)\n", skb->len);
- + netif_rx(skb);
- + }
- +
- +//by lizhaoming for LED_RX 2008.6.23
- +#ifdef LED_SHIN
- +// printk("==================>data rcvd\n");
- + ieee->ieee80211_led_contorl(dev,LED_CTL_RX);
- +#endif
- +
- + rx_exit:
- +#ifdef NOT_YET
- + if (sta)
- + hostap_handle_sta_release(sta);
- +#endif
- + return 1;
- +
- + rx_dropped:
- + stats->rx_dropped++;
- +#if 0
- + int i;
- + 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);
- + for (i = 0; i < skb->len; i++) {
- + if (i % 16 == 0) printk("\n\t");
- + printk("%2x ", *(skb->data+i));
- + }
- +
- + printk("\n");
- +#endif
- + /* Returning 0 indicates to caller that we have not handled the SKB--
- + * so it is still allocated and can be used again by underlying
- + * hardware as a DMA target */
- + return 0;
- +}
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
- +{
- + u8 *payload;
- + u16 ethertype;
- +
- + /* skb: hdr + (possible reassembled) full plaintext payload */
- + payload = skb->data + hdrlen;
- + ethertype = (payload[6] << 8) | payload[7];
- +
- + /* convert hdr + possible LLC headers into Ethernet header */
- + if (skb->len - hdrlen >= 8 &&
- + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
- + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- + /* remove RFC1042 or Bridge-Tunnel encapsulation and
- + * replace EtherType */
- + skb_pull(skb, hdrlen + SNAP_SIZE);
- + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- + } else {
- + u16 len;
- + /* Leave Ethernet header part of hdr and full payload */
- + skb_pull(skb, hdrlen);
- + len = htons(skb->len);
- + memcpy(skb_push(skb, 2), &len, 2);
- + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- + }
- +
- + return 1;
- +}
- +#endif // _RTL8187_EXT_PATCH_
- +
- +
- +#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
- +
- +static inline int ieee80211_is_ofdm_rate(u8 rate)
- +{
- + switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
- + case IEEE80211_OFDM_RATE_6MB:
- + case IEEE80211_OFDM_RATE_9MB:
- + case IEEE80211_OFDM_RATE_12MB:
- + case IEEE80211_OFDM_RATE_18MB:
- + case IEEE80211_OFDM_RATE_24MB:
- + case IEEE80211_OFDM_RATE_36MB:
- + case IEEE80211_OFDM_RATE_48MB:
- + case IEEE80211_OFDM_RATE_54MB:
- + return 1;
- + }
- + return 0;
- +}
- +
- +
- +//
- +// Description:
- +// Translate 0-100 signal strength index into dBm.
- +//
- +int
- +TranslateToDbm8187(
- + unsigned char SignalStrengthIndex // 0-100 index.
- + )
- +{
- + unsigned char SignalPower; // in dBm.
- +
- + // Translate to dBm (x=0.5y-95).
- + //SignalPower = (int)((SignalStrengthIndex + 1) >> 1);
- + SignalPower = (int)SignalStrengthIndex * 7 / 10;
- + SignalPower -= 95;
- +// printk("==>SignalPower:%d\n", SignalPower);
- + return SignalPower;
- +}
- +
- +static inline int ieee80211_SignalStrengthTranslate(
- + int CurrSS
- + )
- +{
- + int RetSS;
- +
- + // Step 1. Scale mapping.
- + if(CurrSS >= 71 && CurrSS <= 100)
- + {
- + RetSS = 95 + (((CurrSS - 70) / 6 == 5) ? 5 : ((CurrSS - 70) / 6 + 1));
- + }
- + else if(CurrSS >= 41 && CurrSS <= 70)
- + {
- + RetSS = 83 + ((CurrSS - 40) / 3);
- + }
- + else if(CurrSS >= 31 && CurrSS <= 40)
- + {
- + RetSS = 71 + (CurrSS - 30);
- + }
- + else if(CurrSS >= 21 && CurrSS <= 30)
- + {
- + RetSS = 59 + (CurrSS - 20);
- + }
- + else if(CurrSS >= 5 && CurrSS <= 20)
- + {
- + RetSS = 47 + (((CurrSS - 5) * 2) / 3);
- + }
- + else if(CurrSS == 4)
- + {
- + RetSS = 37;
- + }
- + else if(CurrSS == 3)
- + {
- + RetSS = 27;
- + }
- + else if(CurrSS == 2)
- + {
- + RetSS = 18;
- + }
- + else if(CurrSS == 1)
- + {
- + RetSS = 9;
- + }
- + else
- + {
- + RetSS = CurrSS;
- + }
- + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
- +
- + // Step 2. Smoothing.
- +
- + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
- +
- + return RetSS;
- +}
- +
- +#ifdef ENABLE_DOT11D
- +static inline void ieee80211_extract_country_ie(
- + struct ieee80211_device *ieee,
- + struct ieee80211_info_element *info_element,
- + struct ieee80211_network *network,
- + u8 * addr2
- +)
- +{
- +#if 0
- + u32 i = 0;
- + u8 * p = (u8*)info_element->data;
- + printk("-----------------------\n");
- + printk("%s Country IE:", network->ssid);
- + for(i=0; i<info_element->len; i++)
- + printk("\t%2.2x", *(p+i));
- + printk("\n-----------------------\n");
- +#endif
- + if(IS_DOT11D_ENABLE(ieee))
- + {
- + if(info_element->len!= 0)
- + {
- + memcpy(network->CountryIeBuf, info_element->data, info_element->len);
- + network->CountryIeLen = info_element->len;
- +
- + if(!IS_COUNTRY_IE_VALID(ieee))
- + {
- + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
- + }
- + }
- +
- + //
- + // 070305, rcnjko: I update country IE watch dog here because
- + // some AP (e.g. Cisco 1242) don't include country IE in their
- + // probe response frame.
- + //
- + if(IS_EQUAL_CIE_SRC(ieee, addr2) )
- + {
- + UPDATE_CIE_WATCHDOG(ieee);
- + }
- + }
- +
- +}
- +#endif
- +
- +
- + inline int ieee80211_network_init(
- + struct ieee80211_device *ieee,
- + struct ieee80211_probe_response *beacon,
- + struct ieee80211_network *network,
- + struct ieee80211_rx_stats *stats)
- +{
- +#ifdef CONFIG_IEEE80211_DEBUG
- + char rates_str[64];
- + char *p;
- +#endif
- + struct ieee80211_info_element *info_element;
- + u16 left;
- + u8 i;
- + short offset;
- +
- + /* Pull out fixed field data */
- + memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
- + network->capability = beacon->capability;
- + network->last_scanned = jiffies;
- + network->time_stamp[0] = beacon->time_stamp[0];
- + network->time_stamp[1] = beacon->time_stamp[1];
- + network->beacon_interval = beacon->beacon_interval;
- + /* Where to pull this? beacon->listen_interval;*/
- + network->listen_interval = 0x0A;
- + network->rates_len = network->rates_ex_len = 0;
- + network->last_associate = 0;
- + network->ssid_len = 0;
- + network->flags = 0;
- + network->atim_window = 0;
- + network->QoS_Enable = 0;
- +#ifdef THOMAS_TURBO
- + network->Turbo_Enable = 0;
- +#endif
- +#ifdef ENABLE_DOT11D
- + network->CountryIeLen = 0;
- + memset(network->CountryIeBuf, 0, MAX_IE_LEN);
- +#endif
- +
- + if (stats->freq == IEEE80211_52GHZ_BAND) {
- + /* for A band (No DS info) */
- + network->channel = stats->received_channel;
- + } else
- + network->flags |= NETWORK_HAS_CCK;
- +
- + network->wpa_ie_len = 0;
- + network->rsn_ie_len = 0;
- +
- + info_element = &beacon->info_element;
- + left = stats->len - ((void *)info_element - (void *)beacon);
- + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
- + IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
- + info_element->len + sizeof(struct ieee80211_info_element),
- + left);
- + return 1;
- + }
- +
- + switch (info_element->id) {
- + case MFIE_TYPE_SSID:
- + if (ieee80211_is_empty_essid(info_element->data,
- + info_element->len)) {
- + network->flags |= NETWORK_EMPTY_ESSID;
- + break;
- + }
- +
- + network->ssid_len = min(info_element->len,
- + (u8)IW_ESSID_MAX_SIZE);
- + memcpy(network->ssid, info_element->data, network->ssid_len);
- + if (network->ssid_len < IW_ESSID_MAX_SIZE)
- + memset(network->ssid + network->ssid_len, 0,
- + IW_ESSID_MAX_SIZE - network->ssid_len);
- +
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
- + network->ssid, network->ssid_len);
- + break;
- +
- + case MFIE_TYPE_RATES:
- +#ifdef CONFIG_IEEE80211_DEBUG
- + p = rates_str;
- +#endif
- + network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
- + for (i = 0; i < network->rates_len; i++) {
- + network->rates[i] = info_element->data[i];
- +#ifdef CONFIG_IEEE80211_DEBUG
- + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
- +#endif
- + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
- + network->flags |= NETWORK_HAS_OFDM;
- + if (info_element->data[i] &
- + IEEE80211_BASIC_RATE_MASK)
- + network->flags &=
- + ~NETWORK_HAS_CCK;
- + }
- + }
- +
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
- + rates_str, network->rates_len);
- + break;
- +
- + case MFIE_TYPE_RATES_EX:
- +#ifdef CONFIG_IEEE80211_DEBUG
- + p = rates_str;
- +#endif
- + network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
- + for (i = 0; i < network->rates_ex_len; i++) {
- + network->rates_ex[i] = info_element->data[i];
- +#ifdef CONFIG_IEEE80211_DEBUG
- + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
- +#endif
- + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
- + network->flags |= NETWORK_HAS_OFDM;
- + if (info_element->data[i] &
- + IEEE80211_BASIC_RATE_MASK)
- + network->flags &=
- + ~NETWORK_HAS_CCK;
- + }
- + }
- +
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
- + rates_str, network->rates_ex_len);
- + break;
- +
- + case MFIE_TYPE_DS_SET:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
- + info_element->data[0]);
- + if (stats->freq == IEEE80211_24GHZ_BAND)
- + network->channel = info_element->data[0];
- + break;
- +
- + case MFIE_TYPE_FH_SET:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
- + break;
- +
- + case MFIE_TYPE_CF_SET:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
- + break;
- +
- + case MFIE_TYPE_TIM:
- +
- + if(info_element->len < 4)
- + break;
- +
- + network->dtim_period = info_element->data[1];
- +
- + if(ieee->state != IEEE80211_LINKED)
- + break;
- +
- + network->last_dtim_sta_time[0] = stats->mac_time[0];
- + network->last_dtim_sta_time[1] = stats->mac_time[1];
- +
- + network->dtim_data = IEEE80211_DTIM_VALID;
- +
- + if(info_element->data[0] != 0)
- + break;
- +
- + if(info_element->data[2] & 1)
- + network->dtim_data |= IEEE80211_DTIM_MBCAST;
- +
- + offset = (info_element->data[2] >> 1)*2;
- +
- + //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
- +
- + if(ieee->assoc_id < offset ||
- + ieee->assoc_id > 8*(offset + info_element->len -3))
- +
- + break;
- +
- +
- + offset = offset + ieee->assoc_id / 8;// + ((aid % 8)? 0 : 1) ;
- +
- + // printk("offset:%x data:%x, ucast:%d\n", offset,
- + // info_element->data[3+offset] ,
- + // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
- +
- + if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
- + network->dtim_data |= IEEE80211_DTIM_UCAST;
- +
- + break;
- +
- + case MFIE_TYPE_IBSS_SET:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
- + break;
- +
- + case MFIE_TYPE_CHALLENGE:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
- + break;
- +
- + case MFIE_TYPE_GENERIC:
- + //nic is 87B
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
- + info_element->len);
- + if (info_element->len >= 4 &&
- + info_element->data[0] == 0x00 &&
- + info_element->data[1] == 0x50 &&
- + info_element->data[2] == 0xf2 &&
- + info_element->data[3] == 0x01) {
- + network->wpa_ie_len = min(info_element->len + 2,
- + MAX_WPA_IE_LEN);
- + memcpy(network->wpa_ie, info_element,
- + network->wpa_ie_len);
- + }
- +
- +#ifdef THOMAS_TURBO
- + if (info_element->len == 7 &&
- + info_element->data[0] == 0x00 &&
- + info_element->data[1] == 0xe0 &&
- + info_element->data[2] == 0x4c &&
- + info_element->data[3] == 0x01 &&
- + info_element->data[4] == 0x02) {
- + network->Turbo_Enable = 1;
- + }
- +#endif
- + if (1 == stats->nic_type) {//nic 87
- + break;
- + }
- +
- + if (info_element->len >= 5 &&
- + info_element->data[0] == 0x00 &&
- + info_element->data[1] == 0x50 &&
- + info_element->data[2] == 0xf2 &&
- + info_element->data[3] == 0x02 &&
- + info_element->data[4] == 0x00) {
- + //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
- + //WMM Information Element
- + network->wmm_info = info_element->data[6];
- + network->QoS_Enable = 1;
- + }
- +
- + if (info_element->len >= 8 &&
- + info_element->data[0] == 0x00 &&
- + info_element->data[1] == 0x50 &&
- + info_element->data[2] == 0xf2 &&
- + info_element->data[3] == 0x02 &&
- + info_element->data[4] == 0x01) {
- + // Not care about version at present.
- + //WMM Information Element
- + //printk(KERN_WARNING "wmm info¶m updated: %x\n", info_element->data[6]);
- + network->wmm_info = info_element->data[6];
- + //WMM Parameter Element
- + memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
- + network->QoS_Enable = 1;
- + }
- + break;
- +
- + case MFIE_TYPE_RSN:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
- + info_element->len);
- + network->rsn_ie_len = min(info_element->len + 2,
- + MAX_WPA_IE_LEN);
- + memcpy(network->rsn_ie, info_element,
- + network->rsn_ie_len);
- + break;
- +
- +#ifdef ENABLE_DOT11D
- + case MFIE_TYPE_COUNTRY:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
- + info_element->len);
- +// printk("=====>Receive <%s> Country IE\n",network->ssid);
- + ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
- + break;
- +#endif
- +
- + default:
- + IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
- + info_element->id);
- + break;
- + }
- +
- + left -= sizeof(struct ieee80211_info_element_hdr) +
- + info_element->len;
- + info_element = (struct ieee80211_info_element *)
- + &info_element->data[info_element->len];
- + }
- +
- + network->mode = 0;
- + if (stats->freq == IEEE80211_52GHZ_BAND)
- + network->mode = IEEE_A;
- + else {
- + if (network->flags & NETWORK_HAS_OFDM)
- + network->mode |= IEEE_G;
- + if (network->flags & NETWORK_HAS_CCK)
- + network->mode |= IEEE_B;
- + }
- +
- + if (network->mode == 0) {
- + IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
- + "network.\n",
- + escape_essid(network->ssid,
- + network->ssid_len),
- + MAC_ARG(network->bssid));
- + return 1;
- + }
- +
- + if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
- + network->flags |= NETWORK_EMPTY_ESSID;
- +
- +#if 1
- + //if(strcmp(network->ssid, "linksys_lzm000") == 0)
- + // printk("----signalstrength = %d ", stats->signalstrength);
- + stats->signal = TranslateToDbm8187(stats->signalstrength);
- + //stats->noise = stats->signal - stats->noise;
- + stats->noise = TranslateToDbm8187(100 - stats->signalstrength) - 25;
- +#endif
- + memcpy(&network->stats, stats, sizeof(network->stats));
- +
- + //YJ,test,080611
- + //if(strcmp(network->ssid, "ZyXEL") == 0)
- + // IEEE_NET_DUMP(network);
- +
- + return 0;
- +}
- +
- +static inline int is_same_network(struct ieee80211_network *src,
- + struct ieee80211_network *dst,
- + struct ieee80211_device * ieee)
- +{
- + /* A network is only a duplicate if the channel, BSSID, ESSID
- + * and the capability field (in particular IBSS and BSS) all match.
- + * We treat all <hidden> with the same BSSID and channel
- + * as one network */
- + return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
- + //((src->ssid_len == dst->ssid_len) &&
- + (src->channel == dst->channel) &&
- + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
- + (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
- + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
- + ((src->capability & WLAN_CAPABILITY_IBSS) ==
- + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
- + ((src->capability & WLAN_CAPABILITY_BSS) ==
- + (dst->capability & WLAN_CAPABILITY_BSS)));
- +}
- +
- +inline void update_network(struct ieee80211_network *dst,
- + struct ieee80211_network *src)
- +{
- + unsigned char quality = src->stats.signalstrength;
- + unsigned char signal = 0;
- + unsigned char noise = 0;
- + if(dst->stats.signalstrength > 0) {
- + quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
- + }
- + signal = TranslateToDbm8187(quality);
- + //noise = signal - src->stats.noise;
- + if(dst->stats.noise > 0)
- + noise = (dst->stats.noise * 5 + src->stats.noise)/6;
- + //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
- +// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
- + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
- + dst->stats.signalstrength = quality;
- + dst->stats.signal = signal;
- + dst->stats.noise = noise;
- + dst->capability = src->capability;
- + memcpy(dst->rates, src->rates, src->rates_len);
- + dst->rates_len = src->rates_len;
- + memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
- + dst->rates_ex_len = src->rates_ex_len;
- +
- + //YJ,add,080819,for hidden ap
- + if(src->ssid_len > 0)
- + {
- + //if(src->ssid_len == 13)
- + // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
- + memset(dst->ssid, 0, dst->ssid_len);
- + dst->ssid_len = src->ssid_len;
- + memcpy(dst->ssid, src->ssid, src->ssid_len);
- + }
- + //YJ,add,080819,for hidden ap,end
- + dst->channel = src->channel;
- + dst->mode = src->mode;
- + dst->flags = src->flags;
- + dst->time_stamp[0] = src->time_stamp[0];
- + dst->time_stamp[1] = src->time_stamp[1];
- +
- + dst->beacon_interval = src->beacon_interval;
- + dst->listen_interval = src->listen_interval;
- + dst->atim_window = src->atim_window;
- + dst->dtim_period = src->dtim_period;
- + dst->dtim_data = src->dtim_data;
- + dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
- + dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
- +
- + memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
- + dst->wpa_ie_len = src->wpa_ie_len;
- + memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
- + dst->rsn_ie_len = src->rsn_ie_len;
- +
- + dst->last_scanned = jiffies;
- + /* dst->last_associate is not overwritten */
- +#if 1
- + dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
- +/*
- + if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
- + memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
- + }
- +*/
- + if(src->wmm_param[0].ac_aci_acm_aifsn|| \
- + src->wmm_param[1].ac_aci_acm_aifsn|| \
- + src->wmm_param[2].ac_aci_acm_aifsn|| \
- + src->wmm_param[1].ac_aci_acm_aifsn) {
- + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
- + }
- + dst->QoS_Enable = src->QoS_Enable;
- +#else
- + dst->QoS_Enable = 1;//for Rtl8187 simulation
- +#endif
- + dst->SignalStrength = src->SignalStrength;
- +#ifdef THOMAS_TURBO
- + dst->Turbo_Enable = src->Turbo_Enable;
- +#endif
- +#ifdef ENABLE_DOT11D
- + dst->CountryIeLen = src->CountryIeLen;
- + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
- +#endif
- +
- +}
- +
- +inline void ieee80211_process_probe_response(
- + struct ieee80211_device *ieee,
- + struct ieee80211_probe_response *beacon,
- + struct ieee80211_rx_stats *stats)
- +{
- + struct ieee80211_network network;
- + struct ieee80211_network *target;
- + struct ieee80211_network *oldest = NULL;
- +#ifdef CONFIG_IEEE80211_DEBUG
- + struct ieee80211_info_element *info_element = &beacon->info_element;
- +#endif
- + unsigned long flags;
- + short renew;
- + u8 wmm_info;
- + u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0;
- +
- + memset(&network, 0, sizeof(struct ieee80211_network));
- +//rz
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) {
- + ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats);
- + return;
- + }
- +#endif
- + IEEE80211_DEBUG_SCAN(
- + "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- + escape_essid(info_element->data, info_element->len),
- + MAC_ARG(beacon->header.addr3),
- + (beacon->capability & (1<<0xf)) ? '1' : '0',
- + (beacon->capability & (1<<0xe)) ? '1' : '0',
- + (beacon->capability & (1<<0xd)) ? '1' : '0',
- + (beacon->capability & (1<<0xc)) ? '1' : '0',
- + (beacon->capability & (1<<0xb)) ? '1' : '0',
- + (beacon->capability & (1<<0xa)) ? '1' : '0',
- + (beacon->capability & (1<<0x9)) ? '1' : '0',
- + (beacon->capability & (1<<0x8)) ? '1' : '0',
- + (beacon->capability & (1<<0x7)) ? '1' : '0',
- + (beacon->capability & (1<<0x6)) ? '1' : '0',
- + (beacon->capability & (1<<0x5)) ? '1' : '0',
- + (beacon->capability & (1<<0x4)) ? '1' : '0',
- + (beacon->capability & (1<<0x3)) ? '1' : '0',
- + (beacon->capability & (1<<0x2)) ? '1' : '0',
- + (beacon->capability & (1<<0x1)) ? '1' : '0',
- + (beacon->capability & (1<<0x0)) ? '1' : '0');
- +
- + if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- + IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
- + escape_essid(info_element->data,
- + info_element->len),
- + MAC_ARG(beacon->header.addr3),
- + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- + IEEE80211_STYPE_PROBE_RESP ?
- + "PROBE RESPONSE" : "BEACON");
- + return;
- + }
- +
- +#ifdef ENABLE_DOT11D
- + // For Asus EeePc request,
- + // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
- + // wireless adapter should follow the country code.
- + // (2) If there is no any country code in beacon,
- + // then wireless adapter should do active scan from ch1~11 and
- + // passive scan from ch12~14
- + if(ieee->bGlobalDomain)
- + {
- + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
- + {
- + // Case 1: Country code
- + if(IS_COUNTRY_IE_VALID(ieee) )
- + {
- + if( !IsLegalChannel(ieee, network.channel) )
- + {
- + printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
- + return;
- + }
- + }
- + // Case 2: No any country code.
- + else
- + {
- + // Filter over channel ch12~14
- + if(network.channel > 11)
- + {
- + printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
- + return;
- + }
- + }
- + }
- + else
- + {
- + // Case 1: Country code
- + if(IS_COUNTRY_IE_VALID(ieee) )
- + {
- + if( !IsLegalChannel(ieee, network.channel) )
- + {
- + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
- + return;
- + }
- + }
- + // Case 2: No any country code.
- + else
- + {
- + // Filter over channel ch12~14
- + if(network.channel > 14)
- + {
- + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
- + return;
- + }
- + }
- + }
- + }
- +
- + //lzm add 081205
- + // for Toshiba request, we use channel_plan COUNTRY_CODE_WORLD_WIDE_13_INDEX,
- + // For Liteon "World Wide 13" Domain name:ch1~11 active scan & ch12~13 passive scan
- + // So we shoud only rcv beacon in 12-13, and filter probe resp in 12-13.
- + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
- + {
- + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
- + {
- + // Filter over channel ch12~13
- + if(network.channel >= ieee->MinPassiveChnlNum)
- + {
- + printk("GetScanInfo(): passive scan, filter probe resp at channel(%d).\n", network.channel);
- + return;
- + }
- + }
- + }
- +#endif
- +
- +
- + /* The network parsed correctly -- so now we scan our known networks
- + * to see if we can find it in our list.
- + *
- + * NOTE: This search is definitely not optimized. Once its doing
- + * the "right thing" we'll optimize it for efficiency if
- + * necessary */
- +
- + /* Search for this entry in the list and update it if it is
- + * already there. */
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + if(is_same_network(&ieee->current_network, &network, ieee)) {
- + //YJ,add,080819,for hidden ap
- + if(is_beacon == 0)
- + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
- + if ((ieee->state == IEEE80211_LINKED) && is_beacon)
- + ieee->NumRxBcnInPeriod++;
- + wmm_info = ieee->current_network.wmm_info;
- + update_network(&ieee->current_network, &network);
- + }
- +
- + list_for_each_entry(target, &ieee->network_list, list) {
- + if (is_same_network(target, &network, ieee))
- + break;
- + if ((oldest == NULL) ||
- + (target->last_scanned < oldest->last_scanned))
- + oldest = target;
- + }
- +
- + /* If we didn't find a match, then get a new network slot to initialize
- + * with this beacon's information */
- + if (&target->list == &ieee->network_list) {
- + if (list_empty(&ieee->network_free_list)) {
- + /* If there are no more slots, expire the oldest */
- + list_del(&oldest->list);
- + target = oldest;
- + IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
- + "network list.\n",
- + escape_essid(target->ssid,
- + target->ssid_len),
- + MAC_ARG(target->bssid));
- + } else {
- + /* Otherwise just pull from the free list */
- + target = list_entry(ieee->network_free_list.next,
- + struct ieee80211_network, list);
- + list_del(ieee->network_free_list.next);
- + }
- +
- +
- +#ifdef CONFIG_IEEE80211_DEBUG
- + IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
- + escape_essid(network.ssid,
- + network.ssid_len),
- + MAC_ARG(network.bssid),
- + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- + IEEE80211_STYPE_PROBE_RESP ?
- + "PROBE RESPONSE" : "BEACON");
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + network.ext_entry = target->ext_entry;
- +#endif
- + memcpy(target, &network, sizeof(*target));
- + list_add_tail(&target->list, &ieee->network_list);
- + if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
- + ieee80211_softmac_new_net(ieee,&network);
- + } else {
- + IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
- + escape_essid(target->ssid,
- + target->ssid_len),
- + MAC_ARG(target->bssid),
- + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- + IEEE80211_STYPE_PROBE_RESP ?
- + "PROBE RESPONSE" : "BEACON");
- +
- + /* we have an entry and we are going to update it. But this entry may
- + * be already expired. In this case we do the same as we found a new
- + * net and call the new_net handler
- + */
- + renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
- + //YJ,add,080819,for hidden ap
- + if(is_beacon == 0)
- + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
- + //if(strncmp(network.ssid, "linksys-c",9) == 0)
- + // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
- + if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
- + && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
- + ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
- + renew = 1;
- + //YJ,add,080819,for hidden ap,end
- + update_network(target, &network);
- + if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
- + ieee80211_softmac_new_net(ieee,&network);
- + }
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +}
- +
- +void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- + struct ieee80211_hdr *header,
- + struct ieee80211_rx_stats *stats)
- +{
- + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
- +
- + case IEEE80211_STYPE_BEACON:
- + IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
- + WLAN_FC_GET_STYPE(header->frame_ctl));
- + IEEE80211_DEBUG_SCAN("Beacon\n");
- + ieee80211_process_probe_response(
- + ieee, (struct ieee80211_probe_response *)header, stats);
- + break;
- +
- + case IEEE80211_STYPE_PROBE_RESP:
- + IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
- + WLAN_FC_GET_STYPE(header->frame_ctl));
- + IEEE80211_DEBUG_SCAN("Probe response\n");
- + ieee80211_process_probe_response(
- + ieee, (struct ieee80211_probe_response *)header, stats);
- + break;
- +//rz
- +#ifdef _RTL8187_EXT_PATCH_
- + case IEEE80211_STYPE_PROBE_REQ:
- + IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n",
- + WLAN_FC_GET_STYPE(header->frame_ctl));
- + IEEE80211_DEBUG_SCAN("Probe request\n");
- + ///
- + //printk("Probe request\n");
- + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req )
- + ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats);
- + break;
- +#endif // _RTL8187_EXT_PATCH_
- +
- + }
- +}
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_rx_mgt);
- +EXPORT_SYMBOL(ieee80211_rx);
- +EXPORT_SYMBOL(ieee80211_network_init);
- +#ifdef _RTL8187_EXT_PATCH_
- +EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether);
- +#endif
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
- +EXPORT_SYMBOL_NOVERS(ieee80211_rx);
- +EXPORT_SYMBOL_NOVERS(ieee80211_network_init);
- +#ifdef _RTL8187_EXT_PATCH_
- +EXPORT_SYMBOL_NOVERS(ieee_ext_skb_p80211_to_ether);
- +#endif
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,4083 @@
- +/* IEEE 802.11 SoftMAC layer
- + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
- + *
- + * Mostly extracted from the rtl8180-sa2400 driver for the
- + * in-kernel generic ieee802.11 stack.
- + *
- + * Few lines might be stolen from other part of the ieee80211
- + * stack. Copyright who own it's copyright
- + *
- + * WPA code stolen from the ipw2200 driver.
- + * Copyright who own it's copyright.
- + *
- + * released under the GPL
- + */
- +
- +
- +#include "ieee80211.h"
- +
- +#include <linux/random.h>
- +#include <linux/delay.h>
- +#include <linux/version.h>
- +#include <asm/uaccess.h>
- +
- +#ifdef ENABLE_DOT11D
- +#include "dot11d.h"
- +#endif
- +
- +
- +u8 rsn_authen_cipher_suite[16][4] = {
- + {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
- + {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
- + {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
- + {0x00,0x0F,0xAC,0x03}, //WRAP-historical
- + {0x00,0x0F,0xAC,0x04}, //CCMP
- + {0x00,0x0F,0xAC,0x05}, //WEP-104
- +};
- +
- +short ieee80211_is_54g(struct ieee80211_network net)
- +{
- + return ((net.rates_ex_len > 0) || (net.rates_len > 4));
- +}
- +
- +short ieee80211_is_shortslot(struct ieee80211_network net)
- +{
- + return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
- +}
- +
- +/* returns the total length needed for pleacing the RATE MFIE
- + * tag and the EXTENDED RATE MFIE tag if needed.
- + * It encludes two bytes per tag for the tag itself and its len
- + */
- +unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
- +{
- + unsigned int rate_len = 0;
- +
- + if (ieee->modulation & IEEE80211_CCK_MODULATION)
- + rate_len = IEEE80211_CCK_RATE_LEN + 2;
- +
- + if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- +
- + rate_len += IEEE80211_OFDM_RATE_LEN + 2;
- +
- + return rate_len;
- +}
- +
- +/* pleace the MFIE rate, tag to the memory (double) poined.
- + * Then it updates the pointer so that
- + * it points after the new MFIE tag added.
- + */
- +void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
- +{
- + u8 *tag = *tag_p;
- +
- + if (ieee->modulation & IEEE80211_CCK_MODULATION){
- + *tag++ = MFIE_TYPE_RATES;
- + *tag++ = 7;
- + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
- + //added for basic rate set
- + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- + }
- +
- + /* We may add an option for custom rates that specific HW might support */
- + *tag_p = tag;
- +}
- +
- +void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
- +{
- + u8 *tag = *tag_p;
- +
- + if (ieee->modulation & IEEE80211_OFDM_MODULATION){
- +
- + *tag++ = MFIE_TYPE_RATES_EX;
- + *tag++ = 5;
- + *tag++ = IEEE80211_OFDM_RATE_9MB;
- + *tag++ = IEEE80211_OFDM_RATE_18MB;
- + *tag++ = IEEE80211_OFDM_RATE_36MB;
- + *tag++ = IEEE80211_OFDM_RATE_48MB;
- + *tag++ = IEEE80211_OFDM_RATE_54MB;
- +
- + }
- +
- + /* We may add an option for custom rates that specific HW might support */
- + *tag_p = tag;
- +}
- +
- +
- +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
- + u8 *tag = *tag_p;
- +
- + *tag++ = MFIE_TYPE_GENERIC; //0
- + *tag++ = 7;
- + *tag++ = 0x00;
- + *tag++ = 0x50;
- + *tag++ = 0xf2;
- + *tag++ = 0x02;//5
- + *tag++ = 0x00;
- + *tag++ = 0x01;
- +#ifdef SUPPORT_USPD
- + if(ieee->current_network.wmm_info & 0x80) {
- + *tag++ = 0x0f|MAX_SP_Len;
- + } else {
- + *tag++ = MAX_SP_Len;
- + }
- +#else
- + *tag++ = MAX_SP_Len;
- +#endif
- + *tag_p = tag;
- +}
- +
- +#ifdef THOMAS_TURBO
- +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
- + u8 *tag = *tag_p;
- +
- + *tag++ = MFIE_TYPE_GENERIC; //0
- + *tag++ = 7;
- + *tag++ = 0x00;
- + *tag++ = 0xe0;
- + *tag++ = 0x4c;
- + *tag++ = 0x01;//5
- + *tag++ = 0x02;
- + *tag++ = 0x11;
- + *tag++ = 0x00;
- +
- + *tag_p = tag;
- + printk(KERN_ALERT "This is enable turbo mode IE process\n");
- +}
- +#endif
- +
- +void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
- +{
- + int nh;
- + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
- +
- +/*
- + * if the queue is full but we have newer frames then
- + * just overwrites the oldest.
- + *
- + * if (nh == ieee->mgmt_queue_tail)
- + * return -1;
- + */
- + ieee->mgmt_queue_head = nh;
- + ieee->mgmt_queue_ring[nh] = skb;
- +
- + //return 0;
- +}
- +
- +struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
- +{
- + struct sk_buff *ret;
- +
- + if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
- + return NULL;
- +
- + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
- +
- + ieee->mgmt_queue_tail =
- + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
- +
- + return ret;
- +}
- +
- +void init_mgmt_queue(struct ieee80211_device *ieee)
- +{
- + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
- +}
- +
- +
- +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
- +
- +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
- +{
- + unsigned long flags;
- + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- + struct ieee80211_hdr_3addr *header=
- + (struct ieee80211_hdr_3addr *) skb->data;
- +
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + /* called with 2nd param 0, no mgmt lock required */
- + ieee80211_sta_wakeup(ieee,0);
- +
- + if(single){
- + if(ieee->queue_stop){
- +
- + enqueue_mgmt(ieee,skb);
- + }else{
- + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
- +
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- +
- + /* avoid watchdog triggers */
- + ieee->dev->trans_start = jiffies;
- + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- +// dev_kfree_skb_any(skb);//edit by thomas //'cause this function will cause Oops called in interrupt context in old version 101907
- +#endif
- + }
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- + }else{
- + spin_unlock_irqrestore(&ieee->lock, flags);
- + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
- +
- + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
- +
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- +
- + ieee->softmac_hard_start_xmit(skb,ieee->dev);
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- +// dev_kfree_skb_any(skb);//edit by thomas
- +#endif
- + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
- + }
- +}
- +
- +
- +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
- +{
- +
- + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- + struct ieee80211_hdr_3addr *header =
- + (struct ieee80211_hdr_3addr *) skb->data;
- +
- +
- + if(single){
- +
- + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
- +
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- +
- + /* avoid watchdog triggers */
- + ieee->dev->trans_start = jiffies;
- + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
- +
- + }else{
- +
- + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
- +
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- +
- + ieee->softmac_hard_start_xmit(skb,ieee->dev);
- +
- + }
- + dev_kfree_skb_any(skb);//edit by thomas
- +}
- +
- +inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
- +{
- + unsigned int len,rate_len;
- + u8 *tag;
- + struct sk_buff *skb;
- + struct ieee80211_probe_request *req;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + short extMore = 0;
- + if(ieee->ext_patch_ieee80211_probe_req_1)
- + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
- +#endif
- +
- + len = ieee->current_network.ssid_len;
- +
- + rate_len = ieee80211_MFIE_rate_len(ieee);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(!extMore)
- +#endif
- + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
- + 2 + len + rate_len);
- +#ifdef _RTL8187_EXT_PATCH_
- + else
- + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
- + 2 + len + rate_len+128); // MESHID + CAP
- +#endif
- +
- + if (!skb)
- + return NULL;
- +
- + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
- + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- + req->header.duration_id = 0; //FIXME: is this OK ?
- +
- + memset(req->header.addr1, 0xff, ETH_ALEN);
- + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memset(req->header.addr3, 0xff, ETH_ALEN);
- +
- + tag = (u8 *) skb_put(skb,len+2+rate_len);
- +
- + *tag++ = MFIE_TYPE_SSID;
- + *tag++ = len;
- + memcpy(tag, ieee->current_network.ssid, len);
- + tag += len;
- +
- + ieee80211_MFIE_Brate(ieee,&tag);
- + ieee80211_MFIE_Grate(ieee,&tag);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(extMore)
- + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
- +#endif
- + return skb;
- +}
- +
- +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +void ext_ieee80211_send_beacon_wq(struct work_struct *work)
- +{
- + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
- +#else
- +void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- +
- + struct sk_buff *skb;
- +
- + //unsigned long flags;
- +// printk("=========>%s()\n", __FUNCTION__);
- + skb = ieee80211_get_beacon_(ieee);
- +
- + if (skb){
- + softmac_mgmt_xmit(skb, ieee);
- + ieee->softmac_stats.tx_beacons++;
- + dev_kfree_skb_any(skb);//edit by thomas
- + }
- +
- +
- + //printk(KERN_WARNING "[1] beacon sending!\n");
- +// ieee->beacon_timer.expires = jiffies +
- +// (MSECS( ieee->current_network.beacon_interval -5));
- +
- + //spin_lock_irqsave(&ieee->beacon_lock,flags);
- +// if(ieee->beacon_txing)
- +// add_timer(&ieee->beacon_timer);
- + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
- +}
- +#endif
- +
- +void ieee80211_send_beacon(struct ieee80211_device *ieee)
- +{
- + struct sk_buff *skb;
- +
- + //unsigned long flags;
- +// printk("=========>%s()\n", __FUNCTION__);
- + skb = ieee80211_get_beacon_(ieee);
- +
- + if (skb){
- + softmac_mgmt_xmit(skb, ieee);
- + ieee->softmac_stats.tx_beacons++;
- + dev_kfree_skb_any(skb);//edit by thomas
- + }
- +
- +
- + //printk(KERN_WARNING "[1] beacon sending!\n");
- + ieee->beacon_timer.expires = jiffies +
- + (MSECS( ieee->current_network.beacon_interval -5));
- +
- + //spin_lock_irqsave(&ieee->beacon_lock,flags);
- + if(ieee->beacon_txing)
- + add_timer(&ieee->beacon_timer);
- + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
- +}
- +
- +
- +void ieee80211_send_beacon_cb(unsigned long _ieee)
- +{
- + struct ieee80211_device *ieee =
- + (struct ieee80211_device *) _ieee;
- + unsigned long flags;
- +
- + spin_lock_irqsave(&ieee->beacon_lock, flags);
- + ieee80211_send_beacon(ieee);
- + spin_unlock_irqrestore(&ieee->beacon_lock, flags);
- +}
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +
- +inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
- +{
- + unsigned int len,rate_len;
- + u8 *tag;
- + struct sk_buff *skb;
- + struct ieee80211_probe_request *req;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + short extMore = 0;
- + if(ieee->ext_patch_ieee80211_probe_req_1)
- + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
- +#endif
- +
- + len = len_ssid;
- +
- + rate_len = ieee80211_MFIE_rate_len(ieee);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(!extMore)
- +#endif
- + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
- + 2 + len + rate_len);
- +#ifdef _RTL8187_EXT_PATCH_
- + else
- + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
- + 2 + len + rate_len+128); // MESHID + CAP
- +#endif
- +
- + if (!skb)
- + return NULL;
- +
- + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
- + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- + req->header.duration_id = 0; //FIXME: is this OK ?
- +
- + memset(req->header.addr1, 0xff, ETH_ALEN);
- + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memset(req->header.addr3, 0xff, ETH_ALEN);
- +
- + tag = (u8 *) skb_put(skb,len+2+rate_len);
- +
- + *tag++ = MFIE_TYPE_SSID;
- + *tag++ = len;
- + if(len)
- + {
- + memcpy(tag, ssid, len);
- + tag += len;
- + }
- +
- + ieee80211_MFIE_Brate(ieee,&tag);
- + ieee80211_MFIE_Grate(ieee,&tag);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(extMore)
- + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
- +#endif
- + return skb;
- +}
- +
- +#endif // _RTL8187_EXT_PATCH_
- +
- +
- +void ieee80211_send_probe(struct ieee80211_device *ieee)
- +{
- + struct sk_buff *skb;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
- + else
- +#endif
- + skb = ieee80211_probe_req(ieee);
- + if (skb){
- + softmac_mgmt_xmit(skb, ieee);
- + ieee->softmac_stats.tx_probe_rq++;
- + dev_kfree_skb_any(skb);//edit by thomas
- + }
- +}
- +
- +void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
- +{
- + if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
- + ieee80211_send_probe(ieee);
- + ieee80211_send_probe(ieee);
- + }
- +}
- +
- +/* this performs syncro scan blocking the caller until all channels
- + * in the allowed channel map has been checked.
- + */
- +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
- +{
- + short ch = 0;
- +#ifdef ENABLE_DOT11D
- + u8 channel_map[MAX_CHANNEL_NUMBER+1];
- + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- +#endif
- +
- +
- + down(&ieee->scan_sem);
- +
- + while(1)
- + {
- +
- + do{
- + ch++;
- + if (ch > MAX_CHANNEL_NUMBER)
- + goto out; /* scan completed */
- +
- +#ifdef ENABLE_DOT11D
- + }while(!channel_map[ch]);
- +#else
- + }while(!ieee->channel_map[ch]);
- +#endif
- +
- + //printk("=>current channel is %d\n",ch);
- +
- + /* this fuction can be called in two situations
- + * 1- We have switched to ad-hoc mode and we are
- + * performing a complete syncro scan before conclude
- + * there are no interesting cell and to create a
- + * new one. In this case the link state is
- + * IEEE80211_NOLINK until we found an interesting cell.
- + * If so the ieee8021_new_net, called by the RX path
- + * will set the state to IEEE80211_LINKED, so we stop
- + * scanning
- + * 2- We are linked and the root uses run iwlist scan.
- + * So we switch to IEEE80211_LINKED_SCANNING to remember
- + * that we are still logically linked (not interested in
- + * new network events, despite for updating the net list,
- + * but we are temporarly 'unlinked' as the driver shall
- + * not filter RX frames and the channel is changing.
- + * So the only situation in witch are interested is to check
- + * if the state become LINKED because of the #1 situation
- + */
- +
- + if (ieee->state == IEEE80211_LINKED)
- + goto out;
- +
- + //printk("---->%s: chan %d\n", __func__, ch);
- + ieee->set_chan(ieee->dev, ch);
- +#ifdef ENABLE_DOT11D
- + if(channel_map[ch] == 1)
- +#endif
- + {
- + ieee80211_send_probe_requests(ieee);
- + }
- +
- + /* this prevent excessive time wait when we
- + * need to wait for a syncro scan to end..
- + */
- + if (ieee->sync_scan_hurryup)
- + goto out;
- +
- +
- + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
- +
- + }
- +out:
- + ieee->sync_scan_hurryup = 0;
- + up(&ieee->scan_sem);
- +#ifdef ENABLE_DOT11D
- + if(IS_DOT11D_ENABLE(ieee))
- + DOT11D_ScanComplete(ieee);
- +#endif
- +
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- +/* called both by wq with ieee->lock held */
- +void ieee80211_softmac_scan(struct ieee80211_device *ieee)
- +{
- +#if 0
- + short watchdog = 0;
- + do{
- + ieee->current_network.channel =
- + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
- + if (watchdog++ > MAX_CHANNEL_NUMBER)
- + return; /* no good chans */
- +
- + }while(!ieee->channel_map[ieee->current_network.channel]);
- +#endif
- +
- + schedule_task(&ieee->softmac_scan_wq);
- +}
- +#endif
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void ieee80211_softmac_scan_wq(struct work_struct *work)
- +{
- + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
- + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
- +#else
- +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- + //static short watchdog = 0;
- + //short watchdog = 0;//lzm move into ieee->scan_watchdog 081215 for roaming
- + u8 channel_bak = ieee->current_network.channel;//lzm for channel+1
- +#ifdef ENABLE_DOT11D
- + u8 channel_map[MAX_CHANNEL_NUMBER+1];
- + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- +#endif
- + down(&ieee->scan_sem);
- +
- + do{
- + ieee->current_network.channel =
- + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
- + if (ieee->scan_watchdog++ > MAX_CHANNEL_NUMBER)
- + goto out; /* no good chans */
- +#ifdef ENABLE_DOT11D
- + }while(!channel_map[ieee->current_network.channel]);
- +#else
- + }while(!ieee->channel_map[ieee->current_network.channel]);
- +#endif
- +
- + if (ieee->scanning == 0 )
- + goto out;
- +
- + //printk("current channel is %d\n",ieee->current_network.channel);
- + ieee->set_chan(ieee->dev, ieee->current_network.channel);
- +#ifdef ENABLE_DOT11D
- + if(channel_map[ieee->current_network.channel] == 1)
- +#endif
- + {
- + ieee80211_send_probe_requests(ieee);
- + }
- +
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
- +#else
- + ieee->scan_timer.expires = jiffies + (IEEE80211_SOFTMAC_SCAN_TIME);
- + if (ieee->scanning == 1)
- + add_timer(&ieee->scan_timer);
- +#endif
- +
- + up(&ieee->scan_sem);
- + return;
- +out:
- + //printk("%s():Stop scan now\n",__FUNCTION__);
- + ieee->actscanning = false;
- + ieee->scan_watchdog = 0;
- + ieee->scanning = 0;
- + ieee->current_network.channel = channel_bak;
- + up(&ieee->scan_sem);
- +#ifdef ENABLE_DOT11D
- + if(IS_DOT11D_ENABLE(ieee))
- + DOT11D_ScanComplete(ieee);
- +#endif
- +
- + return;
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- +void ieee80211_softmac_scan_cb(unsigned long _dev)
- +{
- + unsigned long flags;
- + struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- + ieee80211_softmac_scan(ieee);
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +}
- +#endif
- +
- +
- +void ieee80211_beacons_start(struct ieee80211_device *ieee)
- +{
- + unsigned long flags;
- +
- + spin_lock_irqsave(&ieee->beacon_lock,flags);
- +
- + ieee->beacon_txing = 1;
- + ieee80211_send_beacon(ieee);
- +
- + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
- +}
- +
- +void ieee80211_beacons_stop(struct ieee80211_device *ieee)
- +{
- + unsigned long flags;
- +
- + spin_lock_irqsave(&ieee->beacon_lock,flags);
- +
- + ieee->beacon_txing = 0;
- + del_timer_sync(&ieee->beacon_timer);
- +
- + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
- +
- +}
- +
- +
- +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
- +{
- + if(ieee->stop_send_beacons)
- + ieee->stop_send_beacons(ieee->dev);
- + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- + ieee80211_beacons_stop(ieee);
- +}
- +
- +
- +void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
- +{
- + if(ieee->start_send_beacons)
- + ieee->start_send_beacons(ieee->dev);
- + if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- + ieee80211_beacons_start(ieee);
- +}
- +
- +
- +void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
- +{
- +// unsigned long flags;
- +
- + ieee->sync_scan_hurryup = 1;
- +
- + down(&ieee->scan_sem);
- +// spin_lock_irqsave(&ieee->lock, flags);
- +
- + if (ieee->scanning == 1){
- + //printk("%s():Stop scan now\n",__FUNCTION__);
- + ieee->scanning = 0;
- + //lzm add for softmac_scan_wq can't return from out
- + //example: rcv probe_response
- + ieee->scan_watchdog = 0;//lzm add 081215 for roaming
- + ieee->actscanning = false;
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + cancel_delayed_work(&ieee->softmac_scan_wq);
- +#else
- + del_timer_sync(&ieee->scan_timer);
- +#endif
- + }
- +
- +// spin_unlock_irqrestore(&ieee->lock, flags);
- + up(&ieee->scan_sem);
- +}
- +
- +void ieee80211_stop_scan(struct ieee80211_device *ieee)
- +{
- + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- + ieee80211_softmac_stop_scan(ieee);
- + else
- + ieee->stop_scan(ieee->dev);
- +}
- +
- +/* called with ieee->lock held */
- +void ieee80211_start_scan(struct ieee80211_device *ieee)
- +{
- + ieee->actscanning = true;
- +#ifdef CONFIG_IPS
- + ieee->ieee80211_ips_leave(ieee->dev);
- +#endif
- +
- +#ifdef ENABLE_DOT11D
- + if(IS_DOT11D_ENABLE(ieee) )
- + {
- + if(IS_COUNTRY_IE_VALID(ieee))
- + {
- + RESET_CIE_WATCHDOG(ieee);
- + }
- + }
- +#endif
- +
- + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
- + if (ieee->scanning == 0){
- + ieee->scanning = 1;
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0);
- +#else
- + ieee80211_softmac_scan(ieee);
- +#endif
- + }
- + }else
- + ieee->start_scan(ieee->dev);
- +
- +}
- +
- +/* called with wx_sem held */
- +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
- +{
- + //printk("====>%s()\n", __func__);
- +#ifdef CONFIG_IPS
- + ieee->ieee80211_ips_leave(ieee->dev);
- +#endif
- + ieee->actscanning = true;
- +
- +#ifdef ENABLE_DOT11D
- + if(IS_DOT11D_ENABLE(ieee) )
- + {
- + if(IS_COUNTRY_IE_VALID(ieee))
- + {
- + RESET_CIE_WATCHDOG(ieee);
- + }
- + }
- +#endif
- +
- + ieee->sync_scan_hurryup = 0;
- +
- + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- + ieee80211_softmac_scan_syncro(ieee);
- + else
- + ieee->scan_syncro(ieee->dev);
- +
- + ieee->actscanning = false;
- + //printk("<====%s()\n", __func__);
- +}
- +
- +inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
- + struct ieee80211_device *ieee, int challengelen)
- +{
- + struct sk_buff *skb;
- + struct ieee80211_authentication *auth;
- +
- + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
- +
- + if (!skb) return NULL;
- +
- + auth = (struct ieee80211_authentication *)
- + skb_put(skb, sizeof(struct ieee80211_authentication));
- +
- + auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
- + if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
- +
- + auth->header.duration_id = 0x013a; //FIXME
- +
- + memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
- + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
- +
- + auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- +
- + auth->transaction = cpu_to_le16(ieee->associate_seq);
- + ieee->associate_seq++;
- +
- + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
- +
- + return skb;
- +
- +}
- +
- +u8 WPA_OUI[3] = {0x00, 0x50, 0xf2};
- +
- +static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
- +{
- + u8 *tag;
- + int beacon_size;
- + struct ieee80211_probe_response *beacon_buf;
- + struct sk_buff *skb;
- + int encrypt;
- + int atim_len,erp_len;
- + struct ieee80211_crypt_data* crypt;
- +
- + char *ssid = ieee->current_network.ssid;
- + int ssid_len = ieee->current_network.ssid_len;
- + int rate_len = ieee->current_network.rates_len+2;
- + int rate_ex_len = ieee->current_network.rates_ex_len;
- +
- + int wpa_ie_len = 0, wpa_type=0;
- + if(rate_ex_len > 0) rate_ex_len+=2;
- +
- + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
- + atim_len = 4;
- + else
- + atim_len = 0;
- +
- + if(ieee80211_is_54g(ieee->current_network))
- + erp_len = 3;
- + else
- + erp_len = 0;
- + if (ieee->wpa_enabled)
- + {
- + // printk("hoho wpa_enalbe\n");
- + wpa_ie_len = ieee->wpa_ie_len; //24-2
- + }
- + beacon_size = sizeof(struct ieee80211_probe_response)+
- + ssid_len
- + +3 //channel
- + +rate_len
- + +rate_ex_len
- + +atim_len
- + +erp_len
- + +wpa_ie_len;
- +
- + skb = dev_alloc_skb(beacon_size);
- +
- + if (!skb)
- + return NULL;
- +
- + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
- +
- + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
- + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
- +
- + beacon_buf->header.duration_id = 0; //FIXME
- + beacon_buf->beacon_interval =
- + cpu_to_le16(ieee->current_network.beacon_interval);
- + beacon_buf->capability =
- + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
- +
- + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
- + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
- +#ifdef _RTL8187_EXT_PATCH_
- +{
- +/* struct ieee80211_crypt_data_list* cryptlist = ieee->cryptlist[1];
- + u8 i = cryptlist->used;
- + crypt = cryptlist ->crypt[ieee->tx_keyidx];
- +*/
- + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
- +}
- +#else
- +
- + crypt = ieee->crypt[ieee->tx_keyidx];
- +#endif
- + if (crypt)
- + wpa_type = strcmp(crypt->ops->name, "TKIP");
- +
- +
- + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
- + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
- +
- + if (encrypt)
- + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
- +
- +
- + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
- +
- + beacon_buf->info_element.id = MFIE_TYPE_SSID;
- + beacon_buf->info_element.len = ssid_len;
- +
- + tag = (u8*) beacon_buf->info_element.data;
- +
- + memcpy(tag, ssid, ssid_len);
- +
- + tag += ssid_len;
- +
- + *(tag++) = MFIE_TYPE_RATES;
- + *(tag++) = rate_len-2;
- + memcpy(tag,ieee->current_network.rates,rate_len-2);
- + tag+=rate_len-2;
- +
- + *(tag++) = MFIE_TYPE_DS_SET;
- + *(tag++) = 1;
- + *(tag++) = ieee->current_network.channel;
- +
- + if(atim_len){
- + u16 val16;
- + *(tag++) = MFIE_TYPE_IBSS_SET;
- + *(tag++) = 2;
- + val16 = cpu_to_le16(ieee->current_network.atim_window);
- + //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
- + memcpy((u8 *)tag,(u8 *)&val16,2);
- + tag+=2;
- + }
- +
- + if(erp_len){
- + *(tag++) = MFIE_TYPE_ERP;
- + *(tag++) = 1;
- + *(tag++) = 0;
- + }
- +
- + if(rate_ex_len){
- + *(tag++) = MFIE_TYPE_RATES_EX;
- + *(tag++) = rate_ex_len-2;
- + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
- + tag+=rate_ex_len-2;
- + }
- + if (wpa_ie_len)
- + {
- +#if 0
- + *(tag++) = 0xdd;
- + *(tag++) = wpa_ie_len-2;
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = 1;
- + *(tag++) = 1;
- + *(tag++) = 0;
- +
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = wpa_type ? 4:2;
- + *(tag++) = 1;
- + *(tag++) = 0;
- +
- +
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = wpa_type ? 4:0;
- + *(tag++) = 1;
- + *(tag++) = 0;
- +
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = 0;
- +#else
- + if (ieee->iw_mode == IW_MODE_ADHOC)
- + {//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
- + memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
- + }
- +
- + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
- +
- +#endif
- + }
- +
- +
- + skb->dev = ieee->dev;
- + return skb;
- +}
- +
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net)
- +{
- + u8 *tag;
- + int beacon_size;
- + struct ieee80211_probe_response *beacon_buf;
- + struct sk_buff *skb;
- + int encrypt;
- + int atim_len,erp_len;
- + struct ieee80211_crypt_data* crypt;
- + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
- +
- + char *ssid = net->ssid;
- + int ssid_len = net->ssid_len;
- +
- + int rate_len = ieee->current_network.rates_len+2;
- + int rate_ex_len = ieee->current_network.rates_ex_len;
- + int wpa_ie_len = 0, wpa_type=0;
- + if(rate_ex_len > 0) rate_ex_len+=2;
- +
- + if( ieee->meshScanMode&4)
- + ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
- + if( ieee->meshScanMode&6)
- + {
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
- +#else
- + schedule_task(&ieee->ext_stop_scan_wq);
- +#endif
- + }
- + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
- + atim_len = 4;
- + else
- + atim_len = 0;
- +
- + if(ieee80211_is_54g(*net))
- + erp_len = 3;
- + else
- + erp_len = 0;
- +
- + if (ieee->wpa_enabled &&(ieee->iw_ext_mode==ieee->iw_mode))
- + {
- +// printk("hoho wpa_enalbe\n");
- + wpa_ie_len = ieee->wpa_ie_len; //24-2
- + }
- +
- + beacon_size = sizeof(struct ieee80211_probe_response)+
- + ssid_len
- + +3 //channel
- + +rate_len
- + +rate_ex_len
- + +atim_len
- + +erp_len
- + +wpa_ie_len;
- +//b
- + skb = dev_alloc_skb(beacon_size+196);
- +
- + if (!skb)
- + return NULL;
- +
- + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
- +
- + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
- + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
- +
- + beacon_buf->header.duration_id = 0; //FIXME
- +
- + beacon_buf->beacon_interval =
- + cpu_to_le16(ieee->current_network.beacon_interval); // use current_network here
- + beacon_buf->capability =
- + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
- +
- + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
- + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
- +#ifdef _RTL8187_EXT_PATCH_
- +
- + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
- +#else
- +
- + crypt = ieee->crypt[ieee->tx_keyidx];
- +#endif
- +
- +// crypt = ieee->crypt[ieee->tx_keyidx];
- + if (crypt)
- + wpa_type = strcmp(crypt->ops->name, "TKIP");
- +
- + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
- + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
- +
- + if (encrypt)
- + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
- +
- +
- + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
- +
- + beacon_buf->info_element.id = MFIE_TYPE_SSID;
- + beacon_buf->info_element.len = ssid_len;
- +
- + tag = (u8*) beacon_buf->info_element.data;
- +
- + // brocad cast / probe rsp
- + if(memcmp(dest, broadcast_addr, ETH_ALEN ))
- + memcpy(tag, ssid, ssid_len);
- + else
- + ssid_len=0;
- +
- + tag += ssid_len;
- +
- +//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
- +//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
- +
- + *(tag++) = MFIE_TYPE_RATES;
- + *(tag++) = rate_len-2;
- + memcpy(tag,ieee->current_network.rates,rate_len-2);
- + tag+=rate_len-2;
- +
- + *(tag++) = MFIE_TYPE_DS_SET;
- + *(tag++) = 1;
- + *(tag++) = ieee->current_network.channel; // use current_network here
- +
- +
- + if(atim_len){
- + *(tag++) = MFIE_TYPE_IBSS_SET;
- + *(tag++) = 2;
- + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
- + tag+=2;
- + }
- +
- + if(erp_len){
- + *(tag++) = MFIE_TYPE_ERP;
- + *(tag++) = 1;
- + *(tag++) = 0;
- + }
- +
- + if(rate_ex_len){
- + *(tag++) = MFIE_TYPE_RATES_EX;
- + *(tag++) = rate_ex_len-2;
- + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
- + tag+=rate_ex_len-2;
- + }
- +
- + if (wpa_ie_len)
- + {
- +#if 0
- + *(tag++) = 0xdd;
- + *(tag++) = wpa_ie_len-2;
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = 1;
- + *(tag++) = 1;
- + *(tag++) = 0;
- +
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = wpa_type ? 4:2;
- + *(tag++) = 1;
- + *(tag++) = 0;
- +
- +
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = wpa_type ? 4:0;
- + *(tag++) = 1;
- + *(tag++) = 0;
- +
- + memcpy(tag, WPA_OUI, 3);
- + tag += 3;
- + *(tag++) = 0;
- +#else
- + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
- +#endif
- + }
- +
- +
- + skb->dev = ieee->dev;
- + return skb;
- +}
- +#endif // _RTL8187_EXT_PATCH_
- +
- +
- +struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
- +{
- + struct sk_buff *skb;
- + u8* tag;
- +
- + struct ieee80211_crypt_data* crypt;
- + struct ieee80211_assoc_response_frame *assoc;
- + short encrypt;
- +
- + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
- +
- + skb = dev_alloc_skb(len);
- +
- + if (!skb)
- + return NULL;
- +
- + assoc = (struct ieee80211_assoc_response_frame *)
- + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
- +
- + assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
- + memcpy(assoc->header.addr1, dest,ETH_ALEN);
- + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
- + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
- +
- +
- + if(ieee->short_slot)
- + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
- +
- + if (ieee->host_encrypt){
- +#ifdef _RTL8187_EXT_PATCH_
- + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
- +#else
- + crypt = ieee->crypt[ieee->tx_keyidx];
- +#endif
- + }
- + else crypt = NULL;
- +
- + encrypt = ( crypt && crypt->ops);
- +
- + if (encrypt)
- + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
- +
- + assoc->status = 0;
- + assoc->aid = cpu_to_le16(ieee->assoc_id);
- + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
- + else ieee->assoc_id++;
- +
- + tag = (u8*) skb_put(skb, rate_len);
- +
- + ieee80211_MFIE_Brate(ieee, &tag);
- + ieee80211_MFIE_Grate(ieee, &tag);
- +
- + return skb;
- +}
- +
- +struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
- +{
- + struct sk_buff *skb;
- + struct ieee80211_authentication *auth;
- +
- + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
- +
- + if (!skb)
- + return NULL;
- +
- + skb->len = sizeof(struct ieee80211_authentication);
- +
- + auth = (struct ieee80211_authentication *)skb->data;
- +
- + auth->status = cpu_to_le16(status);
- + auth->transaction = cpu_to_le16(2);
- + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + memcpy(auth->header.addr3, dest, ETH_ALEN);
- +#else
- + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- +#endif
- + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy(auth->header.addr1, dest, ETH_ALEN);
- + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
- + return skb;
- +
- +
- +}
- +
- +struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
- +{
- + struct sk_buff *skb;
- + struct ieee80211_hdr_3addr* hdr;
- +
- + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
- +
- + if (!skb)
- + return NULL;
- +
- + hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
- +
- + memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
- + memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
- +
- + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
- + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
- + (pwr ? IEEE80211_FCTL_PM:0));
- +
- + return skb;
- +
- +
- +}
- +
- +
- +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
- +{
- + struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
- +
- + if (buf){
- + softmac_mgmt_xmit(buf, ieee);
- + dev_kfree_skb_any(buf);//edit by thomas
- + }
- +}
- +
- +
- +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
- +{
- + struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
- +
- + if (buf){
- + softmac_mgmt_xmit(buf, ieee);
- + dev_kfree_skb_any(buf);//edit by thomas
- + }
- +}
- +
- +
- +void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
- +{
- +
- + struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
- +
- + if (buf) {
- + softmac_mgmt_xmit(buf, ieee);
- + dev_kfree_skb_any(buf);//edit by thomas
- + }
- +}
- +
- +
- +inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
- +{
- + struct sk_buff *skb;
- +
- + struct ieee80211_assoc_request_frame *hdr;
- + u8 *tag;
- + //int i;
- + unsigned int wpa_len = beacon->wpa_ie_len;
- +#if 1
- + // for testing purpose
- + unsigned int rsn_len = beacon->rsn_ie_len;
- +#else
- + unsigned int rsn_len = beacon->rsn_ie_len - 4;
- +#endif
- + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- + unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
- +#ifdef THOMAS_TURBO
- + unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
- +#endif
- +
- + u8 encry_proto = ieee->wpax_type_notify & 0xff;
- +
- +
- + int len = 0;
- +
- + //[0] Notify type of encryption: WPA/WPA2
- + //[1] pair wise type
- + //[2] authen type
- + if(ieee->wpax_type_set) {
- + if (IEEE_PROTO_WPA == encry_proto) {
- + rsn_len = 0;
- + } else if (IEEE_PROTO_RSN == encry_proto) {
- + wpa_len = 0;
- + }
- + }
- +#ifdef THOMAS_TURBO
- + len = sizeof(struct ieee80211_assoc_request_frame)+
- + + beacon->ssid_len//essid tagged val
- + + rate_len//rates tagged val
- + + wpa_len
- + + rsn_len
- + + wmm_info_len
- + + turbo_info_len;
- +#else
- + len = sizeof(struct ieee80211_assoc_request_frame)+
- + + beacon->ssid_len//essid tagged val
- + + rate_len//rates tagged val
- + + wpa_len
- + + rsn_len
- + + wmm_info_len;
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + skb = dev_alloc_skb(len+256); // stanley
- + else
- +#endif
- + skb = dev_alloc_skb(len);
- +
- + if (!skb)
- + return NULL;
- +
- + hdr = (struct ieee80211_assoc_request_frame *)
- + skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
- +
- +
- + hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
- + hdr->header.duration_id= 37; //FIXME
- + memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
- + memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
- + memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
- +
- + hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
- + if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
- + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
- +
- + if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE )
- + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
- +
- + if(ieee->short_slot)
- + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1)
- + ieee->ext_patch_ieee80211_association_req_1(hdr);
- +#endif
- +
- + hdr->listen_interval = 0xa; //FIXME
- +
- + hdr->info_element.id = MFIE_TYPE_SSID;
- +
- + hdr->info_element.len = beacon->ssid_len;
- + tag = skb_put(skb, beacon->ssid_len);
- + memcpy(tag, beacon->ssid, beacon->ssid_len);
- +
- + tag = skb_put(skb, rate_len);
- +
- + ieee80211_MFIE_Brate(ieee, &tag);
- + ieee80211_MFIE_Grate(ieee, &tag);
- +
- + //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
- + //choose AES encryption as default algorithm while using mixed mode
- +#if 0
- + if(rsn_len == 0){
- +
- + tag = skb_put(skb,wpa_len);
- +
- + if(wpa_len) {
- +
- +
- + //{add by david. 2006.8.31
- + //fix linksys compatibility bug
- + //}
- + if(wpa_len > 24) {//22+2, mean include the capability
- + beacon->wpa_ie[wpa_len - 2] = 0;
- + }
- + //multicast cipher OUI
- + if( beacon->wpa_ie[11]==0x2 ){ //0x0050f202 is the oui of tkip
- + ieee->broadcast_key_type = KEY_TYPE_TKIP;
- + }
- + else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp
- + ieee->broadcast_key_type = KEY_TYPE_CCMP;
- + }
- + //unicast cipher OUI
- + if( beacon->wpa_ie[14]==0
- + && beacon->wpa_ie[15]==0x50
- + && beacon->wpa_ie[16]==0xf2
- + && beacon->wpa_ie[17]==0x2 ){ //0x0050f202 is the oui of tkip
- + ieee->pairwise_key_type = KEY_TYPE_TKIP;
- + }
- +
- + else if( beacon->wpa_ie[14]==0
- + && beacon->wpa_ie[15]==0x50
- + && beacon->wpa_ie[16]==0xf2
- + && beacon->wpa_ie[17]==0x4 ){//0x0050f204 is the oui of ccmp
- + ieee->pairwise_key_type = KEY_TYPE_CCMP;
- + }
- + //indicate the wpa_ie content to WPA_SUPPLICANT
- + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
- + memset(buff, 0, IW_CUSTOM_MAX);
- + p=buff;
- + p += sprintf(p, "ASSOCINFO(ReqIEs=");
- + for(i=0;i<wpa_len;i++){
- + p += sprintf(p, "%02x", beacon->wpa_ie[i]);
- + }
- + p += sprintf(p, ")");
- + memset(&wrqu, 0, sizeof(wrqu) );
- + wrqu.data.length = p - buff;
- +
- + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
- + memcpy(tag,beacon->wpa_ie,wpa_len);
- + }
- +
- + }
- +
- + if(rsn_len > 22) {
- +
- + if( beacon->rsn_ie[4]==0x0 &&
- + beacon->rsn_ie[5]==0xf &&
- + beacon->rsn_ie[6]==0xac){
- +
- + switch(beacon->rsn_ie[7]){
- + case 0x1:
- + ieee->broadcast_key_type = KEY_TYPE_WEP40;
- + break;
- + case 0x2:
- + ieee->broadcast_key_type = KEY_TYPE_TKIP;
- + break;
- + case 0x4:
- + ieee->broadcast_key_type = KEY_TYPE_CCMP;
- + break;
- + case 0x5:
- + ieee->broadcast_key_type = KEY_TYPE_WEP104;
- + break;
- + default:
- + printk("fault suite type in RSN broadcast key\n");
- + break;
- + }
- + }
- +
- + if( beacon->rsn_ie[10]==0x0 &&
- + beacon->rsn_ie[11]==0xf &&
- + beacon->rsn_ie[12]==0xac){
- + if(beacon->rsn_ie[8]==1){//not mixed mode
- + switch(beacon->rsn_ie[13]){
- + case 0x2:
- + ieee->pairwise_key_type = KEY_TYPE_TKIP;
- + break;
- + case 0x4:
- + ieee->pairwise_key_type = KEY_TYPE_CCMP;
- + break;
- + default:
- + printk("fault suite type in RSN pairwise key\n");
- + break;
- + }
- + }
- + else if(beacon->rsn_ie[8]==2){//mixed mode
- + ieee->pairwise_key_type = KEY_TYPE_CCMP;
- + }
- + }
- +
- +
- +
- + tag = skb_put(skb,22);
- + memcpy(tag,(beacon->rsn_ie + info_addr),8);
- + tag[1] = 20;
- + tag += 8;
- + info_addr += 8;
- +
- + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
- + for (i = 0; i < 2; i++) {
- + tag[0] = 1;
- + tag[1] = 0;
- + tag += 2;
- + suite_count = beacon->rsn_ie[info_addr] + \
- + (beacon->rsn_ie[info_addr + 1] << 8);
- + info_addr += 2;
- + if(1 == suite_count) {
- + memcpy(tag,(beacon->rsn_ie + info_addr),4);
- + info_addr += 4;
- + } else {
- + // if the wpax_type_notify has been set by the application,
- + // just use it, otherwise just use the default one.
- + if(ieee->wpax_type_set) {
- + suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ;
- + memcpy(tag,rsn_authen_cipher_suite[suit_select],4);
- + } else {
- + //default set as ccmp, or none authentication
- + if(i == 0) {
- + memcpy(tag,rsn_authen_cipher_suite[4],4);
- + } else {
- + memcpy(tag,rsn_authen_cipher_suite[2],4);
- + }
- +
- + }
- +
- + info_addr += (suite_count * 4);
- + }
- + tag += 4;
- + }
- + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
- +
- + tag[0] = 0;
- + tag[1] = beacon->rsn_ie[info_addr+1];
- +
- +
- +
- + } else {
- + tag = skb_put(skb,rsn_len);
- + if(rsn_len) {
- +
- +
- + if( beacon->rsn_ie[4]==0x0 &&
- + beacon->rsn_ie[5]==0xf &&
- + beacon->rsn_ie[6]==0xac){
- + switch(beacon->rsn_ie[7]){
- + case 0x1:
- + ieee->broadcast_key_type = KEY_TYPE_WEP40;
- + break;
- + case 0x2:
- + ieee->broadcast_key_type = KEY_TYPE_TKIP;
- + break;
- + case 0x4:
- + ieee->broadcast_key_type = KEY_TYPE_CCMP;
- + break;
- + case 0x5:
- + ieee->broadcast_key_type = KEY_TYPE_WEP104;
- + break;
- + default:
- + printk("fault suite type in RSN broadcast key\n");
- + break;
- + }
- + }
- + if( beacon->rsn_ie[10]==0x0 &&
- + beacon->rsn_ie[11]==0xf &&
- + beacon->rsn_ie[12]==0xac){
- + if(beacon->rsn_ie[8]==1){//not mixed mode
- + switch(beacon->rsn_ie[13]){
- + case 0x2:
- + ieee->pairwise_key_type = KEY_TYPE_TKIP;
- + break;
- + case 0x4:
- + ieee->pairwise_key_type = KEY_TYPE_CCMP;
- + break;
- + default:
- + printk("fault suite type in RSN pairwise key\n");
- + break;
- + }
- +
- + }
- + else if(beacon->rsn_ie[8]==2){//mixed mode
- + ieee->pairwise_key_type = KEY_TYPE_CCMP;
- + }
- + }
- +
- +
- + beacon->rsn_ie[rsn_len - 2] = 0;
- + memcpy(tag,beacon->rsn_ie,rsn_len);
- + }
- + }
- +#else
- + if (ieee->wpa_ie){
- + tag = skb_put(skb,ieee->wpa_ie_len);
- + memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
- + }
- +#endif
- + tag = skb_put(skb,wmm_info_len);
- + if(wmm_info_len) {
- + ieee80211_WMM_Info(ieee, &tag);
- + }
- +#ifdef THOMAS_TURBO
- + tag = skb_put(skb,turbo_info_len);
- + if(turbo_info_len) {
- + ieee80211_TURBO_Info(ieee, &tag);
- + }
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2)
- + ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb);
- +#endif
- +
- + return skb;
- +}
- +
- +void ieee80211_associate_abort(struct ieee80211_device *ieee)
- +{
- +
- + unsigned long flags;
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + ieee->associate_seq++;
- +
- + /* don't scan, and avoid to have the RX path possibily
- + * try again to associate. Even do not react to AUTH or
- + * ASSOC response. Just wait for the retry wq to be scheduled.
- + * Here we will check if there are good nets to associate
- + * with, so we retry or just get back to NO_LINK and scanning
- + */
- + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
- + IEEE80211_DEBUG_MGMT("Authentication failed\n");
- + ieee->softmac_stats.no_auth_rs++;
- + }else{
- + IEEE80211_DEBUG_MGMT("Association failed\n");
- + ieee->softmac_stats.no_ass_rs++;
- + }
- +
- + ieee->state = IEEE80211_ASSOCIATING_RETRY;
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
- + IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
- +#else
- + schedule_task(&ieee->associate_retry_wq);
- +#endif
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +}
- +
- +void ieee80211_associate_abort_cb(unsigned long dev)
- +{
- + ieee80211_associate_abort((struct ieee80211_device *) dev);
- +}
- +
- +
- +void ieee80211_associate_step1(struct ieee80211_device *ieee)
- +{
- + struct ieee80211_network *beacon = &ieee->current_network;
- + struct sk_buff *skb;
- +
- + IEEE80211_DEBUG_MGMT("Stopping scan\n");
- +
- + ieee->softmac_stats.tx_auth_rq++;
- + skb=ieee80211_authentication_req(beacon, ieee, 0);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode ) {
- + if(skb)
- + softmac_mgmt_xmit(skb, ieee);
- + return;
- + }else
- +#endif
- + if (!skb)
- + ieee80211_associate_abort(ieee);
- + else{
- + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
- + IEEE80211_DEBUG_MGMT("Sending authentication request\n");
- + //printk(KERN_WARNING "Sending authentication request\n");
- + softmac_mgmt_xmit(skb, ieee);
- + //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
- + if(!timer_pending(&ieee->associate_timer)){
- + ieee->associate_timer.expires = jiffies + (HZ / 2);
- + add_timer(&ieee->associate_timer);
- + }
- + dev_kfree_skb_any(skb);//edit by thomas
- + }
- +}
- +
- +void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
- +{
- + u8 *c;
- + struct sk_buff *skb;
- + struct ieee80211_network *beacon = &ieee->current_network;
- +// int hlen = sizeof(struct ieee80211_authentication);
- +
- + ieee->associate_seq++;
- + ieee->softmac_stats.tx_auth_rq++;
- +
- + skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
- + if (!skb)
- + ieee80211_associate_abort(ieee);
- + else{
- + c = skb_put(skb, chlen+2);
- + *(c++) = MFIE_TYPE_CHALLENGE;
- + *(c++) = chlen;
- + memcpy(c, challenge, chlen);
- +
- + IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
- +
- + ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
- +
- + softmac_mgmt_xmit(skb, ieee);
- +
- + if(!timer_pending(&ieee->associate_timer)){
- + ieee->associate_timer.expires = jiffies + (HZ / 2);
- + add_timer(&ieee->associate_timer);
- + }
- + dev_kfree_skb_any(skb);//edit by thomas
- + }
- + kfree(challenge);
- +}
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +
- +// based on ieee80211_assoc_resp
- +struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
- +{
- + struct sk_buff *skb;
- + u8* tag;
- +
- + struct ieee80211_crypt_data* crypt;
- + struct ieee80211_assoc_response_frame *assoc;
- + short encrypt;
- +
- + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
- +
- + if(ieee->iw_mode == ieee->iw_ext_mode)
- + skb = dev_alloc_skb(len+256); // stanley
- + else
- + skb = dev_alloc_skb(len);
- +
- + if (!skb)
- + return NULL;
- +
- + assoc = (struct ieee80211_assoc_response_frame *)
- + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
- +
- + assoc->header.frame_ctl = cpu_to_le16(pkt_type);
- +
- + memcpy(assoc->header.addr1, dest,ETH_ALEN);
- + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
- + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
- +
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1)
- + ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc);
- +
- + if(ieee->short_slot)
- + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
- +
- + if (ieee->host_encrypt)
- +#ifdef _RTL8187_EXT_PATCH_
- + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
- +#else
- + crypt = ieee->crypt[ieee->tx_keyidx];
- +#endif
- +
- + else crypt = NULL;
- +
- + encrypt = ( crypt && crypt->ops);
- +
- + if (encrypt)
- + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
- +
- + assoc->status = 0;
- + assoc->aid = cpu_to_le16(ieee->assoc_id);
- + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
- + else ieee->assoc_id++;
- +
- + assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
- + assoc->info_element.len = 0;
- +
- + tag = (u8*) skb_put(skb, rate_len);
- +
- + ieee80211_MFIE_Brate(ieee, &tag);
- + ieee80211_MFIE_Grate(ieee, &tag);
- +
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2)
- + ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb);
- +
- + return skb;
- +}
- +
- +// based on ieee80211_resp_to_assoc_rq
- +void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
- +{
- + struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
- +
- + if (buf)
- + softmac_mgmt_xmit(buf, ieee);
- +}
- +
- +// based on ieee80211_associate_step2
- +void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
- +{
- +
- + struct sk_buff* skb;
- +
- + // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
- +
- + ieee->softmac_stats.tx_ass_rq++;
- + skb=ieee80211_association_req(pstat, ieee);
- + if (skb)
- + softmac_mgmt_xmit(skb, ieee);
- +}
- +
- +void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
- +{
- + // do nothing
- + // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
- + return;
- +}
- +#endif // _RTL8187_EXT_PATCH_
- +
- +void ieee80211_associate_step2(struct ieee80211_device *ieee)
- +{
- + struct sk_buff* skb;
- + struct ieee80211_network *beacon = &ieee->current_network;
- +
- +// del_timer_sync(&ieee->associate_timer);
- +
- + IEEE80211_DEBUG_MGMT("Sending association request\n");
- +
- + ieee->softmac_stats.tx_ass_rq++;
- + skb=ieee80211_association_req(beacon, ieee);
- + if (!skb)
- + ieee80211_associate_abort(ieee);
- + else{
- + softmac_mgmt_xmit(skb, ieee);
- + if(!timer_pending(&ieee->associate_timer)){
- + ieee->associate_timer.expires = jiffies + (HZ / 2);
- + add_timer(&ieee->associate_timer);
- + }
- + dev_kfree_skb_any(skb);//edit by thomas
- + }
- +}
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void ieee80211_associate_complete_wq(struct work_struct *work)
- +{
- + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
- +#else
- +void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- + printk(KERN_INFO "Associated successfully\n");
- + if(ieee80211_is_54g(ieee->current_network) &&
- + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
- +
- + ieee->rate = 540;
- + printk(KERN_INFO"Using G rates\n");
- + }else{
- + ieee->rate = 110;
- + printk(KERN_INFO"Using B rates\n");
- + }
- +
- +//by lizhaoming for LED LINK
- +#ifdef LED_SHIN
- + {
- + struct net_device *dev = ieee->dev;
- + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
- + }
- +#endif
- +
- + ieee->link_change(ieee->dev);
- + notify_wx_assoc_event(ieee);
- + if (ieee->data_hard_resume)
- + ieee->data_hard_resume(ieee->dev);
- + netif_carrier_on(ieee->dev);
- +}
- +
- +void ieee80211_associate_complete(struct ieee80211_device *ieee)
- +{
- + int i;
- +// struct net_device *dev = ieee->dev;
- + del_timer_sync(&ieee->associate_timer);
- +
- + for(i = 0; i < 6; i++) {
- +// ieee->seq_ctrl[i] = 0;
- + }
- + ieee->state = IEEE80211_LINKED;
- + IEEE80211_DEBUG_MGMT("Successfully associated\n");
- +
- + //by lizhaoming for LED LINK
- + //ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq, &ieee->associate_complete_wq);
- +#else
- + schedule_task(&ieee->associate_complete_wq);
- +#endif
- +}
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void ieee80211_associate_procedure_wq(struct work_struct *work)
- +{
- + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
- +#else
- +void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- + ieee->sync_scan_hurryup = 1;
- + down(&ieee->wx_sem);
- +
- + if (ieee->data_hard_stop)
- + ieee->data_hard_stop(ieee->dev);
- +
- + ieee80211_stop_scan(ieee);
- + //printk("=======>%s set chan:%d\n", __func__, ieee->current_network.channel);
- + ieee->set_chan(ieee->dev, ieee->current_network.channel);
- +
- + ieee->associate_seq = 1;
- + ieee80211_associate_step1(ieee);
- +
- + up(&ieee->wx_sem);
- +}
- +#ifdef _RTL8187_EXT_PATCH_
- +// based on ieee80211_associate_procedure_wq
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +void ieee80211_ext_stop_scan_wq(struct work_struct *work)
- +{
- + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
- +#else
- +void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- +/*
- + if (ieee->scanning == 0)
- + {
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
- + && ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) )
- + return;
- + }
- +*/
- + ieee->sync_scan_hurryup = 1;
- +
- + down(&ieee->wx_sem);
- +
- + // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
- + if (ieee->data_hard_stop)
- + ieee->data_hard_stop(ieee->dev);
- +
- + ieee80211_stop_scan(ieee);
- +
- + // set channel
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel)
- + {
- + int ch = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
- + ieee->current_network.channel = ch;
- + ieee->set_chan(ieee->dev, ch);
- + }
- + else
- + {
- + ieee->set_chan(ieee->dev, ieee->current_network.channel);
- + }
- + //
- + up(&ieee->wx_sem);
- +}
- +
- +
- +void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
- +{
- + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
- + #else
- + schedule_task(&ieee->ext_send_beacon_wq);
- + #endif
- +
- +}
- +
- +#endif // _RTL8187_EXT_PATCH_
- +
- +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
- +{
- + u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
- + int tmp_ssid_len = 0;
- +
- + short apset,ssidset,ssidbroad,apmatch,ssidmatch;
- +// printk("===============>%s()\n",__FUNCTION__);
- + /* we are interested in new new only if we are not associated
- + * and we are not associating / authenticating
- + */
- + if (ieee->state != IEEE80211_NOLINK)
- + return;
- +
- + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
- + return;
- +
- + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
- + return;
- +
- +
- + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
- + /* if the user specified the AP MAC, we need also the essid
- + * This could be obtained by beacons or, if the network does not
- + * broadcast it, it can be put manually.
- + */
- + apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
- + ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
- + ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
- + apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
- + if(ieee->current_network.ssid_len != net->ssid_len)
- + ssidmatch = 0;
- + else
- + ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
- +
- +
- +
- + if ( /* if the user set the AP check if match.
- + * if the network does not broadcast essid we check the user supplyed ANY essid
- + * if the network does broadcast and the user does not set essid it is OK
- + * if the network does broadcast and the user did set essid chech if essid match
- + */
- + ( apset && apmatch &&
- + //((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
- + ((ssidset && ssidbroad && ssidmatch) || (!ssidbroad && ssidset)) ) ||
- + /* if the ap is not set, check that the user set the bssid
- + * and the network does bradcast and that those two bssid matches
- + */
- + (!apset && ssidset && ssidbroad && ssidmatch)
- + ){
- + /* if the essid is hidden replace it with the
- + * essid provided by the user.
- + */
- + if (!ssidbroad){
- + strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
- + tmp_ssid_len = ieee->current_network.ssid_len;
- + }
- + memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
- +
- + if (!ssidbroad){
- + strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
- + ieee->current_network.ssid_len = tmp_ssid_len;
- + }
- + printk(KERN_INFO"Linking with %s, channel:%d\n",ieee->current_network.ssid, ieee->current_network.channel);
- +
- +#ifdef CONFIG_IPS
- + ieee->ieee80211_ips_leave(ieee->dev);
- +#endif
- +
- + if (ieee->iw_mode == IW_MODE_INFRA){
- + ieee->state = IEEE80211_ASSOCIATING;
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq, &ieee->associate_procedure_wq);
- +#else
- + schedule_task(&ieee->associate_procedure_wq);
- +#endif
- + }else{
- + ieee->state = IEEE80211_LINKED;
- + if(ieee80211_is_54g(ieee->current_network) &&
- + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
- + ieee->rate = 540;
- + printk(KERN_INFO"Using G rates\n");
- + }else{
- + ieee->rate = 110;
- + printk(KERN_INFO"Using B rates\n");
- + }
- + }
- +
- + }
- + }
- +
- +}
- +
- +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
- +{
- + unsigned long flags;
- + struct ieee80211_network *target;
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- +#if 0
- + list_for_each_entry(target, &ieee->network_list, list) {
- + printk(KERN_INFO"check network list SSID: %s, channel: %d\n",target->ssid,target->channel);
- + }
- +#endif
- + list_for_each_entry(target, &ieee->network_list, list) {
- +
- + /* if the state become different that NOLINK means
- + * we had found what we are searching for
- + */
- +
- + if (ieee->state != IEEE80211_NOLINK)
- + break;
- +
- + if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
- + ieee80211_softmac_new_net(ieee, target);
- + }
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- + //printk("<=====%s\n", __func__);
- +}
- +
- +
- +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
- +{
- + struct ieee80211_authentication *a;
- + u8 *t;
- + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
- + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
- + return 0xcafe;
- + }
- + *challenge = NULL;
- + a = (struct ieee80211_authentication*) skb->data;
- + if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
- + t = skb->data + sizeof(struct ieee80211_authentication);
- +
- + if(*(t++) == MFIE_TYPE_CHALLENGE){
- + *chlen = *(t++);
- + *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
- + memcpy(*challenge, t, *chlen);
- + }
- + }
- +
- + return cpu_to_le16(a->status);
- +
- +}
- +
- +
- +int auth_rq_parse(struct sk_buff *skb,u8* dest)
- +{
- + struct ieee80211_authentication *a;
- +
- + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
- + IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
- + return -1;
- + }
- + a = (struct ieee80211_authentication*) skb->data;
- +
- + memcpy(dest,a->header.addr2, ETH_ALEN);
- +
- + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
- + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
- +
- + return WLAN_STATUS_SUCCESS;
- +}
- +
- +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
- +{
- + u8 *tag;
- + u8 *skbend;
- + u8 *ssid=NULL;
- + u8 ssidlen = 0;
- +
- + struct ieee80211_hdr_3addr *header =
- + (struct ieee80211_hdr_3addr *) skb->data;
- +
- + if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
- + return -1; /* corrupted */
- +
- + memcpy(src,header->addr2, ETH_ALEN);
- +
- + skbend = (u8*)skb->data + skb->len;
- +
- + tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
- +
- + while (tag+1 < skbend){
- + if (*tag == 0){
- + ssid = tag+2;
- + ssidlen = *(tag+1);
- + break;
- + }
- + tag++; /* point to the len field */
- + tag = tag + *(tag); /* point to the last data byte of the tag */
- + tag++; /* point to the next tag */
- + }
- +
- + //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
- + if (ssidlen == 0) return 1;
- +
- + if (!ssid) return 1; /* ssid not found in tagged param */
- + return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
- +
- +}
- +
- +int assoc_rq_parse(struct sk_buff *skb,u8* dest)
- +{
- + struct ieee80211_assoc_request_frame *a;
- +
- + if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
- + sizeof(struct ieee80211_info_element))) {
- +
- + IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
- + return -1;
- + }
- +
- + a = (struct ieee80211_assoc_request_frame*) skb->data;
- +
- + memcpy(dest,a->header.addr2,ETH_ALEN);
- +
- + return 0;
- +}
- +
- +static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
- +{
- + struct ieee80211_assoc_response_frame *a;
- + if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
- + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
- + return 0xcafe;
- + }
- +
- + a = (struct ieee80211_assoc_response_frame*) skb->data;
- + *aid = le16_to_cpu(a->aid) & 0x3fff;
- + return le16_to_cpu(a->status);
- +}
- +
- +static inline void
- +ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
- +{
- + u8 dest[ETH_ALEN];
- +
- + //IEEE80211DMESG("Rx probe");
- + ieee->softmac_stats.rx_probe_rq++;
- + //DMESG("Dest is "MACSTR, MAC2STR(dest));
- + if (probe_rq_parse(ieee, skb, dest)){
- + //IEEE80211DMESG("Was for me!");
- + ieee->softmac_stats.tx_probe_rs++;
- + ieee80211_resp_to_probe(ieee, dest);
- + }
- +}
- +
- +//static inline void
- +inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
- +{
- + u8 dest[ETH_ALEN];
- + int status;
- + //IEEE80211DMESG("Rx probe");
- + ieee->softmac_stats.rx_auth_rq++;
- +
- + if ((status = auth_rq_parse(skb, dest))!= -1){
- + ieee80211_resp_to_auth(ieee, status, dest);
- + }
- + //DMESG("Dest is "MACSTR, MAC2STR(dest));
- +
- +}
- +
- +//static inline void
- +inline void
- +ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
- +{
- +
- + u8 dest[ETH_ALEN];
- + //unsigned long flags;
- +
- + ieee->softmac_stats.rx_ass_rq++;
- + if (assoc_rq_parse(skb,dest) != -1){
- + ieee80211_resp_to_assoc_rq(ieee, dest);
- + }
- +
- + printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
- + //FIXME
- + #if 0
- + spin_lock_irqsave(&ieee->lock,flags);
- + add_associate(ieee,dest);
- + spin_unlock_irqrestore(&ieee->lock,flags);
- + #endif
- +}
- +
- +
- +
- +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
- +{
- +
- + struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
- +
- + printk(KERN_ALERT "ieee80211_sta_ps_send_null_frame \n");
- + if (buf)
- + softmac_ps_mgmt_xmit(buf, ieee);
- +
- +}
- +
- +
- +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
- +{
- + int timeout = ieee->ps_timeout;
- + u8 dtim;
- + /*if(ieee->ps == IEEE80211_PS_DISABLED ||
- + ieee->iw_mode != IW_MODE_INFRA ||
- + ieee->state != IEEE80211_LINKED)
- +
- + return 0;
- + */
- + dtim = ieee->current_network.dtim_data;
- + //printk("DTIM\n");
- + if(!(dtim & IEEE80211_DTIM_VALID))
- + return 0;
- + //printk("VALID\n");
- + ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
- +
- + if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
- + return 2;
- +
- + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
- + return 0;
- +
- + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
- + return 0;
- +
- + if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
- + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
- + return 0;
- +
- + if(time_l){
- + *time_l = ieee->current_network.last_dtim_sta_time[0]
- + + (ieee->current_network.beacon_interval
- + * ieee->current_network.dtim_period) * 1000;
- + }
- +
- + if(time_h){
- + *time_h = ieee->current_network.last_dtim_sta_time[1];
- + if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
- + *time_h += 1;
- + }
- +
- + return 1;
- +
- +
- +}
- +
- +inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
- +{
- +
- + u32 th,tl;
- + short sleep;
- +
- + unsigned long flags,flags2;
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + if((ieee->ps == IEEE80211_PS_DISABLED ||
- + ieee->iw_mode != IW_MODE_INFRA ||
- + ieee->state != IEEE80211_LINKED)){
- +
- + // #warning CHECK_LOCK_HERE
- + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- +
- + ieee80211_sta_wakeup(ieee, 1);
- +
- + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- + }
- +
- + sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
- + /* 2 wake, 1 sleep, 0 do nothing */
- + if(sleep == 0)
- + goto out;
- +
- + if(sleep == 1){
- +
- + if(ieee->sta_sleep == 1)
- + ieee->enter_sleep_state(ieee->dev,th,tl);
- +
- + else if(ieee->sta_sleep == 0){
- + // printk("send null 1\n");
- + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- +
- + if(ieee->ps_is_queue_empty(ieee->dev)){
- +
- +
- + ieee->sta_sleep = 2;
- +
- + ieee->ps_request_tx_ack(ieee->dev);
- +
- + ieee80211_sta_ps_send_null_frame(ieee,1);
- +
- + ieee->ps_th = th;
- + ieee->ps_tl = tl;
- + }
- + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- +
- + }
- +
- +
- + }else if(sleep == 2){
- +//#warning CHECK_LOCK_HERE
- + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- +
- + ieee80211_sta_wakeup(ieee,1);
- +
- + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- + }
- +
- +out:
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- +}
- +
- +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
- +{
- + if(ieee->sta_sleep == 0){
- + if(nl){
- + printk("Warning: driver is probably failing to report TX ps error\n");
- + ieee->ps_request_tx_ack(ieee->dev);
- + ieee80211_sta_ps_send_null_frame(ieee, 0);
- + }
- + return;
- +
- + }
- +
- + if(ieee->sta_sleep == 1)
- + ieee->sta_wake_up(ieee->dev);
- +
- + ieee->sta_sleep = 0;
- +
- + if(nl){
- + ieee->ps_request_tx_ack(ieee->dev);
- + ieee80211_sta_ps_send_null_frame(ieee, 0);
- + }
- +}
- +
- +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
- +{
- + unsigned long flags,flags2;
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + if(ieee->sta_sleep == 2){
- + /* Null frame with PS bit set */
- + if(success){
- + ieee->sta_sleep = 1;
- + ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
- + }
- + /* if the card report not success we can't be sure the AP
- + * has not RXed so we can't assume the AP believe us awake
- + */
- + }
- + /* 21112005 - tx again null without PS bit if lost */
- + else {
- +
- + if((ieee->sta_sleep == 0) && !success){
- + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- + ieee80211_sta_ps_send_null_frame(ieee, 0);
- + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- + }
- + }
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +}
- +
- +inline int
- +ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
- + struct ieee80211_rx_stats *rx_stats, u16 type,
- + u16 stype)
- +{
- + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
- + u16 errcode;
- + u8* challenge=NULL;
- + int chlen=0;
- + int aid=0;
- + struct ieee80211_assoc_response_frame *assoc_resp;
- + struct ieee80211_info_element *info_element;
- +
- + if(!ieee->proto_started)
- + return 0;
- +
- + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
- + ieee->iw_mode == IW_MODE_INFRA &&
- + ieee->state == IEEE80211_LINKED))
- +
- + tasklet_schedule(&ieee->ps_task);
- +
- + if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
- + WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
- + ieee->last_rx_ps_time = jiffies;
- +
- + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
- + case IEEE80211_STYPE_ASSOC_RESP:
- + case IEEE80211_STYPE_REASSOC_RESP:
- +
- + IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
- + WLAN_FC_GET_STYPE(header->frame_ctl));
- + //printk(KERN_WARNING "Received association response\n");
- + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- + ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
- + ieee->iw_mode == IW_MODE_INFRA){
- + if (0 == (errcode=assoc_parse(skb, &aid))){
- + u16 left;
- +
- + ieee->state=IEEE80211_LINKED;
- + ieee->assoc_id = aid;
- + ieee->softmac_stats.rx_ass_ok++;
- +
- + //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B");
- + if(1 == rx_stats->nic_type) //card type is 8187
- + {
- + goto associate_complete;
- + }
- + assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
- + info_element = &assoc_resp->info_element;
- + left = skb->len - ((void*)info_element - (void*)assoc_resp);
- +
- + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
- + printk(KERN_WARNING "[re]associate reeponse error!");
- + return 1;
- + }
- + switch (info_element->id) {
- + case MFIE_TYPE_GENERIC:
- + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
- + if (info_element->len >= 8 &&
- + info_element->data[0] == 0x00 &&
- + info_element->data[1] == 0x50 &&
- + info_element->data[2] == 0xf2 &&
- + info_element->data[3] == 0x02 &&
- + info_element->data[4] == 0x01) {
- + // Not care about version at present.
- + //WMM Parameter Element
- + memcpy(ieee->current_network.wmm_param,(u8*)(info_element->data\
- + + 8),(info_element->len - 8));
- +
- + if (((ieee->current_network.wmm_info^info_element->data[6])& \
- + 0x0f)||(!ieee->init_wmmparam_flag)) {
- + //refresh paramete element for current network
- + // update the register parameter for hardware
- + ieee->init_wmmparam_flag = 1;
- + //ieee->wmm_param_update(ieee);
- + //schedule_work(&ieee->wmm_param_update_wq);
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq, &ieee->wmm_param_update_wq);
- +#else
- + schedule_task(&ieee->wmm_param_update_wq);
- +#endif
- +
- + }
- + //update info_element for current network
- + ieee->current_network.wmm_info = info_element->data[6];
- + }
- + break;
- + default:
- + //nothing to do at present!!!
- + break;
- + }
- +
- + left -= sizeof(struct ieee80211_info_element_hdr) +
- + info_element->len;
- + info_element = (struct ieee80211_info_element *)
- + &info_element->data[info_element->len];
- + }
- + if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register
- + {
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq,&ieee->wmm_param_update_wq);
- +#else
- + schedule_task(&ieee->wmm_param_update_wq);
- +#endif
- + ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate
- + }
- +associate_complete:
- + ieee80211_associate_complete(ieee);
- + }else{
- + ieee->softmac_stats.rx_ass_err++;
- + IEEE80211_DEBUG_MGMT(
- + "Association response status code 0x%x\n",
- + errcode);
- + printk(KERN_WARNING "Association response status code 0x%x\n",
- + errcode);
- + ieee80211_associate_abort(ieee);
- + }
- + }
- +#ifdef _RTL8187_EXT_PATCH_
- + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp)
- + {
- + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
- + }
- +#endif
- + break;
- +
- + case IEEE80211_STYPE_ASSOC_REQ:
- + case IEEE80211_STYPE_REASSOC_REQ:
- + //printk("Received IEEE80211_STYPE_ASSOC_REQ\n");
- +
- + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- + ieee->iw_mode == IW_MODE_MASTER)
- +
- + ieee80211_rx_assoc_rq(ieee, skb);
- +#ifdef _RTL8187_EXT_PATCH_
- + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req)
- + {
- + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
- + }
- +#endif
- + break;
- +
- + case IEEE80211_STYPE_AUTH:
- + //printk("Received authentication response\n");
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +//printk("IEEE80211_STYPE_AUTH\n");
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth)
- + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) );
- +#endif
- + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
- + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
- + ieee->iw_mode == IW_MODE_INFRA){
- +
- + IEEE80211_DEBUG_MGMT("Received authentication response");
- +
- + if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
- + if(ieee->open_wep || !challenge){
- + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
- + ieee->softmac_stats.rx_auth_rs_ok++;
- +
- + ieee80211_associate_step2(ieee);
- + }else{
- + ieee80211_auth_challenge(ieee, challenge, chlen);
- + }
- + }else{
- + ieee->softmac_stats.rx_auth_rs_err++;
- + IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
- + ieee80211_associate_abort(ieee);
- + }
- +
- + }else if (ieee->iw_mode == IW_MODE_MASTER){
- + ieee80211_rx_auth_rq(ieee, skb);
- + }
- + }
- + break;
- +
- + case IEEE80211_STYPE_PROBE_REQ:
- + //printk("Received IEEE80211_STYPE_PROBE_REQ\n");
- +
- + if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
- + ((ieee->iw_mode == IW_MODE_ADHOC ||
- + ieee->iw_mode == IW_MODE_MASTER) &&
- + ieee->state == IEEE80211_LINKED))
- +
- + ieee80211_rx_probe_rq(ieee, skb);
- + break;
- +
- + case IEEE80211_STYPE_DISASSOC:
- + case IEEE80211_STYPE_DEAUTH:
- + //printk("Received IEEE80211_STYPE_DISASSOC\n");
- +#ifdef _RTL8187_EXT_PATCH_
- +//printk("IEEE80211_STYPE_DEAUTH\n");
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth)
- + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) ) ;
- +#endif
- + /* FIXME for now repeat all the association procedure
- + * both for disassociation and deauthentication
- + */
- + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- + ieee->state == IEEE80211_LINKED &&
- + ieee->iw_mode == IW_MODE_INFRA){
- +
- + ieee->state = IEEE80211_ASSOCIATING;
- + ieee->softmac_stats.reassoc++;
- +
- + notify_wx_assoc_event(ieee);
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq, &ieee->associate_procedure_wq);
- +#else
- + schedule_task(&ieee->associate_procedure_wq);
- +#endif
- + }
- +
- + break;
- +
- + default:
- + return -1;
- + break;
- + }
- +
- + //dev_kfree_skb_any(skb);
- + return 0;
- +}
- +
- +
- +
- +/* following are for a simplier TX queue management.
- + * Instead of using netif_[stop/wake]_queue the driver
- + * will uses these two function (plus a reset one), that
- + * will internally uses the kernel netif_* and takes
- + * care of the ieee802.11 fragmentation.
- + * So the driver receives a fragment per time and might
- + * call the stop function when it want without take care
- + * to have enought room to TX an entire packet.
- + * This might be useful if each fragment need it's own
- + * descriptor, thus just keep a total free memory > than
- + * the max fragmentation treshold is not enought.. If the
- + * ieee802.11 stack passed a TXB struct then you needed
- + * to keep N free descriptors where
- + * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
- + * In this way you need just one and the 802.11 stack
- + * will take care of buffering fragments and pass them to
- + * to the driver later, when it wakes the queue.
- + */
- +
- +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
- +{
- +
- +
- + unsigned long flags;
- + int i;
- +#ifdef _RTL8187_EXT_PATCH_
- + int rate = ieee->rate;
- +#endif
- +
- + spin_lock_irqsave(&ieee->lock,flags);
- + #if 0
- + if(ieee->queue_stop){
- + IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
- + netif_stop_queue(ieee->dev);
- + ieee->ieee_stats.swtxstop++;
- + //dev_kfree_skb_any(skb);
- + err = 1;
- + goto exit;
- + }
- +
- + ieee->stats.tx_bytes+=skb->len;
- +
- +
- + txb=ieee80211_skb_to_txb(ieee,skb);
- +
- +
- + if(txb==NULL){
- + IEEE80211DMESG("WW: IEEE stack failed to provide txb");
- + //dev_kfree_skb_any(skb);
- + err = 1;
- + goto exit;
- + }
- + #endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags)
- + {
- + rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
- + }
- +#endif
- + /* called with 2nd parm 0, no tx mgmt lock required */
- + ieee80211_sta_wakeup(ieee,0);
- +
- + for(i = 0; i < txb->nr_frags; i++) {
- +
- + if (ieee->queue_stop){
- + ieee->tx_pending.txb = txb;
- + ieee->tx_pending.frag = i;
- + goto exit;
- + }else{
- + ieee->softmac_data_hard_start_xmit(
- + txb->fragments[i],
- +#ifdef _RTL8187_EXT_PATCH_
- + ieee->dev, rate);
- +#else
- + ieee->dev,ieee->rate);
- +#endif
- + //(i+1)<txb->nr_frags);
- + ieee->stats.tx_packets++;
- + ieee->stats.tx_bytes += txb->fragments[i]->len;
- + ieee->dev->trans_start = jiffies;
- + }
- + }
- +
- + ieee80211_txb_free(txb);
- +
- + exit:
- + spin_unlock_irqrestore(&ieee->lock,flags);
- +
- +}
- +
- +/* called with ieee->lock acquired */
- +void ieee80211_resume_tx(struct ieee80211_device *ieee)
- +{
- + int i;
- + for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
- +
- + if (ieee->queue_stop){
- + ieee->tx_pending.frag = i;
- + return;
- + }else{
- +
- + ieee->softmac_data_hard_start_xmit(
- + ieee->tx_pending.txb->fragments[i],
- + ieee->dev,ieee->rate);
- + //(i+1)<ieee->tx_pending.txb->nr_frags);
- + ieee->stats.tx_packets++;
- + ieee->dev->trans_start = jiffies;
- + }
- + }
- +
- +
- + ieee80211_txb_free(ieee->tx_pending.txb);
- + ieee->tx_pending.txb = NULL;
- +}
- +
- +
- +void ieee80211_reset_queue(struct ieee80211_device *ieee)
- +{
- + unsigned long flags;
- +
- + spin_lock_irqsave(&ieee->lock,flags);
- + init_mgmt_queue(ieee);
- + if (ieee->tx_pending.txb){
- + ieee80211_txb_free(ieee->tx_pending.txb);
- + ieee->tx_pending.txb = NULL;
- + }
- + ieee->queue_stop = 0;
- + spin_unlock_irqrestore(&ieee->lock,flags);
- +
- +}
- +
- +void ieee80211_wake_queue(struct ieee80211_device *ieee)
- +{
- +
- + unsigned long flags;
- + struct sk_buff *skb;
- + struct ieee80211_hdr_3addr *header;
- +
- + spin_lock_irqsave(&ieee->lock,flags);
- + if (! ieee->queue_stop) goto exit;
- +
- + ieee->queue_stop = 0;
- +
- + if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
- + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
- +
- + header = (struct ieee80211_hdr_3addr *) skb->data;
- +
- + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
- +
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- +
- + printk(KERN_ALERT "ieee80211_wake_queue \n");
- + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
- + dev_kfree_skb_any(skb);//edit by thomas
- + }
- + }
- + if (!ieee->queue_stop && ieee->tx_pending.txb)
- + ieee80211_resume_tx(ieee);
- +
- + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
- + ieee->softmac_stats.swtxawake++;
- + netif_wake_queue(ieee->dev);
- + }
- +
- +exit :
- + spin_unlock_irqrestore(&ieee->lock,flags);
- +}
- +
- +
- +void ieee80211_stop_queue(struct ieee80211_device *ieee)
- +{
- + //unsigned long flags;
- + //spin_lock_irqsave(&ieee->lock,flags);
- +
- + if (! netif_queue_stopped(ieee->dev)){
- + netif_stop_queue(ieee->dev);
- + ieee->softmac_stats.swtxstop++;
- + }
- + ieee->queue_stop = 1;
- + //spin_unlock_irqrestore(&ieee->lock,flags);
- +
- +}
- +
- +
- +inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
- +{
- +
- + get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
- +
- + /* an IBSS cell address must have the two less significant
- + * bits of the first byte = 2
- + */
- + ieee->current_network.bssid[0] &= ~0x01;
- + ieee->current_network.bssid[0] |= 0x02;
- +}
- +
- +/* called in user context only */
- +void ieee80211_start_master_bss(struct ieee80211_device *ieee)
- +{
- + ieee->assoc_id = 1;
- +
- + if (ieee->current_network.ssid_len == 0){
- + strncpy(ieee->current_network.ssid,
- + IEEE80211_DEFAULT_TX_ESSID,
- + IW_ESSID_MAX_SIZE);
- +
- + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- + ieee->ssid_set = 1;
- + }
- +
- + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
- +
- + ieee->set_chan(ieee->dev, ieee->current_network.channel);
- + ieee->state = IEEE80211_LINKED;
- +
- +//by lizhaoming for LED LINK
- +#ifdef LED_SHIN
- + {
- + struct net_device *dev = ieee->dev;
- + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
- + }
- +#endif
- + ieee->link_change(ieee->dev);
- + notify_wx_assoc_event(ieee);
- +
- + if (ieee->data_hard_resume)
- + ieee->data_hard_resume(ieee->dev);
- +
- + netif_carrier_on(ieee->dev);
- +}
- +
- +void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
- +{
- + if(ieee->raw_tx){
- +
- + if (ieee->data_hard_resume)
- + ieee->data_hard_resume(ieee->dev);
- +
- + netif_carrier_on(ieee->dev);
- + }
- +}
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void ieee80211_start_ibss_wq(struct work_struct *work)
- +{
- + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
- + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
- +#else
- +void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- +
- + /* iwconfig mode ad-hoc will schedule this and return
- + * on the other hand this will block further iwconfig SET
- + * operations because of the wx_sem hold.
- + * Anyway some most set operations set a flag to speed-up
- + * (abort) this wq (when syncro scanning) before sleeping
- + * on the semaphore
- + */
- +
- + down(&ieee->wx_sem);
- +
- + if (ieee->current_network.ssid_len == 0){
- + strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
- + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- + ieee->ssid_set = 1;
- + }
- +
- +//by lizhaoming for LED BLINK 2008.6.23
- +#ifdef LED_SHIN
- + {
- + struct net_device *dev = ieee->dev;
- + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
- + }
- +#endif
- +
- + /* check if we have this cell in our network list */
- + ieee80211_softmac_check_all_nets(ieee);
- +
- +#ifdef ENABLE_DOT11D
- + //[World wide 13]:
- + // Adhoc:
- + // (1) active scan from ch1~11 and passive scan from ch12~13
- + // (2) IBSS can join ch1~13 adhoc, but only start at ch10.
- + if(ieee->state == IEEE80211_NOLINK)
- + if(ieee->IbssStartChnl != 0)
- + ieee->current_network.channel = ieee->IbssStartChnl;//chan 10
- +#endif
- +
- + /* if not then the state is not linked. Maybe the user swithced to
- + * ad-hoc mode just after being in monitor mode, or just after
- + * being very few time in managed mode (so the card have had no
- + * time to scan all the chans..) or we have just run up the iface
- + * after setting ad-hoc mode. So we have to give another try..
- + * Here, in ibss mode, should be safe to do this without extra care
- + * (in bss mode we had to make sure no-one tryed to associate when
- + * we had just checked the ieee->state and we was going to start the
- + * scan) beacause in ibss mode the ieee80211_new_net function, when
- + * finds a good net, just set the ieee->state to IEEE80211_LINKED,
- + * so, at worst, we waste a bit of time to initiate an unneeded syncro
- + * scan, that will stop at the first round because it sees the state
- + * associated.
- + */
- + if (ieee->state == IEEE80211_NOLINK){
- + ieee80211_start_scan_syncro(ieee);
- + }
- +
- + /* the network definitively is not here.. create a new cell */
- + if (ieee->state == IEEE80211_NOLINK){
- + printk("creating new IBSS cell\n");
- + ieee->state = IEEE80211_LINKED;
- + if(!ieee->wap_set)
- + ieee80211_randomize_cell(ieee);
- +
- + if(ieee->modulation & IEEE80211_CCK_MODULATION){
- +
- + ieee->current_network.rates_len = 4;
- +
- + ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- + ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- + ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- + ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
- +
- + }else
- + ieee->current_network.rates_len = 0;
- +
- + if(ieee->modulation & IEEE80211_OFDM_MODULATION){
- + ieee->current_network.rates_ex_len = 8;
- +
- + ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- + ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
- + ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- + ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
- + ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- + ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
- + ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
- + ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
- +
- + ieee->rate = 540;
- + }else{
- + ieee->current_network.rates_ex_len = 0;
- + ieee->rate = 110;
- + }
- +
- + // By default, WMM function will be disabled in IBSS mode
- + ieee->current_network.QoS_Enable = 0;
- +
- + ieee->current_network.atim_window = 0;
- + ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
- + if(ieee->short_slot)
- + ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
- +
- + }
- +
- + ieee->state = IEEE80211_LINKED;
- +
- +//by lizhaoming for LED LINK
- +#ifdef LED_SHIN
- + {
- + struct net_device *dev = ieee->dev;
- + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
- + }
- +#endif
- +
- + ieee->set_chan(ieee->dev, ieee->current_network.channel);
- + ieee->link_change(ieee->dev);
- +
- + notify_wx_assoc_event(ieee);
- +
- + ieee80211_start_send_beacons(ieee);
- + printk(KERN_WARNING "after sending beacon packet!\n");
- +
- + if (ieee->data_hard_resume)
- + ieee->data_hard_resume(ieee->dev);
- +
- + netif_carrier_on(ieee->dev);
- +
- + up(&ieee->wx_sem);
- +}
- +
- +inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
- +{
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); //change to delayed work, delayed time is need to check
- +#else
- + schedule_task(&ieee->start_ibss_wq);
- +#endif
- +}
- +
- +/* this is called only in user context, with wx_sem held */
- +void ieee80211_start_bss(struct ieee80211_device *ieee)
- +{
- + unsigned long flags;
- + /* check if we have already found the net we
- + * are interested in (if any).
- + * if not (we are disassociated and we are not
- + * in associating / authenticating phase) start the background scanning.
- + */
- +
- +//by lizhaoming for LED BLINK 2008.6.23
- +#ifdef LED_SHIN
- + {
- + struct net_device *dev = ieee->dev;
- + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
- + }
- +#endif
- +
- +#ifdef ENABLE_DOT11D
- + //
- + // Ref: 802.11d 11.1.3.3
- + // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
- + //
- + if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
- + {
- + if(! ieee->bGlobalDomain)
- + {
- + return;
- + }
- + }
- +#endif
- + //printk("======>%s()\n",__FUNCTION__);
- + ieee80211_softmac_check_all_nets(ieee);
- +
- + /* ensure no-one start an associating process (thus setting
- + * the ieee->state to ieee80211_ASSOCIATING) while we
- + * have just cheked it and we are going to enable scan.
- + * The ieee80211_new_net function is always called with
- + * lock held (from both ieee80211_softmac_check_all_nets and
- + * the rx path), so we cannot be in the middle of such function
- + */
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- + if (ieee->state == IEEE80211_NOLINK){
- + //printk("Not find SSID in network list scan now\n");
- + ieee80211_start_scan(ieee);
- + }
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- +}
- +
- +/* called only in userspace context */
- +void ieee80211_disassociate(struct ieee80211_device *ieee)
- +{
- + netif_carrier_off(ieee->dev);
- +
- + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
- + ieee80211_reset_queue(ieee);
- +
- + if (ieee->data_hard_stop)
- + ieee->data_hard_stop(ieee->dev);
- +
- +#ifdef ENABLE_DOT11D
- + if(IS_DOT11D_ENABLE(ieee))
- + Dot11d_Reset(ieee);
- +#endif
- +
- + ieee->state = IEEE80211_NOLINK;
- + ieee->link_change(ieee->dev);
- + notify_wx_assoc_event(ieee);
- +
- +}
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void ieee80211_associate_retry_wq(struct work_struct *work)
- +{
- + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
- + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
- +#else
- +void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- + unsigned long flags;
- +
- + down(&ieee->wx_sem);
- + if(!ieee->proto_started)
- + goto exit;
- +
- + if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
- + goto exit;
- +
- + /* until we do not set the state to IEEE80211_NOLINK
- + * there are no possibility to have someone else trying
- + * to start an association procdure (we get here with
- + * ieee->state = IEEE80211_ASSOCIATING).
- + * When we set the state to IEEE80211_NOLINK it is possible
- + * that the RX path run an attempt to associate, but
- + * both ieee80211_softmac_check_all_nets and the
- + * RX path works with ieee->lock held so there are no
- + * problems. If we are still disassociated then start a scan.
- + * the lock here is necessary to ensure no one try to start
- + * an association procedure when we have just checked the
- + * state and we are going to start the scan.
- + */
- + ieee->state = IEEE80211_NOLINK;
- +
- + ieee80211_softmac_check_all_nets(ieee);
- +
- + spin_lock_irqsave(&ieee->lock, flags);
- + if(ieee->state == IEEE80211_NOLINK)
- + {
- + printk("%s():Not find SSID:%s[ch=%d, mode=%s] in network list scan now\n", __FUNCTION__,
- + ieee->current_network.ssid,ieee->current_network.channel,
- + (ieee->iw_mode == IW_MODE_INFRA) ? "BSS" : "IBSS");
- +
- + ieee80211_start_scan(ieee);
- + }
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- +exit:
- + up(&ieee->wx_sem);
- +}
- +
- +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
- +{
- + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
- +
- + struct sk_buff *skb = NULL;
- + struct ieee80211_probe_response *b;
- +
- +//rz
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp )
- + skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network));
- + else
- + skb = ieee80211_probe_resp(ieee, broadcast_addr);
- +#else
- + skb = ieee80211_probe_resp(ieee, broadcast_addr);
- +#endif
- +//
- + if (!skb)
- + return NULL;
- +
- + b = (struct ieee80211_probe_response *) skb->data;
- + b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
- +
- + return skb;
- +
- +}
- +
- +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
- +{
- + struct sk_buff *skb;
- + struct ieee80211_probe_response *b;
- +// printk("=========>%s()\n", __FUNCTION__);
- + skb = ieee80211_get_beacon_(ieee);
- + if(!skb)
- + return NULL;
- +
- + b = (struct ieee80211_probe_response *) skb->data;
- + b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
- +
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- +
- + return skb;
- +}
- +
- +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
- +{
- + ieee->sync_scan_hurryup = 1;
- + down(&ieee->wx_sem);
- + ieee80211_stop_protocol(ieee);
- + up(&ieee->wx_sem);
- +}
- +
- +
- +void ieee80211_stop_protocol(struct ieee80211_device *ieee)
- +{
- + if (!ieee->proto_started)
- + return;
- +
- + ieee->proto_started = 0;
- + //printk("=====>%s\n", __func__);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->ext_patch_ieee80211_stop_protocol)
- + ieee->ext_patch_ieee80211_stop_protocol(ieee);
- +//if call queue_delayed_work,can call this,or do nothing..
- +//edit by lawrence,20071118
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- +// cancel_delayed_work(&ieee->ext_stop_scan_wq);
- +// cancel_delayed_work(&ieee->ext_send_beacon_wq);
- +#endif
- +#endif // _RTL8187_EXT_PATCH_
- +
- + ieee80211_stop_send_beacons(ieee);
- +
- + del_timer_sync(&ieee->associate_timer);
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + cancel_delayed_work(&ieee->associate_retry_wq);
- + cancel_delayed_work(&ieee->start_ibss_wq); //cancel ibss start workqueue when stop protocol
- +#endif
- + ieee80211_stop_scan(ieee);
- +
- + ieee80211_disassociate(ieee);
- + //printk("<=====%s\n", __func__);
- +
- +}
- +
- +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
- +{
- + ieee->sync_scan_hurryup = 0;
- + down(&ieee->wx_sem);
- + ieee80211_start_protocol(ieee);
- + up(&ieee->wx_sem);
- +}
- +
- +void ieee80211_start_protocol(struct ieee80211_device *ieee)
- +{
- + short ch = 0;
- + int i = 0;
- +
- + if (ieee->proto_started)
- + return;
- +
- + //printk("=====>%s\n", __func__);
- +
- + ieee->proto_started = 1;
- +
- + if (ieee->current_network.channel == 0){
- + do{
- + ch++;
- + if (ch > MAX_CHANNEL_NUMBER)
- + return; /* no channel found */
- +#ifdef ENABLE_DOT11D
- + }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
- +#else
- + }while(!ieee->channel_map[ch]);
- +#endif
- + ieee->current_network.channel = ch;
- + }
- +
- + if (ieee->current_network.beacon_interval == 0)
- + ieee->current_network.beacon_interval = 100;
- +
- + ieee->set_chan(ieee->dev,ieee->current_network.channel);
- + mdelay(10);//must or link change will fail lzm
- +
- + for(i = 0; i < 17; i++) {
- + ieee->last_rxseq_num[i] = -1;
- + ieee->last_rxfrag_num[i] = -1;
- + ieee->last_packet_time[i] = 0;
- + }
- +
- + ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
- +
- +
- + /* if the user set the MAC of the ad-hoc cell and then
- + * switch to managed mode, shall we make sure that association
- + * attempts does not fail just because the user provide the essid
- + * and the nic is still checking for the AP MAC ??
- + */
- +
- + if (ieee->iw_mode == IW_MODE_INFRA){
- + ieee80211_start_bss(ieee);
- + // printk("==========> IW_MODE_INFRA\n");
- + }
- + else if (ieee->iw_mode == IW_MODE_ADHOC){
- + // printk("==========> IW_MODE_ADHOC\n");
- + ieee80211_start_ibss(ieee);
- + }
- + else if (ieee->iw_mode == IW_MODE_MASTER){
- + ieee80211_start_master_bss(ieee);
- +// printk("==========> IW_MODE_MASTER\n");
- + }
- + else if(ieee->iw_mode == IW_MODE_MONITOR){
- + ieee80211_start_monitor_mode(ieee);
- +// printk("==========> IW_MODE_MONITOR\n");
- + }
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +// else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol && ieee->ext_patch_ieee80211_start_protocol(ieee))
- + else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol)
- + {
- + ieee->ext_patch_ieee80211_start_mesh(ieee);
- + }
- +#endif
- +}
- +
- +
- +#define DRV_NAME "Ieee80211"
- +void ieee80211_softmac_init(struct ieee80211_device *ieee)
- +{
- + int i;
- + memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
- +
- + ieee->state = IEEE80211_NOLINK;
- + ieee->sync_scan_hurryup = 0;
- + for(i = 0; i < 5; i++) {
- + ieee->seq_ctrl[i] = 0;
- + }
- +
- + ieee->assoc_id = 0;
- + ieee->queue_stop = 0;
- + ieee->scanning = 0;
- + ieee->scan_watchdog = 0;//lzm add 081215 for roaming
- + ieee->softmac_features = 0; //so IEEE2100-like driver are happy
- + ieee->wap_set = 0;
- + ieee->ssid_set = 0;
- + ieee->proto_started = 0;
- + ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
- + ieee->rate = 3;
- + ieee->ps = IEEE80211_PS_DISABLED;
- + ieee->sta_sleep = 0;
- +//by amy
- + ieee->bInactivePs = false;
- + ieee->actscanning = false;
- + ieee->ListenInterval = 2;
- + ieee->NumRxData = 0;
- + ieee->NumRxDataInPeriod = 0; //YJ,add,080828
- + ieee->NumRxBcnInPeriod = 0; //YJ,add,080828
- + ieee->bHwRadioOff = false;//by lizhaoming
- +//by amy
- +#ifdef _RTL8187_EXT_PATCH_
- + ieee->iw_ext_mode = 999;
- +#endif
- +
- + init_mgmt_queue(ieee);
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- + init_timer(&ieee->scan_timer);
- + ieee->scan_timer.data = (unsigned long)ieee;
- + ieee->scan_timer.function = ieee80211_softmac_scan_cb;
- +#endif
- + ieee->tx_pending.txb = NULL;
- +
- + init_timer(&ieee->associate_timer);
- + ieee->associate_timer.data = (unsigned long)ieee;
- + ieee->associate_timer.function = ieee80211_associate_abort_cb;
- +
- + init_timer(&ieee->beacon_timer);
- + ieee->beacon_timer.data = (unsigned long) ieee;
- + ieee->beacon_timer.function = ieee80211_send_beacon_cb;
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- +#ifdef PF_SYNCTHREAD
- + ieee->wq = create_workqueue(DRV_NAME,0);
- +#else
- + ieee->wq = create_workqueue(DRV_NAME);
- +#endif
- +#endif
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
- + INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
- + INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
- + INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
- + INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
- + INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
- + INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
- +//added by lawrence,20071118
- +#ifdef _RTL8187_EXT_PATCH_
- + INIT_WORK(&ieee->ext_stop_scan_wq, ieee80211_ext_stop_scan_wq);
- + //INIT_WORK(&ieee->ext_send_beacon_wq, ieee80211_beacons_start,ieee);
- + INIT_WORK(&ieee->ext_send_beacon_wq, ext_ieee80211_send_beacon_wq);
- +#endif //_RTL8187_EXT_PATCH_
- +#else
- + INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
- + INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
- + INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
- + INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
- + INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
- + INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
- +#ifdef _RTL8187_EXT_PATCH_
- + INIT_WORK(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
- + //INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
- + INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
- +#endif
- +#endif
- +#else
- + tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
- + tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
- + tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
- + tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
- + tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
- + tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
- +#ifdef _RTL8187_EXT_PATCH_
- + tq_init(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
- + //tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
- + tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
- +#endif
- +#endif
- + sema_init(&ieee->wx_sem, 1);
- + sema_init(&ieee->scan_sem, 1);
- + sema_init(&ieee->ips_sem,1);
- + spin_lock_init(&ieee->mgmt_tx_lock);
- + spin_lock_init(&ieee->beacon_lock);
- + spin_lock_init(&ieee->beaconflag_lock);
- + tasklet_init(&ieee->ps_task,
- + (void(*)(unsigned long)) ieee80211_sta_ps,
- + (unsigned long)ieee);
- +#ifdef ENABLE_DOT11D
- + ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
- +#endif
- +
- +}
- +
- +void ieee80211_softmac_free(struct ieee80211_device *ieee)
- +{
- + down(&ieee->wx_sem);
- +
- + del_timer_sync(&ieee->associate_timer);
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + cancel_delayed_work(&ieee->associate_retry_wq);
- +
- +
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + //When kernel>2.6.20,crash....
- +// cancel_delayed_work(&ieee->ext_stop_scan_wq);
- +// cancel_delayed_work(&ieee->ext_send_beacon_wq);
- +#endif
- + destroy_workqueue(ieee->wq);
- +#endif
- +
- +#ifdef ENABLE_DOT11D
- + if(NULL != ieee->pDot11dInfo)
- + kfree(ieee->pDot11dInfo);
- +#endif
- +
- + up(&ieee->wx_sem);
- +}
- +
- +/********************************************************
- + * Start of WPA code. *
- + * this is stolen from the ipw2200 driver *
- + ********************************************************/
- +
- +
- +static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
- +{
- + /* This is called when wpa_supplicant loads and closes the driver
- + * interface. */
- + printk("%s WPA\n",value ? "enabling" : "disabling");
- + ieee->wpa_enabled = value;
- + return 0;
- +}
- +
- +
- +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
- +{
- + /* make sure WPA is enabled */
- + ieee80211_wpa_enable(ieee, 1);
- +
- + ieee80211_disassociate(ieee);
- +}
- +
- +
- +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
- +{
- +
- + int ret = 0;
- +
- + switch (command) {
- + case IEEE_MLME_STA_DEAUTH:
- + // silently ignore
- + break;
- +
- + case IEEE_MLME_STA_DISASSOC:
- + ieee80211_disassociate(ieee);
- + break;
- +
- + default:
- + printk("Unknown MLME request: %d\n", command);
- + ret = -EOPNOTSUPP;
- + }
- +
- + return ret;
- +}
- +
- +
- +static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
- + struct ieee_param *param, int plen)
- +{
- + u8 *buf;
- +
- + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
- + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
- + return -EINVAL;
- +
- + if (param->u.wpa_ie.len) {
- + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
- + if (buf == NULL)
- + return -ENOMEM;
- +
- + memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
- + kfree(ieee->wpa_ie);
- + ieee->wpa_ie = buf;
- + ieee->wpa_ie_len = param->u.wpa_ie.len;
- + } else {
- + kfree(ieee->wpa_ie);
- + ieee->wpa_ie = NULL;
- + ieee->wpa_ie_len = 0;
- + }
- +
- + ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
- + return 0;
- +}
- +
- +#define AUTH_ALG_OPEN_SYSTEM 0x1
- +#define AUTH_ALG_SHARED_KEY 0x2
- +
- +static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
- +{
- +
- + struct ieee80211_security sec = {
- + .flags = SEC_AUTH_MODE,
- + };
- + int ret = 0;
- +
- + if (value & AUTH_ALG_SHARED_KEY) {
- + sec.auth_mode = WLAN_AUTH_SHARED_KEY;
- + ieee->open_wep = 0;
- + } else {
- + sec.auth_mode = WLAN_AUTH_OPEN;
- + ieee->open_wep = 1;
- + }
- +
- + if (ieee->set_security)
- + ieee->set_security(ieee->dev, &sec);
- + else
- + ret = -EOPNOTSUPP;
- +
- + return ret;
- +}
- +
- +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
- +{
- + int ret=0;
- + unsigned long flags;
- +
- + switch (name) {
- + case IEEE_PARAM_WPA_ENABLED:
- + ret = ieee80211_wpa_enable(ieee, value);
- + break;
- +
- + case IEEE_PARAM_TKIP_COUNTERMEASURES:
- + ieee->tkip_countermeasures=value;
- + break;
- +
- + case IEEE_PARAM_DROP_UNENCRYPTED: {
- + /* HACK:
- + *
- + * wpa_supplicant calls set_wpa_enabled when the driver
- + * is loaded and unloaded, regardless of if WPA is being
- + * used. No other calls are made which can be used to
- + * determine if encryption will be used or not prior to
- + * association being expected. If encryption is not being
- + * used, drop_unencrypted is set to false, else true -- we
- + * can use this to determine if the CAP_PRIVACY_ON bit should
- + * be set.
- + */
- + struct ieee80211_security sec = {
- + .flags = SEC_ENABLED,
- + .enabled = value,
- + };
- + ieee->drop_unencrypted = value;
- + /* We only change SEC_LEVEL for open mode. Others
- + * are set by ipw_wpa_set_encryption.
- + */
- + if (!value) {
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_0;
- + }
- + else {
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_1;
- + }
- + if (ieee->set_security)
- + ieee->set_security(ieee->dev, &sec);
- + break;
- + }
- +
- + case IEEE_PARAM_PRIVACY_INVOKED:
- + ieee->privacy_invoked=value;
- + break;
- +
- + case IEEE_PARAM_AUTH_ALGS:
- + ret = ieee80211_wpa_set_auth_algs(ieee, value);
- + break;
- +
- + case IEEE_PARAM_IEEE_802_1X:
- + ieee->ieee802_1x=value;
- + break;
- + case IEEE_PARAM_WPAX_SELECT:
- + // added for WPA2 mixed mode
- + //printk(KERN_WARNING "------------------------>wpax value = %x\n", value);
- + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
- + ieee->wpax_type_set = 1;
- + ieee->wpax_type_notify = value;
- + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
- + break;
- +
- + default:
- + printk("Unknown WPA param: %d\n",name);
- + ret = -EOPNOTSUPP;
- + }
- +
- + return ret;
- +}
- +
- +/* implementation borrowed from hostap driver */
- +
- +static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
- + struct ieee_param *param, int param_len)
- +{
- + int ret = 0;
- +
- + struct ieee80211_crypto_ops *ops;
- + struct ieee80211_crypt_data **crypt;
- +
- + struct ieee80211_security sec = {
- + .flags = 0,
- + };
- +
- + param->u.crypt.err = 0;
- + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
- +
- + if (param_len !=
- + (int) ((char *) param->u.crypt.key - (char *) param) +
- + param->u.crypt.key_len) {
- + printk("Len mismatch %d, %d\n", param_len,
- + param->u.crypt.key_len);
- + return -EINVAL;
- + }
- + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
- + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
- + if (param->u.crypt.idx >= WEP_KEYS)
- + return -EINVAL;
- +#ifdef _RTL8187_EXT_PATCH_
- + crypt = &ieee->cryptlist[0]->crypt[param->u.crypt.idx];
- +#else
- + crypt = &ieee->crypt[param->u.crypt.idx];
- +#endif
- +
- + } else {
- + return -EINVAL;
- + }
- +
- + if (strcmp(param->u.crypt.alg, "none") == 0) {
- + if (crypt) {
- + sec.enabled = 0;
- + // FIXME FIXME
- + //sec.encrypt = 0;
- + sec.level = SEC_LEVEL_0;
- + sec.flags |= SEC_ENABLED | SEC_LEVEL;
- + ieee80211_crypt_delayed_deinit(ieee, crypt);
- + }
- + goto done;
- + }
- + sec.enabled = 1;
- +// FIXME FIXME
- +// sec.encrypt = 1;
- + sec.flags |= SEC_ENABLED;
- +
- + /* IPW HW cannot build TKIP MIC, host decryption still needed. */
- + if (!(ieee->host_encrypt || ieee->host_decrypt) &&
- + strcmp(param->u.crypt.alg, "TKIP"))
- + goto skip_host_crypt;
- +
- + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
- + request_module("ieee80211_crypt_wep");
- + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
- + request_module("ieee80211_crypt_tkip");
- + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
- + request_module("ieee80211_crypt_ccmp");
- + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- + }
- + if (ops == NULL) {
- + printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
- + param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
- + ret = -EINVAL;
- + goto done;
- + }
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + u8 i;
- + for (i=0; i<MAX_MP; i++){
- + crypt = &ieee->cryptlist[i]->crypt[param->u.crypt.idx];
- +// if (crypt != NULL) printk("crypt not null\n", crypt);
- +
- + *crypt = ieee->cryptlist[i]->crypt[param->u.crypt.idx];
- +#endif
- + if (*crypt == NULL || (*crypt)->ops != ops) {
- + struct ieee80211_crypt_data *new_crypt;
- +
- + ieee80211_crypt_delayed_deinit(ieee, crypt);
- +
- + new_crypt = (struct ieee80211_crypt_data *)
- + kmalloc(sizeof(*new_crypt), GFP_KERNEL);
- + if (new_crypt == NULL) {
- + ret = -ENOMEM;
- + goto done;
- + }
- + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
- + new_crypt->ops = ops;
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
- +#else
- + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
- +#endif
- + new_crypt->priv =
- + new_crypt->ops->init(param->u.crypt.idx);
- +
- + if (new_crypt->priv == NULL) {
- + kfree(new_crypt);
- + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
- + ret = -EINVAL;
- + goto done;
- + }
- +
- + *crypt = new_crypt;
- + }
- +
- + if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
- + (*crypt)->ops->set_key(param->u.crypt.key,
- + param->u.crypt.key_len, param->u.crypt.seq,
- + (*crypt)->priv) < 0) {
- + printk("key setting failed\n");
- + param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
- + ret = -EINVAL;
- + goto done;
- + }
- +#ifdef _RTL8187_EXT_PATCH_
- + }
- +#endif
- + skip_host_crypt:
- + if (param->u.crypt.set_tx) {
- + ieee->tx_keyidx = param->u.crypt.idx;
- + sec.active_key = param->u.crypt.idx;
- + sec.flags |= SEC_ACTIVE_KEY;
- + } else
- + sec.flags &= ~SEC_ACTIVE_KEY;
- +
- + if (param->u.crypt.alg != NULL) {
- + memcpy(sec.keys[param->u.crypt.idx],
- + param->u.crypt.key,
- + param->u.crypt.key_len);
- + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
- + sec.flags |= (1 << param->u.crypt.idx);
- +
- + if (strcmp(param->u.crypt.alg, "WEP") == 0) {
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_1;
- + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_2;
- + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_3;
- + }
- + }
- + done:
- + if (ieee->set_security)
- + ieee->set_security(ieee->dev, &sec);
- +#if 1
- +#ifdef _RTL8187_EXT_PATCH_
- + if (ret != 0)//error out
- + {
- + for (i=0; i<MAX_MP; i++)
- + {
- + if (ieee->cryptlist[i]->crypt[param->u.crypt.idx]==NULL){
- + break;
- + }
- + else{
- + //if (ieee->cryptlist[i]->crypt[param->u.crypt.idx] != NULL)
- + // {
- + kfree(ieee->cryptlist[i]->crypt[param->u.crypt.idx]);
- + ieee->cryptlist[i]->crypt[param->u.crypt.idx] = NULL;
- + // }
- + // kfree(ieee->cryptlist[i]);
- + // ieee->cryptlist[i] = NULL;
- + }
- + }
- + }
- +#endif
- +#endif
- + /* Do not reset port if card is in Managed mode since resetting will
- + * generate new IEEE 802.11 authentication which may end up in looping
- + * with IEEE 802.1X. If your hardware requires a reset after WEP
- + * configuration (for example... Prism2), implement the reset_port in
- + * the callbacks structures used to initialize the 802.11 stack. */
- + if (ieee->reset_on_keychange &&
- + ieee->iw_mode != IW_MODE_INFRA &&
- + ieee->reset_port &&
- + ieee->reset_port(ieee->dev)) {
- + printk("reset_port failed\n");
- + param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
- + return -EINVAL;
- + }
- +
- + return ret;
- +}
- +
- +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
- +{
- + struct ieee_param *param;
- + int ret=0;
- +
- + down(&ieee->wx_sem);
- + //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
- +
- + if (p->length < sizeof(struct ieee_param) || !p->pointer){
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
- + if (param == NULL){
- + ret = -ENOMEM;
- + goto out;
- + }
- + if (copy_from_user(param, p->pointer, p->length)) {
- + kfree(param);
- + ret = -EFAULT;
- + goto out;
- + }
- +
- + switch (param->cmd) {
- +
- + case IEEE_CMD_SET_WPA_PARAM:
- + ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
- + param->u.wpa_param.value);
- + break;
- +
- + case IEEE_CMD_SET_WPA_IE:
- + ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
- + break;
- +
- + case IEEE_CMD_SET_ENCRYPTION:
- + ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
- + break;
- +
- + case IEEE_CMD_MLME:
- + ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
- + param->u.mlme.reason_code);
- + break;
- +
- + default:
- + printk("Unknown WPA supplicant request: %d\n",param->cmd);
- + ret = -EOPNOTSUPP;
- + break;
- + }
- +
- + if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- + ret = -EFAULT;
- +
- + kfree(param);
- +out:
- + up(&ieee->wx_sem);
- +
- + return ret;
- +}
- +
- +void notify_wx_assoc_event(struct ieee80211_device *ieee)
- +{
- + union iwreq_data wrqu;
- + wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- + if (ieee->state == IEEE80211_LINKED)
- + memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
- + else
- + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
- + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
- +}
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_get_beacon);
- +EXPORT_SYMBOL(ieee80211_wake_queue);
- +EXPORT_SYMBOL(ieee80211_stop_queue);
- +EXPORT_SYMBOL(ieee80211_reset_queue);
- +EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
- +EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
- +EXPORT_SYMBOL(ieee80211_is_shortslot);
- +EXPORT_SYMBOL(ieee80211_is_54g);
- +EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
- +EXPORT_SYMBOL(ieee80211_ps_tx_ack);
- +EXPORT_SYMBOL(notify_wx_assoc_event);
- +EXPORT_SYMBOL(ieee80211_stop_send_beacons);
- +EXPORT_SYMBOL(ieee80211_start_send_beacons);
- +EXPORT_SYMBOL(ieee80211_start_scan_syncro);
- +EXPORT_SYMBOL(ieee80211_start_protocol);
- +EXPORT_SYMBOL(ieee80211_stop_protocol);
- +EXPORT_SYMBOL(ieee80211_start_scan);
- +EXPORT_SYMBOL(ieee80211_stop_scan);
- +#ifdef _RTL8187_EXT_PATCH_
- +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req);
- +EXPORT_SYMBOL(ieee80211_ext_issue_disassoc);
- +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp);
- +EXPORT_SYMBOL(softmac_mgmt_xmit);
- +EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net);
- +EXPORT_SYMBOL(ieee80211_stop_scan);
- +EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon);
- +EXPORT_SYMBOL(ieee80211_rx_auth_rq);
- +EXPORT_SYMBOL(ieee80211_associate_step1);
- +#endif // _RTL8187_EXT_PATCH_
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue);
- +EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue);
- +EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
- +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
- +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
- +EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot);
- +EXPORT_SYMBOL_NOVERS(ieee80211_is_54g);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl);
- +EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack);
- +EXPORT_SYMBOL_NOVERS(ieee80211_start_scan);
- +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
- +#ifdef _RTL8187_EXT_PATCH_
- +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_req);
- +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_disassoc);
- +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_rsp);
- +EXPORT_SYMBOL_NOVERS(softmac_mgmt_xmit);
- +EXPORT_SYMBOL_NOVERS(ieee80211_ext_probe_resp_by_net);
- +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
- +EXPORT_SYMBOL_NOVERS(ieee80211_ext_send_11s_beacon);
- +EXPORT_SYMBOL_NOVERS(ieee80211_rx_auth_rq);
- +EXPORT_SYMBOL(ieee80211_associate_step1);
- +#endif // _RTL8187_EXT_PATCH_
- +
- +#endif
- +//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
- 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
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,629 @@
- +/* IEEE 802.11 SoftMAC layer
- + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
- + *
- + * Mostly extracted from the rtl8180-sa2400 driver for the
- + * in-kernel generic ieee802.11 stack.
- + *
- + * Some pieces of code might be stolen from ipw2100 driver
- + * copyright of who own it's copyright ;-)
- + *
- + * PS wx handler mostly stolen from hostap, copyright who
- + * own it's copyright ;-)
- + *
- + * released under the GPL
- + */
- +
- +
- +#include "ieee80211.h"
- +#ifdef ENABLE_DOT11D
- +#include "dot11d.h"
- +#endif
- +
- +/* FIXME: add A freqs */
- +
- +const long ieee80211_wlan_frequencies[] = {
- + 2412, 2417, 2422, 2427,
- + 2432, 2437, 2442, 2447,
- + 2452, 2457, 2462, 2467,
- + 2472, 2484
- +};
- +
- +
- +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + int ret;
- + struct iw_freq *fwrq = & wrqu->freq;
- +
- + down(&ieee->wx_sem);
- +
- + if(ieee->iw_mode == IW_MODE_INFRA){
- + ret = -EOPNOTSUPP;
- + goto out;
- + }
- +
- + /* if setting by freq convert to channel */
- + if (fwrq->e == 1) {
- + if ((fwrq->m >= (int) 2.412e8 &&
- + fwrq->m <= (int) 2.487e8)) {
- + int f = fwrq->m / 100000;
- + int c = 0;
- +
- + while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
- + c++;
- +
- + /* hack to fall through */
- + fwrq->e = 0;
- + fwrq->m = c + 1;
- + }
- + }
- +
- + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
- + ret = -EOPNOTSUPP;
- + goto out;
- +
- + }else { /* Set the channel */
- +
- +#ifdef ENABLE_DOT11D
- + if(!IsLegalChannel(ieee, fwrq->m) )
- + {
- + printk("channel(%d). is invalide\n", fwrq->m);
- + ret = -EOPNOTSUPP;
- + goto out;
- + }
- + else
- + {
- + if(ieee->iw_mode == IW_MODE_ADHOC)
- + {
- + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
- + {
- + if(fwrq->m >= ieee->MinPassiveChnlNum)
- + {
- + ret = -EOPNOTSUPP;
- + goto out;
- + }
- + }
- + }
- + }
- +#endif
- + ieee->current_network.channel = fwrq->m;
- + ieee->set_chan(ieee->dev, ieee->current_network.channel);
- +
- + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- + if(ieee->state == IEEE80211_LINKED){
- +
- + ieee80211_stop_send_beacons(ieee);
- + ieee80211_start_send_beacons(ieee);
- + }
- + }
- +
- + ret = 0;
- +out:
- + up(&ieee->wx_sem);
- + return ret;
- +}
- +
- +
- +int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
- + struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + struct iw_freq *fwrq = & wrqu->freq;
- +
- + if (ieee->current_network.channel == 0)
- + return -1;
- +
- + fwrq->m = ieee->current_network.channel;
- + fwrq->e = 0;
- +
- + return 0;
- +}
- +
- +int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + unsigned long flags;
- +
- + wrqu->ap_addr.sa_family = ARPHRD_ETHER;
- +
- + if (ieee->iw_mode == IW_MODE_MONITOR)
- + return -1;
- +
- + /* We want avoid to give to the user inconsistent infos*/
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + if (ieee->state != IEEE80211_LINKED &&
- + ieee->state != IEEE80211_LINKED_SCANNING &&
- + ieee->wap_set == 0)
- +
- + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
- + else
- + memcpy(wrqu->ap_addr.sa_data,
- + ieee->current_network.bssid, ETH_ALEN);
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- + return 0;
- +}
- +
- +
- +int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *awrq,
- + char *extra)
- +{
- +
- + int ret = 0;
- + u8 zero[] = {0,0,0,0,0,0};
- + unsigned long flags;
- +
- + short ifup = ieee->proto_started;//dev->flags & IFF_UP;
- + struct sockaddr *temp = (struct sockaddr *)awrq;
- +
- + ieee->sync_scan_hurryup = 1;
- +
- + down(&ieee->wx_sem);
- + /* use ifconfig hw ether */
- + if (ieee->iw_mode == IW_MODE_MASTER){
- + ret = -1;
- + goto out;
- + }
- +
- + if (temp->sa_family != ARPHRD_ETHER){
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + if (ifup)
- + ieee80211_stop_protocol(ieee);
- +
- + /* just to avoid to give inconsistent infos in the
- + * get wx method. not really needed otherwise
- + */
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
- + ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- + if (ifup)
- + ieee80211_start_protocol(ieee);
- +
- +out:
- + up(&ieee->wx_sem);
- + return ret;
- +}
- +
- + int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
- +{
- + int len,ret = 0;
- + unsigned long flags;
- +
- + if (ieee->iw_mode == IW_MODE_MONITOR)
- + return -1;
- +
- + /* We want avoid to give to the user inconsistent infos*/
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + if (ieee->current_network.ssid[0] == '\0' ||
- + ieee->current_network.ssid_len == 0){
- + ret = -1;
- + goto out;
- + }
- +
- + if (ieee->state != IEEE80211_LINKED &&
- + ieee->state != IEEE80211_LINKED_SCANNING &&
- + ieee->ssid_set == 0){
- + ret = -1;
- + goto out;
- + }
- + len = ieee->current_network.ssid_len;
- + wrqu->essid.length = len;
- + strncpy(b,ieee->current_network.ssid,len);
- + wrqu->essid.flags = 1;
- +
- +out:
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- + return ret;
- +
- +}
- +
- +int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- +
- + u32 target_rate = wrqu->bitrate.value;
- +
- + ieee->rate = target_rate/100000;
- + //FIXME: we might want to limit rate also in management protocols.
- + return 0;
- +}
- +
- +
- +
- +int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- +
- + wrqu->bitrate.value = ieee->rate * 100000;
- +
- + return 0;
- +}
- +
- +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- +
- + ieee->sync_scan_hurryup = 1;
- +
- + down(&ieee->wx_sem);
- + //printk("=======>%s\n", __func__);
- +
- + if (wrqu->mode == ieee->iw_mode)
- + goto out;
- +
- + if (wrqu->mode == IW_MODE_MONITOR){
- +
- + ieee->dev->type = ARPHRD_IEEE80211;
- + }else{
- + ieee->dev->type = ARPHRD_ETHER;
- + }
- +
- + if (!ieee->proto_started){
- + ieee->iw_mode = wrqu->mode;
- + }else{
- + ieee80211_stop_protocol(ieee);
- + ieee->iw_mode = wrqu->mode;
- + ieee80211_start_protocol(ieee);
- + }
- +
- +out:
- + up(&ieee->wx_sem);
- + return 0;
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +void ieee80211_wx_sync_scan_wq(struct work_struct *work)
- +{
- + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
- +#else
- +void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
- +{
- +#endif
- + short chan;
- +
- + chan = ieee->current_network.channel;
- +
- + netif_carrier_off(ieee->dev);
- +
- + if (ieee->data_hard_stop)
- + ieee->data_hard_stop(ieee->dev);
- +
- + ieee80211_stop_send_beacons(ieee);
- +
- + ieee->state = IEEE80211_LINKED_SCANNING;
- + ieee->link_change(ieee->dev);
- +
- + ieee80211_start_scan_syncro(ieee);
- +
- + ieee->set_chan(ieee->dev, chan);
- +
- + ieee->state = IEEE80211_LINKED;
- + ieee->link_change(ieee->dev);
- +
- + if (ieee->data_hard_resume)
- + ieee->data_hard_resume(ieee->dev);
- +
- + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- + ieee80211_start_send_beacons(ieee);
- +
- + netif_carrier_on(ieee->dev);
- +
- + up(&ieee->wx_sem);
- +
- +}
- +
- +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + int ret = 0;
- +
- + down(&ieee->wx_sem);
- +
- + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
- + ret = -1;
- + goto out;
- + }
- +
- + if ( ieee->state == IEEE80211_LINKED){
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
- +#else
- + schedule_task(&ieee->wx_sync_scan_wq);
- +#endif
- + /* intentionally forget to up sem */
- + return 0;
- + }
- +
- +out:
- + up(&ieee->wx_sem);
- + return ret;
- +}
- +
- +int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- + struct iw_request_info *a,
- + union iwreq_data *wrqu, char *extra)
- +{
- +
- + int ret=0,len;
- + short proto_started;
- + unsigned long flags;
- +
- + ieee->sync_scan_hurryup = 1;
- +
- + down(&ieee->wx_sem);
- +
- + //printk("=======>%s\n", __func__);
- + proto_started = ieee->proto_started;
- +
- + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
- + ret= -E2BIG;
- + goto out;
- + }
- +
- + if (ieee->iw_mode == IW_MODE_MONITOR){
- + ret= -1;
- + goto out;
- + }
- +
- + if(proto_started){
- + ieee80211_stop_protocol(ieee);
- + }
- +
- + /* this is just to be sure that the GET wx callback
- + * has consisten infos. not needed otherwise
- + */
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + if (wrqu->essid.flags && wrqu->essid.length) {
- + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + strncpy(ieee->current_network.ssid, extra, len);
- + ieee->current_network.ssid_len = len;
- +#else
- + strncpy(ieee->current_network.ssid, extra, len+1);
- + ieee->current_network.ssid_len = len+1;
- +#endif
- + ieee->ssid_set = 1;
- + //YJ,add,080819,for hidden ap
- + if(len == 0){
- + memset(ieee->current_network.bssid, 0, ETH_ALEN);
- + ieee->current_network.capability = 0;
- + }
- + //YJ,add,080819,for hidden ap,end
- + }
- + else{
- + ieee->ssid_set = 0;
- + ieee->current_network.ssid[0] = '\0';
- + ieee->current_network.ssid_len = 0;
- + }
- +
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +
- + if (proto_started){
- + ieee80211_start_protocol(ieee);
- + }
- +out:
- + up(&ieee->wx_sem);
- + return ret;
- +}
- +
- + int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- +
- + wrqu->mode = ieee->iw_mode;
- + return 0;
- +}
- +
- + int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- +
- + int *parms = (int *)extra;
- + int enable = (parms[0] > 0);
- + short prev = ieee->raw_tx;
- +
- + down(&ieee->wx_sem);
- +
- + if(enable)
- + ieee->raw_tx = 1;
- + else
- + ieee->raw_tx = 0;
- +
- + printk(KERN_INFO"raw TX is %s\n",
- + ieee->raw_tx ? "enabled" : "disabled");
- +
- + if(ieee->iw_mode == IW_MODE_MONITOR)
- + {
- + if(prev == 0 && ieee->raw_tx){
- + if (ieee->data_hard_resume)
- + ieee->data_hard_resume(ieee->dev);
- +
- + netif_carrier_on(ieee->dev);
- + }
- +
- + if(prev && ieee->raw_tx == 1)
- + netif_carrier_off(ieee->dev);
- + }
- +
- + up(&ieee->wx_sem);
- +
- + return 0;
- +}
- +
- +int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + strcpy(wrqu->name, "802.11");
- + if(ieee->modulation & IEEE80211_CCK_MODULATION){
- + strcat(wrqu->name, "b");
- + if(ieee->modulation & IEEE80211_OFDM_MODULATION)
- + strcat(wrqu->name, "/g");
- + }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
- + strcat(wrqu->name, "g");
- +
- + if((ieee->state == IEEE80211_LINKED) ||
- + (ieee->state == IEEE80211_LINKED_SCANNING))
- + strcat(wrqu->name," linked");
- + else if(ieee->state != IEEE80211_NOLINK)
- + strcat(wrqu->name," link..");
- +
- +
- + return 0;
- +}
- +
- +
- +/* this is mostly stolen from hostap */
- +int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + int ret = 0;
- +
- + if(
- + (!ieee->sta_wake_up) ||
- + (!ieee->ps_request_tx_ack) ||
- + (!ieee->enter_sleep_state) ||
- + (!ieee->ps_is_queue_empty)){
- +
- + printk("ERROR. PS mode is tryied to be use but\
- +driver missed a callback\n\n");
- +
- + return -1;
- + }
- +
- + down(&ieee->wx_sem);
- +
- + if (wrqu->power.disabled){
- + ieee->ps = IEEE80211_PS_DISABLED;
- +
- + goto exit;
- + }
- + switch (wrqu->power.flags & IW_POWER_MODE) {
- + case IW_POWER_UNICAST_R:
- + ieee->ps = IEEE80211_PS_UNICAST;
- +
- + break;
- + case IW_POWER_ALL_R:
- + ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
- + break;
- +
- + case IW_POWER_ON:
- + ieee->ps = IEEE80211_PS_DISABLED;
- + break;
- +
- + default:
- + ret = -EINVAL;
- + goto exit;
- + }
- +
- + if (wrqu->power.flags & IW_POWER_TIMEOUT) {
- +
- + ieee->ps_timeout = wrqu->power.value / 1000;
- + printk("Timeout %d\n",ieee->ps_timeout);
- + }
- +
- + if (wrqu->power.flags & IW_POWER_PERIOD) {
- +
- + ret = -EOPNOTSUPP;
- + goto exit;
- + //wrq->value / 1024;
- +
- + }
- +exit:
- + up(&ieee->wx_sem);
- + return ret;
- +
- +}
- +
- +/* this is stolen from hostap */
- +int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + int ret =0;
- +
- + down(&ieee->wx_sem);
- +
- + if(ieee->ps == IEEE80211_PS_DISABLED){
- + wrqu->power.disabled = 1;
- + goto exit;
- + }
- +
- + wrqu->power.disabled = 0;
- +
- +// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- + wrqu->power.flags = IW_POWER_TIMEOUT;
- + wrqu->power.value = ieee->ps_timeout * 1000;
- +// } else {
- +// ret = -EOPNOTSUPP;
- +// goto exit;
- + //wrqu->power.flags = IW_POWER_PERIOD;
- + //wrqu->power.value = ieee->current_network.dtim_period *
- + // ieee->current_network.beacon_interval * 1024;
- +// }
- +
- +
- + if (ieee->ps & IEEE80211_PS_MBCAST)
- + wrqu->power.flags |= IW_POWER_ALL_R;
- + else
- + wrqu->power.flags |= IW_POWER_UNICAST_R;
- +
- +exit:
- + up(&ieee->wx_sem);
- + return ret;
- +
- +}
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_wx_get_essid);
- +EXPORT_SYMBOL(ieee80211_wx_set_essid);
- +EXPORT_SYMBOL(ieee80211_wx_set_rate);
- +EXPORT_SYMBOL(ieee80211_wx_get_rate);
- +EXPORT_SYMBOL(ieee80211_wx_set_wap);
- +EXPORT_SYMBOL(ieee80211_wx_get_wap);
- +EXPORT_SYMBOL(ieee80211_wx_set_mode);
- +EXPORT_SYMBOL(ieee80211_wx_get_mode);
- +EXPORT_SYMBOL(ieee80211_wx_set_scan);
- +EXPORT_SYMBOL(ieee80211_wx_get_freq);
- +EXPORT_SYMBOL(ieee80211_wx_set_freq);
- +EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
- +EXPORT_SYMBOL(ieee80211_wx_get_name);
- +EXPORT_SYMBOL(ieee80211_wx_set_power);
- +EXPORT_SYMBOL(ieee80211_wx_get_power);
- +EXPORT_SYMBOL(ieee80211_wlan_frequencies);
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies);
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,876 @@
- +/******************************************************************************
- +
- + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
- +
- + This program is free software; you can redistribute it and/or modify it
- + under the terms of version 2 of the GNU General Public License as
- + published by the Free Software Foundation.
- +
- + This program is distributed in the hope that it will be useful, but WITHOUT
- + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + more details.
- +
- + You should have received a copy of the GNU General Public License along with
- + this program; if not, write to the Free Software Foundation, Inc., 59
- + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- +
- + The full GNU General Public License is included in this distribution in the
- + file called LICENSE.
- +
- + Contact Information:
- + James P. Ketrenos <ipw2100-admin@linux.intel.com>
- + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- +
- +******************************************************************************
- +
- + Few modifications for Realtek's Wi-Fi drivers by
- + Andrea Merello <andreamrl@tiscali.it>
- +
- + A special thanks goes to Realtek for their support !
- +
- +******************************************************************************/
- +
- +#include <linux/compiler.h>
- +//#include <linux/config.h>
- +#include <linux/errno.h>
- +#include <linux/if_arp.h>
- +#include <linux/in6.h>
- +#include <linux/in.h>
- +#include <linux/ip.h>
- +#include <linux/kernel.h>
- +#include <linux/module.h>
- +#include <linux/netdevice.h>
- +#include <linux/pci.h>
- +#include <linux/proc_fs.h>
- +#include <linux/skbuff.h>
- +#include <linux/slab.h>
- +#include <linux/tcp.h>
- +#include <linux/types.h>
- +#include <linux/version.h>
- +#include <linux/wireless.h>
- +#include <linux/etherdevice.h>
- +#include <asm/uaccess.h>
- +#include <linux/if_vlan.h>
- +
- +#include "ieee80211.h"
- +
- +
- +/*
- +
- +
- +802.11 Data Frame
- +
- +
- +802.11 frame_contorl for data frames - 2 bytes
- + ,-----------------------------------------------------------------------------------------.
- +bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
- + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
- +val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
- + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
- +desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
- + | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
- + '-----------------------------------------------------------------------------------------'
- + /\
- + |
- +802.11 Data Frame |
- + ,--------- 'ctrl' expands to >-----------'
- + |
- + ,--'---,-------------------------------------------------------------.
- +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- + |------|------|---------|---------|---------|------|---------|------|
- +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
- + | | tion | (BSSID) | | | ence | data | |
- + `--------------------------------------------------| |------'
- +Total: 28 non-data bytes `----.----'
- + |
- + .- 'Frame data' expands to <---------------------------'
- + |
- + V
- + ,---------------------------------------------------.
- +Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
- + |------|------|---------|----------|------|---------|
- +Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
- + | DSAP | SSAP | | | | Packet |
- + | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
- + `-----------------------------------------| |
- +Total: 8 non-data bytes `----.----'
- + |
- + .- 'IP Packet' expands, if WEP enabled, to <--'
- + |
- + V
- + ,-----------------------.
- +Bytes | 4 | 0-2296 | 4 |
- + |-----|-----------|-----|
- +Desc. | IV | Encrypted | ICV |
- + | | IP Packet | |
- + `-----------------------'
- +Total: 8 non-data bytes
- +
- +
- +802.3 Ethernet Data Frame
- +
- + ,-----------------------------------------.
- +Bytes | 6 | 6 | 2 | Variable | 4 |
- + |-------|-------|------|-----------|------|
- +Desc. | Dest. | Source| Type | IP Packet | fcs |
- + | MAC | MAC | | | |
- + `-----------------------------------------'
- +Total: 18 non-data bytes
- +
- +In the event that fragmentation is required, the incoming payload is split into
- +N parts of size ieee->fts. The first fragment contains the SNAP header and the
- +remaining packets are just data.
- +
- +If encryption is enabled, each fragment payload size is reduced by enough space
- +to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
- +So if you have 1500 bytes of payload with ieee->fts set to 500 without
- +encryption it will take 3 frames. With WEP it will take 4 frames as the
- +payload of each frame is reduced to 492 bytes.
- +
- +* SKB visualization
- +*
- +* ,- skb->data
- +* |
- +* | ETHERNET HEADER ,-<-- PAYLOAD
- +* | | 14 bytes from skb->data
- +* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
- +* | | | |
- +* |,-Dest.--. ,--Src.---. | | |
- +* | 6 bytes| | 6 bytes | | | |
- +* v | | | | | |
- +* 0 | v 1 | v | v 2
- +* 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
- +* ^ | ^ | ^ |
- +* | | | | | |
- +* | | | | `T' <---- 2 bytes for Type
- +* | | | |
- +* | | '---SNAP--' <-------- 6 bytes for SNAP
- +* | |
- +* `-IV--' <-------------------- 4 bytes for IV (WEP)
- +*
- +* SNAP HEADER
- +*
- +*/
- +
- +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
- +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
- +
- +static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
- +{
- + struct ieee80211_snap_hdr *snap;
- + u8 *oui;
- +
- + snap = (struct ieee80211_snap_hdr *)data;
- + snap->dsap = 0xaa;
- + snap->ssap = 0xaa;
- + snap->ctrl = 0x03;
- +
- + if (h_proto == 0x8137 || h_proto == 0x80f3)
- + oui = P802_1H_OUI;
- + else
- + oui = RFC1042_OUI;
- + snap->oui[0] = oui[0];
- + snap->oui[1] = oui[1];
- + snap->oui[2] = oui[2];
- +
- + *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
- +
- + return SNAP_SIZE + sizeof(u16);
- +}
- +
- +int ieee80211_encrypt_fragment(
- + struct ieee80211_device *ieee,
- + struct sk_buff *frag,
- + int hdr_len)
- +{
- + struct ieee80211_crypt_data* crypt = NULL;//ieee->crypt[ieee->tx_keyidx];
- + int res;//, i;
- +// printk("====>wwwwww%s():ieee:%x, hdr_len:%d\n", __FUNCTION__, ieee, hdr_len);
- +/* printk("\n%s(), hdr_len:%d\n", __FUNCTION__, hdr_len);
- + for (i = 0; i < 48; i++) {
- + if (i % 16 == 0) printk("\n\t");
- + printk("%2x ", *(frag->data+i));
- + }
- +*/
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +#if 0
- + i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*) frag->data)->addr1);
- + if (i== -1){
- + printk("error find MP entry in %s()\n", __FUNCTION__);
- + return i;
- + }
- + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)frag->data)->addr1), i);
- +#endif
- +// crypt = ieee->cryptlist[MAX_MP-1]->crypt[ieee->tx_keyidx];
- + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
- +#else
- + crypt = ieee->crypt[ieee->tx_keyidx];
- +#endif
- + /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
- + if (!crypt || !crypt->ops)
- + return -1;
- +
- +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- + struct ieee80211_hdr *header;
- +
- + if (ieee->tkip_countermeasures &&
- + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- + header = (struct ieee80211_hdr *) frag->data;
- + if (net_ratelimit()) {
- + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
- + "TX packet to " MAC_FMT "\n",
- + ieee->dev->name, MAC_ARG(header->addr1));
- + }
- + return -1;
- + }
- +#endif
- + /* To encrypt, frame format is:
- + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
- +
- + // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
- + /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
- + * call both MSDU and MPDU encryption functions from here. */
- + atomic_inc(&crypt->refcnt);
- + res = 0;
- + if (crypt->ops->encrypt_msdu)
- + res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
- + if (res == 0 && crypt->ops->encrypt_mpdu)
- + res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
- + atomic_dec(&crypt->refcnt);
- + if (res < 0) {
- + printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
- + ieee->dev->name, frag->len);
- + ieee->ieee_stats.tx_discards++;
- + return -1;
- + }
- +
- + return 0;
- +}
- +
- +
- +void ieee80211_txb_free(struct ieee80211_txb *txb) {
- + int i;
- + if (unlikely(!txb))
- + return;
- + for (i = 0; i < txb->nr_frags; i++)
- + if (txb->fragments[i])
- + dev_kfree_skb_any(txb->fragments[i]);
- + kfree(txb);
- +}
- +
- +struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
- + int gfp_mask)
- +{
- + struct ieee80211_txb *txb;
- + int i;
- + txb = kmalloc(
- + sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
- + gfp_mask);
- + if (!txb)
- + return NULL;
- +
- + memset(txb, 0, sizeof(struct ieee80211_txb));
- + txb->nr_frags = nr_frags;
- + txb->frag_size = txb_size;
- +
- + for (i = 0; i < nr_frags; i++) {
- + txb->fragments[i] = dev_alloc_skb(txb_size);
- + if (unlikely(!txb->fragments[i])) {
- + i--;
- + break;
- + }
- + }
- + if (unlikely(i != nr_frags)) {
- + while (i >= 0)
- + dev_kfree_skb_any(txb->fragments[i--]);
- + kfree(txb);
- + return NULL;
- + }
- + return txb;
- +}
- +
- +// Classify the to-be send data packet
- +// Need to acquire the sent queue index.
- +static int
- +ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
- +{
- + struct ether_header *eh = (struct ether_header*)skb->data;
- + unsigned int wme_UP = 0;
- +
- + if(!network->QoS_Enable) {
- + skb->priority = 0;
- + return(wme_UP);
- + }
- +
- + if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
- + const struct iphdr *ih = (struct iphdr*)(skb->data + \
- + sizeof(struct ether_header));
- + wme_UP = (ih->tos >> 5)&0x07;
- + } else if (vlan_tx_tag_present(skb)) {//vtag packet
- +#ifndef VLAN_PRI_SHIFT
- +#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
- +#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
- +#endif
- + u32 tag = vlan_tx_tag_get(skb);
- + wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
- + } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
- + //printk(KERN_WARNING "type = normal packet\n");
- + wme_UP = 7;
- + }
- + skb->priority = wme_UP;
- +/*
- + if (network->QoS_Enable) {
- + skb->priority = wme_UP;
- + }else {
- + skb->priority = 0;
- + }
- +*/
- + return(wme_UP);
- +}
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
- +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)
- +{
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- + struct ieee80211_device *ieee = netdev_priv(dev);
- +#else
- + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
- +#endif
- + struct ieee80211_txb *txb = NULL;
- + struct ieee80211_hdr_3addr *frag_hdr;
- + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
- + int ether_type;
- + int bytes, QOS_ctl;
- + struct sk_buff *skb_frag;
- +
- + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
- +
- + /* Advance the SKB to the start of the payload */
- + skb_pull(skb, sizeof(struct ethhdr));
- +
- + /* Determine total amount of storage required for TXB packets */
- + bytes = skb->len + SNAP_SIZE + sizeof(u16);
- +
- + /* Determine fragmentation size based on destination (multicast
- + * and broadcast are not fragmented) */
- + // if (is_multicast_ether_addr(dest) ||
- + // is_broadcast_ether_addr(dest)) {
- + if (is_multicast_ether_addr(header->addr1) ||
- + is_broadcast_ether_addr(header->addr1)) {
- + frag_size = MAX_FRAG_THRESHOLD;
- + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
- + }
- + else {
- + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
- + frag_size = ieee->fts;//default:392
- + QOS_ctl = 0;
- + }
- +
- + if(isQoS) {
- + QOS_ctl |= skb->priority; //set in the ieee80211_classify
- + *pQOS_ctl = cpu_to_le16(QOS_ctl);
- + }
- + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
- + /* Determine amount of payload per fragment. Regardless of if
- + * this stack is providing the full 802.11 header, one will
- + * eventually be affixed to this fragment -- so we must account for
- + * it when determining the amount of payload space. */
- + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
- + bytes_per_frag = frag_size - hdr_len;
- + if (ieee->config &
- + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- + bytes_per_frag -= IEEE80211_FCS_LEN;
- +
- + /* Each fragment may need to have room for encryptiong pre/postfix */
- + if (isEncrypt)
- + bytes_per_frag -= crypt->ops->extra_prefix_len +
- + crypt->ops->extra_postfix_len;
- +
- + /* Number of fragments is the total bytes_per_frag /
- + * payload_per_fragment */
- + nr_frags = bytes / bytes_per_frag;
- + bytes_last_frag = bytes % bytes_per_frag;
- + if (bytes_last_frag)
- + nr_frags++;
- + else
- + bytes_last_frag = bytes_per_frag;
- +
- + /* When we allocate the TXB we allocate enough space for the reserve
- + * and full fragment bytes (bytes_per_frag doesn't include prefix,
- + * postfix, header, FCS, etc.) */
- + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
- + if (unlikely(!txb)) {
- + printk(KERN_WARNING "%s: Could not allocate TXB\n",
- + ieee->dev->name);
- + return NULL;
- + }
- + txb->encrypted = isEncrypt;
- + txb->payload_size = bytes;
- +
- + for (i = 0; i < nr_frags; i++) {
- + skb_frag = txb->fragments[i];
- + skb_frag->priority = UP2AC(skb->priority);
- + if (isEncrypt)
- + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
- +
- + frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
- + memcpy(frag_hdr, (void *)header, hdr_len);
- +
- + /* If this is not the last fragment, then add the MOREFRAGS
- + * bit to the frame control */
- + if (i != nr_frags - 1) {
- + frag_hdr->frame_ctl = cpu_to_le16(
- + header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
- + bytes = bytes_per_frag;
- +
- + } else {
- + /* The last fragment takes the remaining length */
- + bytes = bytes_last_frag;
- + }
- +
- + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
- + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
- + //
- +
- + /* Put a SNAP header on the first fragment */
- + if (i == 0) {
- + ieee80211_put_snap(
- + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
- + bytes -= SNAP_SIZE + sizeof(u16);
- + }
- +
- + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
- +
- + /* Advance the SKB... */
- + skb_pull(skb, bytes);
- +
- + /* Encryption routine will move the header forward in order
- + * to insert the IV between the header and the payload */
- + if (isEncrypt)
- + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
- + if (ieee->config &
- + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- + skb_put(skb_frag, 4);
- + }
- + // Advance sequence number in data frame.
- + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- + // stanley, just for debug
- +/*
- +{
- + int j=0;
- + for(j=0;j<nr_frags;j++)
- + {
- + int i;
- + struct sk_buff *skb = txb->fragments[j];
- + printk("send(%d): ", j);
- + for (i=0;i<skb->len;i++)
- + printk("%02X ", skb->data[i]&0xff);
- + printk("\n");
- + }
- +}
- +*/
- +
- + return txb;
- +}
- +
- +
- +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
- +// Assume no encryption, no FCS computing
- +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)
- +{
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- + struct ieee80211_device *ieee = netdev_priv(dev);
- +#else
- + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
- +#endif
- + struct ieee80211_txb *txb = NULL;
- + struct ieee80211_hdr_3addr *frag_hdr;
- + int ether_type;
- + int bytes, QOS_ctl;
- +
- + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
- +
- + /* Advance the SKB to the start of the payload */
- + skb_pull(skb, sizeof(struct ethhdr));
- +
- + /* Determine total amount of storage required for TXB packets */
- + bytes = skb->len + SNAP_SIZE + sizeof(u16);
- +
- + if (is_multicast_ether_addr(header->addr1) ||
- + is_broadcast_ether_addr(header->addr1)) {
- + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
- + }
- + else {
- + QOS_ctl = 0;
- + }
- +
- + if(isQoS) {
- + QOS_ctl |= skb->priority; //set in the ieee80211_classify
- + *pQOS_ctl = cpu_to_le16(QOS_ctl);
- + }
- +
- + txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
- + if (unlikely(!txb)) {
- + printk(KERN_WARNING "%s: Could not allocate TXB\n",
- + ieee->dev->name);
- + return NULL;
- + }
- +
- + txb->nr_frags = 1;
- + txb->frag_size = bytes;
- + txb->encrypted = isEncrypt;
- + txb->payload_size = bytes;
- +
- + txb->fragments[0] = skb;
- + ieee80211_put_snap(
- + skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
- + frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
- + memcpy(frag_hdr, (void *)header, hdr_len);
- + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
- + skb->priority = UP2AC(skb->priority);
- + if(isEncrypt)
- + ieee80211_encrypt_fragment(ieee,skb,hdr_len);
- +
- + // Advance sequence number in data frame.
- + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- +
- + return txb;
- +}
- +
- +#endif // _RTL8187_EXT_PATCH_
- +
- +/* SKBs are added to the ieee->tx_queue. */
- +int ieee80211_xmit(struct sk_buff *skb,
- + struct net_device *dev)
- +{
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
- + struct ieee80211_device *ieee = netdev_priv(dev);
- +#else
- + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
- +#endif
- + struct ieee80211_txb *txb = NULL;
- + struct ieee80211_hdr_3addr_QOS *frag_hdr;
- + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
- + unsigned long flags;
- + struct net_device_stats *stats = &ieee->stats;
- + int ether_type, encrypt;
- + int bytes, fc, QOS_ctl, hdr_len;
- + struct sk_buff *skb_frag;
- + //struct ieee80211_hdr header = { /* Ensure zero initialized */
- + // .duration_id = 0,
- + // .seq_ctl = 0
- + //};
- + struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
- + .duration_id = 0,
- + .seq_ctl = 0,
- + .QOS_ctl = 0
- + };
- + u8 dest[ETH_ALEN], src[ETH_ALEN];
- +
- + struct ieee80211_crypt_data* crypt;
- +
- + //printk(KERN_WARNING "upper layer packet!\n");
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + /* If there is no driver handler to take the TXB, dont' bother
- + * creating it... */
- + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
- + ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
- + printk(KERN_WARNING "%s: No xmit handler.\n",
- + ieee->dev->name);
- + goto success;
- + }
- +
- + ieee80211_classify(skb,&ieee->current_network);
- + if(likely(ieee->raw_tx == 0)){
- +
- + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
- + printk(KERN_WARNING "%s: skb too small (%d).\n",
- + ieee->dev->name, skb->len);
- + goto success;
- + }
- +
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + // note, skb->priority which was set by ieee80211_classify, and used by physical tx
- + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
- + {
- + txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
- + goto success;
- + }
- +#endif
- +
- + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
- +#ifdef _RTL8187_EXT_PATCH_
- + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
- +#else
- + crypt = ieee->crypt[ieee->tx_keyidx];
- +#endif
- + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
- + ieee->host_encrypt && crypt && crypt->ops;
- +
- + if (!encrypt && ieee->ieee802_1x &&
- + ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
- + stats->tx_dropped++;
- + goto success;
- + }
- +
- + #ifdef CONFIG_IEEE80211_DEBUG
- + if (crypt && !encrypt && ether_type == ETH_P_PAE) {
- + struct eapol *eap = (struct eapol *)(skb->data +
- + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
- + IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
- + eap_get_type(eap->type));
- + }
- + #endif
- +
- + /* Save source and destination addresses */
- + memcpy(&dest, skb->data, ETH_ALEN);
- + memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
- +
- + /* Advance the SKB to the start of the payload */
- + skb_pull(skb, sizeof(struct ethhdr));
- +
- + /* Determine total amount of storage required for TXB packets */
- + bytes = skb->len + SNAP_SIZE + sizeof(u16);
- +
- + if(ieee->current_network.QoS_Enable) {
- + if (encrypt)
- + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
- + IEEE80211_FCTL_WEP;
- + else
- + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
- +
- + } else {
- + if (encrypt)
- + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
- + IEEE80211_FCTL_WEP;
- + else
- + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
- + }
- +
- + if (ieee->iw_mode == IW_MODE_INFRA) {
- + fc |= IEEE80211_FCTL_TODS;
- + /* To DS: Addr1 = BSSID, Addr2 = SA,
- + Addr3 = DA */
- + memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
- + memcpy(&header.addr2, &src, ETH_ALEN);
- + memcpy(&header.addr3, &dest, ETH_ALEN);
- + } else if (ieee->iw_mode == IW_MODE_ADHOC) {
- + /* not From/To DS: Addr1 = DA, Addr2 = SA,
- + Addr3 = BSSID */
- + memcpy(&header.addr1, dest, ETH_ALEN);
- + memcpy(&header.addr2, src, ETH_ALEN);
- + memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
- + }
- + // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
- + header.frame_ctl = cpu_to_le16(fc);
- + //hdr_len = IEEE80211_3ADDR_LEN;
- +
- + /* Determine fragmentation size based on destination (multicast
- + * and broadcast are not fragmented) */
- +// if (is_multicast_ether_addr(dest) ||
- +// is_broadcast_ether_addr(dest)) {
- + if (is_multicast_ether_addr(header.addr1) ||
- + is_broadcast_ether_addr(header.addr1)) {
- + frag_size = MAX_FRAG_THRESHOLD;
- + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
- + }
- + else {
- + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
- + frag_size = ieee->fts;//default:392
- + QOS_ctl = 0;
- + }
- +
- + if (ieee->current_network.QoS_Enable) {
- + hdr_len = IEEE80211_3ADDR_LEN + 2;
- + QOS_ctl |= skb->priority; //set in the ieee80211_classify
- + header.QOS_ctl = cpu_to_le16(QOS_ctl);
- + } else {
- + hdr_len = IEEE80211_3ADDR_LEN;
- + }
- + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
- + /* Determine amount of payload per fragment. Regardless of if
- + * this stack is providing the full 802.11 header, one will
- + * eventually be affixed to this fragment -- so we must account for
- + * it when determining the amount of payload space. */
- + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
- + bytes_per_frag = frag_size - hdr_len;
- + if (ieee->config &
- + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- + bytes_per_frag -= IEEE80211_FCS_LEN;
- +
- + /* Each fragment may need to have room for encryptiong pre/postfix */
- + if (encrypt)
- + bytes_per_frag -= crypt->ops->extra_prefix_len +
- + crypt->ops->extra_postfix_len;
- +
- + /* Number of fragments is the total bytes_per_frag /
- + * payload_per_fragment */
- + nr_frags = bytes / bytes_per_frag;
- + bytes_last_frag = bytes % bytes_per_frag;
- + if (bytes_last_frag)
- + nr_frags++;
- + else
- + bytes_last_frag = bytes_per_frag;
- +
- + /* When we allocate the TXB we allocate enough space for the reserve
- + * and full fragment bytes (bytes_per_frag doesn't include prefix,
- + * postfix, header, FCS, etc.) */
- + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
- + if (unlikely(!txb)) {
- + printk(KERN_WARNING "%s: Could not allocate TXB\n",
- + ieee->dev->name);
- + goto failed;
- + }
- + txb->encrypted = encrypt;
- + txb->payload_size = bytes;
- +
- + for (i = 0; i < nr_frags; i++) {
- + skb_frag = txb->fragments[i];
- + skb_frag->priority = UP2AC(skb->priority);
- + if (encrypt)
- + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
- +
- + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
- + memcpy(frag_hdr, &header, hdr_len);
- +
- + /* If this is not the last fragment, then add the MOREFRAGS
- + * bit to the frame control */
- + if (i != nr_frags - 1) {
- + frag_hdr->frame_ctl = cpu_to_le16(
- + fc | IEEE80211_FCTL_MOREFRAGS);
- + bytes = bytes_per_frag;
- +
- + } else {
- + /* The last fragment takes the remaining length */
- + bytes = bytes_last_frag;
- + }
- + if(ieee->current_network.QoS_Enable) {
- + // add 1 only indicate to corresponding seq number control 2006/7/12
- + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
- + //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
- + //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
- + } else {
- + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
- + }
- + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
- + //
- +
- + /* Put a SNAP header on the first fragment */
- + if (i == 0) {
- + ieee80211_put_snap(
- + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
- + ether_type);
- + bytes -= SNAP_SIZE + sizeof(u16);
- + }
- +
- + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
- +
- + /* Advance the SKB... */
- + skb_pull(skb, bytes);
- +
- + /* Encryption routine will move the header forward in order
- + * to insert the IV between the header and the payload */
- + if (encrypt)
- + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
- + if (ieee->config &
- + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- + skb_put(skb_frag, 4);
- + }
- + // Advance sequence number in data frame.
- + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
- + if (ieee->current_network.QoS_Enable) {
- + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
- + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
- + else
- + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
- + } else {
- + if (ieee->seq_ctrl[0] == 0xFFF)
- + ieee->seq_ctrl[0] = 0;
- + else
- + ieee->seq_ctrl[0]++;
- + }
- + //---
- + }else{
- + if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
- + printk(KERN_WARNING "%s: skb too small (%d).\n",
- + ieee->dev->name, skb->len);
- + goto success;
- + }
- +
- + txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
- + if(!txb){
- + printk(KERN_WARNING "%s: Could not allocate TXB\n",
- + ieee->dev->name);
- + goto failed;
- + }
- +
- + txb->encrypted = 0;
- + txb->payload_size = skb->len;
- + memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
- + }
- +
- + success:
- + spin_unlock_irqrestore(&ieee->lock, flags);
- +#ifdef _RTL8187_EXT_PATCH_
- + // Sometimes, extension mode can reuse skb (by txb->fragments[0])
- + if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
- +#endif
- + dev_kfree_skb_any(skb);
- + if (txb) {
- + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
- + ieee80211_softmac_xmit(txb, ieee);
- + }else{
- + if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
- + stats->tx_packets++;
- + stats->tx_bytes += txb->payload_size;
- + return 0;
- + }
- + ieee80211_txb_free(txb);
- + }
- + }
- +
- + return 0;
- +
- + failed:
- + spin_unlock_irqrestore(&ieee->lock, flags);
- + netif_stop_queue(dev);
- + printk("netif_stop_queue in ieee80211_xmit \n");
- + stats->tx_errors++;
- + return 1;
- +
- +}
- +
- +
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +EXPORT_SYMBOL(ieee80211_txb_free);
- +#ifdef _RTL8187_EXT_PATCH_
- +EXPORT_SYMBOL(ieee80211_alloc_txb);
- +EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
- +EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
- +
- +EXPORT_SYMBOL(ieee80211_encrypt_fragment);
- +#endif // _RTL8187_EXT_PATCH_
- +#else
- +EXPORT_SYMBOL_NOVERS(ieee80211_txb_free);
- +#ifdef _RTL8187_EXT_PATCH_
- +EXPORT_SYMBOL_NOVERS(ieee80211_alloc_txb);
- +EXPORT_SYMBOL_NOVERS(ieee80211_ext_reuse_txb);
- +
- +EXPORT_SYMBOL_NOVERS(ieee80211_encrypt_fragment);
- +#endif // _RTL8187_EXT_PATCH_
- +#endif
- +
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,926 @@
- +/******************************************************************************
- +
- + Copyright(c) 2004 Intel Corporation. All rights reserved.
- +
- + Portions of this file are based on the WEP enablement code provided by the
- + Host AP project hostap-drivers v0.1.3
- + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- + <jkmaline@cc.hut.fi>
- + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- +
- + This program is free software; you can redistribute it and/or modify it
- + under the terms of version 2 of the GNU General Public License as
- + published by the Free Software Foundation.
- +
- + This program is distributed in the hope that it will be useful, but WITHOUT
- + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + more details.
- +
- + You should have received a copy of the GNU General Public License along with
- + this program; if not, write to the Free Software Foundation, Inc., 59
- + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- +
- + The full GNU General Public License is included in this distribution in the
- + file called LICENSE.
- +
- + Contact Information:
- + James P. Ketrenos <ipw2100-admin@linux.intel.com>
- + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- +
- +******************************************************************************/
- +#include <linux/wireless.h>
- +#include <linux/version.h>
- +#include <linux/kmod.h>
- +#include <linux/module.h>
- +
- +#include "ieee80211.h"
- +static const char *ieee80211_modes[] = {
- + "?", "a", "b", "ab", "g", "ag", "bg", "abg"
- +};
- +
- +#define MAX_CUSTOM_LEN 64
- +static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
- + char *start, char *stop,
- + struct ieee80211_network *network,
- + struct iw_request_info *info)
- +{
- + char custom[MAX_CUSTOM_LEN];
- + char *p;
- + struct iw_event iwe;
- + int i, j;
- + u8 max_rate, rate;
- +
- + /* First entry *MUST* be the AP MAC address */
- + iwe.cmd = SIOCGIWAP;
- + iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- + memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
- +#else
- + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
- +#endif
- + /* Remaining entries will be displayed in the order we provide them */
- +
- + /* Add the ESSID */
- + iwe.cmd = SIOCGIWESSID;
- + iwe.u.data.flags = 1;
- + //YJ,modified,080903,for hidden ap
- + //if (network->flags & NETWORK_EMPTY_ESSID) {
- + if (network->ssid_len == 0) {
- + iwe.u.data.length = sizeof("<hidden>");
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
- +#endif
- + } else {
- + iwe.u.data.length = min(network->ssid_len, (u8)32);
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
- +#endif
- + }
- +
- + /* Add the protocol name */
- + iwe.cmd = SIOCGIWNAME;
- + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
- +#else
- + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
- +#endif
- + /* Add mode */
- + iwe.cmd = SIOCGIWMODE;
- + if (network->capability &
- + (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
- + if (network->capability & WLAN_CAPABILITY_BSS)
- + iwe.u.mode = IW_MODE_MASTER;
- + else
- + iwe.u.mode = IW_MODE_ADHOC;
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_event(info, start, stop, &iwe,
- + IW_EV_UINT_LEN);
- +#else
- + start = iwe_stream_add_event(start, stop, &iwe,
- + IW_EV_UINT_LEN);
- +#endif
- + }
- +
- + /* Add frequency/channel */
- + iwe.cmd = SIOCGIWFREQ;
- +/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
- + iwe.u.freq.e = 3; */
- + iwe.u.freq.m = network->channel;
- + iwe.u.freq.e = 0;
- + iwe.u.freq.i = 0;
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
- +#else
- + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
- +#endif
- + /* Add encryption capability */
- + iwe.cmd = SIOCGIWENCODE;
- + if (network->capability & WLAN_CAPABILITY_PRIVACY)
- + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- + else
- + iwe.u.data.flags = IW_ENCODE_DISABLED;
- + iwe.u.data.length = 0;
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
- +#endif
- + /* Add basic and extended rates */
- + max_rate = 0;
- + p = custom;
- + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
- + for (i = 0, j = 0; i < network->rates_len; ) {
- + if (j < network->rates_ex_len &&
- + ((network->rates_ex[j] & 0x7F) <
- + (network->rates[i] & 0x7F)))
- + rate = network->rates_ex[j++] & 0x7F;
- + else
- + rate = network->rates[i++] & 0x7F;
- + if (rate > max_rate)
- + max_rate = rate;
- + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- + }
- + for (; j < network->rates_ex_len; j++) {
- + rate = network->rates_ex[j] & 0x7F;
- + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- + if (rate > max_rate)
- + max_rate = rate;
- + }
- +
- + iwe.cmd = SIOCGIWRATE;
- + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- + iwe.u.bitrate.value = max_rate * 500000;
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_event(info, start, stop, &iwe,IW_EV_PARAM_LEN);
- +#else
- + start = iwe_stream_add_event(start, stop, &iwe,IW_EV_PARAM_LEN);
- +#endif
- + iwe.cmd = IWEVCUSTOM;
- + iwe.u.data.length = p - custom;
- + if (iwe.u.data.length)
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, custom);
- +#endif
- + /* Add quality statistics */
- + /* TODO: Fix these values... */
- + iwe.cmd = IWEVQUAL;
- + iwe.u.qual.qual = network->stats.signalstrength;//network->stats.signal;
- + iwe.u.qual.level = network->stats.signal;//network->stats.rssi;
- + iwe.u.qual.noise = network->stats.noise;
- +#if 0
- + iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
- + if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
- + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- + if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
- + iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- + if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
- + iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
- +#endif
- +
- + iwe.u.qual.updated = 0x7;//network->stats.mask & IEEE80211_STATMASK_WEMASK;
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
- +#else
- + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
- +#endif
- + iwe.cmd = IWEVCUSTOM;
- + p = custom;
- +
- + iwe.u.data.length = p - custom;
- + if (iwe.u.data.length)
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, custom);
- +#endif
- +#if 0
- + if (ieee->wpa_enabled && network->wpa_ie_len){
- + char buf[MAX_WPA_IE_LEN * 2 + 30];
- + // printk("WPA IE\n");
- + u8 *p = buf;
- + p += sprintf(p, "wpa_ie=");
- + for (i = 0; i < network->wpa_ie_len; i++) {
- + p += sprintf(p, "%02x", network->wpa_ie[i]);
- + }
- +
- + memset(&iwe, 0, sizeof(iwe));
- + iwe.cmd = IWEVCUSTOM;
- + iwe.u.data.length = strlen(buf);
- + start = iwe_stream_add_point(start, stop, &iwe, buf);
- + }
- +
- + if (ieee->wpa_enabled && network->rsn_ie_len){
- + char buf[MAX_WPA_IE_LEN * 2 + 30];
- +
- + u8 *p = buf;
- + p += sprintf(p, "rsn_ie=");
- + for (i = 0; i < network->rsn_ie_len; i++) {
- + p += sprintf(p, "%02x", network->rsn_ie[i]);
- + }
- +
- +
- +#else
- + memset(&iwe, 0, sizeof(iwe));
- + if (network->wpa_ie_len) {
- + //printk("wpa_ie_len:%d\n", network->wpa_ie_len);
- + char buf[MAX_WPA_IE_LEN];
- + memcpy(buf, network->wpa_ie, network->wpa_ie_len);
- + iwe.cmd = IWEVGENIE;
- + iwe.u.data.length = network->wpa_ie_len;
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, buf);
- +#endif
- + }
- +
- + memset(&iwe, 0, sizeof(iwe));
- + if (network->rsn_ie_len) {
- + //printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
- + #if 0
- + {
- + int i;
- + for (i=0; i<network->rsn_ie_len; i++);
- + printk("%2x ", network->rsn_ie[i]);
- + printk("\n");
- + }
- + #endif
- + char buf[MAX_WPA_IE_LEN];
- + memcpy(buf, network->rsn_ie, network->rsn_ie_len);
- + iwe.cmd = IWEVGENIE;
- + iwe.u.data.length = network->rsn_ie_len;
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, buf);
- +#endif
- + }
- +
- +#endif
- +
- + /* Add EXTRA: Age to display seconds since last beacon/probe response
- + * for given network. */
- + iwe.cmd = IWEVCUSTOM;
- + p = custom;
- + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- + " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
- + iwe.u.data.length = p - custom;
- + if (iwe.u.data.length)
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
- + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
- +#else
- + start = iwe_stream_add_point(start, stop, &iwe, custom);
- +#endif
- +
- + return start;
- +}
- +
- +int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct ieee80211_network *network;
- + unsigned long flags;
- + int err = 0;
- + char *ev = extra;
- + char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
- + //char *stop = ev + IW_SCAN_MAX_DATA;
- + int i = 0;
- +
- + IEEE80211_DEBUG_WX("Getting scan\n");
- + down(&ieee->wx_sem);
- + spin_lock_irqsave(&ieee->lock, flags);
- +
- + if(!ieee->bHwRadioOff)
- + {
- + list_for_each_entry(network, &ieee->network_list, list) {
- + i++;
- +
- + if((stop-ev)<200)
- + {
- + err = -E2BIG;
- + break;
- + }
- +
- + if (ieee->scan_age == 0 ||
- + time_after(network->last_scanned + ieee->scan_age, jiffies))
- + {
- + ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
- + }
- + else
- + IEEE80211_DEBUG_SCAN(
- + "Not showing network '%s ("
- + MAC_FMT ")' due to age (%lums).\n",
- + escape_essid(network->ssid,
- + network->ssid_len),
- + MAC_ARG(network->bssid),
- + (jiffies - network->last_scanned) / (HZ / 100));
- + }
- + }
- + spin_unlock_irqrestore(&ieee->lock, flags);
- + up(&ieee->wx_sem);
- + wrqu->data.length = ev - extra;
- + wrqu->data.flags = 0;
- +
- + IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
- +
- + return err;
- +}
- +
- +int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *keybuf)
- +{
- + struct iw_point *erq = &(wrqu->encoding);
- + struct net_device *dev = ieee->dev;
- + struct ieee80211_security sec = {
- + .flags = 0
- + };
- + int i, key, key_provided, len;
- + struct ieee80211_crypt_data **crypt;
- +
- + IEEE80211_DEBUG_WX("SET_ENCODE\n");
- +
- + key = erq->flags & IW_ENCODE_INDEX;
- + if (key) {
- + if (key > WEP_KEYS)
- + return -EINVAL;
- + key--;
- + key_provided = 1;
- + } else {
- + key_provided = 0;
- + key = ieee->tx_keyidx;
- + }
- +
- + IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
- + "provided" : "default");
- +#ifdef _RTL8187_EXT_PATCH_
- +#if 0
- +{
- + int j;
- + for(j=0; j<MAX_MP; j++){
- + crypt = &ieee->cryptlist[j]->crypt[key];
- +#else
- + crypt = &ieee->cryptlist[0]->crypt[key];
- +#endif
- +#else
- + crypt = &ieee->crypt[key];
- +#endif
- + if (erq->flags & IW_ENCODE_DISABLED) {
- + if (key_provided && *crypt) {
- + IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
- + key);
- + ieee80211_crypt_delayed_deinit(ieee, crypt);
- + } else
- + IEEE80211_DEBUG_WX("Disabling encryption.\n");
- +
- + /* Check all the keys to see if any are still configured,
- + * and if no key index was provided, de-init them all */
- + for (i = 0; i < WEP_KEYS; i++) {
- +#ifdef _RTL8187_EXT_PATCH_
- +
- + if (ieee->cryptlist[0]->crypt[i] != NULL){
- +#else
- +
- + if (ieee->crypt[i] != NULL) {
- +#endif
- + if (key_provided)
- + break;
- + ieee80211_crypt_delayed_deinit(
- +#ifdef _RTL8187_EXT_PATCH_
- + ieee, &ieee->cryptlist[0]->crypt[i]);
- +#else
- + ieee, &ieee->crypt[i]);
- +#endif
- + }
- + }
- +
- + if (i == WEP_KEYS) {
- + sec.enabled = 0;
- + sec.level = SEC_LEVEL_0;
- + sec.flags |= SEC_ENABLED | SEC_LEVEL;
- + }
- +
- + goto done;
- + }
- +
- +
- +
- + sec.enabled = 1;
- + sec.flags |= SEC_ENABLED;
- +
- + if (*crypt != NULL && (*crypt)->ops != NULL &&
- + strcmp((*crypt)->ops->name, "WEP") != 0) {
- + /* changing to use WEP; deinit previously used algorithm
- + * on this key */
- + ieee80211_crypt_delayed_deinit(ieee, crypt);
- + }
- +
- + if (*crypt == NULL) {
- + struct ieee80211_crypt_data *new_crypt;
- +
- + /* take WEP into use */
- + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
- + GFP_KERNEL);
- + if (new_crypt == NULL)
- + return -ENOMEM;
- + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
- + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- + if (!new_crypt->ops) {
- + request_module("ieee80211_crypt_wep");
- + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- + }
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
- +#else
- + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
- +#endif
- + new_crypt->priv = new_crypt->ops->init(key);
- +
- + if (!new_crypt->ops || !new_crypt->priv) {
- + kfree(new_crypt);
- + new_crypt = NULL;
- +
- + printk(KERN_WARNING "%s: could not initialize WEP: "
- + "load module ieee80211_crypt_wep\n",
- + dev->name);
- + return -EOPNOTSUPP;
- + }
- + *crypt = new_crypt;
- + }
- +
- + /* If a new key was provided, set it up */
- + if (erq->length > 0) {
- + len = erq->length <= 5 ? 5 : 13;
- + memcpy(sec.keys[key], keybuf, erq->length);
- + if (len > erq->length)
- + memset(sec.keys[key] + erq->length, 0,
- + len - erq->length);
- + IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
- + key, escape_essid(sec.keys[key], len),
- + erq->length, len);
- + sec.key_sizes[key] = len;
- + (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- + (*crypt)->priv);
- + sec.flags |= (1 << key);
- + /* This ensures a key will be activated if no key is
- + * explicitely set */
- + if (key == sec.active_key)
- + sec.flags |= SEC_ACTIVE_KEY;
- +
- + ieee->tx_keyidx = key; //we need it to support multi_key setting. added by wb 2008_2_22
- + } else {
- + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- + NULL, (*crypt)->priv);
- + if (len == 0) {
- + /* Set a default key of all 0 */
- + IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
- + key);
- + memset(sec.keys[key], 0, 13);
- + (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- + (*crypt)->priv);
- + sec.key_sizes[key] = 13;
- + sec.flags |= (1 << key);
- + }
- +
- + /* No key data - just set the default TX key index */
- + if (key_provided) {
- + IEEE80211_DEBUG_WX(
- + "Setting key %d to default Tx key.\n", key);
- + ieee->tx_keyidx = key;
- + sec.active_key = key;
- + sec.flags |= SEC_ACTIVE_KEY;
- + }
- + }
- +#ifdef _RTL8187_EXT_PATCH_
- +#if 0
- +}
- +}
- +#endif
- +#endif
- + done:
- + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- + sec.flags |= SEC_AUTH_MODE;
- + IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
- + "OPEN" : "SHARED KEY");
- +
- + /* For now we just support WEP, so only set that security level...
- + * TODO: When WPA is added this is one place that needs to change */
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
- +
- + if (ieee->set_security)
- + ieee->set_security(dev, &sec);
- +
- + /* Do not reset port if card is in Managed mode since resetting will
- + * generate new IEEE 802.11 authentication which may end up in looping
- + * with IEEE 802.1X. If your hardware requires a reset after WEP
- + * configuration (for example... Prism2), implement the reset_port in
- + * the callbacks structures used to initialize the 802.11 stack. */
- + if (ieee->reset_on_keychange &&
- + ieee->iw_mode != IW_MODE_INFRA &&
- + ieee->reset_port && ieee->reset_port(dev)) {
- + printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
- + return -EINVAL;
- + }
- + return 0;
- +}
- +
- +int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *keybuf)
- +{
- + struct iw_point *erq = &(wrqu->encoding);
- + int len, key;
- + struct ieee80211_crypt_data *crypt;
- +
- + IEEE80211_DEBUG_WX("GET_ENCODE\n");
- +
- + if(ieee->iw_mode == IW_MODE_MONITOR)
- + return -1;
- +
- + key = erq->flags & IW_ENCODE_INDEX;
- + if (key) {
- + if (key > WEP_KEYS)
- + return -EINVAL;
- + key--;
- + } else
- + key = ieee->tx_keyidx;
- +#ifdef _RTL8187_EXT_PATCH_
- + crypt = ieee->cryptlist[0]->crypt[key];
- +#else
- + crypt = ieee->crypt[key];
- +#endif
- + erq->flags = key + 1;
- +
- + if (crypt == NULL || crypt->ops == NULL) {
- + erq->length = 0;
- + erq->flags |= IW_ENCODE_DISABLED;
- + return 0;
- + }
- +
- + if (strcmp(crypt->ops->name, "WEP") != 0) {
- + /* only WEP is supported with wireless extensions, so just
- + * report that encryption is used */
- + erq->length = 0;
- + erq->flags |= IW_ENCODE_ENABLED;
- + return 0;
- + }
- +
- + len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
- + erq->length = (len >= 0 ? len : 0);
- +
- + erq->flags |= IW_ENCODE_ENABLED;
- +
- + if (ieee->open_wep)
- + erq->flags |= IW_ENCODE_OPEN;
- + else
- + erq->flags |= IW_ENCODE_RESTRICTED;
- +
- + return 0;
- +}
- +
- +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct net_device *dev = ieee->dev;
- + struct iw_point *encoding = &wrqu->encoding;
- + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- + int i, idx, ret = 0;
- + int group_key = 0;
- + const char *alg, *module;
- + struct ieee80211_crypto_ops *ops;
- + struct ieee80211_crypt_data **crypt;
- +
- + struct ieee80211_security sec = {
- + .flags = 0,
- + };
- + //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
- + idx = encoding->flags & IW_ENCODE_INDEX;
- + if (idx) {
- + if (idx < 1 || idx > WEP_KEYS)
- + return -EINVAL;
- + idx--;
- + } else
- + idx = ieee->tx_keyidx;
- +
- + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- +#ifdef _RTL8187_EXT_PATCH_
- + crypt = &ieee->cryptlist[0]->crypt[idx];
- +#else
- + crypt = &ieee->crypt[idx];
- +#endif
- + group_key = 1;
- + } else {
- + /* some Cisco APs use idx>0 for unicast in dynamic WEP */
- + //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
- + if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
- + return -EINVAL;
- + if (ieee->iw_mode == IW_MODE_INFRA)
- +#ifdef _RTL8187_EXT_PATCH_
- + crypt = &ieee->cryptlist[0]->crypt[idx];
- +#else
- + crypt = &ieee->crypt[idx];
- +#endif
- + else
- + return -EINVAL;
- + }
- +
- + sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
- + if ((encoding->flags & IW_ENCODE_DISABLED) ||
- + ext->alg == IW_ENCODE_ALG_NONE) {
- + if (*crypt)
- + ieee80211_crypt_delayed_deinit(ieee, crypt);
- +
- + for (i = 0; i < WEP_KEYS; i++)
- +#ifdef _RTL8187_EXT_PATCH_
- + if (ieee->cryptlist[0]->crypt[i] != NULL)
- +#else
- + if (ieee->crypt[i] != NULL)
- +#endif
- + break;
- +
- + if (i == WEP_KEYS) {
- + sec.enabled = 0;
- + // sec.encrypt = 0;
- + sec.level = SEC_LEVEL_0;
- + sec.flags |= SEC_LEVEL;
- + }
- + //printk("disabled: flag:%x\n", encoding->flags);
- + goto done;
- + }
- +
- + sec.enabled = 1;
- + // sec.encrypt = 1;
- +#if 0
- + if (group_key ? !ieee->host_mc_decrypt :
- + !(ieee->host_encrypt || ieee->host_decrypt ||
- + ieee->host_encrypt_msdu))
- + goto skip_host_crypt;
- +#endif
- + switch (ext->alg) {
- + case IW_ENCODE_ALG_WEP:
- + alg = "WEP";
- + module = "ieee80211_crypt_wep";
- + break;
- + case IW_ENCODE_ALG_TKIP:
- + alg = "TKIP";
- + module = "ieee80211_crypt_tkip";
- + break;
- + case IW_ENCODE_ALG_CCMP:
- + alg = "CCMP";
- + module = "ieee80211_crypt_ccmp";
- + break;
- + default:
- + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- + dev->name, ext->alg);
- + ret = -EINVAL;
- + goto done;
- + }
- + printk("alg name:%s\n",alg);
- +
- + ops = ieee80211_get_crypto_ops(alg);
- + if (ops == NULL) {
- + request_module(module);
- + ops = ieee80211_get_crypto_ops(alg);
- + }
- + if (ops == NULL) {
- + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- + dev->name, ext->alg);
- + printk("========>unknown crypto alg %d\n", ext->alg);
- + ret = -EINVAL;
- + goto done;
- + }
- +
- + if (*crypt == NULL || (*crypt)->ops != ops) {
- + struct ieee80211_crypt_data *new_crypt;
- +
- + ieee80211_crypt_delayed_deinit(ieee, crypt);
- +
- + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
- + if (new_crypt == NULL) {
- + ret = -ENOMEM;
- + goto done;
- + }
- + new_crypt->ops = ops;
- + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
- + new_crypt->priv = new_crypt->ops->init(idx);
- + if (new_crypt->priv == NULL) {
- + kfree(new_crypt);
- + ret = -EINVAL;
- + goto done;
- + }
- + *crypt = new_crypt;
- +
- + }
- + //I need to deinit other crypt here in mesh mode instead deinit them while use them to tx&rx.
- +#ifdef _RTL8187_EXT_PATCH_
- + if (ieee->iw_mode == ieee->iw_ext_mode)
- + {
- + int j;
- + for (j=1; j<MAX_MP; j++)
- + {
- + struct ieee80211_crypt_data ** crypttmp = &ieee->cryptlist[j]->crypt[idx];
- + if (*crypttmp == NULL)
- + break;
- + if (*crypttmp && (*crypttmp)->ops != ops)
- + ieee80211_crypt_delayed_deinit(ieee, crypttmp);
- + }
- + }
- +#endif
- + if (ext->key_len > 0 && (*crypt)->ops->set_key &&
- + (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
- + (*crypt)->priv) < 0) {
- + IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
- + printk("key setting failed\n");
- + ret = -EINVAL;
- + goto done;
- + }
- +#if 1
- +// skip_host_crypt:
- + //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
- + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- + ieee->tx_keyidx = idx;
- + sec.active_key = idx;
- + sec.flags |= SEC_ACTIVE_KEY;
- + }
- +
- + if (ext->alg != IW_ENCODE_ALG_NONE) {
- + memcpy(sec.keys[idx], ext->key, ext->key_len);
- + sec.key_sizes[idx] = ext->key_len;
- + sec.flags |= (1 << idx);
- + if (ext->alg == IW_ENCODE_ALG_WEP) {
- + // sec.encode_alg[idx] = SEC_ALG_WEP;
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_1;
- + } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
- + // sec.encode_alg[idx] = SEC_ALG_TKIP;
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_2;
- + } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
- + // sec.encode_alg[idx] = SEC_ALG_CCMP;
- + sec.flags |= SEC_LEVEL;
- + sec.level = SEC_LEVEL_3;
- + }
- + /* Don't set sec level for group keys. */
- + if (group_key)
- + sec.flags &= ~SEC_LEVEL;
- + }
- +#endif
- +done:
- + if (ieee->set_security)
- + ieee->set_security(ieee->dev, &sec);
- +
- + if (ieee->reset_on_keychange &&
- + ieee->iw_mode != IW_MODE_INFRA &&
- + ieee->reset_port && ieee->reset_port(dev)) {
- + IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
- + return -EINVAL;
- + }
- +
- + return ret;
- +}
- +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct iw_mlme *mlme = (struct iw_mlme *) extra;
- +// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd);
- +#if 1
- + switch (mlme->cmd) {
- + case IW_MLME_DEAUTH:
- + case IW_MLME_DISASSOC:
- + // printk("disassoc now\n");
- + ieee80211_disassociate(ieee);
- + break;
- + default:
- + return -EOPNOTSUPP;
- + }
- +#endif
- + return 0;
- +}
- +
- +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- + struct iw_request_info *info,
- + struct iw_param *data, char *extra)
- +{
- +/*
- + struct ieee80211_security sec = {
- + .flags = SEC_AUTH_MODE,
- + }
- +*/
- + //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
- + switch (data->flags & IW_AUTH_INDEX) {
- + case IW_AUTH_WPA_VERSION:
- + /*need to support wpa2 here*/
- + //printk("wpa version:%x\n", data->value);
- + break;
- + case IW_AUTH_CIPHER_PAIRWISE:
- + case IW_AUTH_CIPHER_GROUP:
- + case IW_AUTH_KEY_MGMT:
- + /*
- + * * Host AP driver does not use these parameters and allows
- + * * wpa_supplicant to control them internally.
- + * */
- + break;
- + case IW_AUTH_TKIP_COUNTERMEASURES:
- + ieee->tkip_countermeasures = data->value;
- + break;
- + case IW_AUTH_DROP_UNENCRYPTED:
- + ieee->drop_unencrypted = data->value;
- + break;
- +
- + case IW_AUTH_80211_AUTH_ALG:
- + ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
- + //printk("open_wep:%d\n", ieee->open_wep);
- + break;
- +
- +#if 1
- + case IW_AUTH_WPA_ENABLED:
- + ieee->wpa_enabled = (data->value)?1:0;
- + //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
- + break;
- +
- +#endif
- + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- + ieee->ieee802_1x = data->value;
- + break;
- + case IW_AUTH_PRIVACY_INVOKED:
- + ieee->privacy_invoked = data->value;
- + break;
- + default:
- + return -EOPNOTSUPP;
- + }
- + return 0;
- +}
- +
- +#if 1
- +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
- +{
- +#if 0
- + printk("====>%s()\n", __FUNCTION__);
- + {
- + int i;
- + for (i=0; i<len; i++)
- + printk("%2x ", ie[i]&0xff);
- + printk("\n");
- + }
- +#endif
- + u8 *buf = NULL;
- +
- + if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
- + {
- + // printk("return error out, len:%d\n", len);
- + return -EINVAL;
- + }
- + if (len)
- + {
- +
- + if (len != ie[1]+2) printk("len:%d, ie:%d\n", (int)len, ie[1]);
- + buf = kmalloc(len, GFP_KERNEL);
- + if (buf == NULL)
- + return -ENOMEM;
- + memcpy(buf, ie, len);
- + kfree(ieee->wpa_ie);
- + ieee->wpa_ie = buf;
- + ieee->wpa_ie_len = len;
- + }
- + else{
- + if (ieee->wpa_ie)
- + kfree(ieee->wpa_ie);
- + ieee->wpa_ie = NULL;
- + ieee->wpa_ie_len = 0;
- + }
- +// printk("<=====out %s()\n", __FUNCTION__);
- +
- + return 0;
- +
- +}
- +#endif
- +
- +EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
- +EXPORT_SYMBOL(ieee80211_wx_set_mlme);
- +EXPORT_SYMBOL(ieee80211_wx_set_auth);
- +EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
- +EXPORT_SYMBOL(ieee80211_wx_get_scan);
- +EXPORT_SYMBOL(ieee80211_wx_set_encode);
- +EXPORT_SYMBOL(ieee80211_wx_get_encode);
- +#if 0
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode);
- +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode);
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/internal.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/internal.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/internal.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/internal.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,115 @@
- +/*
- + * Cryptographic API.
- + *
- + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the Free
- + * Software Foundation; either version 2 of the License, or (at your option)
- + * any later version.
- + *
- + */
- +#ifndef _CRYPTO_INTERNAL_H
- +#define _CRYPTO_INTERNAL_H
- +
- +
- +//#include <linux/crypto.h>
- +#include "rtl_crypto.h"
- +#include <linux/mm.h>
- +#include <linux/highmem.h>
- +#include <linux/init.h>
- +#include <asm/hardirq.h>
- +#include <asm/softirq.h>
- +#include <asm/kmap_types.h>
- +
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
- +#define list_for_each_entry(pos, head, member) \
- + for (pos = list_entry((head)->next, typeof(*pos), member), \
- + prefetch(pos->member.next); \
- + &pos->member != (head); \
- + pos = list_entry(pos->member.next, typeof(*pos), member), \
- + prefetch(pos->member.next))
- +
- +static inline void cond_resched(void)
- +{
- + if (need_resched()) {
- + set_current_state(TASK_RUNNING);
- + schedule();
- + }
- +}
- +#endif
- +
- +extern enum km_type crypto_km_types[];
- +
- +static inline enum km_type crypto_kmap_type(int out)
- +{
- + return crypto_km_types[(in_softirq() ? 2 : 0) + out];
- +}
- +
- +static inline void *crypto_kmap(struct page *page, int out)
- +{
- + return kmap_atomic(page, crypto_kmap_type(out));
- +}
- +
- +static inline void crypto_kunmap(void *vaddr, int out)
- +{
- + kunmap_atomic(vaddr, crypto_kmap_type(out));
- +}
- +
- +static inline void crypto_yield(struct crypto_tfm *tfm)
- +{
- + if (!in_softirq())
- + cond_resched();
- +}
- +
- +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
- +{
- + return (void *)&tfm[1];
- +}
- +
- +struct crypto_alg *crypto_alg_lookup(const char *name);
- +
- +#ifdef CONFIG_KMOD
- +void crypto_alg_autoload(const char *name);
- +struct crypto_alg *crypto_alg_mod_lookup(const char *name);
- +#else
- +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
- +{
- + return crypto_alg_lookup(name);
- +}
- +#endif
- +
- +#ifdef CONFIG_CRYPTO_HMAC
- +int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
- +void crypto_free_hmac_block(struct crypto_tfm *tfm);
- +#else
- +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
- +{
- + return 0;
- +}
- +
- +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
- +{ }
- +#endif
- +
- +#ifdef CONFIG_PROC_FS
- +void __init crypto_init_proc(void);
- +#else
- +static inline void crypto_init_proc(void)
- +{ }
- +#endif
- +
- +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
- +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
- +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
- +
- +int crypto_init_digest_ops(struct crypto_tfm *tfm);
- +int crypto_init_cipher_ops(struct crypto_tfm *tfm);
- +int crypto_init_compress_ops(struct crypto_tfm *tfm);
- +
- +void crypto_exit_digest_ops(struct crypto_tfm *tfm);
- +void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
- +void crypto_exit_compress_ops(struct crypto_tfm *tfm);
- +
- +#endif /* _CRYPTO_INTERNAL_H */
- +
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,20 @@
- +#ifndef __KMAP_TYPES_H
- +
- +#define __KMAP_TYPES_H
- +
- +
- +enum km_type {
- + KM_BOUNCE_READ,
- + KM_SKB_SUNRPC_DATA,
- + KM_SKB_DATA_SOFTIRQ,
- + KM_USER0,
- + KM_USER1,
- + KM_BH_IRQ,
- + KM_SOFTIRQ0,
- + KM_SOFTIRQ1,
- + KM_TYPE_NR
- +};
- +
- +#define _ASM_KMAP_TYPES_H
- +
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/readme linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/readme
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/readme 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/readme 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,162 @@
- +What this layer should do
- +
- +- It mantain the old mechanism as alternative, so the
- + ipw2100 driver works with really few changes.
- +- Encapsulate / Decapsulate ieee80211 packet
- +- Handle fragmentation
- +- Optionally provide an alterantive mechanism for netif queue stop/wake,
- + so that the ieee80211 layer will pass one fragment per time instead of
- + one txb struct per time. so the driver can stop the queue in the middle
- + of a packet.
- +- Provide two different TX interfaces for cards that can handle management
- + frames on one HW queue, and data on another, and for cards that have only
- + one HW queue (the latter untested and very, very rough).
- +- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes
- + and for the channel, essid and wap get/set wireless extension requests.
- + so that the driver has only to change channel when the ieee stack tell it.
- +- Optionally provide a scanning mechanism so that the driver has not to
- + worry about this, just implement the set channel calback and pass
- + frames to the upper layer
- +- Optionally provide the bss client protocol handshaking (just with open
- + authentication)
- +- Optionally provide the probe request send mechanism
- +- Optionally provide the bss master mode logic to handle association
- + protocol (only open authentication) and probe responses.
- +- SW wep encryption (with open authentication)
- +- It collects some stats
- +- It provides beacons to the card when it ask for them
- +
- +What this layer doesn't do (yet)
- +- Perform shared authentication
- +- Have full support for master mode (the AP should loop back in the air
- + frames from an associated client to another. This could be done easily
- + with few lines of code, and it is done in my previous version of the
- + stach, but a table of association must be keept and a disassociation
- + policy must be decided and implemented.
- +- Handle cleanly the full ieee 802.11 protocol. In AP mode it never
- + disassociate clients, and it is really prone to always allow access.
- + In bss client mode it is a bit rough with AP deauth and disassoc requests.
- +- It has not any entry point to view the collected stats.
- +- Altought it takes care of the card supported rates in the management frame
- + it sends, support for rate changing on TXed packet is not complete.
- +- Give up once associated in bss client mode (it never detect a
- + signal loss condition to disassociate and restart scanning)
- +- Provide a mechanism for enabling the TX in monitor mode, so
- + userspace programs can TX raw packets.
- +- Provide a mechanism for cards that need that the SW take care of beacon
- + TX completely, in sense that the SW has to enqueue by itself beacons
- + to the card so it TX them (if any...)
- +APIs
- +
- +Callback functions in the original stack has been mantained.
- +following has been added (from ieee80211.h)
- +
- + /* Softmac-generated frames (mamagement) are TXed via this
- + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
- + * not set. As some cards may have different HW queues that
- + * one might want to use for data and management frames
- + * the option to have two callbacks might be useful.
- + * This fucntion can't sleep.
- + */
- + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
- + struct net_device *dev);
- +
- + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
- + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
- + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
- + * then also management frames are sent via this callback.
- + * This function can't sleep.
- + */
- + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
- + struct net_device *dev);
- +
- + /* stops the HW queue for DATA frames. Useful to avoid
- + * waste time to TX data frame when we are reassociating
- + * This function can sleep.
- + */
- + void (*data_hard_stop)(struct net_device *dev);
- +
- + /* OK this is complementar to data_poll_hard_stop */
- + void (*data_hard_resume)(struct net_device *dev);
- +
- + /* ask to the driver to retune the radio .
- + * This function can sleep. the driver should ensure
- + * the radio has been swithced before return.
- + */
- + void (*set_chan)(struct net_device *dev,short ch);
- +
- + /* These are not used if the ieee stack takes care of
- + * scanning (IEEE_SOFTMAC_SCAN feature set).
- + * In this case only the set_chan is used.
- + *
- + * The syncro version is similar to the start_scan but
- + * does not return until all channels has been scanned.
- + * this is called in user context and should sleep,
- + * it is called in a work_queue when swithcing to ad-hoc mode
- + * or in behalf of iwlist scan when the card is associated
- + * and root user ask for a scan.
- + * the fucntion stop_scan should stop both the syncro and
- + * background scanning and can sleep.
- + * The fucntion start_scan should initiate the background
- + * scanning and can't sleep.
- + */
- + void (*scan_syncro)(struct net_device *dev);
- + void (*start_scan)(struct net_device *dev);
- + void (*stop_scan)(struct net_device *dev);
- +
- + /* indicate the driver that the link state is changed
- + * for example it may indicate the card is associated now.
- + * Driver might be interested in this to apply RX filter
- + * rules or simply light the LINK led
- + */
- + void (*link_change)(struct net_device *dev);
- +
- +Functions hard_data_[resume/stop] are optional and should not be used
- +if the driver decides to uses data+management frames enqueue in a
- +single HQ queue (thus using just the softmac_hard_data_start_xmit
- +callback).
- +
- +Function that the driver can use are:
- +
- +ieee80211_get_beacon - this is called by the driver when
- + the HW needs a beacon.
- +ieee80211_softmac_start_protocol - this should normally be called in the
- + driver open function
- +ieee80211_softmac_stop_protocol - the opposite of the above
- +ieee80211_wake_queue - this is similar to netif_wake_queue
- +ieee80211_reset_queue - this throw away fragments pending(if any)
- +ieee80211_stop_queue - this is similar to netif_stop_queue
- +
- +
- +known BUGS:
- +- When performing syncro scan (possiblily when swithcing to ad-hoc mode
- + and when running iwlist scan when associated) there is still an odd
- + behaviour.. I have not looked in this more accurately (yet).
- +
- +locking:
- +locking is done by means of three structures.
- +1- ieee->lock (by means of spin_[un]lock_irq[save/restore]
- +2- ieee->wx_sem
- +3- ieee->scan_sem
- +
- +the lock 1 is what protect most of the critical sections in the ieee stack.
- +the lock 2 is used to avoid that more than one of the SET wireless extension
- +handlers (as well as start/stop protocol function) are running at the same time.
- +the lock 1 is used when we need to modify or read the shared data in the wx handlers.
- +In other words the lock 2 will prevent one SET action will run across another SET
- +action (by make sleep the 2nd one) but allow GET actions, while the lock 1
- +make atomic those little shared data access in both GET and SET operation.
- +So get operation will be never be delayed really: they will never sleep..
- +Furthermore in the top of some SET operations a flag is set before acquiring
- +the lock. This is an help to make the previous running SET operation to
- +finish faster if needed (just in case the second one will totally undo the
- +first, so there is not need to complete the 1st really.. ).
- +The background scanning mechaninsm is protected by the lock 1 except for the
- +workqueue. this wq is here just to let the set_chan callback sleep (I thinked it
- +might be appreciated by USB network card driver developer). In this case the lock 3
- +take its turn.
- +Thus the stop function needs both the locks.
- +Funny in the syncro scan the lock 2 play its role (as both the syncro_scan
- +function and the stop scan function are called with this semaphore held).
- +
- +
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,282 @@
- +#ifndef _RTL8187_MESH_H_
- +#define _RTL8187_MESH_H_
- +
- +#include "msh_class.h" // struct mshclass
- +#include "mesh.h" // struct MESH-Neighbor-Entry
- +#include "ieee80211.h" // struct ieee80211-network
- +#include "mesh_8185_util.h" // DOT11-QUEUE
- +#include "hash_table.h" // hash-table
- +#include "8185s_pathsel.h"
- +#include <linux/list.h>
- +
- +#define GET_MESH_PRIV(x) ((struct mshclass_priv *)(x->priv))
- +
- +struct ieee80211_hdr_mesh {
- + u16 frame_ctl;
- + u16 duration_id;
- + u8 addr1[ETH_ALEN];
- + u8 addr2[ETH_ALEN];
- + u8 addr3[ETH_ALEN];
- + u16 seq_ctl;
- + u8 addr4[ETH_ALEN];
- + unsigned char mesh_flag;
- + INT8 TTL;
- + UINT16 segNum;
- + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
- + unsigned char SrcMACAddr[ETH_ALEN];
- +} __attribute__ ((packed));
- +
- +struct myMeshIDNode {
- + struct list_head list;
- + char id[MESH_ID_LEN+1];
- + short popEN;
- + char tried;
- + unsigned long expire;
- + struct ieee80211_network mesh_network;
- +};
- +
- +struct ieee80211_hdr_mesh_QOS {
- + u16 frame_ctl;
- + u16 duration_id;
- + u8 addr1[ETH_ALEN];
- + u8 addr2[ETH_ALEN];
- + u8 addr3[ETH_ALEN];
- + u16 seq_ctl;
- + u8 addr4[ETH_ALEN];
- + u16 QOS_ctl;
- + unsigned char mesh_flag;
- + INT8 TTL;
- + UINT16 segNum;
- + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
- + unsigned char SrcMACAddr[ETH_ALEN];
- +} __attribute__ ((packed));
- +
- +
- +struct mesh_PeerEntry {
- + // based on 8185ag.h
- + struct list_head hash_list;
- + unsigned int used; ///< used == TRUE => has been allocated, \n used == FALSE => can be allocated
- + unsigned char hwaddr[MACADDRLEN]; ///< hardware address
- +
- + // struct list_head mesh_unEstablish_ptr; // 尚未(或從已連線 -> 未連線) 之 MP list
- + struct list_head mesh_mp_ptr; // MP list
- +
- + /*mesh_neighbor:
- + * Inited by "Neighbor Discovering"
- + * cleaned by "Disassociation" or "Expired"
- + */
- + struct MESH_Neighbor_Entry mesh_neighbor_TBL;
- +
- + struct ieee80211_network * pstat; // a backward pointer
- +
- + // 802.11 seq checking
- + u16 last_rxseq; /* rx seq previous per-tid */
- + u16 last_rxfrag;/* tx frag previous per-tid */
- + unsigned long last_time;
- + //
- +};
- +
- +
- +struct mshclass_priv {
- +
- + struct mesh_PeerEntry *meshEntries; // 1-to-1 for priv->ieee80211->networks
- +
- + spinlock_t lock_stainfo; // lock for accessing the data structure of stat info
- + spinlock_t lock_queue; // lock for DOT11_EnQueue2/DOT11_DeQueue2/enque/dequeue
- + spinlock_t lock_Rreq; // lock for rreq_retry. Some function like aodv_expire/tx use lock_queue simultaneously
- +// spinlock_t lock_meshlist;
- +
- + // struct _DOT11_QUEUE *pevent_queue; ///< 802.11 QUEUE結構
- + // struct hash_table *pathsel_table; // GANTOE
- + //tsananiu
- + struct _DOT11_QUEUE *pathsel_queue; ///< 802.11 QUEUE結構
- +
- + //tsananiu end
- +
- + //add by shlu 20070518
- + unsigned char RreqMAC[AODV_RREQ_TABLE_SIZE][6];
- + unsigned int RreqBegin;
- + unsigned int RreqEnd;
- +
- +#if defined(MESH_ROLE_ROOT) || defined(MESH_ROLE_PORTAL)
- +#define MAX_SZ_BAD_MAC 3
- + unsigned char BadMac[MAX_SZ_BAD_MAC][MACADDRLEN];
- + int idx_BadMac;
- +#endif // MESH_ROLE_ROOT || MESH_ROLE_PORTAL
- +
- + //-------------
- + unsigned char root_mac[MACADDRLEN];
- + struct mesh_info dot11MeshInfo; // extrated from wifi_mib (ieee802_mib.h)
- + struct hash_table *proxy_table, *mesh_rreq_retry_queue; //GANTOE //GANTOE
- + struct hash_table *pathsel_table; // add by chuangch 2007.09.13
- + // add by Jason
- + struct mpp_tb *pann_mpp_tb;
- +
- + struct timer_list expire_timer; // 1sec timer
- +
- + struct timer_list beacon_timer; // 1sec timer
- + struct list_head stat_hash[MAX_NETWORK_COUNT]; // sta_info hash table (aid_obj)
- +
- + struct list_head meshList[MAX_CHANNEL_NUMBER];
- + int scanMode;
- +
- + struct {
- + struct ieee80211_network *pstat;
- + unsigned char hwaddr[MACADDRLEN];
- + } stainfo_cache;
- +
- + // The following elements are used by 802.11s.
- + // For copyright-pretection, we use an independent (binary) module.
- + // Note that it can also be put either under r8180_priv or ieee80211_device. The adv of put under
- + // r8180_priv is to get "higher encapsulation". On the other hand, r8180_priv was originally designed
- + // for "hardward specific."
- + char mesh_mac_filter_allow[8][13];
- + char mesh_mac_filter_deny[8][13];
- +
- + struct MESH_Share meshare; // mesh share data
- +
- + struct {
- +
- + int prev_iw_mode; // Save this->iw_mode for r8180_wx->r8180_wx_enable_mesh. No init requirement
- +
- + struct MESH_Profile mesh_profile; // contains MESHID
- +
- + struct mesh_info dot11MeshInfo; // contains meshMaxAssocNum
- +
- + struct net_device_stats mesh_stats;
- +
- + UINT8 mesh_Version; // 使用的版本
- + // WLAN Mesh Capability
- + INT16 mesh_PeerCAP_cap; // peer capability-Cap number (有號數)
- + UINT8 mesh_PeerCAP_flags; // peer capability-flags
- + UINT8 mesh_PowerSaveCAP; // Power Save capability
- + UINT8 mesh_SyncCAP; // Synchronization capability
- + UINT8 mesh_MDA_CAP; // MDA capability
- + UINT32 mesh_ChannelPrecedence; // Channel Precedence
- +
- + // neighbor -> candidate neighbor, if mesh_available_peerlink > 0, page 56, D0.02
- + UINT8 mesh_AvailablePeerLink; // 此是否有需要?(因它等同於 mesh_PeerCAP)=>暫 時保 留
- +
- + UINT8 mesh_HeaderFlags; // mesh header 內的 mesh flags field
- +
- + // MKD domain element [MKDDIE]
- + UINT8 mesh_MKD_DomainID[6];
- + UINT8 mesh_MKDDIE_SecurityConfiguration;
- +
- + // EMSA Handshake element [EMSAIE]
- + UINT8 mesh_EMSAIE_ANonce[32];
- + UINT8 mesh_EMSAIE_SNonce[32];
- + UINT8 mesh_EMSAIE_MA_ID[6];
- + UINT16 mesh_EMSAIE_MIC_Control;
- + UINT8 mesh_EMSAIE_MIC[16];
- +
- + struct timer_list mesh_peer_link_timer; ///< 對尚未連 線(與連線退至未連線) MP mesh_unEstablish_hdr 作 peer link time out
- +
- +// struct timer_list mesh_beacon_timer;
- + // mesh_unEstablish_hdr:
- + // It is a list structure, only stores unEstablish (or Establish -> unEstablish [MP_HOLDING])MP entry
- + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
- + // and removed by successful "Peer link setup" or "Expired"
- + struct list_head mesh_unEstablish_hdr;
- +
- + // mesh_mp_hdr:
- + // It is a list of MP/MAP/MPP who has already passed "Peer link setup"
- + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
- + // Every entry is inserted by "successful peer link setup"
- + // and removed by "Expired"
- + struct list_head mesh_mp_hdr;
- +
- + } mesh;
- +
- + int iCurChannel; // remember the working channel
- +};
- +
- +// Stanley, 04/23/07
- +// The following mode is used by ieee80211_device->iw_mode
- +// Although it is better to put the definition under linux/wireless.h (or wireless_copy.h), it is a system file
- +// that we shouldn't modify directly.
- +#define IW_MODE_MESH 11 /* 802.11s mesh mode */
- +
- +// Default MESHID
- +#define IEEE80211S_DEFAULT_MESHID "802.11s"
- +
- +// callback for 802.11s
- +extern short rtl8187_patch_ieee80211_probe_req_1 (struct ieee80211_device *ieee);
- +extern u8* rtl8187_patch_ieee80211_probe_req_2 (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag);
- +
- +// wx
- +extern int rtl8187_patch_r8180_wx_get_meshinfo(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +extern int rtl8187_patch_r8180_wx_enable_mesh(struct net_device *dev);
- +extern int rtl8187_patch_r8180_wx_disable_mesh(struct net_device *dev);
- +extern int rtl8187_patch_r8180_wx_wx_set_meshID(struct net_device *dev, char *ext,unsigned char channel);
- +extern void rtl8187_patch_r8180_wx_set_channel (struct ieee80211_device *ieee, int ch);
- +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);
- +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);
- +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);
- +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);
- +extern int rtl8187_patch_r8180_wx_get_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +extern int rtl8187_patch_r8180_wx_get_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +
- +extern int rtl8187_patch_r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +extern int rtl8187_patch_r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +extern int rtl8187_patch_r8180_wx_get_selected_mesh(struct net_device *dev, int en, char *cho, char* id);
- +//by amy for networkmanager UI
- +extern int rtl8187_patch_r8180_wx_get_selected_mesh_channel(struct net_device *dev, char *extmeshid, char *cho);
- +//by amy for networkmanager UI
- +// osdep
- +extern int rtl8187_patch_ieee80211_start_protocol (struct ieee80211_device *ieee);
- +extern u8 rtl8187_patch_rtl8180_up(struct mshclass *priv);
- +extern void rtl8187_patch_ieee80211_stop_protocol(struct ieee80211_device *ieee);
- +
- +// issue_assocreq_MP
- +extern void rtl8187_patch_ieee80211_association_req_1 (struct ieee80211_assoc_request_frame *hdr);
- +extern u8* rtl8187_patch_ieee80211_association_req_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
- +
- +// OnAssocReq_MP
- +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_req (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- +// issue_assocrsp_MP
- +extern void rtl8187_patch_ieee80211_assoc_resp_by_net_1 (struct ieee80211_assoc_response_frame *assoc);
- +u8* rtl8187_patch_ieee80211_assoc_resp_by_net_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
- +
- +// OnAssocRsp_MP
- +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_rsp (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- +
- +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_auth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_deauth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- +extern unsigned int rtl8187_patch_ieee80211_process_probe_response_1( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
- +extern void rtl8187_patch_ieee80211_rx_mgt_on_probe_req( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
- +extern void rtl8187_patch_ieee80211_rx_mgt_update_expire ( struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- +// set channel
- +extern int rtl8187_patch_ieee80211_ext_stop_scan_wq_set_channel (struct ieee80211_device *ieee);
- +
- +// on rx (rx isr)
- +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);
- +
- +// r8187_core
- +// handle ioctl
- +extern int rtl8187_patch_rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
- +// create proc
- +extern void rtl8187_patch_create_proc(struct r8180_priv *priv);
- +extern void rtl8187_patch_remove_proc(struct r8180_priv *priv);
- +
- +// tx, xmit
- +// locked by ieee->lock. Call ieee80211_softmac_xmit afterward
- +extern struct ieee80211_txb* rtl8187_patch_ieee80211_xmit (struct sk_buff *skb, struct net_device *dev);
- +
- +// given a skb, output header's length
- +extern int rtl8187_patch_ieee80211_rx_frame_get_hdrlen (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- +// check the frame control field, return 0: not accept, 1: accept
- +extern int rtl8187_patch_ieee80211_rx_is_valid_framectl (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
- +
- +// process_dataframe
- +extern int rtl8187_patch_ieee80211_rx_process_dataframe (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- +
- +extern int rtl8187_patch_is_duplicate_packet (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
- +
- +extern int rtl8187_patch_ieee80211_softmac_xmit_get_rate (struct ieee80211_device *ieee, struct sk_buff *skb);
- +extern void ieee80211_start_mesh(struct ieee80211_device *ieee);
- +#endif // _RTL8187_MESH_H_
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,399 @@
- +/*
- + * Scatterlist Cryptographic API.
- + *
- + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- + * Copyright (c) 2002 David S. Miller (davem@redhat.com)
- + *
- + * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- + * and Nettle, by Niels M敿ēer.
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the Free
- + * Software Foundation; either version 2 of the License, or (at your option)
- + * any later version.
- + *
- + */
- +#ifndef _LINUX_CRYPTO_H
- +#define _LINUX_CRYPTO_H
- +
- +#include <linux/module.h>
- +#include <linux/kernel.h>
- +#include <linux/types.h>
- +#include <linux/list.h>
- +#include <linux/string.h>
- +#include <asm/page.h>
- +#include <asm/errno.h>
- +
- +#define crypto_register_alg crypto_register_alg_rtl
- +#define crypto_unregister_alg crypto_unregister_alg_rtl
- +#define crypto_alloc_tfm crypto_alloc_tfm_rtl
- +#define crypto_free_tfm crypto_free_tfm_rtl
- +#define crypto_alg_available crypto_alg_available_rtl
- +
- +/*
- + * Algorithm masks and types.
- + */
- +#define CRYPTO_ALG_TYPE_MASK 0x000000ff
- +#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
- +#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
- +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
- +
- +/*
- + * Transform masks and values (for crt_flags).
- + */
- +#define CRYPTO_TFM_MODE_MASK 0x000000ff
- +#define CRYPTO_TFM_REQ_MASK 0x000fff00
- +#define CRYPTO_TFM_RES_MASK 0xfff00000
- +
- +#define CRYPTO_TFM_MODE_ECB 0x00000001
- +#define CRYPTO_TFM_MODE_CBC 0x00000002
- +#define CRYPTO_TFM_MODE_CFB 0x00000004
- +#define CRYPTO_TFM_MODE_CTR 0x00000008
- +
- +#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
- +#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
- +#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
- +#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
- +#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
- +#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
- +
- +/*
- + * Miscellaneous stuff.
- + */
- +#define CRYPTO_UNSPEC 0
- +#define CRYPTO_MAX_ALG_NAME 64
- +
- +struct scatterlist;
- +
- +/*
- + * Algorithms: modular crypto algorithm implementations, managed
- + * via crypto_register_alg() and crypto_unregister_alg().
- + */
- +struct cipher_alg {
- + unsigned int cia_min_keysize;
- + unsigned int cia_max_keysize;
- + int (*cia_setkey)(void *ctx, const u8 *key,
- + unsigned int keylen, u32 *flags);
- + void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
- + void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
- +};
- +
- +struct digest_alg {
- + unsigned int dia_digestsize;
- + void (*dia_init)(void *ctx);
- + void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
- + void (*dia_final)(void *ctx, u8 *out);
- + int (*dia_setkey)(void *ctx, const u8 *key,
- + unsigned int keylen, u32 *flags);
- +};
- +
- +struct compress_alg {
- + int (*coa_init)(void *ctx);
- + void (*coa_exit)(void *ctx);
- + int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
- + u8 *dst, unsigned int *dlen);
- + int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
- + u8 *dst, unsigned int *dlen);
- +};
- +
- +#define cra_cipher cra_u.cipher
- +#define cra_digest cra_u.digest
- +#define cra_compress cra_u.compress
- +
- +struct crypto_alg {
- + struct list_head cra_list;
- + u32 cra_flags;
- + unsigned int cra_blocksize;
- + unsigned int cra_ctxsize;
- + const char cra_name[CRYPTO_MAX_ALG_NAME];
- +
- + union {
- + struct cipher_alg cipher;
- + struct digest_alg digest;
- + struct compress_alg compress;
- + } cra_u;
- +
- + struct module *cra_module;
- +};
- +
- +/*
- + * Algorithm registration interface.
- + */
- +int crypto_register_alg(struct crypto_alg *alg);
- +int crypto_unregister_alg(struct crypto_alg *alg);
- +
- +/*
- + * Algorithm query interface.
- + */
- +int crypto_alg_available(const char *name, u32 flags);
- +
- +/*
- + * Transforms: user-instantiated objects which encapsulate algorithms
- + * and core processing logic. Managed via crypto_alloc_tfm() and
- + * crypto_free_tfm(), as well as the various helpers below.
- + */
- +struct crypto_tfm;
- +
- +struct cipher_tfm {
- + void *cit_iv;
- + unsigned int cit_ivsize;
- + u32 cit_mode;
- + int (*cit_setkey)(struct crypto_tfm *tfm,
- + const u8 *key, unsigned int keylen);
- + int (*cit_encrypt)(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes);
- + int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes, u8 *iv);
- + int (*cit_decrypt)(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes);
- + int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes, u8 *iv);
- + void (*cit_xor_block)(u8 *dst, const u8 *src);
- +};
- +
- +struct digest_tfm {
- + void (*dit_init)(struct crypto_tfm *tfm);
- + void (*dit_update)(struct crypto_tfm *tfm,
- + struct scatterlist *sg, unsigned int nsg);
- + void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
- + void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
- + unsigned int nsg, u8 *out);
- + int (*dit_setkey)(struct crypto_tfm *tfm,
- + const u8 *key, unsigned int keylen);
- +#ifdef CONFIG_CRYPTO_HMAC
- + void *dit_hmac_block;
- +#endif
- +};
- +
- +struct compress_tfm {
- + int (*cot_compress)(struct crypto_tfm *tfm,
- + const u8 *src, unsigned int slen,
- + u8 *dst, unsigned int *dlen);
- + int (*cot_decompress)(struct crypto_tfm *tfm,
- + const u8 *src, unsigned int slen,
- + u8 *dst, unsigned int *dlen);
- +};
- +
- +#define crt_cipher crt_u.cipher
- +#define crt_digest crt_u.digest
- +#define crt_compress crt_u.compress
- +
- +struct crypto_tfm {
- +
- + u32 crt_flags;
- +
- + union {
- + struct cipher_tfm cipher;
- + struct digest_tfm digest;
- + struct compress_tfm compress;
- + } crt_u;
- +
- + struct crypto_alg *__crt_alg;
- +};
- +
- +/*
- + * Transform user interface.
- + */
- +
- +/*
- + * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
- + * If that fails and the kernel supports dynamically loadable modules, it
- + * will then attempt to load a module of the same name or alias. A refcount
- + * is grabbed on the algorithm which is then associated with the new transform.
- + *
- + * crypto_free_tfm() frees up the transform and any associated resources,
- + * then drops the refcount on the associated algorithm.
- + */
- +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
- +void crypto_free_tfm(struct crypto_tfm *tfm);
- +
- +/*
- + * Transform helpers which query the underlying algorithm.
- + */
- +static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
- +{
- + return tfm->__crt_alg->cra_name;
- +}
- +
- +static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
- +{
- + struct crypto_alg *alg = tfm->__crt_alg;
- +
- + if (alg->cra_module)
- + return alg->cra_module->name;
- + else
- + return NULL;
- +}
- +
- +static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
- +{
- + return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
- +}
- +
- +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + return tfm->__crt_alg->cra_cipher.cia_min_keysize;
- +}
- +
- +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + return tfm->__crt_alg->cra_cipher.cia_max_keysize;
- +}
- +
- +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + return tfm->crt_cipher.cit_ivsize;
- +}
- +
- +static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
- +{
- + return tfm->__crt_alg->cra_blocksize;
- +}
- +
- +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
- + return tfm->__crt_alg->cra_digest.dia_digestsize;
- +}
- +
- +/*
- + * API wrappers.
- + */
- +static inline void crypto_digest_init(struct crypto_tfm *tfm)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
- + tfm->crt_digest.dit_init(tfm);
- +}
- +
- +static inline void crypto_digest_update(struct crypto_tfm *tfm,
- + struct scatterlist *sg,
- + unsigned int nsg)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
- + tfm->crt_digest.dit_update(tfm, sg, nsg);
- +}
- +
- +static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
- + tfm->crt_digest.dit_final(tfm, out);
- +}
- +
- +static inline void crypto_digest_digest(struct crypto_tfm *tfm,
- + struct scatterlist *sg,
- + unsigned int nsg, u8 *out)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
- + tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
- +}
- +
- +static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
- + const u8 *key, unsigned int keylen)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
- + if (tfm->crt_digest.dit_setkey == NULL)
- + return -ENOSYS;
- + return tfm->crt_digest.dit_setkey(tfm, key, keylen);
- +}
- +
- +static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
- + const u8 *key, unsigned int keylen)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
- +}
- +
- +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
- +}
- +
- +static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes, u8 *iv)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
- + return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
- +}
- +
- +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
- +}
- +
- +static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
- + struct scatterlist *dst,
- + struct scatterlist *src,
- + unsigned int nbytes, u8 *iv)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
- + return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
- +}
- +
- +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
- + const u8 *src, unsigned int len)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + memcpy(tfm->crt_cipher.cit_iv, src, len);
- +}
- +
- +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
- + u8 *dst, unsigned int len)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
- + memcpy(dst, tfm->crt_cipher.cit_iv, len);
- +}
- +
- +static inline int crypto_comp_compress(struct crypto_tfm *tfm,
- + const u8 *src, unsigned int slen,
- + u8 *dst, unsigned int *dlen)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
- + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
- +}
- +
- +static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
- + const u8 *src, unsigned int slen,
- + u8 *dst, unsigned int *dlen)
- +{
- + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
- + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
- +}
- +
- +/*
- + * HMAC support.
- + */
- +#ifdef CONFIG_CRYPTO_HMAC
- +void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
- +void crypto_hmac_update(struct crypto_tfm *tfm,
- + struct scatterlist *sg, unsigned int nsg);
- +void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
- + unsigned int *keylen, u8 *out);
- +void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
- + struct scatterlist *sg, unsigned int nsg, u8 *out);
- +#endif /* CONFIG_CRYPTO_HMAC */
- +
- +#endif /* _LINUX_CRYPTO_H */
- +
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,51 @@
- +/*
- + * Cryptographic API.
- + *
- + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- + * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
- + * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
- + *
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the Free
- + * Software Foundation; either version 2 of the License, or (at your option)
- + * any later version.
- + *
- + */
- +
- +#ifndef _CRYPTO_SCATTERWALK_H
- +#define _CRYPTO_SCATTERWALK_H
- +#include <linux/mm.h>
- +#include <asm/scatterlist.h>
- +
- +struct scatter_walk {
- + struct scatterlist *sg;
- + struct page *page;
- + void *data;
- + unsigned int len_this_page;
- + unsigned int len_this_segment;
- + unsigned int offset;
- +};
- +
- +/* Define sg_next is an inline routine now in case we want to change
- + scatterlist to a linked list later. */
- +static inline struct scatterlist *sg_next(struct scatterlist *sg)
- +{
- + return sg + 1;
- +}
- +
- +static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
- + struct scatter_walk *walk_out,
- + void *src_p, void *dst_p)
- +{
- + return walk_in->page == walk_out->page &&
- + walk_in->offset == walk_out->offset &&
- + walk_in->data == src_p && walk_out->data == dst_p;
- +}
- +
- +void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
- +void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
- +int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
- +void scatterwalk_map(struct scatter_walk *walk, int out);
- +void scatterwalk_done(struct scatter_walk *walk, int out, int more);
- +
- +#endif /* _CRYPTO_SCATTERWALK_H */
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/Makefile linux-lemote/drivers/net/wireless/rtl8187b/Makefile
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/Makefile 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,41 @@
- +obj-$(CONFIG_RTL8187B) += rtl8187b.o
- +
- +rtl8187b-objs := r8187_core.o \
- + r8180_93cx6.o \
- + r8180_wx.o \
- + r8180_rtl8225.o \
- + r8180_rtl8225z2.o \
- + r8180_pm.o \
- + r8180_dm.o \
- + r8187_led.o \
- + r8187_rfkill.o \
- + ieee80211/dot11d.o \
- + ieee80211/ieee80211_softmac.o \
- + ieee80211/ieee80211_rx.o \
- + ieee80211/ieee80211_tx.o \
- + ieee80211/ieee80211_wx.o \
- + ieee80211/ieee80211_module.o \
- + ieee80211/ieee80211_softmac_wx.o \
- + ieee80211/ieee80211_crypt.o \
- + ieee80211/ieee80211_crypt_tkip.o \
- + ieee80211/ieee80211_crypt_ccmp.o \
- + ieee80211/ieee80211_crypt_wep.o
- +
- +EXTRA_CFLAGS += -DCONFIG_RTL8180_PM
- +EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
- +EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
- +EXTRA_CFLAGS += -DJOHN_IOCTL
- +EXTRA_CFLAGS += -DLED
- +#EXTRA_CFLAGS += -DLED_SHIN
- +#EXTRA_CFLAGS += -DSW_ANTE_DIVERSITY
- +EXTRA_CFLAGS += -DCPU_64BIT
- +EXTRA_CFLAGS += -DCONFIG_IPS
- +#CFLAGS += -DJOHN_HWSEC -DJOHN_TKIP
- +#CFLAGS += -DJOHN_DUMP_TX
- +#EXTRA_CFLAGS += -DJOHN_DUMP_TXPKT
- +
- +#Radio On/Off debug
- +#EXTRA_CFLAGS += -DCONFIG_RADIO_DEBUG
- +
- +#for dot11d
- +EXTRA_CFLAGS += -DENABLE_DOT11D
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/msh_class.h linux-lemote/drivers/net/wireless/rtl8187b/msh_class.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/msh_class.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/msh_class.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,117 @@
- +/*! \file msh_class.h
- + \brief msh CLASS extension
- +
- + \date 2007/5/2
- + \author Stanley Chang <chagnsl@cs.nctu.edu.tw>
- +*/
- +
- +#ifndef _MESH_CLASS_HDR_H_
- +#define _MESH_CLASS_HDR_H_
- +
- +#include <linux/if_ether.h> /* ETH_ALEN */
- +#include <linux/kernel.h> /* ARRAY_SIZE */
- +#include <linux/version.h>
- +#include <linux/jiffies.h>
- +#include <linux/timer.h>
- +#include <linux/sched.h>
- +
- +#include "ieee80211/ieee80211.h" // for struct ieee80211-xxxx
- +#include "r8187.h" // for struct r8180-priv
- +
- +#define MAC_TABLE_SIZE 8
- +
- +struct mshclass {
- + struct r8180_priv * p8187;
- +
- + // callback functions
- + // ieee80211_softmac.c
- + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
- +
- + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
- + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
- +
- + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
- + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
- +
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
- +
- + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
- + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
- +
- + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
- +
- + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
- +
- + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- +//by amy for mesh
- + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
- +//by amy for mesh
- + /// r8180_wx.c
- + int (*ext_patch_r8180_wx_get_meshinfo) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_enable_mesh) (struct net_device *dev);
- + int (*ext_patch_r8180_wx_disable_mesh) (struct net_device *dev);
- + int (*ext_patch_r8180_wx_set_meshID) ( struct net_device *dev, char *ext);
- +//by amy for mesh
- + int (*ext_patch_r8180_wx_set_mesh_chan)(struct net_device *dev, unsigned char channel);
- +//by amy for mesh
- + void (*ext_patch_r8180_wx_set_channel) (struct ieee80211_device *ieee, int ch);
- +
- + int (*ext_patch_r8180_wx_set_add_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_set_del_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_set_add_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_set_del_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_get_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_get_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +
- + int (*ext_patch_r8180_wx_get_mesh_list) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_mesh_scan) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- + int (*ext_patch_r8180_wx_get_selected_mesh)(struct net_device *dev, int en, char *cho, char* id);
- +//by amy for networkmanager UI
- + int (*ext_patch_r8180_wx_get_selected_mesh_channel)(struct net_device *dev, char* extmeshid, char *cho);
- +//by amy for networkmanager UI
- + /// r8187_core.c
- + u8 (*ext_patch_rtl8180_up) (struct mshclass *priv);
- +
- + // ieee80211_rx.c
- + unsigned int (*ext_patch_ieee80211_process_probe_response_1) ( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
- + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
- +
- + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- + 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);
- +
- + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
- +
- + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
- +
- + // return > 0 is success. 0 when failed
- + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
- +
- + int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
- + /* added by david for setting acl dynamically */
- + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
- +
- + // r8187_core.c
- + int (*ext_patch_rtl8180_ioctl) (struct net_device *dev, struct ifreq *rq, int cmd);
- + void (*ext_patch_create_proc) (struct r8180_priv *priv);
- + void (*ext_patch_remove_proc) (struct r8180_priv *priv);
- +
- + // ieee80211_tx.c
- +
- + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
- + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
- +
- + // DO NOT MODIFY ANY STRUCTURE BELOW THIS LINE
- + u8 priv[0]; // mshclass_priv;
- +};
- +
- +extern void free_mshobj(struct mshclass **pObj);
- +extern struct mshclass *alloc_mshobj(struct r8180_priv *caller_priv);
- +
- +
- +#endif // _MESH_CLASS_HDR_H_
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,146 @@
- +/*
- + This files contains card eeprom (93c46 or 93c56) programming routines,
- + memory is addressed by 16 bits words.
- +
- + This is part of rtl8180 OpenSource driver.
- + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +
- + Parts of this driver are based on the GPL part of the
- + official realtek driver.
- +
- + Parts of this driver are based on the rtl8180 driver skeleton
- + from Patric Schenke & Andres Salomon.
- +
- + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
- +
- + We want to tanks the Authors of those projects and the Ndiswrapper
- + project Authors.
- +*/
- +
- +#include "r8180_93cx6.h"
- +
- +void eprom_cs(struct net_device *dev, short bit)
- +{
- + if(bit)
- + write_nic_byte(dev, EPROM_CMD,
- + (1<<EPROM_CS_SHIFT) | \
- + read_nic_byte(dev, EPROM_CMD)); //enable EPROM
- + else
- + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
- + &~(1<<EPROM_CS_SHIFT)); //disable EPROM
- +
- + force_pci_posting(dev);
- + udelay(EPROM_DELAY);
- +}
- +
- +
- +void eprom_ck_cycle(struct net_device *dev)
- +{
- + write_nic_byte(dev, EPROM_CMD,
- + (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
- + force_pci_posting(dev);
- + udelay(EPROM_DELAY);
- + write_nic_byte(dev, EPROM_CMD,
- + read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
- + force_pci_posting(dev);
- + udelay(EPROM_DELAY);
- +}
- +
- +
- +void eprom_w(struct net_device *dev,short bit)
- +{
- + if(bit)
- + write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
- + read_nic_byte(dev,EPROM_CMD));
- + else
- + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
- + &~(1<<EPROM_W_SHIFT));
- +
- + force_pci_posting(dev);
- + udelay(EPROM_DELAY);
- +}
- +
- +
- +short eprom_r(struct net_device *dev)
- +{
- + short bit;
- +
- + bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
- + udelay(EPROM_DELAY);
- +
- + if(bit) return 1;
- + return 0;
- +}
- +
- +
- +void eprom_send_bits_string(struct net_device *dev, short b[], int len)
- +{
- + int i;
- +
- + for(i=0; i<len; i++){
- + eprom_w(dev, b[i]);
- + eprom_ck_cycle(dev);
- + }
- +}
- +
- +
- +u32 eprom_read(struct net_device *dev, u32 addr)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + short read_cmd[]={1,1,0};
- + short addr_str[8];
- + int i;
- + int addr_len;
- + u32 ret;
- +
- + ret=0;
- + //enable EPROM programming
- + write_nic_byte(dev, EPROM_CMD,
- + (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
- + force_pci_posting(dev);
- + udelay(EPROM_DELAY);
- +
- + if (priv->epromtype==EPROM_93c56){
- + addr_str[7]=addr & 1;
- + addr_str[6]=addr & (1<<1);
- + addr_str[5]=addr & (1<<2);
- + addr_str[4]=addr & (1<<3);
- + addr_str[3]=addr & (1<<4);
- + addr_str[2]=addr & (1<<5);
- + addr_str[1]=addr & (1<<6);
- + addr_str[0]=addr & (1<<7);
- + addr_len=8;
- + }else{
- + addr_str[5]=addr & 1;
- + addr_str[4]=addr & (1<<1);
- + addr_str[3]=addr & (1<<2);
- + addr_str[2]=addr & (1<<3);
- + addr_str[1]=addr & (1<<4);
- + addr_str[0]=addr & (1<<5);
- + addr_len=6;
- + }
- + eprom_cs(dev, 1);
- + eprom_ck_cycle(dev);
- + eprom_send_bits_string(dev, read_cmd, 3);
- + eprom_send_bits_string(dev, addr_str, addr_len);
- +
- + //keep chip pin D to low state while reading.
- + //I'm unsure if it is necessary, but anyway shouldn't hurt
- + eprom_w(dev, 0);
- +
- + for(i=0;i<16;i++){
- + //eeprom needs a clk cycle between writing opcode&adr
- + //and reading data. (eeprom outs a dummy 0)
- + eprom_ck_cycle(dev);
- + ret |= (eprom_r(dev)<<(15-i));
- + }
- +
- + eprom_cs(dev, 0);
- + eprom_ck_cycle(dev);
- +
- + //disable EPROM programming
- + write_nic_byte(dev, EPROM_CMD,
- + (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
- + return ret;
- +}
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_93cx6.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_93cx6.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,46 @@
- +/*
- + This is part of rtl8187 OpenSource driver
- + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +
- + Parts of this driver are based on the GPL part of the official realtek driver
- + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
- + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
- +
- + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
- +*/
- +
- +/*This files contains card eeprom (93c46 or 93c56) programming routines*/
- +/*memory is addressed by WORDS*/
- +
- +#include "r8187.h"
- +#include "r8180_hw.h"
- +
- +#define EPROM_DELAY 10
- +
- +#define EPROM_ANAPARAM_ADDRLWORD 0xd
- +#define EPROM_ANAPARAM_ADDRHWORD 0xe
- +
- +#define EPROM_CHANNEL_PLAN 0x3 //0x6>>1
- +//0x77 BIT[0]0:use gpio 1 bit 1, 1:use gpio 1 bit 2.
- +#define EPROM_SELECT_GPIO (0x77 >> 1)
- +//#define EEPROM_COUNTRY_CODE 0x2E//87se channel plan is here
- +
- +#define EPROM_RFCHIPID 0x6
- +#define EPROM_TXPW_BASE 0x05
- +#define EPROM_RFCHIPID_RTL8225U 5
- +#define EPROM_RFCHIPID_RTL8225U_VF 6
- +#define EPROM_RF_PARAM 0x4
- +#define EPROM_CONFIG2 0xc
- +
- +#define EPROM_VERSION 0x1E
- +#define MAC_ADR 0x7
- +
- +#define CIS 0x18
- +
- +#define EPROM_TXPW0 0x16
- +#define EPROM_TXPW2 0x1b
- +#define EPROM_TXPW1 0x3d
- +
- +
- +u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,882 @@
- +/*++
- +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
- +
- +Module Name:
- + r8180_dig.c
- +
- +Abstract:
- + Hardware dynamic mechanism for RTL8187B
- +
- +Major Change History:
- + When Who What
- + ---------- --------------- -------------------------------
- + 2006-11-15 david Created
- +
- +Notes:
- + This file is ported from RTL8187B Windows driver.
- +
- +
- +--*/
- +#include "r8180_dm.h"
- +#include "r8180_hw.h"
- +#include "r8180_rtl8225.h"
- +
- +//================================================================================
- +// Local Constant.
- +//================================================================================
- +#define Z1_HIPWR_UPPER_TH 99
- +#define Z1_HIPWR_LOWER_TH 70
- +#define Z2_HIPWR_UPPER_TH 99
- +#define Z2_HIPWR_LOWER_TH 90
- +
- +bool CheckDig(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- +
- + if(ieee->state != IEEE80211_LINKED)
- + return false;
- +
- + if(priv->card_8187 == NIC_8187B) {
- + //
- + // We need to schedule dig workitem on either of the below mechanisms.
- + // By Bruce, 2007-06-01.
- + //
- + if(!priv->bDigMechanism && !priv->bCCKThMechanism)
- + return false;
- +
- + if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
- + return false;
- + } else {
- + if(!priv->bDigMechanism)
- + return false;
- +
- + if(priv->CurrentOperaRate < 48)
- + return false;
- + }
- + return true;
- +}
- +
- +
- +//
- +// Description:
- +// Implementation of DIG for Zebra and Zebra2.
- +//
- +void DIG_Zebra(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + //PHAL_DATA_8187 pHalData = GetHalData8187(Adapter);
- + u16 CCKFalseAlarm, OFDMFalseAlarm;
- + u16 OfdmFA1, OfdmFA2;
- + int InitialGainStep = 7; // The number of initial gain stages.
- + int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
- +
- +// printk("---------> DIG_Zebra()\n");
- +
- + //Read only 1 byte because of HW bug. This is a temporal modification. Joseph
- + // Modify by Isaiah 2006-06-27
- + if(priv->card_8187_Bversion == VERSION_8187B_B)
- + {
- + CCKFalseAlarm = 0;
- + OFDMFalseAlarm = (u16)(priv->FalseAlarmRegValue);
- + OfdmFA1 = 0x01;
- + OfdmFA2 = priv->RegDigOfdmFaUpTh;
- + }
- + else
- + {
- + CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
- + OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
- + OfdmFA1 = 0x15;
- + //OfdmFA2 = 0xC00;
- + OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
- + }
- +
- +// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
- +// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
- +
- +
- +
- + // The number of initial gain steps is different, by Bruce, 2007-04-13.
- + if(priv->card_8187 == NIC_8187) {
- + if (priv->InitialGain == 0 ) //autoDIG
- + {
- + switch( priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + priv->InitialGain = 5; // m74dBm;
- + break;
- + case RF_ZEBRA2:
- + priv->InitialGain = 4; // m78dBm;
- + break;
- + default:
- + priv->InitialGain = 5; // m74dBm;
- + break;
- + }
- + }
- + InitialGainStep = 7;
- + if(priv->InitialGain > 7)
- + priv->InitialGain = 5;
- + LowestGainStage = 4;
- + } else {
- + if (priv->InitialGain == 0 ) //autoDIG
- + { // Advised from SD3 DZ, by Bruce, 2007-06-05.
- + priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
- + }
- + if(priv->card_8187_Bversion != VERSION_8187B_B)
- + { // Advised from SD3 DZ, by Bruce, 2007-06-05.
- + OfdmFA1 = 0x20;
- + }
- + InitialGainStep = 8;
- + LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
- + }
- +
- + if (OFDMFalseAlarm > OfdmFA1)
- + {
- + if (OFDMFalseAlarm > OfdmFA2)
- + {
- + priv->DIG_NumberFallbackVote++;
- + if (priv->DIG_NumberFallbackVote >1)
- + {
- + //serious OFDM False Alarm, need fallback
- + // By Bruce, 2007-03-29.
- + // if (pHalData->InitialGain < 7) // In 87B, m66dBm means State 7 (m74dBm)
- + if (priv->InitialGain < InitialGainStep)
- + {
- + priv->InitialGain = (priv->InitialGain + 1);
- + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
- + //printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
- + UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
- + }
- + priv->DIG_NumberFallbackVote = 0;
- + priv->DIG_NumberUpgradeVote=0;
- + }
- + }
- + else
- + {
- + if (priv->DIG_NumberFallbackVote)
- + priv->DIG_NumberFallbackVote--;
- + }
- + priv->DIG_NumberUpgradeVote=0;
- + }
- + else //OFDM False Alarm < 0x15
- + {
- + if (priv->DIG_NumberFallbackVote)
- + priv->DIG_NumberFallbackVote--;
- + priv->DIG_NumberUpgradeVote++;
- +
- + if (priv->DIG_NumberUpgradeVote>9)
- + {
- + if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
- + {
- + priv->InitialGain = (priv->InitialGain - 1);
- + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
- + //printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
- + UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
- + }
- + priv->DIG_NumberFallbackVote = 0;
- + priv->DIG_NumberUpgradeVote=0;
- + }
- + }
- +
- +// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
- +// printk("<--------- DIG_Zebra()\n");
- +}
- +
- +//
- +// Description:
- +// Dispatch DIG implementation according to RF.
- +//
- +void DynamicInitGain(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
- + //case RF_ZEBRA4:
- + DIG_Zebra(dev);
- + break;
- +
- + default:
- + printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
- + break;
- + }
- +}
- +
- +// By Bruce, 2007-03-29.
- +//
- +// Description:
- +// Dispatch CCK Power Detection implementation according to RF.
- +//
- +void DynamicCCKThreshold(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + u16 CCK_Up_Th;
- + u16 CCK_Lw_Th;
- + u16 CCKFalseAlarm;
- +
- + printk("=====>DynamicCCKThreshold()\n");
- +
- + CCK_Up_Th = priv->CCKUpperTh;
- + CCK_Lw_Th = priv->CCKLowerTh;
- + CCKFalseAlarm = (u16)((priv->FalseAlarmRegValue & 0x0000ffff) >> 8); // We only care about the higher byte.
- + printk("DynamicCCKThreshold(): CCK Upper Threshold: 0x%02X, Lower Threshold: 0x%02X, CCKFalseAlarmHighByte: 0x%02X\n", CCK_Up_Th, CCK_Lw_Th, CCKFalseAlarm);
- +
- + if(priv->StageCCKTh < 3 && CCKFalseAlarm >= CCK_Up_Th)
- + {
- + priv->StageCCKTh ++;
- + UpdateCCKThreshold(dev);
- + }
- + else if(priv->StageCCKTh > 0 && CCKFalseAlarm <= CCK_Lw_Th)
- + {
- + priv->StageCCKTh --;
- + UpdateCCKThreshold(dev);
- + }
- +
- + printk("<=====DynamicCCKThreshold()\n");
- +}
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void rtl8180_hw_dig_wq (struct work_struct *work)
- +{
- + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
- + struct net_device *dev = ieee->dev;
- +#else
- +void rtl8180_hw_dig_wq(struct net_device *dev)
- +{
- + // struct r8180_priv *priv = ieee80211_priv(dev);
- +#endif
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + // Read CCK and OFDM False Alarm.
- + if(priv->card_8187_Bversion == VERSION_8187B_B) {
- + // Read only 1 byte because of HW bug. This is a temporal modification. Joseph
- + // Modify by Isaiah 2006-06-27
- + priv->FalseAlarmRegValue = (u32)read_nic_byte(dev, (OFDM_FALSE_ALARM+1));
- + } else {
- + priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
- + }
- +
- + // Adjust Initial Gain dynamically.
- + if(priv->bDigMechanism) {
- + DynamicInitGain(dev);
- + }
- +
- + //
- + // Move from DynamicInitGain to be independent of the OFDM DIG mechanism, by Bruce, 2007-06-01.
- + //
- + if(priv->card_8187 == NIC_8187B) {
- + // By Bruce, 2007-03-29.
- + // Dynamically update CCK Power Detection Threshold.
- + if(priv->bCCKThMechanism)
- + {
- + DynamicCCKThreshold(dev);
- + }
- + }
- +}
- +
- +void SetTxPowerLevel8187(struct net_device *dev, short chan)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + rtl8225_SetTXPowerLevel(dev,chan);
- + break;
- +
- + case RF_ZEBRA2:
- + //case RF_ZEBRA4:
- + rtl8225z2_SetTXPowerLevel(dev,chan);
- + break;
- + }
- +}
- +
- +//
- +// Description:
- +// Check if input power signal strength exceeds maximum input power threshold
- +// of current HW.
- +// If yes, we set our HW to high input power state:
- +// RX: always force TR switch to SW Tx mode to reduce input power.
- +// TX: turn off smaller Tx output power (see RtUsbCheckForHang).
- +//
- +// If no, we restore our HW to normal input power state:
- +/// RX: restore TR switch to HW controled mode.
- +// TX: restore TX output power (see RtUsbCheckForHang).
- +//
- +// TODO:
- +// 1. Tx power control shall not be done in Platform-dependent timer (e.g. RtUsbCheckForHang).
- +// 2. Allow these threshold adjustable by RF SD.
- +//
- +void DoRxHighPower(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + TR_SWITCH_STATE TrSwState;
- + u16 HiPwrUpperTh = 0;
- + u16 HiPwrLowerTh = 0;
- + u16 RSSIHiPwrUpperTh = 0;
- + u16 RSSIHiPwrLowerTh = 0;
- +
- + //87S remove TrSwitch mechanism
- + if((priv->card_8187 == NIC_8187B)||(priv->card_8187 == NIC_8187)) {
- +
- + //printk("----> DoRxHighPower()\n");
- +
- + //
- + // Get current TR switch setting.
- + //
- + //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_TR_SWITCH, (pu1Byte)(&TrSwState));
- + TrSwState = priv->TrSwitchState;
- +
- + //
- + // Determine threshold according to RF type.
- + //
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + HiPwrUpperTh = Z1_HIPWR_UPPER_TH;
- + HiPwrLowerTh = Z1_HIPWR_LOWER_TH;
- + printk("DoRxHighPower(): RF_ZEBRA, Upper Threshold: %d LOWER Threshold: %d\n",
- + HiPwrUpperTh, HiPwrLowerTh);
- + break;
- +
- + case RF_ZEBRA2:
- + if((priv->card_8187 == NIC_8187)) {
- + HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
- + HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
- + } else {
- + // By Bruce, 2007-04-11.
- + // HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
- + // HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
- +
- + HiPwrUpperTh = priv->Z2HiPwrUpperTh;
- + HiPwrLowerTh = priv->Z2HiPwrLowerTh;
- + HiPwrUpperTh = HiPwrUpperTh * 10;
- + HiPwrLowerTh = HiPwrLowerTh * 10;
- +
- + RSSIHiPwrUpperTh = priv->Z2RSSIHiPwrUpperTh;
- + RSSIHiPwrLowerTh = priv->Z2RSSIHiPwrLowerTh;
- + //printk("DoRxHighPower(): RF_ZEBRA2, Upper Threshold: %d LOWER Threshold: %d, RSSI Upper Th: %d, RSSI Lower Th: %d\n",HiPwrUpperTh, HiPwrLowerTh, RSSIHiPwrUpperTh, RSSIHiPwrLowerTh);
- + }
- + break;
- +
- + default:
- + printk("DoRxHighPower(): Unknown RFChipID(%d), UndecoratedSmoothedSS(%d), TrSwState(%d)!!!\n",
- + priv->rf_chip, priv->UndecoratedSmoothedSS, TrSwState);
- + return;
- + break;
- + }
- +
- + /*printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",\
- + priv->UndecoratedSmoothedSS, priv->CurCCKRSSI);
- + */
- + if((priv->card_8187 == NIC_8187)) {
- + //
- + // Perform Rx part High Power Mechanism by UndecoratedSmoothedSS.
- + //
- + if (priv->UndecoratedSmoothedSS > HiPwrUpperTh)
- + { // High input power state.
- + if( priv->TrSwitchState == TR_HW_CONTROLLED )
- + {
- + /* printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d \n", \
- + priv->UndecoratedSmoothedSS);
- + // printk(">>>>>>>>>> TR_SW_TX\n");
- + */
- + write_nic_byte(dev, RFPinsSelect,
- + (u8)(priv->wMacRegRfPinsSelect | TR_SW_MASK_8187 ));
- + write_nic_byte(dev, RFPinsOutput,
- + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
- + priv->TrSwitchState = TR_SW_TX;
- + priv->bToUpdateTxPwr = true;
- + }
- + }
- + else if (priv->UndecoratedSmoothedSS < HiPwrLowerTh)
- + { // Normal input power state.
- + if( priv->TrSwitchState == TR_SW_TX)
- + {
- + /* printk("<<<<<<<<<<<Set TR switch to hardware control UndecoratedSmoothedSS:%d \n", \
- + priv->UndecoratedSmoothedSS);
- + // printk("<<<<<<<<<< TR_HW_CONTROLLED\n");
- + */
- + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
- + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
- + priv->TrSwitchState = TR_HW_CONTROLLED;
- + priv->bToUpdateTxPwr = true;
- + }
- + }
- + }else {
- + /*printk("=====>TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
- + //printk("UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",priv->UndecoratedSmoothedSS, priv->CurCCKRSSI); */
- + // Asked by SD3 DZ, by Bruce, 2007-04-12.
- + if(TrSwState == TR_HW_CONTROLLED)
- + {
- + if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
- + (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
- + {
- + //printk("===============================> high power!\n");
- + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect|TR_SW_MASK_8187 ));
- + write_nic_byte(dev, RFPinsOutput,
- + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
- + priv->TrSwitchState = TR_SW_TX;
- + priv->bToUpdateTxPwr = true;
- + }
- + }
- + else
- + {
- + if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
- + (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
- + {
- + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
- + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
- + priv->TrSwitchState = TR_HW_CONTROLLED;
- + priv->bToUpdateTxPwr = true;
- + }
- + }
- + //printk("<=======TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
- + }
- + //printk("<---- DoRxHighPower()\n");
- + }
- +}
- +
- +
- +//
- +// Description:
- +// Callback function of UpdateTxPowerWorkItem.
- +// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
- +// We update Tx power of current channel again.
- +//
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void rtl8180_tx_pw_wq (struct work_struct *work)
- +{
- + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
- + struct net_device *dev = ieee->dev;
- +#else
- +void rtl8180_tx_pw_wq(struct net_device *dev)
- +{
- + // struct r8180_priv *priv = ieee80211_priv(dev);
- +#endif
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + //printk("----> UpdateTxPowerWorkItemCallback()\n");
- +
- + if(priv->bToUpdateTxPwr)
- + {
- + //printk("DoTxHighPower(): schedule UpdateTxPowerWorkItem......\n");
- + priv->bToUpdateTxPwr = false;
- + SetTxPowerLevel8187(dev, priv->chan);
- + }
- +
- + DoRxHighPower(dev);
- + //printk("<---- UpdateTxPowerWorkItemCallback()\n");
- +}
- +
- +//
- +// Description:
- +// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
- +//
- +bool CheckHighPower(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- +
- + if(!priv->bRegHighPowerMechanism)
- + {
- + return false;
- + }
- +
- + if((ieee->state == IEEE80211_LINKED_SCANNING)||(ieee->state == IEEE80211_MESH_SCANNING))
- + {
- + return false;
- + }
- +
- + return true;
- +}
- +
- +#ifdef SW_ANTE_DIVERSITY
- +
- +#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
- +
- +void
- +SwAntennaDiversityRxOk8185(
- + struct net_device *dev,
- + u8 SignalStrength
- + )
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + //printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
- +
- + priv->AdRxOkCnt++;
- +
- + if( priv->AdRxSignalStrength != -1)
- + {
- + priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
- + }
- + else
- + { // Initialization case.
- + priv->AdRxSignalStrength = SignalStrength;
- + }
- +
- + //printk("====>pkt rcvd by %d\n", priv->LastRxPktAntenna);
- + if( priv->LastRxPktAntenna ) //Main antenna.
- + priv->AdMainAntennaRxOkCnt++;
- + else // Aux antenna.
- + priv->AdAuxAntennaRxOkCnt++;
- + //printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
- +}
- +
- +//
- +// Description: Change Antenna Switch.
- +//
- +bool
- +SetAntenna8185(
- + struct net_device *dev,
- + u8 u1bAntennaIndex
- + )
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + bool bAntennaSwitched = false;
- +
- +// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
- +
- + switch(u1bAntennaIndex)
- + {
- + case 0://main antenna
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + case RF_ZEBRA2:
- + //case RF_ZEBRA4:
- + // Tx Antenna.
- + write_nic_byte(dev, ANTSEL, 0x03); // Config TX antenna.
- +
- + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x01009b90); // Config CCK RX antenna.
- + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x5c8D); // Config OFDM RX antenna.
- +
- + // Rx CCK .
- + write_nic_byte(dev, 0x7f, ((0x01009b90 & 0xff000000) >> 24));
- + write_nic_byte(dev, 0x7e, ((0x01009b90 & 0x00ff0000) >> 16));
- + write_nic_byte(dev, 0x7d, ((0x01009b90 & 0x0000ff00) >> 8));
- + write_nic_byte(dev, 0x7c, ((0x01009b90 & 0x000000ff) >> 0));
- +
- + // Rx OFDM.
- + write_nic_byte(dev, 0x7f, ((0x00005c8D & 0xff000000) >> 24));
- + write_nic_byte(dev, 0x7e, ((0x00005c8D & 0x00ff0000) >> 16));
- + write_nic_byte(dev, 0x7d, ((0x00005c8D & 0x0000ff00) >> 8));
- + write_nic_byte(dev, 0x7c, ((0x00005c8D & 0x000000ff) >> 0));
- +
- + bAntennaSwitched = true;
- + break;
- +
- + default:
- + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
- + break;
- + }
- + break;
- +
- + case 1:
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + case RF_ZEBRA2:
- + //case RF_ZEBRA4:
- + // Tx Antenna.
- + write_nic_byte(dev, ANTSEL, 0x00); // Config TX antenna.
- +
- + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x0100bb90); // Config CCK RX antenna.
- + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x548D); // Config OFDM RX antenna.
- +
- + // Rx CCK.
- + write_nic_byte(dev, 0x7f, ((0x0100bb90 & 0xff000000) >> 24));
- + write_nic_byte(dev, 0x7e, ((0x0100bb90 & 0x00ff0000) >> 16));
- + write_nic_byte(dev, 0x7d, ((0x0100bb90 & 0x0000ff00) >> 8));
- + write_nic_byte(dev, 0x7c, ((0x0100bb90 & 0x000000ff) >> 0));
- +
- + // Rx OFDM.
- + write_nic_byte(dev, 0x7f, ((0x0000548D & 0xff000000) >> 24));
- + write_nic_byte(dev, 0x7e, ((0x0000548D & 0x00ff0000) >> 16));
- + write_nic_byte(dev, 0x7d, ((0x0000548D & 0x0000ff00) >> 8));
- + write_nic_byte(dev, 0x7c, ((0x0000548D & 0x000000ff) >> 0));
- +
- + bAntennaSwitched = true;
- + break;
- +
- + default:
- + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
- + break;
- + }
- + break;
- +
- + default:
- + printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
- + break;
- + }
- +
- + if(bAntennaSwitched)
- + {
- + priv->CurrAntennaIndex = u1bAntennaIndex;
- + }
- +
- +// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
- +
- + return bAntennaSwitched;
- +}
- +
- +//
- +// Description: Toggle Antenna switch.
- +//
- +bool SwitchAntenna(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + bool bResult = false;
- +
- + if(priv->CurrAntennaIndex == 0)
- + {
- + bResult = SetAntenna8185(dev, 1);
- + if(priv->ieee80211->state == IEEE80211_LINKED)
- + printk("Switching to Aux antenna 1 \n");
- + }
- + else
- + {
- + bResult = SetAntenna8185(dev, 0);
- + if(priv->ieee80211->state == IEEE80211_LINKED)
- + printk("Switching to Main antenna 0 \n");
- + }
- +
- + return bResult;
- +}
- +
- +//
- +// Description:
- +// Engine of SW Antenna Diversity mechanism.
- +// Since 8187 has no Tx part information,
- +// this implementation is only dependend on Rx part information.
- +//
- +// 2006.04.17, by rcnjko.
- +//
- +void SwAntennaDiversity(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + //bool bSwCheckSS=false;
- + bool bSwCheckSS=true;//open the SignalStrength check if not switched by rx ok pkt.
- +
- +// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
- +
- +//by amy 080312
- + if(bSwCheckSS){
- + priv->AdTickCount++;
- +
- + //printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod);
- + //printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
- + }
- +// priv->AdTickCount++;//-by amy 080312
- +
- + // Case 1. No Link.
- + if(priv->ieee80211->state != IEEE80211_LINKED){
- + //printk("SwAntennaDiversity(): Case 1. No Link.\n");
- +
- + priv->bAdSwitchedChecking = false;
- + // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
- + SwitchAntenna(dev);
- + }
- + // Case 2. Linked but no packet received.
- + else if(priv->AdRxOkCnt == 0){
- + printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
- +
- + priv->bAdSwitchedChecking = false;
- + SwitchAntenna(dev);
- + }
- + // Case 3. Evaluate last antenna switch action in case4. and undo it if necessary.
- + else if(priv->bAdSwitchedChecking == true){
- + //printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
- +
- + priv->bAdSwitchedChecking = false;
- +
- + // Adjust Rx signal strength threashold.
- + priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
- +
- + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
- + if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched){
- + // Rx signal strength is not improved after we swtiched antenna. => Swich back.
- + printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
- +
- + //by amy 080312
- + // Increase Antenna Diversity checking period due to bad decision.
- + priv->AdCheckPeriod *= 2;
- + //by amy 080312
- + //
- + // Increase Antenna Diversity checking period.
- + if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
- + priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
- +
- + // Wrong deceision => switch back.
- + SwitchAntenna(dev);
- + }else{ // Rx Signal Strength is improved.
- + printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
- +
- + // Reset Antenna Diversity checking period to its min value.
- + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- + }
- +
- + //printk("SwAntennaDiversity(): AdRxSsThreshold: %ld, AdCheckPeriod: %d\n",
- + // priv->AdRxSsThreshold, priv->AdCheckPeriod);
- + }
- + // Case 4. Evaluate if we shall switch antenna now.
- + // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
- + else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
- + {
- + //printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
- +
- + priv->AdTickCount = 0;
- +
- + //
- + // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
- + // evaluate signal strength.
- + // The following operation can overcome the disability of CCA on both two antennas
- + // When signal strength was extremely low or high.
- + // 2008.01.30.
- + //
- +
- + //
- + // Evaluate RxOk count from each antenna if we shall switch default antenna now.
- + // Added by Roger, 2008.02.21.
- +
- + //{by amy 080312
- + if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)){
- + // We set Main antenna as default but RxOk count was less than Aux ones.
- +
- + printk("SwAntennaDiversity(): Main antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
- +
- + // Switch to Aux antenna.
- + SwitchAntenna(dev);
- + priv->bHWAdSwitched = true;
- + }else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)){
- + // We set Aux antenna as default but RxOk count was less than Main ones.
- +
- + printk("SwAntennaDiversity(): Aux antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
- +
- + // Switch to Main antenna.
- + SwitchAntenna(dev);
- + priv->bHWAdSwitched = true;
- + }else{// Default antenna is better.
- +
- + printk("SwAntennaDiversity(): Current Antenna %d is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
- +
- + // Still need to check current signal strength.
- + priv->bHWAdSwitched = false;
- + }
- + //
- + // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
- + // didn't changed by HW evaluation.
- + // 2008.02.27.
- + //
- + // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
- + // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
- + // but AdRxSignalStrength is less than main.
- + // Our guess is that main antenna have lower throughput and get many change
- + // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
- + //
- + if( (!priv->bHWAdSwitched) && (bSwCheckSS)){
- + //by amy 080312}
- +
- + // Evaluate Rx signal strength if we shall switch antenna now.
- + if(priv->AdRxSignalStrength < priv->AdRxSsThreshold){
- + // Rx signal strength is weak => Switch Antenna.
- + printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
- +
- + priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
- + priv->bAdSwitchedChecking = true;
- +
- + SwitchAntenna(dev);
- + }else{ // Rx signal strength is OK.
- + printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
- +
- + priv->bAdSwitchedChecking = false;
- + // Increase Rx signal strength threashold if necessary.
- + if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
- + priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
- + {
- + priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
- + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
- + }
- +
- + // Reduce Antenna Diversity checking period if possible.
- + if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
- + {
- + priv->AdCheckPeriod /= 2;
- + }
- + }
- + }
- + }
- +//by amy 080312
- + // Reset antenna diversity Rx related statistics.
- + priv->AdRxOkCnt = 0;
- + priv->AdMainAntennaRxOkCnt = 0;
- + priv->AdAuxAntennaRxOkCnt = 0;
- +//by amy 080312
- +
- +// priv->AdRxOkCnt = 0;//-by amy 080312
- +
- + //printk("-SwAntennaDiversity()\n");
- +}
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void SwAntennaWorkItemCallback(struct work_struct *work)
- +{
- + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, SwAntennaWorkItem.work);
- + struct net_device *dev = ieee->dev;
- +#else
- +void SwAntennaWorkItemCallback(struct net_device *dev)
- +{
- +#endif
- + //printk("==>%s \n", __func__);
- + SwAntennaDiversity(dev);
- +}
- +
- +//
- +// Description: Timer callback function of SW Antenna Diversity.
- +//
- +void SwAntennaDiversityTimerCallback(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + RT_RF_POWER_STATE rtState;
- +
- + //printk("+SwAntennaDiversityTimerCallback()\n");
- +
- + //
- + // We do NOT need to switch antenna while RF is off.
- + // 2007.05.09, added by Roger.
- + //
- + rtState = priv->eRFPowerState;
- + do{
- + if (rtState == eRfOff){
- +// printk("SwAntennaDiversityTimer - RF is OFF.\n");
- + break;
- + }else if (rtState == eRfSleep){
- + // Don't access BB/RF under Disable PLL situation.
- + //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
- + break;
- + }
- +
- + queue_work(priv->ieee80211->wq,(void *)&priv->ieee80211->SwAntennaWorkItem);
- +
- + }while(false);
- +
- + if(priv->up){
- + //priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
- + //add_timer(&priv->SwAntennaDiversityTimer);
- + mod_timer(&priv->SwAntennaDiversityTimer, jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD));
- + }
- +
- +}
- +#endif
- +
- +
- +
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_dm.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_dm.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,38 @@
- +/*
- + Hardware dynamic mechanism for RTL8187B.
- +Notes:
- + This file is ported from RTL8187B Windows driver
- +*/
- +
- +#ifndef R8180_DM_H
- +#define R8180_DM_H
- +
- +#include "r8187.h"
- +
- +bool CheckDig(struct net_device *dev);
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void rtl8180_hw_dig_wq (struct work_struct *work);
- +#else
- +void rtl8180_hw_dig_wq(struct net_device *dev);
- +#endif
- +
- +bool CheckHighPower(struct net_device *dev);
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void rtl8180_tx_pw_wq (struct work_struct *work);
- +#else
- +void rtl8180_tx_pw_wq(struct net_device *dev);
- +#endif
- +
- +//by lzm for antenna
- +#ifdef SW_ANTE_DIVERSITY
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void SwAntennaWorkItemCallback(struct work_struct *work);
- +#else
- +void SwAntennaWorkItemCallback(struct net_device *dev);
- +#endif
- +void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
- +void SwAntennaDiversityTimerCallback(struct net_device *dev);
- +#endif
- +//by lzm for antenna
- +
- +#endif //R8180_PM_H
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_hw.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_hw.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_hw.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_hw.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,788 @@
- +/*
- + This is part of rtl8187 OpenSource driver.
- + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +
- + Parts of this driver are based on the GPL part of the
- + official Realtek driver.
- + Parts of this driver are based on the rtl8180 driver skeleton
- + from Patric Schenke & Andres Salomon.
- + Parts of this driver are based on the Intel Pro Wireless
- + 2100 GPL driver.
- +
- + We want to tanks the Authors of those projects
- + and the Ndiswrapper project Authors.
- +*/
- +
- +/* Mariusz Matuszek added full registers definition with Realtek's name */
- +
- +/* this file contains register definitions for the rtl8187 MAC controller */
- +#ifndef R8180_HW
- +#define R8180_HW
- +
- +typedef enum _RF_TYPE_8187{
- + RF_TYPE_MIN,
- + RF_ZEBRA = 5,
- + RF_ZEBRA2, // added by Annie, 2005-08-01.
- + RF_TYPE_MAX,
- +}RF_TYPE_8187,*PRF_TYPE_8187;
- +
- +typedef enum _VERSION_8187{
- + // RTL8187
- + VERSION_8187_B, // B-cut
- + VERSION_8187_D, // D-cut
- + // RTL8187B
- + VERSION_8187B_B, // B-cut
- + VERSION_8187B_D, //D-cut //added 2007-9-14
- + VERSION_8187B_E, //E-cut //added 2007-9-14
- +}VERSION_8187,*PVERSION_8187;
- +
- +//by lzm for antenna
- +#ifdef SW_ANTE_DIVERSITY
- +#define RF_PARAM 0x19
- +#define RF_PARAM_DIGPHY_SHIFT 0
- +#define RF_PARAM_ANTBDEFAULT_SHIFT 1
- +#define EEPROM_VERSION 0x3c
- +#define EEPROM_CONFIG2 0x18
- +#define EEPROM_CS_THRESHOLD 0x2F
- +#define EEPROM_RF_PARAM 0x08
- +//// BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable.
- +#define EEPROM_SW_AD_MASK 0x0300
- +#define EEPROM_SW_AD_ENABLE 0x0100
- +//// BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
- +#define EEPROM_DEF_ANT_MASK 0x0C00
- +#define EEPROM_DEF_ANT_1 0x0400
- +
- +#define RCR_EnCS1 BIT29 // enable carrier sense method 1
- +#define RCR_EnCS2 BIT30 // enable carrier sense method 2
- +#endif
- +//by lzm for antenna
- +
- +#define RTL8187_RF_INDEX 0x8225
- +#define RTL8187_REQT_READ 0xc0
- +#define RTL8187_REQT_WRITE 0x40
- +#define RTL8187_REQ_GET_REGS 0x05
- +#define RTL8187_REQ_SET_REGS 0x05
- +
- +
- +
- +#define MAX_TX_URB 5
- +#define MAX_RX_URB 16
- +#define RX_URB_SIZE 0x9C4
- +
- +
- +
- +
- +
- +#define BB_ANTATTEN_CHAN14 0x0c
- +#define BB_ANTENNA_B 0x40
- +
- +#define BB_HOST_BANG (1<<30)
- +#define BB_HOST_BANG_EN (1<<2)
- +#define BB_HOST_BANG_CLK (1<<1)
- +#define BB_HOST_BANG_RW (1<<3)
- +#define BB_HOST_BANG_DATA 1
- +
- +#define ANAPARAM_TXDACOFF_SHIFT 27
- +#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28))
- +#define ANAPARAM_PWR0_SHIFT 28
- +#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20))
- +#define ANAPARAM_PWR1_SHIFT 20
- +
- +#define MAC0 0
- +#define MAC1 1
- +#define MAC2 2
- +#define MAC3 3
- +#define MAC4 4
- +#define MAC5 5
- +
- +#define RXFIFOCOUNT 0x10
- +#define TXFIFOCOUNT 0x12
- +#define BcnIntTime 0x74
- +#define TALLY_SEL 0xfc
- +#define BQREQ 0x13
- +
- +#define CMD 0x37
- +#define CMD_RST_SHIFT 4
- +#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
- +#define CMD_RX_ENABLE_SHIFT 3
- +#define CMD_TX_ENABLE_SHIFT 2
- +
- +#define EPROM_CMD 0x50
- +#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
- +#define EPROM_CMD_OPERATING_MODE_SHIFT 6
- +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
- +#define EPROM_CMD_CONFIG 0x3
- +#define EPROM_CMD_NORMAL 0
- +#define EPROM_CMD_LOAD 1
- +#define EPROM_CMD_PROGRAM 2
- +#define EPROM_CS_SHIFT 3
- +#define EPROM_CK_SHIFT 2
- +#define EPROM_W_SHIFT 1
- +#define EPROM_R_SHIFT 0
- +#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
- +#define INTA 0x3e
- +#define INTA_TXOVERFLOW (1<<15)
- +#define INTA_TIMEOUT (1<<14)
- +#define INTA_BEACONTIMEOUT (1<<13)
- +#define INTA_ATIM (1<<12)
- +#define INTA_BEACONDESCERR (1<<11)
- +#define INTA_BEACONDESCOK (1<<10)
- +#define INTA_HIPRIORITYDESCERR (1<<9)
- +#define INTA_HIPRIORITYDESCOK (1<<8)
- +#define INTA_NORMPRIORITYDESCERR (1<<7)
- +#define INTA_NORMPRIORITYDESCOK (1<<6)
- +#define INTA_RXOVERFLOW (1<<5)
- +#define INTA_RXDESCERR (1<<4)
- +#define INTA_LOWPRIORITYDESCERR (1<<3)
- +#define INTA_LOWPRIORITYDESCOK (1<<2)
- +#define INTA_RXCRCERR (1<<1)
- +#define INTA_RXOK (1)
- +#define INTA_MASK 0x3c
- +#define RXRING_ADDR 0xe4 // page 0
- +#define PGSELECT 0x5e
- +#define PGSELECT_PG_SHIFT 0
- +#define RX_CONF 0x44
- +#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
- +(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
- +#define RX_CHECK_BSSID_SHIFT 23
- +#define ACCEPT_PWR_FRAME_SHIFT 22
- +#define ACCEPT_MNG_FRAME_SHIFT 20
- +#define ACCEPT_CTL_FRAME_SHIFT 19
- +#define ACCEPT_DATA_FRAME_SHIFT 18
- +#define ACCEPT_ICVERR_FRAME_SHIFT 12
- +#define ACCEPT_CRCERR_FRAME_SHIFT 5
- +#define ACCEPT_BCAST_FRAME_SHIFT 3
- +#define ACCEPT_MCAST_FRAME_SHIFT 2
- +#define ACCEPT_ALLMAC_FRAME_SHIFT 0
- +#define ACCEPT_NICMAC_FRAME_SHIFT 1
- +#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
- +#define RX_FIFO_THRESHOLD_SHIFT 13
- +#define RX_FIFO_THRESHOLD_128 3
- +#define RX_FIFO_THRESHOLD_256 4
- +#define RX_FIFO_THRESHOLD_512 5
- +#define RX_FIFO_THRESHOLD_1024 6
- +#define RX_FIFO_THRESHOLD_NONE 7
- +#define RX_AUTORESETPHY_SHIFT 28
- +#define EPROM_TYPE_SHIFT 6
- +#define TX_CONF 0x40
- +#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
- +#define TX_LOOPBACK_SHIFT 17
- +#define TX_LOOPBACK_MAC 1
- +#define TX_LOOPBACK_BASEBAND 2
- +#define TX_LOOPBACK_NONE 0
- +#define TX_LOOPBACK_CONTINUE 3
- +#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
- +#define TX_LRLRETRY_SHIFT 0
- +#define R8180_MAX_RETRY 255
- +#define TX_SRLRETRY_SHIFT 8
- +#define TX_NOICV_SHIFT 19
- +#define TX_NOCRC_SHIFT 16
- +#define TX_DMA_POLLING 0xd9
- +#define TX_DMA_POLLING_BEACON_SHIFT 7
- +#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
- +#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
- +#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
- +#define TX_DMA_STOP_BEACON_SHIFT 3
- +#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
- +#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
- +#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
- +#define TX_NORMPRIORITY_RING_ADDR 0x24
- +#define TX_HIGHPRIORITY_RING_ADDR 0x28
- +#define TX_LOWPRIORITY_RING_ADDR 0x20
- +#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
- +#define MAX_RX_DMA_2048 7
- +#define MAX_RX_DMA_1024 6
- +#define MAX_RX_DMA_SHIFT 10
- +#define INT_TIMEOUT 0x48
- +#define CONFIG3_CLKRUN_SHIFT 2
- +#define CONFIG3_ANAPARAM_W_SHIFT 6
- +#define ANAPARAM 0x54
- +#define BEACON_INTERVAL 0x70
- +#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
- +(1<<6)|(1<<7)|(1<<8)|(1<<9))
- +#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
- +(1<<8)|(1<<9))
- +#define ATIM 0x72
- +#define EPROM_CS_SHIFT 3
- +#define EPROM_CK_SHIFT 2
- +#define PHY_DELAY 0x78
- +#define PHY_CONFIG 0x80
- +#define PHY_ADR 0x7c
- +#define PHY_READ 0x7e
- +#define CARRIER_SENSE_COUNTER 0x79 //byte
- +#define SECURITY 0x5f
- +#define SECURITY_WEP_TX_ENABLE_SHIFT 1
- +#define SECURITY_WEP_RX_ENABLE_SHIFT 0
- +#define SECURITY_ENCRYP_104 1
- +#define SECURITY_ENCRYP_SHIFT 4
- +#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
- +#define KEY0 0x90
- +#define CONFIG2_ANTENNA_SHIFT 6
- +#define TX_BEACON_RING_ADDR 0x4c
- +#define CONFIG0_WEP40_SHIFT 7
- +#define CONFIG0_WEP104_SHIFT 6
- +#define AGCRESET_SHIFT 5
- +
- +
- +
- +/*
- + * Operational registers offsets in PCI (I/O) space.
- + * RealTek names are used.
- + */
- +
- +#define IDR0 0x0000
- +#define IDR1 0x0001
- +#define IDR2 0x0002
- +#define IDR3 0x0003
- +#define IDR4 0x0004
- +#define IDR5 0x0005
- +
- +/* 0x0006 - 0x0007 - reserved */
- +
- +#define MAR0 0x0008
- +#define MAR1 0x0009
- +#define MAR2 0x000A
- +#define MAR3 0x000B
- +#define MAR4 0x000C
- +#define MAR5 0x000D
- +#define MAR6 0x000E
- +#define MAR7 0x000F
- +
- +/* 0x0010 - 0x0017 - reserved */
- +
- +#define TSFTR 0x0018
- +#define TSFTR_END 0x001F
- +
- +#define TLPDA 0x0020
- +#define TLPDA_END 0x0023
- +#define TNPDA 0x0024
- +#define TNPDA_END 0x0027
- +#define THPDA 0x0028
- +#define THPDA_END 0x002B
- +
- +#define BRSR_8187 0x002C
- +#define BRSR_8187_END 0x002D
- +#define BRSR_8187B 0x0034
- +#define BRSR_8187B_END 0x0035
- +
- +#define BSSID 0x002E
- +#define BSSID_END 0x0033
- +
- +/* 0x0034 - 0x0034 - reserved */
- +
- +/* 0x0038 - 0x003B - reserved */
- +
- +#define IMR 0x003C
- +#define IMR_END 0x003D
- +
- +#define ISR 0x003E
- +#define ISR_END 0x003F
- +
- +#define TCR 0x0040
- +#define TCR_END 0x0043
- +
- +#define RCR 0x0044
- +#define RCR_END 0x0047
- +
- +#define TimerInt 0x0048
- +#define TimerInt_END 0x004B
- +
- +#define TBDA 0x004C
- +#define TBDA_END 0x004F
- +
- +#define CR9346 0x0050
- +
- +#define CONFIG0 0x0051
- +#define CONFIG1 0x0052
- +#define CONFIG2 0x0053
- +
- +#define ANA_PARAM 0x0054
- +#define ANA_PARAM_END 0x0x0057
- +
- +#define MSR 0x0058
- +
- +#define CONFIG3 0x0059
- +#define CONFIG4 0x005A
- +
- +#define TESTR 0x005B
- +
- +/* 0x005C - 0x005D - reserved */
- +#define TFPC_AC 0x005C
- +#define PSR 0x005E
- +
- +#define SCR 0x005F
- +
- +/* 0x0060 - 0x006F - reserved */
- +#define ANA_PARAM2 0x0060
- +#define ANA_PARAM2_END 0x0063
- +
- +#define BcnIntv 0x0070
- +#define BcnItv_END 0x0071
- +
- +#define AtimWnd 0x0072
- +#define AtimWnd_END 0x0073
- +
- +#define BintrItv 0x0074
- +#define BintrItv_END 0x0075
- +
- +#define AtimtrItv 0x0076
- +#define AtimtrItv_END 0x0077
- +
- +#define PhyDelay 0x0078
- +
- +//#define CRCount 0x0079
- +
- +#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us.
- +/* 0x007A - 0x007B - reserved */
- +#define BBAddr 0x007C
- +
- +
- +#define PhyAddr 0x007C
- +#define PhyDataW 0x007D
- +#define PhyDataR 0x007E
- +#define RF_Ready 0x007F
- +
- +#define PhyCFG 0x0080
- +#define PhyCFG_END 0x0083
- +
- +/* following are for rtl8185 */
- +#define RFPinsOutput 0x80
- +#define RFPinsEnable 0x82
- +#define RF_TIMING 0x8c
- +#define RFPinsSelect 0x84
- +#define ANAPARAM2 0x60
- +#define RF_PARA 0x88
- +#define RFPinsInput 0x86
- +#define GP_ENABLE 0x90
- +#define GPIO 0x91
- +#define HSSI_PARA 0x94 // HSS Parameter
- +#define SW_CONTROL_GPIO 0x400
- +#define CCK_TXAGC 0x9d
- +#define OFDM_TXAGC 0x9e
- +#define ANTSEL 0x9f
- +#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02
- +#define WPA_CONFIG 0xb0
- +#define TX_AGC_CTL 0x9c
- +#define TX_AGC_CTL_PER_PACKET_TXAGC 0x01
- +#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
- +#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
- +#define TX_AGC_CTL_FEEDBACK_ANT 2
- +#define RESP_RATE 0x34
- +#define SIFS 0xb4
- +#define DIFS 0xb5
- +#define EIFS_8187 0x35
- +#define EIFS_8187B 0x2D
- +#define SLOT 0xb6
- +#define CW_VAL 0xbd
- +#define CW_CONF 0xbc
- +#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02
- +#define CW_CONF_PERPACKET_CW 0x01
- +#define CW_CONF_PERPACKET_RETRY_SHIFT 1
- +#define CW_CONF_PERPACKET_CW_SHIFT 0
- +#define MAX_RESP_RATE_SHIFT 4
- +#define MIN_RESP_RATE_SHIFT 0
- +#define RATE_FALLBACK 0xbe
- +#define RATE_FALLBACK_CTL_ENABLE 0x80
- +#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
- +
- +#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
- +#define RMS 0x1EC // Rx Max Pacetk Size (0x1ec[0:12])
- +
- +/*
- + * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
- + * is set to 1
- + */
- +
- +#define Wakeup0 0x0084
- +#define Wakeup0_END 0x008B
- +
- +#define Wakeup1 0x008C
- +#define Wakeup1_END 0x0093
- +
- +#define Wakeup2LD 0x0094
- +#define Wakeup2LD_END 0x009B
- +#define Wakeup2HD 0x009C
- +#define Wakeup2HD_END 0x00A3
- +
- +#define Wakeup3LD 0x00A4
- +#define Wakeup3LD_END 0x00AB
- +#define Wakeup3HD 0x00AC
- +#define Wakeup3HD_END 0x00B3
- +
- +#define Wakeup4LD 0x00B4
- +#define Wakeup4LD_END 0x00BB
- +#define Wakeup4HD 0x00BC
- +#define Wakeup4HD_END 0x00C3
- +
- +#define CRC0 0x00C4
- +#define CRC0_END 0x00C5
- +#define CRC1 0x00C6
- +#define CRC1_END 0x00C7
- +#define CRC2 0x00C8
- +#define CRC2_END 0x00C9
- +#define CRC3 0x00CA
- +#define CRC3_END 0x00CB
- +#define CRC4 0x00CC
- +#define CRC4_END 0x00CD
- +
- +/* 0x00CE - 0x00D3 - reserved */
- +
- +
- +
- +/*
- + * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
- + * is set to 0
- + */
- +
- +/* 0x0084 - 0x008F - reserved */
- +
- +#define DK0 0x0090
- +#define DK0_END 0x009F
- +#define DK1 0x00A0
- +#define DK1_END 0x00AF
- +#define DK2 0x00B0
- +#define DK2_END 0x00BF
- +#define DK3 0x00C0
- +#define DK3_END 0x00CF
- +
- +#define GPO 0x90
- +#define GPE 0x91
- +#define GPI 0x92
- +
- +#define RFTiming 0x008C
- +#define ACM_CONTROL 0x00BF // ACM Control Registe
- +#define INT_MIG 0x00E2 // Interrupt Migration (0xE2 ~ 0xE3)
- +#define TID_AC_MAP 0x00E8 // TID to AC Mapping Register
- +
- +#define AC_VO_PARAM 0x00F0 // AC_VO Parameters Record
- +#define AC_VI_PARAM 0x00F4 // AC_VI Parameters Record
- +#define AC_BE_PARAM 0x00F8 // AC_BE Parameters Record
- +#define AC_BK_PARAM 0x00FC // AC_BK Parameters Record
- +
- +/* 0x00D0 - 0x00D3 - reserved */
- +#define CCK_FALSE_ALARM 0x00D0
- +#define OFDM_FALSE_ALARM 0x00D2
- +
- +
- +/* 0x00D4 - 0x00D7 - reserved */
- +
- +#define CONFIG5 0x00D8
- +
- +#define TPPoll 0x00D9
- +
- +/* 0x00DA - 0x00DB - reserved */
- +
- +#define CWR 0x00DC
- +#define CWR_END 0x00DD
- +
- +#define RetryCTR 0x00DE
- +
- +/* 0x00DF - 0x00E3 - reserved */
- +
- +#define RDSAR 0x00E4
- +#define RDSAR_END 0x00E7
- +
- +/* 0x00E8 - 0x00EF - reserved */
- +#define ANA_PARAM3 0x00EE
- +
- +#define FER 0x00F0
- +#define FER_END 0x00F3
- +
- +#define FEMR 0x1D4 // Function Event Mask register (0xf4 ~ 0xf7)
- +//#define FEMR 0x00F4
- +#define FEMR_END 0x00F7
- +
- +#define FPSR 0x00F8
- +#define FPSR_END 0x00FB
- +
- +#define FFER 0x00FC
- +#define FFER_END 0x00FF
- +
- +/*
- + * 0x0000 - 0x00ff is selected to page 0 when PSEn bit (bit0, PSR)
- + * is set to 2
- + */
- +#define RFSW_CTRL 0x272 // 0x272-0x273.
- +
- +
- +
- +//----------------------------------------------------------------------------
- +// 8187B AC_XX_PARAM bits
- +//----------------------------------------------------------------------------
- +#define AC_PARAM_TXOP_LIMIT_OFFSET 16
- +#define AC_PARAM_ECW_MAX_OFFSET 12
- +#define AC_PARAM_ECW_MIN_OFFSET 8
- +#define AC_PARAM_AIFS_OFFSET 0
- +
- +//----------------------------------------------------------------------------
- +// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
- +//----------------------------------------------------------------------------
- +#define VOQ_ACM_EN (0x01 << 7) //BIT7
- +#define VIQ_ACM_EN (0x01 << 6) //BIT6
- +#define BEQ_ACM_EN (0x01 << 5) //BIT5
- +#define ACM_HW_EN (0x01 << 4) //BIT4
- +#define TXOPSEL (0x01 << 3) //BIT3
- +#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
- +#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
- +#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
- +
- +//----------------------------------------------------------------------------
- +// 8187B RF pins related setting (offset 0xFF80-0xFF87,)
- +//----------------------------------------------------------------------------
- +#define TR_SW_MASK_TX_8187 BIT5
- +#define TR_SW_MASK_RX_8187 BIT6
- +#define TR_SW_MASK_8187 (TR_SW_MASK_TX_8187 | TR_SW_MASK_RX_8187)
- +
- +/*
- + * Bitmasks for specific register functions.
- + * Names are derived from the register name and function name.
- + *
- + * <REGISTER>_<FUNCTION>[<bit>]
- + *
- + * this leads to some awkward names...
- + */
- +
- +#define BRSR_BPLCP ((1<< 8))
- +#define BRSR_MBR ((1<< 1)|(1<< 0))
- +#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))
- +#define BRSR_MBR0 ((1<< 0))
- +#define BRSR_MBR1 ((1<< 1))
- +
- +#define CR_RST ((1<< 4))
- +#define CR_RE ((1<< 3))
- +#define CR_TE ((1<< 2))
- +#define CR_MulRW ((1<< 0))
- +
- +#define IMR_TXFOVW ((1<<15))
- +#define IMR_TimeOut ((1<<14))
- +#define IMR_BcnInt ((1<<13))
- +#define IMR_ATIMInt ((1<<12))
- +#define IMR_TBDER ((1<<11))
- +#define IMR_TBDOK ((1<<10))
- +#define IMR_THPDER ((1<< 9))
- +#define IMR_THPDOK ((1<< 8))
- +#define IMR_TNPDER ((1<< 7))
- +#define IMR_TNPDOK ((1<< 6))
- +#define IMR_RXFOVW ((1<< 5))
- +#define IMR_RDU ((1<< 4))
- +#define IMR_TLPDER ((1<< 3))
- +#define IMR_TLPDOK ((1<< 2))
- +#define IMR_RER ((1<< 1))
- +#define IMR_ROK ((1<< 0))
- +
- +#define ISR_TXFOVW ((1<<15))
- +#define ISR_TimeOut ((1<<14))
- +#define ISR_BcnInt ((1<<13))
- +#define ISR_ATIMInt ((1<<12))
- +#define ISR_TBDER ((1<<11))
- +#define ISR_TBDOK ((1<<10))
- +#define ISR_THPDER ((1<< 9))
- +#define ISR_THPDOK ((1<< 8))
- +#define ISR_TNPDER ((1<< 7))
- +#define ISR_TNPDOK ((1<< 6))
- +#define ISR_RXFOVW ((1<< 5))
- +#define ISR_RDU ((1<< 4))
- +#define ISR_TLPDER ((1<< 3))
- +#define ISR_TLPDOK ((1<< 2))
- +#define ISR_RER ((1<< 1))
- +#define ISR_ROK ((1<< 0))
- +
- +#define HW_VERID_R8180_F 3
- +#define HW_VERID_R8180_ABCD 2
- +#define HW_VERID_R8185_ABC 4
- +#define HW_VERID_R8185_D 5
- +
- +#define TCR_DurProcMode ((1<<30))
- +#define TCR_DISReqQsize ((1<<28))
- +#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
- +#define TCR_HWVERID_SHIFT 25
- +#define TCR_SWPLCPLEN ((1<<24))
- +#define TCR_PLCP_LEN TCR_SAT // rtl8180
- +#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21))
- +#define TCR_MXDMA_1024 6
- +#define TCR_MXDMA_2048 7
- +#define TCR_MXDMA_SHIFT 21
- +#define TCR_DISCW ((1<<20))
- +#define TCR_ICV ((1<<19))
- +#define TCR_LBK ((1<<18)|(1<<17))
- +#define TCR_LBK1 ((1<<18))
- +#define TCR_LBK0 ((1<<17))
- +#define TCR_CRC ((1<<16))
- +#define TCR_SRL_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
- +#define TCR_LRL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
- +#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
- +
- +#define RCR_ONLYERLPKT ((1<<31))
- +#define RCR_CS_SHIFT 29
- +#define RCR_CS_MASK ((1<<30) | (1<<29))
- +#define RCR_ENMARP ((1<<28))
- +#define RCR_CBSSID ((1<<23))
- +#define RCR_APWRMGT ((1<<22))
- +#define RCR_ADD3 ((1<<21))
- +#define RCR_AMF ((1<<20))
- +#define RCR_ACF ((1<<19))
- +#define RCR_ADF ((1<<18))
- +#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13))
- +#define RCR_RXFTH2 ((1<<15))
- +#define RCR_RXFTH1 ((1<<14))
- +#define RCR_RXFTH0 ((1<<13))
- +#define RCR_AICV ((1<<12))
- +#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8))
- +#define RCR_MXDMA2 ((1<<10))
- +#define RCR_MXDMA1 ((1<< 9))
- +#define RCR_MXDMA0 ((1<< 8))
- +#define RCR_9356SEL ((1<< 6))
- +#define RCR_ACRC32 ((1<< 5))
- +#define RCR_AB ((1<< 3))
- +#define RCR_AM ((1<< 2))
- +#define RCR_APM ((1<< 1))
- +#define RCR_AAP ((1<< 0))
- +
- +#define CR9346_EEM ((1<<7)|(1<<6))
- +#define CR9346_EEM1 ((1<<7))
- +#define CR9346_EEM0 ((1<<6))
- +#define CR9346_EECS ((1<<3))
- +#define CR9346_EESK ((1<<2))
- +#define CR9346_EED1 ((1<<1))
- +#define CR9346_EED0 ((1<<0))
- +
- +#define CONFIG0_WEP104 ((1<<6))
- +#define CONFIG0_LEDGPO_En ((1<<4))
- +#define CONFIG0_Aux_Status ((1<<3))
- +#define CONFIG0_GL ((1<<1)|(1<<0))
- +#define CONFIG0_GL1 ((1<<1))
- +#define CONFIG0_GL0 ((1<<0))
- +
- +#define CONFIG1_LEDS ((1<<7)|(1<<6))
- +#define CONFIG1_LEDS1 ((1<<7))
- +#define CONFIG1_LEDS0 ((1<<6))
- +#define CONFIG1_LWACT ((1<<4))
- +#define CONFIG1_MEMMAP ((1<<3))
- +#define CONFIG1_IOMAP ((1<<2))
- +#define CONFIG1_VPD ((1<<1))
- +#define CONFIG1_PMEn ((1<<0))
- +
- +#define CONFIG2_LCK ((1<<7))
- +#define CONFIG2_ANT ((1<<6))
- +#define CONFIG2_DPS ((1<<3))
- +#define CONFIG2_PAPE_sign ((1<<2))
- +#define CONFIG2_PAPE_time ((1<<1)|(1<<0))
- +#define CONFIG2_PAPE_time1 ((1<<1))
- +#define CONFIG2_PAPE_time0 ((1<<0))
- +
- +#define CONFIG3_GNTSel ((1<<7))
- +#define CONFIG3_PARM_En ((1<<6))
- +#define CONFIG3_Magic ((1<<5))
- +#define CONFIG3_CardB_En ((1<<3))
- +#define CONFIG3_CLKRUN_En ((1<<2))
- +#define CONFIG3_FuncRegEn ((1<<1))
- +#define CONFIG3_FBtbEn ((1<<0))
- +
- +#define CONFIG4_VCOPDN ((1<<7))
- +#define CONFIG4_PWROFF ((1<<6))
- +#define CONFIG4_PWRMGT ((1<<5))
- +#define CONFIG4_LWPME ((1<<4))
- +#define CONFIG4_LWPTN ((1<<2))
- +#define CONFIG4_RFTYPE ((1<<1)|(1<<0))
- +#define CONFIG4_RFTYPE1 ((1<<1))
- +#define CONFIG4_RFTYPE0 ((1<<0))
- +
- +#define CONFIG5_TX_FIFO_OK ((1<<7))
- +#define CONFIG5_RX_FIFO_OK ((1<<6))
- +#define CONFIG5_CALON ((1<<5))
- +#define CONFIG5_EACPI ((1<<2))
- +#define CONFIG5_LANWake ((1<<1))
- +#define CONFIG5_PME_STS ((1<<0))
- +
- +#define MSR_LINK_MASK ((1<<2)|(1<<3))
- +#define MSR_LINK_MANAGED 2
- +#define MSR_LINK_NONE 0
- +#define MSR_LINK_SHIFT 2
- +#define MSR_LINK_ADHOC 1
- +#define MSR_LINK_MASTER 3
- +#define MSR_LINK_ENEDCA (1<<4)
- +
- +#define PSR_GPO ((1<<7))
- +#define PSR_GPI ((1<<6))
- +#define PSR_LEDGPO1 ((1<<5))
- +#define PSR_LEDGPO0 ((1<<4))
- +#define PSR_UWF ((1<<1))
- +#define PSR_PSEn ((1<<0))
- +
- +#define SCR_KM ((1<<5)|(1<<4))
- +#define SCR_KM1 ((1<<5))
- +#define SCR_KM0 ((1<<4))
- +#define SCR_TXSECON ((1<<1))
- +#define SCR_RXSECON ((1<<0))
- +
- +#define BcnItv_BcnItv (0x01FF)
- +
- +#define AtimWnd_AtimWnd (0x01FF)
- +
- +#define BintrItv_BintrItv (0x01FF)
- +
- +#define AtimtrItv_AtimtrItv (0x01FF)
- +
- +#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0))
- +
- +#define TPPoll_BQ ((1<<7))
- +#define TPPoll_HPQ ((1<<6))
- +#define TPPoll_NPQ ((1<<5))
- +#define TPPoll_LPQ ((1<<4))
- +#define TPPoll_SBQ ((1<<3))
- +#define TPPoll_SHPQ ((1<<2))
- +#define TPPoll_SNPQ ((1<<1))
- +#define TPPoll_SLPQ ((1<<0))
- +
- +#define CWR_CW (0x01FF)
- +
- +#define FER_INTR ((1<<15))
- +#define FER_GWAKE ((1<< 4))
- +
- +#define FEMR_INTR ((1<<15))
- +#define FEMR_WKUP ((1<<14))
- +#define FEMR_GWAKE ((1<< 4))
- +
- +#define FPSR_INTR ((1<<15))
- +#define FPSR_GWAKE ((1<< 4))
- +
- +#define FFER_INTR ((1<<15))
- +#define FFER_GWAKE ((1<< 4))
- +
- +
- +//----------------------------------------------------------------------------
- +// 818xB AnaParm & AnaParm2 Register
- +//----------------------------------------------------------------------------
- +/*
- +#ifdef RTL8185B_FPGA
- +#define ANAPARM_FPGA_ON 0xa0000b59
- +//#define ANAPARM_FPGA_OFF
- +#define ANAPARM2_FPGA_ON 0x860dec11
- +//#define ANAPARM2_FPGA_OFF
- +#else //ASIC
- +*/
- +#define ANAPARM_ASIC_ON 0x45090658
- +//#define ANAPARM_ASIC_OFF
- +#define ANAPARM2_ASIC_ON 0x727f3f52
- +//#define ANAPARM2_ASIC_OFF
- +//#endif
- +//by amy for power save
- +#define RF_CHANGE_BY_SW BIT31
- +#define RF_CHANGE_BY_HW BIT30
- +#define RF_CHANGE_BY_PS BIT29
- +#define RF_CHANGE_BY_IPS BIT28
- +#define ANAPARM_ASIC_ON 0x45090658
- +#define ANAPARM2_ASIC_ON 0x727f3f52
- +
- +#define ANAPARM_ON ANAPARM_ASIC_ON
- +#define ANAPARM2_ON ANAPARM2_ASIC_ON
- +#define TFPC 0x5C // Tx FIFO Packet Count for BK, BE, VI, VO queues (2 bytes)
- +#define Config4_PowerOff BIT6 // Turn ON/Off RF Power(RFMD)
- +#define ANAPARM_OFF 0x51480658
- +#define ANAPARM2_OFF 0x72003f70
- +//by amy for power save
- +
- +#define MAX_DOZE_WAITING_TIMES_87B 500
- +
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,97 @@
- +/*
- + Power management interface routines.
- + Written by Mariusz Matuszek.
- + This code is currently just a placeholder for later work and
- + does not do anything useful.
- +
- + This is part of rtl8180 OpenSource driver.
- + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +*/
- +
- +#ifdef CONFIG_RTL8180_PM
- +
- +
- +#include "r8180_hw.h"
- +#include "r8180_pm.h"
- +#include "r8187.h"
- +int rtl8180_save_state (struct pci_dev *dev, u32 state)
- +{
- + printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
- + return(-EAGAIN);
- +}
- +
- +//netif_running is set to 0 before system call rtl8180_close,
- +//netif_running is set to 1 before system call rtl8180_open,
- +//if open success it will not change, or it change to 0;
- +int rtl8187_suspend (struct usb_interface *intf, pm_message_t state)
- +{
- + struct r8180_priv *priv;
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + struct net_device *dev = usb_get_intfdata(intf);
- +#else
- + //struct net_device *dev = (struct net_device *)ptr;
- +#endif
- +
- + printk("====>%s \n", __func__);
- + priv=ieee80211_priv(dev);
- +
- + if(dev) {
- + /* save the old rfkill state and then power off it */
- + priv->eInactivePowerState = priv->eRFPowerState;
- + /* power off the wifi by default */
- + r8187b_wifi_change_rfkill_state(dev, eRfOff);
- +
- + if (!netif_running(dev)) {
- + //printk(KERN_WARNING "UI or other close dev before suspend, go out suspend function\n");
- + return 0;
- + }
- +
- + dev->netdev_ops->ndo_stop(dev);
- + netif_device_detach(dev);
- + }
- + return 0;
- +}
- +
- +
- +int rtl8187_resume (struct usb_interface *intf)
- +{
- + struct r8180_priv *priv;
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + struct net_device *dev = usb_get_intfdata(intf);
- +#else
- + //struct net_device *dev = (struct net_device *)ptr;
- +#endif
- +
- + printk("====>%s \n", __func__);
- + priv=ieee80211_priv(dev);
- +
- + if(dev) {
- + /* resume the old rfkill state */
- + r8187b_wifi_change_rfkill_state(dev, priv->eInactivePowerState);
- +
- + if (!netif_running(dev)){
- + //printk(KERN_WARNING "UI or other close dev before suspend, go out resume function\n");
- + return 0;
- + }
- +
- + netif_device_attach(dev);
- + dev->netdev_ops->ndo_open(dev);
- + }
- +
- + return 0;
- +}
- +
- +
- +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
- +{
- +
- + //printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
- + // state, enable);
- + return 0;
- + //return(-EAGAIN);
- +}
- +
- +
- +
- +#endif //CONFIG_RTL8180_PM
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_pm.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_pm.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,28 @@
- +/*
- + Power management interface routines.
- + Written by Mariusz Matuszek.
- + This code is currently just a placeholder for later work and
- + does not do anything useful.
- +
- + This is part of rtl8180 OpenSource driver.
- + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +
- +*/
- +
- +#ifdef CONFIG_RTL8180_PM
- +
- +#ifndef R8180_PM_H
- +#define R8180_PM_H
- +
- +#include <linux/types.h>
- +#include <linux/usb.h>
- +
- +int rtl8180_save_state (struct pci_dev *dev, u32 state);
- +int rtl8187_suspend (struct usb_interface *intf,pm_message_t state);
- +int rtl8187_resume (struct usb_interface *intf);
- +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
- +
- +#endif //R8180_PM_H
- +
- +#endif // CONFIG_RTL8180_PM
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,1007 @@
- +/*
- + This is part of the rtl8180-sa2400 driver
- + released under the GPL (See file COPYING for details).
- + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
- +
- + This files contains programming code for the rtl8225
- + radio frontend.
- +
- + *Many* thanks to Realtek Corp. for their great support!
- +
- +*/
- +
- +
- +
- +#include "r8180_hw.h"
- +#include "r8180_rtl8225.h"
- +#ifdef ENABLE_DOT11D
- +#include "dot11d.h"
- +#endif
- +
- +#define USE_8051_3WIRE 1
- +
- +u8 rtl8225_threshold[]={
- + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
- +};
- +
- +u8 rtl8225_gain[]={
- + 0x23,0x88,0x7c,0xa5,// -82dbm
- + 0x23,0x88,0x7c,0xb5,// -82dbm
- + 0x23,0x88,0x7c,0xc5,// -82dbm
- + 0x33,0x80,0x79,0xc5,// -78dbm
- + 0x43,0x78,0x76,0xc5,// -74dbm
- + 0x53,0x60,0x73,0xc5,// -70dbm
- + 0x63,0x58,0x70,0xc5,// -66dbm
- +};
- +
- +u16 rtl8225bcd_rxgain[]={
- + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
- + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
- + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
- + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
- + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
- + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
- + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
- + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
- + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
- + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
- + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
- + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
- +
- +};
- +
- +
- +
- +u8 rtl8225_tx_gain_cck_ofdm[]={
- + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
- +};
- +
- +
- +u8 rtl8225_tx_power_ofdm[]={
- + 0x80,0x90,0xa2,0xb5,0xcb,0xe4
- +};
- +
- +
- +u8 rtl8225_tx_power_cck_ch14[]={
- + 0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
- + 0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
- + 0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
- + 0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
- + 0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
- + 0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00
- +};
- +
- +
- +u8 rtl8225_tx_power_cck[]={
- + 0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,
- + 0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,
- + 0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,
- + 0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,
- + 0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,
- + 0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03
- +};
- +
- +u8 rtl8225_agc[]={
- + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
- + 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
- + 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
- + 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
- + 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
- + 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
- + 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
- + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
- +};
- +
- +u32 rtl8225_chan[] = {
- + 0, //dummy channel 0
- + 0x085c, //1
- + 0x08dc, //2
- + 0x095c, //3
- + 0x09dc, //4
- + 0x0a5c, //5
- + 0x0adc, //6
- + 0x0b5c, //7
- + 0x0bdc, //8
- + 0x0c5c, //9
- + 0x0cdc, //10
- + 0x0d5c, //11
- + 0x0ddc, //12
- + 0x0e5c, //13
- + //0x0f5c, //14
- + 0x0f72, // 14
- +};
- +
- +void rtl8225_set_gain(struct net_device *dev, short gain)
- +{
- + write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
- + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
- + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
- + write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
- +
- +}
- +
- +
- +void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
- +{
- +//in windows the delays in this function was del from 85 to 87,
- +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
- +
- +#ifdef USE_8051_3WIRE
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- + //u8 bit;
- + //u16 wReg80, wReg82, wReg84;
- + u16 wReg80, wReg84;
- +
- + wReg80 = read_nic_word(dev, RFPinsOutput);
- + wReg80 &= 0xfff3;
- +// wReg82 = read_nic_word(dev, RFPinsEnable);
- + wReg84 = read_nic_word(dev, RFPinsSelect);
- + // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
- + //wReg84 &= 0xfff0;
- + wReg84 &= 0xfff8; //modified by david according to windows segment code.
- +
- + // We must set SW enabled before terminating HW 3-wire, 2005.07.29, by rcnjko.
- +// write_nic_word(dev, RFPinsEnable, (wReg82|0x0007)); // Set To Output Enable
- + write_nic_word(dev, RFPinsSelect, (wReg84|0x0007)); // Set To SW Switch
- +// force_pci_posting(dev);
- +// udelay(10); //
- +
- + write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80)); // Set SI_EN (RFLE)
- +// force_pci_posting(dev);
- +// udelay(2);
- + //twreg.struc.enableB = 0;
- + write_nic_word(dev, 0x80, (wReg80)); // Clear SI_EN (RFLE)
- +// force_pci_posting(dev);
- +// udelay(10);
- +
- + usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + adr, 0x8225, &data, 2, HZ / 2);
- +
- + // write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80));
- +// force_pci_posting(dev);
- +// udelay(10);
- +
- + write_nic_word(dev, 0x80, (wReg80|0x0004));
- + write_nic_word(dev, 0x84, (wReg84|0x0000));// Set To SW Switch
- +
- + if(priv->card_type == USB)
- + ;// msleep(2);
- + else
- + ; // rtl8185_rf_pins_enable(dev);
- +
- +#else
- + int i;
- + u16 out,select;
- + u8 bit;
- + u32 bangdata = (data << 4) | (adr & 0xf);
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
- +
- + write_nic_word(dev,RFPinsEnable,
- + (read_nic_word(dev,RFPinsEnable) | 0x7));
- +
- + select = read_nic_word(dev, RFPinsSelect);
- +
- + write_nic_word(dev, RFPinsSelect, select | 0x7 |
- + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
- +
- +// force_pci_posting(dev);
- +// udelay(10);
- +
- + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
- +
- +// force_pci_posting(dev);
- +// udelay(2);
- +
- + write_nic_word(dev, RFPinsOutput, out);
- +
- +// force_pci_posting(dev);
- +// udelay(10);
- +
- +
- + for(i=15; i>=0;i--){
- +
- + bit = (bangdata & (1<<i)) >> i;
- +
- + write_nic_word(dev, RFPinsOutput, bit | out);
- +
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- +
- + i--;
- + bit = (bangdata & (1<<i)) >> i;
- +
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- +
- + write_nic_word(dev, RFPinsOutput, bit | out);
- +
- + }
- +
- + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
- +
- +// force_pci_posting(dev);
- +// udelay(10);
- +
- + write_nic_word(dev, RFPinsOutput, out |
- + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
- +
- + write_nic_word(dev, RFPinsSelect, select |
- + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
- +
- + if(priv->card_type == USB)
- + ;// msleep(2);
- + else
- +// rtl8185_rf_pins_enable(dev);
- +#endif
- +}
- +
- +
- +void write_rtl8225_patch(struct net_device *dev, u8 adr, u16 data)
- +{
- +
- + int i;
- + u16 out,select;
- + u8 bit;
- + u32 bangdata = (data << 4) | (adr & 0xf);
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
- +
- + write_nic_word(dev,RFPinsEnable,
- + (read_nic_word(dev,RFPinsEnable) | 0x7));
- +
- + select = read_nic_word(dev, RFPinsSelect);
- +
- + write_nic_word(dev, RFPinsSelect, select | 0x7 |
- + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
- +
- + force_pci_posting(dev);
- + udelay(10);
- +
- + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
- +
- + force_pci_posting(dev);
- + udelay(2);
- +
- + write_nic_word(dev, RFPinsOutput, out);
- +
- + force_pci_posting(dev);
- + udelay(10);
- +
- + for(i=15; i>=0;i--){
- +
- + bit = (bangdata & (1<<i)) >> i;
- +
- + write_nic_word(dev, RFPinsOutput, bit | out);
- +
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- +
- + i--;
- + bit = (bangdata & (1<<i)) >> i;
- +
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- +
- + write_nic_word(dev, RFPinsOutput, bit | out);
- +
- + }
- +
- + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
- +
- + force_pci_posting(dev);
- + udelay(10);
- +
- + write_nic_word(dev, RFPinsOutput, out |
- + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
- +
- + write_nic_word(dev, RFPinsSelect, select |
- + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
- +
- + if(priv->card_type == USB)
- + mdelay(2);
- + else
- + rtl8185_rf_pins_enable(dev);
- +
- +}
- +
- +void rtl8225_rf_close(struct net_device *dev)
- +{
- + write_rtl8225(dev, 0x4, 0x1f);
- +
- + force_pci_posting(dev);
- + mdelay(1);
- +
- + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
- + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
- +}
- +
- +#ifdef ENABLE_DOT11D
- +//
- +// Description:
- +// Map dBm into Tx power index according to
- +// current HW model, for example, RF and PA, and
- +// current wireless mode.
- +//
- +s8
- +DbmToTxPwrIdx(
- + struct r8180_priv *priv,
- + WIRELESS_MODE WirelessMode,
- + s32 PowerInDbm
- + )
- +{
- + bool bUseDefault = true;
- + s8 TxPwrIdx = 0;
- +
- +#ifdef CONFIG_RTL818X_S
- + //
- + // 071011, SD3 SY:
- + // OFDM Power in dBm = Index * 0.5 + 0
- + // CCK Power in dBm = Index * 0.25 + 13
- + //
- + if(priv->card_8185 >= VERSION_8187S_B)
- + {
- + s32 tmp = 0;
- +
- + if(WirelessMode == WIRELESS_MODE_G)
- + {
- + bUseDefault = false;
- + tmp = (2 * PowerInDbm);
- +
- + if(tmp < 0)
- + TxPwrIdx = 0;
- + else if(tmp > 40) // 40 means 20 dBm.
- + TxPwrIdx = 40;
- + else
- + TxPwrIdx = (s8)tmp;
- + }
- + else if(WirelessMode == WIRELESS_MODE_B)
- + {
- + bUseDefault = false;
- + tmp = (4 * PowerInDbm) - 52;
- +
- + if(tmp < 0)
- + TxPwrIdx = 0;
- + else if(tmp > 28) // 28 means 20 dBm.
- + TxPwrIdx = 28;
- + else
- + TxPwrIdx = (s8)tmp;
- + }
- + }
- +#endif
- +
- + //
- + // TRUE if we want to use a default implementation.
- + // We shall set it to FALSE when we have exact translation formular
- + // for target IC. 070622, by rcnjko.
- + //
- + if(bUseDefault)
- + {
- + if(PowerInDbm < 0)
- + TxPwrIdx = 0;
- + else if(PowerInDbm > 35)
- + TxPwrIdx = 35;
- + else
- + TxPwrIdx = (u8)PowerInDbm;
- + }
- +
- + return TxPwrIdx;
- +}
- +#endif
- +
- +
- +short rtl8225_rf_set_sens(struct net_device *dev, short sens)
- +{
- + if (sens <0 || sens > 6) return -1;
- +
- + if(sens > 4)
- + write_rtl8225(dev, 0x0c, 0x850);
- + else
- + write_rtl8225(dev, 0x0c, 0x50);
- +
- + sens= 6-sens;
- + rtl8225_set_gain(dev, sens);
- +
- + write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
- + return 0;
- +
- +}
- +
- +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + int GainIdx;
- + int GainSetting;
- + int i;
- + u8 power;
- + u8 *cck_power_table;
- + u8 max_cck_power_level;
- + u8 max_ofdm_power_level;
- + u8 min_ofdm_power_level;
- + u8 cck_power_level = 0xff & priv->chtxpwr[ch];
- + u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
- +
- +#ifdef ENABLE_DOT11D
- + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
- + IS_DOT11D_STATE_DONE(priv->ieee80211) )
- + {
- + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
- + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
- + u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
- + u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
- +
- + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
- +
- + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
- + // ch, cck_power_level, ofdm_power_level);
- +
- + if(cck_power_level > CckMaxPwrIdx)
- + cck_power_level = CckMaxPwrIdx;
- + if(ofdm_power_level > OfdmMaxPwrIdx)
- + ofdm_power_level = OfdmMaxPwrIdx;
- + }
- +
- + //priv->CurrentCckTxPwrIdx = cck_power_level;
- + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
- +#endif
- +
- +
- + if(priv->card_type == USB){
- + max_cck_power_level = 11;
- + max_ofdm_power_level = 25; // 12 -> 25
- + min_ofdm_power_level = 10;
- + }else{
- + max_cck_power_level = 35;
- + max_ofdm_power_level = 35;
- + min_ofdm_power_level = 0;
- + }
- + if( priv->TrSwitchState == TR_SW_TX )
- + {
- + printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d\n", ofdm_power_level);
- + ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
- + cck_power_level -= GetTxCckHighPowerBias(dev);
- + printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
- + ofdm_power_level);
- + printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
- + cck_power_level);
- + }
- +
- +
- +
- + /* CCK power setting */
- + if(cck_power_level > max_cck_power_level)
- + cck_power_level = max_cck_power_level;
- + GainIdx=cck_power_level % 6;
- + GainSetting=cck_power_level / 6;
- +
- + if(ch == 14)
- + cck_power_table = rtl8225_tx_power_cck_ch14;
- + else
- + cck_power_table = rtl8225_tx_power_cck;
- +
- +// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
- + /*Ver B*/
- +// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
- +// }else{
- + /*Ver C - D */
- + write_nic_byte(dev, CCK_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
- +// }
- +
- + for(i=0;i<8;i++){
- +
- + power = cck_power_table[GainIdx * 8 + i];
- + write_phy_cck(dev, 0x44 + i, power);
- + }
- +
- + /* FIXME Is this delay really needeed ? */
- + force_pci_posting(dev);
- + mdelay(1);
- +
- + /* OFDM power setting */
- +// Old:
- +// if(ofdm_power_level > max_ofdm_power_level)
- +// ofdm_power_level = 35;
- +// ofdm_power_level += min_ofdm_power_level;
- +// Latest:
- + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
- + ofdm_power_level = max_ofdm_power_level;
- + else
- + ofdm_power_level += min_ofdm_power_level;
- + if(ofdm_power_level > 35)
- + ofdm_power_level = 35;
- +//
- +
- + GainIdx=ofdm_power_level % 6;
- + GainSetting=ofdm_power_level / 6;
- +#if 1
- +// if(priv->card_type == USB){
- + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
- +
- + write_phy_ofdm(dev,2,0x42);
- + write_phy_ofdm(dev,6,0);
- + write_phy_ofdm(dev,8,0);
- +// }
- +#endif
- +// if(priv->card_8185 == 1 && priv->card_8185_Bversion){
- +// /*Ver B*/
- +// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
- +// }else{
- + /*Ver C - D */
- + write_nic_byte(dev, OFDM_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
- +// }
- +
- +
- + power = rtl8225_tx_power_ofdm[GainIdx];
- +
- + write_phy_ofdm(dev, 0x5, power);
- + write_phy_ofdm(dev, 0x7, power);
- +
- + force_pci_posting(dev);
- + mdelay(1);
- + //write_nic_byte(dev, TX_AGC_CONTROL,4);
- +}
- +
- +void rtl8225_rf_set_chan(struct net_device *dev, short ch)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
- + ieee80211_is_54g(priv->ieee80211->current_network)) ||
- + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
- + int eifs_addr;
- +
- + if(NIC_8187 == priv->card_8187) {
- + eifs_addr = EIFS_8187;
- + } else {
- + eifs_addr = EIFS_8187B;
- + }
- +
- +#ifdef ENABLE_DOT11D
- + if(!IsLegalChannel(priv->ieee80211, ch) )
- + {
- + printk("channel(%d). is invalide\n", ch);
- + return;
- + }
- +#endif
- +
- + rtl8225_SetTXPowerLevel(dev, ch);
- +
- + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
- +
- + force_pci_posting(dev);
- + mdelay(10);
- +
- + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
- +
- + if(gset)
- + write_nic_byte(dev,DIFS,20); //DIFS: 20
- + else
- + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
- +
- + if(priv->ieee80211->state == IEEE80211_LINKED &&
- + ieee80211_is_shortslot(priv->ieee80211->current_network))
- + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
- +
- + else
- + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
- +
- +
- + if(gset){
- + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
- + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
- + //DMESG("using G net params");
- + }else{
- + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
- + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
- + //DMESG("using B net params");
- + }
- +
- +
- +}
- +
- +void rtl8225_host_pci_init(struct net_device *dev)
- +{
- + write_nic_word(dev, RFPinsOutput, 0x480);
- +
- + rtl8185_rf_pins_enable(dev);
- +
- + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
- + //write_nic_word(dev, RFPinsSelect, 0x88);
- + //else
- + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
- +
- + write_nic_byte(dev, GP_ENABLE, 0);
- +
- + force_pci_posting(dev);
- + mdelay(200);
- +
- + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
- +
- +
- +}
- +
- +void rtl8225_host_usb_init(struct net_device *dev)
- +{
- + write_nic_byte(dev,RFPinsSelect+1,0);
- +
- + write_nic_byte(dev,GPIO,0);
- +
- + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
- +
- + write_nic_byte(dev,RFPinsSelect+1,4);
- +
- + write_nic_byte(dev,GPIO,0x20);
- +
- + write_nic_byte(dev,GP_ENABLE,0);
- +
- +
- + /* Config BB & RF */
- + write_nic_word(dev, RFPinsOutput, 0x80);
- +
- + write_nic_word(dev, RFPinsSelect, 0x80);
- +
- + write_nic_word(dev, RFPinsEnable, 0x80);
- +
- +
- + mdelay(100);
- +
- + mdelay(1000);
- +
- +}
- +
- +void rtl8225_rf_init(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int i;
- + short channel = 1;
- + u16 brsr;
- + int brsr_addr;
- +
- + if(NIC_8187 == priv->card_8187) {
- + brsr_addr = BRSR_8187;
- + } else {
- + brsr_addr = BRSR_8187B;
- + }
- +
- +
- + priv->chan = channel;
- +
- + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
- +
- +
- + if(priv->card_type == USB)
- + rtl8225_host_usb_init(dev);
- + else
- + rtl8225_host_pci_init(dev);
- +
- + write_nic_dword(dev, RF_TIMING, 0x000a8008);
- +
- + //brsr = read_nic_word(dev, BRSR);
- + brsr = read_nic_word(dev, brsr_addr);
- +
- + //write_nic_word(dev, BRSR, 0xffff);
- + write_nic_word(dev, brsr_addr, 0xffff);
- +
- + write_nic_dword(dev, RF_PARA, 0x100044);
- +
- + #if 1 //0->1
- + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- + write_nic_byte(dev, CONFIG3, 0x44);
- + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
- + #endif
- +
- + if(priv->card_type == USB){
- + rtl8185_rf_pins_enable(dev);
- +
- + mdelay(1000);
- + }
- +
- + write_rtl8225(dev, 0x0, 0x67); mdelay(1);
- +
- +
- + write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
- +
- + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
- +
- + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
- +
- + if(priv->card_type == USB)
- + write_rtl8225(dev, 0x4, 0x486);
- + else
- + write_rtl8225(dev, 0x4, 0x8be);
- +
- + mdelay(1);
- +
- +
- + /* version B & C */
- +
- + if(priv->card_type == USB)
- + write_rtl8225(dev, 0x5, 0xbc0);
- + else if(priv->card_type == MINIPCI)
- + write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3));
- + else
- + write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
- +
- + mdelay(1);
- +// }
- +
- + write_rtl8225(dev, 0x6, 0xae6); mdelay(1);
- +
- + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
- +
- + write_rtl8225(dev, 0x8, 0x1f); mdelay(1);
- +
- + write_rtl8225(dev, 0x9, 0x334); mdelay(1);
- +
- + write_rtl8225(dev, 0xa, 0xfd4); mdelay(1);
- +
- + write_rtl8225(dev, 0xb, 0x391); mdelay(1);
- +
- + write_rtl8225(dev, 0xc, 0x50); mdelay(1);
- +
- +
- + write_rtl8225(dev, 0xd, 0x6db); mdelay(1);
- +
- + write_rtl8225(dev, 0xe, 0x29); mdelay(1);
- +
- + write_rtl8225(dev, 0xf, 0x914);
- +
- + if(priv->card_type == USB){
- + //force_pci_posting(dev);
- + mdelay(100);
- + }
- +
- + write_rtl8225(dev, 0x2, 0xc4d);
- +
- + if(priv->card_type == USB){
- + // force_pci_posting(dev);
- + mdelay(200);
- +
- + write_rtl8225(dev, 0x2, 0x44d);
- +
- + // force_pci_posting(dev);
- + mdelay(100);
- +
- + }//End of if(priv->card_type == USB)
- + /* FIXME!! rtl8187 we have to check if calibrarion
- + * is successful and eventually cal. again (repeat
- + * the two write on reg 2)
- + */
- + force_pci_posting(dev);
- +
- + mdelay(100); //200 for 8187
- +
- + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
- +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
- +
- + write_rtl8225(dev, 0x0, 0x127);
- +
- + for(i=0;i<95;i++){
- + write_rtl8225(dev, 0x1, (u8)(i+1));
- +
- + /* version B & C & D*/
- +
- + write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
- + }
- +
- + write_rtl8225(dev, 0x0, 0x27);
- +
- +
- +// //if(priv->card_type != USB){
- +// write_rtl8225(dev, 0x2, 0x44d);
- +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
- +// write_rtl8225(dev, 0x2, 0x47d);
- +//
- +// force_pci_posting(dev);
- +// mdelay(100);
- +//
- +// write_rtl8225(dev, 0x2, 0x44d);
- +// //}
- +
- + write_rtl8225(dev, 0x0, 0x22f);
- +
- + if(priv->card_type != USB)
- + rtl8185_rf_pins_enable(dev);
- +
- + for(i=0;i<128;i++){
- + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
- +
- + mdelay(1);
- + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
- +
- + mdelay(1);
- + }
- +
- + force_pci_posting(dev);
- + mdelay(1);
- +
- + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
- + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
- + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
- + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
- + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
- + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
- +
- + /* ver C & D */
- + write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
- +
- + //write_phy_ofdm(dev, 0x18, 0xef);
- + // }
- + //}
- + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
- +
- + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
- +
- +
- + //if(priv->card_type != USB)
- + //write_phy_ofdm(dev, 0xd, 0x33); // <>
- +
- + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
- +
- + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
- +/*ver D & 8187*/
- +// }
- +
- +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
- +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
- +// else
- + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
- +/*ver C & D & 8187*/
- +
- + write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
- +/*agc resp time 700*/
- +
- +
- +// if(priv->card_8185 == 2){
- + /* Ver D & 8187*/
- + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
- + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
- +
- +// if (priv->card_type == USB)
- +// write_phy_ofdm(dev, 0x18, 0xef);
- +
- + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
- +
- +
- + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
- + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
- +
- +// if (priv->card_type != USB){
- +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
- +// write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */
- +// else
- + write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
- + /* Ver C & D */ //FIXME:MAYBE not needed
- +// }
- +
- + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
- +
- + /*ver D & 8187*/
- + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
- +
- +// }
- +
- + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
- +
- +// if(priv->card_type != USB)
- + //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
- +
- + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
- + write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
- + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
- + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
- +/* Ver C & D & 8187*/
- +
- + // <> Set init. gain to m74dBm.
- +
- + rtl8225_set_gain(dev,4);
- + /*write_phy_ofdm(dev, 0x0d, 0x43); mdelay(1);
- + write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1);
- + write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
- + write_phy_ofdm(dev, 0x23, 0x78); mdelay(1);
- +*/
- + //if(priv->card_type == USB);
- + // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
- +
- + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
- + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
- + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
- + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
- + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
- + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
- + /* Ver C & D & 8187*/
- +
- + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
- +
- + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
- + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
- + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
- + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
- +
- + write_phy_cck(dev, 0x19, 0x0);
- + write_phy_cck(dev, 0x1a, 0xa0);
- + write_phy_cck(dev, 0x1b, 0x8);
- + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
- +
- + write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
- +
- +
- + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
- + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
- + write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
- + write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
- + write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
- + write_phy_cck(dev, 0x47, 0x15); mdelay(1);
- + write_phy_cck(dev, 0x48, 0x10); mdelay(1);
- + write_phy_cck(dev, 0x49, 0xa); mdelay(1);
- + write_phy_cck(dev, 0x4a, 0x5); mdelay(1);
- + write_phy_cck(dev, 0x4b, 0x2); mdelay(1);
- + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
- +
- +
- + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
- +
- +
- +
- +// <>
- +// // TESTR 0xb 8187
- +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
- +//
- +// //if(priv->card_type != USB){
- +// write_phy_ofdm(dev, 0x2, 0x62);
- +// write_phy_ofdm(dev, 0x6, 0x0);
- +// write_phy_ofdm(dev, 0x8, 0x0);
- +// //}
- +
- + rtl8225_SetTXPowerLevel(dev, channel);
- +
- + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
- + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
- +
- + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
- +
- + /* switch to high-speed 3-wire
- + * last digit. 2 for both cck and ofdm
- + */
- + if(priv->card_type == USB)
- + write_nic_dword(dev, 0x94, 0x3dc00002);
- + else{
- + write_nic_dword(dev, 0x94, 0x15c00002);
- + rtl8185_rf_pins_enable(dev);
- + }
- +
- +// if(priv->card_type != USB)
- +// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
- +// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
- +//
- +// /* make sure is waken up! */
- +// write_rtl8225(dev,0x4, 0x9ff);
- +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
- +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
- +
- + rtl8225_rf_set_chan(dev, priv->chan);
- +
- + //write_nic_word(dev,BRSR,brsr);
- +
- +}
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,77 @@
- +/*
- + This is part of the rtl8180-sa2400 driver
- + released under the GPL (See file COPYING for details).
- + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
- +
- + This files contains programming code for the rtl8225
- + radio frontend.
- +
- + *Many* thanks to Realtek Corp. for their great support!
- +
- +*/
- +
- +#ifndef RTL8225H
- +#define RTL8225H
- +
- +#include "r8187.h"
- +
- +#define RTL8225_ANAPARAM_ON 0xa0000a59
- +
- +// FIXME: OFF ANAPARAM MIGHT BE WRONG!
- +#define RTL8225_ANAPARAM_OFF 0xa00beb59
- +#define RTL8225_ANAPARAM2_OFF 0x840dec11
- +
- +#define RTL8225_ANAPARAM2_ON 0x860c7312
- +
- +void rtl8225_rf_init(struct net_device *dev);
- +void rtl8225z2_rf_init(struct net_device *dev);
- +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
- +short rtl8225_is_V_z2(struct net_device *dev);
- +void rtl8225_rf_set_chan(struct net_device *dev,short ch);
- +void rtl8225_rf_close(struct net_device *dev);
- +short rtl8225_rf_set_sens(struct net_device *dev, short sens);
- +void rtl8225_host_pci_init(struct net_device *dev);
- +void rtl8225_host_usb_init(struct net_device *dev);
- +void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
- +void rtl8225z2_rf_set_mode(struct net_device *dev) ;
- +void rtl8185_rf_pins_enable(struct net_device *dev);
- +void rtl8180_set_mode(struct net_device *dev,int mode);
- +void UpdateInitialGain(struct net_device *dev);
- +void UpdateCCKThreshold(struct net_device *dev);
- +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch);
- +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
- +
- +#define RTL8225_RF_MAX_SENS 6
- +#define RTL8225_RF_DEF_SENS 4
- +
- +extern inline char GetTxOfdmHighPowerBias(struct net_device *dev)
- +{
- + //
- + // We should always adjust our Tx Power for 8187 and 8187B.
- + // It was ever recommended not to adjust Tx Power of 8187B with Atheros AP
- + // for throughput by David, but now we found it is not the issue to impact
- + // the Atheros's problem and also no adjustion for Tx Power will cause "low"
- + // throughput. By Bruce, 2007-07-03.
- + //
- + return 10;
- +}
- +
- +//
- +// Description:
- +// Return Tx power level to minus if we are in high power state.
- +//
- +// Note:
- +// Adjust it according to RF if required.
- +//
- +extern inline char GetTxCckHighPowerBias(struct net_device *dev)
- +{
- + return 7;
- +}
- +
- +
- +
- +extern u8 rtl8225_agc[];
- +
- +extern u32 rtl8225_chan[];
- +
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,2092 @@
- +/*
- + This is part of the rtl8180-sa2400 driver
- + released under the GPL (See file COPYING for details).
- + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
- +
- + This files contains programming code for the rtl8225
- + radio frontend.
- +
- + *Many* thanks to Realtek Corp. for their great support!
- +
- +*/
- +
- +
- +
- +#include "r8180_hw.h"
- +#include "r8180_rtl8225.h"
- +#ifdef ENABLE_DOT11D
- +#include "dot11d.h"
- +#endif
- +
- +//2005.11.16
- +u8 rtl8225z2_threshold[]={
- + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
- +};
- +
- +// 0xd 0x19 0x1b 0x21
- +u8 rtl8225z2_gain_bg[]={
- + 0x23, 0x15, 0xa5, // -82-1dbm
- + 0x23, 0x15, 0xb5, // -82-2dbm
- + 0x23, 0x15, 0xc5, // -82-3dbm
- + 0x33, 0x15, 0xc5, // -78dbm
- + 0x43, 0x15, 0xc5, // -74dbm
- + 0x53, 0x15, 0xc5, // -70dbm
- + 0x63, 0x15, 0xc5, // -66dbm
- +};
- +
- +u8 rtl8225z2_gain_a[]={
- + 0x13,0x27,0x5a,//,0x37,// -82dbm
- + 0x23,0x23,0x58,//,0x37,// -82dbm
- + 0x33,0x1f,0x56,//,0x37,// -82dbm
- + 0x43,0x1b,0x54,//,0x37,// -78dbm
- + 0x53,0x17,0x51,//,0x37,// -74dbm
- + 0x63,0x24,0x4f,//,0x37,// -70dbm
- + 0x73,0x0f,0x4c,//,0x37,// -66dbm
- +};
- +static u32 MAC_REG_TABLE[][3]={
- + {0xf0, 0x32, 0000}, {0xf1, 0x32, 0000}, {0xf2, 0x00, 0000}, {0xf3, 0x00, 0000},
- + {0xf4, 0x32, 0000}, {0xf5, 0x43, 0000}, {0xf6, 0x00, 0000}, {0xf7, 0x00, 0000},
- + {0xf8, 0x46, 0000}, {0xf9, 0xa4, 0000}, {0xfa, 0x00, 0000}, {0xfb, 0x00, 0000},
- + {0xfc, 0x96, 0000}, {0xfd, 0xa4, 0000}, {0xfe, 0x00, 0000}, {0xff, 0x00, 0000},
- +
- + {0x58, 0x4b, 0001}, {0x59, 0x00, 0001}, {0x5a, 0x4b, 0001}, {0x5b, 0x00, 0001},
- + {0x60, 0x4b, 0001}, {0x61, 0x09, 0001}, {0x62, 0x4b, 0001}, {0x63, 0x09, 0001},
- + {0xce, 0x0f, 0001}, {0xcf, 0x00, 0001}, {0xe0, 0xff, 0001}, {0xe1, 0x0f, 0001},
- + {0xe2, 0x00, 0001}, {0xf0, 0x4e, 0001}, {0xf1, 0x01, 0001}, {0xf2, 0x02, 0001},
- + {0xf3, 0x03, 0001}, {0xf4, 0x04, 0001}, {0xf5, 0x05, 0001}, {0xf6, 0x06, 0001},
- + {0xf7, 0x07, 0001}, {0xf8, 0x08, 0001},
- +
- + {0x4e, 0x00, 0002}, {0x0c, 0x04, 0002}, {0x21, 0x61, 0002}, {0x22, 0x68, 0002},
- + {0x23, 0x6f, 0002}, {0x24, 0x76, 0002}, {0x25, 0x7d, 0002}, {0x26, 0x84, 0002},
- + {0x27, 0x8d, 0002}, {0x4d, 0x08, 0002}, {0x50, 0x05, 0002}, {0x51, 0xf5, 0002},
- + {0x52, 0x04, 0002}, {0x53, 0xa0, 0002}, {0x54, 0x1f, 0002}, {0x55, 0x23, 0002},
- + {0x56, 0x45, 0002}, {0x57, 0x67, 0002}, {0x58, 0x08, 0002}, {0x59, 0x08, 0002},
- + {0x5a, 0x08, 0002}, {0x5b, 0x08, 0002}, {0x60, 0x08, 0002}, {0x61, 0x08, 0002},
- + {0x62, 0x08, 0002}, {0x63, 0x08, 0002}, {0x64, 0xcf, 0002}, {0x72, 0x56, 0002},
- + {0x73, 0x9a, 0002},
- +
- + {0x34, 0xf0, 0000}, {0x35, 0x0f, 0000}, {0x5b, 0x40, 0000}, {0x84, 0x88, 0000},
- + {0x85, 0x24, 0000}, {0x88, 0x54, 0000}, {0x8b, 0xb8, 0000}, {0x8c, 0x07, 0000},
- + {0x8d, 0x00, 0000}, {0x94, 0x1b, 0000}, {0x95, 0x12, 0000}, {0x96, 0x00, 0000},
- + {0x97, 0x06, 0000}, {0x9d, 0x1a, 0000}, {0x9f, 0x10, 0000}, {0xb4, 0x22, 0000},
- + {0xbe, 0x80, 0000}, {0xdb, 0x00, 0000}, {0xee, 0x00, 0000}, {0x91, 0x01, 0000},
- + //lzm mode 0x91 form 0x03->0x01 open GPIO BIT1,
- + //because Polling methord will rurn off Radio
- + //the first time when read GPI(0x92).
- + //because after 0x91:bit1 form 1->0, there will
- + //be time for 0x92:bit1 form 0->1
- +
- + {0x4c, 0x00, 0002}, {0x9f, 0x00, 0003}, {0x8c, 0x01, 0000}, {0x8d, 0x10, 0000},
- + {0x8e, 0x08, 0000}, {0x8f, 0x00, 0000}
- +};
- +
- +static u8 ZEBRA_AGC[]={
- + 0,
- + 0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,
- + 0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,
- + 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,
- + 0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
- + 0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
- + 0x26,0x27,0x27,0x28,0x28,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,
- + 0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x31,0x31,0x31,0x31,
- + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31
- +};
- +
- +static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
- + 0,
- + 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409,
- + 0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541,
- + 0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583,
- + 0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644,
- + 0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688,
- + 0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745,
- + 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789,
- + 0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793,
- + 0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,
- + 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9,
- + 0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3,
- + 0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb
- +};
- +
- +// Use the new SD3 given param, by shien chang, 2006.07.14
- +
- +static u8 OFDM_CONFIG[]={
- + // 0x00
- + 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
- + 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
- +
- + // 0x10
- + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
- + 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
- +
- + // 0x20
- + 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
- + 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
- +
- + // 0x30
- + 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
- + 0x6d, 0x3c, 0xfb, 0x07//0xc7
- + };
- +
- +//2005.11.16,
- +u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={
- + 0x00,0x01,0x02,0x03,0x04,0x05,
- + 0x06,0x07,0x08,0x09,0x0a,0x0b,
- + 0x0c,0x0d,0x0e,0x0f,0x10,0x11,
- + 0x12,0x13,0x14,0x15,0x16,0x17,
- + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,
- + 0x1e,0x1f,0x20,0x21,0x22,0x23,
- +};
- +//-
- +u16 rtl8225z2_rxgain[]={
- + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
- + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
- + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
- + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
- + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
- + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
- + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
- + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
- + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
- + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
- + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
- + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
- +
- +};
- +
- +
- +/*
- + from 0 to 0x23
- +u8 rtl8225_tx_gain_cck_ofdm[]={
- + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
- +};
- +*/
- +
- +//-
- +u8 rtl8225z2_tx_power_ofdm[]={
- + 0x42,0x00,0x40,0x00,0x40
- +};
- +
- +
- +//-
- +u8 rtl8225z2_tx_power_cck_ch14[]={
- + 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00,
- + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
- + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
- + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
- +};
- +
- +
- +//-
- +u8 rtl8225z2_tx_power_cck[]={
- + 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04,
- + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
- + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
- + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
- +};
- +
- +#ifdef ENABLE_DOT11D
- +//
- +// Description:
- +// Map dBm into Tx power index according to
- +// current HW model, for example, RF and PA, and
- +// current wireless mode.
- +//
- +s8
- +rtl8187B_DbmToTxPwrIdx(
- + struct r8180_priv *priv,
- + WIRELESS_MODE WirelessMode,
- + s32 PowerInDbm
- + )
- +{
- + bool bUseDefault = true;
- + s8 TxPwrIdx = 0;
- +
- +#ifdef CONFIG_RTL818X_S
- + //
- + // 071011, SD3 SY:
- + // OFDM Power in dBm = Index * 0.5 + 0
- + // CCK Power in dBm = Index * 0.25 + 13
- + //
- + if(priv->card_8185 >= VERSION_8187S_B)
- + {
- + s32 tmp = 0;
- +
- + if(WirelessMode == WIRELESS_MODE_G)
- + {
- + bUseDefault = false;
- + tmp = (2 * PowerInDbm);
- +
- + if(tmp < 0)
- + TxPwrIdx = 0;
- + else if(tmp > 40) // 40 means 20 dBm.
- + TxPwrIdx = 40;
- + else
- + TxPwrIdx = (s8)tmp;
- + }
- + else if(WirelessMode == WIRELESS_MODE_B)
- + {
- + bUseDefault = false;
- + tmp = (4 * PowerInDbm) - 52;
- +
- + if(tmp < 0)
- + TxPwrIdx = 0;
- + else if(tmp > 28) // 28 means 20 dBm.
- + TxPwrIdx = 28;
- + else
- + TxPwrIdx = (s8)tmp;
- + }
- + }
- +#endif
- +
- + //
- + // TRUE if we want to use a default implementation.
- + // We shall set it to FALSE when we have exact translation formular
- + // for target IC. 070622, by rcnjko.
- + //
- + if(bUseDefault)
- + {
- + if(PowerInDbm < 0)
- + TxPwrIdx = 0;
- + else if(PowerInDbm > 35)
- + TxPwrIdx = 35;
- + else
- + TxPwrIdx = (u8)PowerInDbm;
- + }
- +
- + return TxPwrIdx;
- +}
- +#endif
- +
- +
- +void rtl8225z2_set_gain(struct net_device *dev, short gain)
- +{
- + u8* rtl8225_gain;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + u8 mode = priv->ieee80211->mode;
- +
- + if(mode == IEEE_B || mode == IEEE_G)
- + rtl8225_gain = rtl8225z2_gain_bg;
- + else
- + rtl8225_gain = rtl8225z2_gain_a;
- +
- + //write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]);
- + //write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]);
- + //write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]);
- + //2005.11.17, by ch-hsu
- + write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
- + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
- + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
- + write_phy_ofdm(dev, 0x21, 0x37);
- +
- +}
- +
- +u32 read_rtl8225(struct net_device *dev, u8 adr)
- +{
- + u32 data2Write = ((u32)(adr & 0x1f)) << 27;
- + u32 dataRead;
- + u32 mask;
- + u16 oval,oval2,oval3,tmp;
- +// ThreeWireReg twreg;
- +// ThreeWireReg tdata;
- + int i;
- + short bit, rw;
- +
- + u8 wLength = 6;
- + u8 rLength = 12;
- + u8 low2high = 0;
- +
- + oval = read_nic_word(dev, RFPinsOutput);
- + oval2 = read_nic_word(dev, RFPinsEnable);
- + oval3 = read_nic_word(dev, RFPinsSelect);
- + write_nic_word(dev, RFPinsEnable, (oval2|0xf));
- + write_nic_word(dev, RFPinsSelect, (oval3|0xf));
- +
- + dataRead = 0;
- +
- + oval &= ~0xf;
- +
- + write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4);
- +
- + write_nic_word(dev, RFPinsOutput, oval ); udelay(5);
- +
- + rw = 0;
- +
- + mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
- + for(i = 0; i < wLength/2; i++)
- + {
- + bit = ((data2Write&mask) != 0) ? 1 : 0;
- + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
- +
- + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
- + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
- +
- + mask = (low2high) ? (mask<<1): (mask>>1);
- +
- + if(i == 2)
- + {
- + rw = BB_HOST_BANG_RW;
- + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
- + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2);
- + break;
- + }
- +
- + bit = ((data2Write&mask) != 0) ? 1: 0;
- +
- + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
- + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
- +
- + write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1);
- +
- + mask = (low2high) ? (mask<<1) : (mask>>1);
- + }
- +
- + //twreg.struc.clk = 0;
- + //twreg.struc.data = 0;
- + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2);
- + mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
- +
- + // We must set data pin to HW controled, otherwise RF can't driver it and
- + // value RF register won't be able to read back properly. 2006.06.13, by rcnjko.
- + write_nic_word(dev, RFPinsEnable,((oval2|0xe) & (~0x01)));
- +
- + for(i = 0; i < rLength; i++)
- + {
- + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
- +
- + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
- + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
- + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
- + tmp = read_nic_word(dev, RFPinsInput);
- +
- + dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
- +
- + write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
- +
- + mask = (low2high) ? (mask<<1) : (mask>>1);
- + }
- +
- + write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
- +
- + write_nic_word(dev, RFPinsEnable, oval2);
- + write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
- + write_nic_word(dev, RFPinsOutput, 0x3a0);
- +
- + return dataRead;
- +
- +}
- +short rtl8225_is_V_z2(struct net_device *dev)
- +{
- + short vz2 = 1;
- + //set VCO-PDN pin
- +// printk("%s()\n", __FUNCTION__);
- + write_nic_word(dev, RFPinsOutput, 0x0080);
- + write_nic_word(dev, RFPinsSelect, 0x0080);
- + write_nic_word(dev, RFPinsEnable, 0x0080);
- +
- + //lzm mod for up take too long time 20081201
- + //mdelay(100);
- + //mdelay(1000);
- +
- + /* sw to reg pg 1 */
- + write_rtl8225(dev, 0, 0x1b7);
- + /* reg 8 pg 1 = 23*/
- + if( read_rtl8225(dev, 8) != 0x588)
- + vz2 = 0;
- +
- + else /* reg 9 pg 1 = 24 */
- + if( read_rtl8225(dev, 9) != 0x700)
- + vz2 = 0;
- +
- + /* sw back to pg 0 */
- + write_rtl8225(dev, 0, 0xb7);
- +
- + return vz2;
- +
- +}
- +
- +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +// int GainIdx;
- +// int GainSetting;
- + int i;
- + u8 power;
- + u8 *cck_power_table;
- + u8 max_cck_power_level;
- + u8 min_cck_power_level;
- + u8 max_ofdm_power_level;
- + u8 min_ofdm_power_level;
- + s8 cck_power_level = 0xff & priv->chtxpwr[ch];
- + s8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
- + u8 hw_version = priv->card_8187_Bversion;
- +
- +#ifdef ENABLE_DOT11D
- + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
- + IS_DOT11D_STATE_DONE(priv->ieee80211) )
- + {
- + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
- + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
- + u8 CckMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
- + u8 OfdmMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
- +
- + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
- +
- + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
- + // ch, cck_power_level, ofdm_power_level);
- +
- + if(cck_power_level > CckMaxPwrIdx)
- + cck_power_level = CckMaxPwrIdx;
- + if(ofdm_power_level > OfdmMaxPwrIdx)
- + ofdm_power_level = OfdmMaxPwrIdx;
- + }
- +
- + //priv->CurrentCckTxPwrIdx = cck_power_level;
- + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
- +#endif
- +
- + if (NIC_8187B == priv->card_8187)
- + {
- + if (hw_version == VERSION_8187B_B)
- + {
- + min_cck_power_level = 0;
- + max_cck_power_level = 15;
- + min_ofdm_power_level = 2;
- + max_ofdm_power_level = 17;
- + }else
- + {
- + min_cck_power_level = 7;
- + max_cck_power_level = 22;
- + min_ofdm_power_level = 10;
- + max_ofdm_power_level = 25;
- + }
- +
- + if( priv->TrSwitchState == TR_SW_TX )
- + {
- + //printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d, adjust value = %d\n", ofdm_power_level,GetTxOfdmHighPowerBias(dev));
- + ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
- + cck_power_level -= GetTxCckHighPowerBias(dev);
- + //printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
- + // ofdm_power_level);
- + //printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
- + // cck_power_level);
- + }
- + /* CCK power setting */
- + if(cck_power_level > (max_cck_power_level -min_cck_power_level))
- + cck_power_level = max_cck_power_level;
- + else
- + cck_power_level += min_cck_power_level;
- + cck_power_level += priv->cck_txpwr_base;
- +
- + if(cck_power_level > 35)
- + cck_power_level = 35;
- + if(cck_power_level < 0)
- + cck_power_level = 0;
- +
- + if(ch == 14)
- + cck_power_table = rtl8225z2_tx_power_cck_ch14;
- + else
- + cck_power_table = rtl8225z2_tx_power_cck;
- + if (hw_version == VERSION_8187B_B)
- + {
- + if (cck_power_level <= 6){
- + }
- + else if (cck_power_level <=11){
- + cck_power_table += 8;
- + }
- + else{
- + cck_power_table += (8*2);
- + }
- + }else{
- + if (cck_power_level<=5){
- + }else if(cck_power_level<=11){
- + cck_power_table += 8;
- + }else if(cck_power_level <= 17){
- + cck_power_table += 8*2;
- + }else{
- + cck_power_table += 8*3;
- + }
- + }
- +
- +
- +
- + for(i=0;i<8;i++){
- +
- + power = cck_power_table[i];
- + write_phy_cck(dev, 0x44 + i, power);
- + }
- +
- + //write_nic_byte(dev, TX_GAIN_CCK, power);
- + //2005.11.17,
- + write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]*2));
- +
- +// force_pci_posting(dev);
- +// msleep(1);
- +//in windows the delay was del from 85 to 87,
- +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
- +
- + /* OFDM power setting */
- + // Old:
- + // if(ofdm_power_level > max_ofdm_power_level)
- + // ofdm_power_level = 35;
- + // ofdm_power_level += min_ofdm_power_level;
- + // Latest:
- + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
- + ofdm_power_level = max_ofdm_power_level;
- + else
- + ofdm_power_level += min_ofdm_power_level;
- +
- + ofdm_power_level += priv->ofdm_txpwr_base;
- +
- + if(ofdm_power_level > 35)
- + ofdm_power_level = 35;
- +
- + if(ofdm_power_level < 0)
- + ofdm_power_level = 0;
- + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]*2);
- +
- + if (hw_version == VERSION_8187B_B)
- + {
- + if(ofdm_power_level<=11){
- + write_phy_ofdm(dev, 0x87, 0x60);
- + write_phy_ofdm(dev, 0x89, 0x60);
- + }
- + else{
- + write_phy_ofdm(dev, 0x87, 0x5c);
- + write_phy_ofdm(dev, 0x89, 0x5c);
- + }
- + }else{
- + if(ofdm_power_level<=11){
- + write_phy_ofdm(dev, 0x87, 0x5c);
- + write_phy_ofdm(dev, 0x89, 0x5c);
- + }
- + if(ofdm_power_level<=17){
- + write_phy_ofdm(dev, 0x87, 0x54);
- + write_phy_ofdm(dev, 0x89, 0x54);
- + }
- + else{
- + write_phy_ofdm(dev, 0x87, 0x50);
- + write_phy_ofdm(dev, 0x89, 0x50);
- + }
- + }
- +// force_pci_posting(dev);
- +// msleep(1);
- +//in windows the delay was del from 85 to 87,
- +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
- + }else if(NIC_8187 == priv->card_8187) {
- + min_cck_power_level = 0;
- + max_cck_power_level = 15;
- + min_ofdm_power_level = 10;
- + max_ofdm_power_level = 25;
- + if(cck_power_level > (max_cck_power_level -min_cck_power_level))
- + cck_power_level = max_cck_power_level;
- + else
- + cck_power_level += min_cck_power_level;
- + cck_power_level += priv->cck_txpwr_base;
- +
- + if(cck_power_level > 35)
- + cck_power_level = 35;
- +
- + if(ch == 14)
- + cck_power_table = rtl8225z2_tx_power_cck_ch14;
- + else
- + cck_power_table = rtl8225z2_tx_power_cck;
- + for(i=0;i<8;i++){
- + power = cck_power_table[i];
- + write_phy_cck(dev, 0x44 + i, power);
- + }
- +
- + //write_nic_byte(dev, TX_GAIN_CCK, power);
- + //2005.11.17,
- + write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]);
- +
- +// force_pci_posting(dev);
- +// msleep(1);
- +//in windows the delay was del from 85 to 87,
- +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
- + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
- + ofdm_power_level = max_ofdm_power_level;
- + else
- + ofdm_power_level += min_ofdm_power_level;
- +
- + ofdm_power_level += priv->ofdm_txpwr_base;
- +
- + if(ofdm_power_level > 35)
- + ofdm_power_level = 35;
- + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]);
- +
- + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
- +
- + write_phy_ofdm(dev,2,0x42);
- + write_phy_ofdm(dev,5,0);
- + write_phy_ofdm(dev,6,0x40);
- + write_phy_ofdm(dev,7,0);
- + write_phy_ofdm(dev,8,0x40);
- + }
- +
- +}
- +
- +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
- + ieee80211_is_54g(priv->ieee80211->current_network)) ||
- + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
- + int eifs_addr;
- +
- + down(&priv->set_chan_sem);
- +
- + if(NIC_8187 == priv->card_8187) {
- + eifs_addr = EIFS_8187;
- + } else {
- + eifs_addr = EIFS_8187B;
- + }
- +
- +#ifdef ENABLE_DOT11D
- + if(!IsLegalChannel(priv->ieee80211, ch) )
- + {
- + printk("channel(%d). is invalide\n", ch);
- + up(&priv->set_chan_sem);
- + return;
- + }
- +#endif
- + //87B not do it FIXME
- + rtl8225z2_SetTXPowerLevel(dev, ch);
- +
- + //write_nic_byte(dev,0x7,(u8)rtl8225_chan[ch]);
- + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
- +
- + force_pci_posting(dev);
- + //mdelay(10);
- +//in windows the delay was del from 85 to 87,
- +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
- + if(NIC_8187 == priv->card_8187){
- + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
- +
- + if(gset)
- + write_nic_byte(dev,DIFS,20); //DIFS: 20
- + else
- + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
- +
- + if(priv->ieee80211->state == IEEE80211_LINKED &&
- + ieee80211_is_shortslot(priv->ieee80211->current_network))
- + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
- +
- + else
- + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
- +
- +
- + if(gset){
- + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
- + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
- + //DMESG("using G net params");
- + }else{
- + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
- + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
- + //DMESG("using B net params");
- + }
- + }
- +
- + else {
- +#ifdef THOMAS_TURBO
- + if(priv->ieee80211->current_network.Turbo_Enable && priv->ieee80211->iw_mode == IW_MODE_INFRA){
- + write_nic_word(dev,AC_VO_PARAM,0x5114);
- + write_nic_word(dev,AC_VI_PARAM,0x5114);
- + write_nic_word(dev,AC_BE_PARAM,0x5114);
- + write_nic_word(dev,AC_BK_PARAM,0x5114);
- + } else {
- + write_nic_word(dev,AC_VO_PARAM,0x731c);
- + write_nic_word(dev,AC_VI_PARAM,0x731c);
- + write_nic_word(dev,AC_BE_PARAM,0x731c);
- + write_nic_word(dev,AC_BK_PARAM,0x731c);
- + }
- +#endif
- + }
- +
- + up(&priv->set_chan_sem);
- +}
- +void
- +MacConfig_87BASIC_HardCode(struct net_device *dev)
- +{
- + //============================================================================
- + // MACREG.TXT
- + //============================================================================
- + int nLinesRead = 0;
- + u32 u4bRegOffset, u4bRegValue, u4bPageIndex;
- + int i;
- +
- + nLinesRead=(sizeof(MAC_REG_TABLE)/3)/4;
- +
- + for(i = 0; i < nLinesRead; i++)
- + {
- + u4bRegOffset=MAC_REG_TABLE[i][0];
- + u4bRegValue=MAC_REG_TABLE[i][1];
- + u4bPageIndex=MAC_REG_TABLE[i][2];
- +
- + u4bRegOffset|= (u4bPageIndex << 8);
- +
- + write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
- + }
- + //============================================================================
- +}
- +
- +static void MacConfig_87BASIC(struct net_device *dev)
- +{
- + MacConfig_87BASIC_HardCode(dev);
- +
- + //============================================================================
- +
- + // Follow TID_AC_MAP of WMac.
- + //PlatformEFIOWrite2Byte(dev, TID_AC_MAP, 0xfa50);
- + write_nic_word(dev, TID_AC_MAP, 0xfa50);
- +
- + // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko.
- + write_nic_word(dev, INT_MIG, 0x0000);
- +
- + // Prevent TPC to cause CRC error. Added by Annie, 2006-06-10.
- + write_nic_dword(dev, 0x1F0, 0x00000000);
- + write_nic_dword(dev, 0x1F4, 0x00000000);
- + write_nic_byte(dev, 0x1F8, 0x00);
- +
- + // For WiFi 5.2.2.5 Atheros AP performance. Added by Annie, 2006-06-12.
- + // PlatformIOWrite4Byte(dev, RFTiming, 0x0008e00f);
- + // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
- + write_nic_dword(dev, RFTiming, 0x00004001);
- +
- +#ifdef TODO
- + // Asked for by Victor, for 87B B-cut Rx FIFO overflow bug, 2006.06.27, by rcnjko.
- + if(dev->NdisUsbDev.CardInfo.USBIsHigh == FALSE)
- + {
- + PlatformEFIOWrite1Byte(dev, 0x24E, 0x01);
- + }
- +#endif
- +}
- +
- +
- +//
- +// Description:
- +// Initialize RFE and read Zebra2 version code.
- +//
- +// 2005-08-01, by Annie.
- +//
- +void
- +SetupRFEInitialTiming(struct net_device* dev)
- +{
- + //u32 data8, data9;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + // setup initial timing for RFE
- + // Set VCO-PDN pin.
- + write_nic_word(dev, RFPinsOutput, 0x0480);
- + write_nic_word(dev, RFPinsSelect, 0x2488);
- + write_nic_word(dev, RFPinsEnable, 0x1FFF);
- +
- + mdelay(100);
- + // Steven recommends: delay 1 sec for setting RF 1.8V. by Annie, 2005-04-28.
- + mdelay(1000);
- +
- + //
- + // TODO: Read Zebra version code if necessary.
- + //
- + priv->rf_chip = RF_ZEBRA2;
- +}
- +
- +
- +void ZEBRA_Config_87BASIC_HardCode(struct net_device* dev)
- +{
- + u32 i;
- + u32 addr,data;
- + u32 u4bRegOffset, u4bRegValue;
- +
- +
- + //=============================================================================
- + // RADIOCFG.TXT
- + //=============================================================================
- + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1);
- + write_rtl8225(dev, 0x01, 0x0ee0); mdelay(1);
- + write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
- + write_rtl8225(dev, 0x03, 0x0441); mdelay(1);
- + write_rtl8225(dev, 0x04, 0x08c3); mdelay(1);
- + write_rtl8225(dev, 0x05, 0x0c72); mdelay(1);
- + write_rtl8225(dev, 0x06, 0x00e6); mdelay(1);
- + write_rtl8225(dev, 0x07, 0x082a); mdelay(1);
- + write_rtl8225(dev, 0x08, 0x003f); mdelay(1);
- + write_rtl8225(dev, 0x09, 0x0335); mdelay(1);
- + write_rtl8225(dev, 0x0a, 0x09d4); mdelay(1);
- + write_rtl8225(dev, 0x0b, 0x07bb); mdelay(1);
- + write_rtl8225(dev, 0x0c, 0x0850); mdelay(1);
- + write_rtl8225(dev, 0x0d, 0x0cdf); mdelay(1);
- + write_rtl8225(dev, 0x0e, 0x002b); mdelay(1);
- + write_rtl8225(dev, 0x0f, 0x0114); mdelay(1);
- +
- + write_rtl8225(dev, 0x00, 0x01b7); mdelay(1);
- +
- +
- + for(i=1;i<=95;i++)
- + {
- + write_rtl8225(dev, 0x01, i);mdelay(1);
- + write_rtl8225(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
- + //DbgPrint("RF - 0x%x = 0x%x\n", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
- + }
- +
- + write_rtl8225(dev, 0x03, 0x0080); mdelay(1); // write reg 18
- + write_rtl8225(dev, 0x05, 0x0004); mdelay(1); // write reg 20
- + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1); // switch to reg0-reg15
- + //lzm mod for up take too long time 20081201
- +#ifdef THOMAS_BEACON
- + msleep(1000);// Deay 1 sec. //0xfd
- + //msleep(1000);// Deay 1 sec. //0xfd
- + //msleep(1000);// Deay 1 sec. //0xfd
- + msleep(400);// Deay 1 sec. //0xfd
- +#else
- +
- + mdelay(1000);
- + //mdelay(1000);
- + //mdelay(1000);
- + mdelay(400);
- +#endif
- + write_rtl8225(dev, 0x02, 0x0c4d); mdelay(1);
- + //lzm mod for up take too long time 20081201
- + //mdelay(1000);
- + //mdelay(1000);
- + msleep(100);// Deay 100 ms. //0xfe
- + msleep(100);// Deay 100 ms. //0xfe
- + write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
- + write_rtl8225(dev, 0x00, 0x02bf); mdelay(1); //0x002f disable 6us corner change, 06f--> enable
- +
- + //=============================================================================
- +
- + //=============================================================================
- + // CCKCONF.TXT
- + //=============================================================================
- + /*
- + u4bRegOffset=0x41;
- + u4bRegValue=0xc8;
- +
- + //DbgPrint("\nCCK- 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
- + WriteBB(dev, (0x01000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
- + */
- +
- +
- + //=============================================================================
- +
- + //=============================================================================
- + // Follow WMAC RTL8225_Config()
- + //=============================================================================
- +// //
- +// // enable EEM0 and EEM1 in 9346CR
- +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)|0xc0);
- +// // enable PARM_En in Config3
- +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)|0x40);
- +//
- +// PlatformEFIOWrite4Byte(dev, AnaParm2, ANAPARM2_ASIC_ON); //0x727f3f52
- +// PlatformEFIOWrite4Byte(dev, AnaParm, ANAPARM_ASIC_ON); //0x45090658
- +
- + // power control
- + write_nic_byte(dev, CCK_TXAGC, 0x03);
- + write_nic_byte(dev, OFDM_TXAGC, 0x07);
- + write_nic_byte(dev, ANTSEL, 0x03);
- +
- +// // disable PARM_En in Config3
- +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)&0xbf);
- +// // disable EEM0 and EEM1 in 9346CR
- +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)&0x3f);
- + //=============================================================================
- +
- + //=============================================================================
- + // AGC.txt
- + //=============================================================================
- + //write_nic_dword( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
- + //write_phy_ofdm( dev, 0x00, 0x12); // David, 2006-08-01
- + write_phy_ofdm( dev, 0x80, 0x12); // David, 2006-08-09
- +
- + for (i=0; i<128; i++)
- + {
- + //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
- +
- + data = ZEBRA_AGC[i+1];
- + data = data << 8;
- + data = data | 0x0000008F;
- +
- + addr = i + 0x80; //enable writing AGC table
- + addr = addr << 8;
- + addr = addr | 0x0000008E;
- +
- + write_phy_ofdm(dev,data&0x7f,(data>>8)&0xff);
- + write_phy_ofdm(dev,addr&0x7f,(addr>>8)&0xff);
- + write_phy_ofdm(dev,0x0E,0x00);
- + }
- +
- + //write_nic_dword(dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
- + //write_phy_ofdm( dev, 0x00, 0x10); // David, 2006-08-01
- + write_phy_ofdm( dev, 0x80, 0x10); // David, 2006-08-09
- +
- + //=============================================================================
- +
- + //=============================================================================
- + // OFDMCONF.TXT
- + //=============================================================================
- +
- + for(i=0; i<60; i++)
- + {
- + u4bRegOffset=i;
- + u4bRegValue=OFDM_CONFIG[i];
- + //u4bRegValue=OFDM_CONFIG3m82[i];
- +
- + // write_nic_dword(dev,PhyAddr,(0x00000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
- + write_phy_ofdm(dev,i,u4bRegValue);
- + }
- +
- +
- + //=============================================================================
- +}
- +
- +void ZEBRA_Config_87BASIC(struct net_device *dev)
- +{
- + ZEBRA_Config_87BASIC_HardCode(dev);
- +}
- +//by amy for DIG
- +//
- +// Description:
- +// Update initial gain into PHY.
- +//
- +void
- +UpdateCCKThreshold(
- + struct net_device *dev
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + // Update CCK Power Detection(0x41) value.
- + switch(priv->StageCCKTh)
- + {
- + case 0:
- +// printk("Update CCK Stage 0: 88 \n");
- + write_phy_cck(dev, 0xc1, 0x88);mdelay(1);
- + break;
- +
- + case 1:
- +// printk("Update CCK Stage 1: 98 \n");
- + write_phy_cck(dev, 0xc1, 0x98);mdelay(1);
- + break;
- +
- + case 2:
- +// printk("Update CCK Stage 2: C8 \n");
- + write_phy_cck(dev, 0xc1, 0xC8);mdelay(1);
- + break;
- +
- + case 3:
- +// printk("Update CCK Stage 3: D8 \n");
- + write_phy_cck(dev, 0xc1, 0xD8);mdelay(1);
- + break;
- +
- + default:
- +// printk("Update CCK Stage %d ERROR!\n", pHalData->StageCCKTh);
- + break;
- + }
- +}
- +//
- +// Description:
- +// Update initial gain into PHY.
- +//
- +void
- +UpdateInitialGain(
- + struct net_device *dev
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //u8 u1Tmp=0;
- +
- + //printk("UpdateInitialGain(): InitialGain: %d RFChipID: %d\n", priv->InitialGain, priv->rf_chip);
- +
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + case RF_ZEBRA2:
- +
- + //
- + // Note:
- + // Whenever we update this gain table, we should be careful about those who call it.
- + // Functions which call UpdateInitialGain as follows are important:
- + // (1)StaRateAdaptive87B
- + // (2)DIG_Zebra
- + // (3)ActSetWirelessMode8187 (when the wireless mode is "B" mode, we set the
- + // OFDM[0x17] = 0x26 to improve the Rx sensitivity).
- + // By Bruce, 2007-06-01.
- + //
- +
- + //
- + // SD3 C.M. Lin Initial Gain Table, by Bruce, 2007-06-01.
- + //
- + switch(priv->InitialGain)
- + {
- + case 1: //m861dBm
- +// DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm ");
- + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
- + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
- + break;
- +
- + case 2: //m862dBm
- +// DMESG("RTL8187 + 8225 Initial Gain State 2: -78 dBm ");
- + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
- + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
- + break;
- +
- + case 3: //m863dBm
- +// DMESG("RTL8187 + 8225 Initial Gain State 3: -78 dBm ");
- + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
- + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
- + break;
- +
- + case 4: //m864dBm
- +// DMESG("RTL8187 + 8225 Initial Gain State 4: -74 dBm ");
- + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
- + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
- + break;
- +
- + case 5: //m82dBm
- +// DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm ");
- + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
- + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
- + break;
- +
- + case 6: //m78dBm
- +// DMESG("RTL8187 + 8225 Initial Gain State 6: -70 dBm ");
- + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
- + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
- + break;
- +
- + case 7: //m74dBm
- +// DMESG("RTL8187 + 8225 Initial Gain State 7: -70 dBm ");
- + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
- + write_phy_ofdm(dev, 0xa4, 0xa6); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
- + break;
- +
- + // By Bruce, 2007-03-29.
- + case 8:
- + write_phy_ofdm(dev, 0x97, 0x66); mdelay(1);
- + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
- + break;
- +
- + default: //MP
- +// DMESG("RTL8187 + 8225 Initial Gain State: -82 dBm (default), InitialGain(%d)", priv->InitialGain);
- + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
- + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
- + break;
- + }
- + break;
- +
- + default:
- + break;
- + }
- +}
- +//by amy for DIG
- +void PhyConfig8187(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 btConfig4;
- +
- + btConfig4 = read_nic_byte(dev, CONFIG4);
- + priv->RFProgType = (btConfig4 & 0x03);
- +
- +
- +
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA2:
- + ZEBRA_Config_87BASIC(dev);
- + break;
- + }
- + if(priv->bDigMechanism)
- + {
- + if(priv->InitialGain == 0)
- + priv->InitialGain = 4;
- + //DMESG("DIG is enabled, set default initial gain index to %d", priv->InitialGain);
- + }
- +
- + // By Bruce, 2007-03-29.
- + UpdateCCKThreshold(dev);
- + // Update initial gain after PhyConfig comleted, asked for by SD3 CMLin.
- + UpdateInitialGain(dev);
- + return ;
- +}
- +
- +u8 GetSupportedWirelessMode8187(struct net_device* dev)
- +{
- + u8 btSupportedWirelessMode;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + btSupportedWirelessMode = 0;
- +
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + case RF_ZEBRA2:
- + btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
- + break;
- + default:
- + btSupportedWirelessMode = WIRELESS_MODE_B;
- + break;
- + }
- + return btSupportedWirelessMode;
- +}
- +
- +void ActUpdateChannelAccessSetting(struct net_device *dev,
- + int WirelessMode,
- + PCHANNEL_ACCESS_SETTING ChnlAccessSetting)
- +{
- + AC_CODING eACI;
- + AC_PARAM AcParam;
- +#ifdef TODO
- + PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
- +#endif
- + //bool bFollowLegacySetting = false;
- +
- +
- + switch( WirelessMode )
- + {
- + case WIRELESS_MODE_A:
- + ChnlAccessSetting->SIFS_Timer = 0x22;
- + ChnlAccessSetting->DIFS_Timer = 34; // 34 = 16 + 2*9. 2006.06.07, by rcnjko.
- + ChnlAccessSetting->SlotTimeTimer = 9;
- + ChnlAccessSetting->EIFS_Timer = 23;
- + ChnlAccessSetting->CWminIndex = 4;
- + ChnlAccessSetting->CWmaxIndex = 10;
- + break;
- +
- + case WIRELESS_MODE_B:
- + ChnlAccessSetting->SIFS_Timer = 0x22;
- + ChnlAccessSetting->DIFS_Timer = 50; // 50 = 10 + 2*20. 2006.06.07, by rcnjko.
- + ChnlAccessSetting->SlotTimeTimer = 20;
- + ChnlAccessSetting->EIFS_Timer = 91;
- + ChnlAccessSetting->CWminIndex = 5;
- + ChnlAccessSetting->CWmaxIndex = 10;
- + break;
- +
- + case WIRELESS_MODE_G:
- + //
- + // <RJ_TODO_8185B>
- + // TODO: We still don't know how to set up these registers, just follow WMAC to
- + // verify 8185B FPAG.
- + //
- + // <RJ_TODO_8185B>
- + // Jong said CWmin/CWmax register are not functional in 8185B,
- + // so we shall fill channel access realted register into AC parameter registers,
- + // even in nQBss.
- + //
- + ChnlAccessSetting->SIFS_Timer = 0x22; // Suggested by Jong, 2005.12.08.
- + ChnlAccessSetting->SlotTimeTimer = 9; // 2006.06.07, by rcnjko.
- + ChnlAccessSetting->DIFS_Timer = 28; // 28 = 10 + 2*9. 2006.06.07, by rcnjko.
- + ChnlAccessSetting->EIFS_Timer = 0x5B; // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
- +#ifdef TODO
- + switch (Adapter->NdisUsbDev.CWinMaxMin)
- +#else
- + switch (2)
- +#endif
- + {
- + case 0:// 0: [max:7 min:1 ]
- + ChnlAccessSetting->CWminIndex = 1;
- + ChnlAccessSetting->CWmaxIndex = 7;
- + break;
- + case 1:// 1: [max:7 min:2 ]
- + ChnlAccessSetting->CWminIndex = 2;
- + ChnlAccessSetting->CWmaxIndex = 7;
- + break;
- + case 2:// 2: [max:7 min:3 ]
- + ChnlAccessSetting->CWminIndex = 3;
- + ChnlAccessSetting->CWmaxIndex = 7;
- + break;
- + case 3:// 3: [max:9 min:1 ]
- + ChnlAccessSetting->CWminIndex = 1;
- + ChnlAccessSetting->CWmaxIndex = 9;
- + break;
- + case 4:// 4: [max:9 min:2 ]
- + ChnlAccessSetting->CWminIndex = 2;
- + ChnlAccessSetting->CWmaxIndex = 9;
- + break;
- + case 5:// 5: [max:9 min:3 ]
- + ChnlAccessSetting->CWminIndex = 3;
- + ChnlAccessSetting->CWmaxIndex = 9;
- + break;
- + case 6:// 6: [max:A min:5 ]
- + ChnlAccessSetting->CWminIndex = 5;
- + ChnlAccessSetting->CWmaxIndex = 10;
- + break;
- + case 7:// 7: [max:A min:4 ]
- + ChnlAccessSetting->CWminIndex = 4;
- + ChnlAccessSetting->CWmaxIndex = 10;
- + break;
- +
- + default:
- + ChnlAccessSetting->CWminIndex = 1;
- + ChnlAccessSetting->CWmaxIndex = 7;
- + break;
- + }
- +#ifdef TODO
- + if( Adapter->MgntInfo.OpMode == RT_OP_MODE_IBSS)
- + {
- + ChnlAccessSetting->CWminIndex= 4;
- + ChnlAccessSetting->CWmaxIndex= 10;
- + }
- +#endif
- + break;
- + }
- +
- +
- + write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
- +//{ update slot time related by david, 2006-7-21
- + write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
- +#ifdef TODO
- + if(pStaQos->CurrentQosMode > QOS_DISABLE)
- + {
- + for(eACI = 0; eACI < AC_MAX; eACI++)
- + {
- + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, \
- + (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
- + }
- + }
- + else
- +#endif
- + {
- + u8 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
- +
- + write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
- + write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
- + write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
- + write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
- + }
- +//}
- +
- + write_nic_byte(dev, EIFS_8187B, ChnlAccessSetting->EIFS_Timer);
- + write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
- +#ifdef TODO
- + // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
- + if( pStaQos->CurrentQosMode > QOS_DISABLE )
- + { // QoS mode.
- + if(pStaQos->QBssWirelessMode == WirelessMode)
- + {
- + // Follow AC Parameters of the QBSS.
- + for(eACI = 0; eACI < AC_MAX; eACI++)
- + {
- + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
- + }
- + }
- + else
- + {
- + // Follow Default WMM AC Parameters.
- + bFollowLegacySetting = TRUE;
- + }
- + }
- + else
- + { // Legacy 802.11.
- + bFollowLegacySetting = TRUE;
- + }
- +
- + if(bFollowLegacySetting)
- +#endif
- + if(true)
- + {
- + //
- + // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
- + // 2005.12.01, by rcnjko.
- + //
- + AcParam.longData = 0;
- + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
- + AcParam.f.AciAifsn.f.ACM = 0;
- + AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; // Follow 802.11 CWmin.
- + AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; // Follow 802.11 CWmax.
- + AcParam.f.TXOPLimit = 0;
- + for(eACI = 0; eACI < AC_MAX; eACI++)
- + {
- + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
- + {
- + PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
- + AC_CODING eACI;
- + u8 u1bAIFS;
- + u32 u4bAcParam;
- +
- + // Retrive paramters to udpate.
- + eACI = pAcParam->f.AciAifsn.f.ACI;
- + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
- + u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
- + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
- + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
- + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
- +
- + switch(eACI)
- + {
- + case AC1_BK:
- + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
- + break;
- +
- + case AC0_BE:
- + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
- + break;
- +
- + case AC2_VI:
- + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
- + break;
- +
- + case AC3_VO:
- + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
- + break;
- +
- + default:
- + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
- + break;
- + }
- +
- + // Cehck ACM bit.
- + // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
- + //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
- + {
- + PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
- + AC_CODING eACI = pAciAifsn->f.ACI;
- +
- + //modified Joseph
- + //for 8187B AsynIORead issue
- +#ifdef TODO
- + u8 AcmCtrl = pHalData->AcmControl;
- +#else
- + u8 AcmCtrl = 0;
- +#endif
- + if( pAciAifsn->f.ACM )
- + { // ACM bit is 1.
- + switch(eACI)
- + {
- + case AC0_BE:
- + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21
- + break;
- +
- + case AC2_VI:
- + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42
- + break;
- +
- + case AC3_VO:
- + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84
- + break;
- +
- + default:
- + printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set\
- + failed: eACI is %d\n", eACI );
- + break;
- + }
- + }
- + else
- + { // ACM bit is 0.
- + switch(eACI)
- + {
- + case AC0_BE:
- + AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE
- + break;
- +
- + case AC2_VI:
- + AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD
- + break;
- +
- + case AC3_VO:
- + AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B
- + break;
- +
- + default:
- + break;
- + }
- + }
- +
- + //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
- +
- +#ifdef TO_DO
- + pHalData->AcmControl = AcmCtrl;
- +#endif
- + write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
- + }
- + }
- + }
- + }
- +}
- +
- +void ActSetWirelessMode8187(struct net_device* dev, u8 btWirelessMode)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- + //PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo);
- + u8 btSupportedWirelessMode = GetSupportedWirelessMode8187(dev);
- +
- + if( (btWirelessMode & btSupportedWirelessMode) == 0 )
- + { // Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko.
- + printk(KERN_WARNING "ActSetWirelessMode8187(): WirelessMode(%d) is not supported (%d)!\n",
- + btWirelessMode, btSupportedWirelessMode);
- + return;
- + }
- +
- + // 1. Assign wireless mode to swtich if necessary.
- + if( (btWirelessMode == WIRELESS_MODE_AUTO) ||
- + (btWirelessMode & btSupportedWirelessMode) == 0 )
- + {
- + if((btSupportedWirelessMode & WIRELESS_MODE_A))
- + {
- + btWirelessMode = WIRELESS_MODE_A;
- + }
- + else if((btSupportedWirelessMode & WIRELESS_MODE_G))
- + {
- + btWirelessMode = WIRELESS_MODE_G;
- + }
- + else if((btSupportedWirelessMode & WIRELESS_MODE_B))
- + {
- + btWirelessMode = WIRELESS_MODE_B;
- + }
- + else
- + {
- + printk(KERN_WARNING "MptActSetWirelessMode8187(): No valid wireless mode supported, \
- + btSupportedWirelessMode(%x)!!!\n", btSupportedWirelessMode);
- + btWirelessMode = WIRELESS_MODE_B;
- + }
- + }
- +
- + // 2. Swtich band.
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA:
- + case RF_ZEBRA2:
- + {
- + // Update current wireless mode if we swtich to specified band successfully.
- + ieee->mode = (WIRELESS_MODE)btWirelessMode;
- + }
- + break;
- +
- + default:
- + printk(KERN_WARNING "MptActSetWirelessMode8187(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
- + break;
- + }
- +
- + // 4. Change related setting.
- +#if 0
- + if( ieee->mode == WIRELESS_MODE_A ){
- + DMESG("WIRELESS_MODE_A");
- + }
- + else if(ieee->mode == WIRELESS_MODE_B ){
- + DMESG("WIRELESS_MODE_B");
- + }
- + else if( ieee->mode == WIRELESS_MODE_G ){
- + DMESG("WIRELESS_MODE_G");
- + }
- +#endif
- + ActUpdateChannelAccessSetting(dev, ieee->mode, &priv->ChannelAccessSetting );
- +//by amy 0305
- +#ifdef TODO
- + if(ieee->mode == WIRELESS_MODE_B && priv->InitialGain > pHalData->RegBModeGainStage)
- + {
- + pHalData->InitialGain = pHalData->RegBModeGainStage; // B mode, OFDM[0x17] = 26.
- + RT_TRACE(COMP_INIT | COMP_DIG, DBG_LOUD, ("ActSetWirelessMode8187(): update init_gain to index %d for B mode\n",pHalData->InitialGain));
- + PlatformScheduleWorkItem( &(pHalData->UpdateDigWorkItem) );
- + }
- +// pAdapter->MgntInfo.dot11CurrentWirelessMode = pHalData->CurrentWirelessMode;
- +// MgntSetRegdot11OperationalRateSet( pAdapter );
- +#endif
- +//by amy 0305
- +}
- +
- +
- +void
- +InitializeExtraRegsOn8185(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- + //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
- + bool bUNIVERSAL_CONTROL_RL = false; // Enable per-packet tx retry, 2005.03.31, by rcnjko.
- + bool bUNIVERSAL_CONTROL_AGC = true;//false;
- + bool bUNIVERSAL_CONTROL_ANT = true;//false;
- + bool bAUTO_RATE_FALLBACK_CTL = true;
- + u8 val8;
- +
- + // Set up ACK rate.
- + // Suggested by wcchu, 2005.08.25, by rcnjko.
- + // 1. Initialize (MinRR, MaxRR) to (6,24) for A/G.
- + // 2. MUST Set RR before BRSR.
- + // 3. CCK must be basic rate.
- + if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
- + {
- + write_nic_word(dev, BRSR_8187B, 0x0fff);
- + }
- + else
- + {
- + write_nic_word(dev, BRSR_8187B, 0x000f);
- + }
- +
- +
- + // Retry limit
- + val8 = read_nic_byte(dev, CW_CONF);
- + if(bUNIVERSAL_CONTROL_RL)
- + {
- + val8 &= (~CW_CONF_PERPACKET_RETRY_LIMIT);
- + }
- + else
- + {
- + val8 |= CW_CONF_PERPACKET_RETRY_LIMIT;
- + }
- +
- + write_nic_byte(dev, CW_CONF, val8);
- +
- + // Tx AGC
- + val8 = read_nic_byte(dev, TX_AGC_CTL);
- + if(bUNIVERSAL_CONTROL_AGC)
- + {
- + val8 &= (~TX_AGC_CTL_PER_PACKET_TXAGC);
- + write_nic_byte(dev, CCK_TXAGC, 128);
- + write_nic_byte(dev, OFDM_TXAGC, 128);
- + }
- + else
- + {
- + val8 |= TX_AGC_CTL_PER_PACKET_TXAGC;
- + }
- + write_nic_byte(dev, TX_AGC_CTL, val8);
- +
- + // Tx Antenna including Feedback control
- + val8 = read_nic_byte(dev, TX_AGC_CTL);
- +
- + if(bUNIVERSAL_CONTROL_ANT)
- + {
- + write_nic_byte(dev, ANTSEL, 0x00);
- + val8 &= (~TXAGC_CTL_PER_PACKET_ANT_SEL);
- + }
- + else
- + {
- + val8 |= TXAGC_CTL_PER_PACKET_ANT_SEL;
- + }
- + write_nic_byte(dev, TX_AGC_CTL, val8);
- +
- + // Auto Rate fallback control
- + val8 = read_nic_byte(dev, RATE_FALLBACK);
- + if( bAUTO_RATE_FALLBACK_CTL )
- + {
- + val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP0;
- +
- + // <RJ_TODO_8187B> We shall set up the ARFR according to user's setting.
- + write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
- + }
- + else
- + {
- + val8 &= (~RATE_FALLBACK_CTL_ENABLE);
- + }
- + write_nic_byte(dev, RATE_FALLBACK, val8);
- +
- +}
- +///////////////////////////
- +void rtl8225z2_rf_init(struct net_device *dev)
- +{
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + if (NIC_8187B == priv->card_8187){
- + struct ieee80211_device *ieee = priv->ieee80211;
- + u8 InitWirelessMode;
- + u8 SupportedWirelessMode;
- + bool bInvalidWirelessMode = false;
- + InitializeExtraRegsOn8185(dev);
- +
- + write_nic_byte(dev, MSR, read_nic_byte(dev,MSR) & 0xf3); // default network type to 'No Link'
- + //{to avoid tx stall
- + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR)|MSR_LINK_ENEDCA);//should always set ENDCA bit
- + write_nic_byte(dev, ACM_CONTROL, priv->AcmControl);
- +
- + write_nic_word(dev, BcnIntv, 100);
- + write_nic_word(dev, AtimWnd, 2);
- + write_nic_word(dev, FEMR, 0xFFFF);
- + //LED TYPE
- + {
- + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
- + }
- + write_nic_byte(dev, CR9346, 0x0); // disable config register write
- +
- + //{ add some info here
- + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
- + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
- +
- + write_nic_byte(dev, WPA_CONFIG, 0);
- + //}
- +
- + MacConfig_87BASIC(dev);
- +
- + // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
- + write_nic_word(dev, RFSW_CTRL, 0x569a);
- +#ifdef JOHN_TKIP
- + {
- + void CamResetAllEntry(struct net_device *dev);
- + void EnableHWSecurityConfig8187(struct net_device *dev);
- + CamResetAllEntry(dev);
- + EnableHWSecurityConfig8187(dev);
- + write_nic_word(dev, AESMSK_FC, AESMSK_FC_DEFAULT); mdelay(1);
- + write_nic_word(dev, AESMSK_SC, AESMSK_SC_DEFAULT); mdelay(1);
- + write_nic_word(dev, AESMSK_QC, AESMSK_QC_DEFAULT); mdelay(1);
- + }
- +#endif
- + //-----------------------------------------------------------------------------
- + // Set up PHY related.
- + //-----------------------------------------------------------------------------
- + // Enable Config3.PARAM_En to revise AnaaParm.
- + write_nic_byte(dev, CR9346, 0xC0);
- + write_nic_byte(dev, CONFIG3, read_nic_byte(dev,CONFIG3)|CONFIG3_PARM_En);
- + write_nic_byte(dev, CR9346, 0x0);
- +
- + // Initialize RFE and read Zebra2 version code. Added by Annie, 2005-08-01.
- + SetupRFEInitialTiming(dev);
- + // PHY config.
- + PhyConfig8187(dev);
- +
- + // We assume RegWirelessMode has already been initialized before,
- + // however, we has to validate the wireless mode here and provide a reasonble
- + // initialized value if necessary. 2005.01.13, by rcnjko.
- + SupportedWirelessMode = GetSupportedWirelessMode8187(dev);
- +
- + if((ieee->mode != WIRELESS_MODE_B) &&
- + (ieee->mode != WIRELESS_MODE_G) &&
- + (ieee->mode != WIRELESS_MODE_A) &&
- + (ieee->mode != WIRELESS_MODE_AUTO))
- + { // It should be one of B, G, A, or AUTO.
- + bInvalidWirelessMode = true;
- + }
- + else
- + { // One of B, G, A, or AUTO.
- + // Check if the wireless mode is supported by RF.
- + if( (ieee->mode != WIRELESS_MODE_AUTO) &&
- + (ieee->mode & SupportedWirelessMode) == 0 )
- + {
- + bInvalidWirelessMode = true;
- + }
- + }
- +
- + if(bInvalidWirelessMode || ieee->mode==WIRELESS_MODE_AUTO)
- + { // Auto or other invalid value.
- + // Assigne a wireless mode to initialize.
- + if((SupportedWirelessMode & WIRELESS_MODE_A))
- + {
- + InitWirelessMode = WIRELESS_MODE_A;
- + }
- + else if((SupportedWirelessMode & WIRELESS_MODE_G))
- + {
- +
- + InitWirelessMode = WIRELESS_MODE_G;
- + }
- + else if((SupportedWirelessMode & WIRELESS_MODE_B))
- + {
- +
- + InitWirelessMode = WIRELESS_MODE_B;
- + }
- + else
- + {
- + printk(KERN_WARNING
- + "InitializeAdapter8187(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
- + SupportedWirelessMode);
- + InitWirelessMode = WIRELESS_MODE_B;
- + }
- +
- + // Initialize RegWirelessMode if it is not a valid one.
- + if(bInvalidWirelessMode)
- + {
- + ieee->mode = (WIRELESS_MODE)InitWirelessMode;
- + }
- + }
- + else
- + { // One of B, G, A.
- + InitWirelessMode = ieee->mode;
- + }
- + ActSetWirelessMode8187(dev, (u8)(InitWirelessMode));
- + {//added for init gain
- + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
- + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
- + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
- + write_phy_cck(dev, 0xc1, 0x88); mdelay(1);
- + }
- +
- + }
- + else{
- + int i;
- + short channel = 1;
- + u16 brsr;
- + u32 data,addr;
- +
- + priv->chan = channel;
- +
- + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
- +
- + if(priv->card_type == USB)
- + rtl8225_host_usb_init(dev);
- + else
- + rtl8225_host_pci_init(dev);
- +
- + write_nic_dword(dev, RF_TIMING, 0x000a8008);
- +
- + brsr = read_nic_word(dev, BRSR_8187);
- +
- + write_nic_word(dev, BRSR_8187, 0xffff);
- +
- +
- + write_nic_dword(dev, RF_PARA, 0x100044);
- +
- + #if 1 //0->1
- + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- + write_nic_byte(dev, CONFIG3, 0x44);
- + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
- + #endif
- +
- +
- + rtl8185_rf_pins_enable(dev);
- +
- + // mdelay(1000);
- +
- + write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
- +
- +
- + write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
- +
- + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
- +
- + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
- +
- +
- + write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
- +
- +
- +
- + write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
- + // }
- +
- + write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
- +
- + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
- +
- + write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
- +
- + write_rtl8225(dev, 0x9, 0x335); mdelay(1);
- +
- + write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
- +
- + write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
- +
- + write_rtl8225(dev, 0xc, 0x850); mdelay(1);
- +
- +
- + write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
- +
- + write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
- +
- + write_rtl8225(dev, 0xf, 0x114);
- +
- +
- + mdelay(100);
- +
- +
- + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
- + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
- +
- + write_rtl8225(dev, 0x0, 0x1b7);
- +
- + for(i=0;i<95;i++){
- + write_rtl8225(dev, 0x1, (u8)(i+1));
- + /* version B & C & D*/
- + write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
- + }
- + //write_rtl8225(dev, 0x3, 0x80);
- + write_rtl8225(dev, 0x3, 0x2);
- + write_rtl8225(dev, 0x5, 0x4);
- +
- + write_rtl8225(dev, 0x0, 0xb7);
- +
- + write_rtl8225(dev, 0x2, 0xc4d);
- +
- + if(priv->card_type == USB){
- + // force_pci_posting(dev);
- + mdelay(200);
- +
- + write_rtl8225(dev, 0x2, 0x44d);
- +
- + // force_pci_posting(dev);
- + mdelay(200);
- +
- + }//End of if(priv->card_type == USB)
- + /* FIXME!! rtl8187 we have to check if calibrarion
- + * is successful and eventually cal. again (repeat
- + * the two write on reg 2)
- + */
- + // Check for calibration status, 2005.11.17,
- + data = read_rtl8225(dev, 6);
- + if (!(data&0x00000080))
- + {
- + write_rtl8225(dev, 0x02, 0x0c4d);
- + force_pci_posting(dev); mdelay(200);
- + write_rtl8225(dev, 0x02, 0x044d);
- + force_pci_posting(dev); mdelay(100);
- + data = read_rtl8225(dev, 6);
- + if (!(data&0x00000080))
- + {
- + DMESGW("RF Calibration Failed!!!!\n");
- + }
- + }
- + //force_pci_posting(dev);
- +
- + mdelay(200); //200 for 8187
- +
- +
- + // //if(priv->card_type != USB){
- + // write_rtl8225(dev, 0x2, 0x44d);
- + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
- + // write_rtl8225(dev, 0x2, 0x47d);
- + //
- + // force_pci_posting(dev);
- + // mdelay(100);
- + //
- + // write_rtl8225(dev, 0x2, 0x44d);
- + // //}
- +
- + write_rtl8225(dev, 0x0, 0x2bf);
- +
- + if(priv->card_type != USB)
- + rtl8185_rf_pins_enable(dev);
- + //set up ZEBRA AGC table, 2005.11.17,
- + for(i=0;i<128;i++){
- + data = rtl8225_agc[i];
- +
- + addr = i + 0x80; //enable writing AGC table
- + write_phy_ofdm(dev, 0xb, data);
- +
- + mdelay(1);
- + write_phy_ofdm(dev, 0xa, addr);
- +
- + mdelay(1);
- + }
- +
- + force_pci_posting(dev);
- + mdelay(1);
- +
- + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
- + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
- + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
- + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
- + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
- + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
- +
- + write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
- +
- + //write_phy_ofdm(dev, 0x18, 0xef);
- + // }
- + //}
- + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
- +
- + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
- +
- +
- + //if(priv->card_type != USB)
- + write_phy_ofdm(dev, 0xd, 0x43);
- +
- + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
- +
- + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
- + /*ver D & 8187*/
- + // }
- +
- + // if(priv->card_8185 == 1 && priv->card_8185_Bversion)
- + // write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
- + // else
- + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
- + /*ver C & D & 8187*/
- +
- + write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
- + /*agc resp time 700*/
- +
- +
- + // if(priv->card_8185 == 2){
- + /* Ver D & 8187*/
- + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
- + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
- + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
- +
- + // if (priv->card_type == USB)
- + // write_phy_ofdm(dev, 0x18, 0xef);
- +
- + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
- +
- +
- + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
- + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
- + write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
- +
- + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
- +
- + // }
- +
- + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
- +
- + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
- +
- + // if(priv->card_type != USB)
- + write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
- +
- + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
- + write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
- + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
- +
- + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
- +
- +
- + // <> Set init. gain to m74dBm.
- +
- + rtl8225z2_set_gain(dev,4);
- + //rtl8225z2_set_gain(dev,2);
- +
- + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
- + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
- + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
- + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
- + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
- + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
- + /* Ver C & D & 8187*/
- + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
- +
- + write_phy_cck(dev, 0x9, 0x11);mdelay(1);
- + write_phy_cck(dev, 0xa, 0x17);mdelay(1);
- + write_phy_cck(dev, 0xb, 0x11);mdelay(1);
- +
- + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
- + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
- + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
- + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
- +
- + write_phy_cck(dev, 0x19, 0x0); mdelay(1);
- + write_phy_cck(dev, 0x1a, 0xa0); mdelay(1);
- + write_phy_cck(dev, 0x1b, 0x8); mdelay(1);
- + write_phy_cck(dev, 0x1d, 0x0); mdelay(1);
- +
- + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */ mdelay(1);
- +
- + write_phy_cck(dev, 0x41, 0x9d);mdelay(1);
- +
- +
- + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
- + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
- +
- +
- + write_phy_cck(dev, 0x44, 0x36); mdelay(1);
- + write_phy_cck(dev, 0x45, 0x35); mdelay(1);
- + write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
- + write_phy_cck(dev, 0x47, 0x25); mdelay(1);
- + write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
- + write_phy_cck(dev, 0x49, 0x12); mdelay(1);
- + write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
- + write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
- + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
- +
- +
- + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
- +
- +
- +
- + // <>
- + // // TESTR 0xb 8187
- + // write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
- + //
- + // //if(priv->card_type != USB){
- + // write_phy_ofdm(dev, 0x2, 0x62);
- + // write_phy_ofdm(dev, 0x6, 0x0);
- + // write_phy_ofdm(dev, 0x8, 0x0);
- + // //}
- +
- + rtl8225z2_SetTXPowerLevel(dev, channel);
- +
- + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
- + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
- +
- + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
- +
- + /* switch to high-speed 3-wire
- + * last digit. 2 for both cck and ofdm
- + */
- + if(priv->card_type == USB)
- + write_nic_dword(dev, 0x94, 0x3dc00002);
- + else{
- + write_nic_dword(dev, 0x94, 0x15c00002);
- + rtl8185_rf_pins_enable(dev);
- + }
- +
- + // if(priv->card_type != USB)
- + // rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
- + // rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
- + //
- + // /* make sure is waken up! */
- + // write_rtl8225(dev,0x4, 0x9ff);
- + // rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
- + // rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
- +
- + rtl8225_rf_set_chan(dev, priv->chan);
- +
- + //write_nic_word(dev,BRSR,brsr);
- +
- + //rtl8225z2_rf_set_mode(dev);
- + }
- +}
- +
- +void rtl8225z2_rf_set_mode(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(priv->ieee80211->mode == IEEE_A)
- + {
- + write_rtl8225(dev, 0x5, 0x1865);
- + write_nic_dword(dev, RF_PARA, 0x10084);
- + write_nic_dword(dev, RF_TIMING, 0xa8008);
- + write_phy_ofdm(dev, 0x0, 0x0);
- + write_phy_ofdm(dev, 0xa, 0x6);
- + write_phy_ofdm(dev, 0xb, 0x99);
- + write_phy_ofdm(dev, 0xf, 0x20);
- + write_phy_ofdm(dev, 0x11, 0x7);
- +
- + rtl8225z2_set_gain(dev,4);
- +
- + write_phy_ofdm(dev,0x15, 0x40);
- + write_phy_ofdm(dev,0x17, 0x40);
- +
- + write_nic_dword(dev, 0x94,0x10000000);
- + }else{
- +
- + write_rtl8225(dev, 0x5, 0x1864);
- + write_nic_dword(dev, RF_PARA, 0x10044);
- + write_nic_dword(dev, RF_TIMING, 0xa8008);
- + write_phy_ofdm(dev, 0x0, 0x1);
- + write_phy_ofdm(dev, 0xa, 0x6);
- + write_phy_ofdm(dev, 0xb, 0x99);
- + write_phy_ofdm(dev, 0xf, 0x20);
- + write_phy_ofdm(dev, 0x11, 0x7);
- +
- + rtl8225z2_set_gain(dev,4);
- +
- + write_phy_ofdm(dev,0x15, 0x40);
- + write_phy_ofdm(dev,0x17, 0x40);
- +
- + write_nic_dword(dev, 0x94,0x04000002);
- + }
- +}
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.c linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,2067 @@
- +/*
- + This file contains wireless extension handlers.
- +
- + This is part of rtl8180 OpenSource driver.
- + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +
- + Parts of this driver are based on the GPL part
- + of the official realtek driver.
- +
- + Parts of this driver are based on the rtl8180 driver skeleton
- + from Patric Schenke & Andres Salomon.
- +
- + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
- +
- + We want to tanks the Authors of those projects and the Ndiswrapper
- + project Authors.
- +*/
- +
- +
- +
- +#include "r8187.h"
- +#include "r8180_hw.h"
- +//added 1117
- +#include "ieee80211/ieee80211.h"
- +#ifdef ENABLE_DOT11D
- +#include "dot11d.h"
- +#endif
- +
- +
- +//#define RATE_COUNT 4
- +u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
- + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
- +#define RATE_COUNT sizeof(rtl8180_rates)/(sizeof(rtl8180_rates[0]))
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +#define IW_MODE_MESH 11
- +static int r8180_wx_join_mesh(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +static int r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +static int r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +#endif
- +
- +static int r8180_wx_get_freq(struct net_device *dev,
- + struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
- +}
- +
- +
- +#if 0
- +
- +static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
- + union iwreq_data *wrqu, char *b)
- +{
- + int *parms = (int *)b;
- + int bi = parms[0];
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- + down(&priv->wx_sem);
- + DMESG("setting beacon interval to %x",bi);
- +
- + priv->ieee80211->beacon_interval=bi;
- + rtl8180_commit(dev);
- + up(&priv->wx_sem);
- +
- + return 0;
- +}
- +
- +
- +static int r8180_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv=ieee80211_priv(dev);
- + int *parms = (int *)extra;
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + priv->ieee80211->force_associate = (parms[0] > 0);
- +
- +
- + return 0;
- +}
- +
- +#endif
- +static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + struct r8180_priv *priv=ieee80211_priv(dev);
- +
- + return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
- +}
- +
- +
- +
- +static int r8180_wx_get_rate(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
- +}
- +
- +
- +
- +static int r8180_wx_set_rate(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + int ret;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +
- + ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
- +
- + up(&priv->wx_sem);
- +
- + return ret;
- +}
- +#ifdef JOHN_IOCTL
- +u16 read_rtl8225(struct net_device *dev, u8 addr);
- +void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
- +u32 john_read_rtl8225(struct net_device *dev, u8 adr);
- +void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
- +
- +static int r8180_wx_read_regs(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 addr = 0;
- + u16 data1;
- +
- + down(&priv->wx_sem);
- +
- +
- + get_user(addr,(u8*)wrqu->data.pointer);
- + data1 = read_rtl8225(dev, addr);
- + wrqu->data.length = data1;
- +
- + up(&priv->wx_sem);
- + return 0;
- +
- +}
- +
- +static int r8180_wx_write_regs(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 addr = 0;
- +
- + down(&priv->wx_sem);
- +
- + get_user(addr, (u8*)wrqu->data.pointer);
- + write_rtl8225(dev, addr, wrqu->data.length);
- +
- + up(&priv->wx_sem);
- + return 0;
- +
- +}
- +
- +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
- +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
- +
- +static int r8180_wx_read_bb(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 databb;
- +#if 0
- + int i;
- + for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
- +#endif
- +
- + down(&priv->wx_sem);
- +
- + databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
- + wrqu->data.length = databb;
- +
- + up(&priv->wx_sem);
- + return 0;
- +}
- +
- +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
- +static int r8180_wx_write_bb(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 databb = 0;
- +
- + down(&priv->wx_sem);
- +
- + get_user(databb, (u8*)wrqu->data.pointer);
- + rtl8187_write_phy(dev, wrqu->data.length, databb);
- +
- + up(&priv->wx_sem);
- + return 0;
- +
- +}
- +
- +
- +static int r8180_wx_write_nicb(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u32 addr = 0;
- +
- + down(&priv->wx_sem);
- +
- + get_user(addr, (u32*)wrqu->data.pointer);
- + write_nic_byte(dev, addr, wrqu->data.length);
- +
- + up(&priv->wx_sem);
- + return 0;
- +
- +}
- +static int r8180_wx_read_nicb(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u32 addr = 0;
- + u16 data1;
- +
- + down(&priv->wx_sem);
- +
- + get_user(addr,(u32*)wrqu->data.pointer);
- + data1 = read_nic_byte(dev, addr);
- + wrqu->data.length = data1;
- +
- + up(&priv->wx_sem);
- + return 0;
- +}
- +
- +static inline int is_same_network(struct ieee80211_network *src,
- + struct ieee80211_network *dst,
- + struct ieee80211_device *ieee)
- +{
- + /* A network is only a duplicate if the channel, BSSID, ESSID
- + * and the capability field (in particular IBSS and BSS) all match.
- + * We treat all <hidden> with the same BSSID and channel
- + * as one network */
- + return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
- + //((src->ssid_len == dst->ssid_len) &&
- + (src->channel == dst->channel) &&
- + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
- + (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
- + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
- + ((src->capability & WLAN_CAPABILITY_IBSS) ==
- + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
- + ((src->capability & WLAN_CAPABILITY_BSS) ==
- + (dst->capability & WLAN_CAPABILITY_BSS)));
- +}
- +
- +static int r8180_wx_get_ap_status(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- + struct ieee80211_network *target;
- + int name_len;
- +
- + down(&priv->wx_sem);
- +
- + //count the length of input ssid
- + for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
- +
- + //search for the correspoding info which is received
- + list_for_each_entry(target, &ieee->network_list, list) {
- + if ( (target->ssid_len == name_len) &&
- + (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
- + if( ((jiffies-target->last_scanned)/HZ > 1) && (ieee->state == IEEE80211_LINKED) && (is_same_network(&ieee->current_network,target, ieee)) )
- + wrqu->data.length = 999;
- + else
- + wrqu->data.length = target->SignalStrength;
- + if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
- + //set flags=1 to indicate this ap is WPA
- + wrqu->data.flags = 1;
- + else wrqu->data.flags = 0;
- +
- +
- + break;
- + }
- + }
- +
- + if (&target->list == &ieee->network_list){
- + wrqu->data.flags = 3;
- + }
- + up(&priv->wx_sem);
- + return 0;
- +}
- +
- +
- +
- +#endif
- +
- +static int r8180_wx_set_rawtx(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int ret;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +
- + ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
- +
- + up(&priv->wx_sem);
- +
- + return ret;
- +
- +}
- +
- +static int r8180_wx_set_crcmon(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int *parms = (int *)extra;
- + int enable = (parms[0] > 0);
- + short prev = priv->crcmon;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +
- + if(enable)
- + priv->crcmon=1;
- + else
- + priv->crcmon=0;
- +
- + DMESG("bad CRC in monitor mode are %s",
- + priv->crcmon ? "accepted" : "rejected");
- +
- + if(prev != priv->crcmon && priv->up){
- + rtl8180_down(dev);
- + rtl8180_up(dev);
- + }
- +
- + up(&priv->wx_sem);
- +
- + return 0;
- +}
- +
- +static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int ret;
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)) return 0;
- +#endif
- + down(&priv->wx_sem);
- +
- +#ifdef CONFIG_IPS
- + if(priv->bInactivePs){
- + if(wrqu->mode != IW_MODE_INFRA){
- + down(&priv->ieee80211->ips_sem);
- + IPSLeave(dev);
- + up(&priv->ieee80211->ips_sem);
- + }
- + }
- +#endif
- + ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
- +
- + rtl8187_set_rxconf(dev);
- +
- + up(&priv->wx_sem);
- + return ret;
- +}
- +
- +
- +//YJ,add,080819,for hidden ap
- +struct iw_range_with_scan_capa
- +{
- + /* Informative stuff (to choose between different interface) */
- + __u32 throughput; /* To give an idea... */
- + /* In theory this value should be the maximum benchmarked
- + * TCP/IP throughput, because with most of these devices the
- + * bit rate is meaningless (overhead an co) to estimate how
- + * fast the connection will go and pick the fastest one.
- + * I suggest people to play with Netperf or any benchmark...
- + */
- +
- + /* NWID (or domain id) */
- + __u32 min_nwid; /* Minimal NWID we are able to set */
- + __u32 max_nwid; /* Maximal NWID we are able to set */
- +
- + /* Old Frequency (backward compat - moved lower ) */
- + __u16 old_num_channels;
- + __u8 old_num_frequency;
- +
- + /* Scan capabilities */
- + __u8 scan_capa;
- +};
- +//YJ,add,080819,for hidden ap
- +
- +static int rtl8180_wx_get_range(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct iw_range *range = (struct iw_range *)extra;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u16 val;
- + int i;
- + struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
- +
- + wrqu->data.length = sizeof(*range);
- + memset(range, 0, sizeof(*range));
- +
- + /* Let's try to keep this struct in the same order as in
- + * linux/include/wireless.h
- + */
- +
- + /* TODO: See what values we can set, and remove the ones we can't
- + * set, or fill them with some default data.
- + */
- +
- + /* ~5 Mb/s real (802.11b) */
- + range->throughput = 5 * 1000 * 1000;
- +
- + // TODO: Not used in 802.11b?
- +// range->min_nwid; /* Minimal NWID we are able to set */
- + // TODO: Not used in 802.11b?
- +// range->max_nwid; /* Maximal NWID we are able to set */
- +
- + /* Old Frequency (backward compat - moved lower ) */
- +// range->old_num_channels;
- +// range->old_num_frequency;
- +// range->old_freq[6]; /* Filler to keep "version" at the same offset */
- + if(priv->rf_set_sens != NULL)
- + range->sensitivity = priv->max_sens; /* signal level threshold range */
- +
- + range->max_qual.qual = 100;
- + /* TODO: Find real max RSSI and stick here */
- + range->max_qual.level = 0;
- + range->max_qual.noise = -98;
- + range->max_qual.updated = 7; /* Updated all three */
- +
- + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
- + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
- + range->avg_qual.level = 20 + -98;
- + range->avg_qual.noise = 0;
- + range->avg_qual.updated = 7; /* Updated all three */
- +
- + range->num_bitrates = RATE_COUNT;
- +
- + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
- + range->bitrate[i] = rtl8180_rates[i];
- + }
- +
- + range->min_frag = MIN_FRAG_THRESHOLD;
- + range->max_frag = MAX_FRAG_THRESHOLD;
- +
- + range->pm_capa = 0;
- +
- + range->we_version_compiled = WIRELESS_EXT;
- + range->we_version_source = 16;
- +
- +// range->retry_capa; /* What retry options are supported */
- +// range->retry_flags; /* How to decode max/min retry limit */
- +// range->r_time_flags; /* How to decode max/min retry life */
- +// range->min_retry; /* Minimal number of retries */
- +// range->max_retry; /* Maximal number of retries */
- +// range->min_r_time; /* Minimal retry lifetime */
- +// range->max_r_time; /* Maximal retry lifetime */
- +
- + range->num_channels = 14;
- +
- + for (i = 0, val = 0; i < 14; i++) {
- +
- + // Include only legal frequencies for some countries
- +#ifdef ENABLE_DOT11D
- + if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
- +#else
- + if ((priv->ieee80211->channel_map)[i+1]) {
- +#endif
- + range->freq[val].i = i + 1;
- + range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
- + range->freq[val].e = 1;
- + val++;
- + } else {
- + // FIXME: do we need to set anything for channels
- + // we don't use ?
- + }
- +
- + if (val == IW_MAX_FREQUENCIES)
- + break;
- + }
- +
- + range->num_frequency = val;
- + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
- +
- + tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
- +
- + return 0;
- +}
- +
- +
- +static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device* ieee = priv->ieee80211;
- + int ret;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- + //printk("==============>%s()\n",__FUNCTION__);
- + if(!priv->up)
- + return -1;
- +
- + if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
- + {
- + struct iw_scan_req* req = (struct iw_scan_req*)b;
- + if (req->essid_len)
- + {
- + ieee->current_network.ssid_len = req->essid_len;
- + memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
- + }
- + }
- +
- + //set Tr switch to hardware control to scan more bss
- + if(priv->TrSwitchState == TR_SW_TX) {
- + //YJ,add,080611
- + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
- + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
- + //YJ,add,080611,end
- + priv->TrSwitchState = TR_HW_CONTROLLED;
- + }
- +#ifdef _RTL8187_EXT_PATCH_
- + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
- + r8180_wx_mesh_scan(dev,a,wrqu,b);
- + ret = 0;
- + }
- + else
- +#endif
- + {
- + down(&priv->wx_sem);
- + if(priv->ieee80211->state != IEEE80211_LINKED){
- + //printk("===>start no link scan\n");
- + //ieee80211_start_scan(priv->ieee80211);
- + //lzm mod 090115 because wq can't scan complete once
- + //because after start protocal wq scan is in doing
- + //so we should stop it first.
- + ieee80211_stop_scan(priv->ieee80211);
- + ieee80211_start_scan_syncro(priv->ieee80211);
- + ret = 0;
- + } else {
- + ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
- + }
- + up(&priv->wx_sem);
- + }
- + return ret;
- +}
- +
- +
- +static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- +
- + int ret;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(!priv->up) return -1;
- +#ifdef _RTL8187_EXT_PATCH_
- + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
- + ret = r8180_wx_get_mesh_list(dev, a, wrqu, b);
- + }
- + else
- +#endif
- + {
- + down(&priv->wx_sem);
- +
- + ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
- +
- + up(&priv->wx_sem);
- + }
- + return ret;
- +}
- +
- +
- +static int r8180_wx_set_essid(struct net_device *dev,
- + struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int ret;
- +#ifdef _RTL8187_EXT_PATCH_
- + struct ieee80211_device *ieee = priv->ieee80211;
- + char ch = 0;
- + char tmpmeshid[32];
- + char *p;
- + int tmpmeshid_len=0;
- + int i;
- + short proto_started;
- +#endif
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- + //printk("==========>%s()\n",__FUNCTION__);
- + down(&priv->wx_sem);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
- + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
- + ret= -E2BIG;
- + goto out;
- + }
- + if (wrqu->essid.flags && (wrqu->essid.length > 1)) {
- + memset(tmpmeshid,0,32);
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + tmpmeshid_len=wrqu->essid.length;
- +#else
- + tmpmeshid_len=wrqu->essid.length + 1;
- +#endif
- + p=b+tmpmeshid_len-2;
- + for(i=tmpmeshid_len-1;i>0;i--)
- + {
- + if((*p)=='@')
- + break;
- + p--;
- + }
- + if((i == 0) || (i == 1)){
- + printk("error:wrong meshid\n");
- + ret = -1;
- + goto out;
- + }
- +
- + memcpy(tmpmeshid,b,(i-1));
- + p++;
- + if((tmpmeshid_len-1-i)==1)
- + {
- + if(*p > '9'|| *p <= '0'){
- + goto out;
- + } else {
- + ch = *p - '0';
- + }
- + }
- + else if((tmpmeshid_len-1-i)==2)
- + {
- + if((*p == '1') && (*(p+1) >= '0') && (*(p+1) <= '9'))
- + ch = (*p - '0') * 10 + (*(p+1) - '0');
- + else
- + goto out;
- + }
- + else {
- + ret = 0;
- + goto out;
- + }
- + if(ch > 14)
- + {
- + ret = 0;
- + printk("channel is invalid: %d\n",ch);
- + goto out;
- + }
- + ieee->sync_scan_hurryup = 1;
- +
- + proto_started = ieee->proto_started;
- + if(proto_started)
- + ieee80211_stop_protocol(ieee);
- +
- + printk("==============>tmpmeshid is %s\n",tmpmeshid);
- + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, tmpmeshid);
- + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
- + r8180_wx_set_channel(dev, NULL, NULL, &ch);
- + if (proto_started)
- + ieee80211_start_protocol(ieee);
- + }
- + else{
- + printk("BUG:meshid is null\n");
- + ret=0;
- + goto out;
- + }
- +
- + ret = 0;
- + }
- + else
- +#endif
- + {
- + ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
- + }
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +out:
- +#endif
- + up(&priv->wx_sem);
- + return ret;
- +}
- +
- +
- +static int r8180_wx_get_essid(struct net_device *dev,
- + struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + int ret;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + down(&priv->wx_sem);
- +
- + ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
- +
- + up(&priv->wx_sem);
- +
- + return ret;
- +}
- +
- +
- +static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
- + union iwreq_data *wrqu, char *b)
- +{
- + int ret;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +
- + ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
- +
- + up(&priv->wx_sem);
- + return ret;
- +}
- +
- +static int r8180_wx_get_name(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
- +}
- +
- +
- +static int r8180_wx_set_frag(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + if (wrqu->frag.disabled)
- + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
- + else {
- + if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
- + wrqu->frag.value > MAX_FRAG_THRESHOLD)
- + return -EINVAL;
- +
- + priv->ieee80211->fts = wrqu->frag.value & ~0x1;
- + }
- +
- + return 0;
- +}
- +
- +
- +static int r8180_wx_get_frag(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + wrqu->frag.value = priv->ieee80211->fts;
- + wrqu->frag.fixed = 0; /* no auto select */
- + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
- +
- + return 0;
- +}
- +
- +
- +static int r8180_wx_set_wap(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *awrq,
- + char *extra)
- +{
- + int ret;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + //printk("in function %s\n",__FUNCTION__);
- +#ifdef _RTL8187_EXT_PATCH_
- + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)){
- + return 0;
- + }
- +#endif
- + down(&priv->wx_sem);
- +
- + ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
- +
- + up(&priv->wx_sem);
- + return ret;
- +
- +}
- +
- +
- +static int r8180_wx_get_wap(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
- +}
- +
- +
- +static int r8180_wx_get_enc(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *key)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
- +}
- +
- +static int r8180_wx_set_enc(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *key)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int ret;
- +#ifdef JOHN_HWSEC
- +// struct ieee80211_device *ieee = priv->ieee80211;
- +// u32 TargetContent;
- + u32 hwkey[4]={0,0,0,0};
- + u8 mask=0xff;
- + u32 key_idx=0;
- + u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
- + u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
- + {0x00,0x00,0x00,0x00,0x00,0x01},
- + {0x00,0x00,0x00,0x00,0x00,0x02},
- + {0x00,0x00,0x00,0x00,0x00,0x03} };
- + int i;
- +
- +#endif
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +
- + DMESG("Setting SW wep key");
- + ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
- +
- + up(&priv->wx_sem);
- +
- +#ifdef JOHN_HWSEC
- +
- + //sometimes, the length is zero while we do not type key value
- + if(wrqu->encoding.length!=0){
- +
- + for(i=0 ; i<4 ; i++){
- + hwkey[i] |= key[4*i+0]&mask;
- + if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
- + if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
- + hwkey[i] |= (key[4*i+1]&mask)<<8;
- + hwkey[i] |= (key[4*i+2]&mask)<<16;
- + hwkey[i] |= (key[4*i+3]&mask)<<24;
- + }
- +
- + #define CONF_WEP40 0x4
- + #define CONF_WEP104 0x14
- +
- + switch(wrqu->encoding.flags){
- + case 0:
- + case 1: key_idx = 0; break;
- + case 2: key_idx = 1; break;
- + case 3: key_idx = 2; break;
- + case 4: key_idx = 3; break;
- + default: break;
- + }
- +
- + if(wrqu->encoding.length==0x5){
- + setKey( dev,
- + key_idx, //EntryNo
- + key_idx, //KeyIndex
- + KEY_TYPE_WEP40, //KeyType
- + zero_addr[key_idx],
- + 0, //DefaultKey
- + hwkey); //KeyContent
- +
- + if(key_idx == 0){
- +
- + write_nic_byte(dev, WPA_CONFIG, 7);
- +
- + setKey( dev,
- + 4, //EntryNo
- + key_idx, //KeyIndex
- + KEY_TYPE_WEP40, //KeyType
- + broadcast_addr, //addr
- + 0, //DefaultKey
- + hwkey); //KeyContent
- + }
- + }
- +
- + else if(wrqu->encoding.length==0xd){
- + setKey( dev,
- + key_idx, //EntryNo
- + key_idx, //KeyIndex
- + KEY_TYPE_WEP104, //KeyType
- + zero_addr[key_idx],
- + 0, //DefaultKey
- + hwkey); //KeyContent
- +
- + if(key_idx == 0){
- +
- + write_nic_byte(dev, WPA_CONFIG, 7);
- +
- + setKey( dev,
- + 4, //EntryNo
- + key_idx, //KeyIndex
- + KEY_TYPE_WEP104, //KeyType
- + broadcast_addr, //addr
- + 0, //DefaultKey
- + hwkey); //KeyContent
- + }
- + }
- + else printk("wrong type in WEP, not WEP40 and WEP104\n");
- +
- + }
- +
- + //consider the setting different key index situation
- + //wrqu->encoding.flags = 801 means that we set key with index "1"
- + if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
- +
- + write_nic_byte(dev, WPA_CONFIG, 7);
- +
- + //copy wpa config from default key(key0~key3) to broadcast key(key5)
- + //
- + key_idx = (wrqu->encoding.flags & 0xf)-1 ;
- + write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
- + write_cam(dev, (4*6)+1, 0xffffffff);
- + write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
- + write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
- + write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
- + write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
- + }
- +
- +#endif /*JOHN_HWSEC*/
- + return ret;
- +}
- +
- +
- +static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
- + iwreq_data *wrqu, char *p){
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int *parms=(int*)p;
- + int mode=parms[0];
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + priv->ieee80211->active_scan = mode;
- +
- + return 1;
- +}
- +
- +
- +
- +static int r8180_wx_set_retry(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int err = 0;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +
- + if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
- + wrqu->retry.disabled){
- + err = -EINVAL;
- + goto exit;
- + }
- + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
- + err = -EINVAL;
- + goto exit;
- + }
- +
- + if(wrqu->retry.value > R8180_MAX_RETRY){
- + err= -EINVAL;
- + goto exit;
- + }
- + if (wrqu->retry.flags & IW_RETRY_MAX) {
- + priv->retry_rts = wrqu->retry.value;
- + DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
- +
- + }else {
- + priv->retry_data = wrqu->retry.value;
- + DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
- + }
- +
- + /* FIXME !
- + * We might try to write directly the TX config register
- + * or to restart just the (R)TX process.
- + * I'm unsure if whole reset is really needed
- + */
- +
- + rtl8180_commit(dev);
- + /*
- + if(priv->up){
- + rtl8180_rtx_disable(dev);
- + rtl8180_rx_enable(dev);
- + rtl8180_tx_enable(dev);
- +
- + }
- + */
- +exit:
- + up(&priv->wx_sem);
- +
- + return err;
- +}
- +
- +static int r8180_wx_get_retry(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +
- + wrqu->retry.disabled = 0; /* can't be disabled */
- +
- + if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
- + IW_RETRY_LIFETIME)
- + return -EINVAL;
- +
- + if (wrqu->retry.flags & IW_RETRY_MAX) {
- + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
- + wrqu->retry.value = priv->retry_rts;
- + } else {
- + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
- + wrqu->retry.value = priv->retry_data;
- + }
- + //DMESG("returning %d",wrqu->retry.value);
- +
- +
- + return 0;
- +}
- +
- +static int r8180_wx_get_sens(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + if(priv->rf_set_sens == NULL)
- + return -1; /* we have not this support for this radio */
- + wrqu->sens.value = priv->sens;
- + return 0;
- +}
- +
- +
- +static int r8180_wx_set_sens(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + short err = 0;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- + //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
- + if(priv->rf_set_sens == NULL) {
- + err= -1; /* we have not this support for this radio */
- + goto exit;
- + }
- + if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
- + priv->sens = wrqu->sens.value;
- + else
- + err= -EINVAL;
- +
- +exit:
- + up(&priv->wx_sem);
- +
- + return err;
- +}
- +
- +
- +static int dummy(struct net_device *dev, struct iw_request_info *a,
- + union iwreq_data *wrqu,char *b)
- +{
- + return -1;
- +}
- +static int r8180_wx_set_enc_ext(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //printk("===>%s()\n", __FUNCTION__);
- +
- + int ret=0;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- + ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
- + up(&priv->wx_sem);
- + return ret;
- +
- +}
- +static int r8180_wx_set_auth(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data* data, char *extra)
- +{
- + //printk("====>%s()\n", __FUNCTION__);
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int ret=0;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- + ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
- + up(&priv->wx_sem);
- + return ret;
- +}
- +
- +static int r8180_wx_set_mlme(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + //printk("====>%s()\n", __FUNCTION__);
- +
- + int ret=0;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +#if 1
- + ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
- +#endif
- + up(&priv->wx_sem);
- + return ret;
- +}
- +
- +static int r8180_wx_set_gen_ie(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data* data, char *extra)
- +{
- + //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
- + int ret=0;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- +#if 1
- + ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
- +#endif
- + up(&priv->wx_sem);
- + //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
- + return ret;
- +
- +
- +}
- +
- +#ifdef _RTL8187_EXT_PATCH_
- +/*
- + Output:
- + (case 1) Mesh: Enable. MESHID=[%s] (max length of %s is 32 bytes).
- + (case 2) Mesh: Disable.
- +*/
- +static int r8180_wx_get_meshinfo(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_meshinfo )
- + return 0;
- + return priv->mshobj->ext_patch_r8180_wx_get_meshinfo(dev, info, wrqu, extra);
- +}
- +
- +
- +static int r8180_wx_enable_mesh(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- +
- + int ret = 0;
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_enable_mesh )
- + return 0;
- +
- + down(&priv->wx_sem);
- + if(priv->mshobj->ext_patch_r8180_wx_enable_mesh(dev))
- + {
- + union iwreq_data tmprqu;
- + tmprqu.mode = ieee->iw_mode;
- + ieee->iw_mode = 0;
- + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
- + rtl8187_set_rxconf(dev);
- + }
- +
- + up(&priv->wx_sem);
- +
- + return ret;
- +
- +}
- +
- +static int r8180_wx_disable_mesh(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- +
- + int ret = 0;
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_disable_mesh )
- + return 0;
- +
- + down(&priv->wx_sem);
- + if(priv->mshobj->ext_patch_r8180_wx_disable_mesh(dev))
- + {
- + union iwreq_data tmprqu;
- + tmprqu.mode = ieee->iw_mode;
- + ieee->iw_mode = 999;
- + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
- + rtl8187_set_rxconf(dev);
- + }
- +
- + up(&priv->wx_sem);
- +
- + return ret;
- +}
- +
- +
- +int r8180_wx_set_channel(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + int ch = *extra;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + // is 11s ?
- + if (!priv->mshobj || (ieee->iw_mode != ieee->iw_ext_mode) || !priv->mshobj->ext_patch_r8180_wx_set_channel )
- + return 0;
- +
- + printk("set channel = %d\n", ch);
- + if ( ch < 0 )
- + {
- + ieee80211_start_scan(ieee); // auto
- + ieee->meshScanMode =2;
- + }
- + else
- + {
- +//#ifdef NETWORKMANAGER_UI
- + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
- + }
- +//#else
- + else{
- + down(&priv->wx_sem);}
- +//#endif
- + ieee->meshScanMode =0;
- + // ieee->set_chan(dev, ch);
- +//#ifdef _RTL8187_EXT_PATCH_
- + if(priv->mshobj->ext_patch_r8180_wx_set_channel)
- + {
- + priv->mshobj->ext_patch_r8180_wx_set_channel(ieee, ch);
- + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
- + }
- +//#endif
- + ieee->set_chan(ieee->dev, ch);
- + ieee->current_network.channel = ch;
- + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
- + ieee80211_ext_send_11s_beacon(ieee);
- +//#ifdef NETWORKMANAGER_UI
- + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
- + }
- +//#else
- + else{
- + up(&priv->wx_sem);}
- +//#endif
- + //up(&ieee->wx_sem);
- +
- + // ieee80211_stop_scan(ieee); // user set
- + //
- +
- + /*
- + netif_carrier_off(ieee->dev);
- +
- + if (ieee->data_hard_stop)
- + ieee->data_hard_stop(ieee->dev);
- +
- + ieee->state = IEEE80211_NOLINK;
- + ieee->link_change(ieee->dev);
- +
- + ieee->current_network.channel = fwrq->m;
- + ieee->set_chan(ieee->dev, ieee->current_network.channel);
- +
- +
- + if (ieee->data_hard_resume)
- + ieee->data_hard_resume(ieee->dev);
- +
- + netif_carrier_on(ieee->dev);
- + */
- +
- + }
- +
- + return 0;
- +}
- +
- +static int r8180_wx_set_meshID(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_meshID )
- + return 0;
- +
- + //printk("len=%d\n", wrqu->data.length);
- + //printk("\nCall setMeshid.");
- + return priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, wrqu->data.pointer);
- +}
- +
- +
- +/* reserved for future
- +static int r8180_wx_add_mac_allow(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow(dev, info, wrqu, extra);
- +}
- +
- +static int r8180_wx_del_mac_allow(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow(dev, info, wrqu, extra);
- +}
- +*/
- +static int r8180_wx_add_mac_deny(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny(dev, info, wrqu, extra);
- +}
- +
- +static int r8180_wx_del_mac_deny(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny(dev, info, wrqu, extra);
- +}
- +
- +/* reserved for future
- +static int r8180_wx_get_mac_allow(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_allow )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_get_mac_allow(dev, info, wrqu, extra);
- +}
- +*/
- +
- +static int r8180_wx_get_mac_deny(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_deny )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_get_mac_deny(dev, info, wrqu, extra);
- +}
- +
- +
- +static int r8180_wx_get_mesh_list(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mesh_list )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_get_mesh_list(dev, info, wrqu, extra);
- +}
- +
- +static int r8180_wx_mesh_scan(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_mesh_scan )
- + return 0;
- +
- + return priv->mshobj->ext_patch_r8180_wx_mesh_scan(dev, info, wrqu, extra);
- +}
- +
- +static int r8180_wx_join_mesh(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int index;
- + int ret=0;
- + char extmeshid[32];
- + int len=0;
- + char id[50], ch;
- +//#ifdef NETWORKMANAGER_UI
- +
- + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
- + printk("join mesh %s\n",extra);
- + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
- + ret= -E2BIG;
- + goto out;
- + }
- + //printk("wrqu->essid.length is %d\n",wrqu->essid.length);
- + //printk("wrqu->essid.flags is %d\n",wrqu->essid.flags);
- + if((wrqu->essid.length == 1) && (wrqu->essid.flags == 1)){
- + ret = 0;
- + goto out;
- + }
- + if (wrqu->essid.flags && wrqu->essid.length) {
- + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, extra, &ch))
- + {
- + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
- + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
- + r8180_wx_set_channel(dev, NULL, NULL, &ch);
- + }
- + else
- + printk("invalid mesh #\n");
- +
- + }
- +#if 0
- + else{
- + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, 0, &ch))
- + {
- + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
- + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
- + r8180_wx_set_channel(dev, NULL, NULL, &ch);
- + }
- + else
- + printk("invalid mesh #\n");
- +
- + }
- +#endif
- + }
- + else{
- +//#else
- + index = *(extra);
- +// printk("index=%d\n", index);
- +
- + if( ! priv->mshobj
- + || !priv->mshobj->ext_patch_r8180_wx_set_meshID
- + || !priv->mshobj->ext_patch_r8180_wx_get_selected_mesh )
- + return 0;
- +
- + if( priv->mshobj->ext_patch_r8180_wx_get_selected_mesh(dev, index, &ch, id) )
- + {
- + // printk("ch=%d, id=%s\n", ch, id);
- + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, id);
- + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
- + r8180_wx_set_channel(dev, NULL, NULL, &ch);
- + }
- + else
- + printk("invalid mesh #\n");
- + }
- +//#endif
- +out:
- + return ret;
- +}
- +
- +#endif // _RTL8187_EXT_PATCH_
- +
- +
- +static int r8180_wx_get_radion(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +// u8 addr;
- +
- + down(&priv->wx_sem);
- + if(priv->radion == 1) {
- + *(int *)extra = 1;
- + } else {
- +
- + *(int *)extra = 0;
- + }
- + up(&priv->wx_sem);
- + return 0;
- +
- +}
- +
- +static int r8180_wx_set_radion(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + int radion = *extra;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +// struct ieee80211_device *ieee = priv->ieee80211;
- + u8 btCR9346, btConfig3;
- + int i;
- + u16 u2bTFPC = 0;
- + u8 u1bTmp;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- + printk("set radion = %d\n", radion);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(ieee->iw_mode == ieee->iw_ext_mode) {
- + printk("mesh mode:: could not set radi on/off = %d\n", radion);
- + up(&priv->wx_sem);
- + return 0;
- + }
- +#endif
- + // Set EEM0 and EEM1 in 9346CR.
- + btCR9346 = read_nic_byte(dev, CR9346);
- + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
- + // Set PARM_En in Config3.
- + btConfig3 = read_nic_byte(dev, CONFIG3);
- + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
- +
- + if ( radion == 1) //radion off
- + {
- + printk("==================>RF on\n");
- + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
- + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
- + write_nic_byte(dev, CONFIG4, (priv->RFProgType));
- +
- + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
- + write_rtl8225(dev, 0x4, 0x9FF);
- +
- + u1bTmp = read_nic_byte(dev, 0x24E);
- + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
- + priv->radion = 1; //radion on
- + }
- + else
- + {
- + printk("==================>RF off\n");
- + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B; i++)
- + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
- + u2bTFPC = read_nic_word(dev, TFPC);
- + if(u2bTFPC == 0)
- + {
- + break;
- + }
- + else
- + {
- + printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
- + udelay(10);
- + }
- + }
- + if( i == MAX_DOZE_WAITING_TIMES_87B )
- + {
- + printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n",\
- + MAX_DOZE_WAITING_TIMES_87B, u2bTFPC);
- + }
- +
- + u1bTmp = read_nic_byte(dev, 0x24E);
- + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
- +
- + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
- + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
- +
- + write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
- +
- + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
- + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
- + priv->radion = 0; //radion off
- + }
- + // Clear PARM_En in Config3.
- + btConfig3 &= ~(CONFIG3_PARM_En);
- + write_nic_byte(dev, CONFIG3, btConfig3);
- + // Clear EEM0 and EEM1 in 9346CR.
- + btCR9346 &= ~(0xC0);
- + write_nic_byte(dev, CR9346, btCR9346);
- +
- + up(&priv->wx_sem);
- +
- + return 0;
- +}
- +
- +static int r8180_wx_set_ratadpt (struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + int ratadapt = *extra;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- +
- + if(priv->ieee80211->bHwRadioOff)
- + return 0;
- +
- + down(&priv->wx_sem);
- + printk("Set rate adaptive %s\n", (ratadapt==0)?"on":"off");
- + if(ratadapt == 0) {
- + del_timer_sync(&priv->rateadapter_timer);
- + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- + priv->rateadapter_timer.function((unsigned long)dev);
- + } else {
- + del_timer_sync(&priv->rateadapter_timer);
- + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- + printk("force rate to %d\n", ratadapt);
- + ieee->rate = ratadapt;
- + }
- + up(&priv->wx_sem);
- + return 0;
- +}
- +
- +#ifdef ENABLE_TOSHIBA_CONFIG
- +static int r8180_wx_get_tblidx(struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //extern u8 chan_plan_index;
- + //printk("=========>%s(), %x\n", __FUNCTION__, priv->channel_plan);
- + down(&priv->wx_sem);
- + put_user(priv->channel_plan, (u8*)wrqu->data.pointer);
- + up(&priv->wx_sem);
- + return 0;
- +
- +}
- +
- +//This func will be called after probe auto
- +static int r8180_wx_set_tbl (struct net_device *dev,
- + struct iw_request_info *info,
- + union iwreq_data *wrqu, char *extra)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 len = 0;
- + s8 err = -1;
- + extern CHANNEL_LIST Current_tbl;
- + down(&priv->wx_sem);
- + if (!wrqu->data.pointer)
- + {
- + printk("user data pointer is null\n");
- + goto exit;
- + }
- + len = wrqu->data.length;
- + //printk("=========>%s(), len:%d\n", __FUNCTION__, len);
- + //memset(&Current_tbl, 0, sizeof(CHANNEL_LIST));
- + if (copy_from_user((u8*)&Current_tbl, (void*)wrqu->data.pointer, len))
- + {
- + printk("error copy from user\n");
- + goto exit;
- + }
- + {
- + int i;
- + Current_tbl.Len = len;
- + //printk("%d\n", Current_tbl.Len);
- +
- + Dot11d_Init(priv->ieee80211);
- + priv->ieee80211->bGlobalDomain = false;
- + priv->ieee80211->bWorldWide13 = false;
- +
- + //lzm add 081205
- + priv->ieee80211->MinPassiveChnlNum=12;
- + priv->ieee80211->IbssStartChnl= 10;
- +
- + for (i=0; i<Current_tbl.Len; i++){
- + //printk("%2d ", Current_tbl.Channel[i]);
- + if(priv->channel_plan == COUNTRY_CODE_ETSI)
- + {
- + if(Current_tbl.Channel[i] <= 11)
- + {
- +#ifdef ENABLE_DOT11D
- + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
- +#else
- + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
- +#endif
- + }
- + else if((Current_tbl.Channel[i] >= 11) && (Current_tbl.Channel[i] <= 13))
- + {
- +#ifdef ENABLE_DOT11D
- + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 2;
- +#else
- + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 2;
- +#endif
- + }
- + }
- + else
- + {
- + if(Current_tbl.Channel[i] <= 14)
- + {
- +#ifdef ENABLE_DOT11D
- + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
- +#else
- + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
- +#endif
- + }
- + }
- + }
- +#if 0
- + printk("\n");
- + for(i=1; i<MAX_CHANNEL_NUMBER; i++)
- + {
- +#ifdef ENABLE_DOT11D
- + printk("%2d ", GET_DOT11D_INFO(priv->ieee80211)->channel_map[i]);
- +#else
- + printk("%2d ", priv->ieee80211->channel_map[i]);
- +#endif
- + }
- + printk("\n");
- +
- +#endif
- + if(priv->ieee80211->proto_started)
- + {//we need to restart protocol now if it was start before channel map
- + ieee80211_softmac_stop_protocol(priv->ieee80211);
- + //mdelay(1);
- + ieee80211_softmac_start_protocol(priv->ieee80211);
- + }
- + }
- + err = 0;
- +exit:
- + up(&priv->wx_sem);
- + return err;
- +
- +
- +}
- +
- +#endif
- +
- +
- +static iw_handler r8180_wx_handlers[] =
- +{
- + NULL, /* SIOCSIWCOMMIT */
- + r8180_wx_get_name, /* SIOCGIWNAME */
- + dummy, /* SIOCSIWNWID */
- + dummy, /* SIOCGIWNWID */
- + r8180_wx_set_freq, /* SIOCSIWFREQ */
- + r8180_wx_get_freq, /* SIOCGIWFREQ */
- + r8180_wx_set_mode, /* SIOCSIWMODE */
- + r8180_wx_get_mode, /* SIOCGIWMODE */
- + r8180_wx_set_sens, /* SIOCSIWSENS */
- + r8180_wx_get_sens, /* SIOCGIWSENS */
- + NULL, /* SIOCSIWRANGE */
- + rtl8180_wx_get_range, /* SIOCGIWRANGE */
- + NULL, /* SIOCSIWPRIV */
- + NULL, /* SIOCGIWPRIV */
- + NULL, /* SIOCSIWSTATS */
- + NULL, /* SIOCGIWSTATS */
- + dummy, /* SIOCSIWSPY */
- + dummy, /* SIOCGIWSPY */
- + NULL, /* SIOCGIWTHRSPY */
- + NULL, /* SIOCWIWTHRSPY */
- + r8180_wx_set_wap, /* SIOCSIWAP */
- + r8180_wx_get_wap, /* SIOCGIWAP */
- + r8180_wx_set_mlme, //NULL, /* SIOCSIWMLME*/ /* -- hole -- */
- + dummy, /* SIOCGIWAPLIST -- depricated */
- + r8180_wx_set_scan, /* SIOCSIWSCAN */
- + r8180_wx_get_scan, /* SIOCGIWSCAN */
- + r8180_wx_set_essid, /* SIOCSIWESSID */
- + r8180_wx_get_essid, /* SIOCGIWESSID */
- + dummy, /* SIOCSIWNICKN */
- + dummy, /* SIOCGIWNICKN */
- + NULL, /* -- hole -- */
- + NULL, /* -- hole -- */
- + r8180_wx_set_rate, /* SIOCSIWRATE */
- + r8180_wx_get_rate, /* SIOCGIWRATE */
- + dummy, /* SIOCSIWRTS */
- + dummy, /* SIOCGIWRTS */
- + r8180_wx_set_frag, /* SIOCSIWFRAG */
- + r8180_wx_get_frag, /* SIOCGIWFRAG */
- + dummy, /* SIOCSIWTXPOW */
- + dummy, /* SIOCGIWTXPOW */
- + r8180_wx_set_retry, /* SIOCSIWRETRY */
- + r8180_wx_get_retry, /* SIOCGIWRETRY */
- + r8180_wx_set_enc, /* SIOCSIWENCODE */
- + r8180_wx_get_enc, /* SIOCGIWENCODE */
- + dummy, /* SIOCSIWPOWER */
- + dummy, /* SIOCGIWPOWER */
- + NULL, /*---hole---*/
- + NULL, /*---hole---*/
- + r8180_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
- + NULL, /* SIOCSIWGENIE */
- + r8180_wx_set_auth,//NULL, /* SIOCSIWAUTH */
- + NULL,//r8180_wx_get_auth,//NULL, /* SIOCSIWAUTH */
- + r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
- + NULL,//r8180_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
- + NULL, /* SIOCSIWPMKSA */
- + NULL, /*---hole---*/
- +};
- +
- +
- +static const struct iw_priv_args r8180_private_args[] = {
- + {
- + SIOCIWFIRSTPRIV + 0x0,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
- + },
- +
- + {
- + SIOCIWFIRSTPRIV + 0x1,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
- +
- + },
- + {
- + SIOCIWFIRSTPRIV + 0x2,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
- + },
- +#ifdef JOHN_IOCTL
- + {
- + SIOCIWFIRSTPRIV + 0x3,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
- + }
- + ,
- + {
- + SIOCIWFIRSTPRIV + 0x4,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
- + }
- + ,
- + {
- + SIOCIWFIRSTPRIV + 0x5,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
- + }
- + ,
- + {
- + SIOCIWFIRSTPRIV + 0x6,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
- + }
- + ,
- + {
- + SIOCIWFIRSTPRIV + 0x7,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
- + }
- + ,
- + {
- + SIOCIWFIRSTPRIV + 0x8,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
- + }
- + ,
- + {
- + SIOCIWFIRSTPRIV + 0x9,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
- + },
- +#endif
- + {
- + SIOCIWFIRSTPRIV + 0xA,
- + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED |1, "getradion"
- + },
- + {
- + SIOCIWFIRSTPRIV + 0xB,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setradion"
- + },
- + {
- + SIOCIWFIRSTPRIV + 0xC,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ratadpt"
- + },
- +#ifdef ENABLE_TOSHIBA_CONFIG
- + {
- + SIOCIWFIRSTPRIV + 0xD,
- + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettblidx"
- + },
- + {
- + SIOCIWFIRSTPRIV + 0xE,
- + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,0, "settblidx"
- + },
- +
- +#endif
- +
- +};
- +
- +/*
- + * Private ioctl interface information
- +
- +struct iw_priv_args
- +{
- +// __u32 cmd;
- +// __u16 set_args;
- +// __u16 get_args;
- +// char name[IFNAMSIZ];
- +//};
- +*/
- +//If get cmd's number is big,there may cause some problemes.
- +//So modified by Lawrence,071120
- +
- +static iw_handler r8180_private_handler[] = {
- +// r8180_wx_set_monitor, /* SIOCIWFIRSTPRIV */
- + r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
- +// r8180_wx_set_forceassociate,
- +// r8180_wx_set_beaconinterval,
- +// r8180_wx_set_monitor_type,
- + r8180_wx_set_scan_type,
- + r8180_wx_set_rawtx,
- +
- +#if 0
- +#ifdef _RTL8187_EXT_PATCH_
- + r8180_wx_get_meshinfo,
- + r8180_wx_enable_mesh,
- + r8180_wx_disable_mesh,
- + r8180_wx_set_channel,
- + r8180_wx_set_meshID,
- +
- +// r8180_wx_add_mac_allow,
- +// r8180_wx_get_mac_allow,
- +// r8180_wx_del_mac_allow,
- + r8180_wx_add_mac_deny,
- + r8180_wx_get_mac_deny,
- + r8180_wx_del_mac_deny,
- + r8180_wx_get_mesh_list,
- + r8180_wx_mesh_scan,
- + r8180_wx_join_mesh,
- +#endif
- +#endif
- +
- +#ifdef JOHN_IOCTL
- + r8180_wx_read_regs,
- + r8180_wx_write_regs,
- + r8180_wx_read_bb,
- + r8180_wx_write_bb,
- + r8180_wx_read_nicb,
- + r8180_wx_write_nicb,
- + r8180_wx_get_ap_status,
- +#endif
- + r8180_wx_get_radion,
- + r8180_wx_set_radion,
- + r8180_wx_set_ratadpt,
- +#ifdef ENABLE_TOSHIBA_CONFIG
- + r8180_wx_get_tblidx,
- + r8180_wx_set_tbl,
- +#endif
- +};
- +
- +#if WIRELESS_EXT >= 17
- +//WB modefied to show signal to GUI on 18-01-2008
- +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_device* ieee = priv->ieee80211;
- + struct iw_statistics* wstats = &priv->wstats;
- +// struct ieee80211_network* target = NULL;
- + int tmp_level = 0;
- + int tmp_qual = 0;
- + int tmp_noise = 0;
- +// unsigned long flag;
- +
- + if (ieee->state < IEEE80211_LINKED)
- + {
- + wstats->qual.qual = 0;
- + wstats->qual.level = 0;
- + wstats->qual.noise = 0;
- + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- + return wstats;
- + }
- +#if 0
- + spin_lock_irqsave(&ieee->lock, flag);
- + list_for_each_entry(target, &ieee->network_list, list)
- + {
- + if (is_same_network(target, &ieee->current_network))
- + {
- + printk("it's same network:%s\n", target->ssid);
- +#if 0
- + if (!tmp_level)
- + {
- + tmp_level = target->stats.signalstrength;
- + tmp_qual = target->stats.signal;
- + }
- + else
- + {
- +
- + tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
- + tmp_qual = (15*tmp_qual + target->stats.signal)/16;
- + }
- +#else
- + tmp_level = target->stats.signal;
- + tmp_qual = target->stats.signalstrength;
- + tmp_noise = target->stats.noise;
- + printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
- +#endif
- + break;
- + }
- + }
- + spin_unlock_irqrestore(&ieee->lock, flag);
- +#endif
- + tmp_level = (&ieee->current_network)->stats.signal;
- + tmp_qual = (&ieee->current_network)->stats.signalstrength;
- + tmp_noise = (&ieee->current_network)->stats.noise;
- + //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
- +
- + wstats->qual.level = tmp_level;
- + wstats->qual.qual = tmp_qual;
- + wstats->qual.noise = tmp_noise;
- + wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
- + return wstats;
- +}
- +#endif
- +
- +
- +struct iw_handler_def r8180_wx_handlers_def={
- + .standard = r8180_wx_handlers,
- + .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
- + .private = r8180_private_handler,
- + .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
- + .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
- +#if WIRELESS_EXT >= 17
- + .get_wireless_stats = r8180_get_wireless_stats,
- +#endif
- + .private_args = (struct iw_priv_args *)r8180_private_args,
- +};
- +#ifdef _RTL8187_EXT_PATCH_
- +EXPORT_SYMBOL(r8180_wx_set_channel);
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.h linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8180_wx.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8180_wx.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,21 @@
- +/*
- + This is part of rtl8180 OpenSource driver - v 0.3
- + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +
- + Parts of this driver are based on the GPL part of the official realtek driver
- + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
- + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
- +
- + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
- +*/
- +
- +/* this file (will) contains wireless extension handlers*/
- +
- +#ifndef R8180_WX_H
- +#define R8180_WX_H
- +#include <linux/wireless.h>
- +#include "ieee80211/ieee80211.h"
- +extern struct iw_handler_def r8180_wx_handlers_def;
- +
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_core.c linux-lemote/drivers/net/wireless/rtl8187b/r8187_core.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_core.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_core.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,7042 @@
- +/*
- + This is part of rtl8187 OpenSource driver - v 0.1
- + Copyright (C) Andrea Merello 2005 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public License)
- +
- +
- + Parts of this driver are based on the rtl8180 driver skeleton
- + from Patric Schenke & Andres Salomon.
- +
- + Parts of this driver are based on the Intel Pro Wireless 2*00 GPL drivers.
- +
- + some ideas might be derived from David Young rtl8180 netbsd driver.
- +
- + Parts of the usb code are from the r8150.c driver in linux kernel
- +
- + Some ideas borrowed from the 8139too.c driver included in linux kernel.
- +
- + We (I?) want to thanks the Authors of those projecs and also the
- + Ndiswrapper's project Authors.
- +
- + A special big thanks goes also to Realtek corp. for their help in my
- + attempt to add RTL8187 and RTL8225 support, and to David Young also.
- +
- + - Please note that this file is a modified version from rtl8180-sa2400
- + drv. So some other people have contributed to this project, and they are
- + thanked in the rtl8180-sa2400 CHANGELOG.
- +*/
- +
- +#undef LOOP_TEST
- +#undef DUMP_RX
- +#undef DUMP_TX
- +#undef DEBUG_TX_DESC2
- +#undef RX_DONT_PASS_UL
- +#undef DEBUG_EPROM
- +#undef DEBUG_RX_VERBOSE
- +#undef DUMMY_RX
- +#undef DEBUG_ZERO_RX
- +#undef DEBUG_RX_SKB
- +#undef DEBUG_TX_FRAG
- +#undef DEBUG_RX_FRAG
- +#undef DEBUG_TX_FILLDESC
- +#undef DEBUG_TX
- +#undef DEBUG_IRQ
- +#undef DEBUG_RX
- +#undef DEBUG_RXALLOC
- +#undef DEBUG_REGISTERS
- +#undef DEBUG_RING
- +#undef DEBUG_IRQ_TASKLET
- +#undef DEBUG_TX_ALLOC
- +#undef DEBUG_TX_DESC
- +#undef CONFIG_SOFT_BEACON
- +#undef DEBUG_RW_REGISTER
- +
- +#define CONFIG_RTL8180_IO_MAP
- +//#define CONFIG_SOFT_BEACON
- +//#define DEBUG_RW_REGISTER
- +
- +#include "r8180_hw.h"
- +#include "r8187.h"
- +#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
- +#include "r8180_93cx6.h" /* Card EEPROM */
- +#include "r8180_wx.h"
- +#include "r8180_dm.h"
- +
- +#include <linux/dmapool.h>
- +
- +#include <linux/usb.h>
- +// FIXME: check if 2.6.7 is ok
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
- +#define usb_kill_urb usb_unlink_urb
- +#endif
- +
- +#ifdef CONFIG_RTL8180_PM
- +#include "r8180_pm.h"
- +#endif
- +
- +#ifdef ENABLE_DOT11D
- +#include "dot11d.h"
- +#endif
- +
- +#ifndef USB_VENDOR_ID_REALTEK
- +#define USB_VENDOR_ID_REALTEK 0x0bda
- +#endif
- +#ifndef USB_VENDOR_ID_NETGEAR
- +#define USB_VENDOR_ID_NETGEAR 0x0846
- +#endif
- +
- +#define TXISR_SELECT(priority) ((priority == MANAGE_PRIORITY)?rtl8187_managetx_isr:\
- + (priority == BEACON_PRIORITY)?rtl8187_beacontx_isr: \
- + (priority == VO_PRIORITY)?rtl8187_votx_isr: \
- + (priority == VI_PRIORITY)?rtl8187_vitx_isr:\
- + (priority == BE_PRIORITY)?rtl8187_betx_isr:rtl8187_bktx_isr)
- +
- +static struct usb_device_id rtl8187_usb_id_tbl[] = {
- + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8187)},
- + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8189)},
- +// {USB_DEVICE_VER(USB_VENDOR_ID_REALTEK, 0x8187,0x0200,0x0200)},
- + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6100)},
- + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6a00)},
- + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8197)},
- + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8198)},
- + {}
- +};
- +
- +static char* ifname = "wlan%d";
- +#if 0
- +static int hwseqnum = 0;
- +static int hwwep = 0;
- +#endif
- +static int channels = 0x3fff;
- +//static int channels = 0x7ff;// change by thomas, use 1 - 11 channel 0907-2007
- +#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 )
- +//by amy for rate adaptive
- +#define DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD 300
- +//by amy for rate adaptive
- +//by amy for ps
- +#define IEEE80211_WATCH_DOG_TIME 2000
- +//by amy for ps
- +MODULE_LICENSE("GPL");
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +MODULE_VERSION("V 1.1");
- +#endif
- +MODULE_DEVICE_TABLE(usb, rtl8187_usb_id_tbl);
- +MODULE_AUTHOR("Realsil Wlan");
- +MODULE_DESCRIPTION("Linux driver for Realtek RTL8187 WiFi cards");
- +
- +#if 0
- +MODULE_PARM(ifname,"s");
- +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
- +
- +MODULE_PARM(hwseqnum,"i");
- +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
- +
- +MODULE_PARM(hwwep,"i");
- +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
- +
- +MODULE_PARM(channels,"i");
- +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
- +#endif
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
- +module_param(ifname, charp, S_IRUGO|S_IWUSR );
- +//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
- +//module_param(hwwep,int, S_IRUGO|S_IWUSR);
- +module_param(channels,int, S_IRUGO|S_IWUSR);
- +#else
- +MODULE_PARM(ifname, "s");
- +//MODULE_PARM(hwseqnum,"i");
- +//MODULE_PARM(hwwep,"i");
- +MODULE_PARM(channels,"i");
- +#endif
- +
- +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
- +//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
- +//MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
- +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- +static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
- + const struct usb_device_id *id);
- +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf);
- +#else
- +static void *__devinit rtl8187_usb_probe(struct usb_device *udev,unsigned int ifnum,
- + const struct usb_device_id *id);
- +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr);
- +#endif
- +
- +
- +static struct usb_driver rtl8187_usb_driver = {
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
- + .owner = THIS_MODULE,
- +#endif
- + .name = RTL8187_MODULE_NAME, /* Driver name */
- + .id_table = rtl8187_usb_id_tbl, /* PCI_ID table */
- + .probe = rtl8187_usb_probe, /* probe fn */
- + .disconnect = rtl8187_usb_disconnect, /* remove fn */
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
- +#ifdef CONFIG_RTL8180_PM
- + .suspend = rtl8187_suspend, /* PM suspend fn */
- + .resume = rtl8187_resume, /* PM resume fn */
- +#else
- + .suspend = NULL, /* PM suspend fn */
- + .resume = NULL, /* PM resume fn */
- +#endif
- +#endif
- +};
- +
- +#ifdef JOHN_HWSEC
- +void CAM_mark_invalid(struct net_device *dev, u8 ucIndex)
- +{
- + u32 ulContent=0;
- + u32 ulCommand=0;
- + u32 ulEncAlgo=CAM_AES;
- +
- + // keyid must be set in config field
- + ulContent |= (ucIndex&3) | ((u16)(ulEncAlgo)<<2);
- +
- + ulContent |= BIT15;
- + // polling bit, and No Write enable, and address
- + ulCommand= CAM_CONTENT_COUNT*ucIndex;
- + ulCommand= ulCommand | BIT31|BIT16;
- + // write content 0 is equall to mark invalid
- +
- + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
- + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A4: %x \n",ulContent));
- + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
- + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A0: %x \n",ulCommand));
- +}
- +
- +void CAM_empty_entry(struct net_device *dev, u8 ucIndex)
- +{
- + u32 ulCommand=0;
- + u32 ulContent=0;
- + u8 i;
- + u32 ulEncAlgo=CAM_AES;
- +
- + for(i=0;i<6;i++)
- + {
- +
- + // filled id in CAM config 2 byte
- + if( i == 0)
- + {
- + ulContent |=(ucIndex & 0x03) | (ulEncAlgo<<2);
- + ulContent |= BIT15;
- +
- + }
- + else
- + {
- + ulContent = 0;
- + }
- + // polling bit, and No Write enable, and address
- + ulCommand= CAM_CONTENT_COUNT*ucIndex+i;
- + ulCommand= ulCommand | BIT31|BIT16;
- + // write content 0 is equall to mark invalid
- + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
- + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %x \n",ulContent));
- + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
- + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %x \n",ulCommand));
- + }
- +}
- +
- +void CamResetAllEntry(struct net_device *dev)
- +{
- + u8 ucIndex;
- +
- + //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
- + // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
- + // In this condition, Cam can not be reset because upper layer will not set this static key again.
- + //if(Adapter->EncAlgorithm == WEP_Encryption)
- + // return;
- + //debug
- + //DbgPrint("========================================\n");
- + //DbgPrint(" Call ResetAllEntry \n");
- + //DbgPrint("========================================\n\n");
- +
- + for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
- + CAM_mark_invalid(dev, ucIndex);
- + for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
- + CAM_empty_entry(dev, ucIndex);
- +
- +}
- +
- +
- +void write_cam(struct net_device *dev, u8 addr, u32 data)
- +{
- + write_nic_dword(dev, WCAMI, data);
- + write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
- +}
- +u32 read_cam(struct net_device *dev, u8 addr)
- +{
- + write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
- + return read_nic_dword(dev, 0xa8);
- +}
- +#endif /*JOHN_HWSEC*/
- +
- +#ifdef DEBUG_RW_REGISTER
- +//lzm add for write time out test
- +void add_into_rw_registers(struct net_device *dev, u32 addr, u32 cont, u8 flag)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + int reg_index = (priv->write_read_register_index % 200) ;
- +
- + priv->write_read_registers[reg_index].address = 0;
- + priv->write_read_registers[reg_index].content = 0;
- + priv->write_read_registers[reg_index].flag = 0;
- +
- + priv->write_read_registers[reg_index].address = addr;
- + priv->write_read_registers[reg_index].content = cont;
- + priv->write_read_registers[reg_index].flag = flag;
- +
- + priv->write_read_register_index = (priv->write_read_register_index + 1) % 200;
- +}
- +
- +bool print_once = 0;
- +
- +void print_rw_registers(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + int reg_index = 0;
- + int watchdog = 0;
- + if(print_once == false)
- + {
- + print_once = true;
- + for(reg_index = ((priv->write_read_register_index + 1) % 200); watchdog <= 199; reg_index++)
- + {
- + watchdog++;
- + printk("====>reg_addr:0x%x, reg_cont:0x%x, read_or_write:0x%d\n",
- + priv->write_read_registers[reg_index].address,
- + priv->write_read_registers[reg_index].content,
- + priv->write_read_registers[reg_index].flag);
- + }
- + }
- +}
- +//lzm add for write time out test
- +#endif
- +
- +#ifdef CPU_64BIT
- +void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
- +{
- + int status;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + indx|0xfe00, 0, &data, 1, HZ / 2);
- +
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, data, 2);
- +#endif
- +
- + if (status < 0)
- + {
- + printk("write_nic_byte_E TimeOut!addr:%x, status:%x\n", indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +}
- +
- +u8 read_nic_byte_E(struct net_device *dev, int indx)
- +{
- + int status;
- + u8 data, *buf;
- + dma_addr_t dma_handle;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
- + if (!buf) {
- + printk("read_nic_byte_E out of memory\n");
- + return -ENOMEM;
- + }
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + indx|0xfe00, 0, buf, 1, HZ / 2);
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, buf[0], 1);
- +#endif
- +
- + if (status < 0)
- + {
- + printk("read_nic_byte_E TimeOut!addr:%x, status:%x\n",indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +
- + data = buf[0];
- + dma_pool_free(priv->usb_pool, buf, dma_handle);
- + return data;
- +}
- +
- +void write_nic_byte(struct net_device *dev, int indx, u8 data)
- +{
- + int status;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
- +
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, data, 2);
- +#endif
- + if (status < 0)
- + {
- + printk("write_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +
- +
- +}
- +
- +void write_nic_word(struct net_device *dev, int indx, u16 data)
- +{
- +
- + int status;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
- +
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, data, 2);
- +
- + if(priv->write_read_register_index == 199)
- + {
- + //print_rw_registers(dev);
- + }
- +#endif
- + if (status < 0)
- + {
- + printk("write_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +
- +}
- +
- +void write_nic_dword(struct net_device *dev, int indx, u32 data)
- +{
- +
- + int status;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, data, 2);
- +#endif
- +
- +
- + if (status < 0)
- + {
- + printk("write_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +
- +}
- +
- + u8 read_nic_byte(struct net_device *dev, int indx)
- +{
- + u8 data, *buf;
- + int status;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- + dma_addr_t dma_handle;
- +
- + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
- + if (!buf) {
- + printk("read_nic_byte: out of memory\n");
- + return -ENOMEM;
- + }
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, buf[0], 1);
- +#endif
- +
- + if (status < 0)
- + {
- + printk("read_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +
- + data = buf[0];
- + dma_pool_free(priv->usb_pool, buf, dma_handle);
- + return data;
- +}
- +
- +u16 read_nic_word(struct net_device *dev, int indx)
- +{
- + u16 data, *buf;
- + int status;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- + dma_addr_t dma_handle;
- +
- + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
- + if (!buf) {
- + printk("read_nic_word: out of memory\n");
- + return -ENOMEM;
- + }
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, buf[0], 1);
- +#endif
- +
- + if (status < 0)
- + {
- + printk("read_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +
- +
- + data = buf[0];
- + dma_pool_free(priv->usb_pool, buf, dma_handle);
- + return data;
- +}
- +
- +u32 read_nic_dword(struct net_device *dev, int indx)
- +{
- + u32 data, *buf;
- + int status;
- + dma_addr_t dma_handle;
- +// int result;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
- + if (!buf){
- + printk("read_nic_dword: out of memory\n");
- + return -ENOMEM;
- + }
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + add_into_rw_registers(dev, indx, buf[0], 1);
- +#endif
- +
- + if (status < 0)
- + {
- + printk("read_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
- +#ifdef DEBUG_RW_REGISTER
- + print_rw_registers(dev);
- +#endif
- + }
- +
- +
- +
- + data = buf[0];
- + dma_pool_free(priv->usb_pool, buf, dma_handle);
- + return data;
- +}
- +#else
- +void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
- +{
- + int status;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + indx|0xfe00, 0, &data, 1, HZ / 2);
- +
- + if (status < 0)
- + {
- + printk("write_nic_byte_E TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data,status);
- + }
- +}
- +
- +u8 read_nic_byte_E(struct net_device *dev, int indx)
- +{
- + int status;
- + u8 data = 0;
- + u8 buf[64];
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + indx|0xfe00, 0, buf, 1, HZ / 2);
- +
- + if (status < 0)
- + {
- + printk("read_nic_byte_E TimeOut!addr:0x%x, status:%x\n", indx, status);
- + }
- +
- + data = *(u8*)buf;
- + return data;
- +}
- +
- +void write_nic_byte(struct net_device *dev, int indx, u8 data)
- +{
- + int status;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
- +
- + if (status < 0)
- + {
- + printk("write_nic_byte TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
- + }
- +
- +
- +}
- +
- +void write_nic_word(struct net_device *dev, int indx, u16 data)
- +{
- +
- + int status;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
- +
- + if (status < 0)
- + {
- + printk("write_nic_word TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
- + }
- +
- +}
- +
- +void write_nic_dword(struct net_device *dev, int indx, u32 data)
- +{
- +
- + int status;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
- +
- +
- + if (status < 0)
- + {
- + printk("write_nic_dword TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
- + }
- +
- +}
- +
- +u8 read_nic_byte(struct net_device *dev, int indx)
- +{
- + u8 data = 0;
- + u8 buf[64];
- + int status;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
- +
- + if (status < 0)
- + {
- + printk("read_nic_byte TimeOut!addr:0x%x,status:%x\n", indx,status);
- + }
- +
- +
- + data = *(u8*)buf;
- + return data;
- +}
- +
- +u16 read_nic_word(struct net_device *dev, int indx)
- +{
- + u16 data = 0;
- + u8 buf[64];
- + int status;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
- +
- + if (status < 0)
- + {
- + printk("read_nic_word TimeOut!addr:0x%x,status:%x\n", indx,status);
- + }
- +
- + data = *(u16*)buf;
- + return data;
- +}
- +
- +u32 read_nic_dword(struct net_device *dev, int indx)
- +{
- + u32 data = 0;
- + u8 buf[64];
- + int status;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct usb_device *udev = priv->udev;
- +
- + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
- + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
- +
- + if (status < 0)
- + {
- + printk("read_nic_dword TimeOut!addr:0x%x,status:%x\n", indx, status);
- + }
- +
- +
- + data = *(u32*)buf;
- + return data;
- +}
- +#endif
- +
- +
- +u8 read_phy_cck(struct net_device *dev, u8 adr);
- +u8 read_phy_ofdm(struct net_device *dev, u8 adr);
- +/* this might still called in what was the PHY rtl8185/rtl8187 common code
- + * plans are to possibilty turn it again in one common code...
- + */
- +inline void force_pci_posting(struct net_device *dev)
- +{
- +}
- +
- +
- +static struct net_device_stats *rtl8180_stats(struct net_device *dev);
- +void rtl8180_commit(struct net_device *dev);
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void rtl8180_restart(struct work_struct *work);
- +#else
- +void rtl8180_restart(struct net_device *dev);
- +#endif
- +/****************************************************************************
- + -----------------------------PROCFS STUFF-------------------------
- +*****************************************************************************/
- +
- +static struct proc_dir_entry *rtl8180_proc = NULL;
- +static int proc_get_stats_ap(char *page, char **start,
- + off_t offset, int count,
- + int *eof, void *data)
- +{
- + struct net_device *dev = data;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- + struct ieee80211_network *target;
- +
- + int len = 0;
- +
- + list_for_each_entry(target, &ieee->network_list, list) {
- +
- + len += snprintf(page + len, count - len,
- + "%s ", target->ssid);
- + len += snprintf(page + len, count - len,
- + "%ld ", (jiffies-target->last_scanned)/HZ);
- +
- +
- +
- + if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
- + len += snprintf(page + len, count - len,
- + "WPA\n");
- + }
- + else{
- + len += snprintf(page + len, count - len,
- + "non_WPA\n");
- + }
- +
- + }
- +
- + *eof = 1;
- + return len;
- +}
- +
- +static int proc_get_registers(char *page, char **start,
- + off_t offset, int count,
- + int *eof, void *data)
- +{
- + struct net_device *dev = data;
- +
- + int len = 0;
- + int i,n;
- +
- + int max=0xff;
- +
- + /* This dump the current register page */
- +len += snprintf(page + len, count - len,
- + "\n####################page 0##################\n ");
- +
- + for(n=0;n<=max;)
- + {
- + //printk( "\nD: %2x> ", n);
- + len += snprintf(page + len, count - len,
- + "\nD: %2x > ",n);
- +
- + for(i=0;i<16 && n<=max;i++,n++)
- + len += snprintf(page + len, count - len,
- + "%2x ",read_nic_byte(dev,n));
- +
- + // printk("%2x ",read_nic_byte(dev,n));
- + }
- + len += snprintf(page + len, count - len,"\n");
- +len += snprintf(page + len, count - len,
- + "\n####################page 1##################\n ");
- + for(n=0;n<=max;)
- + {
- + //printk( "\nD: %2x> ", n);
- + len += snprintf(page + len, count - len,
- + "\nD: %2x > ",n);
- +
- + for(i=0;i<16 && n<=max;i++,n++)
- + len += snprintf(page + len, count - len,
- + "%2x ",read_nic_byte(dev,0x100|n));
- +
- + // printk("%2x ",read_nic_byte(dev,n));
- + }
- +len += snprintf(page + len, count - len,
- + "\n####################page 2##################\n ");
- + for(n=0;n<=max;)
- + {
- + //printk( "\nD: %2x> ", n);
- + len += snprintf(page + len, count - len,
- + "\nD: %2x > ",n);
- +
- + for(i=0;i<16 && n<=max;i++,n++)
- + len += snprintf(page + len, count - len,
- + "%2x ",read_nic_byte(dev,0x200|n));
- +
- + // printk("%2x ",read_nic_byte(dev,n));
- + }
- +
- +
- +
- + *eof = 1;
- + return len;
- +
- +}
- +
- +
- +static int proc_get_cck_reg(char *page, char **start,
- + off_t offset, int count,
- + int *eof, void *data)
- +{
- + struct net_device *dev = data;
- +
- + int len = 0;
- + int i,n;
- +
- + int max = 0x5F;
- +
- + /* This dump the current register page */
- + for(n=0;n<=max;)
- + {
- + //printk( "\nD: %2x> ", n);
- + len += snprintf(page + len, count - len,
- + "\nD: %2x > ",n);
- +
- + for(i=0;i<16 && n<=max;i++,n++)
- + len += snprintf(page + len, count - len,
- + "%2x ",read_phy_cck(dev,n));
- +
- + // printk("%2x ",read_nic_byte(dev,n));
- + }
- + len += snprintf(page + len, count - len,"\n");
- +
- +
- + *eof = 1;
- + return len;
- +
- +}
- +
- +
- +static int proc_get_ofdm_reg(char *page, char **start,
- + off_t offset, int count,
- + int *eof, void *data)
- +{
- + struct net_device *dev = data;
- +
- + int len = 0;
- + int i,n;
- +
- + //int max=0xff;
- + int max = 0x40;
- +
- + /* This dump the current register page */
- + for(n=0;n<=max;)
- + {
- + //printk( "\nD: %2x> ", n);
- + len += snprintf(page + len, count - len,
- + "\nD: %2x > ",n);
- +
- + for(i=0;i<16 && n<=max;i++,n++)
- + len += snprintf(page + len, count - len,
- + "%2x ",read_phy_ofdm(dev,n));
- +
- + // printk("%2x ",read_nic_byte(dev,n));
- + }
- + len += snprintf(page + len, count - len,"\n");
- +
- +
- +
- + *eof = 1;
- + return len;
- +
- +}
- +
- +
- +#if 0
- +static int proc_get_stats_hw(char *page, char **start,
- + off_t offset, int count,
- + int *eof, void *data)
- +{
- + struct net_device *dev = data;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + int len = 0;
- +
- + len += snprintf(page + len, count - len,
- + "NIC int: %lu\n"
- + "Total int: %lu\n",
- + priv->stats.ints,
- + priv->stats.shints);
- +
- + *eof = 1;
- + return len;
- +}
- +#endif
- +
- +static int proc_get_stats_tx(char *page, char **start,
- + off_t offset, int count,
- + int *eof, void *data)
- +{
- + struct net_device *dev = data;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + int len = 0;
- +
- + len += snprintf(page + len, count - len,
- + "TX VI priority ok int: %lu\n"
- + "TX VI priority error int: %lu\n"
- + "TX VO priority ok int: %lu\n"
- + "TX VO priority error int: %lu\n"
- + "TX BE priority ok int: %lu\n"
- + "TX BE priority error int: %lu\n"
- + "TX BK priority ok int: %lu\n"
- + "TX BK priority error int: %lu\n"
- + "TX MANAGE priority ok int: %lu\n"
- + "TX MANAGE priority error int: %lu\n"
- + "TX BEACON priority ok int: %lu\n"
- + "TX BEACON priority error int: %lu\n"
- +// "TX high priority ok int: %lu\n"
- +// "TX high priority failed error int: %lu\n"
- + "TX queue resume: %lu\n"
- + "TX queue stopped?: %d\n"
- + "TX fifo overflow: %lu\n"
- +// "TX beacon: %lu\n"
- + "TX VI queue: %d\n"
- + "TX VO queue: %d\n"
- + "TX BE queue: %d\n"
- + "TX BK queue: %d\n"
- + "TX BEACON queue: %d\n"
- + "TX MANAGE queue: %d\n"
- +// "TX HW queue: %d\n"
- + "TX VI dropped: %lu\n"
- + "TX VO dropped: %lu\n"
- + "TX BE dropped: %lu\n"
- + "TX BK dropped: %lu\n"
- + "TX total data packets %lu\n",
- +// "TX beacon aborted: %lu\n",
- + priv->stats.txviokint,
- + priv->stats.txvierr,
- + priv->stats.txvookint,
- + priv->stats.txvoerr,
- + priv->stats.txbeokint,
- + priv->stats.txbeerr,
- + priv->stats.txbkokint,
- + priv->stats.txbkerr,
- + priv->stats.txmanageokint,
- + priv->stats.txmanageerr,
- + priv->stats.txbeaconokint,
- + priv->stats.txbeaconerr,
- +// priv->stats.txhpokint,
- +// priv->stats.txhperr,
- + priv->stats.txresumed,
- + netif_queue_stopped(dev),
- + priv->stats.txoverflow,
- +// priv->stats.txbeacon,
- + atomic_read(&(priv->tx_pending[VI_PRIORITY])),
- + atomic_read(&(priv->tx_pending[VO_PRIORITY])),
- + atomic_read(&(priv->tx_pending[BE_PRIORITY])),
- + atomic_read(&(priv->tx_pending[BK_PRIORITY])),
- + atomic_read(&(priv->tx_pending[BEACON_PRIORITY])),
- + atomic_read(&(priv->tx_pending[MANAGE_PRIORITY])),
- +// read_nic_byte(dev, TXFIFOCOUNT),
- + priv->stats.txvidrop,
- + priv->stats.txvodrop,
- + priv->stats.txbedrop,
- + priv->stats.txbkdrop,
- + priv->stats.txdatapkt
- +// priv->stats.txbeaconerr
- + );
- +
- + *eof = 1;
- + return len;
- +}
- +
- +
- +
- +static int proc_get_stats_rx(char *page, char **start,
- + off_t offset, int count,
- + int *eof, void *data)
- +{
- + struct net_device *dev = data;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + int len = 0;
- +
- + len += snprintf(page + len, count - len,
- + "RX packets: %lu\n"
- + "RX urb status error: %lu\n"
- + "RX invalid urb error: %lu\n",
- + priv->stats.rxok,
- + priv->stats.rxstaterr,
- + priv->stats.rxurberr);
- +
- + *eof = 1;
- + return len;
- +}
- +
- +#if WIRELESS_EXT < 17
- +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + return &priv->wstats;
- +}
- +#endif
- +
- +void rtl8180_proc_module_init(void)
- +{
- + DMESG("Initializing proc filesystem");
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
- + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, proc_net);
- +#else
- + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
- +#endif
- +}
- +
- +
- +void rtl8180_proc_module_remove(void)
- +{
- +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
- + remove_proc_entry(RTL8187_MODULE_NAME, proc_net);
- +#else
- + remove_proc_entry(RTL8187_MODULE_NAME, init_net.proc_net);
- +#endif
- +}
- +
- +
- +void rtl8180_proc_remove_one(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + if (priv->dir_dev) {
- + // remove_proc_entry("stats-hw", priv->dir_dev);
- + remove_proc_entry("stats-tx", priv->dir_dev);
- + remove_proc_entry("stats-rx", priv->dir_dev);
- + // remove_proc_entry("stats-ieee", priv->dir_dev);
- + remove_proc_entry("stats-ap", priv->dir_dev);
- + remove_proc_entry("registers", priv->dir_dev);
- + remove_proc_entry("cck-registers",priv->dir_dev);
- + remove_proc_entry("ofdm-registers",priv->dir_dev);
- + remove_proc_entry(dev->name, rtl8180_proc);
- + priv->dir_dev = NULL;
- + }
- +}
- +
- +
- +void rtl8180_proc_init_one(struct net_device *dev)
- +{
- + struct proc_dir_entry *e;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + priv->dir_dev = create_proc_entry(dev->name,
- + S_IFDIR | S_IRUGO | S_IXUGO,
- + rtl8180_proc);
- + if (!priv->dir_dev) {
- + DMESGE("Unable to initialize /proc/net/rtl8187/%s\n",
- + dev->name);
- + return;
- + }
- + #if 0
- + e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_stats_hw, dev);
- +
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/stats-hw\n",
- + dev->name);
- + }
- + #endif
- + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_stats_rx, dev);
- +
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/stats-rx\n",
- + dev->name);
- + }
- +
- +
- + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_stats_tx, dev);
- +
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/stats-tx\n",
- + dev->name);
- + }
- + #if 0
- + e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_stats_ieee, dev);
- +
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/stats-ieee\n",
- + dev->name);
- + }
- +
- + #endif
- +
- + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_stats_ap, dev);
- +
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/stats-ap\n",
- + dev->name);
- + }
- +
- + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_registers, dev);
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/registers\n",
- + dev->name);
- + }
- +
- + e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_cck_reg, dev);
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/cck-registers\n",
- + dev->name);
- + }
- +
- + e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
- + priv->dir_dev, proc_get_ofdm_reg, dev);
- + if (!e) {
- + DMESGE("Unable to initialize "
- + "/proc/net/rtl8187/%s/ofdm-registers\n",
- + dev->name);
- + }
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if( priv->mshobj && priv->mshobj->ext_patch_create_proc )
- + priv->mshobj->ext_patch_create_proc(priv);
- +#endif
- +
- +}
- +/****************************************************************************
- + -----------------------------MISC STUFF-------------------------
- +*****************************************************************************/
- +
- +/* this is only for debugging */
- +void print_buffer(u32 *buffer, int len)
- +{
- + int i;
- + u8 *buf =(u8*)buffer;
- +
- + printk("ASCII BUFFER DUMP (len: %x):\n",len);
- +
- + for(i=0;i<len;i++)
- + printk("%c",buf[i]);
- +
- + printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
- +
- + for(i=0;i<len;i++)
- + printk("%x",buf[i]);
- +
- + printk("\n");
- +}
- +
- +short check_nic_enought_desc(struct net_device *dev, priority_t priority)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //int used = atomic_read((priority == NORM_PRIORITY) ?
- + // &priv->tx_np_pending : &priv->tx_lp_pending);
- + int used = atomic_read(&priv->tx_pending[priority]);
- +
- + return (used < MAX_TX_URB);
- +}
- +
- +void tx_timeout(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //rtl8180_commit(dev);
- + printk("@@@@ Transmit timeout at %ld, latency %ld\n", jiffies,
- + jiffies - dev->trans_start);
- +
- + printk("@@@@ netif_queue_stopped = %d\n", netif_queue_stopped(dev));
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- + schedule_work(&priv->reset_wq);
- +#else
- + schedule_task(&priv->reset_wq);
- +#endif
- + //DMESG("TXTIMEOUT");
- +}
- +
- +
- +/* this is only for debug */
- +void dump_eprom(struct net_device *dev)
- +{
- + int i;
- + for(i=0; i<63; i++)
- + DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
- +}
- +
- +/* this is only for debug */
- +void rtl8180_dump_reg(struct net_device *dev)
- +{
- + int i;
- + int n;
- + int max=0xff;
- +
- + DMESG("Dumping NIC register map");
- +
- + for(n=0;n<=max;)
- + {
- + printk( "\nD: %2x> ", n);
- + for(i=0;i<16 && n<=max;i++,n++)
- + printk("%2x ",read_nic_byte(dev,n));
- + }
- + printk("\n");
- +}
- +
- +/****************************************************************************
- + ------------------------------HW STUFF---------------------------
- +*****************************************************************************/
- +
- +
- +void rtl8180_irq_enable(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + //priv->irq_enabled = 1;
- +
- + //write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |
- + // INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |
- + // INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |
- + // INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
- +
- + write_nic_word(dev,INTA_MASK, priv->irq_mask);
- +}
- +
- +
- +void rtl8180_irq_disable(struct net_device *dev)
- +{
- + write_nic_word(dev,INTA_MASK,0);
- + force_pci_posting(dev);
- +// priv->irq_enabled = 0;
- +}
- +
- +
- +void rtl8180_set_mode(struct net_device *dev,int mode)
- +{
- + u8 ecmd;
- + ecmd=read_nic_byte(dev, EPROM_CMD);
- + ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
- + ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
- + ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
- + ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
- + write_nic_byte(dev, EPROM_CMD, ecmd);
- +}
- +
- +
- +void rtl8180_update_msr(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 msr;
- +
- + msr = read_nic_byte(dev, MSR);
- + msr &= ~ MSR_LINK_MASK;
- +
- + /* do not change in link_state != WLAN_LINK_ASSOCIATED.
- + * msr must be updated if the state is ASSOCIATING.
- + * this is intentional and make sense for ad-hoc and
- + * master (see the create BSS/IBSS func)
- + */
- + if (priv->ieee80211->state == IEEE80211_LINKED){
- +
- + if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
- + msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
- + else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- + msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
- + else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
- + msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
- +
- + }else
- + msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
- +
- + write_nic_byte(dev, MSR, msr);
- +}
- +
- +void rtl8180_set_chan(struct net_device *dev,short ch)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + u32 tx;
- +
- + priv->chan=ch;
- + #if 0
- + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
- + priv->ieee80211->iw_mode == IW_MODE_MASTER){
- +
- + priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
- + priv->ieee80211->master_chan = ch;
- + rtl8180_update_beacon_ch(dev);
- + }
- + #endif
- +
- + /* this hack should avoid frame TX during channel setting*/
- + tx = read_nic_dword(dev,TX_CONF);
- + tx &= ~TX_LOOPBACK_MASK;
- +
- +#ifndef LOOP_TEST
- + write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
- + priv->rf_set_chan(dev,priv->chan);
- + //mdelay(10); //CPU occupany is too high. LZM 31/10/2008
- + write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
- +#endif
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs);
- +#else
- +void rtl8187_rx_isr(struct urb* rx_urb);
- +#endif
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs);
- +#else
- +void rtl8187_rx_manage_isr(struct urb* rx_urb);
- +#endif
- +
- +
- +
- +void rtl8187_rx_urbsubmit(struct net_device *dev, struct urb* rx_urb)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + int err;
- +
- + usb_fill_bulk_urb(rx_urb,priv->udev,
- + usb_rcvbulkpipe(priv->udev,(NIC_8187 == priv->card_8187)?0x81:0x83),
- + rx_urb->transfer_buffer,
- + RX_URB_SIZE,
- + rtl8187_rx_isr,
- + dev);
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + err = usb_submit_urb(rx_urb, GFP_ATOMIC);
- +#else
- + err = usb_submit_urb(rx_urb);
- +#endif
- + if(err && err != -EPERM){
- + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
- + }
- +}
- +
- +
- +void rtl8187_rx_manage_urbsubmit(struct net_device *dev, struct urb* rx_urb)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + int err;
- +#ifdef THOMAS_BEACON
- + usb_fill_bulk_urb(rx_urb,priv->udev,
- + usb_rcvbulkpipe(priv->udev,0x09),
- + rx_urb->transfer_buffer,
- + rx_urb->transfer_buffer_length,
- + rtl8187_rx_manage_isr, dev);
- +#endif
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + err = usb_submit_urb(rx_urb, GFP_ATOMIC);
- +#else
- + err = usb_submit_urb(rx_urb);
- +#endif
- + if(err && err != -EPERM){
- + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
- + }
- +}
- +
- +
- +
- +void rtl8187_rx_initiate(struct net_device *dev)
- +{
- + int i;
- + unsigned long flags;
- + struct urb *purb;
- +
- + struct sk_buff *pskb;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + priv->tx_urb_index = 0;
- +
- + if ((!priv->rx_urb) || (!priv->pp_rxskb)) {
- +
- + DMESGE("Cannot intiate RX urb mechanism");
- + return;
- +
- + }
- +
- + priv->rx_inx = 0;
- +#ifdef THOMAS_TASKLET
- + atomic_set(&priv->irt_counter,0);
- +#endif
- + for(i = 0;i < MAX_RX_URB; i++){
- +
- + purb = priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
- +
- + if(!priv->rx_urb[i])
- + goto destroy;
- +
- + pskb = priv->pp_rxskb[i] = dev_alloc_skb (RX_URB_SIZE);
- +
- + if (pskb == NULL)
- + goto destroy;
- +
- + purb->transfer_buffer_length = RX_URB_SIZE;
- + purb->transfer_buffer = pskb->data;
- + }
- +
- + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
- +
- + for(i=0;i<MAX_RX_URB;i++)
- + rtl8187_rx_urbsubmit(dev,priv->rx_urb[i]);
- +
- + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
- +
- + return;
- +
- +destroy:
- +
- + for(i = 0; i < MAX_RX_URB; i++) {
- +
- + purb = priv->rx_urb[i];
- +
- + if (purb)
- + usb_free_urb(purb);
- +
- + pskb = priv->pp_rxskb[i];
- +
- + if (pskb)
- + dev_kfree_skb_any(pskb);
- +
- + }
- +
- + return;
- +}
- +
- +
- +void rtl8187_rx_manage_initiate(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + if(!priv->rx_urb)
- + DMESGE("Cannot intiate RX urb mechanism");
- +
- + rtl8187_rx_manage_urbsubmit(dev,priv->rx_urb[MAX_RX_URB]);
- +
- +}
- +
- +
- +void rtl8187_set_rxconf(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + u32 rxconf;
- +
- + rxconf=read_nic_dword(dev,RX_CONF);
- + rxconf = rxconf &~ MAC_FILTER_MASK;
- + rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
- + rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
- + rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
- + rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
- + //rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
- +#ifdef SW_ANTE_DIVERSITY
- + rxconf = rxconf | priv->EEPROMCSMethod;//for antenna
- +#endif
- +
- + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
- +
- + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
- + dev->flags & IFF_PROMISC){
- + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
- + } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
- + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
- + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
- + }*/else{
- + rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
- + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
- + }
- +
- +
- + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
- + rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
- + rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
- + }
- +
- + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
- + rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
- +
- +
- + rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
- + rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
- + rxconf = rxconf &~ MAX_RX_DMA_MASK;
- + rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
- +
- + rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
- + rxconf = rxconf | RCR_ONLYERLPKT;
- +
- + //rxconf = rxconf &~ RCR_CS_MASK;
- + //rxconf = rxconf | (1<<RCR_CS_SHIFT);
- +
- + write_nic_dword(dev, RX_CONF, rxconf);
- +
- + #ifdef DEBUG_RX
- + DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
- + #endif
- +}
- +
- +void rtl8180_rx_enable(struct net_device *dev)
- +{
- + u8 cmd;
- +
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + rtl8187_rx_initiate(dev);
- + rtl8187_set_rxconf(dev);
- +
- + if(NIC_8187 == priv->card_8187) {
- + cmd=read_nic_byte(dev,CMD);
- + write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
- + } else {
- + //write_nic_dword(dev, RCR, priv->ReceiveConfig);
- + }
- +}
- +
- +
- +void rtl8180_tx_enable(struct net_device *dev)
- +{
- + u8 cmd;
- + u8 byte;
- + u32 txconf = 0;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + if(NIC_8187B == priv->card_8187){
- + write_nic_dword(dev, TCR, priv->TransmitConfig);
- + byte = read_nic_byte(dev, MSR);
- + byte |= MSR_LINK_ENEDCA;
- + write_nic_byte(dev, MSR, byte);
- +#ifdef LOOP_TEST
- + txconf= read_nic_dword(dev,TX_CONF);
- + txconf = txconf | (TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT);
- + write_nic_dword(dev,TX_CONF,txconf);
- +#endif
- + } else {
- + byte = read_nic_byte(dev,CW_CONF);
- + byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
- + byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
- + write_nic_byte(dev, CW_CONF, byte);
- +
- + byte = read_nic_byte(dev, TX_AGC_CTL);
- + byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
- + byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
- + byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
- + write_nic_byte(dev, TX_AGC_CTL, byte);
- +
- + txconf= read_nic_dword(dev,TX_CONF);
- +
- +
- + txconf = txconf &~ TX_LOOPBACK_MASK;
- +
- +#ifndef LOOP_TEST
- + txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
- +#else
- + txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
- +#endif
- + txconf = txconf &~ TCR_SRL_MASK;
- + txconf = txconf &~ TCR_LRL_MASK;
- +
- + txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
- + txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
- +
- + txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
- +
- + txconf = txconf &~ TCR_MXDMA_MASK;
- + txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
- +
- + txconf = txconf | TCR_DISReqQsize;
- + txconf = txconf | TCR_DISCW;
- + txconf = txconf &~ TCR_SWPLCPLEN;
- +
- + txconf=txconf | (1<<TX_NOICV_SHIFT);
- +
- + write_nic_dword(dev,TX_CONF,txconf);
- +
- +#ifdef DEBUG_TX
- + DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
- +#endif
- +
- + cmd=read_nic_byte(dev,CMD);
- + write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
- + }
- +}
- +
- +#if 0
- +void rtl8180_beacon_tx_enable(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
- + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
- + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- +}
- +
- +
- +void rtl8180_
- +_disable(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
- + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
- + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- +}
- +
- +#endif
- +
- +
- +void rtl8180_rtx_disable(struct net_device *dev)
- +{
- + u8 cmd;
- + int i;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + cmd=read_nic_byte(dev,CMD);
- + write_nic_byte(dev, CMD, cmd &~ \
- + ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
- + force_pci_posting(dev);
- + mdelay(10);
- +
- +#ifdef THOMAS_BEACON
- + {
- + int index = priv->rx_inx;//0
- + i=0;
- + if(priv->rx_urb){
- + while(i<MAX_RX_URB){
- + if(priv->rx_urb[index]){
- + usb_kill_urb(priv->rx_urb[index]);
- + }
- + if( index == (MAX_RX_URB-1) )
- + index=0;
- + else
- + index=index+1;
- + i++;
- + }
- + if(priv->rx_urb[MAX_RX_URB])
- + usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
- + }
- + }
- +#endif
- +}
- +
- +
- +int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
- +{
- + #if 0
- + int i;
- + u32 *tmp;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
- + sizeof(u32)*8*count,
- + &priv->txbeaconringdma);
- + if (!priv->txbeaconring) return -1;
- + for (tmp=priv->txbeaconring,i=0;i<count;i++){
- + *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
- + /*
- + *(tmp+2) = (u32)dma_tmp;
- + *(tmp+3) = bufsize;
- + */
- + if(i+1<count)
- + *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
- + else
- + *(tmp+4) = (u32)priv->txbeaconringdma;
- +
- + tmp=tmp+8;
- + }
- + #endif
- + return 0;
- +}
- +
- +long NetgearSignalStrengthTranslate(long LastSS,long CurrSS)
- +{
- + long RetSS;
- +
- + // Step 1. Scale mapping.
- + if(CurrSS >= 71 && CurrSS <= 100){
- + RetSS = 90 + ((CurrSS - 70) / 3);
- + }else if(CurrSS >= 41 && CurrSS <= 70){
- + RetSS = 78 + ((CurrSS - 40) / 3);
- + }else if(CurrSS >= 31 && CurrSS <= 40){
- + RetSS = 66 + (CurrSS - 30);
- + }else if(CurrSS >= 21 && CurrSS <= 30){
- + RetSS = 54 + (CurrSS - 20);
- + }else if(CurrSS >= 5 && CurrSS <= 20){
- + RetSS = 42 + (((CurrSS - 5) * 2) / 3);
- + }else if(CurrSS == 4){
- + RetSS = 36;
- + }else if(CurrSS == 3){
- + RetSS = 27;
- + }else if(CurrSS == 2){
- + RetSS = 18;
- + }else if(CurrSS == 1){
- + RetSS = 9;
- + }else{
- + RetSS = CurrSS;
- + }
- + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
- +
- + // Step 2. Smoothing.
- + if(LastSS > 0){
- + RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
- + }
- + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
- +
- + return RetSS;
- +}
- +
- +extern long TranslateToDbm8187(u8 SignalStrengthIndex); // 0-100 index.
- +//long TranslateToDbm8187(u8 SignalStrengthIndex) // 0-100 index.
- +//{
- + // long SignalPower; // in dBm.
- +
- + // Translate to dBm (x=0.5y-95).
- + // SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
- + // SignalPower -= 95;
- +
- + // return SignalPower;
- +//}
- +
- +
- +void rtl8180_reset(struct net_device *dev)
- +{
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 cr;
- + int i;
- +
- +
- + /* make sure the analog power is on before
- + * reset, otherwise reset may fail
- + */
- + if(NIC_8187 == priv->card_8187) {
- + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
- + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
- + rtl8180_irq_disable(dev);
- + mdelay(200);
- + write_nic_byte_E(dev,0x18,0x10);
- + write_nic_byte_E(dev,0x18,0x11);
- + write_nic_byte_E(dev,0x18,0x00);
- + mdelay(200);
- + }
- +
- +
- + cr=read_nic_byte(dev,CMD);
- + cr = cr & 2;
- + cr = cr | (1<<CMD_RST_SHIFT);
- + write_nic_byte(dev,CMD,cr);
- +
- + //lzm mod for up take too long time 20081201
- + //force_pci_posting(dev);
- + //mdelay(200);
- + udelay(20);
- +
- + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
- + DMESGW("Card reset timeout!");
- +
- + if(NIC_8187 == priv->card_8187) {
- +
- + //printk("This is RTL8187 Reset procedure\n");
- + rtl8180_set_mode(dev,EPROM_CMD_LOAD);
- + force_pci_posting(dev);
- + mdelay(200);
- +
- + /* after the eeprom load cycle, make sure we have
- + * correct anaparams
- + */
- + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
- + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
- + }
- + else {
- + //printk("This is RTL8187B Reset procedure\n");
- + //test pending bug, john 20070815
- + //initialize tx_pending
- + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
- +
- + }
- +
- +}
- +
- +inline u16 ieeerate2rtlrate(int rate)
- +{
- + switch(rate){
- + case 10:
- + return 0;
- + case 20:
- + return 1;
- + case 55:
- + return 2;
- + case 110:
- + return 3;
- + case 60:
- + return 4;
- + case 90:
- + return 5;
- + case 120:
- + return 6;
- + case 180:
- + return 7;
- + case 240:
- + return 8;
- + case 360:
- + return 9;
- + case 480:
- + return 10;
- + case 540:
- + return 11;
- + default:
- + return 3;
- +
- + }
- +}
- +static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720};
- +inline u16 rtl8180_rate2rate(short rate)
- +{
- + if (rate >12) return 10;
- + return rtl_rate[rate];
- +}
- +
- +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_rx_isr(struct urb* rx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)rx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + priv->rxurb_task = rx_urb;
- +
- +
- + //DMESGW("David: Rx tasklet start!");
- +
- +#ifdef THOMAS_TASKLET
- + atomic_inc( &priv->irt_counter );
- +
- + //if( likely(priv->irt_counter_head+1 != priv->irt_counter_tail) ){
- + // priv->irt_counter_head = (priv->irt_counter_head+1)&0xffff ;
- + tasklet_schedule(&priv->irq_rx_tasklet);
- + //} else{
- + //DMESG("error: priv->irt_counter_head is going to pass through priv->irt_counter_tail\n");
- + /*
- + skb = priv->pp_rxskb[priv->rx_inx];
- + dev_kfree_skb_any(skb);
- +
- + skb = dev_alloc_skb(RX_URB_SIZE);
- + if (skb == NULL)
- + panic("No Skb For RX!/n");
- +
- + rx_urb->transfer_buffer = skb->data;
- +
- + priv->pp_rxskb[priv->rx_inx] = skb;
- + if(status == 0)
- + rtl8187_rx_urbsubmit(dev,rx_urb);
- + else {
- + priv->pp_rxskb[priv->rx_inx] = NULL;
- + dev_kfree_skb_any(skb);
- + printk("RX process aborted due to explicit shutdown (%x) ", status);
- + }
- +
- + if (*prx_inx == (MAX_RX_URB -1))
- + *prx_inx = 0;
- + else
- + *prx_inx = *prx_inx + 1;
- +
- + */
- + //}
- +#endif
- +
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_rx_manage_isr(struct urb* rx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)rx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int status,cmd;
- + struct sk_buff *skb;
- + u32 *desc;
- + int ret;
- + unsigned long flag;
- +
- + //DMESG("RX %d ",rx_urb->status);
- + status = rx_urb->status;
- + if(status == 0){
- +
- + desc = (u32*)(rx_urb->transfer_buffer);
- + cmd = (desc[0] >> 30) & 0x03;
- + //printk(KERN_ALERT "buffersize = %d, length = %d, pipe = %p\n",
- + //rx_urb->transfer_buffer_length, rx_urb->actual_length, rx_urb->pipe>>15);
- +
- + if(cmd == 0x00) {//beacon interrupt
- + //send beacon packet
- +
- + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
- + if(priv->flag_beacon == true){
- + //printk("rtl8187_rx_manage_isr(): CMD_TYPE0_BCN_INTR\n");
- +
- + skb = ieee80211_get_beacon(priv->ieee80211);
- + if(!skb){
- + DMESG("not enought memory for allocating beacon");
- + return;
- + }
- + //printk(KERN_WARNING "to send beacon packet through beacon endpoint!\n");
- + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, BEACON_PRIORITY,
- + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
- +
- + if( ret != 0 ){
- + printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
- + }
- + dev_kfree_skb_any(skb);
- +
- + //} else {//0x00
- + //{ log the device information
- + // At present, It is not implemented just now.
- + //}
- + //}
- +
- + }
- + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
- + }
- + else if(cmd == 0x01){
- + //printk("rtl8187_rx_manage_isr(): CMD_TYPE1_TX_CLOSE\n");
- + priv->CurrRetryCnt += (u16)desc[0]&0x000000ff;
- + //printk("priv->CurrRetryCnt is %d\n",priv->CurrRetryCnt);
- + }
- + else
- + printk("HalUsbInCommandComplete8187B(): unknown Type(%#X) !!!\n", cmd);
- +
- + }else{
- + priv->stats.rxstaterr++;
- + priv->ieee80211->stats.rx_errors++;
- + }
- +
- +
- + if( status == 0 )
- + //if(status != -ENOENT)
- + rtl8187_rx_manage_urbsubmit(dev, rx_urb);
- + else
- + ;//DMESG("Mangement RX process aborted due to explicit shutdown");
- +}
- +
- +#if 0
- +void rtl8180_tx_queues_stop(struct net_device *dev)
- +{
- + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
- + dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
- + dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
- + dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
- +
- + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
- + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- +}
- +#endif
- +
- +void rtl8180_data_hard_stop(struct net_device *dev)
- +{
- + //FIXME !!
- + #if 0
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
- + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
- + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- + #endif
- +}
- +
- +
- +void rtl8180_data_hard_resume(struct net_device *dev)
- +{
- + // FIXME !!
- + #if 0
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
- + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
- + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- + #endif
- +}
- +
- +unsigned int PRI2EP[4] = {0x06,0x07,0x05,0x04};
- +// this function TX data frames when the ieee80211 stack requires this.
- +// It checks also if we need to stop the ieee tx queue, eventually do it
- +void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + short morefrag = 0;
- + unsigned long flags;
- + struct ieee80211_hdr *h = (struct ieee80211_hdr *) skb->data;
- +
- + unsigned char ep;
- + short ret; //john
- +
- + if (le16_to_cpu(h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS)
- + morefrag = 1;
- + //DMESG("%x %x", h->frame_ctl, h->seq_ctl);
- + /*
- + * This function doesn't require lock because we make
- + * sure it's called with the tx_lock already acquired.
- + * this come from the kernel's hard_xmit callback (trought
- + * the ieee stack, or from the try_wake_queue (again trought
- + * the ieee stack.
- + */
- + spin_lock_irqsave(&priv->tx_lock,flags);
- +
- + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
- + if((priv->ieee80211->bHwRadioOff)||(!priv->up))
- + {
- + spin_unlock_irqrestore(&priv->tx_lock,flags);
- +
- + return;
- + }
- +
- + if(NIC_8187B == priv->card_8187){
- + ep = PRI2EP[skb->priority];
- + } else {
- + ep = LOW_PRIORITY;
- + }
- + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
- + if (!check_nic_enought_desc(dev, ep)){
- + DMESG("Error: no TX slot ");
- + ieee80211_stop_queue(priv->ieee80211);
- + }
- +
- +#ifdef LED_SHIN
- + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_TX);
- +#endif
- +
- + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, ep, morefrag,ieeerate2rtlrate(rate));
- + if(ret!=0) DMESG("Error: rtl8180_tx failed in rtl8180_hard_data_xmit\n");//john
- +
- + priv->stats.txdatapkt++;
- +
- + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
- + if (!check_nic_enought_desc(dev, ep)){
- + ieee80211_stop_queue(priv->ieee80211);
- + }
- +
- + spin_unlock_irqrestore(&priv->tx_lock,flags);
- +
- +}
- +
- +//This is a rough attempt to TX a frame
- +//This is called by the ieee 80211 stack to TX management frames.
- +//If the ring is full packet are dropped (for data frame the queue
- +//is stopped before this can happen).
- +
- +int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct ieee80211_device *ieee = priv->ieee80211;
- + int ret;
- + unsigned long flags;
- + spin_lock_irqsave(&priv->tx_lock,flags);
- +
- + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
- + if((priv->ieee80211->bHwRadioOff)||(!priv->up))
- + {
- + spin_unlock_irqrestore(&priv->tx_lock,flags);
- + return 0;
- + }
- +
- + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, MANAGE_PRIORITY, 0, ieeerate2rtlrate(ieee->basic_rate));
- +
- + priv->ieee80211->stats.tx_bytes+=skb->len;
- + priv->ieee80211->stats.tx_packets++;
- +
- + spin_unlock_irqrestore(&priv->tx_lock,flags);
- +
- + return ret;
- +}
- +
- +
- +#if 0
- +// longpre 144+48 shortpre 72+24
- +u16 rtl8180_len2duration(u32 len, short rate,short* ext)
- +{
- + u16 duration;
- + u16 drift;
- + *ext=0;
- +
- + switch(rate){
- + case 0://1mbps
- + *ext=0;
- + duration = ((len+4)<<4) /0x2;
- + drift = ((len+4)<<4) % 0x2;
- + if(drift ==0 ) break;
- + duration++;
- + break;
- +
- + case 1://2mbps
- + *ext=0;
- + duration = ((len+4)<<4) /0x4;
- + drift = ((len+4)<<4) % 0x4;
- + if(drift ==0 ) break;
- + duration++;
- + break;
- +
- + case 2: //5.5mbps
- + *ext=0;
- + duration = ((len+4)<<4) /0xb;
- + drift = ((len+4)<<4) % 0xb;
- + if(drift ==0 )
- + break;
- + duration++;
- + break;
- +
- + default:
- + case 3://11mbps
- + *ext=0;
- + duration = ((len+4)<<4) /0x16;
- + drift = ((len+4)<<4) % 0x16;
- + if(drift ==0 )
- + break;
- + duration++;
- + if(drift > 6)
- + break;
- + *ext=1;
- + break;
- + }
- +
- + return duration;
- +}
- +#endif
- +
- +void rtl8180_try_wake_queue(struct net_device *dev, int pri);
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_lptx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_lptx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txlpokint++;
- + priv->txokbytestotal+=tx_urb->actual_length;
- + }else{
- + priv->stats.txlperr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[LOW_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[LOW_PRIORITY]);
- +
- + rtl8180_try_wake_queue(dev,LOW_PRIORITY);
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_nptx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txnpokint++;
- + }else{
- + priv->stats.txnperr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[NORM_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[NORM_PRIORITY]);
- + //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_votx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_votx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txvookint++;
- + priv->txokbytestotal+=tx_urb->actual_length;
- + }else{
- + priv->stats.txvoerr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[VO_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[VO_PRIORITY]);
- + rtl8180_try_wake_queue(dev,VO_PRIORITY);
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_vitx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_vitx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txviokint++;
- + priv->txokbytestotal+=tx_urb->actual_length;
- + }else{
- + priv->stats.txvierr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[VI_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[VI_PRIORITY]);
- + rtl8180_try_wake_queue(dev,VI_PRIORITY);
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_betx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_betx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txbeokint++;
- + priv->txokbytestotal+=tx_urb->actual_length;
- + }else{
- + priv->stats.txbeerr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[BE_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[BE_PRIORITY]);
- + rtl8180_try_wake_queue(dev, BE_PRIORITY);
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_bktx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_bktx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txbkokint++;
- + }else{
- + priv->stats.txbkerr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[BK_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[BK_PRIORITY]);
- + rtl8180_try_wake_queue(dev,BK_PRIORITY);
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_beacontx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_beacontx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txbeaconokint++;
- + priv->txokbytestotal+=tx_urb->actual_length;
- + }else{
- + priv->stats.txbeaconerr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[BEACON_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[BEACON_PRIORITY]);
- + //rtl8180_try_wake_queue(dev,BEACON_PRIORITY);
- +}
- +
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void rtl8187_managetx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +#else
- +void rtl8187_managetx_isr(struct urb* tx_urb)
- +#endif
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0){
- + dev->trans_start = jiffies; //john
- + priv->stats.txmanageokint++;
- + priv->txokbytestotal+=tx_urb->actual_length;
- + }else{
- + priv->stats.txmanageerr++;
- + }
- +
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- +
- + if(atomic_read(&priv->tx_pending[MANAGE_PRIORITY]) >= 1)
- + atomic_dec(&priv->tx_pending[MANAGE_PRIORITY]);
- +// rtl8180_try_wake_queue(dev,MANAGE_PRIORITY);
- +}
- +
- +void rtl8187_beacon_stop(struct net_device *dev)
- +{
- + u8 msr, msrm, msr2;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + unsigned long flag;
- + msr = read_nic_byte(dev, MSR);
- + msrm = msr & MSR_LINK_MASK;
- + msr2 = msr & ~MSR_LINK_MASK;
- + if(NIC_8187B == priv->card_8187) {
- + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
- + priv->flag_beacon = false;
- + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
- + }
- + if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
- + (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
- + write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
- + write_nic_byte(dev, MSR, msr);
- + }
- +}
- +
- +
- +void rtl8187_net_update(struct net_device *dev)
- +{
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_network *net;
- + net = & priv->ieee80211->current_network;
- +
- +
- + write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
- + write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
- +
- + rtl8180_update_msr(dev);
- +
- + //rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + write_nic_word(dev, AtimWnd, 2);
- + write_nic_word(dev, AtimtrItv, 100);
- + write_nic_word(dev, BEACON_INTERVAL, net->beacon_interval);
- + //write_nic_word(dev, BcnIntTime, 100);
- + write_nic_word(dev, BcnIntTime, 0x3FF);
- +
- +
- +}
- +
- +void rtl8187_beacon_tx(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct sk_buff *skb;
- + int i = 0;
- + u8 cr;
- + unsigned long flag;
- + rtl8187_net_update(dev);
- +
- + if(NIC_8187B == priv->card_8187) {
- + //Cause TSF timer of MAC reset to 0
- + cr=read_nic_byte(dev,CMD);
- + cr = cr | (1<<CMD_RST_SHIFT);
- + write_nic_byte(dev,CMD,cr);
- +
- + //lzm mod 20081201
- + //mdelay(200);
- + mdelay(20);
- +
- + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
- + DMESGW("Card reset timeout for ad-hoc!");
- + else
- + DMESG("Card successfully reset for ad-hoc");
- +
- + write_nic_byte(dev,CMD, (read_nic_byte(dev,CMD)|CR_RE|CR_TE));
- + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
- + priv->flag_beacon = true;
- + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
- +
- + //rtl8187_rx_manage_initiate(dev);
- + } else {
- + printk(KERN_WARNING "get the beacon!\n");
- + skb = ieee80211_get_beacon(priv->ieee80211);
- + if(!skb){
- + DMESG("not enought memory for allocating beacon");
- + return;
- + }
- +
- + write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
- +
- + i=0;
- + //while(!read_nic_byte(dev,BQREQ & (1<<7)))
- + while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
- + {
- + msleep_interruptible_rtl(HZ/2);
- + if(i++ > 10){
- + DMESGW("get stuck to wait HW beacon to be ready");
- + return ;
- + }
- + }
- + //tx
- + rtl8180_tx(dev, (u32*)skb->data, skb->len, NORM_PRIORITY,
- + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
- + if(skb)
- + dev_kfree_skb_any(skb);
- + }
- +}
- +
- +#if 0
- +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
- +{
- + struct net_device *dev = (struct net_device*)tx_urb->context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if(tx_urb->status == 0)
- + priv->stats.txnpokint++;
- + else
- + priv->stats.txnperr++;
- + kfree(tx_urb->transfer_buffer);
- + usb_free_urb(tx_urb);
- + atomic_dec(&priv->tx_np_pending);
- + //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
- +}
- +#endif
- +inline u8 rtl8180_IsWirelessBMode(u16 rate)
- +{
- + if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
- + return 1;
- + else return 0;
- +}
- +
- +u16 N_DBPSOfRate(u16 DataRate);
- +
- +u16 ComputeTxTime(
- + u16 FrameLength,
- + u16 DataRate,
- + u8 bManagementFrame,
- + u8 bShortPreamble
- + )
- +{
- + u16 FrameTime;
- + u16 N_DBPS;
- + u16 Ceiling;
- +
- + if( rtl8180_IsWirelessBMode(DataRate) )
- + {
- + if( bManagementFrame || !bShortPreamble || DataRate == 10 ){ // long preamble
- + FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
- + }else{ // Short preamble
- + FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
- + }
- + if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
- + FrameTime ++;
- + } else { //802.11g DSSS-OFDM PLCP length field calculation.
- + N_DBPS = N_DBPSOfRate(DataRate);
- + Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
- + + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
- + FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
- + }
- + return FrameTime;
- +}
- +
- +u16 N_DBPSOfRate(u16 DataRate)
- +{
- + u16 N_DBPS = 24;
- +
- + switch(DataRate)
- + {
- + case 60:
- + N_DBPS = 24;
- + break;
- +
- + case 90:
- + N_DBPS = 36;
- + break;
- +
- + case 120:
- + N_DBPS = 48;
- + break;
- +
- + case 180:
- + N_DBPS = 72;
- + break;
- +
- + case 240:
- + N_DBPS = 96;
- + break;
- +
- + case 360:
- + N_DBPS = 144;
- + break;
- +
- + case 480:
- + N_DBPS = 192;
- + break;
- +
- + case 540:
- + N_DBPS = 216;
- + break;
- +
- + default:
- + break;
- + }
- +
- + return N_DBPS;
- +}
- +// NOte!!!
- +// the rate filled in is the rtl_rate.
- +// while the priv->ieee80211->basic_rate,used in the following code is ieee80211 rate.
- +
- +#ifdef JUST_FOR_87SEMESH
- +#define ActionHeadLen 30
- +#endif
- +#define sCrcLng 4
- +#define sAckCtsLng 112 // bits in ACK and CTS frames
- +short rtl8180_tx(struct net_device *dev, u32* txbuf, int len, priority_t priority,
- + short morefrag, short rate)
- +{
- + u32 *tx;
- + int pend ;
- + int status;
- + struct urb *tx_urb;
- + int urb_len;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct ieee80211_hdr_3addr_QOS *frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
- + struct ieee80211_device *ieee;//added for descriptor
- + u8 dest[ETH_ALEN];
- +
- + bool bUseShortPreamble = false;
- + bool bCTSEnable = false;
- + bool bRTSEnable = false;
- + u16 Duration = 0;
- + u16 RtsDur = 0;
- + u16 ThisFrameTime = 0;
- + u16 TxDescDuration = 0;
- +
- + ieee = priv->ieee80211;
- +#if 0
- +//{added by david for filter the packet listed in the filter table
- +#ifdef _RTL8187_EXT_PATCH_
- + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
- + {
- + if(!ieee->ext_patch_ieee80211_acl_query(ieee, frag_hdr->addr1)) {
- + return 0;
- + }
- + }
- +#endif
- +//}
- +#endif
- +
- +#ifdef JUST_FOR_87SEMESH
- +//#ifdef Lawrence_Mesh
- + u8* meshtype = (u8*)txbuf;
- + if(*meshtype == 0xA8)
- + {
- + //overflow??
- + //memcpy(meshtype+ActionHeadLen+2,meshtype+ActionHeadLen,Len-ActionHeadLen);
- + //memcpy(meshtype+ActionHeadLen,0,2);
- + u8 actionframe[256];
- + memset(actionframe,0,256);
- + memcpy(actionframe,meshtype,ActionHeadLen);
- + memcpy(actionframe+ActionHeadLen+2,meshtype+ActionHeadLen,len-ActionHeadLen);
- + txbuf = (u32*)actionframe;
- + len=len+2;
- + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
- + }
- +#endif
- +
- + //pend = atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
- + pend = atomic_read(&priv->tx_pending[priority]);
- + /* we are locked here so the two atomic_read and inc are executed without interleaves */
- + if( pend > MAX_TX_URB){
- + if(NIC_8187 == priv->card_8187) {
- + if(priority == NORM_PRIORITY)
- + priv->stats.txnpdrop++;
- + else
- + priv->stats.txlpdrop++;
- +
- + } else {
- + switch (priority) {
- + case VO_PRIORITY:
- + priv->stats.txvodrop++;
- + break;
- + case VI_PRIORITY:
- + priv->stats.txvidrop++;
- + break;
- + case BE_PRIORITY:
- + priv->stats.txbedrop++;
- + break;
- + case MANAGE_PRIORITY: //lzm for MANAGE_PRIORITY pending
- + if(priv->commit == 0)
- + {
- + priv->commit = 1;
- + printk(KERN_INFO "manage pkt pending will commit now....\n");
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- + schedule_work(&priv->reset_wq);
- +#else
- + schedule_task(&priv->reset_wq);
- +#endif
- + }
- + break;
- + default://BK_PRIORITY
- + priv->stats.txbkdrop++;
- + break;
- + }
- + }
- + //printk(KERN_INFO "tx_pending: %d > MAX_TX_URB\n", priority);
- + return -1;
- + }
- +
- + urb_len = len + ((NIC_8187 == priv->card_8187)?(4*3):(4*8));
- + if((0 == (urb_len&63))||(0 == (urb_len&511))) {
- + urb_len += 1;
- + }
- +
- + tx = kmalloc(urb_len, GFP_ATOMIC);
- + if(!tx) return -ENOMEM;
- + memset(tx, 0, sizeof(u32) * 8);
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
- +#else
- + tx_urb = usb_alloc_urb(0);
- +#endif
- +
- + if(!tx_urb){
- + kfree(tx);
- + return -ENOMEM;
- + }
- +
- + // Check multicast/broadcast
- + if (ieee->iw_mode == IW_MODE_INFRA) {
- + /* To DS: Addr1 = BSSID, Addr2 = SA,
- + Addr3 = DA */
- + //memcpy(&dest, frag_hdr->addr3, ETH_ALEN);
- + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
- + } else if (ieee->iw_mode == IW_MODE_ADHOC) {
- + /* not From/To DS: Addr1 = DA, Addr2 = SA,
- + Addr3 = BSSID */
- + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
- + }
- +
- + if (is_multicast_ether_addr(dest) ||is_broadcast_ether_addr(dest))
- + {
- + Duration = 0;
- + RtsDur = 0;
- + bRTSEnable = false;
- + bCTSEnable = false;
- +
- + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
- + TxDescDuration = ThisFrameTime;
- + } else {// Unicast packet
- + //u8 AckRate;
- + u16 AckTime;
- +
- + // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
- + //AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) );
- + // Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko.
- + //AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE);
- + //For simplicity, just use the 1M basic rate
- + AckTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
- + //AckTime = ComputeTxTime(14, 2,false, false); // AckCTSLng = 14 use 1M bps send
- +
- + if ( ((len + sCrcLng) > priv->rts) && priv->rts ){ // RTS/CTS.
- + u16 RtsTime, CtsTime;
- + //u16 CtsRate;
- + bRTSEnable = true;
- + bCTSEnable = false;
- +
- + // Rate and time required for RTS.
- + RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, false, false);
- + // Rate and time required for CTS.
- + CtsTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
- +
- + // Figure out time required to transmit this frame.
- + ThisFrameTime = ComputeTxTime(len + sCrcLng,
- + rtl8180_rate2rate(rate),
- + false,
- + bUseShortPreamble);
- +
- + // RTS-CTS-ThisFrame-ACK.
- + RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime;
- +
- + TxDescDuration = RtsTime + RtsDur;
- + }else {// Normal case.
- + bCTSEnable = false;
- + bRTSEnable = false;
- + RtsDur = 0;
- +
- + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
- + TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
- + }
- +
- + if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment
- + // ThisFrame-ACK.
- + Duration = aSifsTime + AckTime;
- + } else { // One or more fragments remained.
- + u16 NextFragTime;
- + NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet
- + rtl8180_rate2rate(rate),
- + false, bUseShortPreamble );
- +
- + //ThisFrag-ACk-NextFrag-ACK.
- + Duration = NextFragTime + 3*aSifsTime + 2*AckTime;
- + }
- +
- + } // End of Unicast packet
- +
- +
- + //fill the tx desriptor
- + tx[0] |= len & 0xfff;
- +#ifdef JOHN_HWSEC
- + if(frag_hdr->frame_ctl & IEEE80211_FCTL_WEP ){
- + tx[0] &= 0xffff7fff;
- + //group key may be different from pairwise key
- + if( frag_hdr->addr1[0]==0xff &&
- + frag_hdr->addr1[0]==0xff &&
- + frag_hdr->addr1[0]==0xff &&
- + frag_hdr->addr1[0]==0xff &&
- + frag_hdr->addr1[0]==0xff &&
- + frag_hdr->addr1[0]==0xff ){
- + if(ieee->broadcast_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//ccmp
- + else tx[7] |= 0x1;//wep and tkip
- + }
- + else {
- + if(ieee->pairwise_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//CCMP
- + else tx[7] |= 0x1;//WEP and TKIP
- + }
- + }
- + else
- +#endif /*JOHN_HWSEC*/
- +
- + tx[0] |= (1<<15);
- +
- + if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE){
- + if (priv->plcp_preamble_mode==1 && rate!=0) { // short mode now, not long!
- + tx[0] |= (1<<16);
- + } // enable short preamble mode.
- + }
- +
- + if(morefrag) tx[0] |= (1<<17);
- + //printk(KERN_WARNING "rtl_rate = %d\n", rate);
- + tx[0] |= (rate << 24); //TX rate
- + frag_hdr->duration_id = Duration;
- +
- + if(NIC_8187B == priv->card_8187) {
- + if(bCTSEnable) {
- + tx[0] |= (1<<18);
- + }
- +
- + if(bRTSEnable) //rts enable
- + {
- + tx[0] |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE
- + tx[0] |= (1<<23);//rts enable
- + tx[1] |= RtsDur;//RTS Duration
- + }
- + tx[3] |= (TxDescDuration<<16); //DURATION
- + if( WLAN_FC_GET_STYPE(le16_to_cpu(frag_hdr->frame_ctl)) == IEEE80211_STYPE_PROBE_RESP )
- + tx[5] |= (1<<8);//(priv->retry_data<<8); //retry lim ;
- + else
- + tx[5] |= (11<<8);//(priv->retry_data<<8); //retry lim ;
- +
- + //frag_hdr->duration_id = Duration;
- + memcpy(tx+8,txbuf,len);
- + } else {
- + if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
- + tx[0] |= (1<<23); //enalbe RTS function
- + tx[1] |= RtsDur; //Need to edit here! ----hikaru
- + }
- + else {
- + tx[1]=0;
- + }
- + tx[0] |= (ieeerate2rtlrate(priv->ieee80211->basic_rate) << 19); /* RTS RATE - should be basic rate */
- +
- + tx[2] = 3; // CW min
- + tx[2] |= (7<<4); //CW max
- + tx[2] |= (11<<8);//(priv->retry_data<<8); //retry lim
- +
- + // printk("%x\n%x\n",tx[0],tx[1]);
- +
- +#ifdef DUMP_TX
- + int i;
- + printk("<Tx pkt>--rate %x---",rate);
- + for (i = 0; i < (len + 3); i++)
- + printk("%2x", ((u8*)tx)[i]);
- + printk("---------------\n");
- +#endif
- + memcpy(tx+3,txbuf,len);
- + }
- +
- +#ifdef JOHN_DUMP_TXDESC
- + int i;
- + printk("<Tx descriptor>--rate %x---",rate);
- + for (i = 0; i < 8; i++)
- + printk("%8x ", tx[i]);
- + printk("\n");
- +#endif
- +#ifdef JOHN_DUMP_TXPKT
- + {
- + int j;
- + printk("\n---------------------------------------------------------------------\n");
- + printk("<Tx packet>--rate %x--urb_len in decimal %d",rate, urb_len);
- + for (j = 32; j < (urb_len); j++){
- + if( ( (j-32)%24 )==0 ) printk("\n");
- + printk("%2x ", ((u8*)tx)[j]);
- + }
- + printk("\n---------------------------------------------------------------------\n");
- +
- + }
- +#endif
- +
- + if(NIC_8187 == priv->card_8187) {
- + usb_fill_bulk_urb(tx_urb,priv->udev,
- + usb_sndbulkpipe(priv->udev,priority), tx,
- + urb_len, (priority == LOW_PRIORITY)?rtl8187_lptx_isr:rtl8187_nptx_isr, dev);
- +
- + } else {
- + //printk(KERN_WARNING "Tx packet use by submit urb!\n");
- + /* FIXME check what EP is for low/norm PRI */
- + usb_fill_bulk_urb(tx_urb,priv->udev,
- + usb_sndbulkpipe(priv->udev,priority), tx,
- + urb_len, TXISR_SELECT(priority), dev);
- + }
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + status = usb_submit_urb(tx_urb, GFP_ATOMIC);
- +#else
- + status = usb_submit_urb(tx_urb);
- +#endif
- +
- + if (!status){
- + //atomic_inc((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
- + atomic_inc(&priv->tx_pending[priority]);
- + dev->trans_start = jiffies;
- + //printk("=====> tx_pending[%d]=%d\n", priority, atomic_read(&priv->tx_pending[priority]));
- + return 0;
- + }else{
- + DMESGE("Error TX URB %d, error pending %d",
- + //atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending),
- + atomic_read(&priv->tx_pending[priority]),
- + status);
- + return -1;
- + }
- +}
- +
- + short rtl8187_usb_initendpoints(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
- +
- + memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
- +
- +#ifdef JACKSON_NEW_RX
- + priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL);
- + if (priv->pp_rxskb == NULL)
- + goto destroy;
- +
- + memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB);
- +#endif
- +#ifdef THOMAS_BEACON
- + {
- + int align;
- + unsigned long oldaddr,newaddr; //lzm mod for 64bit cpu crash 20081107
- + priv->rx_urb[MAX_RX_URB] = usb_alloc_urb(0, GFP_KERNEL);
- + priv->oldaddr = kmalloc(16, GFP_KERNEL);
- + oldaddr = (unsigned long)priv->oldaddr;
- + align = oldaddr&3;
- + if(align != 0 ){
- + newaddr = oldaddr + 4 - align;
- + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16-4+align;
- + }
- + else{
- + newaddr = oldaddr;
- + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16;
- + }
- + priv->rx_urb[MAX_RX_URB]->transfer_buffer = (u32*)newaddr;
- + }
- +#endif
- +
- +
- + goto _middle;
- +
- +
- +destroy:
- +
- +#ifdef JACKSON_NEW_RX
- + if (priv->pp_rxskb) {
- + kfree(priv->pp_rxskb);
- + priv->pp_rxskb = NULL;
- +
- + }
- +#endif
- + if (priv->rx_urb) {
- + kfree(priv->rx_urb);
- + }
- + priv->rx_urb = NULL;
- +
- + DMESGE("Endpoint Alloc Failure");
- + return -ENOMEM;
- +
- +
- +_middle:
- +
- + return 0;
- +
- +}
- +#ifdef THOMAS_BEACON
- +void rtl8187_usb_deleteendpoints(struct net_device *dev)
- +{
- + int i;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if( in_interrupt() )
- + printk(KERN_ALERT " %ld in interrupt \n",in_interrupt() );
- + if(priv->rx_urb){
- + for(i=0;i<(MAX_RX_URB+1);i++){
- + if(priv->rx_urb[i]) {
- + usb_kill_urb(priv->rx_urb[i]);
- + usb_free_urb(priv->rx_urb[i]);
- + }
- + }
- + kfree(priv->rx_urb);
- + priv->rx_urb = NULL;
- + }
- + if(priv->oldaddr){
- + kfree(priv->oldaddr);
- + priv->oldaddr = NULL;
- + }
- + if (priv->pp_rxskb) {
- + kfree(priv->pp_rxskb);
- + priv->pp_rxskb = 0;
- + }
- +}
- +#endif
- +
- +void rtl8187_set_rate(struct net_device *dev)
- +{
- + int i;
- + u16 word;
- + int basic_rate,min_rr_rate,max_rr_rate;
- +
- + //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
- + // priv->ieee80211->state == IEEE80211_LINKED){
- + basic_rate = ieeerate2rtlrate(240);
- + min_rr_rate = ieeerate2rtlrate(60);
- + max_rr_rate = ieeerate2rtlrate(240);
- +
- + /*
- + }else{
- + basic_rate = ieeerate2rtlrate(20);
- + min_rr_rate = ieeerate2rtlrate(10);
- + max_rr_rate = ieeerate2rtlrate(110);
- + }
- + */
- +
- + write_nic_byte(dev, RESP_RATE,
- + max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
- +
- + //word = read_nic_word(dev, BRSR);
- + word = read_nic_word(dev, BRSR_8187);
- + word &= ~BRSR_MBR_8185;
- +
- +
- + for(i=0;i<=basic_rate;i++)
- + word |= (1<<i);
- +
- + //write_nic_word(dev, BRSR, word);
- + write_nic_word(dev, BRSR_8187, word);
- +}
- +
- +
- +void rtl8187_link_change(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //write_nic_word(dev, BintrItv, net->beacon_interval);
- + rtl8187_net_update(dev);
- + /*update timing params*/
- + rtl8180_set_chan(dev, priv->chan);
- + rtl8187_set_rxconf(dev);
- +}
- +
- +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
- +void rtl8180_wmm_param_update(struct work_struct* work)
- +{
- + struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq);
- + struct net_device *dev = ieee->dev;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +#else
- +void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
- +{
- + struct net_device *dev = ieee->dev;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +#endif
- + u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
- + u8 mode = ieee->current_network.mode;
- + AC_CODING eACI;
- + AC_PARAM AcParam;
- + PAC_PARAM pAcParam;
- + u8 i;
- +
- + //8187 need not to update wmm param, added by David, 2006.9.8
- + if(NIC_8187 == priv->card_8187) {
- + return;
- + }
- +
- + if(!ieee->current_network.QoS_Enable)
- + {
- + //legacy ac_xx_param update
- +
- + AcParam.longData = 0;
- + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
- + AcParam.f.AciAifsn.f.ACM = 0;
- + AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin.
- + AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax.
- + AcParam.f.TXOPLimit = 0;
- + for(eACI = 0; eACI < AC_MAX; eACI++)
- + {
- + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
- + {
- + u8 u1bAIFS;
- + u32 u4bAcParam;
- +
- +
- + pAcParam = (PAC_PARAM)(&AcParam);
- + // Retrive paramters to udpate.
- + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
- + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
- + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
- + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
- + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
- +
- + switch(eACI)
- + {
- + case AC1_BK:
- + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
- + break;
- +
- + case AC0_BE:
- + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
- + break;
- +
- + case AC2_VI:
- + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
- + break;
- +
- + case AC3_VO:
- + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
- + break;
- +
- + default:
- + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
- + break;
- + }
- + }
- + }
- +
- + return;
- + }
- + //
- + for(i = 0; i < AC_MAX; i++){
- + pAcParam = (AC_PARAM * )ac_param;
- + {
- + AC_CODING eACI;
- + u8 u1bAIFS;
- + u32 u4bAcParam;
- +
- + // Retrive paramters to udpate.
- + eACI = pAcParam->f.AciAifsn.f.ACI;
- + //Mode G/A: slotTimeTimer = 9; Mode B: 20
- + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
- + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
- + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
- + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
- + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
- +
- + switch(eACI)
- + {
- + case AC1_BK:
- + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
- + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BK_PARAM,read_nic_dword(dev, AC_BK_PARAM));
- + break;
- +
- + case AC0_BE:
- + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
- + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BE_PARAM,read_nic_dword(dev, AC_BE_PARAM));
- + break;
- +
- + case AC2_VI:
- + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
- + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VI_PARAM,read_nic_dword(dev, AC_VI_PARAM));
- + break;
- +
- + case AC3_VO:
- + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
- + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VO_PARAM,read_nic_dword(dev, AC_VO_PARAM));
- + break;
- +
- + default:
- + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
- + break;
- + }
- + }
- + ac_param += (sizeof(AC_PARAM));
- + }
- +}
- +
- +int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate )
- +{
- + u8 rate_len;
- + u8 rate_ex_len;
- + u8 RateMask = 0x7F;
- + u8 idx;
- + unsigned short Found = 0;
- + u8 NaiveTxRate = TxRate&RateMask;
- +
- + rate_len = priv->ieee80211->current_network.rates_len;
- + rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
- +
- + for( idx=0; idx< rate_len; idx++ ){
- + if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate ) {
- + Found = 1;
- + goto found_rate;
- + }
- + }
- +
- + for( idx=0; idx< rate_ex_len; idx++ ) {
- + if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate ) {
- + Found = 1;
- + goto found_rate;
- + }
- + }
- +
- + return Found;
- + found_rate:
- + return Found;
- +}
- +//
- +// Description:
- +// Get the Tx rate one degree up form the input rate in the supported rates.
- +// Return the upgrade rate if it is successed, otherwise return the input rate.
- +// By Bruce, 2007-06-05.
- +//
- +u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 UpRate;
- +
- + // Upgrade 1 degree.
- + switch(rate)
- + {
- + case 108: // Up to 54Mbps.
- + UpRate = 108;
- + break;
- +
- + case 96: // Up to 54Mbps.
- + UpRate = 108;
- + break;
- +
- + case 72: // Up to 48Mbps.
- + UpRate = 96;
- + break;
- +
- + case 48: // Up to 36Mbps.
- + UpRate = 72;
- + break;
- +
- + case 36: // Up to 24Mbps.
- + UpRate = 48;
- + break;
- +
- + case 22: // Up to 18Mbps.
- + UpRate = 36;
- + break;
- +
- + case 11: // Up to 11Mbps.
- + UpRate = 22;
- + break;
- +
- + case 4: // Up to 5.5Mbps.
- + UpRate = 11;
- + break;
- +
- + case 2: // Up to 2Mbps.
- + UpRate = 4;
- + break;
- +
- + default:
- + printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- + return rate;
- + }
- + // Check if the rate is valid.
- + if(IncludedInSupportedRates(priv, UpRate))
- + {
- +// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
- + return UpRate;
- + }
- + else
- + {
- + printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
- + return rate;
- + }
- + return rate;
- +}
- +//
- +// Description:
- +// Get the Tx rate one degree down form the input rate in the supported rates.
- +// Return the degrade rate if it is successed, otherwise return the input rate.
- +// By Bruce, 2007-06-05.
- +//
- +u8 GetDegradeTxRate( struct net_device *dev, u8 rate)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 DownRate;
- +
- + // Upgrade 1 degree.
- + switch(rate)
- + {
- + case 108: // Down to 48Mbps.
- + DownRate = 96;
- + break;
- +
- + case 96: // Down to 36Mbps.
- + DownRate = 72;
- + break;
- +
- + case 72: // Down to 24Mbps.
- + DownRate = 48;
- + break;
- +
- + case 48: // Down to 18Mbps.
- + DownRate = 36;
- + break;
- +
- + case 36: // Down to 11Mbps.
- + DownRate = 22;
- + break;
- +
- + case 22: // Down to 5.5Mbps.
- + DownRate = 11;
- + break;
- +
- + case 11: // Down to 2Mbps.
- + DownRate = 4;
- + break;
- +
- + case 4: // Down to 1Mbps.
- + DownRate = 2;
- + break;
- +
- + case 2: // Down to 1Mbps.
- + DownRate = 2;
- + break;
- +
- + default:
- + printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- + return rate;
- + }
- + // Check if the rate is valid.
- + if(IncludedInSupportedRates(priv, DownRate)){
- +// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
- + return DownRate;
- + }else{
- + printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
- + return rate;
- + }
- + return rate;
- +}
- +
- +//
- +// Helper function to determine if specified data rate is
- +// CCK rate.
- +// 2005.01.25, by rcnjko.
- +//
- +bool MgntIsCckRate(u16 rate )
- +{
- + bool bReturn = false;
- +
- + if((rate <= 22) && (rate != 12) && (rate != 18)){
- + bReturn = true;
- + }
- +
- + return bReturn;
- +}
- +//by amy for rate adaptive
- +//
- +// Description:
- +// Core logic to adjust Tx data rate in STA mode according to
- +// OFDM retry count ratio.
- +//
- +// Note:
- +// RTL8187 : pHalData->CurrRetryCnt = TallyCnt
- +// RTL8187B : pHalData->CurrRetryCnt = PktRetryCnt in TxClosedCommand
- +//
- +void sta_rateadaptive8187B(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + unsigned long CurrTxokCnt;
- + u16 CurrRetryCnt;
- + u16 CurrRetryRate;
- + unsigned long CurrRxokCnt;
- + bool bTryUp = false;
- + bool bTryDown = false;
- + u8 TryUpTh = 1;
- + u8 TryDownTh = 2;
- + u32 TxThroughput;
- + long CurrSignalStrength;
- + bool bUpdateInitialGain = false;
- + CurrRetryCnt = priv->CurrRetryCnt;
- + CurrTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
- + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint)- priv->LastTxokCnt;
- + CurrRxokCnt = priv->stats.rxok - priv->LastRxokCnt;
- + CurrSignalStrength = priv->RecvSignalPower;
- + TxThroughput = (u32)(priv->txokbytestotal - priv->LastTxOKBytes);
- + priv->LastTxOKBytes = priv->txokbytestotal;
- + priv->CurrentOperaRate = priv->ieee80211->rate / 5;
- + //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
- +
- +#if 1
- + //2 Compute retry ratio.
- + if (CurrTxokCnt>0)
- + {
- + CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
- + }
- + else
- + { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
- + CurrRetryRate = (u16)(CurrRetryCnt*100/1);
- + }
- +#endif
- +
- +
- + //printk("\n(1) priv->LastRetryRate: %d \n",priv->LastRetryRate);
- + //printk("(2) CurrRetryCnt = %d \n", CurrRetryCnt);
- + //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
- + //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
- + //printk("(5) SignalStrength = %d \n",priv->RecvSignalPower);
- +
- + priv->LastRetryCnt = priv->CurrRetryCnt;
- + priv->LastTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
- + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint);
- + priv->LastRxokCnt = priv->stats.rxok;
- + priv->CurrRetryCnt = 0;
- + //2No Tx packets, return to init_rate or not?
- + if (CurrRetryRate==0 && CurrTxokCnt == 0)
- + {
- + //
- + // 2007.04.09, by Roger. after 4.5 seconds in this condition, we try to raise rate.
- + //
- + priv->TryupingCountNoData++;
- +
- + //printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
- + //printk("(6) priv->CurrentOperaRate =%d\n", priv->CurrentOperaRate);
- +
- + if (priv->TryupingCountNoData>15)
- + {
- + priv->TryupingCountNoData = 0;
- + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
- + // Reset Fail Record
- + priv->LastFailTxRate = 0;
- + priv->LastFailTxRateSS = -200;
- + priv->FailTxRateCount = 0;
- + }
- + goto SetInitialGain;
- + }
- + else
- + {
- + priv->TryupingCountNoData=0; //Reset trying up times.
- + }
- +
- + //
- + // For Netgear case, I comment out the following signal strength estimation,
- + // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
- + // 2007.04.09, by Roger.
- + //
- +#if 1
- + // If sample is not enough, we use signalstrength.
- + if ( CurrTxokCnt<10|| CurrRetryCnt<10)
- + {
- + //printk("Sample is not enough, we use signalstrength for rate adaptive\n");
- + //After 3 sec, and trying up.
- + priv->TryupingCountNoData++;
- + if (priv->TryupingCountNoData>10)
- + {
- + //printk("Sample is not enough and After 3 sec try up\n");
- + priv->TryupingCountNoData=0;
- +
- + //
- + // Added by Roger, 2007.01.04.
- + // Signal strength plus 3 for air link.
- + //
- +
- + if ( CurrSignalStrength>-68 )//&& IncludedInSupportedRates(Adapter, 108) )
- + {
- + priv->ieee80211->rate = 540;
- + //pMgntInfo->CurrentOperaRate = 108;
- + }
- + else if (CurrSignalStrength>-70)// && IncludedInSupportedRates(Adapter, 96) )
- + {
- + priv->ieee80211->rate = 480;
- + //pMgntInfo->CurrentOperaRate = 96;
- + }
- + else if (CurrSignalStrength>-73)// && IncludedInSupportedRates(Adapter, 72) )
- + {
- + priv->ieee80211->rate = 360;
- + //pMgntInfo->CurrentOperaRate = 72;
- + }
- + else if (CurrSignalStrength>-79)// && IncludedInSupportedRates(Adapter, 48) )
- + {
- + priv->ieee80211->rate = 240;
- + //pMgntInfo->CurrentOperaRate = 48;
- + }
- + else if (CurrSignalStrength>-81)// && IncludedInSupportedRates(Adapter, 36) )
- + {
- + priv->ieee80211->rate = 180;
- + //pMgntInfo->CurrentOperaRate = 36;
- + }
- + else if (CurrSignalStrength>-83)// && IncludedInSupportedRates(Adapter, 22) )
- + {
- + priv->ieee80211->rate = 110;
- + //pMgntInfo->CurrentOperaRate = 22;
- + }
- + else if (CurrSignalStrength>-85)// && IncludedInSupportedRates(Adapter, 11) )
- + {
- + priv->ieee80211->rate = 55;
- + //pMgntInfo->CurrentOperaRate = 11;
- + }
- + else if (CurrSignalStrength>-89)// && IncludedInSupportedRates(Adapter, 4) )
- + {
- + priv->ieee80211->rate = 20;
- + //pMgntInfo->CurrentOperaRate = 4;
- + }
- +
- +
- + }
- +
- + //2004.12.23 skip record for 0
- + //pHalData->LastRetryRate = CurrRetryRate;
- + //printk("pMgntInfo->CurrentOperaRate =%d\n",priv->ieee80211->rate);
- + return;
- + }
- + else
- + {
- + priv->TryupingCountNoData=0;
- + }
- +#endif
- + //
- + // Restructure rate adaptive as the following main stages:
- + // (1) Add retry threshold in 54M upgrading condition with signal strength.
- + // (2) Add the mechanism to degrade to CCK rate according to signal strength
- + // and retry rate.
- + // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
- + // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
- + // (4) Add the mehanism of trying to upgrade tx rate.
- + // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
- + // By Bruce, 2007-06-05.
- + //
- + //
- +
- + // 11Mbps or 36Mbps
- + // Check more times in these rate(key rates).
- + //
- + if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
- + {
- + TryUpTh += 9;
- + }
- + //
- + // Let these rates down more difficult.
- + //
- + if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
- + {
- + TryDownTh += 1;
- + }
- +
- + //1 Adjust Rate.
- + if (priv->bTryuping == true)
- + {
- + //2 For Test Upgrading mechanism
- + // Note:
- + // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
- + // thus the low data rate does not improve the performance.
- + // We randomly upgrade the data rate and check if the retry rate is improved.
- +
- + // Upgrading rate did not improve the retry rate, fallback to the original rate.
- + if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
- + {
- + //Not necessary raising rate, fall back rate.
- + bTryDown = true;
- + //printk("Not necessary raising rate, fall back rate....\n");
- + //printk("(7) priv->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
- + // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
- + }
- + else
- + {
- + priv->bTryuping = false;
- + }
- + }
- + else if (CurrSignalStrength > -51 && (CurrRetryRate < 100))
- + {
- + //2For High Power
- + //
- + // Added by Roger, 2007.04.09.
- + // Return to highest data rate, if signal strength is good enough.
- + // SignalStrength threshold(-50dbm) is for RTL8186.
- + // Revise SignalStrength threshold to -51dbm.
- + //
- + // Also need to check retry rate for safety, by Bruce, 2007-06-05.
- + if(priv->CurrentOperaRate != 108)
- + {
- + bTryUp = true;
- + // Upgrade Tx Rate directly.
- + priv->TryupingCount += TryUpTh;
- + //printk("StaRateAdaptive87B: Power(%d) is high enough!!. \n", CurrSignalStrength);
- + }
- + }
- + // To avoid unstable rate jumping, comment out this condition, by Bruce, 2007-06-26.
- + /*
- + else if(CurrSignalStrength < -86 && CurrRetryRate >= 100)
- + {
- + //2 For Low Power
- + //
- + // Low signal strength and high current tx rate may cause Tx rate to degrade too slowly.
- + // Update Tx rate to CCK rate directly.
- + // By Bruce, 2007-06-05.
- + //
- + if(!MgntIsCckRate(pMgntInfo->CurrentOperaRate))
- + {
- + if(CurrSignalStrength > -88 && IncludedInSupportedRates(Adapter, 22)) // 11M
- + pMgntInfo->CurrentOperaRate = 22;
- + else if(CurrSignalStrength > -90 && IncludedInSupportedRates(Adapter, 11)) // 5.5M
- + pMgntInfo->CurrentOperaRate = 11;
- + else if(CurrSignalStrength > -92 && IncludedInSupportedRates(Adapter, 4)) // 2M
- + pMgntInfo->CurrentOperaRate = 4;
- + else // 1M
- + pMgntInfo->CurrentOperaRate = 2;
- + }
- + else if(CurrRetryRate >= 200)
- + {
- + pMgntInfo->CurrentOperaRate = GetDegradeTxRate(Adapter, pMgntInfo->CurrentOperaRate);
- + }
- + RT_TRACE(COMP_RATE, DBG_LOUD, ("RA: Low Power(%d), or High Retry Rate(%d), set rate to CCK rate (%d). \n",
- + CurrSignalStrength, CurrRetryRate, pMgntInfo->CurrentOperaRate));
- + bUpdateInitialGain = TRUE;
- + // Reset Fail Record
- + pHalData->LastFailTxRate = 0;
- + pHalData->LastFailTxRateSS = -200;
- + pHalData->FailTxRateCount = 0;
- + goto SetInitialGain;
- + }
- + */
- + else if(CurrTxokCnt< 100 && CurrRetryRate >= 600)
- + {
- + //2 For Serious Retry
- + //
- + // Traffic is not busy but our Tx retry is serious.
- + //
- + bTryDown = true;
- + // Let Rate Mechanism to degrade tx rate directly.
- + priv->TryDownCountLowData += TryDownTh;
- + //printk("RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
- + }
- + else if ( priv->CurrentOperaRate == 108 )
- + {
- + //2For 54Mbps
- + // if ( (CurrRetryRate>38)&&(pHalData->LastRetryRate>35))
- + if ( (CurrRetryRate>33)&&(priv->LastRetryRate>32))
- + {
- + //(30,25) for cable link threshold. (38,35) for air link.
- + //Down to rate 48Mbps.
- + bTryDown = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 96 )
- + {
- + //2For 48Mbps
- + // if ( ((CurrRetryRate>73) && (pHalData->LastRetryRate>72)) && IncludedInSupportedRates(Adapter, 72) )
- + if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
- + {
- + //(73, 72) for temp used.
- + //(25, 23) for cable link, (60,59) for air link.
- + //CurrRetryRate plus 25 and 26 respectively for air link.
- + //Down to rate 36Mbps.
- + bTryDown = true;
- + }
- + else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
- + {
- + bTryUp = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 72 )
- + {
- + //2For 36Mbps
- + //if ( (CurrRetryRate>97) && (pHalData->LastRetryRate>97))
- + if ( (CurrRetryRate>55) && (priv->LastRetryRate>54))
- + {
- + //(30,25) for cable link threshold respectively. (103,10) for air link respectively.
- + //CurrRetryRate plus 65 and 69 respectively for air link threshold.
- + //Down to rate 24Mbps.
- + bTryDown = true;
- + }
- + // else if ( (CurrRetryRate<20) && (pHalData->LastRetryRate<20) && IncludedInSupportedRates(Adapter, 96) )//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
- + else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16))//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
- + {
- + bTryUp = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 48 )
- + {
- + //2For 24Mbps
- + // if ( ((CurrRetryRate>119) && (pHalData->LastRetryRate>119) && IncludedInSupportedRates(Adapter, 36)))
- + if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
- + {
- + //(15,15) for cable link threshold respectively. (119, 119) for air link threshold.
- + //Plus 84 for air link threshold.
- + //Down to rate 18Mbps.
- + bTryDown = true;
- + }
- + // else if ( (CurrRetryRate<14) && (pHalData->LastRetryRate<15) && IncludedInSupportedRates(Adapter, 72)) //TO DO: need to consider (RSSI)
- + else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
- + {
- + bTryUp = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 36 )
- + {
- + //2For 18Mbps
- + if ( ((CurrRetryRate>109) && (priv->LastRetryRate>109)))
- + {
- + //(99,99) for cable link, (109,109) for air link.
- + //Down to rate 11Mbps.
- + bTryDown = true;
- + }
- + // else if ( (CurrRetryRate<15) && (pHalData->LastRetryRate<16) && IncludedInSupportedRates(Adapter, 48)) //TO DO: need to consider (RSSI)
- + else if ( (CurrRetryRate<25) && (priv->LastRetryRate<26)) //TO DO: need to consider (RSSI)
- + {
- + bTryUp = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 22 )
- + {
- + //2For 11Mbps
- + // if (CurrRetryRate>299 && IncludedInSupportedRates(Adapter, 11))
- + if (CurrRetryRate>95)
- + {
- + bTryDown = true;
- + }
- + else if (CurrRetryRate<55)//&& (device->LastRetryRate<55) ) //TO DO: need to consider (RSSI)
- + {
- + bTryUp = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 11 )
- + {
- + //2For 5.5Mbps
- + // if (CurrRetryRate>159 && IncludedInSupportedRates(Adapter, 4) )
- + if (CurrRetryRate>149)
- + {
- + bTryDown = true;
- + }
- + // else if ( (CurrRetryRate<30) && (pHalData->LastRetryRate<30) && IncludedInSupportedRates(Adapter, 22) )
- + else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
- + {
- + bTryUp = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 4 )
- + {
- + //2For 2 Mbps
- + if((CurrRetryRate>99) && (priv->LastRetryRate>99))
- + {
- + bTryDown = true;
- + }
- + // else if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 11) )
- + else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
- + {
- + bTryUp = true;
- + }
- + }
- + else if ( priv->CurrentOperaRate == 2 )
- + {
- + //2For 1 Mbps
- + // if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 4))
- + if ( (CurrRetryRate<70) && (priv->LastRetryRate<75))
- + {
- + bTryUp = true;
- + }
- + }
- + if(bTryUp && bTryDown)
- + printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
- +
- + //1 Test Upgrading Tx Rate
- + // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
- + // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
- + if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
- + && priv->CurrentOperaRate != 108 && priv->FailTxRateCount < 2)
- + {
- +#if 1
- + if(jiffies% (CurrRetryRate + 101) == 0)
- + {
- + bTryUp = true;
- + priv->bTryuping = true;
- + printk("======================================================>StaRateAdaptive87B(): Randomly try upgrading...\n");
- + }
- +#endif
- + }
- + //1 Rate Mechanism
- + if(bTryUp)
- + {
- + priv->TryupingCount++;
- + priv->TryDownCountLowData = 0;
- +
- + //
- + // Check more times if we need to upgrade indeed.
- + // Because the largest value of pHalData->TryupingCount is 0xFFFF and
- + // the largest value of pHalData->FailTxRateCount is 0x14,
- + // this condition will be satisfied at most every 2 min.
- + //
- + if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
- + (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
- + {
- + priv->TryupingCount = 0;
- + //
- + // When transfering from CCK to OFDM, DIG is an important issue.
- + //
- + if(priv->CurrentOperaRate == 22)
- + bUpdateInitialGain = true;
- + // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
- + // (2)If the signal strength is increased, it may be able to upgrade.
- + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
- + //printk("StaRateAdaptive87B(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
- +
- + // Update Fail Tx rate and count.
- + if(priv->LastFailTxRate != priv->CurrentOperaRate)
- + {
- + priv->LastFailTxRate = priv->CurrentOperaRate;
- + priv->FailTxRateCount = 0;
- + priv->LastFailTxRateSS = -200; // Set lowest power.
- + }
- + }
- + }
- + else
- + {
- + if(priv->TryupingCount > 0)
- + priv->TryupingCount --;
- + }
- +
- + if(bTryDown)
- + {
- + priv->TryDownCountLowData++;
- + priv->TryupingCount = 0;
- +
- +
- + //Check if Tx rate can be degraded or Test trying upgrading should fallback.
- + if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
- + {
- + priv->TryDownCountLowData = 0;
- + priv->bTryuping = false;
- + // Update fail information.
- + if(priv->LastFailTxRate == priv->CurrentOperaRate)
- + {
- + priv->FailTxRateCount ++;
- + // Record the Tx fail rate signal strength.
- + if(CurrSignalStrength > priv->LastFailTxRateSS)
- + {
- + priv->LastFailTxRateSS = CurrSignalStrength;
- + }
- + }
- + else
- + {
- + priv->LastFailTxRate = priv->CurrentOperaRate;
- + priv->FailTxRateCount = 1;
- + priv->LastFailTxRateSS = CurrSignalStrength;
- + }
- + priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
- + //
- + // When it is CCK rate, it may need to update initial gain to receive lower power packets.
- + //
- + if(MgntIsCckRate(priv->CurrentOperaRate))
- + {
- + bUpdateInitialGain = true;
- + }
- + //printk("StaRateAdaptive87B(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
- + }
- + }
- + else
- + {
- + if(priv->TryDownCountLowData > 0)
- + priv->TryDownCountLowData --;
- + }
- + // Keep the Tx fail rate count to equal to 0x15 at most.
- + // Reduce the fail count at least to 10 sec if tx rate is tending stable.
- + if(priv->FailTxRateCount >= 0x15 ||
- + (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
- + {
- + priv->FailTxRateCount --;
- + }
- +
- + //
- + // We need update initial gain when we set tx rate "from OFDM to CCK" or
- + // "from CCK to OFDM".
- + //
- +SetInitialGain:
- +#if 1 //to be done
- + if(bUpdateInitialGain)
- + {
- + if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
- + {
- + if(priv->InitialGain > priv->RegBModeGainStage)
- + {
- + if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
- + {
- + priv->InitialGain = priv->RegBModeGainStage;
- + }
- + else if(priv->InitialGain > priv->RegBModeGainStage + 1)
- + {
- + priv->InitialGain -= 2;
- + }
- + else
- + {
- + priv->InitialGain --;
- + }
- + UpdateInitialGain(dev);
- + }
- + }
- + else // OFDM
- + {
- + if(priv->InitialGain < 4)
- + {
- + priv->InitialGain ++;
- + UpdateInitialGain(dev);
- + }
- + }
- + }
- +#endif
- + //Record the related info
- + priv->LastRetryRate = CurrRetryRate;
- + priv->LastTxThroughput = TxThroughput;
- + priv->ieee80211->rate = priv->CurrentOperaRate * 5;
- +}
- +
- +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
- +void rtl8180_rate_adapter(struct work_struct * work)
- +{
- + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
- + struct net_device *dev = ieee->dev;
- +#else
- +void rtl8180_rate_adapter(struct net_device *dev)
- +{
- +
- +#endif
- + sta_rateadaptive8187B(dev);
- +}
- +
- +void timer_rate_adaptive(unsigned long data)
- +{
- + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
- + //DMESG("---->timer_rate_adaptive()\n");
- + if(!priv->up)
- + {
- + //DMESG("<----timer_rate_adaptive():driver is not up!\n");
- + return;
- + }
- + if( (priv->ieee80211->mode != IEEE_B) &&
- + (priv->ieee80211->iw_mode != IW_MODE_MASTER)
- + && ((priv->ieee80211->state == IEEE80211_LINKED)||(priv->ieee80211->state == IEEE80211_MESH_LINKED)))
- + {
- + //DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq, 0);
- +#else
- + queue_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq);
- +#endif
- + }
- +
- + mod_timer(&priv->rateadapter_timer, jiffies + MSECS(DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD));
- + //DMESG("<----timer_rate_adaptive()\n");
- +}
- +//by amy for rate adaptive
- +
- +
- +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv);
- +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
- +
- +//YJ,add,080828,for KeepAlive
- +#if 0
- +static void MgntLinkKeepAlive(struct r8180_priv *priv )
- +{
- + if (priv->keepAliveLevel == 0)
- + return;
- +
- + if(priv->ieee80211->state == IEEE80211_LINKED)
- + {
- + //
- + // Keep-Alive.
- + //
- + //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);
- +
- + if ( (priv->keepAliveLevel== 2) ||
- + (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
- + priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast )
- + )
- + {
- + priv->link_detect.IdleCount++;
- +
- + //
- + // Send a Keep-Alive packet packet to AP if we had been idle for a while.
- + //
- + if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) )
- + {
- + priv->link_detect.IdleCount = 0;
- + ieee80211_sta_ps_send_null_frame(priv->ieee80211, false);
- + }
- + }
- + else
- + {
- + priv->link_detect.IdleCount = 0;
- + }
- + priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast;
- + priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
- + }
- +}
- +//YJ,add,080828,for KeepAlive,end
- +#endif
- +void InactivePowerSave(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + //
- + // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
- + // is really scheduled.
- + // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
- + // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
- + // blocks the IPS procedure of switching RF.
- + // By Bruce, 2007-12-25.
- + //
- + priv->bSwRfProcessing = true;
- + MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
- +
- + //
- + // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
- + //
- +#if 0
- + while( index < 4 )
- + {
- + if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
- + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
- + {
- + if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
- + pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
- +
- + }
- + index++;
- + }
- +#endif
- + priv->bSwRfProcessing = false;
- +}
- +
- +//
- +// Description:
- +// Enter the inactive power save mode. RF will be off
- +// 2007.08.17, by shien chang.
- +//
- +void IPSEnter(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + RT_RF_POWER_STATE rtState;
- +
- + if (priv->bInactivePs)
- + {
- + rtState = priv->eRFPowerState;
- +
- + //
- + // Added by Bruce, 2007-12-25.
- + // Do not enter IPS in the following conditions:
- + // (1) RF is already OFF or Sleep
- + // (2) bSwRfProcessing (indicates the IPS is still under going)
- + // (3) Connectted (only disconnected can trigger IPS)
- + // (4) IBSS (send Beacon)
- + // (5) AP mode (send Beacon)
- + //
- + if (rtState == eRfOn && !priv->bSwRfProcessing && (priv->ieee80211->iw_mode != IW_MODE_ADHOC)
- + && (priv->ieee80211->state != IEEE80211_LINKED ))
- + {
- +#ifdef CONFIG_RADIO_DEBUG
- + DMESG("IPSEnter(): Turn off RF.");
- +#endif
- + priv->eInactivePowerState = eRfOff;
- + InactivePowerSave(dev);
- + //SetRFPowerState(dev, priv->eInactivePowerState);
- + //MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
- + }
- + }
- + //printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
- +}
- +
- +void IPSLeave(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + RT_RF_POWER_STATE rtState;
- + if (priv->bInactivePs)
- + {
- + rtState = priv->eRFPowerState;
- + if (rtState == eRfOff && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
- + {
- +#ifdef CONFIG_RADIO_DEBUG
- + DMESG("ISLeave(): Turn on RF.");
- +#endif
- + priv->eInactivePowerState = eRfOn;
- + InactivePowerSave(dev);
- + }
- + }
- +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
- +}
- +//by amy for power save
- +
- +//YJ,add,081230
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void IPSLeave_wq (struct work_struct *work)
- +{
- + struct ieee80211_device *ieee = container_of(work,struct ieee80211_device,ips_leave_wq);
- + struct net_device *dev = ieee->dev;
- +#else
- +void IPSLeave_wq(struct net_device *dev)
- +{
- +#endif
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + down(&priv->ieee80211->ips_sem);
- + IPSLeave(dev);
- + up(&priv->ieee80211->ips_sem);
- +}
- +
- +void ieee80211_ips_leave(struct net_device *dev)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + if(priv->bInactivePs){
- + if(priv->eRFPowerState == eRfOff)
- + {
- + //DMESG("%s", __FUNCTION__);
- + queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
- + }
- + }
- +}
- +//YJ,add,081230,end
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void rtl8180_watch_dog_wq (struct work_struct *work)
- +{
- + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,watch_dog_wq);
- + struct net_device *dev = ieee->dev;
- +#else
- +void rtl8180_watch_dog_wq(struct net_device *dev)
- +{
- +#endif
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //bool bEnterPS = false;
- + //bool bBusyTraffic = false;
- + u32 TotalRxNum = 0;
- + u16 SlotIndex = 0, i=0;
- + //YJ,add,080828,for link state check
- + if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){
- + SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum;
- + priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod;
- + for( i=0; i<priv->link_detect.SlotNum; i++ )
- + TotalRxNum+= priv->link_detect.RxFrameNum[i];
- +#if 0 //for roaming temp del
- + if(TotalRxNum == 0){
- + priv->ieee80211->state = IEEE80211_ASSOCIATING;
- + printk("=========>turn to another AP\n");
- + queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
- + }
- +#endif
- + }
- + priv->link_detect.NumRxOkInPeriod = 0;
- + priv->link_detect.NumTxOkInPeriod = 0;
- + priv->ieee80211->NumRxDataInPeriod = 0;
- + priv->ieee80211->NumRxBcnInPeriod = 0;
- +
- +#ifdef CONFIG_IPS
- + if(priv->ieee80211->actscanning == false){
- + if((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
- + (priv->ieee80211->state == IEEE80211_NOLINK) &&
- + (priv->eRFPowerState == eRfOn))
- + {
- + //printk("actscanning:%d, state:%d, eRFPowerState:%d\n",
- + // priv->ieee80211->actscanning,
- + // priv->ieee80211->state,
- + // priv->eRFPowerState);
- +
- + down(&priv->ieee80211->ips_sem);
- + IPSEnter(dev);
- + up(&priv->ieee80211->ips_sem);
- + }
- + }
- + //queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,IEEE80211_WATCH_DOG_TIME);
- +#endif
- +
- + //printk("========================>leave rtl8180_watch_dog_wq()\n");
- +}
- +
- +void watch_dog_adaptive(unsigned long data)
- +{
- + struct net_device* dev = (struct net_device*)data;
- + struct r8180_priv* priv = ieee80211_priv(dev);
- + //DMESG("---->watch_dog_adaptive()\n");
- + if(!priv->up){
- + //DMESG("<----watch_dog_adaptive():driver is not up!\n");
- + return;
- + }
- + // Tx and Rx High Power Mechanism.
- + if(CheckHighPower(dev)){
- + //printk("===============================> high power!\n");
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq, 0);
- +#else
- + queue_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq);
- +#endif
- + }
- +
- + // Schedule an workitem to perform DIG
- + if(CheckDig(dev) == true){
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq,0);
- +#else
- + queue_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq);
- +#endif
- + }
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,0);
- +#else
- + queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
- +#endif
- +
- + mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
- + //DMESG("<----watch_dog_adaptive()\n");
- +}
- +
- +#ifdef ENABLE_DOT11D
- +
- +CHANNEL_LIST Current_tbl;
- +
- +static CHANNEL_LIST ChannelPlan[] = {
- + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
- + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
- + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
- + {{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.
- + {{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.
- + {{14,36,40,44,48,52,56,60,64},9}, //MKK
- + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
- + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
- + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
- + {{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
- + {{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
- +};
- +
- +static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
- +{
- + int i;
- +
- + //lzm add 081205
- + ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1;
- + ieee->IbssStartChnl=0;
- +
- + switch (channel_plan)
- + {
- + case COUNTRY_CODE_FCC:
- + case COUNTRY_CODE_IC:
- + case COUNTRY_CODE_ETSI:
- + case COUNTRY_CODE_SPAIN:
- + case COUNTRY_CODE_FRANCE:
- + case COUNTRY_CODE_MKK:
- + case COUNTRY_CODE_MKK1:
- + case COUNTRY_CODE_ISRAEL:
- + case COUNTRY_CODE_TELEC:
- + {
- + Dot11d_Init(ieee);
- + ieee->bGlobalDomain = false;
- + ieee->bWorldWide13 = false;
- + if (ChannelPlan[channel_plan].Len != 0){
- + // Clear old channel map
- + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
- + // Set new channel map
- + for (i=0;i<ChannelPlan[channel_plan].Len;i++)
- + {
- + if(ChannelPlan[channel_plan].Channel[i] <= 14)
- + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
- + }
- + }
- + break;
- + }
- + case COUNTRY_CODE_GLOBAL_DOMAIN:
- + {
- + GET_DOT11D_INFO(ieee)->bEnabled = 0;
- + Dot11d_Reset(ieee);
- + ieee->bGlobalDomain = true;
- + ieee->bWorldWide13 = false;
- +
- + //lzm add 081205
- + ieee->MinPassiveChnlNum=12;
- + ieee->IbssStartChnl= 10;
- +
- + break;
- + }
- + case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 081205
- + {
- + Dot11d_Init(ieee);
- + ieee->bGlobalDomain = false;
- + ieee->bWorldWide13 = true;
- +
- + //lzm add 081205
- + ieee->MinPassiveChnlNum=12;
- + ieee->IbssStartChnl= 10;
- +
- + if (ChannelPlan[channel_plan].Len != 0){
- + // Clear old channel map
- + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
- + // Set new channel map
- + for (i=0;i<ChannelPlan[channel_plan].Len;i++)
- + {
- + if(ChannelPlan[channel_plan].Channel[i] <= 11)//ch1~ch11 active scan
- + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
- + else//ch12~13 passive scan
- + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 2;
- + }
- + }
- +
- + break;
- + }
- + default:
- + {
- + Dot11d_Init(ieee);
- + ieee->bGlobalDomain = false;
- + ieee->bWorldWide13 = false;
- + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
- + for (i=1;i<=14;i++)
- + {
- + GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
- + }
- + break;
- + }
- + }
- +}
- +#endif
- +
- +
- +static void rtl8180_link_detect_init(plink_detect_t plink_detect)
- +{
- + memset(plink_detect, 0, sizeof(link_detect_t));
- + plink_detect->SlotNum = DEFAULT_SLOT_NUM;
- +}
- +
- +#ifdef SW_ANTE_DIVERSITY
- +static void rtl8187_antenna_diversity_read(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u16 usValue;
- +
- + //2 Read CustomerID
- + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET>>1);
- + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
- + //DMESG("EEPROM Customer ID: %02X\n", priv->EEPROMCustomerID);
- +
- + //2 Read AntennaDiversity
- + // SW Antenna Diversity.
- + if( (usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE ){
- + priv->EEPROMSwAntennaDiversity = false;
- + DMESG("EEPROM Disable SW Antenna Diversity");
- + }else{
- + priv->EEPROMSwAntennaDiversity = true;
- + DMESG("EEPROM Enable SW Antenna Diversity");
- + }
- + // Default Antenna to use.
- + if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 ) {
- + priv->EEPROMDefaultAntenna1 = false;
- + DMESG("EEPROM Default Main Antenna 0");
- + }else{
- + priv->EEPROMDefaultAntenna1 = false;
- + DMESG( "EEPROM Default Aux Antenna 1");
- + }
- +
- + //
- + // Antenna diversity mechanism. Added by Roger, 2007.11.05.
- + //
- + if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto //set it to 0 when init
- + {// 0: default from EEPROM.
- + priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
- + }else{// 1:disable antenna diversity, 2: enable antenna diversity.
- + priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
- + }
- + //DMESG("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
- +
- +
- + //
- + // Default antenna settings. Added by Roger, 2007.11.05.
- + //
- + if( priv->RegDefaultAntenna == 0)//set it to 0 when init
- + { // 0: default from EEPROM.
- + priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
- + }else{// 1: main, 2: aux.
- + priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
- + }
- + //DMESG("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
- +
- +//by amy for antenna
- +}
- +#endif
- +
- +short rtl8180_init(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int i, j;
- + u16 word;
- + //int ch;
- + //u16 version;
- + u8 hw_version;
- + //u8 config3;
- + struct usb_device *udev;
- + u16 idProduct;
- + u16 bcdDevice;
- + //u8 chan_plan_index;
- +
- + //FIXME: these constants are placed in a bad pleace.
- +
- + //priv->txbuffsize = 1024;
- + //priv->txringcount = 32;
- + //priv->rxbuffersize = 1024;
- + //priv->rxringcount = 32;
- + //priv->txbeaconcount = 3;
- + //priv->rx_skb_complete = 1;
- + //priv->txnp_pending.ispending=0;
- + /* ^^ the SKB does not containt a partial RXed packet (is empty) */
- +
- + //memcpy(priv->stats,0,sizeof(struct Stats));
- +
- + //priv->irq_enabled=0;
- + priv->driver_upping = 0;
- + priv->commit = 0;
- +
- + //priv->stats.rxdmafail=0;
- + priv->stats.txrdu=0;
- + //priv->stats.rxrdu=0;
- + //priv->stats.rxnolast=0;
- + //priv->stats.rxnodata=0;
- + //priv->stats.rxreset=0;
- + //priv->stats.rxwrkaround=0;
- + //priv->stats.rxnopointer=0;
- + priv->stats.txbeerr=0;
- + priv->stats.txbkerr=0;
- + priv->stats.txvierr=0;
- + priv->stats.txvoerr=0;
- + priv->stats.txmanageerr=0;
- + priv->stats.txbeaconerr=0;
- + priv->stats.txresumed=0;
- + //priv->stats.rxerr=0;
- + //priv->stats.rxoverflow=0;
- + //priv->stats.rxint=0;
- + priv->stats.txbeokint=0;
- + priv->stats.txbkokint=0;
- + priv->stats.txviokint=0;
- + priv->stats.txvookint=0;
- + priv->stats.txmanageokint=0;
- + priv->stats.txbeaconokint=0;
- + /*priv->stats.txhpokint=0;
- + priv->stats.txhperr=0;*/
- + priv->stats.rxurberr=0;
- + priv->stats.rxstaterr=0;
- + priv->stats.txoverflow=0;
- + priv->stats.rxok=0;
- + //priv->stats.txbeaconerr=0;
- + //priv->stats.txlperr=0;
- + //priv->stats.txlpokint=0;
- +//john
- + priv->stats.txnpdrop=0;
- + priv->stats.txlpdrop =0;
- + priv->stats.txbedrop =0;
- + priv->stats.txbkdrop =0;
- + priv->stats.txvidrop =0;
- + priv->stats.txvodrop =0;
- + priv->stats.txbeacondrop =0;
- + priv->stats.txmanagedrop =0;
- +
- + // priv->stats.txokbytestotal =0;
- +//by amy
- + priv->LastSignalStrengthInPercent=0;
- + priv->SignalStrength=0;
- + priv->SignalQuality=0;
- + priv->antenna_flag=0;
- + priv->flag_beacon = false;
- +//by amy
- +//david
- + //radion on defaultly
- + priv->radion = 1;
- +//david
- +//by amy for rate adaptive
- + priv->CurrRetryCnt=0;
- + priv->LastRetryCnt=0;
- + priv->LastTxokCnt=0;
- + priv->LastRxokCnt=0;
- + priv->LastRetryRate=0;
- + priv->bTryuping=0;
- + priv->CurrTxRate=0;
- + priv->CurrRetryRate=0;
- + priv->TryupingCount=0;
- + priv->TryupingCountNoData=0;
- + priv->TryDownCountLowData=0;
- + priv->RecvSignalPower=0;
- + priv->LastTxOKBytes=0;
- + priv->LastFailTxRate=0;
- + priv->LastFailTxRateSS=0;
- + priv->FailTxRateCount=0;
- + priv->LastTxThroughput=0;
- + priv->txokbytestotal=0;
- +//by amy for rate adaptive
- +//by amy for ps
- + priv->RFChangeInProgress = false;
- + priv->SetRFPowerStateInProgress = false;
- + priv->RFProgType = 0;
- + priv->bInHctTest = false;
- + priv->bInactivePs = true;//false;
- + priv->ieee80211->bInactivePs = priv->bInactivePs;
- + priv->eInactivePowerState = eRfOn;//lzm add for IPS and Polling methord
- + priv->bSwRfProcessing = false;
- + priv->eRFPowerState = eRfOff;
- + priv->RfOffReason = 0;
- + priv->NumRxOkInPeriod = 0;
- + priv->NumTxOkInPeriod = 0;
- + priv->bLeisurePs = true;
- + priv->dot11PowerSaveMode = eActive;
- + priv->RegThreeWireMode=HW_THREE_WIRE_BY_8051;
- + priv->ps_mode = false;
- +//by amy for ps
- +//by amy for DIG
- + priv->bDigMechanism = 1;
- + priv->bCCKThMechanism = 0;
- + priv->InitialGain = 0;
- + priv->StageCCKTh = 0;
- + priv->RegBModeGainStage = 2;
- +//by amy for DIG
- +// {by david for DIG, 2008.3.6
- + priv->RegDigOfdmFaUpTh = 0x0c;
- + priv->RegBModeGainStage = 0x02;
- + priv->DIG_NumberFallbackVote = 0;
- + priv->DIG_NumberUpgradeVote = 0;
- + priv->CCKUpperTh = 0x100;
- + priv->CCKLowerTh = 0x20;
- +//}
- +//{added by david for High tx power, 2008.3.11
- + priv->bRegHighPowerMechanism = true;
- + priv->bToUpdateTxPwr = false;
- +
- + priv->Z2HiPwrUpperTh = 77;
- + priv->Z2HiPwrLowerTh = 75;
- + priv->Z2RSSIHiPwrUpperTh = 70;
- + priv->Z2RSSIHiPwrLowerTh = 20;
- + //specify for rtl8187B
- + priv->wMacRegRfPinsOutput = 0x0480;
- + priv->wMacRegRfPinsSelect = 0x2488;
- + //
- + // Note that, we just set TrSwState to TR_HW_CONTROLLED here instead of changing
- + // HW setting because we assume it should be inialized as HW controlled. 061010, by rcnjko.
- + //
- + priv->TrSwitchState = TR_HW_CONTROLLED;
- +//}
- + priv->ieee80211->iw_mode = IW_MODE_INFRA;
- +//test pending bug, john 20070815
- + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
- +//by lizhaoming for LED
- +#ifdef LED
- + priv->ieee80211->ieee80211_led_contorl = LedControl8187;
- +#endif
- +#ifdef CONFIG_IPS
- + priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;//IPSLeave;
- +#endif
- +
- +#ifdef SW_ANTE_DIVERSITY
- + priv->antb=0;
- + priv->diversity=1;
- + priv->LastRxPktAntenna = 0;
- + priv->AdMinCheckPeriod = 5;
- + priv->AdMaxCheckPeriod = 10;
- + // Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
- + priv->AdMaxRxSsThreshold = 30;//60->30
- + priv->AdRxSsThreshold = 20;//50->20
- + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- + priv->AdTickCount = 0;
- + priv->AdRxSignalStrength = -1;
- + priv->RegSwAntennaDiversityMechanism = 0;
- + priv->RegDefaultAntenna = 0;
- + priv->SignalStrength = 0;
- + priv->AdRxOkCnt = 0;
- + priv->CurrAntennaIndex = 0;
- + priv->AdRxSsBeforeSwitched = 0;
- + init_timer(&priv->SwAntennaDiversityTimer);
- + priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
- + priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
- +#endif
- +
- + priv->retry_rts = DEFAULT_RETRY_RTS;
- + priv->retry_data = DEFAULT_RETRY_DATA;
- + priv->ieee80211->rate = 110; //11 mbps
- + priv->CurrentOperaRate=priv->ieee80211->rate/5;
- + priv->ieee80211->short_slot = 1;
- + priv->ieee80211->mode = IEEE_G;
- + priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
- +
- + rtl8180_link_detect_init(&priv->link_detect);
- +
- + spin_lock_init(&priv->tx_lock);
- + spin_lock_init(&priv->irq_lock);//added by thomas
- + spin_lock_init(&priv->rf_ps_lock);
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- + INIT_WORK(&priv->reset_wq, (void*)rtl8180_restart);
- + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); //YJ,add,081230,for IPS
- + INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);
- + INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);
- + INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq);
- + INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);
- +
- +#ifdef SW_ANTE_DIVERSITY
- + INIT_DELAYED_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback);
- +#endif
- +
- +#else
- + INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart,dev);
- + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq,dev); //YJ,add,081230,for IPS
- + INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev);
- + INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev);
- + INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq,dev);
- + INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev);
- +
- +#ifdef SW_ANTE_DIVERSITY
- + INIT_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback, dev);
- +#endif
- +
- +#endif
- +#else
- + tq_init(&priv->reset_wq,(void*) rtl8180_restart,dev);
- +#endif
- + sema_init(&priv->wx_sem,1);
- + sema_init(&priv->set_chan_sem,1);
- +#ifdef THOMAS_TASKLET
- + tasklet_init(&priv->irq_rx_tasklet,
- + (void(*)(unsigned long))rtl8180_irq_rx_tasklet_new,
- + (unsigned long)priv);
- +#else
- + tasklet_init(&priv->irq_rx_tasklet,
- + (void(*)(unsigned long))rtl8180_irq_rx_tasklet,
- + (unsigned long)priv);
- +#endif
- +//by amy for rate adaptive
- + init_timer(&priv->rateadapter_timer);
- + priv->rateadapter_timer.data = (unsigned long)dev;
- + priv->rateadapter_timer.function = timer_rate_adaptive;
- +//by amy for rate adaptive
- +//by amy for ps
- + init_timer(&priv->watch_dog_timer);
- + priv->watch_dog_timer.data = (unsigned long)dev;
- + priv->watch_dog_timer.function = watch_dog_adaptive;
- +//by amy
- +//by amy for ps
- + priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
- + priv->ieee80211->iw_mode = IW_MODE_INFRA;
- + priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
- + IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
- +#ifdef CONFIG_SOFT_BEACON
- + IEEE_SOFTMAC_BEACONS | //IEEE_SOFTMAC_SINGLE_QUEUE;
- +#endif
- + IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
- +
- + priv->ieee80211->active_scan = 1;
- + //priv->ieee80211->ch_lock = 0;
- + priv->ieee80211->rate = 110; //11 mbps
- + priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
- + priv->ieee80211->host_encrypt = 1;
- + priv->ieee80211->host_decrypt = 1;
- +#ifdef CONFIG_SOFT_BEACON
- + priv->ieee80211->start_send_beacons = NULL;
- + priv->ieee80211->stop_send_beacons = NULL;
- +#else
- + priv->ieee80211->start_send_beacons = rtl8187_beacon_tx;
- + priv->ieee80211->stop_send_beacons = rtl8187_beacon_stop;
- +#endif
- + priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
- + priv->ieee80211->set_chan = rtl8180_set_chan;
- + priv->ieee80211->link_change = rtl8187_link_change;
- + priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
- + priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
- + priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + priv->ieee80211->meshScanMode = 0;
- + priv->mshobj = alloc_mshobj(priv);
- + if(priv->mshobj)
- + {
- + priv->ieee80211->ext_patch_ieee80211_start_protocol = priv->mshobj->ext_patch_ieee80211_start_protocol;
- + priv->ieee80211->ext_patch_ieee80211_stop_protocol = priv->mshobj->ext_patch_ieee80211_stop_protocol;
- +//by amy for mesh
- + priv->ieee80211->ext_patch_ieee80211_start_mesh = priv->mshobj->ext_patch_ieee80211_start_mesh;
- +//by amy for mesh
- + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = priv->mshobj->ext_patch_ieee80211_probe_req_1;
- + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = priv->mshobj->ext_patch_ieee80211_probe_req_2;
- + priv->ieee80211->ext_patch_ieee80211_association_req_1 = priv->mshobj->ext_patch_ieee80211_association_req_1;
- + priv->ieee80211->ext_patch_ieee80211_association_req_2 = priv->mshobj->ext_patch_ieee80211_association_req_2;
- + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_1;
- + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_2;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_auth;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_deauth;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp;
- + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = priv->mshobj->ext_patch_ieee80211_ext_stop_scan_wq_set_channel;
- + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = priv->mshobj->ext_patch_ieee80211_process_probe_response_1;
- + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = priv->mshobj->ext_patch_ieee80211_rx_mgt_on_probe_req;
- + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = priv->mshobj->ext_patch_ieee80211_rx_mgt_update_expire;
- + priv->ieee80211->ext_patch_get_beacon_get_probersp = priv->mshobj->ext_patch_get_beacon_get_probersp;
- + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = priv->mshobj->ext_patch_ieee80211_rx_on_rx;
- + priv->ieee80211->ext_patch_ieee80211_xmit = priv->mshobj->ext_patch_ieee80211_xmit;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = priv->mshobj->ext_patch_ieee80211_rx_frame_get_hdrlen;
- + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = priv->mshobj->ext_patch_ieee80211_rx_is_valid_framectl;
- + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = priv->mshobj->ext_patch_ieee80211_rx_process_dataframe;
- + // priv->ieee80211->ext_patch_is_duplicate_packet = priv->mshobj->ext_patch_is_duplicate_packet;
- + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = priv->mshobj->ext_patch_ieee80211_softmac_xmit_get_rate;
- + /* added by david for setting acl dynamically */
- + priv->ieee80211->ext_patch_ieee80211_acl_query = priv->mshobj->ext_patch_ieee80211_acl_query;
- + }
- +
- +#endif // _RTL8187_EXT_PATCH_
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
- + (void(*)(void*)) rtl8180_wmm_param_update,\
- + priv->ieee80211);
- +#else
- + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
- + rtl8180_wmm_param_update);
- +#endif
- +#else
- + tq_init(&priv->ieee80211->wmm_param_update_wq,\
- + (void(*)(void*)) rtl8180_wmm_param_update,\
- + priv->ieee80211);
- +#endif
- + priv->ieee80211->init_wmmparam_flag = 0;
- + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
- +
- + //priv->card_8185 = 2;
- + priv->phy_ver = 2;
- + priv->card_type = USB;
- +//{add for 87B
- + priv->ShortRetryLimit = 7;
- + priv->LongRetryLimit = 7;
- + priv->EarlyRxThreshold = 7;
- +
- + priv->TransmitConfig =
- + TCR_DurProcMode | //for RTL8185B, duration setting by HW
- + TCR_DISReqQsize |
- + (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
- + (priv->ShortRetryLimit<<TX_SRLRETRY_SHIFT)| // Short retry limit
- + (priv->LongRetryLimit<<TX_LRLRETRY_SHIFT) | // Long retry limit
- + (false ? TCR_SWPLCPLEN : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
- +
- + priv->ReceiveConfig =
- + RCR_AMF | RCR_ADF | //accept management/data
- + RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
- + RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
- + //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
- + RCR_MXDMA | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
- + (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
- + (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
- +
- + priv->AcmControl = 0;
- +//}
- + priv->rf_chip = 0xff & eprom_read(dev,EPROM_RFCHIPID);
- + //DMESG("rf_chip:%x\n", priv->rf_chip);
- + if (!priv->rf_chip)
- + {
- + DMESG("Can't get rf chip ID from EEPROM");
- + DMESGW("So set rf chip ID to defalut EPROM_RFCHIPID_RTL8225U");
- + DMESGW("use it with care and at your own risk and");
- + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
- + priv->rf_chip = EPROM_RFCHIPID_RTL8225U;
- +
- + }
- +
- +
- +//{put the card to detect different card here, mainly I/O processing
- + udev = priv->udev;
- + idProduct = le16_to_cpu(udev->descriptor.idProduct);
- + //idProduct = 0x8197;
- + bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
- + DMESG("idProduct:0x%x, bcdDevice:0x%x", idProduct,bcdDevice);
- + switch (idProduct) {
- + case 0x8189:
- + case 0x8197:
- + case 0x8198:
- + /* check RF frontend chipset */
- + priv->card_8187 = NIC_8187B;
- + priv->rf_init = rtl8225z2_rf_init;
- + priv->rf_set_chan = rtl8225z2_rf_set_chan;
- + priv->rf_set_sens = NULL;
- + break;
- +
- + case 0x8187:
- + if(bcdDevice == 0x0200){
- + priv->card_8187 = NIC_8187B;
- + priv->rf_init = rtl8225z2_rf_init;
- + priv->rf_set_chan = rtl8225z2_rf_set_chan;
- + priv->rf_set_sens = NULL;
- + break;
- + }else{
- + //0x0100 is for 8187
- + //legacy 8187 NIC
- + //delet
- + ;
- + }
- + default:
- + /* check RF frontend chipset */
- + priv->ieee80211->softmac_features |= IEEE_SOFTMAC_SINGLE_QUEUE;
- + priv->card_8187 = NIC_8187;
- + switch (priv->rf_chip) {
- + case EPROM_RFCHIPID_RTL8225U:
- + DMESG("Card reports RF frontend Realtek 8225");
- + DMESGW("This driver has EXPERIMENTAL support for this chipset.");
- + DMESGW("use it with care and at your own risk and");
- + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
- + if(rtl8225_is_V_z2(dev)){
- + priv->rf_init = rtl8225z2_rf_init;
- + priv->rf_set_chan = rtl8225z2_rf_set_chan;
- + priv->rf_set_sens = NULL;
- + DMESG("This seems a new V2 radio");
- + }else{
- + priv->rf_init = rtl8225_rf_init;
- + priv->rf_set_chan = rtl8225_rf_set_chan;
- + priv->rf_set_sens = rtl8225_rf_set_sens;
- + DMESG("This seems a legacy 1st version radio");
- + }
- + break;
- +
- + case EPROM_RFCHIPID_RTL8225U_VF:
- + priv->rf_init = rtl8225z2_rf_init;
- + priv->rf_set_chan = rtl8225z2_rf_set_chan;
- + priv->rf_set_sens = NULL;
- + DMESG("This seems a new V2 radio");
- + break;
- +
- + default:
- + DMESGW("Unknown RF module %x",priv->rf_chip);
- + DMESGW("Exiting...");
- + return -1;
- + }
- + break;
- + }
- +
- + priv->rf_close = rtl8225_rf_close;
- + priv->max_sens = RTL8225_RF_MAX_SENS;
- + priv->sens = RTL8225_RF_DEF_SENS;
- +
- +#ifdef ENABLE_DOT11D
- +#if 0
- + for(i=0;i<0xFF;i++) {
- + if(i%16 == 0)
- + printk("\n[%x]: ", i/16);
- + printk("\t%4.4x", eprom_read(dev,i));
- + }
- +#endif
- + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xFF;
- + //DMESG("EPROM_CHANNEL_PLAN is %x", priv->channel_plan);
- +
- + // lzm add 081205 for Toshiba:
- + // For Toshiba,reading the value from EEPROM 0x6h bit[7] to determine the priority of
- + // channel plan to be defined.
- + // -If bit[7] is true, then the channel plan is defined by EEPROM but no user defined.
- + // -If bit[7] is false, then the channel plan is defined by user first.
- + //
- + if(priv->channel_plan & 0x80) {
- + DMESG("Toshiba channel plan is defined by EEPROM");
- + priv->channel_plan &= 0xf;
- + }
- + else
- + priv->channel_plan = 0;
- +
- + //if(priv->channel_plan > COUNTRY_CODE_WORLD_WIDE_13_INDEX){
- + if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
- + DMESG("rtl8180_init:Error channel plan! Set to default.\n");
- + priv->channel_plan = 0;
- + }
- +
- + //priv->channel_plan = 9; //Global Domain
- + //priv->channel_plan = 2; //ETSI
- +
- +
- + DMESG("Channel plan is %d ",priv->channel_plan);
- +
- + //for Toshiba card we read channel plan from ChanPlanBin
- + if((idProduct != 0x8197) && (idProduct != 0x8198))
- + rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
- +#else
- + int ch;
- + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xff;
- + if(priv->channel_plan & 0x80) {
- + priv->channel_plan &= 0x7f;
- + if (ChannelPlan[priv->channel_plan].Len != 0){
- + // force channel plan map
- + for (i=0;i<ChannelPlan[priv->channel_plan].Len;i++)
- + priv->ieee80211->channel_map[ChannelPlan[priv->channel_plan].Channel[i]] = 1;
- + } else {
- + DMESG("No channels, aborting");
- + return -1;
- + }
- + } else {
- + //default channel plan setting
- + if(!channels){
- + DMESG("No channels, aborting");
- + return -1;
- + }
- + ch=channels;
- + // set channels 1..14 allowed in given locale
- + for (i=1; i<=14; i++) {
- + (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
- + ch >>= 1;
- + }
- + }
- +#endif
- +
- + if((idProduct == 0x8197) || (idProduct == 0x8198)) {
- + // lzm add 081205 for Toshiba:
- + // 0x77h bit[0]=1: use GPIO bit[2], bit[0]=0: use GPIO bit[1]
- + priv->EEPROMSelectNewGPIO =((u8)((eprom_read(dev,EPROM_SELECT_GPIO) & 0xff00) >> 8)) ? true : false;
- + DMESG("EPROM_SELECT_GPIO:%d", priv->EEPROMSelectNewGPIO);
- + } else {
- + priv->EEPROMSelectNewGPIO = false;
- + }
- +
- +
- + if (NIC_8187 == priv->card_8187){
- + hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
- + switch (hw_version) {
- + case 0x06:
- + //priv->card_8187_Bversion = VERSION_8187B_B;
- + break;
- + case 0x05:
- + priv->card_8187_Bversion = VERSION_8187_D;
- + break;
- + default:
- + priv->card_8187_Bversion = VERSION_8187_B;
- + break;
- + }
- + }else{
- + hw_version = read_nic_byte(dev, 0xe1); //87B hw version reg
- + switch (hw_version){
- + case 0x00:
- + priv->card_8187_Bversion = VERSION_8187B_B;
- + break;
- + case 0x01:
- + priv->card_8187_Bversion = VERSION_8187B_D;
- + break;
- + case 0x02:
- + priv->card_8187_Bversion = VERSION_8187B_E;
- + break;
- + default:
- + priv->card_8187_Bversion = VERSION_8187B_B; //defalt
- + break;
- + }
- + }
- +
- + //printk("=====hw_version:%x\n", priv->card_8187_Bversion);
- + priv->enable_gpio0 = 0;
- +
- + /*the eeprom type is stored in RCR register bit #6 */
- + if (RCR_9356SEL & read_nic_dword(dev, RCR)){
- + priv->epromtype=EPROM_93c56;
- + DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
- + }else{
- + priv->epromtype=EPROM_93c46;
- + DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
- + }
- +
- + dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
- + dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
- + dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
- + dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
- + dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
- + dev->dev_addr[5]=((eprom_read(dev,MAC_ADR+2) & 0xff00)>>8)+1;
- +
- + DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
- +
- + for(i=1,j=0; i<6; i+=2,j++){
- +
- + word = eprom_read(dev,EPROM_TXPW0 + j);
- + priv->chtxpwr[i]=word & 0xf;
- + priv->chtxpwr_ofdm[i]=(word & 0xf0)>>4;
- + priv->chtxpwr[i+1]=(word & 0xf00)>>8;
- + priv->chtxpwr_ofdm[i+1]=(word & 0xf000)>>12;
- + }
- +
- + for(i=1,j=0; i<4; i+=2,j++){
- +
- + word = eprom_read(dev,EPROM_TXPW1 + j);
- + priv->chtxpwr[i+6]=word & 0xf;
- + priv->chtxpwr_ofdm[i+6]=(word & 0xf0)>>4;
- + priv->chtxpwr[i+6+1]=(word & 0xf00)>>8;
- + priv->chtxpwr_ofdm[i+6+1]=(word & 0xf000)>>12;
- + }
- + if (priv->card_8187 == NIC_8187){
- + for(i=1,j=0; i<4; i+=2,j++){
- + word = eprom_read(dev,EPROM_TXPW2 + j);
- + priv->chtxpwr[i+6+4]=word & 0xf;
- + priv->chtxpwr_ofdm[i+6+4]=(word & 0xf0)>>4;
- + priv->chtxpwr[i+6+4+1]=(word & 0xf00)>>8;
- + priv->chtxpwr_ofdm[i+6+4+1]=(word & 0xf000)>>12;
- + }
- + } else{
- + word = eprom_read(dev, 0x1B) & 0xff; //channel 11;
- + priv->chtxpwr[11]=word & 0xf;
- + priv->chtxpwr_ofdm[11] = (word & 0xf0)>>4;
- +
- + word = eprom_read(dev, 0xA) & 0xff; //channel 12;
- + priv->chtxpwr[12]=word & 0xf;
- + priv->chtxpwr_ofdm[12] = (word & 0xf0)>>4;
- +
- + word = eprom_read(dev, 0x1c) ; //channel 13 ,14;
- + priv->chtxpwr[13]=word & 0xf;
- + priv->chtxpwr_ofdm[13] = (word & 0xf0)>>4;
- + priv->chtxpwr[14]=(word & 0xf00)>>8;
- + priv->chtxpwr_ofdm[14] = (word & 0xf000)>>12;
- + }
- +
- + word = eprom_read(dev,EPROM_TXPW_BASE);
- + priv->cck_txpwr_base = word & 0xf;
- + priv->ofdm_txpwr_base = (word>>4) & 0xf;
- +
- + //DMESG("PAPE from CONFIG2: %x",read_nic_byte(dev,CONFIG2)&0x7);
- +
- +#ifdef SW_ANTE_DIVERSITY
- + rtl8187_antenna_diversity_read(dev);
- +#endif
- +
- + if(rtl8187_usb_initendpoints(dev)!=0){
- + DMESG("Endopoints initialization failed");
- + return -ENOMEM;
- + }
- +#ifdef LED
- + InitSwLeds(dev);
- +#endif
- +#ifdef DEBUG_EPROM
- + dump_eprom(dev);
- +#endif
- + return 0;
- +
- +}
- +
- +void rtl8185_rf_pins_enable(struct net_device *dev)
- +{
- +/* u16 tmp;
- + tmp = read_nic_word(dev, RFPinsEnable);*/
- + write_nic_word(dev, RFPinsEnable, 0x1ff7);// | tmp);
- +}
- +
- +
- +void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
- +{
- + u8 conf3;
- +
- + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- +
- + conf3 = read_nic_byte(dev, CONFIG3);
- + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
- +
- + write_nic_dword(dev, ANAPARAM2, a);
- +
- + conf3 = read_nic_byte(dev, CONFIG3);
- + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
- +
- + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
- +
- +}
- +
- +
- +void rtl8180_set_anaparam(struct net_device *dev, u32 a)
- +{
- + u8 conf3;
- +
- + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- +
- + conf3 = read_nic_byte(dev, CONFIG3);
- + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
- +
- + write_nic_dword(dev, ANAPARAM, a);
- +
- + conf3 = read_nic_byte(dev, CONFIG3);
- + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
- +
- + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
- +
- +}
- +
- +
- +void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
- +{
- + write_nic_byte(dev, ANTSEL, ant);
- + //lzm mod for up take too long time 20081201
- + //mdelay(1);
- +}
- +
- +
- +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data)
- +{
- + u32 phyw;
- +
- + adr |= 0x80;
- +
- + phyw= ((data<<8) | adr);
- +
- +
- +
- + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
- + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
- + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
- + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
- + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
- +
- + //read_nic_dword(dev, PHY_ADR);
- +#if 0
- + for(i=0;i<10;i++){
- + write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
- + phyr = read_nic_byte(dev, PHY_READ);
- + if(phyr == (data&0xff)) break;
- +
- + }
- +#endif
- + /* this is ok to fail when we write AGC table. check for AGC table might be
- + * done by masking with 0x7f instead of 0xff */
- + //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data, adr);
- + //msdelay(1);//CPU occupany is too high. LZM 31/10/2008
- +}
- +
- +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data)
- +{
- + u32 phyw;
- +
- + adr &= ~0x80;
- + phyw= ((data<<8) | adr);
- +
- +
- + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
- + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
- + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
- + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
- + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
- +
- + return(read_nic_byte(dev,0x7e));
- +
- +}
- +
- +u8 read_phy_ofdm(struct net_device *dev, u8 adr)
- +{
- + return(rtl8187_read_phy(dev, adr, 0x000000));
- +}
- +
- +u8 read_phy_cck(struct net_device *dev, u8 adr)
- +{
- + return(rtl8187_read_phy(dev, adr, 0x10000));
- +}
- +
- +inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
- +{
- + data = data & 0xff;
- + rtl8187_write_phy(dev, adr, data);
- +}
- +
- +
- +void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
- +{
- + data = data & 0xff;
- + rtl8187_write_phy(dev, adr, data | 0x10000);
- +}
- +//
- +// Description: Change ZEBRA's power state.
- +//
- +// Assumption: This function must be executed in PASSIVE_LEVEL.
- +//
- +// 061214, by rcnjko.
- +//
- +//#define MAX_DOZE_WAITING_TIMES_87B 1000//500
- +#define MAX_DOZE_WAITING_TIMES_87B_MOD 500
- +
- +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 btCR9346, btConfig3;
- + bool bResult = true;
- + int i;
- + u16 u2bTFPC = 0;
- + u8 u1bTmp;
- +
- + // Set EEM0 and EEM1 in 9346CR.
- + btCR9346 = read_nic_byte(dev, CR9346);
- + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
- + // Set PARM_En in Config3.
- + btConfig3 = read_nic_byte(dev, CONFIG3);
- + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
- + // BB and RF related operations:
- + switch(eRFPowerState)
- + {
- + case eRfOn:
- +#ifdef CONFIG_RADIO_DEBUG
- + DMESG("Now Radio ON!");
- +#endif
- + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
- + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
- + //write_nic_byte(dev, CONFIG4, (priv->RFProgType));
- +
- + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
- + write_rtl8225(dev, 0x4, 0x9FF);
- + mdelay(1);
- + //
- + // <Roger_Notes> We reset PLL to reduce power consumption about 30 mA. 2008.01.16.
- + //
- + {
- + u8 Reg62;
- +
- + write_nic_byte(dev, 0x61, 0x10);
- + Reg62 = read_nic_byte(dev, 0x62);
- + write_nic_byte(dev, 0x62, (Reg62 & (~BIT5)) );
- + write_nic_byte(dev, 0x62, (Reg62 | BIT5) ); // Enable PLL.
- + }
- +
- + u1bTmp = read_nic_byte(dev, 0x24E);
- + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
- + break;
- +
- + case eRfSleep:
- +#ifdef CONFIG_RADIO_DEBUG
- + DMESG("Now Radio Sleep!");
- +#endif
- + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
- + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
- + u2bTFPC = read_nic_word(dev, TFPC);
- + if(u2bTFPC == 0){
- + //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
- + break;
- + }else{
- + //printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
- + udelay(10);
- + }
- + }
- +
- + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD ){
- + //printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
- + }
- +
- + u1bTmp = read_nic_byte(dev, 0x24E);
- + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
- +
- + write_rtl8225(dev, 0x4, 0xDFF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
- + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
- +
- + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
- +
- + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
- + write_nic_dword(dev, ANAPARAM2, 0x72303f70); // 070126, by SD1 William.
- + break;
- +
- + case eRfOff:
- +#ifdef CONFIG_RADIO_DEBUG
- + DMESG("Now Radio OFF!");
- +#endif
- + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
- + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
- + u2bTFPC = read_nic_word(dev, TFPC);
- + if(u2bTFPC == 0) {
- + //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
- + break;
- + }else{
- + //printk("%d times TFPC: 0x%x != 0 before doze!\n", (i+1), u2bTFPC);
- + udelay(10);
- + }
- + }
- +
- + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD){
- + //printk("\n\n\nSetZebraRFPowerState8187B(): %d times TFPC: 0x%x != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
- + }
- +
- + u1bTmp = read_nic_byte(dev, 0x24E);
- + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
- +
- + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
- + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
- +
- + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
- +
- + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
- + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
- + break;
- +
- + default:
- + bResult = false;
- + //printk("SetZebraRFPowerState8187B(): unknow state to set: 0x%X!!!\n", eRFPowerState);
- + break;
- + }
- +
- + // Clear PARM_En in Config3.
- + btConfig3 &= ~(CONFIG3_PARM_En);
- + write_nic_byte(dev, CONFIG3, btConfig3);
- + // Clear EEM0 and EEM1 in 9346CR.
- + btCR9346 &= ~(0xC0);
- + write_nic_byte(dev, CR9346, btCR9346);
- +
- + if(bResult){
- + // Update current RF state variable.
- + priv->eRFPowerState = eRFPowerState;
- + }
- +
- + return bResult;
- +}
- +//by amy for ps
- +//
- +// Description: Chang RF Power State.
- +// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
- +//
- +// Assumption:PASSIVE LEVEL.
- +//
- +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + bool bResult = false;
- +
- + //printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
- + if(eRFPowerState == priv->eRFPowerState)
- + {
- + //printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
- + return bResult;
- + }
- +
- + switch(priv->rf_chip)
- + {
- + case RF_ZEBRA2:
- + bResult = SetZebraRFPowerState8187B(dev, eRFPowerState);
- + break;
- +
- + default:
- + printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
- + break;;
- + }
- + //printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
- +
- + return bResult;
- +}
- +
- +bool
- +MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + bool bActionAllowed = false;
- + bool bConnectBySSID = false;
- + RT_RF_POWER_STATE rtState;
- + u16 RFWaitCounter = 0;
- + unsigned long flag;
- + // printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
- + //
- + // Prevent the race condition of RF state change. By Bruce, 2007-11-28.
- + // Only one thread can change the RF state at one time, and others should wait to be executed.
- + //
- +#if 1
- + while(true)
- + {
- + //down(&priv->rf_state);
- + spin_lock_irqsave(&priv->rf_ps_lock,flag);
- + if(priv->RFChangeInProgress)
- + {
- + //up(&priv->rf_state);
- + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
- + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
- + // Set RF after the previous action is done.
- + while(priv->RFChangeInProgress)
- + {
- + RFWaitCounter ++;
- + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
- + udelay(1000); // 1 ms
- +
- + // Wait too long, return FALSE to avoid to be stuck here.
- + if(RFWaitCounter > 1000) // 1sec
- + {
- + // DMESG("MgntActSet_RF_State(): Wait too long to set RF");
- + // TODO: Reset RF state?
- + return false;
- + }
- + }
- + }
- + else
- + {
- + priv->RFChangeInProgress = true;
- +// up(&priv->rf_state);
- + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
- + break;
- + }
- + }
- +#endif
- + rtState = priv->eRFPowerState;
- +
- + switch(StateToSet)
- + {
- + case eRfOn:
- + //
- + // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
- + // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
- + //
- + // leave last reasons and kick this reason till priv->RfOffReason = 0;
- + // if one reason turn radio off check if off->on reason is the same.if so turn, or reject it.
- + // if more than 1 reasons turn radio off we only turn on radio when all reasons turn on radio,
- + // so first turn on trys will reject till priv->RfOffReason = 0;
- + priv->RfOffReason &= (~ChangeSource);
- +
- + if(! priv->RfOffReason)
- + {
- + priv->RfOffReason = 0;
- + bActionAllowed = true;
- +
- + if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest)
- + {
- + bConnectBySSID = true;
- + }
- + } else {
- + ;//lzm must or TX_PENDING 12>MAX_TX_URB
- + //printk("Turn Radio On Reject because RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
- + }
- + break;
- +
- + case eRfOff:
- + // 070125, rcnjko: we always keep connected in AP mode.
- + if (priv->RfOffReason > RF_CHANGE_BY_IPS)
- + {
- + //
- + // 060808, Annie:
- + // Disconnect to current BSS when radio off. Asked by QuanTa.
- + //
- +
- + //
- + // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
- + // because we do NOT need to set ssid to dummy ones.
- + // Revised by Roger, 2007.12.04.
- + //
- +//by amy not supported
- + //MgntDisconnect( dev, disas_lv_ss );
- +
- + // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
- + // 2007.05.28, by shien chang.
- + //PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
- + //pMgntInfo->NumBssDesc = 0;
- + //PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
- + //pMgntInfo->NumBssDesc4Query = 0;
- + }
- +
- +
- +
- + priv->RfOffReason |= ChangeSource;
- + bActionAllowed = true;
- + //printk("Turn Radio Off RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
- + break;
- +
- + case eRfSleep:
- + priv->RfOffReason |= ChangeSource;
- + bActionAllowed = true;
- + break;
- +
- + default:
- + break;
- + }
- +
- + if(bActionAllowed)
- + {
- + // Config HW to the specified mode.
- + //printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
- + SetRFPowerState(dev, StateToSet);
- + // Turn on RF.
- + if(StateToSet == eRfOn)
- + {
- + //HalEnableRx8185Dummy(dev);
- + if(bConnectBySSID)
- + {
- + // by amy not supported
- + //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
- + }
- + }
- + // Turn off RF.
- + else if(StateToSet == eRfOff)
- + {
- + //HalDisableRx8185Dummy(dev);
- + }
- + }
- + else
- + {
- + //printk("Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n",
- + // StateToSet, ChangeSource, priv->RfOffReason);
- + }
- +
- + // Release RF spinlock
- + //down(&priv->rf_state);
- + spin_lock_irqsave(&priv->rf_ps_lock,flag);
- + priv->RFChangeInProgress = false;
- + //up(&priv->rf_state);
- + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
- + return bActionAllowed;
- +}
- +//by amy for ps
- +
- +void rtl8180_adapter_start(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +// struct ieee80211_device *ieee = priv->ieee80211;
- +// u8 InitWirelessMode;
- +// u8 SupportedWirelessMode;
- +// bool bInvalidWirelessMode = false;
- +
- +
- + if(NIC_8187 == priv->card_8187) {
- + //rtl8180_rtx_disable(dev);
- + rtl8180_reset(dev);
- +
- + write_nic_byte(dev,0x85,0);
- + write_nic_byte(dev,0x91,0);
- +
- + /* light blink! */
- + write_nic_byte(dev,0x85,4);
- + write_nic_byte(dev,0x91,1);
- + write_nic_byte(dev,0x90,0);
- +
- + //by lizhaoming for LED POWR ON
- + //LedControl8187(dev, LED_CTL_POWER_ON);
- +
- + /*
- + write_nic_byte(dev, CR9346, 0xC0);
- + //LED TYPE
- + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
- + write_nic_byte(dev, CR9346, 0x0); // disable config register write
- + */
- + priv->irq_mask = 0xffff;
- + /*
- + priv->dma_poll_mask = 0;
- + priv->dma_poll_mask|= (1<<TX_DMA_STOP_BEACON_SHIFT);
- + */
- + // rtl8180_beacon_tx_disable(dev);
- +
- + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
- + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
- +
- + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
- + rtl8180_update_msr(dev);
- +
- + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- +
- + write_nic_word(dev,0xf4,0xffff);
- + write_nic_byte(dev,
- + CONFIG1, (read_nic_byte(dev,CONFIG1) & 0x3f) | 0x80);
- +
- + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- +
- + write_nic_dword(dev,INT_TIMEOUT,0);
- +
- +#ifdef DEBUG_REGISTERS
- + rtl8180_dump_reg(dev);
- +#endif
- +
- +
- + write_nic_byte(dev, WPA_CONFIG, 0);
- +
- + write_nic_byte(dev, RATE_FALLBACK, 0x81);
- + rtl8187_set_rate(dev);
- +
- + priv->rf_init(dev);
- +
- + if(priv->rf_set_sens != NULL) {
- + priv->rf_set_sens(dev,priv->sens);
- + }
- +
- + write_nic_word(dev,0x5e,1);
- + //mdelay(1);
- + write_nic_word(dev,0xfe,0x10);
- + // mdelay(1);
- + write_nic_byte(dev, TALLY_SEL, 0x80);//Set NQ retry count
- + write_nic_byte(dev, 0xff, 0x60);
- + write_nic_word(dev,0x5e,0);
- +
- + rtl8180_irq_enable(dev);
- + } else {
- + /**
- + * IO part migrated from Windows Driver.
- + */
- + priv->irq_mask = 0xffff;
- + // Enable Config3.PARAM_En.
- + write_nic_byte(dev, CR9346, 0xC0);
- +
- + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)| CONFIG3_PARM_En|CONFIG3_GNTSel));
- + // Turn on Analog power.
- + // setup A/D D/A parameter for 8185 b2
- + // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
- + write_nic_dword(dev, ANA_PARAM2, ANAPARM2_ASIC_ON);
- + write_nic_dword(dev, ANA_PARAM, ANAPARM_ASIC_ON);
- + write_nic_byte(dev, ANA_PARAM3, 0x00);
- +
- + //by lizhaoming for LED POWR ON
- + //LedControl8187(dev, LED_CTL_POWER_ON);
- +
- + {//added for reset PLL
- + u8 bReg62;
- + write_nic_byte(dev, 0x61, 0x10);
- + bReg62 = read_nic_byte(dev, 0x62);
- + write_nic_byte(dev, 0x62, bReg62&(~(0x1<<5)));
- + write_nic_byte(dev, 0x62, bReg62|(0x1<<5));
- + }
- + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
- + write_nic_byte(dev, CR9346, 0x00);
- +
- + //rtl8180_rtx_disable(dev);
- + rtl8180_reset(dev);
- + write_nic_byte(dev, CR9346, 0xc0); // enable config register write
- + priv->rf_init(dev);
- + // Enable tx/rx
- +
- + write_nic_byte(dev, CMD, (CR_RE|CR_TE));// Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
- +
- + //add this is for 8187B Rx stall problem
- +
- + rtl8180_irq_enable(dev);
- +
- + write_nic_byte_E(dev, 0x41, 0xF4);
- + write_nic_byte_E(dev, 0x40, 0x00);
- + write_nic_byte_E(dev, 0x42, 0x00);
- + write_nic_byte_E(dev, 0x42, 0x01);
- + write_nic_byte_E(dev, 0x40, 0x0F);
- + write_nic_byte_E(dev, 0x42, 0x00);
- + write_nic_byte_E(dev, 0x42, 0x01);
- +
- + // 8187B demo board MAC and AFE power saving parameters from SD1 William, 2006.07.20.
- + // Parameter revised by SD1 William, 2006.08.21:
- + // 373h -> 0x4F // Original: 0x0F
- + // 377h -> 0x59 // Original: 0x4F
- + // Victor 2006/8/21: 竅�繒q簞�翹�竄��糧繕瞼SD3 簞穠禮C繚� and cable link test OK瞻~瞼聶礎癒 release,瞻瞿竄��糧瞻�禮�
- + // 2006/9/5, Victor & ED: it is OK to use.
- + //if(pHalData->RegBoardType == BT_DEMO_BOARD)
- + //{
- + // AFE.
- + //
- + // Revise the content of Reg0x372, 0x374, 0x378 and 0x37a to fix unusual electronic current
- + // while CTS-To-Self occurs, by DZ's request.
- + // Modified by Roger, 2007.06.22.
- + //
- + write_nic_byte(dev, 0x0DB, (read_nic_byte(dev, 0x0DB)|(BIT2)));
- + write_nic_word(dev, 0x372, 0x59FA); // 0x4FFA-> 0x59FA.
- + write_nic_word(dev, 0x374, 0x59D2); // 0x4FD2-> 0x59D2.
- + write_nic_word(dev, 0x376, 0x59D2);
- + write_nic_word(dev, 0x378, 0x19FA); // 0x0FFA-> 0x19FA.
- + write_nic_word(dev, 0x37A, 0x19FA); // 0x0FFA-> 0x19FA.
- + write_nic_word(dev, 0x37C, 0x00D0);
- +
- + write_nic_byte(dev, 0x061, 0x00);
- +
- + // MAC.
- + write_nic_byte(dev, 0x180, 0x0F);
- + write_nic_byte(dev, 0x183, 0x03);
- + // 061218, lanhsin: for victorh request
- + write_nic_byte(dev, 0x0DA, 0x10);
- + //}
- +
- + //
- + // 061213, rcnjko:
- + // Set MAC.0x24D to 0x00 to prevent cts-to-self Tx/Rx stall symptom.
- + // If we set MAC 0x24D to 0x08, OFDM and CCK will turn off
- + // if not in use, and there is a bug about this action when
- + // we try to send CCK CTS and OFDM data together.
- + //
- + //PlatformEFIOWrite1Byte(Adapter, 0x24D, 0x00);
- + // 061218, lanhsin: for victorh request
- + write_nic_byte(dev, 0x24D, 0x08);
- +
- + //
- + // 061215, rcnjko:
- + // Follow SD3 RTL8185B_87B_MacPhy_Register.doc v0.4.
- + //
- + write_nic_dword(dev, HSSI_PARA, 0x0600321B);
- + //
- + // 061226, rcnjko:
- + // Babble found in HCT 2c_simultaneous test, server with 87B might
- + // receive a packet size about 2xxx bytes.
- + // So, we restrict RMS to 2048 (0x800), while as IC default value is 0xC00.
- + //
- + write_nic_word(dev, RMS, 0x0800);
- +
- + /*****20070321 Resolve HW page bug on system logo test
- + u8 faketemp=read_nic_byte(dev, 0x50);*/
- + }
- +}
- +
- +/* this configures registers for beacon tx and enables it via
- + * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
- + * be used to stop beacon transmission
- + */
- +#if 0
- +void rtl8180_start_tx_beacon(struct net_device *dev)
- +{
- + int i;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + u16 word;
- + DMESG("Enabling beacon TX");
- + //write_nic_byte(dev, 0x42,0xe6);// TCR
- + //rtl8180_init_beacon(dev);
- + //set_nic_txring(dev);
- +// rtl8180_prepare_beacon(dev);
- + rtl8180_irq_disable(dev);
- +// rtl8180_beacon_tx_enable(dev);
- + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + //write_nic_byte(dev,0x9d,0x20); //DMA Poll
- + //write_nic_word(dev,0x7a,0);
- + //write_nic_word(dev,0x7a,0x8000);
- +
- +
- + word = read_nic_word(dev, BcnItv);
- + word &= ~BcnItv_BcnItv; // clear Bcn_Itv
- + write_nic_word(dev, BcnItv, word);
- +
- + write_nic_word(dev, AtimWnd,
- + read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
- +
- + word = read_nic_word(dev, BintrItv);
- + word &= ~BintrItv_BintrItv;
- +
- + //word |= priv->ieee80211->beacon_interval *
- + // ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
- + // FIXME:FIXME check if correct ^^ worked with 0x3e8;
- +
- + write_nic_word(dev, BintrItv, word);
- +
- + //write_nic_word(dev,0x2e,0xe002);
- + //write_nic_dword(dev,0x30,0xb8c7832e);
- + for(i=0; i<ETH_ALEN; i++)
- + write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
- +
- +// rtl8180_update_msr(dev);
- +
- +
- + //write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
- +
- + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
- +
- + rtl8180_irq_enable(dev);
- +
- + /* VV !!!!!!!!!! VV*/
- + /*
- + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
- + write_nic_byte(dev,0x9d,0x00);
- + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
- +*/
- +}
- +#endif
- +/***************************************************************************
- + -------------------------------NET STUFF---------------------------
- +***************************************************************************/
- +static struct net_device_stats *rtl8180_stats(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + return &priv->ieee80211->stats;
- +}
- +
- +int _rtl8180_up(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //int i;
- +
- + priv->driver_upping = 1;
- + priv->up=1;
- +
- +#ifdef LED
- + if(priv->ieee80211->bHwRadioOff == false)
- + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_ON);
- +#endif
- + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_SW);
- +
- + rtl8180_adapter_start(dev);
- + rtl8180_rx_enable(dev);
- + rtl8180_tx_enable(dev);
- +//by amy for rate adaptive
- + timer_rate_adaptive((unsigned long)dev);
- +//by amy for rate adaptive
- +
- +#ifdef SW_ANTE_DIVERSITY
- + if(priv->bSwAntennaDiverity){
- + //DMESG("SW Antenna Diversity Enable!");
- + SwAntennaDiversityTimerCallback(dev);
- + }
- +#endif
- +
- + ieee80211_softmac_start_protocol(priv->ieee80211);
- +
- +//by amy for ps
- + watch_dog_adaptive((unsigned long)dev);
- +//by amy for ps
- +
- + ieee80211_reset_queue(priv->ieee80211);
- + if(!netif_queue_stopped(dev))
- + netif_start_queue(dev);
- + else
- + netif_wake_queue(dev);
- +
- +#ifndef CONFIG_SOFT_BEACON
- + if(NIC_8187B == priv->card_8187)
- + rtl8187_rx_manage_initiate(dev);
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(priv->mshobj && priv->mshobj->ext_patch_rtl8180_up )
- + priv->mshobj->ext_patch_rtl8180_up(priv->mshobj);
- +#endif
- +
- +
- + priv->driver_upping = 0;
- + //DMESG("rtl8187_open process complete");
- + return 0;
- +}
- +
- +
- +int rtl8180_open(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int ret;
- +//changed by lizhaoming for power on/off
- + if(priv->ieee80211->bHwRadioOff == false){
- + //DMESG("rtl8187_open process ");
- + down(&priv->wx_sem);
- + ret = rtl8180_up(dev);
- + up(&priv->wx_sem);
- + return ret;
- + }else{
- + DMESG("rtl8187_open process failed because radio off");
- + return -1;
- + }
- +
- +}
- +
- +
- +int rtl8180_up(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if (priv->up == 1) return -1;
- +
- + return _rtl8180_up(dev);
- +}
- +
- +
- +int rtl8180_close(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int ret;
- +
- + if (priv->up == 0) return -1;
- +
- + down(&priv->wx_sem);
- +
- + //DMESG("rtl8187_close process");
- + ret = rtl8180_down(dev);
- +#ifdef LED
- + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_OFF);
- +#endif
- + up(&priv->wx_sem);
- +
- + return ret;
- +
- +}
- +
- +int rtl8180_down(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if (priv->up == 0) return -1;
- +
- + priv->up=0;
- +
- +/* FIXME */
- + if (!netif_queue_stopped(dev))
- + netif_stop_queue(dev);
- +
- + //DMESG("rtl8180_down process");
- + rtl8180_rtx_disable(dev);
- + rtl8180_irq_disable(dev);
- +//by amy for rate adaptive
- + del_timer_sync(&priv->rateadapter_timer);
- + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- +//by amy for rate adaptive
- + del_timer_sync(&priv->watch_dog_timer);
- + cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
- + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
- + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
- +
- +#ifdef SW_ANTE_DIVERSITY
- + del_timer_sync(&priv->SwAntennaDiversityTimer);
- + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
- +#endif
- +
- + ieee80211_softmac_stop_protocol(priv->ieee80211);
- + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
- + //amy,081212
- + memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network));
- + return 0;
- +}
- +
- +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
- +
- +void rtl8180_commit(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + int i;
- +
- + if (priv->up == 0) return ;
- + printk("==========>%s()\n", __FUNCTION__);
- +
- + /* FIXME */
- + if (!netif_queue_stopped(dev))
- + netif_stop_queue(dev);
- +
- +//by amy for rate adaptive
- + del_timer_sync(&priv->rateadapter_timer);
- + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- +//by amy for rate adaptive
- + del_timer_sync(&priv->watch_dog_timer);
- + cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
- + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
- + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
- +
- +#ifdef SW_ANTE_DIVERSITY
- + del_timer_sync(&priv->SwAntennaDiversityTimer);
- + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
- +#endif
- + ieee80211_softmac_stop_protocol(priv->ieee80211);
- +
- +#if 0
- + if(priv->ieee80211->bHwRadioOff == false){
- + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_HW);
- + mdelay(10);
- + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_HW);
- + }
- +#endif
- +
- + rtl8180_irq_disable(dev);
- + rtl8180_rtx_disable(dev);
- +
- + //test pending bug, john 20070815
- + //initialize tx_pending
- + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
- +
- + _rtl8180_up(dev);
- + priv->commit = 0;
- +}
- +
- +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- +void rtl8180_restart(struct work_struct *work)
- +{
- + struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
- + struct ieee80211_device* ieee = priv->ieee80211;//for commit crash
- + struct net_device *dev = ieee->dev;//for commit crash
- +#else
- +void rtl8180_restart(struct net_device *dev)
- +{
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +#endif
- +
- + down(&priv->wx_sem);
- +
- + rtl8180_commit(dev);
- +
- + up(&priv->wx_sem);
- +}
- +
- +static void r8180_set_multicast(struct net_device *dev)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + short promisc;
- +
- + //down(&priv->wx_sem);
- +
- + /* FIXME FIXME */
- +
- + promisc = (dev->flags & IFF_PROMISC) ? 1:0;
- +
- + if (promisc != priv->promisc)
- + // rtl8180_commit(dev);
- +
- + priv->promisc = promisc;
- +
- + //schedule_work(&priv->reset_wq);
- + //up(&priv->wx_sem);
- +}
- +
- +
- +int r8180_set_mac_adr(struct net_device *dev, void *mac)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + struct sockaddr *addr = mac;
- +
- + down(&priv->wx_sem);
- +
- + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
- +
- +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
- + schedule_work(&priv->reset_wq);
- +#else
- + schedule_task(&priv->reset_wq);
- +#endif
- + up(&priv->wx_sem);
- +
- + return 0;
- +}
- +
- +struct ipw_param {
- + u32 cmd;
- + u8 sta_addr[ETH_ALEN];
- + union {
- + struct {
- + u8 name;
- + u32 value;
- + } wpa_param;
- + struct {
- + u32 len;
- + u8 reserved[32];
- + u8 data[0];
- + } wpa_ie;
- + struct{
- + u32 command;
- + u32 reason_code;
- + } mlme;
- + struct {
- + u8 alg[16];
- + u8 set_tx;
- + u32 err;
- + u8 idx;
- + u8 seq[8];
- + u16 key_len;
- + u8 key[0];
- + } crypt;
- +
- + } u;
- +};
- +
- +
- +/* based on ipw2200 driver */
- +int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + struct iwreq *wrq = (struct iwreq *)rq;
- + int ret=-1;
- +
- +#ifdef JOHN_TKIP
- + u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
- +
- + struct ieee80211_device *ieee = priv->ieee80211;
- + struct ipw_param *ipw = (struct ipw_param *)wrq->u.data.pointer;
- + u32 key[4];
- +
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(priv->mshobj && (priv->ieee80211->iw_mode == priv->ieee80211->iw_ext_mode) && priv->mshobj->ext_patch_rtl8180_ioctl)
- + {
- + // DO NOT put the belowing function in critical section, due to it uses "spin lock"
- + if((ret = priv->mshobj->ext_patch_rtl8180_ioctl(dev, rq, cmd)) != -EOPNOTSUPP)
- + return ret;
- + }
- +#endif
- +
- + down(&priv->wx_sem);
- +
- + switch (cmd) {
- + case RTL_IOCTL_WPA_SUPPLICANT:
- +#ifdef JOHN_TKIP
- +
- +//the following code is specified for ipw driver in wpa_supplicant
- + if( ((u32*)wrq->u.data.pointer)[0]==3 ){
- +
- +
- + if( ((u32*)wrq->u.data.pointer)[7] &&
- + ( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ||
- + ((u32*)wrq->u.data.pointer)[3]==0x50494b54 )) {//50494b54 tkip and 504d4343 ccmp
- +
- + //enable HW security of TKIP and CCMP
- + write_nic_byte(dev, WPA_CONFIG, SCR_TxSecEnable | SCR_RxSecEnable );
- +
- + //copy key from wpa_supplicant ioctl info
- + key[0] = ((u32*)wrq->u.data.pointer)[12];
- + key[1] = ((u32*)wrq->u.data.pointer)[13];
- + key[2] = ((u32*)wrq->u.data.pointer)[14];
- + key[3] = ((u32*)wrq->u.data.pointer)[15];
- + switch (ieee->pairwise_key_type){
- + case KEY_TYPE_TKIP:
- + setKey( dev,
- + 0, //EntryNo
- + ipw->u.crypt.idx, //KeyIndex
- + KEY_TYPE_TKIP, //KeyType
- + (u8*)ieee->ap_mac_addr, //MacAddr
- + 0, //DefaultKey
- + key); //KeyContent
- + break;
- +
- + case KEY_TYPE_CCMP:
- + setKey( dev,
- + 0, //EntryNo
- + ipw->u.crypt.idx, //KeyIndex
- + KEY_TYPE_CCMP, //KeyType
- + (u8*)ieee->ap_mac_addr, //MacAddr
- + 0, //DefaultKey
- + key); //KeyContent
- + break
- +;
- + default:
- + printk("error on key_type: %d\n", ieee->pairwise_key_type);
- + break;
- + }
- + }
- +
- + //group key for broadcast
- + if( ((u32*)wrq->u.data.pointer)[9] ) {
- +
- + key[0] = ((u32*)wrq->u.data.pointer)[12];
- + key[1] = ((u32*)wrq->u.data.pointer)[13];
- + key[2] = ((u32*)wrq->u.data.pointer)[14];
- + key[3] = ((u32*)wrq->u.data.pointer)[15];
- +
- + if( ((u32*)wrq->u.data.pointer)[3]==0x50494b54 ){//50494b54 is the ASCII code of TKIP in reversed order
- + setKey( dev,
- + 1, //EntryNo
- + ipw->u.crypt.idx,//KeyIndex
- + KEY_TYPE_TKIP, //KeyType
- + broadcast_addr, //MacAddr
- + 0, //DefaultKey
- + key); //KeyContent
- + }
- + else if( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ){//CCMP
- + setKey( dev,
- + 1, //EntryNo
- + ipw->u.crypt.idx,//KeyIndex
- + KEY_TYPE_CCMP, //KeyType
- + broadcast_addr, //MacAddr
- + 0, //DefaultKey
- + key); //KeyContent
- + }
- + else if( ((u32*)wrq->u.data.pointer)[3]==0x656e6f6e ){//none
- + //do nothing
- + }
- + else if( ((u32*)wrq->u.data.pointer)[3]==0x504557 ){//WEP
- + setKey( dev,
- + 1, //EntryNo
- + ipw->u.crypt.idx,//KeyIndex
- + KEY_TYPE_WEP40, //KeyType
- + broadcast_addr, //MacAddr
- + 0, //DefaultKey
- + key); //KeyContent
- + }
- + else printk("undefine group key type: %8x\n", ((u32*)wrq->u.data.pointer)[3]);
- + }
- +
- + }
- +#endif /*JOHN_TKIP*/
- +
- +
- +#ifdef JOHN_HWSEC_DEBUG
- + {
- + int i;
- + //john's test 0711
- + printk("@@ wrq->u pointer = ");
- + for(i=0;i<wrq->u.data.length;i++){
- + if(i%10==0) printk("\n");
- + printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
- + }
- + printk("\n");
- + }
- +#endif /*JOHN_HWSEC_DEBUG*/
- + ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
- + break;
- +
- + default:
- + ret = -EOPNOTSUPP;
- + break;
- + }
- +
- + up(&priv->wx_sem);
- +
- + return ret;
- +}
- +
- +
- +struct tx_desc {
- +
- +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
- +
- +
- +//dword 0
- +unsigned int tpktsize:12;
- +unsigned int rsvd0:3;
- +unsigned int no_encrypt:1;
- +unsigned int splcp:1;
- +unsigned int morefrag:1;
- +unsigned int ctsen:1;
- +unsigned int rtsrate:4;
- +unsigned int rtsen:1;
- +unsigned int txrate:4;
- +unsigned int last:1;
- +unsigned int first:1;
- +unsigned int dmaok:1;
- +unsigned int own:1;
- +
- +//dword 1
- +unsigned short rtsdur;
- +unsigned short length:15;
- +unsigned short l_ext:1;
- +
- +//dword 2
- +unsigned int bufaddr;
- +
- +
- +//dword 3
- +unsigned short rxlen:12;
- +unsigned short rsvd1:3;
- +unsigned short miccal:1;
- +unsigned short dur;
- +
- +//dword 4
- +unsigned int nextdescaddr;
- +
- +//dword 5
- +unsigned char rtsagc;
- +unsigned char retrylimit;
- +unsigned short rtdb:1;
- +unsigned short noacm:1;
- +unsigned short pifs:1;
- +unsigned short rsvd2:4;
- +unsigned short rtsratefallback:4;
- +unsigned short ratefallback:5;
- +
- +//dword 6
- +unsigned short delaybound;
- +unsigned short rsvd3:4;
- +unsigned short agc:8;
- +unsigned short antenna:1;
- +unsigned short spc:2;
- +unsigned short rsvd4:1;
- +
- +//dword 7
- +unsigned char len_adjust:2;
- +unsigned char rsvd5:1;
- +unsigned char tpcdesen:1;
- +unsigned char tpcpolarity:2;
- +unsigned char tpcen:1;
- +unsigned char pten:1;
- +
- +unsigned char bckey:6;
- +unsigned char enbckey:1;
- +unsigned char enpmpd:1;
- +unsigned short fragqsz;
- +
- +
- +#else
- +
- +#error "please modify tx_desc to your own\n"
- +
- +#endif
- +
- +
- +} __attribute__((packed));
- +
- +struct rx_desc_rtl8187b {
- +
- +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
- +
- +//dword 0
- +unsigned int rxlen:12;
- +unsigned int icv:1;
- +unsigned int crc32:1;
- +unsigned int pwrmgt:1;
- +unsigned int res:1;
- +unsigned int bar:1;
- +unsigned int pam:1;
- +unsigned int mar:1;
- +unsigned int qos:1;
- +unsigned int rxrate:4;
- +unsigned int trsw:1;
- +unsigned int splcp:1;
- +unsigned int fovf:1;
- +unsigned int dmafail:1;
- +unsigned int last:1;
- +unsigned int first:1;
- +unsigned int eor:1;
- +unsigned int own:1;
- +
- +
- +//dword 1
- +unsigned int tsftl;
- +
- +
- +//dword 2
- +unsigned int tsfth;
- +
- +
- +//dword 3
- +unsigned char sq;
- +unsigned char rssi:7;
- +unsigned char antenna:1;
- +
- +unsigned char agc;
- +unsigned char decrypted:1;
- +unsigned char wakeup:1;
- +unsigned char shift:1;
- +unsigned char rsvd0:5;
- +
- +//dword 4
- +unsigned int num_mcsi:4;
- +unsigned int snr_long2end:6;
- +unsigned int cfo_bias:6;
- +
- +int pwdb_g12:8;
- +unsigned int fot:8;
- +
- +
- +
- +
- +#else
- +
- +#error "please modify tx_desc to your own\n"
- +
- +#endif
- +
- +}__attribute__((packed));
- +
- +
- +
- +struct rx_desc_rtl8187 {
- +
- +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
- +
- +//dword 0
- +unsigned int rxlen:12;
- +unsigned int icv:1;
- +unsigned int crc32:1;
- +unsigned int pwrmgt:1;
- +unsigned int res:1;
- +unsigned int bar:1;
- +unsigned int pam:1;
- +unsigned int mar:1;
- +unsigned int qos:1;
- +unsigned int rxrate:4;
- +unsigned int trsw:1;
- +unsigned int splcp:1;
- +unsigned int fovf:1;
- +unsigned int dmafail:1;
- +unsigned int last:1;
- +unsigned int first:1;
- +unsigned int eor:1;
- +unsigned int own:1;
- +
- +//dword 1
- +unsigned char sq;
- +unsigned char rssi:7;
- +unsigned char antenna:1;
- +
- +unsigned char agc;
- +unsigned char decrypted:1;
- +unsigned char wakeup:1;
- +unsigned char shift:1;
- +unsigned char rsvd0:5;
- +
- +//dword 2
- +unsigned int tsftl;
- +
- +//dword 3
- +unsigned int tsfth;
- +
- +
- +
- +#else
- +
- +#error "please modify tx_desc to your own\n"
- +
- +#endif
- +
- +
- +}__attribute__((packed));
- +
- +
- +
- +union rx_desc {
- +
- +struct rx_desc_rtl8187b desc_87b;
- +struct rx_desc_rtl8187 desc_87;
- +
- +}__attribute__((packed));
- +
- +//
- +// Description:
- +// Perform signal smoothing for dynamic mechanism.
- +// This is different with PerformSignalSmoothing8187 in smoothing fomula.
- +// No dramatic adjustion is apply because dynamic mechanism need some degree
- +// of correctness.
- +// 2007.01.23, by shien chang.
- +//
- +void PerformUndecoratedSignalSmoothing8187(struct net_device *dev, struct ieee80211_rx_stats *stats)
- +{
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- + bool bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats->rate));
- +
- + if(NIC_8187 == priv->card_8187) {
- + if(priv->UndecoratedSmoothedSS >= 0) {
- + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 50) + (stats->signalstrength * 11)) / 60;
- + }else{
- + priv->UndecoratedSmoothedSS = stats->signalstrength;
- + }
- + } else {
- + // Determin the current packet is CCK rate, by Bruce, 2007-04-12.
- + priv->bCurCCKPkt = bCckRate;
- +
- + // Tesing for SD3 DZ, by Bruce, 2007-04-11.
- + if(priv->UndecoratedSmoothedSS >= 0) {
- + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 5) + (stats->signalstrength * 10)) / 6;
- + }else{
- + priv->UndecoratedSmoothedSS = stats->signalstrength * 10;
- + }
- +
- + //
- + // Bacause the AGC parameter is not exactly correct under high power (AGC saturation), we need to record the RSSI value to be
- + // referenced by DoRxHighPower. It is not necessary to record this value when this packet is sent by OFDM rate.
- + // Advised by SD3 DZ, by Bruce, 2007-04-12.
- + //
- + if(bCckRate){
- + priv->CurCCKRSSI = stats->signal;
- + }else{
- + priv->CurCCKRSSI = 0;
- + }
- + }
- + //printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", stats->signalstrength, priv->UndecoratedSmoothedSS);
- +}
- +
- +#ifdef THOMAS_SKB
- +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv)
- +{
- + int status,len,flen;
- +
- +#ifdef SW_ANTE_DIVERSITY
- + u8 Antenna = 0;
- +#endif
- + u32 SignalStrength = 0;
- + u32 quality = 0;
- + bool bCckRate = false;
- + char RX_PWDB = 0;
- + long RecvSignalPower=0;
- + struct sk_buff *skb;
- + struct sk_buff *skb2;//skb for check out of memory
- + union rx_desc *desc;
- + //struct urb *rx_urb = priv->rxurb_task;
- + struct ieee80211_hdr *hdr;//by amy
- + u16 fc,type;
- + u8 bHwError=0,bCRC=0,bICV=0;
- + long SignalStrengthIndex = 0;
- + struct ieee80211_rx_stats stats = {
- + .signal = 0,
- + .noise = -98,
- + .rate = 0,
- + //.mac_time = jiffies,
- + .freq = IEEE80211_24GHZ_BAND,
- + };
- +
- + int *prx_inx=&priv->rx_inx;
- + struct urb *rx_urb=priv->rx_urb[*prx_inx]; //changed by jackson
- + struct net_device *dev = (struct net_device*)rx_urb->context;
- + //DMESG("=====>RX %x ",rx_urb->status);
- +
- + skb = priv->pp_rxskb[*prx_inx];
- + status = rx_urb->status;
- + skb2 = dev_alloc_skb(RX_URB_SIZE);
- +
- + if (skb2 == NULL){
- + printk(KERN_ALERT "No Skb For RX!/n");
- + //rx_urb->transfer_buffer = skb->data;
- + //priv->pp_rxskb[*prx_inx] = skb;
- + } else {
- +
- + if(status == 0)
- + {
- + if(NIC_8187B == priv->card_8187)
- + {
- + stats.nic_type = NIC_8187B;
- + len = rx_urb->actual_length;
- + len -= sizeof (struct rx_desc_rtl8187b);
- + desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
- + flen = desc->desc_87b.rxlen ;
- +
- + if( flen <= rx_urb->actual_length){
- +#if 1
- +#ifdef SW_ANTE_DIVERSITY
- + Antenna = desc->desc_87b.antenna;
- +#endif
- + stats.mac_time[0] = desc->desc_87b.tsftl;
- + stats.mac_time[1] = desc->desc_87b.tsfth;
- +
- + stats.signal = desc->desc_87b.rssi;
- + //stats.noise = desc->desc_87b.sq;
- + quality = desc->desc_87b.sq;
- + stats.rate = desc->desc_87b.rxrate;
- + bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats.rate));
- +
- + if(!bCckRate) { // OFDM rate.
- + if(desc->desc_87b.pwdb_g12 < -106)
- + SignalStrength = 0;
- + else
- + SignalStrength = desc->desc_87b.pwdb_g12 + 106;
- + RX_PWDB = (desc->desc_87b.pwdb_g12)/2 -42;
- + } else { // CCK rate.
- + if(desc->desc_87b.agc> 174)
- + SignalStrength = 0;
- + else
- + SignalStrength = 174 - desc->desc_87b.agc;
- + RX_PWDB = ((desc->desc_87b.agc)/2)*(-1) - 8;
- + }
- +
- + //lzm mod 081028 based on windows driver
- + //compensate SignalStrength when switch TR to SW controled
- + if(priv->TrSwitchState == TR_SW_TX) {
- + SignalStrength = SignalStrength + 54;
- + RX_PWDB = RX_PWDB + 27;
- + }
- +
- + if(SignalStrength > 100)
- + SignalStrength = 100;
- + SignalStrength = (SignalStrength * 70) / 100 + 30;
- +
- + if(SignalStrength > 50)
- + SignalStrength = SignalStrength + 10;
- + if(SignalStrength > 100)
- + SignalStrength = 100;
- +
- + RecvSignalPower = RX_PWDB;
- + //printk("SignalStrength = %d \n",SignalStrength);
- + bHwError = (desc->desc_87b.fovf | desc->desc_87b.icv | desc->desc_87b.crc32);
- + bCRC = desc->desc_87b.crc32;
- + bICV = desc->desc_87b.icv;
- + priv->wstats.qual.level = (u8)SignalStrength;
- +
- + if(!bCckRate){
- + if (quality > 127)
- + quality = 0;
- + else if (quality <27)
- + quality = 100;
- + else
- + quality = 127 - quality;
- + } else {
- + if(quality > 64)
- + quality = 0;
- + else
- + quality = ((64-quality)*100)/64;
- + }
- +
- +
- + priv ->wstats.qual.qual = quality;
- + priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
- +
- + stats.signalstrength = (u8)SignalStrength;
- + stats.signal = (u8)quality;
- + stats.noise = desc->desc_87b.snr_long2end;
- +
- + skb_put(skb,flen-4);
- +
- + priv->stats.rxok++;
- + //by amy
- + hdr = (struct ieee80211_hdr *)skb->data;
- + fc = le16_to_cpu(hdr->frame_ctl);
- + type = WLAN_FC_GET_TYPE(fc);
- +
- + if((IEEE80211_FTYPE_CTL != type) &&
- + (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!bHwError) && (!bCRC)&& (!bICV))
- + {
- + // Perform signal smoothing for dynamic mechanism on demand.
- + // This is different with PerformSignalSmoothing8187 in smoothing fomula.
- + // No dramatic adjustion is apply because dynamic mechanism need some degree
- + // of correctness. 2007.01.23, by shien chang.
- + PerformUndecoratedSignalSmoothing8187(dev, &stats);
- +
- + //Update signal strength and realted into private RxStats for UI query.
- + SignalStrengthIndex = NetgearSignalStrengthTranslate(priv->LastSignalStrengthInPercent, priv->wstats.qual.level);
- + priv->LastSignalStrengthInPercent = SignalStrengthIndex;
- + priv->SignalStrength = TranslateToDbm8187((u8)SignalStrengthIndex);
- + priv->SignalQuality = (priv->SignalQuality*5+quality+5)/6;
- + priv->RecvSignalPower = (priv->RecvSignalPower * 5 + RecvSignalPower - 1) / 6;
- +#ifdef SW_ANTE_DIVERSITY
- + priv->LastRxPktAntenna = Antenna ? 1:0;
- + SwAntennaDiversityRxOk8185(dev, SignalStrength);
- +#endif
- + }
- + //by amy
- +#endif
- + if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
- + dev_kfree_skb_any(skb);
- + }
- + }else {
- + priv->stats.rxurberr++;
- + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
- + dev_kfree_skb_any(skb);
- + }
- + } else {
- + stats.nic_type = NIC_8187;
- + len = rx_urb->actual_length;
- + len -= sizeof (struct rx_desc_rtl8187);
- + desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
- + flen = desc->desc_87.rxlen ;
- +
- + if(flen <= rx_urb->actual_length){
- + stats.signal = desc->desc_87.rssi;
- + stats.noise = desc->desc_87.sq;
- + stats.rate = desc->desc_87.rxrate;
- + stats.mac_time[0] = desc->desc_87.tsftl;
- + stats.mac_time[1] = desc->desc_87.tsfth;
- + SignalStrength = (desc->desc_87.agc&0xfe) >> 1;
- + if( ((stats.rate <= 22) && (stats.rate != 12) && (stats.rate != 18)) || (stats.rate == 44) )//need to translate to real rate here
- + bCckRate= TRUE;
- + if (!bCckRate)
- + {
- + if (SignalStrength > 90) SignalStrength = 90;
- + else if (SignalStrength < 25) SignalStrength = 25;
- + SignalStrength = ((90 - SignalStrength)*100)/65;
- + }
- + else
- + {
- + if (SignalStrength >95) SignalStrength = 95;
- + else if (SignalStrength < 30) SignalStrength = 30;
- + SignalStrength = ((95 - SignalStrength)*100)/65;
- + }
- + stats.signalstrength = (u8)SignalStrength;
- +
- + skb_put(skb,flen-4);
- +
- + priv->stats.rxok++;
- +
- + if(!ieee80211_rx(priv->ieee80211,skb, &stats))
- + dev_kfree_skb_any(skb);
- +
- +
- + }else {
- + priv->stats.rxurberr++;
- + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
- + dev_kfree_skb_any(skb);
- + }
- + }
- + }else{
- +
- + //printk("RX Status Error!\n");
- + priv->stats.rxstaterr++;
- + priv->ieee80211->stats.rx_errors++;
- + dev_kfree_skb_any(skb);
- +
- + }
- +
- + rx_urb->transfer_buffer = skb2->data;
- +
- + priv->pp_rxskb[*prx_inx] = skb2;
- + }
- +
- + if(status != -ENOENT ){
- + rtl8187_rx_urbsubmit(dev,rx_urb);
- + } else {
- + priv->pp_rxskb[*prx_inx] = NULL;
- + dev_kfree_skb_any(skb2);
- + //printk("RX process %d aborted due to explicit shutdown (%x)(%d)\n ", *prx_inx, status, status);
- + }
- +
- + if (*prx_inx == (MAX_RX_URB -1))
- + *prx_inx = 0;
- + else
- + *prx_inx = *prx_inx + 1;
- +}
- +#endif
- +
- +#ifdef THOMAS_TASKLET
- +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv){
- + unsigned long flags;
- + while( atomic_read( &priv->irt_counter ) ){
- + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
- + rtl8180_irq_rx_tasklet(priv);
- + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
- + if(atomic_read(&priv->irt_counter) >= 1)
- + atomic_dec( &priv->irt_counter );
- + }
- +}
- +#endif
- +/****************************************************************************
- + ---------------------------- USB_STUFF---------------------------
- +*****************************************************************************/
- +
- +static const struct net_device_ops rtl8187_netdev_ops = {
- + .ndo_open = rtl8180_open,
- + .ndo_stop = rtl8180_close,
- + .ndo_tx_timeout = tx_timeout,
- + .ndo_do_ioctl = rtl8180_ioctl,
- + .ndo_set_multicast_list = r8180_set_multicast,
- + .ndo_set_mac_address = r8180_set_mac_adr,
- + .ndo_validate_addr = eth_validate_addr,
- + .ndo_change_mtu = eth_change_mtu,
- + .ndo_start_xmit = ieee80211_xmit,
- + .ndo_get_stats = rtl8180_stats,
- +};
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- +static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
- + const struct usb_device_id *id)
- +#else
- +static void * __devinit rtl8187_usb_probe(struct usb_device *udev,
- + unsigned int ifnum,
- + const struct usb_device_id *id)
- +#endif
- +{
- + struct net_device *dev = NULL;
- + struct r8180_priv *priv= NULL;
- +
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + struct usb_device *udev = interface_to_usbdev(intf);
- +#endif
- +
- + dev = alloc_ieee80211(sizeof(struct r8180_priv));
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- + SET_MODULE_OWNER(dev);
- +#endif
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + usb_set_intfdata(intf, dev);
- + SET_NETDEV_DEV(dev, &intf->dev);
- +#endif
- + priv = ieee80211_priv(dev);
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + priv->ieee80211 = netdev_priv(dev);
- +#else
- + priv->ieee80211 = (struct net_device *)dev->priv;
- +#endif
- + priv->udev=udev;
- +#ifdef CPU_64BIT
- + priv->usb_buf = kmalloc(0x200, GFP_KERNEL);
- + priv->usb_pool = dma_pool_create("rtl8187b", NULL, 64, 64, 0);
- +#endif
- +//lzm add for write time out test
- +#ifdef DEBUG_RW_REGISTER
- + {
- + int reg_index = 0;
- + for(reg_index = 0; reg_index <= 199; reg_index++)
- + {
- + priv->write_read_registers[reg_index].address = 0;
- + priv->write_read_registers[reg_index].content = 0;
- + priv->write_read_registers[reg_index].flag = 0;
- + }
- + priv->write_read_register_index = 0;
- + }
- +#endif
- + //init netdev_ops, added by falcon....
- + dev->netdev_ops = &rtl8187_netdev_ops;
- +
- + dev->wireless_handlers = &r8180_wx_handlers_def;
- +#if WIRELESS_EXT >= 12
- +#if WIRELESS_EXT < 17
- + dev->get_wireless_stats = r8180_get_wireless_stats;
- +#endif
- + dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
- +#endif
- +
- + dev->type=ARPHRD_ETHER;
- + dev->watchdog_timeo = HZ*3; //modified by john, 0805
- +
- + if (dev_alloc_name(dev, ifname) < 0){
- + DMESG("Oops: devname already taken! Trying wlan%%d...\n");
- + ifname = "wlan%d";
- + dev_alloc_name(dev, ifname);
- + }
- +
- + if(rtl8180_init(dev)!=0){
- + DMESG("Initialization failed");
- + goto fail;
- + }
- +
- + netif_carrier_off(dev);
- + netif_stop_queue(dev);
- +
- + register_netdev(dev);
- +
- + rtl8180_proc_init_one(dev);
- +
- + /* init rfkill */
- + r8187b_rfkill_init(dev);
- +
- + DMESG("Driver probe completed");
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- + return dev;
- +#else
- + return 0;
- +#endif
- +
- +
- +fail:
- + free_ieee80211(dev);
- +
- + DMESG("wlan driver load failed\n");
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- + return NULL;
- +#else
- + return -ENODEV;
- +#endif
- +
- +}
- +
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf)
- +#else
- +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr)
- +#endif
- +{
- + struct r8180_priv *priv = NULL;
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + struct net_device *dev = usb_get_intfdata(intf);
- +#else
- + struct net_device *dev = (struct net_device *)ptr;
- +#endif
- + if(dev){
- + unregister_netdev(dev);
- +
- + priv=ieee80211_priv(dev);
- +
- + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + if(priv && priv->mshobj)
- + {
- + if(priv->mshobj->ext_patch_remove_proc)
- + priv->mshobj->ext_patch_remove_proc(priv);
- + priv->ieee80211->ext_patch_ieee80211_start_protocol = 0;
- + priv->ieee80211->ext_patch_ieee80211_stop_protocol = 0;
- + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = 0;
- + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = 0;
- + priv->ieee80211->ext_patch_ieee80211_association_req_1 = 0;
- + priv->ieee80211->ext_patch_ieee80211_association_req_2 = 0;
- + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = 0;
- + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth =0;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth =0;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = 0;
- + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = 0;
- + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = 0;
- + priv->ieee80211->ext_patch_get_beacon_get_probersp = 0;
- + priv->ieee80211->ext_patch_ieee80211_xmit = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = 0;
- + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = 0;
- + // priv->ieee80211->ext_patch_is_duplicate_packet = 0;
- + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = 0;
- + free_mshobj(&priv->mshobj);
- + }
- +#endif // _RTL8187_EXT_PATCH_
- +
- + rtl8180_proc_remove_one(dev);
- +
- + rtl8180_down(dev);
- + priv->rf_close(dev);
- +
- + //rtl8180_rtx_disable(dev);
- + rtl8187_usb_deleteendpoints(dev);
- +#ifdef LED
- + DeInitSwLeds(dev);
- +#endif
- + rtl8180_irq_disable(dev);
- + rtl8180_reset(dev);
- + mdelay(10);
- +
- + }
- +
- +#ifdef CPU_64BIT
- + if(priv->usb_buf)
- + kfree(priv->usb_buf);
- + if(priv->usb_pool) {
- + dma_pool_destroy(priv->usb_pool);
- + priv->usb_pool = NULL;
- + }
- +#endif
- + free_ieee80211(dev);
- + DMESG("wlan driver removed");
- +}
- +
- +/* fun with the built-in ieee80211 stack... */
- +extern int ieee80211_crypto_init(void);
- +extern void ieee80211_crypto_deinit(void);
- +extern int ieee80211_crypto_tkip_init(void);
- +extern void ieee80211_crypto_tkip_exit(void);
- +extern int ieee80211_crypto_ccmp_init(void);
- +extern void ieee80211_crypto_ccmp_exit(void);
- +extern int ieee80211_crypto_wep_init(void);
- +extern void ieee80211_crypto_wep_exit(void);
- +
- +static int __init rtl8187_usb_module_init(void)
- +{
- + int ret;
- +
- + ret = ieee80211_crypto_init();
- + if (ret) {
- + printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
- + return ret;
- + }
- + ret = ieee80211_crypto_tkip_init();
- + if (ret) {
- + printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
- + return ret;
- + }
- + ret = ieee80211_crypto_ccmp_init();
- + if (ret) {
- + printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
- + return ret;
- + }
- + ret = ieee80211_crypto_wep_init();
- + if (ret) {
- + printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
- + return ret;
- + }
- +
- + printk("\nLinux kernel driver for RTL8187/RTL8187B based WLAN cards\n");
- + printk("Copyright (c) 2004-2008, Realsil Wlan\n");
- + DMESG("Initializing module");
- + DMESG("Wireless extensions version %d", WIRELESS_EXT);
- + rtl8180_proc_module_init();
- + return usb_register(&rtl8187_usb_driver);
- +}
- +
- +static void __exit rtl8187_usb_module_exit(void)
- +{
- + r8187b_rfkill_exit();
- + usb_deregister(&rtl8187_usb_driver);
- + rtl8180_proc_module_remove();
- + ieee80211_crypto_tkip_exit();
- + ieee80211_crypto_ccmp_exit();
- + ieee80211_crypto_wep_exit();
- + ieee80211_crypto_deinit();
- +
- + DMESG("Exiting\n");
- +}
- +
- +
- +void rtl8180_try_wake_queue(struct net_device *dev, int pri)
- +{
- + unsigned long flags;
- + short enough_desc;
- + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- +
- + spin_lock_irqsave(&priv->tx_lock,flags);
- + enough_desc = check_nic_enought_desc(dev,pri);
- + spin_unlock_irqrestore(&priv->tx_lock,flags);
- +
- + if(enough_desc)
- + ieee80211_wake_queue(priv->ieee80211);
- +}
- +
- +#ifdef JOHN_HWSEC
- +void EnableHWSecurityConfig8187(struct net_device *dev)
- +{
- + u8 SECR_value = 0x0;
- + SECR_value = SCR_TxSecEnable | SCR_RxSecEnable;
- + {
- + write_nic_byte(dev, WPA_CONFIG, 0x7);//SECR_value | SCR_UseDK );
- + }
- +}
- +
- +void setKey(struct net_device *dev,
- + u8 EntryNo,
- + u8 KeyIndex,
- + u16 KeyType,
- + u8 *MacAddr,
- + u8 DefaultKey,
- + u32 *KeyContent )
- +{
- + u32 TargetCommand = 0;
- + u32 TargetContent = 0;
- + u16 usConfig = 0;
- + int i;
- + usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
- +
- +
- + for(i=0 ; i<6 ; i++){
- + TargetCommand = i+6*EntryNo;
- + TargetCommand |= BIT31|BIT16;
- +
- + if(i==0){//MAC|Config
- + TargetContent = (u32)(*(MacAddr+0)) << 16|
- + (u32)(*(MacAddr+1)) << 24|
- + (u32)usConfig;
- +
- + write_nic_dword(dev, WCAMI, TargetContent);
- + write_nic_dword(dev, RWCAM, TargetCommand);
- + //printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
- + } else if(i==1){//MAC
- + TargetContent = (u32)(*(MacAddr+2)) |
- + (u32)(*(MacAddr+3)) << 8|
- + (u32)(*(MacAddr+4)) << 16|
- + (u32)(*(MacAddr+5)) << 24;
- + write_nic_dword(dev, WCAMI, TargetContent);
- + write_nic_dword(dev, RWCAM, TargetCommand);
- + } else { //Key Material
- + write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
- + write_nic_dword(dev, RWCAM, TargetCommand);
- + }
- + }
- +
- +}
- +#endif
- +
- +/****************************************************************************
- + --------------------------- RF power on/power off -----------------
- +*****************************************************************************/
- +
- +/*
- + * the interface for changing the rfkill state
- + * @dev: the device of r8187b
- + * @eRfPowerStateToSet: the state we need to change,
- + * eRfOn: power on
- + * eRfOff: power off
- + *
- + * This function should be called by the SCI interrupt handler when the
- + * KEY_WLAN event happen(or install to the notify function of the SCI
- + * interrupt) or called in the wifi_set function of the rfkill interface for
- + * user-space, and also, it can be called to initialize the wifi state, and
- + * called when suspend/resume.
- + */
- +
- +void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- + if (eRfPowerStateToSet == eRfOn)
- + priv->ieee80211->bHwRadioOff = false;
- + else
- + priv->ieee80211->bHwRadioOff = true;
- +
- +#ifdef CONFIG_RADIO_DEBUG
- + DMESG("SCI interrupt Methord Will Turn Radio %s",
- + (priv->ieee80211->bHwRadioOff == true) ? "Off" : "On");
- +#endif
- +
- +#ifdef LED //by lizhaoming
- + if (priv->ieee80211->bHwRadioOff)
- + priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_OFF);
- + else
- + priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_ON);
- +#endif
- +
- + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
- +
- + /* report the rfkill state to the user-space via uevent interface */
- + r8187b_wifi_report_state(priv);
- +}
- +
- +/***************************************************************************
- + ------------------- module init / exit stubs ----------------
- +****************************************************************************/
- +module_init(rtl8187_usb_module_init);
- +module_exit(rtl8187_usb_module_exit);
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187.h linux-lemote/drivers/net/wireless/rtl8187b/r8187.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,811 @@
- +/*
- + This is part of rtl8187 OpenSource driver.
- + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
- + Released under the terms of GPL (General Public Licence)
- +
- + Parts of this driver are based on the GPL part of the
- + official realtek driver
- +
- + Parts of this driver are based on the rtl8180 driver skeleton
- + from Patric Schenke & Andres Salomon
- +
- + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
- +
- + We want to tanks the Authors of those projects and the Ndiswrapper
- + project Authors.
- +*/
- +
- +#ifndef R8180H
- +#define R8180H
- +
- +
- +#define RTL8187_MODULE_NAME "rtl8187"
- +#define DMESG(x,a...) printk(KERN_INFO RTL8187_MODULE_NAME ": " x "\n", ## a)
- +#define DMESGW(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": WW:" x "\n", ## a)
- +#define DMESGE(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": EE:" x "\n", ## a)
- +
- +#include <linux/module.h>
- +#include <linux/kernel.h>
- +//#include <linux/config.h>
- +#include <linux/init.h>
- +#include <linux/ioport.h>
- +#include <linux/sched.h>
- +#include <linux/types.h>
- +#include <linux/slab.h>
- +#include <linux/netdevice.h>
- +//#include <linux/pci.h>
- +#include <linux/usb.h>
- +#include <linux/etherdevice.h>
- +#include <linux/delay.h>
- +#include <linux/rtnetlink.h> //for rtnl_lock()
- +#include <linux/wireless.h>
- +#include <linux/timer.h>
- +#include <linux/proc_fs.h> // Necessary because we use the proc fs
- +#include <linux/if_arp.h>
- +#include <linux/random.h>
- +#include <linux/version.h>
- +#include <asm/io.h>
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
- +#include <asm/semaphore.h>
- +#endif
- +#include "ieee80211/ieee80211.h"
- +#ifdef _RTL8187_EXT_PATCH_
- +#include "msh_class.h"
- +#endif
- +#ifdef LED
- +#include "r8187_led.h"
- +#endif
- +
- +//added for HW security, john.0629
- +#define FALSE 0
- +#define TRUE 1
- +#define MAX_KEY_LEN 61
- +#define KEY_BUF_SIZE 5
- +
- +#define BIT0 0x00000001
- +#define BIT1 0x00000002
- +#define BIT2 0x00000004
- +#define BIT3 0x00000008
- +#define BIT4 0x00000010
- +#define BIT5 0x00000020
- +#define BIT6 0x00000040
- +#define BIT7 0x00000080
- +#define BIT8 0x00000100
- +#define BIT9 0x00000200
- +#define BIT10 0x00000400
- +#define BIT11 0x00000800
- +#define BIT12 0x00001000
- +#define BIT13 0x00002000
- +#define BIT14 0x00004000
- +#define BIT15 0x00008000
- +#define BIT16 0x00010000
- +#define BIT17 0x00020000
- +#define BIT18 0x00040000
- +#define BIT19 0x00080000
- +#define BIT20 0x00100000
- +#define BIT21 0x00200000
- +#define BIT22 0x00400000
- +#define BIT23 0x00800000
- +#define BIT24 0x01000000
- +#define BIT25 0x02000000
- +#define BIT26 0x04000000
- +#define BIT27 0x08000000
- +#define BIT28 0x10000000
- +#define BIT29 0x20000000
- +#define BIT30 0x40000000
- +#define BIT31 0x80000000
- +
- +//8187B Security
- +#define RWCAM 0xA0 // Software read/write CAM config
- +#define WCAMI 0xA4 // Software write CAM input content
- +#define RCAMO 0xA8 // Output value from CAM according to 0xa0 setting
- +#define DCAM 0xAC // Debug CAM Interface
- +#define SECR 0xB0 // Security configuration register
- +#define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06.
- +#define AESMSK_SC 0x1FC // AES Mask for Sequence Control (0x1FC~0X1FD). Added by Annie, 2006-03-06.
- +#define AESMSK_QC 0x1CE // AES Mask register for QoS Control when computing AES MIC, default = 0x000F. (2 bytes)
- +
- +#define AESMSK_FC_DEFAULT 0xC78F // default value of AES MASK for Frame Control Field. (2 bytes)
- +#define AESMSK_SC_DEFAULT 0x000F // default value of AES MASK for Sequence Control Field. (2 bytes)
- +#define AESMSK_QC_DEFAULT 0x000F // default value of AES MASK for QoS Control Field. (2 bytes)
- +
- +#define CAM_CONTENT_COUNT 6
- +#define CFG_DEFAULT_KEY BIT5
- +#define CFG_VALID BIT15
- +
- +//----------------------------------------------------------------------------
- +// 8187B WPA Config Register (offset 0xb0, 1 byte)
- +//----------------------------------------------------------------------------
- +#define SCR_UseDK 0x01
- +#define SCR_TxSecEnable 0x02
- +#define SCR_RxSecEnable 0x04
- +
- +//----------------------------------------------------------------------------
- +// 8187B CAM Config Setting (offset 0xb0, 1 byte)
- +//----------------------------------------------------------------------------
- +#define CAM_VALID 0x8000
- +#define CAM_NOTVALID 0x0000
- +#define CAM_USEDK 0x0020
- +
- +
- +#define CAM_NONE 0x0
- +#define CAM_WEP40 0x01
- +#define CAM_TKIP 0x02
- +#define CAM_AES 0x04
- +#define CAM_WEP104 0x05
- +
- +
- +//#define CAM_SIZE 16
- +#define TOTAL_CAM_ENTRY 16
- +#define CAM_ENTRY_LEN_IN_DW 6 // 6, unit: in u4byte. Added by Annie, 2006-05-25.
- +#define CAM_ENTRY_LEN_IN_BYTE (CAM_ENTRY_LEN_IN_DW*sizeof(u4Byte)) // 24, unit: in u1byte. Added by Annie, 2006-05-25.
- +
- +#define CAM_CONFIG_USEDK 1
- +#define CAM_CONFIG_NO_USEDK 0
- +
- +#define CAM_WRITE 0x00010000
- +#define CAM_READ 0x00000000
- +#define CAM_POLLINIG 0x80000000
- +
- +//=================================================================
- +//=================================================================
- +
- +#define EPROM_93c46 0
- +#define EPROM_93c56 1
- +
- +#define DEFAULT_FRAG_THRESHOLD 2342U
- +#define MIN_FRAG_THRESHOLD 256U
- +#define DEFAULT_BEACONINTERVAL 0x64U
- +#define DEFAULT_BEACON_ESSID "Rtl8187"
- +
- +#define DEFAULT_SSID ""
- +#define DEFAULT_RETRY_RTS 7
- +#define DEFAULT_RETRY_DATA 7
- +#define PRISM_HDR_SIZE 64
- +
- +typedef enum _WIRELESS_MODE {
- + WIRELESS_MODE_UNKNOWN = 0x00,
- + WIRELESS_MODE_A = 0x01,
- + WIRELESS_MODE_B = 0x02,
- + WIRELESS_MODE_G = 0x04,
- + WIRELESS_MODE_AUTO = 0x08,
- +} WIRELESS_MODE;
- +
- +typedef enum _TR_SWITCH_STATE{
- + TR_HW_CONTROLLED = 0,
- + TR_SW_TX = 1,
- +}TR_SWITCH_STATE, *PTR_SWITCH_STATE;
- +
- +
- +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
- +
- +typedef struct buffer
- +{
- + struct buffer *next;
- + u32 *buf;
- +
- +} buffer;
- +
- +typedef struct rtl_reg_debug{
- + unsigned int cmd;
- + struct {
- + unsigned char type;
- + unsigned char addr;
- + unsigned char page;
- + unsigned char length;
- + } head;
- + unsigned char buf[0xff];
- +}rtl_reg_debug;
- +typedef struct _CHANNEL_LIST{
- + u8 Channel[MAX_CHANNEL_NUMBER + 1];
- + u8 Len;
- +}CHANNEL_LIST, *PCHANNEL_LIST;
- +
- +#define MAX_LD_SLOT_NUM 10
- +#define DEFAULT_SLOT_NUM 2
- +#define KEEP_ALIVE_INTERVAL 20 // in seconds.
- +#define CHECK_FOR_HANG_PERIOD 2 //be equal to watchdog check time
- +#define DEFAULT_KEEP_ALIVE_LEVEL 1
- +
- +typedef struct _link_detect_t
- +{
- + u32 RxFrameNum[MAX_LD_SLOT_NUM]; // number of Rx Frame / CheckForHang_period to determine link status
- + u16 SlotNum; // number of CheckForHang period to determine link status, default is 2
- + u16 SlotIndex;
- +
- + u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang
- + u32 NumRxOkInPeriod; //number of packet received during CheckForHang
- +
- + u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)
- + u32 LastNumTxUnicast;
- + u32 LastNumRxUnicast;
- +
- + bool bBusyTraffic; //when it is set to 1, UI cann't scan at will.
- +}link_detect_t, *plink_detect_t;
- +
- +#if 0
- +
- +typedef struct tx_pendingbuf
- +{
- + struct ieee80211_txb *txb;
- + short ispending;
- + short descfrag;
- +} tx_pendigbuf;
- +
- +#endif
- +
- +typedef struct Stats
- +{
- + unsigned long txrdu;
- +// unsigned long rxrdu;
- + //unsigned long rxnolast;
- + //unsigned long rxnodata;
- +// unsigned long rxreset;
- +// unsigned long rxwrkaround;
- +// unsigned long rxnopointer;
- + unsigned long rxok;
- + unsigned long rxurberr;
- + unsigned long rxstaterr;
- + unsigned long txnperr;
- + unsigned long txnpdrop;
- + unsigned long txresumed;
- +// unsigned long rxerr;
- +// unsigned long rxoverflow;
- +// unsigned long rxint;
- + unsigned long txnpokint;
- +// unsigned long txhpokint;
- +// unsigned long txhperr;
- +// unsigned long ints;
- +// unsigned long shints;
- + unsigned long txoverflow;
- +// unsigned long rxdmafail;
- +// unsigned long txbeacon;
- +// unsigned long txbeaconerr;
- + unsigned long txlpokint;
- + unsigned long txlpdrop;
- + unsigned long txlperr;
- + unsigned long txbeokint;
- + unsigned long txbedrop;
- + unsigned long txbeerr;
- + unsigned long txbkokint;
- + unsigned long txbkdrop;
- + unsigned long txbkerr;
- + unsigned long txviokint;
- + unsigned long txvidrop;
- + unsigned long txvierr;
- + unsigned long txvookint;
- + unsigned long txvodrop;
- + unsigned long txvoerr;
- + unsigned long txbeaconokint;
- + unsigned long txbeacondrop;
- + unsigned long txbeaconerr;
- + unsigned long txmanageokint;
- + unsigned long txmanagedrop;
- + unsigned long txmanageerr;
- + unsigned long txdatapkt;
- +} Stats;
- +
- +typedef struct ChnlAccessSetting {
- + u16 SIFS_Timer;
- + u16 DIFS_Timer;
- + u16 SlotTimeTimer;
- + u16 EIFS_Timer;
- + u16 CWminIndex;
- + u16 CWmaxIndex;
- +}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
- +
- +
- +typedef enum _RT_RF_POWER_STATE
- +{
- + eRfOn,
- + eRfSleep,
- + eRfOff
- +}RT_RF_POWER_STATE;
- +typedef enum _RT_PS_MODE
- +{
- + eActive, // Active/Continuous access.
- + eMaxPs, // Max power save mode.
- + eFastPs // Fast power save mode.
- +}RT_PS_MODE;
- +//
- +// Three wire mode.
- +//
- +#define IC_DEFAULT_THREE_WIRE 0
- +#define SW_THREE_WIRE 1
- +//RTL818xB
- +#define SW_THREE_WIRE_BY_8051 2
- +#define HW_THREE_WIRE 3
- +#define HW_THREE_WIRE_BY_8051 4
- +//lzm add for write time out test
- +typedef struct write_read_register
- +{
- + u32 address;
- + u32 content;
- + u32 flag;
- +} write_read_register;
- +//lzm add for write time out test
- +typedef struct r8180_priv
- +{
- +//lzm add for write time out test
- + struct write_read_register write_read_registers[200];
- + u8 write_read_register_index;
- +//lzm add for write time out test
- +
- + struct usb_device *udev;
- + short epromtype;
- + int irq;
- + struct ieee80211_device *ieee80211;
- +
- + short card_8187; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D */
- + short card_8187_Bversion; /* if TCR reports card V B/C this discriminates */
- + short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
- + short enable_gpio0;
- + enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
- + short hw_plcp_len;
- + short plcp_preamble_mode;
- +
- + spinlock_t irq_lock;
- +// spinlock_t irq_th_lock;
- + spinlock_t tx_lock;
- +//by amy for ps
- + spinlock_t rf_ps_lock;
- +//by amy for ps
- +
- + u16 irq_mask;
- +// short irq_enabled;
- + struct net_device *dev;
- + short chan;
- + short sens;
- + short max_sens;
- + u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
- + u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
- + u8 cck_txpwr_base;
- + u8 ofdm_txpwr_base;
- + u8 challow[15]; //channels from 1 to 14, 0 not used
- + short up;
- + short crcmon; //if 1 allow bad crc frame reception in monitor mode
- +// short prism_hdr;
- +
- +// struct timer_list scan_timer;
- + /*short scanpending;
- + short stopscan;*/
- +// spinlock_t scan_lock;
- +// u8 active_probe;
- + //u8 active_scan_num;
- + struct semaphore wx_sem;
- + struct semaphore set_chan_sem;
- +// short hw_wep;
- +
- +// short digphy;
- +// short antb;
- +// short diversity;
- +// u8 cs_treshold;
- +// short rcr_csense;
- + short rf_chip;
- +// u32 key0[4];
- + short (*rf_set_sens)(struct net_device *dev,short sens);
- + void (*rf_set_chan)(struct net_device *dev,short ch);
- + void (*rf_close)(struct net_device *dev);
- + void (*rf_init)(struct net_device *dev);
- + //short rate;
- + short promisc;
- + /*stats*/
- + struct Stats stats;
- + struct _link_detect_t link_detect; //added on 1016.2008
- + struct iw_statistics wstats;
- + struct proc_dir_entry *dir_dev;
- +
- + /*RX stuff*/
- +// u32 *rxring;
- +// u32 *rxringtail;
- +// dma_addr_t rxringdma;
- + struct urb **rx_urb;
- +#ifdef THOMAS_BEACON
- + unsigned long *oldaddr; //lzm for 64bit CPU crash
- +#endif
- +
- +#ifdef THOMAS_TASKLET
- + atomic_t irt_counter;//count for irq_rx_tasklet
- +#endif
- +#ifdef JACKSON_NEW_RX
- + struct sk_buff **pp_rxskb;
- + int rx_inx;
- +#endif
- +
- + short tx_urb_index;
- +
- + //struct buffer *rxbuffer;
- + //struct buffer *rxbufferhead;
- + //int rxringcount;
- + //u16 rxbuffersize;
- +
- + //struct sk_buff *rx_skb;
- +
- + //short rx_skb_complete;
- +
- + //u32 rx_prevlen;
- + //atomic_t tx_lp_pending;
- + //atomic_t tx_np_pending;
- + atomic_t tx_pending[0x10];//UART_PRIORITY+1
- +
- +#if 0
- + /*TX stuff*/
- + u32 *txlpring;
- + u32 *txhpring;
- + u32 *txnpring;
- + dma_addr_t txlpringdma;
- + dma_addr_t txhpringdma;
- + dma_addr_t txnpringdma;
- + u32 *txlpringtail;
- + u32 *txhpringtail;
- + u32 *txnpringtail;
- + u32 *txlpringhead;
- + u32 *txhpringhead;
- + u32 *txnpringhead;
- + struct buffer *txlpbufs;
- + struct buffer *txhpbufs;
- + struct buffer *txnpbufs;
- + struct buffer *txlpbufstail;
- + struct buffer *txhpbufstail;
- + struct buffer *txnpbufstail;
- + int txringcount;
- + int txbuffsize;
- +
- + //struct tx_pendingbuf txnp_pending;
- + struct tasklet_struct irq_tx_tasklet;
- +#endif
- + struct tasklet_struct irq_rx_tasklet;
- + struct urb *rxurb_task;
- +// u8 dma_poll_mask;
- + //short tx_suspend;
- +
- + /* adhoc/master mode stuff */
- +#if 0
- + u32 *txbeacontail;
- + dma_addr_t txbeaconringdma;
- + u32 *txbeaconring;
- + int txbeaconcount;
- +#endif
- +// struct ieee_tx_beacon *beacon_buf;
- + //char *master_essid;
- +// dma_addr_t beacondmabuf;
- + //u16 master_beaconinterval;
- +// u32 master_beaconsize;
- + //u16 beacon_interval;
- +
- + //2 Tx Related variables
- + u16 ShortRetryLimit;
- + u16 LongRetryLimit;
- + u32 TransmitConfig;
- + u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27.
- +
- + //2 Rx Related variables
- + u16 EarlyRxThreshold;
- + u32 ReceiveConfig;
- + u8 AcmControl;
- +
- + u8 RFProgType;
- +
- + u8 retry_data;
- + u8 retry_rts;
- + u16 rts;
- +
- +//by amy
- + long LastSignalStrengthInPercent;
- + long SignalStrength;
- + long SignalQuality;
- + u8 antenna_flag;
- + bool flag_beacon;
- +//by amy
- +//by amy for rate adaptive
- + struct timer_list rateadapter_timer;
- + u16 LastRetryCnt;
- + u16 LastRetryRate;
- + unsigned long LastTxokCnt;
- + unsigned long LastRxokCnt;
- + u16 CurrRetryCnt;
- + long RecvSignalPower;
- + unsigned long LastTxOKBytes;
- + u8 LastFailTxRate;
- + long LastFailTxRateSS;
- + u8 FailTxRateCount;
- + u32 LastTxThroughput;
- + unsigned long txokbytestotal;
- + //for up rate
- + unsigned short bTryuping;
- + u8 CurrTxRate; //the rate before up
- + u16 CurrRetryRate;
- + u16 TryupingCount;
- + u8 TryDownCountLowData;
- + u8 TryupingCountNoData;
- +
- + u8 CurrentOperaRate;
- +//by amy for rate adaptive
- +//by amy for power save
- + struct timer_list watch_dog_timer;
- + bool bInactivePs;
- + bool bSwRfProcessing;
- + RT_RF_POWER_STATE eInactivePowerState;
- + RT_RF_POWER_STATE eRFPowerState;
- + u32 RfOffReason;
- + bool RFChangeInProgress;
- + bool bInHctTest;
- + bool SetRFPowerStateInProgress;
- + //u8 RFProgType;
- + bool bLeisurePs;
- + RT_PS_MODE dot11PowerSaveMode;
- + u32 NumRxOkInPeriod;
- + u32 NumTxOkInPeriod;
- + u8 RegThreeWireMode;
- + bool ps_mode;
- +//by amy for power save
- +//by amy for DIG
- + bool bDigMechanism;
- + bool bCCKThMechanism;
- + u8 InitialGain;
- + u8 StageCCKTh;
- + u8 RegBModeGainStage;
- + u8 RegDigOfdmFaUpTh; //added by david, 2008.3.6
- + u8 DIG_NumberFallbackVote;
- + u8 DIG_NumberUpgradeVote;
- + u16 CCKUpperTh;
- + u16 CCKLowerTh;
- + u32 FalseAlarmRegValue; //added by david, 2008.3.6
- +//by amy for DIG
- +//{ added by david for high power, 2008.3.11
- + int UndecoratedSmoothedSS;
- + bool bRegHighPowerMechanism;
- + bool bToUpdateTxPwr;
- + u8 Z2HiPwrUpperTh;
- + u8 Z2HiPwrLowerTh;
- + u8 Z2RSSIHiPwrUpperTh;
- + u8 Z2RSSIHiPwrLowerTh;
- + // Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, by Bruce, 2007-04-12.
- + u8 CurCCKRSSI;
- + bool bCurCCKPkt;
- + u32 wMacRegRfPinsOutput;
- + u32 wMacRegRfPinsSelect;
- + TR_SWITCH_STATE TrSwitchState;
- +//}
- +//{added by david for radio on/off
- + u8 radion;
- +//}
- + struct ChnlAccessSetting ChannelAccessSetting;
- +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
- + struct work_struct reset_wq;
- +#else
- + struct tq_struct reset_wq;
- +#endif
- +
- +#ifdef _RTL8187_EXT_PATCH_
- + struct mshclass *mshobj;
- +#endif
- +
- +#ifdef LED
- + /* add for led controll */
- + u8 EEPROMCustomerID;
- + RT_CID_TYPE CustomerID;
- + LED_8187 Gpio0Led;
- + LED_8187 SwLed0;
- + LED_8187 SwLed1;
- + u8 bEnableLedCtrl;
- + LED_STRATEGY_8187 LedStrategy;
- + u8 PsrValue;
- + struct work_struct Gpio0LedWorkItem;
- + struct work_struct SwLed0WorkItem;
- + struct work_struct SwLed1WorkItem;
- +#endif
- + u8 driver_upping;
- +#ifdef CPU_64BIT
- + u8 *usb_buf;
- + struct dma_pool *usb_pool;
- +#endif
- +
- +
- +#ifdef SW_ANTE_DIVERSITY
- +
- +//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +// struct delayed_work SwAntennaWorkItem;
- +//#else
- +// struct work_struct SwAntennaWorkItem;
- +//#endif
- +
- + bool bAntennaDiversityTimerIssued;
- + short antb;
- + short diversity;
- + bool AutoloadFailFlag;
- + u16 EEPROMVersion;
- + u8 EEPROMAntennaDiversity;
- + u16 EEPROMCSThreshold;
- + u8 EEPROMDefaultAntennaB;
- + u8 EEPROMDigitalPhy;
- + u32 EEPROMCSMethod;
- + u8 EEPROMGEPRFOffState;
- + // For HW antenna diversity, added by Roger, 2008.01.30.
- + u32 AdMainAntennaRxOkCnt; // Main antenna Rx OK count.
- + u32 AdAuxAntennaRxOkCnt; // Aux antenna Rx OK count.
- + bool bHWAdSwitched; // TRUE if we has switched default antenna by HW evaluation.
- + u8 EEPROMSwAntennaDiversity;
- + bool EEPROMDefaultAntenna1;
- + u8 RegSwAntennaDiversityMechanism;// 0:default from EEPROM, 1: disable, 2: enable.
- + bool bSwAntennaDiverity;
- + u8 RegDefaultAntenna;// 0: default from EEPROM, 1: main, 2: aux. Added by Roger, 2007.11.05.
- + bool bDefaultAntenna1;
- + //long SignalStrength;
- + long Stats_SignalStrength;
- + //long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average.
- + //long SignalQuality; // in 0-100 index.
- + long Stats_SignalQuality;
- + //long RecvSignalPower; // in dBm.
- + long Stats_RecvSignalPower;
- + u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25.
- + u32 AdRxOkCnt;
- + long AdRxSignalStrength; // Rx signal strength for Antenna Diversity, which had been smoothing, its valid range is [0,100].
- + u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx).
- + u8 AdTickCount; // Times of SwAntennaDiversityTimer happened.
- + u8 AdCheckPeriod; // # of period SwAntennaDiversityTimer to check Rx signal strength for SW Antenna Diversity.
- + u8 AdMinCheckPeriod; // Min value of AdCheckPeriod.
- + u8 AdMaxCheckPeriod; // Max value of AdCheckPeriod.
- + long AdRxSsThreshold; // Signal strength threshold to switch antenna.
- + long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold.
- + bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna.
- + long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna.
- + struct timer_list SwAntennaDiversityTimer;
- +#endif
- + u8 commit;
- +
- +//#ifdef ENABLE_DOT11D
- + u8 channel_plan;
- +//#endif
- + u8 EEPROMSelectNewGPIO;
- +}r8180_priv;
- +
- +// for rtl8187
- +// now mirging to rtl8187B
- +/*
- +typedef enum{
- + LOW_PRIORITY = 0x02,
- + NORM_PRIORITY
- + } priority_t;
- +*/
- +//for rtl8187B
- +typedef enum{
- + BULK_PRIORITY = 0x01,
- + //RSVD0,
- + //RSVD1,
- + LOW_PRIORITY,
- + NORM_PRIORITY,
- + VO_PRIORITY,
- + VI_PRIORITY, //0x05
- + BE_PRIORITY,
- + BK_PRIORITY,
- + RSVD2,
- + RSVD3,
- + BEACON_PRIORITY, //0x0A
- + HIGH_PRIORITY,
- + MANAGE_PRIORITY,
- + RSVD4,
- + RSVD5,
- + UART_PRIORITY //0x0F
- +} priority_t;
- +
- +typedef enum{
- + NIC_8187 = 1,
- + NIC_8187B
- + } nic_t;
- +
- +
- +typedef u32 AC_CODING;
- +#define AC0_BE 0 // ACI: 0x00 // Best Effort
- +#define AC1_BK 1 // ACI: 0x01 // Background
- +#define AC2_VI 2 // ACI: 0x10 // Video
- +#define AC3_VO 3 // ACI: 0x11 // Voice
- +#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
- +
- +//
- +// ECWmin/ECWmax field.
- +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
- +//
- +typedef union _ECW{
- + u8 charData;
- + struct
- + {
- + u8 ECWmin:4;
- + u8 ECWmax:4;
- + }f; // Field
- +}ECW, *PECW;
- +
- +//
- +// ACI/AIFSN Field.
- +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- +//
- +typedef union _ACI_AIFSN{
- + u8 charData;
- +
- + struct
- + {
- + u8 AIFSN:4;
- + u8 ACM:1;
- + u8 ACI:2;
- + u8 Reserved:1;
- + }f; // Field
- +}ACI_AIFSN, *PACI_AIFSN;
- +
- +//
- +// AC Parameters Record Format.
- +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- +//
- +typedef union _AC_PARAM{
- + u32 longData;
- + u8 charData[4];
- +
- + struct
- + {
- + ACI_AIFSN AciAifsn;
- + ECW Ecw;
- + u16 TXOPLimit;
- + }f; // Field
- +}AC_PARAM, *PAC_PARAM;
- +
- +#ifdef JOHN_HWSEC
- +struct ssid_thread {
- + struct net_device *dev;
- + u8 name[IW_ESSID_MAX_SIZE + 1];
- +};
- +#endif
- +
- +short rtl8180_tx(struct net_device *dev,u32* skbuf, int len,priority_t priority,short morefrag,short rate);
- +
- +#ifdef JOHN_TKIP
- +u32 read_cam(struct net_device *dev, u8 addr);
- +void write_cam(struct net_device *dev, u8 addr, u32 data);
- +#endif
- +u8 read_nic_byte(struct net_device *dev, int x);
- +u8 read_nic_byte_E(struct net_device *dev, int x);
- +u32 read_nic_dword(struct net_device *dev, int x);
- +u16 read_nic_word(struct net_device *dev, int x) ;
- +void write_nic_byte(struct net_device *dev, int x,u8 y);
- +void write_nic_byte_E(struct net_device *dev, int x,u8 y);
- +void write_nic_word(struct net_device *dev, int x,u16 y);
- +void write_nic_dword(struct net_device *dev, int x,u32 y);
- +void force_pci_posting(struct net_device *dev);
- +
- +void rtl8180_rtx_disable(struct net_device *);
- +void rtl8180_rx_enable(struct net_device *);
- +void rtl8180_tx_enable(struct net_device *);
- +
- +void rtl8180_disassociate(struct net_device *dev);
- +//void fix_rx_fifo(struct net_device *dev);
- +void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
- +
- +void rtl8180_set_anaparam(struct net_device *dev,u32 a);
- +void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
- +void rtl8180_update_msr(struct net_device *dev);
- +int rtl8180_down(struct net_device *dev);
- +int rtl8180_up(struct net_device *dev);
- +void rtl8180_commit(struct net_device *dev);
- +void rtl8180_set_chan(struct net_device *dev,short ch);
- +void write_phy(struct net_device *dev, u8 adr, u8 data);
- +void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
- +void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
- +void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
- +void rtl8187_set_rxconf(struct net_device *dev);
- +bool MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource);
- +void IPSEnter(struct net_device *dev);
- +void IPSLeave(struct net_device *dev);
- +int r8187b_rfkill_init(struct net_device *dev);
- +void r8187b_rfkill_exit(void);
- +int r8187b_wifi_report_state(r8180_priv *priv);
- +void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet);
- +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
- +void rtl8180_patch_ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
- +#ifdef _RTL8187_EXT_PATCH_
- +extern int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
- +#endif
- +#ifdef JOHN_TKIP
- +void EnableHWSecurityConfig8187(struct net_device *dev);
- +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
- +
- +#endif
- +
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.c linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,1629 @@
- +/*++
- +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
- +
- +Module Name:
- + r8187_led.c
- +
- +Abstract:
- + RTL8187 LED control functions
- +
- +Major Change History:
- + When Who What
- + ---------- --------------- -------------------------------
- + 2006-09-07 Xiong Created
- +
- +Notes:
- +
- +--*/
- +
- +/*--------------------------Include File------------------------------------*/
- +#include "ieee80211/ieee80211.h"
- +#include "r8180_hw.h"
- +#include "r8187.h"
- +#include "r8180_93cx6.h"
- +#include "r8187_led.h"
- +
- +/**
- +*
- +* Initialization function for Sw Leds controll.
- +*
- +* \param dev The net device for this driver.
- +* \return void.
- +*
- +* Note:
- +*
- +*/
- +
- +void
- +InitSwLeds(
- + struct net_device *dev
- + )
- +{
- +
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u16 usValue;
- +// printk("========>%s()\n", __FUNCTION__);
- +
- +// priv->CustomerID = RT_CID_87B_DELL; //by lizhaoming for DELL 2008.6.3
- + priv->CustomerID = RT_CID_DEFAULT; //just set to default now
- + priv->bEnableLedCtrl = 1;
- + priv->PsrValue = read_nic_byte(dev, PSR);
- + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET >> 1);
- + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
- + DMESG("EEPROM Customer ID: %02X", priv->EEPROMCustomerID);
- +
- + if(priv->CustomerID == RT_CID_DEFAULT)
- + { // If we have not yet change priv->CustomerID in register,
- + // we initialzie it from that of EEPROM with proper translation, 2006.07.03, by rcnjko.
- + switch(priv->EEPROMCustomerID)
- + {
- + case EEPROM_CID_RSVD0:
- + case EEPROM_CID_RSVD1:
- + priv->CustomerID = RT_CID_DEFAULT;
- + break;
- +
- + case EEPROM_CID_ALPHA0:
- + priv->CustomerID = RT_CID_8187_ALPHA0;
- + break;
- +
- + case EEPROM_CID_SERCOMM_PS:
- + priv->CustomerID = RT_CID_8187_SERCOMM_PS;
- + break;
- +
- + case EEPROM_CID_HW_LED:
- + priv->CustomerID = RT_CID_8187_HW_LED;
- + break;
- +
- + case EEPROM_CID_QMI:
- + priv->CustomerID = RT_CID_87B_QMI;
- + break;
- +
- + case EEPROM_CID_DELL:
- + priv->CustomerID = RT_CID_87B_DELL;
- + break;
- +
- + default:
- + // Invalid value, so, we use default value instead.
- + priv->CustomerID = RT_CID_DEFAULT;
- + break;
- + }
- + }
- + switch(priv->CustomerID)
- + {
- + case RT_CID_DEFAULT:
- + priv->LedStrategy = SW_LED_MODE0;
- + break;
- +
- + case RT_CID_8187_ALPHA0:
- + priv->LedStrategy = SW_LED_MODE1;
- + break;
- +
- + case RT_CID_8187_SERCOMM_PS:
- + priv->LedStrategy = SW_LED_MODE3;
- + break;
- +
- + case RT_CID_87B_QMI:
- + priv->LedStrategy = SW_LED_MODE4;
- + break;
- +
- + case RT_CID_87B_DELL:
- + priv->LedStrategy = SW_LED_MODE5;
- + break;
- +
- + case RT_CID_8187_HW_LED:
- + priv->LedStrategy = HW_LED;
- + break;
- +
- + default:
- + priv->LedStrategy = SW_LED_MODE0;
- + break;
- + }
- +
- + InitLed8187(dev,
- + &(priv->Gpio0Led),
- + LED_PIN_GPIO0,
- + Gpio0LedBlinkTimerCallback);
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- + INIT_WORK(&priv->Gpio0LedWorkItem,
- + (void(*)(void*))Gpio0LedWorkItemCallback, dev);
- +
- + InitLed8187(dev,
- + &(priv->SwLed0),
- + LED_PIN_LED0,
- + SwLed0BlinkTimerCallback);
- + INIT_WORK(&priv->SwLed0WorkItem,
- + (void(*)(void*))SwLed0WorkItemCallback, dev);
- +
- + InitLed8187(dev,
- + &(priv->SwLed1),
- + LED_PIN_LED1,
- + SwLed1BlinkTimerCallback);
- + INIT_WORK(&priv->SwLed1WorkItem,
- + (void(*)(void*))SwLed1WorkItemCallback, dev);
- +#else
- +INIT_WORK(&priv->Gpio0LedWorkItem,
- + Gpio0LedWorkItemCallback);
- +
- + InitLed8187(dev,
- + &(priv->SwLed0),
- + LED_PIN_LED0,
- + SwLed0BlinkTimerCallback);
- + INIT_WORK(&priv->SwLed0WorkItem,
- + SwLed0WorkItemCallback);
- +
- + InitLed8187(dev,
- + &(priv->SwLed1),
- + LED_PIN_LED1,
- + SwLed1BlinkTimerCallback);
- + INIT_WORK(&priv->SwLed1WorkItem,
- + SwLed1WorkItemCallback);
- +#endif
- +}
- +
- +void
- +DeInitSwLeds(
- + struct net_device *dev
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +// printk("=========>%s In\n", __FUNCTION__);
- + DeInitLed8187(dev, &(priv->Gpio0Led));
- + DeInitLed8187(dev, &(priv->SwLed0));
- + DeInitLed8187(dev, &(priv->SwLed1));
- +}
- +
- +void
- +InitLed8187(
- + struct net_device *dev,
- + PLED_8187 pLed,
- + LED_PIN_8187 LedPin,
- + void * BlinkCallBackFunc)
- +{
- +// printk("=========>%s In\n", __FUNCTION__);
- + pLed->LedPin = LedPin;
- +
- + pLed->bLedOn = 0;
- + pLed->CurrLedState = LED_OFF;
- +
- + pLed->bLedBlinkInProgress = 0;
- + pLed->BlinkTimes = 0;
- + pLed->BlinkingLedState = LED_OFF;
- +
- + init_timer(&(pLed->BlinkTimer));
- + pLed->BlinkTimer.data = (unsigned long)dev;
- + pLed->BlinkTimer.function = BlinkCallBackFunc;
- + //PlatformInitializeTimer(dev, &(pLed->BlinkTimer), BlinkCallBackFunc);
- +}
- +
- +void
- +DeInitLed8187(
- + struct net_device *dev,
- + PLED_8187 pLed)
- +{
- + //printk("=========>%s In\n", __FUNCTION__);
- + //PlatformCancelTimer(dev, &(pLed->BlinkTimer));
- + del_timer_sync(&(pLed->BlinkTimer));
- + // We should reset bLedBlinkInProgress if we cancel the LedControlTimer, 2005.03.10, by rcnjko.
- + pLed->bLedBlinkInProgress = 0;
- +}
- +
- +void
- +LedControl8187(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +// printk("=========>%s In\n", __FUNCTION__);
- + if( priv->bEnableLedCtrl == 0)
- + return;
- +
- +
- + if( priv->eRFPowerState != eRfOn &&
- + (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
- + LedAction == LED_CTL_SITE_SURVEY ||
- + LedAction == LED_CTL_LINK ||
- + LedAction == LED_CTL_NO_LINK) )
- + {
- + return;
- + }
- +
- +
- + switch(priv->LedStrategy)
- + {
- + case SW_LED_MODE0:
- + SwLedControlMode0(dev, LedAction);
- + break;
- +
- + case SW_LED_MODE1:
- + SwLedControlMode1(dev, LedAction);
- + break;
- +
- + case SW_LED_MODE2:
- + SwLedControlMode2(dev, LedAction);
- + break;
- +
- + case SW_LED_MODE3:
- + SwLedControlMode3(dev, LedAction);
- + break;
- + case SW_LED_MODE4:
- + SwLedControlMode4(dev, LedAction);
- + break;
- +
- + case SW_LED_MODE5:
- + SwLedControlMode5(dev, LedAction);
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +
- +//
- +// Description:
- +// Implement each led action for SW_LED_MODE0.
- +// This is default strategy.
- +//
- +void
- +SwLedControlMode0(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + PLED_8187 pLed = &(priv->Gpio0Led);
- +
- +// printk("===+++++++++++++++======>%s In\n", __FUNCTION__);
- + // Decide led state
- + switch(LedAction)
- + {
- + case LED_CTL_TX:
- + case LED_CTL_RX:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->CurrLedState = LED_BLINK_NORMAL;
- + pLed->BlinkTimes = 2;
- + // printk("===========>LED_CTL_TX/RX \n");
- + }
- + else
- + {
- + return;
- + }
- + break;
- +
- + case LED_CTL_SITE_SURVEY:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->CurrLedState = LED_BLINK_SLOWLY;
- + // pLed->BlinkTimes = 10;
- + //printk("===========>LED_CTL_SURVEY \n");
- + }
- + else
- + {
- + return;
- + }
- + break;
- +
- + case LED_CTL_LINK:
- + // printk("===========>associate commplite LED_CTL_LINK\n");
- + pLed->CurrLedState = LED_ON;
- + break;
- +
- + case LED_CTL_NO_LINK:
- + pLed->CurrLedState = LED_OFF;
- + break;
- +
- + case LED_CTL_POWER_ON:
- + // printk("===========>LED_CTL_POWER_ON\n");
- + pLed->CurrLedState = LED_POWER_ON_BLINK;
- + break;
- +
- + case LED_CTL_POWER_OFF:
- + pLed->CurrLedState = LED_OFF;
- + break;
- +
- + default:
- + return;
- + break;
- + }
- +
- + // Change led state.
- + switch(pLed->CurrLedState)
- + {
- + case LED_ON:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + SwLedOn(dev, pLed);
- + }
- + break;
- +
- + case LED_OFF://modified by lizhaoming 2008.6.23
- + // if( pLed->bLedBlinkInProgress == 0 )
- + // {
- + // SwLedOff(dev, pLed);
- + // }
- +
- + if(pLed->bLedBlinkInProgress )/////////lizhaoming
- + {
- + del_timer_sync(&(pLed->BlinkTimer));
- + pLed->bLedBlinkInProgress = FALSE;
- + }
- + SwLedOff(dev, pLed);
- + break;
- +
- + case LED_BLINK_NORMAL:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- + if( pLed->bLedOn )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + }
- + break;
- +
- + case LED_BLINK_SLOWLY:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + //printk("=======>%s SLOWLY\n", __func__);
- + pLed->bLedBlinkInProgress = 1;
- + // if( pLed->bLedOn )
- + pLed->BlinkingLedState = LED_OFF;//for LED_SHIN is LED on
- + // else
- + // pLed->BlinkingLedState = LED_ON;
- +
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- + }
- + break;
- +
- + case LED_POWER_ON_BLINK:
- + SwLedOn(dev, pLed);
- +#ifdef LED_SHIN
- + mdelay(100);
- + SwLedOff(dev, pLed);
- +#endif
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +//
- +// Description:
- +// Implement each led action for SW_LED_MODE1.
- +// For example, this is applied by ALPHA.
- +//
- +void
- +SwLedControlMode1(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + PLED_8187 pLed0 = &(priv->SwLed0);
- + PLED_8187 pLed1 = &(priv->SwLed1);
- +// printk("=====++++++++++++++++++++++====>%s In\n", __FUNCTION__);
- +
- + switch(LedAction)
- + {
- + case LED_CTL_TX:
- + if( pLed0->bLedBlinkInProgress == 0 )
- + {
- + pLed0->CurrLedState = LED_BLINK_NORMAL;
- + pLed0->BlinkTimes = 2;
- + pLed0->bLedBlinkInProgress = 1;
- + if( pLed0->bLedOn )
- + pLed0->BlinkingLedState = LED_OFF;
- + else
- + pLed0->BlinkingLedState = LED_ON;
- +
- + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed0->BlinkTimer));
- + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + }
- + break;
- +
- + case LED_CTL_LINK:
- + pLed0->CurrLedState = LED_ON;
- + if( pLed0->bLedBlinkInProgress == 0 )
- + {
- + SwLedOn(dev, pLed0);
- + }
- + break;
- +
- + case LED_CTL_NO_LINK:
- + pLed0->CurrLedState = LED_OFF;
- + if( pLed0->bLedBlinkInProgress == 0 )
- + {
- + SwLedOff(dev, pLed0);
- + }
- + break;
- +
- + case LED_CTL_POWER_ON:
- + pLed0->CurrLedState = LED_OFF;
- + SwLedOff(dev, pLed0);
- +
- + pLed1->CurrLedState = LED_ON;
- + SwLedOn(dev, pLed1);
- +
- + break;
- +
- + case LED_CTL_POWER_OFF:
- + pLed0->CurrLedState = LED_OFF;
- + SwLedOff(dev, pLed0);
- +
- + pLed1->CurrLedState = LED_OFF;
- + SwLedOff(dev, pLed1);
- + break;
- +
- + case LED_CTL_SITE_SURVEY:
- + if( pLed0->bLedBlinkInProgress == 0 )
- + {
- + pLed0->CurrLedState = LED_BLINK_SLOWLY;;
- + pLed0->BlinkTimes = 10;
- + pLed0->bLedBlinkInProgress = 1;
- + if( pLed0->bLedOn )
- + pLed0->BlinkingLedState = LED_OFF;
- + else
- + pLed0->BlinkingLedState = LED_ON;
- +
- + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
- + //add_timer(&(pLed0->BlinkTimer));
- + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- + }
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +//
- +// Description:
- +// Implement each led action for SW_LED_MODE2,
- +// which is customized for AzWave 8187 minicard.
- +// 2006.04.03, by rcnjko.
- +//
- +void
- +SwLedControlMode2(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + PLED_8187 pLed = &(priv->Gpio0Led);
- +
- +// printk("====+++++++++++++++++++++=====>%s In\n", __FUNCTION__);
- + // Decide led state
- + switch(LedAction)
- + {
- + case LED_CTL_TX:
- + case LED_CTL_RX:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- +
- + pLed->CurrLedState = LED_BLINK_NORMAL;
- + pLed->BlinkTimes = 2;
- +
- + if( pLed->bLedOn )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + }
- + break;
- +
- + case LED_CTL_SITE_SURVEY:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- +
- + //if( dev->MgntInfo.mAssoc ||
- + // dev->MgntInfo.mIbss )
- + //{
- + pLed->CurrLedState = LED_SCAN_BLINK;
- + pLed->BlinkTimes = 4;
- + //}
- + //else
- + //{
- + // pLed->CurrLedState = LED_NO_LINK_BLINK;
- + // pLed->BlinkTimes = 24;
- + //}
- +
- + if( pLed->bLedOn )
- + {
- + pLed->BlinkingLedState = LED_OFF;
- + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
- + }
- + else
- + {
- + pLed->BlinkingLedState = LED_ON;
- + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
- + }
- + }
- + else
- + {
- + if(pLed->CurrLedState != LED_NO_LINK_BLINK)
- + {
- + pLed->CurrLedState = LED_SCAN_BLINK;
- + /*
- + if( dev->MgntInfo.mAssoc ||
- + dev->MgntInfo.mIbss )
- + {
- + pLed->CurrLedState = LED_SCAN_BLINK;
- + }
- + else
- + {
- + pLed->CurrLedState = LED_NO_LINK_BLINK;
- + }
- + */
- + }
- + }
- + break;
- +
- + case LED_CTL_NO_LINK:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- +
- + pLed->CurrLedState = LED_NO_LINK_BLINK;
- + pLed->BlinkTimes = 24;
- +
- + if( pLed->bLedOn )
- + {
- + pLed->BlinkingLedState = LED_OFF;
- + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
- + }
- + else
- + {
- + pLed->BlinkingLedState = LED_ON;
- + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
- + }
- + }
- + else
- + {
- + pLed->CurrLedState = LED_NO_LINK_BLINK;
- + }
- + break;
- +
- + case LED_CTL_LINK:
- + pLed->CurrLedState = LED_ON;
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + SwLedOn(dev, pLed);
- + }
- + break;
- +
- + case LED_CTL_POWER_OFF:
- + pLed->CurrLedState = LED_OFF;
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + SwLedOff(dev, pLed);
- + }
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +
- +//
- +// Description:
- +// Implement each led action for SW_LED_MODE3,
- +// which is customized for Sercomm Printer Server case.
- +// 2006.04.21, by rcnjko.
- +//
- +void
- +SwLedControlMode3(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + PLED_8187 pLed = &(priv->Gpio0Led);
- +
- +// printk("=====+++++++++++++++++++====>%s In\n", __FUNCTION__);
- + // Decide led state
- + switch(LedAction)
- + {
- + case LED_CTL_TX:
- + case LED_CTL_RX:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- +
- + pLed->CurrLedState = LED_BLINK_CM3;
- + pLed->BlinkTimes = 2;
- +
- + if( pLed->bLedOn )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
- + }
- + break;
- +
- + case LED_CTL_SITE_SURVEY:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- +
- + pLed->CurrLedState = LED_BLINK_CM3;
- + pLed->BlinkTimes = 10;
- +
- + if( pLed->bLedOn )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
- + }
- + break;
- +
- + case LED_CTL_LINK:
- + pLed->CurrLedState = LED_ON;
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + SwLedOn(dev, pLed);
- + }
- + break;
- +
- + case LED_CTL_NO_LINK:
- + pLed->CurrLedState = LED_OFF;
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + SwLedOff(dev, pLed);
- + }
- + break;
- +
- + case LED_CTL_POWER_ON:
- + pLed->CurrLedState = LED_POWER_ON_BLINK;
- + SwLedOn(dev, pLed);
- + mdelay(100);
- + SwLedOff(dev, pLed);
- + break;
- +
- + case LED_CTL_POWER_OFF:
- + pLed->CurrLedState = LED_OFF;
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + SwLedOff(dev, pLed);
- + }
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +// added by lizhaoming 2008.6.2
- +//
- +// Description:
- +// Implement each led action for SW_LED_MODE4,
- +// which is customized for QMI 8187B minicard.
- +// 2008.04.21, by chiyokolin.
- +//
- +void
- +SwLedControlMode4(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + PLED_8187 pLed = &(priv->Gpio0Led);
- +
- + //printk("=====+++++++++++++++++++++====>%s In\n", __FUNCTION__);
- + // Decide led state
- + switch(LedAction)
- + {
- + case LED_CTL_TX:
- + case LED_CTL_RX:
- + //if( pLed->bLedBlinkInProgress == false && !priv->bScanInProgress)//?????
- + if( pLed->bLedBlinkInProgress == 0)
- + {
- + pLed->bLedBlinkInProgress = 1;
- +
- + pLed->CurrLedState = LED_BLINK_NORMAL;
- + pLed->BlinkTimes = 2;
- +
- + if( pLed->bLedOn )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + }
- + else
- + //printk("----->LED_CTL_RX/TX bLedBlinkInProgress\n");
- +
- + break;
- +
- + case LED_CTL_SITE_SURVEY:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- +
- + pLed->bLedBlinkInProgress = 1;
- + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//////////??????
- + //{
- + pLed->CurrLedState = LED_SCAN_BLINK;
- + pLed->BlinkTimes = 10;
- +
- + pLed->BlinkingLedState = LED_ON;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + //}
- + //else
- + //{
- + // pLed->CurrLedState = LED_NO_LINK_BLINK;
- + // pLed->BlinkTimes = 24;
- + //
- + // if( pLed->bLedOn )
- + // {
- + // pLed->BlinkingLedState = LED_OFF;
- + //
- + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
- + // add_timer(&(pLed->BlinkTimer));
- + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
- + // }
- + // else
- + // {
- + // pLed->BlinkingLedState = LED_ON;
- +
- + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
- + // add_timer(&(pLed->BlinkTimer));
- + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
- + // }
- + //}
- + }
- + else
- + {
- + if(pLed->CurrLedState != LED_NO_LINK_BLINK)
- + {
- + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//???????????
- + //{
- + //}
- + //else
- + //{
- + // pLed->CurrLedState = LED_NO_LINK_BLINK;
- + //}
- + }
- +
- + //printk("----->LED_CTL_SITE_SURVEY bLedBlinkInProgress\n");
- + }
- + break;
- +
- + case LED_CTL_NO_LINK:
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- +
- + pLed->CurrLedState = LED_NO_LINK_BLINK;
- + pLed->BlinkTimes = 24;
- +
- + if( pLed->bLedOn )
- + {
- + pLed->BlinkingLedState = LED_OFF;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
- + }
- + else
- + {
- + pLed->BlinkingLedState = LED_ON;
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
- + }
- + }
- + else
- + {
- + pLed->CurrLedState = LED_NO_LINK_BLINK;
- + //printk("----->LED_CTL_NO_LINK bLedBlinkInProgress\n");
- + }
- + break;
- +
- + case LED_CTL_LINK:
- + pLed->CurrLedState = LED_ON;
- + if( pLed->bLedBlinkInProgress == 0)
- + {
- + SwLedOn(dev, pLed);
- + }
- + else
- + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
- +
- + break;
- +
- + case LED_CTL_POWER_OFF:
- + pLed->CurrLedState = LED_OFF;
- + if(pLed->bLedBlinkInProgress)
- + {
- + printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
- +
- + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
- + del_timer_sync(&(pLed->BlinkTimer));
- + pLed->bLedBlinkInProgress = 0;
- + }
- + SwLedOff(dev, pLed);
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +
- +
- +//added by lizhaoming 2008.6.3
- +//
- +// Description:
- +// Implement each led action for SW_LED_MODE5,
- +// which is customized for DELL 8187B minicard.
- +// 2008.04.24, by chiyokolin.
- +//
- +void
- +SwLedControlMode5(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + PLED_8187 pLed = &(priv->Gpio0Led);
- +
- + // Decide led state
- + //printk("====++++++++++++++++++++++=====>%s In\n", __FUNCTION__);
- + switch(LedAction)
- + {
- + case LED_CTL_TX:
- + case LED_CTL_RX:
- + case LED_CTL_SITE_SURVEY:
- + case LED_CTL_POWER_ON:
- + case LED_CTL_NO_LINK:
- + case LED_CTL_LINK:
- + pLed->CurrLedState = LED_ON;
- + if( pLed->bLedBlinkInProgress == 0 )
- + {
- + pLed->bLedBlinkInProgress = 1;
- + if(! pLed->bLedOn )
- + pLed->BlinkingLedState = LED_ON;
- + else
- + break;
- +
- + //printk("====++++++++++++++++++++++=====>%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + // SwLedOn(dev, pLed);
- + }
- + else
- + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
- +
- + break;
- +
- + case LED_CTL_POWER_OFF:
- + pLed->CurrLedState = LED_OFF;
- + // printk("<====++++++++++++++++++++++=====%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
- + if(pLed->bLedBlinkInProgress)
- + {
- + // printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
- +
- + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
- + del_timer_sync(&(pLed->BlinkTimer));
- + pLed->bLedBlinkInProgress = 0;
- + }
- + SwLedOff(dev, pLed);
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +//
- +// Callback fuction of the timer, Gpio0Led.BlinkTimer.
- +//
- +void
- +Gpio0LedBlinkTimerCallback(
- + unsigned long data
- + )
- +{
- + struct net_device *dev = (struct net_device *)data;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +// printk("=========>%s In\n", __FUNCTION__);
- + PlatformSwLedBlink(dev, &(priv->Gpio0Led));
- +}
- +
- +
- +
- +//
- +// Callback fuction of the timer, SwLed0.BlinkTimer.
- +//
- +void
- +SwLed0BlinkTimerCallback(
- + unsigned long data
- + )
- +{
- + struct net_device *dev = (struct net_device *)data;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +// printk("=========>%s In\n", __FUNCTION__);
- + PlatformSwLedBlink(dev, &(priv->SwLed0));
- +}
- +
- +
- +
- +//
- +// Callback fuction of the timer, SwLed1.BlinkTimer.
- +//
- +void
- +SwLed1BlinkTimerCallback(
- + unsigned long data
- + )
- +{
- + struct net_device *dev = (struct net_device *)data;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +// printk("=========>%s In\n", __FUNCTION__);
- + PlatformSwLedBlink(dev, &(priv->SwLed1));
- +}
- +
- +void
- +PlatformSwLedBlink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +// printk("=========>%s In\n", __FUNCTION__);
- + switch(pLed->LedPin)
- + {
- + case LED_PIN_GPIO0:
- + schedule_work(&(priv->Gpio0LedWorkItem));
- + break;
- +
- + case LED_PIN_LED0:
- + schedule_work(&(priv->SwLed0WorkItem));
- + break;
- +
- + case LED_PIN_LED1:
- + schedule_work(&(priv->SwLed1WorkItem));
- + break;
- +
- + default:
- + break;
- + }
- +}
- +
- +//
- +// Callback fucntion of the workitem for SW LEDs.
- +// 2006.03.01, by rcnjko.
- +//
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +void Gpio0LedWorkItemCallback(struct work_struct *work)
- +{
- + struct r8180_priv *priv = container_of(work, struct r8180_priv,Gpio0LedWorkItem);
- + struct net_device *dev = priv->ieee80211->dev;
- +#else
- +void
- +Gpio0LedWorkItemCallback(
- + void * Context
- + )
- +{
- + struct net_device *dev = (struct net_device *)Context;
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +#endif
- + PLED_8187 pLed = &(priv->Gpio0Led);
- + if (priv == NULL || dev == NULL){
- +// printk("=========>%s In\n", __FUNCTION__);
- + //printk("ft=====================>%s()\n", __FUNCTION__);
- + }
- +
- +#if 0 // by lizahoming 2008.6.3
- + if(priv->LedStrategy == SW_LED_MODE2)
- + SwLedCm2Blink(dev, pLed);
- + else
- + SwLedBlink(dev, pLed);
- +#endif
- +
- +#if 1 // by lizahoming 2008.6.3
- + switch(priv->LedStrategy)
- + {
- + case SW_LED_MODE2:
- + SwLedCm2Blink(dev, pLed);
- + break;
- + case SW_LED_MODE4:
- + SwLedCm4Blink(dev, pLed);
- + break;
- + default:
- + SwLedBlink(dev, pLed);
- + break;
- + }
- +#endif
- +
- + //LeaveCallbackOfRtWorkItem( &(usbdevice->Gpio0LedWorkItem) );
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +void SwLed0WorkItemCallback(struct work_struct *work)
- +{
- + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed0WorkItem);
- + //struct net_device *dev = priv->dev;
- +#else
- +void SwLed0WorkItemCallback(void * Context)
- +{
- + //struct net_device *dev = (struct net_device *)Context;
- + //struct r8180_priv *priv = ieee80211_priv(dev);
- +#endif
- + //SwLedBlink(dev, &(priv->SwLed0));
- +// printk("=========>%s In\n", __FUNCTION__);
- +
- + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed0WorkItem) );
- +}
- +
- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
- +void SwLed1WorkItemCallback(struct work_struct *work)
- +{
- + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed1WorkItem);
- +// struct net_device *dev = priv->dev;
- +#else
- +void
- +SwLed1WorkItemCallback(
- + void * Context
- + )
- +{
- + //struct net_device *dev = (struct net_device *)Context;
- + //struct r8180_priv *priv = ieee80211_priv(dev);
- +#endif
- +// printk("=========>%s In\n", __FUNCTION__);
- + //SwLedBlink(dev, &(priv->SwLed1));
- +
- + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed1WorkItem) );
- +}
- +
- +//
- +// Implementation of LED blinking behavior.
- +// It toggle off LED and schedule corresponding timer if necessary.
- +//
- +void
- +SwLedBlink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + )
- +{
- + u8 bStopBlinking = 0;
- +
- + //printk("=========>%s In state:%d\n", __FUNCTION__, pLed->CurrLedState);
- + // Change LED according to BlinkingLedState specified.
- + if( pLed->BlinkingLedState == LED_ON )
- + {
- + SwLedOn(dev, pLed);
- +// printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- + }
- + else
- + {
- + SwLedOff(dev, pLed);
- +// printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- + }
- +
- + // Determine if we shall change LED state again.
- +//by lizhaoming for LED BLINK SLOWLY
- + if(pLed->CurrLedState == LED_BLINK_SLOWLY)
- + {
- + bStopBlinking = 0;
- + } else {
- + pLed->BlinkTimes--;
- + if( pLed->BlinkTimes == 0 )
- + {
- + bStopBlinking = 1;
- + }
- + else
- + {
- + if( pLed->CurrLedState != LED_BLINK_NORMAL &&
- + pLed->CurrLedState != LED_BLINK_SLOWLY &&
- + pLed->CurrLedState != LED_BLINK_CM3 )
- + {
- + bStopBlinking = 1;
- + }
- + }
- + }
- +
- + if(bStopBlinking)
- + {
- + if( pLed->CurrLedState == LED_ON && pLed->bLedOn == 0)
- + {
- + SwLedOn(dev, pLed);
- + }
- + else if(pLed->CurrLedState == LED_OFF && pLed->bLedOn == 1)
- + {
- + SwLedOff(dev, pLed);
- + }
- +
- + pLed->BlinkTimes = 0;
- + pLed->bLedBlinkInProgress = 0;
- + }
- + else
- + {
- + // Assign LED state to toggle.
- + if( pLed->BlinkingLedState == LED_ON )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + // Schedule a timer to toggle LED state.
- + switch( pLed->CurrLedState )
- + {
- + case LED_BLINK_NORMAL:
- + //printk("LED_BLINK_NORMAL:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + break;
- +
- + case LED_BLINK_SLOWLY:
- + if( pLed->bLedOn == 1 )
- + {
- + //printk("LED_BLINK_SLOWLY:turn off\n");
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL+50;//for pcie mini card spec page 33, 250ms
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL+50));
- + pLed->BlinkingLedState = LED_OFF;
- + } else {
- + //printk("LED_BLINK_SLOWLY:turn on\n");
- + //pLed->BlinkTimer.expires = jiffies + 5000;//for pcie mini card spec page 33, 5s
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(5000));
- + pLed->BlinkingLedState = LED_ON;
- + }
- + break;
- +
- + case LED_BLINK_CM3:
- + //printk("LED_BLINK_CM3:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
- + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
- + break;
- +
- + default:
- + //printk("LED_BLINK_default:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- + break;
- + }
- + }
- +}
- +
- +
- +
- +//
- +// Implementation of LED blinking behavior for SwLedControlMode2.
- +//
- +void
- +SwLedCm2Blink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + //PMGNT_INFO priv = &(dev->MgntInfo);
- + u8 bStopBlinking = 0;
- +
- + //printk("========+++++++++++++=>%s In\n", __FUNCTION__);
- + //To avoid LED blinking when rf is off, add by lizhaoming 2008.6.2
- + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
- + {
- + SwLedOff(dev, pLed);
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
- + //printk(" Hw/Soft Radio Off, turn off Led\n");
- + return;
- + }
- +
- + // Change LED according to BlinkingLedState specified.
- + if( pLed->BlinkingLedState == LED_ON )
- + {
- + SwLedOn(dev, pLed);
- + //DMESG("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- + }
- + else
- + {
- + SwLedOff(dev, pLed);
- + //DMESG("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- + }
- +
- + //Add by lizhaoming for avoid BlinkTimers <0, 2008.6.2
- + if(pLed->BlinkTimes > 0)
- + {//by lizhaoming 2008.6.2
- + // Determine if we shall change LED state again.
- + pLed->BlinkTimes--;
- + }//by lizhaoming 2008.6.2
- +
- + switch(pLed->CurrLedState)
- + {
- + case LED_BLINK_NORMAL:
- + if(pLed->BlinkTimes == 0)
- + {
- + bStopBlinking = 1;
- + }
- + break;
- +/* CM2 scan blink and no link blind now not be supported
- + case LED_SCAN_BLINK:
- + if( (priv->mAssoc || priv->mIbss) && // Linked.
- + (!priv->bScanInProgress) && // Not in scan stage.
- + (pLed->BlinkTimes % 2 == 0)) // Even
- + {
- + bStopBlinking = 1;
- + }
- + break;
- +
- + case LED_NO_LINK_BLINK:
- + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
- + //if( (priv->mAssoc || priv->mIbss) ) // Linked.
- + if( priv->mAssoc)
- + {
- + bStopBlinking = 1;
- + }
- + else if(priv->mIbss && priv->bMediaConnect )
- + {
- + bStopBlinking = 1;
- + }
- + break;
- +*/
- + default:
- + bStopBlinking = 1;
- + break;
- + }
- +
- + if(bStopBlinking)
- + {
- +/*
- + if( priv->eRFPowerState != eRfOn )
- + {
- + SwLedOff(dev, pLed);
- + }
- + else if( priv->bMediaConnect == 1 && pLed->bLedOn == 0)
- + {
- + SwLedOn(dev, pLed);
- + }
- + else if( priv->bMediaConnect == 0 && pLed->bLedOn == 1)
- + {
- + SwLedOff(dev, pLed);
- + }
- +*/
- + pLed->BlinkTimes = 0;
- + pLed->bLedBlinkInProgress = 0;
- + }
- + else
- + {
- + // Assign LED state to toggle.
- + if( pLed->BlinkingLedState == LED_ON )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + // Schedule a timer to toggle LED state.
- + switch( pLed->CurrLedState )
- + {
- + case LED_BLINK_NORMAL:
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + break;
- +
- + case LED_BLINK_SLOWLY:
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- + break;
- +
- + case LED_SCAN_BLINK:
- + case LED_NO_LINK_BLINK:
- + if( pLed->bLedOn ) {
- + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
- + } else {
- + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
- + }
- + break;
- +
- + default:
- + //RT_ASSERT(0, ("SwLedCm2Blink(): unexpected state!\n"));
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- + break;
- + }
- + }
- +}
- +
- +// added by lizhaoming 2008.6.2
- +//
- +// Description:
- +// Implement LED blinking behavior for SW_LED_MODE4.
- +//
- +void
- +SwLedCm4Blink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + )
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- + u8 bStopBlinking = 0;
- +
- + printk("======++++++++++++++++++======>%s In\n", __FUNCTION__);
- + //To avoid LED blinking when rf is off, add by Maddest 20080307
- + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
- + {
- + SwLedOff(dev, pLed);
- +
- + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
- + printk(" Hw/Soft Radio Off, turn off Led\n");
- + return;
- + }
- + // Change LED according to BlinkingLedState specified.
- + if( pLed->BlinkingLedState == LED_ON )
- + {
- + if(!pLed->bLedOn)
- + {
- + SwLedOn(dev, pLed);
- + }
- + printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
- + }
- + else
- + {
- + SwLedOff(dev, pLed);
- + printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
- + }
- +
- + //Add by Maddest for avoid BlinkTimers <0, 20080307;
- + if(pLed->BlinkTimes > 0)
- + {
- + // Determine if we shall change LED state again.
- + pLed->BlinkTimes--;
- + }
- + printk("pLed->CurrLedState %d pLed->BlinkTimes %d\n", pLed->CurrLedState,pLed->BlinkTimes);
- + switch(pLed->CurrLedState)
- + {
- + case LED_BLINK_NORMAL:
- + if(pLed->BlinkTimes == 0)
- + {
- + bStopBlinking = 1;
- + }
- + break;
- +
- +/* CM2 scan blink and no link blind now not be supported
- + case LED_SCAN_BLINK:
- + if( (priv->mAssoc || priv->mIbss) && // Linked.//????????????
- + (!priv->bScanInProgress) && // Not in scan stage.//????????????
- + (pLed->BlinkTimes % 2 == 0)) // Even
- + {
- + bStopBlinking = 1;
- + }
- + break;
- +
- + case LED_NO_LINK_BLINK:
- + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
- + //if( (pMgntInfo->mAssoc || pMgntInfo->mIbss) ) // Linked.
- + if( priv->mAssoc) //????????????
- + {
- + bStopBlinking = 1;
- + }
- + else if(priv->mIbss && priv->bMediaConnect )//????????????
- + {
- + bStopBlinking = 1;
- + }
- + break;
- +*/
- +
- + default:
- + bStopBlinking = 1;
- + break;
- + }
- +
- + if(bStopBlinking)
- + {
- + /*
- + if( priv->eRFPowerState != eRfOn )
- + {
- + SwLedOff(dev, pLed);
- + }
- + else if( priv->bMediaConnect == true && pLed->bLedOn == false)//????????????
- + {
- + SwLedOn(dev, pLed);
- + }
- + else if( priv->bMediaConnect == false && pLed->bLedOn == true)//????????????
- + {
- + SwLedOff(dev, pLed);
- + }
- + */
- +
- + pLed->BlinkTimes = 0;
- + pLed->bLedBlinkInProgress = 0;
- + }
- + else
- + {
- + // Assign LED state to toggle.
- + if( pLed->BlinkingLedState == LED_ON )
- + pLed->BlinkingLedState = LED_OFF;
- + else
- + pLed->BlinkingLedState = LED_ON;
- +
- + // Schedule a timer to toggle LED state.
- + switch( pLed->CurrLedState )
- + {
- + case LED_BLINK_NORMAL:
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- + break;
- +
- + case LED_BLINK_SLOWLY:
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- + break;
- +
- + case LED_SCAN_BLINK:
- + pLed->BlinkingLedState = LED_ON;
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- +
- + case LED_NO_LINK_BLINK:
- + if( pLed->bLedOn ){
- + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
- + }else{
- + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
- + }
- + break;
- +
- + default:
- + printk("SwLedCm2Blink(): unexpected state!\n");
- + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
- + //add_timer(&(pLed->BlinkTimer));
- + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
- + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- + break;
- + }
- + }
- +}
- +
- +void
- +SwLedOn(
- + struct net_device *dev,
- + PLED_8187 pLed
- +)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +// printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
- + switch(pLed->LedPin)
- + {
- + case LED_PIN_GPIO0:
- + write_nic_byte(dev,0x0091,0x01);
- + write_nic_byte(dev,0x0090,0x00); // write 0 : LED on
- + break;
- +
- + case LED_PIN_LED0:
- + priv->PsrValue &= ~(0x01 << 4);
- + write_nic_byte(dev, PSR, priv->PsrValue);
- + break;
- +
- + case LED_PIN_LED1:
- + priv->PsrValue &= ~(0x01 << 5);
- + write_nic_byte(dev, PSR, priv->PsrValue);
- + break;
- +
- + default:
- + break;
- + }
- +
- + pLed->bLedOn = 1;
- +}
- +
- +void
- +SwLedOff(
- + struct net_device *dev,
- + PLED_8187 pLed
- +)
- +{
- + struct r8180_priv *priv = ieee80211_priv(dev);
- +
- +
- + //printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
- + switch(pLed->LedPin)
- + {
- + case LED_PIN_GPIO0:
- + write_nic_byte(dev,0x0091,0x01);
- + write_nic_byte(dev,0x0090,0x01); // write 1 : LED off
- + break;
- +
- + case LED_PIN_LED0:
- + priv->PsrValue |= (0x01 << 4);
- + write_nic_byte(dev, PSR, priv->PsrValue);
- + break;
- +
- + case LED_PIN_LED1:
- + priv->PsrValue |= (0x01 << 5);
- + write_nic_byte(dev, PSR, priv->PsrValue);
- + break;
- +
- + default:
- + break;
- + }
- +
- + pLed->bLedOn = 0;
- +}
- +
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.h linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.h
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_led.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_led.h 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,276 @@
- +/*++
- +
- +Copyright (c) Microsoft Corporation. All rights reserved.
- +
- +Module Name:
- + r8187_led.h
- +
- +Abstract:
- + definitions and stuctures for rtl8187 led control.
- +
- +Major Change History:
- + When Who What
- + ---------- ------ ----------------------------------------------
- + 2006-09-07 Xiong Created
- +
- +Notes:
- +
- +--*/
- +
- +#ifndef R8187_LED_H
- +#define R8187_LED_H
- +
- +#include <linux/types.h>
- +#include <linux/timer.h>
- +
- +
- +/*--------------------------Define -------------------------------------------*/
- +//
- +// 0x7E-0x7F is reserved for SW customization. 2006.04.21, by rcnjko.
- +//
- +// BIT[0-7] is for CustomerID where value 0x00 and 0xFF is reserved for Realtek.
- +#define EEPROM_SW_REVD_OFFSET 0x7E
- +
- +#define EEPROM_CID_MASK 0x00FF
- +#define EEPROM_CID_RSVD0 0x00
- +#define EEPROM_CID_RSVD1 0xFF
- +#define EEPROM_CID_ALPHA0 0x01
- +#define EEPROM_CID_SERCOMM_PS 0x02
- +#define EEPROM_CID_HW_LED 0x03
- +
- +#define EEPROM_CID_QMI 0x07 //Added by lizhaoming 2008.6.3
- +#define EEPROM_CID_DELL 0x08 //Added by lizhaoming 2008.6.3
- +
- +#define LED_BLINK_NORMAL_INTERVAL 100 //by lizhaoming 50 -> 100
- +#define LED_BLINK_SLOWLY_INTERVAL 200
- +
- +// Customized for AzWave, 2006.04.03, by rcnjko.
- +#define LED_CM2_BLINK_ON_INTERVAL 250
- +#define LED_CM2_BLINK_OFF_INTERVAL 4750
- +//
- +
- +// Customized for Sercomm Printer Server case, 2006.04.21, by rcnjko.
- +#define LED_CM3_BLINK_INTERVAL 1500
- +
- +// by lizhaoming 2008.6.3: Customized for QMI.
- +//
- +#define LED_CM4_BLINK_ON_INTERVAL 500
- +#define LED_CM4_BLINK_OFF_INTERVAL 4500
- +
- +
- +/*--------------------------Define MACRO--------------------------------------*/
- +
- +
- +/*------------------------------Define Struct---------------------------------*/
- +typedef enum _LED_STATE_8187{
- + LED_UNKNOWN = 0,
- + LED_ON = 1,
- + LED_OFF = 2,
- + LED_BLINK_NORMAL = 3,
- + LED_BLINK_SLOWLY = 4,
- + LED_POWER_ON_BLINK = 5,
- + LED_SCAN_BLINK = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning.
- + LED_NO_LINK_BLINK = 7, // LED is blinking during no link state.
- + LED_BLINK_CM3 = 8, // Customzied for Sercomm Printer Server case
- +}LED_STATE_8187;
- +
- +typedef enum _RT_CID_TYPE {
- + RT_CID_DEFAULT,
- + RT_CID_8187_ALPHA0,
- + RT_CID_8187_SERCOMM_PS,
- + RT_CID_8187_HW_LED,
- +
- + RT_CID_87B_QMI , //Added by lizhaoming 2008.6.3
- + RT_CID_87B_DELL, //Added by lizhaoming 2008.6.3
- +
- +} RT_CID_TYPE;
- +
- +typedef enum _LED_STRATEGY_8187{
- + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option.
- + SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA.
- + SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard.
- + SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case.
- + SW_LED_MODE4, //added by lizhaoming for bluetooth 2008.6.3
- + SW_LED_MODE5, //added by lizhaoming for bluetooth 2008.6.3
- + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.)
- +}LED_STRATEGY_8187, *PLED_STRATEGY_8187;
- +
- +typedef enum _LED_PIN_8187{
- + LED_PIN_GPIO0,
- + LED_PIN_LED0,
- + LED_PIN_LED1
- +}LED_PIN_8187;
- +
- +//by lizhaoming for LED 2008.6.23 into ieee80211.h
- +//typedef enum _LED_CTL_MODE {
- +// LED_CTL_POWER_ON,
- +// LED_CTL_POWER_OFF,
- +// LED_CTL_LINK,
- +// LED_CTL_NO_LINK,
- +// LED_CTL_TX,
- +// LED_CTL_RX,
- +// LED_CTL_SITE_SURVEY,
- +//} LED_CTL_MODE;
- +
- +typedef struct _LED_8187{
- + LED_PIN_8187 LedPin; // Identify how to implement this SW led.
- +
- + LED_STATE_8187 CurrLedState; // Current LED state.
- + u8 bLedOn; // TRUE if LED is ON, FALSE if LED is OFF.
- +
- + u8 bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w..
- + u32 BlinkTimes; // Number of times to toggle led state for blinking.
- + LED_STATE_8187 BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are.
- + struct timer_list BlinkTimer; // Timer object for led blinking.
- +} LED_8187, *PLED_8187;
- +
- +
- +
- +/*------------------------Export global variable------------------------------*/
- +
- +
- +/*------------------------------Funciton declaration--------------------------*/
- +void
- +InitSwLeds(
- + struct net_device *dev
- + );
- +
- +void
- +DeInitSwLeds(
- + struct net_device *dev
- + );
- +
- +void
- +InitLed8187(
- + struct net_device *dev,
- + PLED_8187 pLed,
- + LED_PIN_8187 LedPin,
- + void * BlinkCallBackFunc);
- +
- +void
- +DeInitLed8187(
- + struct net_device *dev,
- + PLED_8187 pLed);
- +
- +void
- +LedControl8187(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +);
- +
- +void
- +SwLedControlMode0(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +);
- +
- +void
- +SwLedControlMode1(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +);
- +
- +void
- +SwLedControlMode2(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +);
- +
- +void
- +SwLedControlMode3(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +);
- +
- +
- +void
- +SwLedControlMode4(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +);
- +
- +
- +void
- +SwLedControlMode5(
- + struct net_device *dev,
- + LED_CTL_MODE LedAction
- +);
- +
- +void
- +Gpio0LedBlinkTimerCallback(
- + unsigned long data
- + );
- +
- +void
- +SwLed0BlinkTimerCallback(
- + unsigned long data
- + );
- +
- +void
- +SwLed1BlinkTimerCallback(
- + unsigned long data
- + );
- +
- +void
- +PlatformSwLedBlink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + );
- +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- +void
- +Gpio0LedWorkItemCallback(
- + void * Context
- + );
- +
- +void
- +SwLed0WorkItemCallback(
- + void * Context
- + );
- +
- +void
- +SwLed1WorkItemCallback(
- + void * Context
- + );
- +#else
- +void
- +Gpio0LedWorkItemCallback(struct work_struct *work);
- +
- +void
- +SwLed0WorkItemCallback(struct work_struct *work);
- +
- +void
- +SwLed1WorkItemCallback(struct work_struct *work);
- +
- +#endif
- +void
- +SwLedBlink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + );
- +
- +void
- +SwLedCm2Blink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + );
- +
- +void
- +SwLedCm4Blink(
- + struct net_device *dev,
- + PLED_8187 pLed
- + );
- +
- +void
- +SwLedOn(
- + struct net_device *dev,
- + PLED_8187 pLed
- +);
- +
- +void
- +SwLedOff(
- + struct net_device *dev,
- + PLED_8187 pLed
- +);
- +
- +
- +#endif
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_rfkill.c linux-lemote/drivers/net/wireless/rtl8187b/r8187_rfkill.c
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/r8187_rfkill.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/r8187_rfkill.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,157 @@
- +/*
- + * rtl8187b specific rfkill support
- + *
- + * NOTE: we only concern about two states
- + * eRfOff: RFKILL_STATE_SOFT_BLOCKED
- + * eRfOn: RFKILL_STATE_UNBLOCKED
- + * TODO: move led controlling source code to rfkill framework
- + *
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- + */
- +
- +#include <linux/module.h>
- +#include <linux/rfkill.h>
- +#include <linux/device.h>
- +
- +/* LED macros are defined in r8187.h and rfkill.h, we not use any of them here
- + * just avoid compiling erros here.
- + */
- +#undef LED
- +
- +#include "r8187.h"
- +#include "ieee80211/ieee80211.h"
- +#include "linux/netdevice.h"
- +
- +static struct rfkill *r8187b_rfkill;
- +static struct work_struct r8187b_rfkill_task;
- +static int initialized;
- +/* turn off by default */
- +int r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
- +struct net_device *r8187b_dev = NULL;
- +RT_RF_POWER_STATE eRfPowerStateToSet;
- +
- +/* These two mutexes are used to ensure the relative rfkill status are accessed
- + * by different tasks exclusively */
- +DEFINE_MUTEX(statetoset_lock);
- +DEFINE_MUTEX(state_lock);
- +
- +static void r8187b_wifi_rfkill_task(struct work_struct *work)
- +{
- + if (r8187b_dev) {
- + mutex_lock(&statetoset_lock);
- + r8187b_wifi_change_rfkill_state(r8187b_dev, eRfPowerStateToSet);
- + mutex_unlock(&statetoset_lock);
- + }
- +}
- +
- +static int r8187b_wifi_update_rfkill_state(int status)
- +{
- + /* ensure r8187b_rfkill is initialized if dev is not initialized, means
- + * wifi driver is not start, the status is eRfOff be default.
- + */
- + if (!r8187b_dev)
- + return eRfOff;
- +
- + if (initialized == 0) {
- + /* init the rfkill work task */
- + INIT_WORK(&r8187b_rfkill_task, r8187b_wifi_rfkill_task);
- + initialized = 1;
- + }
- +
- + mutex_lock(&statetoset_lock);
- + if (status == 1)
- + eRfPowerStateToSet = eRfOn;
- + else if (status == 0)
- + eRfPowerStateToSet = eRfOff;
- + else if (status == 2) {
- + /* if the KEY_WLAN is pressed, just switch it! */
- + mutex_lock(&state_lock);
- + if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
- + eRfPowerStateToSet = eRfOff;
- + else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
- + eRfPowerStateToSet = eRfOn;
- + mutex_unlock(&state_lock);
- + }
- + mutex_unlock(&statetoset_lock);
- +
- + schedule_work(&r8187b_rfkill_task);
- +
- + return eRfPowerStateToSet;
- +}
- +
- +static int r8187b_rfkill_set(void *data, bool blocked)
- +{
- + r8187b_wifi_update_rfkill_state(!blocked);
- +
- + return 0;
- +}
- +
- +static void r8187b_rfkill_query(struct rfkill *rfkill, void *data)
- +{
- + static bool blocked;
- +
- + mutex_lock(&state_lock);
- + if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
- + blocked = 0;
- + else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
- + blocked = 1;
- + mutex_unlock(&state_lock);
- +
- + rfkill_set_hw_state(rfkill, blocked);
- +}
- +
- +int r8187b_wifi_report_state(r8180_priv *priv)
- +{
- + mutex_lock(&state_lock);
- + r8187b_rfkill_state = RFKILL_USER_STATE_UNBLOCKED;
- + if (priv->ieee80211->bHwRadioOff && priv->eRFPowerState == eRfOff)
- + r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
- + mutex_unlock(&state_lock);
- +
- + r8187b_rfkill_query(r8187b_rfkill, NULL);
- +
- + return 0;
- +}
- +
- +static const struct rfkill_ops r8187b_rfkill_ops = {
- + .set_block = r8187b_rfkill_set,
- + .query = r8187b_rfkill_query,
- +};
- +
- +int r8187b_rfkill_init(struct net_device *dev)
- +{
- + int ret;
- +
- + /* init the r8187b device */
- + r8187b_dev = dev;
- +
- + /* init the rfkill struct */
- + r8187b_rfkill = rfkill_alloc("r8187b-wifi", &dev->dev,
- + RFKILL_TYPE_WLAN, &r8187b_rfkill_ops,
- + (void *)1);
- +
- + if (!r8187b_rfkill) {
- + rfkill_destroy(r8187b_rfkill);
- + printk(KERN_WARNING "r8187b: Unable to allocate rfkill\n");
- + return -ENOMEM;
- + }
- + ret = rfkill_register(r8187b_rfkill);
- + if (ret) {
- + rfkill_destroy(r8187b_rfkill);
- + return ret;
- + }
- +
- + /* The default status is passed to the rfkill module */
- +
- + return 0;
- +}
- +
- +void r8187b_rfkill_exit(void)
- +{
- + if (r8187b_rfkill) {
- + rfkill_unregister(r8187b_rfkill);
- + rfkill_destroy(r8187b_rfkill);
- + }
- + r8187b_rfkill = NULL;
- +}
- diff -Nur linux-2.6.33/drivers/net/wireless/rtl8187b/readme linux-lemote/drivers/net/wireless/rtl8187b/readme
- --- linux-2.6.33/drivers/net/wireless/rtl8187b/readme 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/net/wireless/rtl8187b/readme 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,124 @@
- +rtl8187 Linux kernel driver
- +Released under the terms of GNU General Public Licence (GPL)
- +Copyright(c) Andrea Merello - 2004,2005
- +
- +Portions of this driver are based on other projects, please see the notes
- +in the source files for detail.
- +A special thanks go to Realtek corp for their support and to David Young
- +------------------------------------------------------------------------------
- +
- +This is an attempt to write somethig that can make rtl8187 usb dongle wifi card
- +on Linux using only opensource stuff.
- +The rtl8225 radio is supported.
- +
- +It's in early development stage so don't expect too much from it
- +(also use it at your own risk!)
- +This should be considered just a fragment of code.. using it on your(any)
- +system is at your own risk! Please note that I never supported the idea to
- +use it in any way, so i cannot be considered responsible in any way for
- +anything deriving by it usage.
- +
- +Anyway for now we have monitor mode and managed mode
- +basically working! This isn't necessary stable, but seems to work..
- +
- +This driver is still under development and very far from perfect. It should work on x86,
- +Other archs are untested..
- +
- +To compile the driver simply run make.
- +
- +The driver contains also the ieee80211.h and ieee80211_crypt.h from the ieee stack.
- +Note that for some reasons this stack is NOT the same that will be included in newer
- +2.6 kernel. I will try to port to this stack as soon as it will have enought features
- +to support 8187 cards.
- +Please note that you will have to make sure the two .h files are the same of the ieee
- +stack.
- +In other words when you download from the CVS this driver and the ieee80211 stack a good
- +idea is to copy the ieee80211.h and ieee80211_crypt.h from the ieee directory to the drv
- +directory
- +
- +Warning during compile are OK
- +
- +To wake up the nic run:
- +
- + ifconfig <ifacename> up
- +
- +(where <ifacename> is your network device for wlan card).
- +
- +Please note that the default interface name is wlanX.
- +
- +Please note thet this will take several seconds..
- +
- +If you would like to set the interface name to something else you may use the
- +'devname=' module parameter. For example:
- +
- + insmod r8187.ko ifname=eth%d
- +
- +will set the interface name of this device to something like eth0.
- +
- +Once the nic is up it can be put in a monitor mode by running:
- +
- + iwconfig <ifacename> mode monitor
- +
- +and channel number may be changed by running:
- +
- + iwconfig <ifacename> channel XX
- +
- +
- +In monitor mode a choice may be made via iwpriv if the nic should pass packets
- +with bad crc or drop them.
- +
- +To put the nic in managed mode run:
- +
- + iwconfig <ifacename> mode managed
- +
- +In managed mode there is support for
- +
- + iwlist scan
- +
- +that should report the currently available networks.
- +Please note that in managed mode channels cannot be changed manually.
- +
- +To associate with a network
- +
- + iwconfig <ifacename> essid XXXXX
- +
- +where XXXXX is the network essid (name) reported by 'iwlist scan'. Please
- +note that essid is case sensitive.
- +
- +If your network is not broadcasting the ESSID, then you need to specify *also*
- +the AP MAC address
- +
- + iwconfig <ifacename> ap XX:XX:XX:XX:XX:XX
- +
- +The driver accepts another boolean parameter: hwseqnum
- +If set to 1 it lets the card HW take care of the sequence number of the TXed
- +frames. Altought in managed mode I can't see an important reason to use HW to
- +do that, when we'll start to TX beacons in master (AP) and ad-hoc modes most
- +probably it will be extremely useful (since most probably we will use two HW
- +queues).
- +
- +I'm unsure if it will work correctly on all NICs.. reports are *VERY, VERY* apreciated..
- +
- +
- + WEP
- + ===
- +
- +WEP encryption should work. For now it's done by host, not by the nic. Key can be set with:
- +Key can be set with
- +
- + iwconfig <ifacename> key 12345...
- +
- +WEP is supported via software thanks to the ipw stack.
- +
- +Shared and open authentication are supported
- +
- + IWPRIV
- + ======
- +
- +This driver supports some private handlers:
- +-badcrc: let you choose to kill or to pass to the upper layer frames with bad crc in monitor mode
- +-activescan: if 0 the driver will avoid to send probe requests, sanning will be only on beacon basis
- +
- +
- +If you have some question/comments please feel free to write me.
- +
- diff -Nur linux-2.6.33/drivers/platform/Kconfig linux-lemote/drivers/platform/Kconfig
- --- linux-2.6.33/drivers/platform/Kconfig 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/platform/Kconfig 2010-03-06 16:43:22.000000000 +0100
- @@ -1,3 +1,7 @@
- if X86
- source "drivers/platform/x86/Kconfig"
- endif
- +
- +if MIPS
- +source "drivers/platform/mips/Kconfig"
- +endif
- diff -Nur linux-2.6.33/drivers/platform/Makefile linux-lemote/drivers/platform/Makefile
- --- linux-2.6.33/drivers/platform/Makefile 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/platform/Makefile 2010-03-06 16:43:22.000000000 +0100
- @@ -3,3 +3,4 @@
- #
-
- obj-$(CONFIG_X86) += x86/
- +obj-$(CONFIG_MIPS) += mips/
- diff -Nur linux-2.6.33/drivers/platform/mips/Kconfig linux-lemote/drivers/platform/mips/Kconfig
- --- linux-2.6.33/drivers/platform/mips/Kconfig 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/platform/mips/Kconfig 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,43 @@
- +#
- +# MIPS Platform Specific Drivers
- +#
- +
- +menuconfig MIPS_PLATFORM_DEVICES
- + bool "MIPS Platform Specific Device Drivers"
- + default y
- + help
- + Say Y here to get to see options for device drivers of various
- + MIPS platforms, including vendor-specific netbook/laptop/pc extension
- + drivers. This option alone does not add any kernel code.
- +
- + If you say N, all options in this submenu will be skipped and disabled.
- +
- +if MIPS_PLATFORM_DEVICES
- +
- +config LEMOTE_YEELOONG2F
- + tristate "Lemote YeeLoong Laptop"
- + depends on LEMOTE_MACH2F
- + select BACKLIGHT_CLASS_DEVICE
- + select POWER_SUPPLY
- + select HWMON
- + select VIDEO_OUTPUT_CONTROL
- + select INPUT_SPARSEKMAP
- + depends on INPUT
- + help
- + YeeLoong netbook is a mini laptop made by Lemote, which is basically
- + compatible to FuLoong2F mini PC, but it has an extra Embedded
- + Controller(kb3310b) for battery, hotkey, backlight, temperature and
- + fan management.
- +
- +config LEMOTE_LYNLOONG2F
- + tristate "Lemote LynLoong PC"
- + depends on LEMOTE_MACH2F
- + select BACKLIGHT_CLASS_DEVICE
- + select VIDEO_OUTPUT_CONTROL
- + help
- + LynLoong PC is an AllINONE machine made by Lemote, which is basically
- + compatible to FuLoong2F Mini PC, the only difference is that it has a
- + size-fixed screen: 1360x768 with sisfb video driver. and also, it has
- + its own specific suspend support.
- +
- +endif # MIPS_PLATFORM_DEVICES
- diff -Nur linux-2.6.33/drivers/platform/mips/lynloong_pc.c linux-lemote/drivers/platform/mips/lynloong_pc.c
- --- linux-2.6.33/drivers/platform/mips/lynloong_pc.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/platform/mips/lynloong_pc.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,511 @@
- +/*
- + * Driver for LynLoong PC extras
- + *
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Xiang Yu <xiangy@lemote.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/err.h>
- +#include <linux/platform_device.h>
- +#include <linux/backlight.h> /* for backlight subdriver */
- +#include <linux/fb.h>
- +#include <linux/video_output.h> /* for video output subdriver */
- +#include <linux/delay.h> /* for suspend support */
- +
- +#include <cs5536/cs5536.h>
- +#include <cs5536/cs5536_mfgpt.h>
- +
- +#include <loongson.h>
- +
- +static u32 gpio_base, mfgpt_base;
- +
- +static void set_gpio_reg_high(int gpio, int reg)
- +{
- + u32 val;
- +
- + val = inl(gpio_base + reg);
- + val |= (1 << gpio);
- + val &= ~(1 << (16 + gpio));
- + outl(val, gpio_base + reg);
- + mmiowb();
- +}
- +
- +static void set_gpio_reg_low(int gpio, int reg)
- +{
- + u32 val;
- +
- + val = inl(gpio_base + reg);
- + val |= (1 << (16 + gpio));
- + val &= ~(1 << gpio);
- + outl(val, gpio_base + reg);
- + mmiowb();
- +}
- +
- +static void set_gpio_output_low(int gpio)
- +{
- + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
- + set_gpio_reg_low(gpio, GPIOL_OUT_VAL);
- +}
- +
- +static void set_gpio_output_high(int gpio)
- +{
- + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
- + set_gpio_reg_high(gpio, GPIOL_OUT_VAL);
- +}
- +
- +/* backlight subdriver */
- +
- +#define MAX_BRIGHTNESS 100
- +#define DEFAULT_BRIGHTNESS 50
- +#define MIN_BRIGHTNESS 0
- +static unsigned int level;
- +
- +DEFINE_SPINLOCK(backlight_lock);
- +/* Tune the brightness */
- +static void setup_mfgpt2(void)
- +{
- + unsigned long flags;
- +
- + spin_lock_irqsave(&backlight_lock, flags);
- +
- + /* Set MFGPT2 comparator 1,2 */
- + outw(MAX_BRIGHTNESS-level, MFGPT2_CMP1);
- + outw(MAX_BRIGHTNESS, MFGPT2_CMP2);
- + /* Clear MFGPT2 UP COUNTER */
- + outw(0, MFGPT2_CNT);
- + /* Enable counter, compare mode, 32k */
- + outw(0x8280, MFGPT2_SETUP);
- +
- + spin_unlock_irqrestore(&backlight_lock, flags);
- +}
- +
- +static int lynloong_set_brightness(struct backlight_device *bd)
- +{
- + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
- + bd->props.power == FB_BLANK_UNBLANK) ?
- + bd->props.brightness : 0;
- +
- + if (level > MAX_BRIGHTNESS)
- + level = MAX_BRIGHTNESS;
- + else if (level < MIN_BRIGHTNESS)
- + level = MIN_BRIGHTNESS;
- +
- + setup_mfgpt2();
- +
- + return 0;
- +}
- +
- +static int lynloong_get_brightness(struct backlight_device *bd)
- +{
- + return level;
- +}
- +
- +static struct backlight_ops backlight_ops = {
- + .get_brightness = lynloong_get_brightness,
- + .update_status = lynloong_set_brightness,
- +};
- +
- +static struct backlight_device *lynloong_backlight_dev;
- +
- +static int lynloong_backlight_init(void)
- +{
- + int ret;
- + u32 hi;
- +
- + /* Get gpio_base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
- + /* Get mfgpt_base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base);
- + /* Get gpio_base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
- +
- + /* Select for mfgpt */
- + set_gpio_reg_high(7, GPIOL_OUT_AUX1_SEL);
- + /* Enable brightness controlling */
- + set_gpio_output_high(7);
- +
- + lynloong_backlight_dev = backlight_device_register("backlight0", NULL,
- + NULL, &backlight_ops);
- +
- + if (IS_ERR(lynloong_backlight_dev)) {
- + ret = PTR_ERR(lynloong_backlight_dev);
- + return ret;
- + }
- +
- + lynloong_backlight_dev->props.max_brightness = MAX_BRIGHTNESS;
- + lynloong_backlight_dev->props.brightness = DEFAULT_BRIGHTNESS;
- + backlight_update_status(lynloong_backlight_dev);
- +
- + return 0;
- +}
- +
- +static void lynloong_backlight_exit(void)
- +{
- + if (lynloong_backlight_dev) {
- + backlight_device_unregister(lynloong_backlight_dev);
- + lynloong_backlight_dev = NULL;
- + }
- + /* Disable brightness controlling */
- + set_gpio_output_low(7);
- +}
- +
- +/* video output driver */
- +static int vo_status = 1;
- +
- +static int lcd_video_output_get(struct output_device *od)
- +{
- + return vo_status;
- +}
- +
- +static int lcd_video_output_set(struct output_device *od)
- +{
- + int i;
- + unsigned long status;
- +
- + status = !!od->request_state;
- +
- + if (status == 0) {
- + /* Set the current status as off */
- + vo_status = 0;
- + /* Turn off the backlight */
- + set_gpio_output_low(11);
- + for (i = 0; i < 0x500; i++)
- + delay();
- + /* Turn off the LCD */
- + set_gpio_output_high(8);
- + } else {
- + /* Turn on the LCD */
- + set_gpio_output_low(8);
- + for (i = 0; i < 0x500; i++)
- + delay();
- + /* Turn on the backlight */
- + set_gpio_output_high(11);
- + /* Set the current status as on */
- + vo_status = 1;
- + }
- +
- + return 0;
- +}
- +
- +static struct output_properties lcd_output_properties = {
- + .set_state = lcd_video_output_set,
- + .get_status = lcd_video_output_get,
- +};
- +
- +static struct output_device *lcd_output_dev;
- +
- +static void lynloong_lcd_vo_set(int status)
- +{
- + lcd_output_dev->request_state = status;
- + lcd_video_output_set(lcd_output_dev);
- +}
- +
- +static int lynloong_vo_init(void)
- +{
- + int ret;
- +
- + /* Register video output device: lcd */
- + lcd_output_dev = video_output_register("LCD", NULL, NULL,
- + &lcd_output_properties);
- +
- + if (IS_ERR(lcd_output_dev)) {
- + ret = PTR_ERR(lcd_output_dev);
- + lcd_output_dev = NULL;
- + return ret;
- + }
- + /* Ensure LCD is on by default */
- + lynloong_lcd_vo_set(1);
- +
- + return 0;
- +}
- +
- +static void lynloong_vo_exit(void)
- +{
- + if (lcd_output_dev) {
- + video_output_unregister(lcd_output_dev);
- + lcd_output_dev = NULL;
- + }
- +}
- +
- +/* suspend support */
- +
- +#ifdef CONFIG_PM
- +
- +static u32 smb_base;
- +
- +/* I2C operations */
- +
- +static int i2c_wait(void)
- +{
- + char c;
- + int i;
- +
- + udelay(1000);
- + for (i = 0; i < 20; i++) {
- + c = inb(smb_base | SMB_STS);
- + if (c & (SMB_STS_BER | SMB_STS_NEGACK))
- + return -1;
- + if (c & SMB_STS_SDAST)
- + return 0;
- + udelay(100);
- + }
- + return -2;
- +}
- +
- +static void i2c_read_single(int addr, int regNo, char *value)
- +{
- + unsigned char c;
- +
- + /* Start condition */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
- + i2c_wait();
- +
- + /* Send slave address */
- + outb(addr & 0xfe, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Acknowledge smbus */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
- +
- + /* Send register index */
- + outb(regNo, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Acknowledge smbus */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
- +
- + /* Start condition again */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
- + i2c_wait();
- +
- + /* Send salve address again */
- + outb(1 | addr, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Acknowledge smbus */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
- +
- + /* Read data */
- + *value = inb(smb_base | SMB_SDA);
- +
- + /* Stop condition */
- + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
- + i2c_wait();
- +}
- +
- +static void i2c_write_single(int addr, int regNo, char value)
- +{
- + unsigned char c;
- +
- + /* Start condition */
- + c = inb(smb_base | SMB_CTRL1);
- + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
- + i2c_wait();
- + /* Send slave address */
- + outb(addr & 0xfe, smb_base | SMB_SDA);
- + i2c_wait();;
- +
- + /* Send register index */
- + outb(regNo, smb_base | SMB_SDA);
- + i2c_wait();
- +
- + /* Write data */
- + outb(value, smb_base | SMB_SDA);
- + i2c_wait();
- + /* Stop condition */
- + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
- + i2c_wait();
- +}
- +
- +static void stop_clock(int clk_reg, int clk_sel)
- +{
- + u8 value;
- +
- + i2c_read_single(0xd3, clk_reg, &value);
- + value &= ~(1 << clk_sel);
- + i2c_write_single(0xd2, clk_reg, value);
- +}
- +
- +static void enable_clock(int clk_reg, int clk_sel)
- +{
- + u8 value;
- +
- + i2c_read_single(0xd3, clk_reg, &value);
- + value |= (1 << clk_sel);
- + i2c_write_single(0xd2, clk_reg, value);
- +}
- +
- +static char cached_clk_freq;
- +static char cached_pci_fixed_freq;
- +
- +static void decrease_clk_freq(void)
- +{
- + char value;
- +
- + i2c_read_single(0xd3, 1, &value);
- + cached_clk_freq = value;
- +
- + /* Select frequency by software */
- + value |= (1 << 1);
- + /* CPU, 3V66, PCI : 100, 66, 33(1) */
- + value |= (1 << 2);
- + i2c_write_single(0xd2, 1, value);
- +
- + /* Cache the pci frequency */
- + i2c_read_single(0xd3, 14, &value);
- + cached_pci_fixed_freq = value;
- +
- + /* Enable PCI fix mode */
- + value |= (1 << 5);
- + /* 3V66, PCI : 64MHz, 32MHz */
- + value |= (1 << 3);
- + i2c_write_single(0xd2, 14, value);
- +
- +}
- +
- +static void resume_clk_freq(void)
- +{
- + i2c_write_single(0xd2, 1, cached_clk_freq);
- + i2c_write_single(0xd2, 14, cached_pci_fixed_freq);
- +}
- +
- +static void stop_clocks(void)
- +{
- + /* CPU Clock Register */
- + stop_clock(2, 5); /* not used */
- + stop_clock(2, 6); /* not used */
- + stop_clock(2, 7); /* not used */
- +
- + /* PCI Clock Register */
- + stop_clock(3, 1); /* 8100 */
- + stop_clock(3, 5); /* SIS */
- + stop_clock(3, 0); /* not used */
- + stop_clock(3, 6); /* not used */
- +
- + /* PCI 48M Clock Register */
- + stop_clock(4, 6); /* USB grounding */
- + stop_clock(4, 5); /* REF(5536_14M) */
- +
- + /* 3V66 Control Register */
- + stop_clock(5, 0); /* VCH_CLK..., grounding */
- +}
- +
- +static void enable_clocks(void)
- +{
- + enable_clock(3, 1); /* 8100 */
- + enable_clock(3, 5); /* SIS */
- +
- + enable_clock(4, 6);
- + enable_clock(4, 5); /* REF(5536_14M) */
- +
- + enable_clock(5, 0); /* VCH_CLOCK, grounding */
- +}
- +
- +static int lynloong_suspend(struct device *dev)
- +{
- + /* Disable AMP */
- + set_gpio_output_high(6);
- + /* Turn off LCD */
- + lynloong_lcd_vo_set(0);
- +
- + /* Stop the clocks of some devices */
- + stop_clocks();
- +
- + /* Decrease the external clock frequency */
- + decrease_clk_freq();
- +
- + return 0;
- +}
- +
- +static int lynloong_resume(struct device *dev)
- +{
- + /* Turn on the LCD */
- + lynloong_lcd_vo_set(1);
- +
- + /* Resume clock frequency, enable the relative clocks */
- + resume_clk_freq();
- + enable_clocks();
- +
- + /* Enable AMP */
- + set_gpio_output_low(6);
- +
- + return 0;
- +}
- +
- +static const SIMPLE_DEV_PM_OPS(lynloong_pm_ops, lynloong_suspend,
- + lynloong_resume);
- +#endif /* !CONFIG_PM */
- +
- +static struct platform_device_id platform_device_ids[] = {
- + {
- + .name = "lynloong_pc",
- + },
- + {}
- +};
- +
- +MODULE_DEVICE_TABLE(platform, platform_device_ids);
- +
- +static struct platform_driver platform_driver = {
- + .driver = {
- + .name = "lynloong_pc",
- + .owner = THIS_MODULE,
- +#ifdef CONFIG_PM
- + .pm = &lynloong_pm_ops,
- +#endif
- + },
- + .id_table = platform_device_ids,
- +};
- +
- +static int __init lynloong_init(void)
- +{
- + int ret;
- +
- + pr_info("Load LynLoong Platform Specific Driver.\n");
- +
- + /* Register platform stuff */
- + ret = platform_driver_register(&platform_driver);
- + if (ret) {
- + pr_err("Fail to register lynloong platform driver.\n");
- + return ret;
- + }
- +
- + ret = lynloong_backlight_init();
- + if (ret) {
- + pr_err("Fail to register lynloong backlight driver.\n");
- + return ret;
- + }
- +
- + ret = lynloong_vo_init();
- + if (ret) {
- + pr_err("Fail to register lynloong backlight driver.\n");
- + lynloong_vo_exit();
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +static void __exit lynloong_exit(void)
- +{
- + lynloong_vo_exit();
- + lynloong_backlight_exit();
- + platform_driver_unregister(&platform_driver);
- +
- + pr_info("Unload LynLoong Platform Specific Driver.\n");
- +}
- +
- +module_init(lynloong_init);
- +module_exit(lynloong_exit);
- +
- +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Xiang Yu <xiangy@lemote.com>");
- +MODULE_DESCRIPTION("LynLoong PC driver");
- +MODULE_LICENSE("GPL");
- diff -Nur linux-2.6.33/drivers/platform/mips/Makefile linux-lemote/drivers/platform/mips/Makefile
- --- linux-2.6.33/drivers/platform/mips/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/platform/mips/Makefile 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,7 @@
- +#
- +# Makefile for MIPS Platform-Specific Drivers
- +#
- +
- +obj-$(CONFIG_LEMOTE_YEELOONG2F) += yeeloong_laptop.o
- +
- +obj-$(CONFIG_LEMOTE_LYNLOONG2F) += lynloong_pc.o
- diff -Nur linux-2.6.33/drivers/platform/mips/yeeloong_ecrom.c linux-lemote/drivers/platform/mips/yeeloong_ecrom.c
- --- linux-2.6.33/drivers/platform/mips/yeeloong_ecrom.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/platform/mips/yeeloong_ecrom.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,943 @@
- +/*
- + * Driver for flushing/dumping ROM of EC on YeeLoong laptop
- + *
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: liujl <liujl@lemote.com>
- + *
- + * NOTE :
- + * The EC resources accessing and programming are supported.
- + */
- +
- +#include <linux/proc_fs.h>
- +#include <linux/miscdevice.h>
- +#include <linux/init.h>
- +#include <linux/delay.h>
- +
- +#include <ec_kb3310b.h>
- +
- +#define EC_MISC_DEV "ec_misc"
- +#define EC_IOC_MAGIC 'E'
- +
- +/* ec registers range */
- +#define EC_MAX_REGADDR 0xFFFF
- +#define EC_MIN_REGADDR 0xF000
- +#define EC_RAM_ADDR 0xF800
- +
- +/* version burned address */
- +#define VER_ADDR 0xf7a1
- +#define VER_MAX_SIZE 7
- +#define EC_ROM_MAX_SIZE 0x10000
- +
- +/* ec internal register */
- +#define REG_POWER_MODE 0xF710
- +#define FLAG_NORMAL_MODE 0x00
- +#define FLAG_IDLE_MODE 0x01
- +#define FLAG_RESET_MODE 0x02
- +
- +/* ec update program flag */
- +#define PROGRAM_FLAG_NONE 0x00
- +#define PROGRAM_FLAG_IE 0x01
- +#define PROGRAM_FLAG_ROM 0x02
- +
- +/* XBI relative registers */
- +#define REG_XBISEG0 0xFEA0
- +#define REG_XBISEG1 0xFEA1
- +#define REG_XBIRSV2 0xFEA2
- +#define REG_XBIRSV3 0xFEA3
- +#define REG_XBIRSV4 0xFEA4
- +#define REG_XBICFG 0xFEA5
- +#define REG_XBICS 0xFEA6
- +#define REG_XBIWE 0xFEA7
- +#define REG_XBISPIA0 0xFEA8
- +#define REG_XBISPIA1 0xFEA9
- +#define REG_XBISPIA2 0xFEAA
- +#define REG_XBISPIDAT 0xFEAB
- +#define REG_XBISPICMD 0xFEAC
- +#define REG_XBISPICFG 0xFEAD
- +#define REG_XBISPIDATR 0xFEAE
- +#define REG_XBISPICFG2 0xFEAF
- +
- +/* commands definition for REG_XBISPICMD */
- +#define SPICMD_WRITE_STATUS 0x01
- +#define SPICMD_BYTE_PROGRAM 0x02
- +#define SPICMD_READ_BYTE 0x03
- +#define SPICMD_WRITE_DISABLE 0x04
- +#define SPICMD_READ_STATUS 0x05
- +#define SPICMD_WRITE_ENABLE 0x06
- +#define SPICMD_HIGH_SPEED_READ 0x0B
- +#define SPICMD_POWER_DOWN 0xB9
- +#define SPICMD_SST_EWSR 0x50
- +#define SPICMD_SST_SEC_ERASE 0x20
- +#define SPICMD_SST_BLK_ERASE 0x52
- +#define SPICMD_SST_CHIP_ERASE 0x60
- +#define SPICMD_FRDO 0x3B
- +#define SPICMD_SEC_ERASE 0xD7
- +#define SPICMD_BLK_ERASE 0xD8
- +#define SPICMD_CHIP_ERASE 0xC7
- +
- +/* bits definition for REG_XBISPICFG */
- +#define SPICFG_AUTO_CHECK 0x01
- +#define SPICFG_SPI_BUSY 0x02
- +#define SPICFG_DUMMY_READ 0x04
- +#define SPICFG_EN_SPICMD 0x08
- +#define SPICFG_LOW_SPICS 0x10
- +#define SPICFG_EN_SHORT_READ 0x20
- +#define SPICFG_EN_OFFSET_READ 0x40
- +#define SPICFG_EN_FAST_READ 0x80
- +
- +/* watchdog timer registers */
- +#define REG_WDTCFG 0xfe80
- +#define REG_WDTPF 0xfe81
- +#define REG_WDT 0xfe82
- +
- +/* lpc configure register */
- +#define REG_LPCCFG 0xfe95
- +
- +/* 8051 reg */
- +#define REG_PXCFG 0xff14
- +
- +/* Fan register in KB3310 */
- +#define REG_ECFAN_SPEED_LEVEL 0xf4e4
- +#define REG_ECFAN_SWITCH 0xf4d2
- +
- +/* the ec flash rom id number */
- +#define EC_ROM_PRODUCT_ID_SPANSION 0x01
- +#define EC_ROM_PRODUCT_ID_MXIC 0xC2
- +#define EC_ROM_PRODUCT_ID_AMIC 0x37
- +#define EC_ROM_PRODUCT_ID_EONIC 0x1C
- +
- +/* misc ioctl operations */
- +#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int)
- +#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int)
- +#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int)
- +#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int)
- +#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int)
- +
- +/* start address for programming of EC content or IE */
- +/* ec running code start address */
- +#define EC_START_ADDR 0x00000000
- +/* ec information element storing address */
- +#define IE_START_ADDR 0x00020000
- +
- +/* EC state */
- +#define EC_STATE_IDLE 0x00 /* ec in idle state */
- +#define EC_STATE_BUSY 0x01 /* ec in busy state */
- +
- +/* timeout value for programming */
- +#define EC_FLASH_TIMEOUT 0x1000 /* ec program timeout */
- +/* command checkout timeout including cmd to port or state flag check */
- +#define EC_CMD_TIMEOUT 0x1000
- +#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) /* unit : us */
- +#define EC_MAX_DELAY_UNIT (10) /* every time for polling */
- +#define SPI_FINISH_WAIT_TIME 10
- +/* EC content max size */
- +#define EC_CONTENT_MAX_SIZE (64 * 1024)
- +#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR)
- +
- +/* the register operation access struct */
- +struct ec_reg {
- + u32 addr; /* the address of kb3310 registers */
- + u8 val; /* the register value */
- +};
- +
- +struct ec_info {
- + u32 start_addr;
- + u32 size;
- + u8 *buf;
- +};
- +
- +/* open for using rom protection action */
- +#define EC_ROM_PROTECTION
- +
- +/* enable the chip reset mode */
- +static int ec_init_reset_mode(void)
- +{
- + int timeout;
- + unsigned char status = 0;
- + int ret = 0;
- +
- + /* make chip goto reset mode */
- + ret = ec_query_seq(CMD_INIT_RESET_MODE);
- + if (ret < 0) {
- + printk(KERN_ERR "ec init reset mode failed.\n");
- + goto out;
- + }
- +
- + /* make the action take active */
- + timeout = EC_CMD_TIMEOUT;
- + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
- + while (timeout--) {
- + if (status) {
- + udelay(EC_REG_DELAY);
- + break;
- + }
- + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
- + udelay(EC_REG_DELAY);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR "ec rom fixup : can't check reset status.\n");
- + ret = -EINVAL;
- + } else
- + printk(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout,
- + EC_CMD_TIMEOUT - timeout, status);
- +
- + /* set MCU to reset mode */
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_PXCFG);
- + status |= (1 << 0);
- + ec_write(REG_PXCFG, status);
- + udelay(EC_REG_DELAY);
- +
- + /* disable FWH/LPC */
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_LPCCFG);
- + status &= ~(1 << 7);
- + ec_write(REG_LPCCFG, status);
- + udelay(EC_REG_DELAY);
- +
- + printk(KERN_INFO "entering reset mode ok..............\n");
- +
- + out:
- + return ret;
- +}
- +
- +/* make ec exit from reset mode */
- +static void ec_exit_reset_mode(void)
- +{
- + unsigned char regval;
- +
- + udelay(EC_REG_DELAY);
- + regval = ec_read(REG_LPCCFG);
- + regval |= (1 << 7);
- + ec_write(REG_LPCCFG, regval);
- + regval = ec_read(REG_PXCFG);
- + regval &= ~(1 << 0);
- + ec_write(REG_PXCFG, regval);
- + printk(KERN_INFO "exit reset mode ok..................\n");
- +
- + return;
- +}
- +
- +/* make ec disable WDD */
- +static void ec_disable_WDD(void)
- +{
- + unsigned char status;
- +
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_WDTCFG);
- + ec_write(REG_WDTPF, 0x03);
- + ec_write(REG_WDTCFG, (status & 0x80) | 0x48);
- + printk(KERN_INFO "Disable WDD ok..................\n");
- +
- + return;
- +}
- +
- +/* make ec enable WDD */
- +static void ec_enable_WDD(void)
- +{
- + unsigned char status;
- +
- + udelay(EC_REG_DELAY);
- + status = ec_read(REG_WDTCFG);
- + ec_write(REG_WDT, 0x28); /* set WDT 5sec(0x28) */
- + ec_write(REG_WDTCFG, (status & 0x80) | 0x03);
- + printk(KERN_INFO "Enable WDD ok..................\n");
- +
- + return;
- +}
- +
- +/* make ec goto idle mode */
- +static int ec_init_idle_mode(void)
- +{
- + int timeout;
- + unsigned char status = 0;
- + int ret = 0;
- +
- + ec_query_seq(CMD_INIT_IDLE_MODE);
- +
- + /* make the action take active */
- + timeout = EC_CMD_TIMEOUT;
- + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
- + while (timeout--) {
- + if (status) {
- + udelay(EC_REG_DELAY);
- + break;
- + }
- + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
- + udelay(EC_REG_DELAY);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR "ec rom fixup : can't check out the status.\n");
- + ret = -EINVAL;
- + } else
- + printk(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout,
- + EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE));
- +
- + printk(KERN_INFO "entering idle mode ok...................\n");
- +
- + return ret;
- +}
- +
- +/* make ec exit from idle mode */
- +static int ec_exit_idle_mode(void)
- +{
- +
- + ec_query_seq(CMD_EXIT_IDLE_MODE);
- +
- + printk(KERN_INFO "exit idle mode ok...................\n");
- +
- + return 0;
- +}
- +
- +static int ec_instruction_cycle(void)
- +{
- + unsigned long timeout;
- + int ret = 0;
- +
- + timeout = EC_FLASH_TIMEOUT;
- + while (timeout-- >= 0) {
- + if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY))
- + break;
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR
- + "EC_INSTRUCTION_CYCLE : timeout for check flag.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + out:
- + return ret;
- +}
- +
- +/* To see if the ec is in busy state or not. */
- +static inline int ec_flash_busy(unsigned long timeout)
- +{
- + /* assurance the first command be going to rom */
- + if (ec_instruction_cycle() < 0)
- + return EC_STATE_BUSY;
- +#if 1
- + timeout = timeout / EC_MAX_DELAY_UNIT;
- + while (timeout-- > 0) {
- + /* check the rom's status of busy flag */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (ec_instruction_cycle() < 0)
- + return EC_STATE_BUSY;
- + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
- + return EC_STATE_IDLE;
- + udelay(EC_MAX_DELAY_UNIT);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR
- + "EC_FLASH_BUSY : timeout for check rom flag.\n");
- + return EC_STATE_BUSY;
- + }
- +#else
- + /* check the rom's status of busy flag */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (ec_instruction_cycle() < 0)
- + return EC_STATE_BUSY;
- +
- + timeout = timeout / EC_MAX_DELAY_UNIT;
- + while (timeout-- > 0) {
- + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
- + return EC_STATE_IDLE;
- + udelay(EC_MAX_DELAY_UNIT);
- + }
- + if (timeout <= 0) {
- + printk(KERN_ERR
- + "EC_FLASH_BUSY : timeout for check rom flag.\n");
- + return EC_STATE_BUSY;
- + }
- +#endif
- +
- + return EC_STATE_IDLE;
- +}
- +
- +static int rom_instruction_cycle(unsigned char cmd)
- +{
- + unsigned long timeout = 0;
- +
- + switch (cmd) {
- + case SPICMD_READ_STATUS:
- + case SPICMD_WRITE_ENABLE:
- + case SPICMD_WRITE_DISABLE:
- + case SPICMD_READ_BYTE:
- + case SPICMD_HIGH_SPEED_READ:
- + timeout = 0;
- + break;
- + case SPICMD_WRITE_STATUS:
- + timeout = 300 * 1000;
- + break;
- + case SPICMD_BYTE_PROGRAM:
- + timeout = 5 * 1000;
- + break;
- + case SPICMD_SST_SEC_ERASE:
- + case SPICMD_SEC_ERASE:
- + timeout = 1000 * 1000;
- + break;
- + case SPICMD_SST_BLK_ERASE:
- + case SPICMD_BLK_ERASE:
- + timeout = 3 * 1000 * 1000;
- + break;
- + case SPICMD_SST_CHIP_ERASE:
- + case SPICMD_CHIP_ERASE:
- + timeout = 20 * 1000 * 1000;
- + break;
- + default:
- + timeout = EC_SPICMD_STANDARD_TIMEOUT;
- + }
- + if (timeout == 0)
- + return ec_instruction_cycle();
- + if (timeout < EC_SPICMD_STANDARD_TIMEOUT)
- + timeout = EC_SPICMD_STANDARD_TIMEOUT;
- +
- + return ec_flash_busy(timeout);
- +}
- +
- +/* delay for start/stop action */
- +static void delay_spi(int n)
- +{
- + while (n--)
- + inb(EC_IO_PORT_HIGH);
- +}
- +
- +/* start the action to spi rom function */
- +static void ec_start_spi(void)
- +{
- + unsigned char val;
- +
- + delay_spi(SPI_FINISH_WAIT_TIME);
- + val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK;
- + ec_write(REG_XBISPICFG, val);
- + delay_spi(SPI_FINISH_WAIT_TIME);
- +}
- +
- +/* stop the action to spi rom function */
- +static void ec_stop_spi(void)
- +{
- + unsigned char val;
- +
- + delay_spi(SPI_FINISH_WAIT_TIME);
- + val =
- + ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK));
- + ec_write(REG_XBISPICFG, val);
- + delay_spi(SPI_FINISH_WAIT_TIME);
- +}
- +
- +/* read one byte from xbi interface */
- +static int ec_read_byte(unsigned int addr, unsigned char *byte)
- +{
- + int ret = 0;
- +
- + /* enable spicmd writing. */
- + ec_start_spi();
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + /* write the address */
- + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
- + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
- + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
- + /* start action */
- + ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ);
- + if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + *byte = ec_read(REG_XBISPIDAT);
- +
- + out:
- + /* disable spicmd writing. */
- + ec_stop_spi();
- +
- + return ret;
- +}
- +
- +/* write one byte to ec rom */
- +static int ec_write_byte(unsigned int addr, unsigned char byte)
- +{
- + int ret = 0;
- +
- + /* enable spicmd writing. */
- + ec_start_spi();
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + /* write the address */
- + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
- + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
- + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
- + ec_write(REG_XBISPIDAT, byte);
- + /* start action */
- + ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM);
- + if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + out:
- + /* disable spicmd writing. */
- + ec_stop_spi();
- +
- + return ret;
- +}
- +
- +/* unprotect SPI ROM */
- +/* EC_ROM_unprotect function code */
- +static int EC_ROM_unprotect(void)
- +{
- + unsigned char status;
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
- + return 1;
- + }
- +
- + /* unprotect the status register of rom */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n");
- + return 1;
- + }
- + status = ec_read(REG_XBISPIDAT);
- + ec_write(REG_XBISPIDAT, status & 0x02);
- + if (ec_instruction_cycle() < 0) {
- + printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n");
- + return 1;
- + }
- +
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
- + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n");
- + return 1;
- + }
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
- + return 1;
- + }
- +
- + return 0;
- +}
- +
- +/* erase one block or chip or sector as needed */
- +static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr)
- +{
- + unsigned char status;
- + int ret = 0, i = 0;
- + int unprotect_count = 3;
- + int check_flag = 0;
- +
- + /* enable spicmd writing. */
- + ec_start_spi();
- +
- +#ifdef EC_ROM_PROTECTION
- + /* added for re-check SPICMD_READ_STATUS */
- + while (unprotect_count-- > 0) {
- + if (EC_ROM_unprotect()) {
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + /* first time:500ms --> 5.5sec -->10.5sec */
- + for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++)
- + udelay(50000);
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (rom_instruction_cycle(SPICMD_READ_STATUS)
- + == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
- + } else {
- + status = ec_read(REG_XBISPIDAT);
- + printk(KERN_INFO "Read unprotect status : 0x%x\n",
- + status);
- + if ((status & 0x1C) == 0x00) {
- + printk(KERN_INFO
- + "Read unprotect status OK1 : 0x%x\n",
- + status & 0x1C);
- + check_flag = 1;
- + break;
- + }
- + }
- + }
- +
- + if (!check_flag) {
- + printk(KERN_INFO "SPI ROM unprotect fail.\n");
- + return 1;
- + }
- +#endif
- +
- + /* block address fill */
- + if (erase_cmd == SPICMD_BLK_ERASE) {
- + ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16);
- + ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8);
- + ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0);
- + }
- +
- + /* erase the whole chip first */
- + ec_write(REG_XBISPICMD, erase_cmd);
- + if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) {
- + printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + out:
- + /* disable spicmd writing. */
- + ec_stop_spi();
- +
- + return ret;
- +}
- +
- +/* update the whole rom content with H/W mode
- + * PLEASE USING ec_unit_erase() FIRSTLY
- + */
- +static int ec_program_rom(struct ec_info *info, int flag)
- +{
- + unsigned int addr = 0;
- + unsigned long size = 0;
- + unsigned char *ptr = NULL;
- + unsigned char data;
- + unsigned char val = 0;
- + int ret = 0;
- + int i, j;
- + unsigned char status;
- +
- + /* modify for program serial No.
- + * set IE_START_ADDR & use idle mode,
- + * disable WDD
- + */
- + if (flag == PROGRAM_FLAG_ROM) {
- + ret = ec_init_reset_mode();
- + addr = info->start_addr + EC_START_ADDR;
- + printk(KERN_INFO "PROGRAM_FLAG_ROM..............\n");
- + } else if (flag == PROGRAM_FLAG_IE) {
- + ret = ec_init_idle_mode();
- + ec_disable_WDD();
- + addr = info->start_addr + IE_START_ADDR;
- + printk(KERN_INFO "PROGRAM_FLAG_IE..............\n");
- + } else {
- + return 0;
- + }
- +
- + if (ret < 0) {
- + if (flag == PROGRAM_FLAG_IE)
- + ec_enable_WDD();
- + return ret;
- + }
- +
- + size = info->size;
- + ptr = info->buf;
- + printk(KERN_INFO "starting update ec ROM..............\n");
- +
- + ret = ec_unit_erase(SPICMD_BLK_ERASE, addr);
- + if (ret) {
- + printk(KERN_ERR "program ec : erase block failed.\n");
- + goto out;
- + }
- + printk(KERN_ERR "program ec : erase block OK.\n");
- +
- + i = 0;
- + while (i < size) {
- + data = *(ptr + i);
- + ec_write_byte(addr, data);
- + ec_read_byte(addr, &val);
- + if (val != data) {
- + ec_write_byte(addr, data);
- + ec_read_byte(addr, &val);
- + if (val != data) {
- + printk(KERN_INFO
- + "EC : Second flash program failed at:\t");
- + printk(KERN_INFO
- + "addr : 0x%x, source : 0x%x, dest: 0x%x\n",
- + addr, data, val);
- + printk(KERN_INFO "This should not happen... STOP\n");
- + break;
- + }
- + }
- + i++;
- + addr++;
- + }
- +
- +#ifdef EC_ROM_PROTECTION
- + /* we should start spi access firstly */
- + ec_start_spi();
- +
- + /* enable write spi flash */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n");
- + goto out1;
- + }
- +
- + /* protect the status register of rom */
- + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
- + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
- + goto out1;
- + }
- + status = ec_read(REG_XBISPIDAT);
- +
- + ec_write(REG_XBISPIDAT, status | 0x1C);
- + if (ec_instruction_cycle() < 0) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : write status value failed.\n");
- + goto out1;
- + }
- +
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
- + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n");
- + goto out1;
- + }
- +#endif
- +
- + /* disable the write action to spi rom */
- + ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE);
- + if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) {
- + printk(KERN_ERR
- + "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n");
- + goto out1;
- + }
- +
- + out1:
- + /* we should stop spi access firstly */
- + ec_stop_spi();
- + out:
- + /* for security */
- + for (j = 0; j < 2000; j++)
- + udelay(1000);
- +
- + /* modify for program serial No.
- + * after program No exit idle mode
- + * and enable WDD
- + */
- + if (flag == PROGRAM_FLAG_ROM) {
- + /* exit from the reset mode */
- + ec_exit_reset_mode();
- + } else {
- + /* ec exit from idle mode */
- + ret = ec_exit_idle_mode();
- + ec_enable_WDD();
- + if (ret < 0)
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +/* ioctl */
- +static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd,
- + u_long arg)
- +{
- + struct ec_info ecinfo;
- + void __user *ptr = (void __user *)arg;
- + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
- + int ret = 0;
- +
- + switch (cmd) {
- + case IOCTL_RDREG:
- + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "reg read : copy from user error.\n");
- + return -EFAULT;
- + }
- + if ((ecreg->addr > EC_MAX_REGADDR)
- + || (ecreg->addr < EC_MIN_REGADDR)) {
- + printk(KERN_ERR
- + "reg read : out of register address range.\n");
- + return -EINVAL;
- + }
- + ecreg->val = ec_read(ecreg->addr);
- + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "reg read : copy to user error.\n");
- + return -EFAULT;
- + }
- + break;
- + case IOCTL_WRREG:
- + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "reg write : copy from user error.\n");
- + return -EFAULT;
- + }
- + if ((ecreg->addr > EC_MAX_REGADDR)
- + || (ecreg->addr < EC_MIN_REGADDR)) {
- + printk(KERN_ERR
- + "reg write : out of register address range.\n");
- + return -EINVAL;
- + }
- + ec_write(ecreg->addr, ecreg->val);
- + break;
- + case IOCTL_READ_EC:
- + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "spi read : copy from user error.\n");
- + return -EFAULT;
- + }
- + if ((ecreg->addr > EC_RAM_ADDR)
- + && (ecreg->addr < EC_MAX_REGADDR)) {
- + printk(KERN_ERR
- + "spi read : out of register address range.\n");
- + return -EINVAL;
- + }
- + ec_read_byte(ecreg->addr, &(ecreg->val));
- + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
- + if (ret) {
- + printk(KERN_ERR "spi read : copy to user error.\n");
- + return -EFAULT;
- + }
- + break;
- + case IOCTL_PROGRAM_IE:
- + ecinfo.start_addr = EC_START_ADDR;
- + ecinfo.size = EC_CONTENT_MAX_SIZE;
- + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
- + if (ecinfo.buf == NULL) {
- + printk(KERN_ERR "program ie : kmalloc failed.\n");
- + return -ENOMEM;
- + }
- + ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size);
- + if (ret) {
- + printk(KERN_ERR "program ie : copy from user error.\n");
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + return -EFAULT;
- + }
- +
- + /* use ec_program_rom to write serial No */
- + ec_program_rom(&ecinfo, PROGRAM_FLAG_IE);
- +
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + break;
- + case IOCTL_PROGRAM_EC:
- + ecinfo.start_addr = EC_START_ADDR;
- + if (get_user((ecinfo.size), (u32 *) ptr)) {
- + printk(KERN_ERR "program ec : get user error.\n");
- + return -EFAULT;
- + }
- + if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) {
- + printk(KERN_ERR "program ec : size out of limited.\n");
- + return -EINVAL;
- + }
- + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
- + if (ecinfo.buf == NULL) {
- + printk(KERN_ERR "program ec : kmalloc failed.\n");
- + return -ENOMEM;
- + }
- + ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size);
- + if (ret) {
- + printk(KERN_ERR "program ec : copy from user error.\n");
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + return -EFAULT;
- + }
- +
- + ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM);
- +
- + kfree(ecinfo.buf);
- + ecinfo.buf = NULL;
- + break;
- +
- + default:
- + break;
- + }
- +
- + return 0;
- +}
- +
- +static long misc_compat_ioctl(struct file *file, unsigned int cmd,
- + unsigned long arg)
- +{
- + return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
- +}
- +
- +static int misc_open(struct inode *inode, struct file *filp)
- +{
- + struct ec_reg *ecreg = NULL;
- + ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL);
- + if (ecreg)
- + filp->private_data = ecreg;
- +
- + return ecreg ? 0 : -ENOMEM;
- +}
- +
- +static int misc_release(struct inode *inode, struct file *filp)
- +{
- + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
- +
- + filp->private_data = NULL;
- + kfree(ecreg);
- +
- + return 0;
- +}
- +
- +static const struct file_operations ecmisc_fops = {
- + .open = misc_open,
- + .release = misc_release,
- + .read = NULL,
- + .write = NULL,
- +#ifdef CONFIG_64BIT
- + .compat_ioctl = misc_compat_ioctl,
- +#else
- + .ioctl = misc_ioctl,
- +#endif
- +};
- +
- +static struct miscdevice ecmisc_device = {
- + .minor = MISC_DYNAMIC_MINOR,
- + .name = EC_MISC_DEV,
- + .fops = &ecmisc_fops
- +};
- +
- +static int __init ecmisc_init(void)
- +{
- + int ret;
- +
- + printk(KERN_INFO "EC misc device init.\n");
- + ret = misc_register(&ecmisc_device);
- +
- + return ret;
- +}
- +
- +static void __exit ecmisc_exit(void)
- +{
- + printk(KERN_INFO "EC misc device exit.\n");
- + misc_deregister(&ecmisc_device);
- +}
- +
- +module_init(ecmisc_init);
- +module_exit(ecmisc_exit);
- +
- +MODULE_AUTHOR("liujl <liujl@lemote.com>");
- +MODULE_DESCRIPTION("Driver for flushing/dumping ROM of EC on YeeLoong laptop");
- +MODULE_LICENSE("GPL");
- diff -Nur linux-2.6.33/drivers/platform/mips/yeeloong_laptop.c linux-lemote/drivers/platform/mips/yeeloong_laptop.c
- --- linux-2.6.33/drivers/platform/mips/yeeloong_laptop.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-lemote/drivers/platform/mips/yeeloong_laptop.c 2010-03-06 16:43:22.000000000 +0100
- @@ -0,0 +1,1194 @@
- +/*
- + * Driver for YeeLoong laptop extras
- + *
- + * Copyright (C) 2009 Lemote Inc.
- + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Liu Junliang <liujl@lemote.com>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + */
- +
- +#include <linux/err.h>
- +#include <linux/platform_device.h>
- +#include <linux/backlight.h> /* for backlight subdriver */
- +#include <linux/fb.h>
- +#include <linux/hwmon.h> /* for hwmon subdriver */
- +#include <linux/hwmon-sysfs.h>
- +#include <linux/video_output.h> /* for video output subdriver */
- +#include <linux/input.h> /* for hotkey subdriver */
- +#include <linux/input/sparse-keymap.h>
- +#include <linux/interrupt.h>
- +#include <linux/delay.h>
- +#include <linux/power_supply.h> /* for AC & Battery subdriver */
- +
- +#include <cs5536/cs5536.h>
- +
- +#include <loongson.h> /* for loongson_cmdline */
- +#include <ec_kb3310b.h>
- +
- +/* common function */
- +#define EC_VER_LEN 64
- +
- +static int ec_ver_small_than(char *version)
- +{
- + char *p, ec_ver[EC_VER_LEN];
- +
- + p = strstr(loongson_cmdline, "EC_VER=");
- + if (!p)
- + memset(ec_ver, 0, EC_VER_LEN);
- + else {
- + strncpy(ec_ver, p, EC_VER_LEN);
- + p = strstr(ec_ver, " ");
- + if (p)
- + *p = '\0';
- + }
- +
- + /* Seems EC(>=PQ1D26) does this job for us, we can not do it again,
- + * otherwise, the brightness will not resume to the normal level! */
- + if (strncasecmp(ec_ver, version, 64) < 0)
- + return 1;
- + return 0;
- +}
- +
- +/* backlight subdriver */
- +#define MAX_BRIGHTNESS 8
- +
- +static int yeeloong_set_brightness(struct backlight_device *bd)
- +{
- + unsigned int level, current_level;
- + static unsigned int old_level;
- +
- + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
- + bd->props.power == FB_BLANK_UNBLANK) ?
- + bd->props.brightness : 0;
- +
- + level = SENSORS_LIMIT(level, 0, MAX_BRIGHTNESS);
- +
- + /* Avoid to modify the brightness when EC is tuning it */
- + if (old_level != level) {
- + current_level = ec_read(REG_DISPLAY_BRIGHTNESS);
- + if (old_level == current_level)
- + ec_write(REG_DISPLAY_BRIGHTNESS, level);
- + old_level = level;
- + }
- +
- + return 0;
- +}
- +
- +static int yeeloong_get_brightness(struct backlight_device *bd)
- +{
- + return ec_read(REG_DISPLAY_BRIGHTNESS);
- +}
- +
- +static struct backlight_ops backlight_ops = {
- + .get_brightness = yeeloong_get_brightness,
- + .update_status = yeeloong_set_brightness,
- +};
- +
- +static struct backlight_device *yeeloong_backlight_dev;
- +
- +static int yeeloong_backlight_init(void)
- +{
- + int ret;
- +
- + yeeloong_backlight_dev = backlight_device_register("backlight0", NULL,
- + NULL, &backlight_ops);
- +
- + if (IS_ERR(yeeloong_backlight_dev)) {
- + ret = PTR_ERR(yeeloong_backlight_dev);
- + yeeloong_backlight_dev = NULL;
- + return ret;
- + }
- +
- + yeeloong_backlight_dev->props.max_brightness = MAX_BRIGHTNESS;
- + yeeloong_backlight_dev->props.brightness =
- + yeeloong_get_brightness(yeeloong_backlight_dev);
- + backlight_update_status(yeeloong_backlight_dev);
- +
- + return 0;
- +}
- +
- +static void yeeloong_backlight_exit(void)
- +{
- + if (yeeloong_backlight_dev) {
- + backlight_device_unregister(yeeloong_backlight_dev);
- + yeeloong_backlight_dev = NULL;
- + }
- +}
- +
- +/* AC & Battery subdriver */
- +
- +static struct power_supply yeeloong_ac, yeeloong_bat;
- +
- +#define AC_OFFLINE 0
- +#define AC_ONLINE 1
- +
- +static int yeeloong_get_ac_props(struct power_supply *psy,
- + enum power_supply_property psp,
- + union power_supply_propval *val)
- +{
- + switch (psp) {
- + case POWER_SUPPLY_PROP_ONLINE:
- + val->intval = ((ec_read(REG_BAT_POWER)) & BIT_BAT_POWER_ACIN) ?
- + AC_ONLINE : AC_OFFLINE;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +static enum power_supply_property yeeloong_ac_props[] = {
- + POWER_SUPPLY_PROP_ONLINE,
- +};
- +
- +static struct power_supply yeeloong_ac = {
- + .name = "yeeloong-ac",
- + .type = POWER_SUPPLY_TYPE_MAINS,
- + .properties = yeeloong_ac_props,
- + .num_properties = ARRAY_SIZE(yeeloong_ac_props),
- + .get_property = yeeloong_get_ac_props,
- +};
- +
- +#define BAT_CAP_CRITICAL 5
- +#define BAT_CAP_HIGH 99
- +
- +#define get_bat_info(type) \
- + ((ec_read(REG_BAT_##type##_HIGH) << 8) | \
- + (ec_read(REG_BAT_##type##_LOW)))
- +
- +static int yeeloong_bat_get_ex_property(enum power_supply_property psp,
- + union power_supply_propval *val)
- +{
- + int bat_in, curr_cap, cap_level, status, charge, health;
- +
- + status = ec_read(REG_BAT_STATUS);
- + bat_in = status & BIT_BAT_STATUS_IN;
- + curr_cap = get_bat_info(RELATIVE_CAP);
- + if (status & BIT_BAT_STATUS_FULL)
- + curr_cap = 100;
- +
- + switch (psp) {
- + case POWER_SUPPLY_PROP_PRESENT:
- + val->intval = bat_in;
- + break;
- + case POWER_SUPPLY_PROP_CAPACITY:
- + val->intval = curr_cap;
- + break;
- + case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
- + if (status & BIT_BAT_STATUS_LOW) {
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
- + if (curr_cap <= BAT_CAP_CRITICAL)
- + cap_level =
- + POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
- + } else if (status & BIT_BAT_STATUS_FULL) {
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
- + if (curr_cap >= BAT_CAP_HIGH)
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
- + } else if (status & BIT_BAT_STATUS_DESTROY)
- + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
- + val->intval = cap_level;
- + break;
- + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
- + /* seconds */
- + val->intval = bat_in ? (curr_cap - 3) * 54 + 142 : 00;
- + break;
- + case POWER_SUPPLY_PROP_STATUS:
- + if (!bat_in)
- + charge = POWER_SUPPLY_STATUS_UNKNOWN;
- + else {
- + if (status & BIT_BAT_STATUS_FULL) {
- + val->intval = POWER_SUPPLY_STATUS_FULL;
- + break;
- + }
- +
- + charge = ec_read(REG_BAT_CHARGE);
- + if (charge & FLAG_BAT_CHARGE_DISCHARGE)
- + charge = POWER_SUPPLY_STATUS_DISCHARGING;
- + else if (charge & FLAG_BAT_CHARGE_CHARGE)
- + charge = POWER_SUPPLY_STATUS_CHARGING;
- + else
- + charge = POWER_SUPPLY_STATUS_NOT_CHARGING;
- + }
- + val->intval = charge;
- + break;
- + case POWER_SUPPLY_PROP_HEALTH:
- + if (!bat_in) /* no battery present */
- + health = POWER_SUPPLY_HEALTH_UNKNOWN;
- + else { /* Assume it is good */
- + health = POWER_SUPPLY_HEALTH_GOOD;
- + if (status &
- + (BIT_BAT_STATUS_DESTROY | BIT_BAT_STATUS_LOW))
- + health = POWER_SUPPLY_HEALTH_DEAD;
- + if (ec_read(REG_BAT_CHARGE_STATUS) &
- + BIT_BAT_CHARGE_STATUS_OVERTEMP)
- + health = POWER_SUPPLY_HEALTH_OVERHEAT;
- + }
- + val->intval = health;
- + break;
- + default:
- + return -EINVAL;
- + }
- + return 0;
- +}
- +
- +static int get_battery_temp(void)
- +{
- + int value;
- +
- + value = get_bat_info(TEMPERATURE);
- +
- + return value * 1000;
- +}
- +
- +static int get_battery_current(void)
- +{
- + s16 value;
- +
- + value = get_bat_info(CURRENT);
- +
- + return -value;
- +}
- +
- +static int get_battery_voltage(void)
- +{
- + int value;
- +
- + value = get_bat_info(VOLTAGE);
- +
- + return value;
- +}
- +
- +static int yeeloong_get_bat_props(struct power_supply *psy,
- + enum power_supply_property psp,
- + union power_supply_propval *val)
- +{
- + switch (psp) {
- + /* Fixed information */
- + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- + val->intval = get_bat_info(DESIGN_CAP) * 1000; /* mV -> 繕V */
- + break;
- + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- + val->intval = get_bat_info(DESIGN_VOL) * 1000; /* mA -> 繕A */
- + break;
- + case POWER_SUPPLY_PROP_CHARGE_FULL:
- + val->intval = get_bat_info(FULLCHG_CAP) * 1000; /* 繕A */
- + break;
- + case POWER_SUPPLY_PROP_MANUFACTURER:
- + val->strval = (ec_read(REG_BAT_VENDOR) ==
- + FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO";
- + break;
- + /* Dynamic information */
- + case POWER_SUPPLY_PROP_CURRENT_NOW:
- + val->intval = get_battery_current() * 1000; /* mA -> 繕A */
- + break;
- + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- + val->intval = get_battery_voltage() * 1000; /* mV -> 繕V */
- + break;
- + case POWER_SUPPLY_PROP_TEMP:
- + val->intval = get_battery_temp(); /* Celcius */
- + break;
- + /* Dynamic but related information */
- + default:
- + return yeeloong_bat_get_ex_property(psp, val);
- + }
- +
- + return 0;
- +}
- +
- +static enum power_supply_property yeeloong_bat_props[] = {
- + POWER_SUPPLY_PROP_STATUS,
- + POWER_SUPPLY_PROP_PRESENT,
- + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
- + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
- + POWER_SUPPLY_PROP_CURRENT_NOW,
- + POWER_SUPPLY_PROP_VOLTAGE_NOW,
- + POWER_SUPPLY_PROP_HEALTH,
- + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
- + POWER_SUPPLY_PROP_CAPACITY,
- + POWER_SUPPLY_PROP_CAPACITY_LEVEL,
- + POWER_SUPPLY_PROP_TEMP,
- + POWER_SUPPLY_PROP_MANUFACTURER,
- +};
- +
- +static struct power_supply yeeloong_bat = {
- + .name = "yeeloong-bat",
- + .type = POWER_SUPPLY_TYPE_BATTERY,
- + .properties = yeeloong_bat_props,
- + .num_properties = ARRAY_SIZE(yeeloong_bat_props),
- + .get_property = yeeloong_get_bat_props,
- +};
- +
- +static int ac_bat_initialized;
- +
- +static int yeeloong_bat_init(void)
- +{
- + int ret;
- +
- + ret = power_supply_register(NULL, &yeeloong_ac);
- + if (ret)
- + return ret;
- + ret = power_supply_register(NULL, &yeeloong_bat);
- + if (ret) {
- + power_supply_unregister(&yeeloong_ac);
- + return ret;
- + }
- + ac_bat_initialized = 1;
- +
- + return 0;
- +}
- +
- +static void yeeloong_bat_exit(void)
- +{
- + ac_bat_initialized = 0;
- +
- + power_supply_unregister(&yeeloong_ac);
- + power_supply_unregister(&yeeloong_bat);
- +}
- +/* hwmon subdriver */
- +
- +#define MIN_FAN_SPEED 0
- +#define MAX_FAN_SPEED 3
- +
- +static int get_fan_pwm_enable(void)
- +{
- + int level, mode;
- +
- + level = ec_read(REG_FAN_SPEED_LEVEL);
- + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
- +
- + if (level == MAX_FAN_SPEED && mode == BIT_FAN_MANUAL)
- + mode = 0;
- + else if (mode == BIT_FAN_MANUAL)
- + mode = 1;
- + else
- + mode = 2;
- +
- + return mode;
- +}
- +
- +static void set_fan_pwm_enable(int mode)
- +{
- + switch (mode) {
- + case 0:
- + /* fullspeed */
- + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
- + ec_write(REG_FAN_SPEED_LEVEL, MAX_FAN_SPEED);
- + break;
- + case 1:
- + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
- + break;
- + case 2:
- + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_AUTO);
- + break;
- + default:
- + break;
- + }
- +}
- +
- +static int get_fan_pwm(void)
- +{
- + return ec_read(REG_FAN_SPEED_LEVEL);
- +}
- +
- +static void set_fan_pwm(int value)
- +{
- + int mode;
- +
- + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
- + if (mode != BIT_FAN_MANUAL)
- + return;
- +
- + value = SENSORS_LIMIT(value, 0, 3);
- +
- + /* We must ensure the fan is on */
- + if (value > 0)
- + ec_write(REG_FAN_CONTROL, BIT_FAN_CONTROL_ON);
- +
- + ec_write(REG_FAN_SPEED_LEVEL, value);
- +}
- +
- +static int get_fan_rpm(void)
- +{
- + int value;
- +
- + value = FAN_SPEED_DIVIDER /
- + (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) |
- + ec_read(REG_FAN_SPEED_LOW));
- +
- + return value;
- +}
- +
- +static int get_cpu_temp(void)
- +{
- + s8 value;
- +
- + value = ec_read(REG_TEMPERATURE_VALUE);
- +
- + return value * 1000;
- +}
- +
- +static int get_cpu_temp_max(void)
- +{
- + return 60 * 1000;
- +}
- +
- +static int get_battery_temp_alarm(void)
- +{
- + int status;
- +
- + status = (ec_read(REG_BAT_CHARGE_STATUS) &
- + BIT_BAT_CHARGE_STATUS_OVERTEMP);
- +
- + return !!status;
- +}
- +
- +static ssize_t store_sys_hwmon(void (*set) (int), const char *buf, size_t count)
- +{
- + int ret;
- + unsigned long value;
- +
- + if (!count)
- + return 0;
- +
- + ret = strict_strtoul(buf, 10, &value);
- + if (ret)
- + return ret;
- +
- + set(value);
- +
- + return count;
- +}
- +
- +static ssize_t show_sys_hwmon(int (*get) (void), char *buf)
- +{
- + return sprintf(buf, "%d\n", get());
- +}
- +
- +#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
- + static ssize_t show_##_name(struct device *dev, \
- + struct device_attribute *attr, \
- + char *buf) \
- + { \
- + return show_sys_hwmon(_set, buf); \
- + } \
- + static ssize_t store_##_name(struct device *dev, \
- + struct device_attribute *attr, \
- + const char *buf, size_t count) \
- + { \
- + return store_sys_hwmon(_get, buf, count); \
- + } \
- + static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
- +
- +CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
- +CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, get_fan_pwm, set_fan_pwm);
- +CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, get_fan_pwm_enable,
- + set_fan_pwm_enable);
- +CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL);
- +CREATE_SENSOR_ATTR(temp1_max, S_IRUGO, get_cpu_temp_max, NULL);
- +CREATE_SENSOR_ATTR(temp2_input, S_IRUGO, get_battery_temp, NULL);
- +CREATE_SENSOR_ATTR(temp2_max_alarm, S_IRUGO, get_battery_temp_alarm, NULL);
- +CREATE_SENSOR_ATTR(curr1_input, S_IRUGO, get_battery_current, NULL);
- +CREATE_SENSOR_ATTR(in1_input, S_IRUGO, get_battery_voltage, NULL);
- +
- +static ssize_t
- +show_name(struct device *dev, struct device_attribute *attr, char *buf)
- +{
- + return sprintf(buf, "yeeloong\n");
- +}
- +
- +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
- +
- +static struct attribute *hwmon_attributes[] = {
- + &sensor_dev_attr_pwm1.dev_attr.attr,
- + &sensor_dev_attr_pwm1_enable.dev_attr.attr,
- + &sensor_dev_attr_fan1_input.dev_attr.attr,
- + &sensor_dev_attr_temp1_input.dev_attr.attr,
- + &sensor_dev_attr_temp1_max.dev_attr.attr,
- + &sensor_dev_attr_temp2_input.dev_attr.attr,
- + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
- + &sensor_dev_attr_curr1_input.dev_attr.attr,
- + &sensor_dev_attr_in1_input.dev_attr.attr,
- + &sensor_dev_attr_name.dev_attr.attr,
- + NULL
- +};
- +
- +static struct attribute_group hwmon_attribute_group = {
- + .attrs = hwmon_attributes
- +};
- +
- +static struct device *yeeloong_hwmon_dev;
- +
- +static int yeeloong_hwmon_init(void)
- +{
- + int ret;
- +
- + yeeloong_hwmon_dev = hwmon_device_register(NULL);
- + if (IS_ERR(yeeloong_hwmon_dev)) {
- + pr_err("Fail to register yeeloong hwmon device\n");
- + yeeloong_hwmon_dev = NULL;
- + return PTR_ERR(yeeloong_hwmon_dev);
- + }
- + ret = sysfs_create_group(&yeeloong_hwmon_dev->kobj,
- + &hwmon_attribute_group);
- + if (ret) {
- + hwmon_device_unregister(yeeloong_hwmon_dev);
- + yeeloong_hwmon_dev = NULL;
- + return ret;
- + }
- + /* ensure fan is set to auto mode */
- + set_fan_pwm_enable(2);
- +
- + return 0;
- +}
- +
- +static void yeeloong_hwmon_exit(void)
- +{
- + if (yeeloong_hwmon_dev) {
- + sysfs_remove_group(&yeeloong_hwmon_dev->kobj,
- + &hwmon_attribute_group);
- + hwmon_device_unregister(yeeloong_hwmon_dev);
- + yeeloong_hwmon_dev = NULL;
- + }
- +}
- +
- +/* video output subdriver */
- +
- +static int lcd_video_output_get(struct output_device *od)
- +{
- + return ec_read(REG_DISPLAY_LCD);
- +}
- +
- +#define LCD 0
- +#define CRT 1
- +
- +static void display_vo_set(int display, int on)
- +{
- + int addr;
- + unsigned long value;
- +
- + addr = (display == LCD) ? 0x31 : 0x21;
- +
- + outb(addr, 0x3c4);
- + value = inb(0x3c5);
- +
- + if (display == LCD)
- + value |= (on ? 0x03 : 0x02);
- + else {
- + if (on)
- + clear_bit(7, &value);
- + else
- + set_bit(7, &value);
- + }
- +
- + outb(addr, 0x3c4);
- + outb(value, 0x3c5);
- +}
- +
- +static int lcd_video_output_set(struct output_device *od)
- +{
- + unsigned long status;
- +
- + status = !!od->request_state;
- +
- + display_vo_set(LCD, status);
- + ec_write(REG_BACKLIGHT_CTRL, status);
- +
- + return 0;
- +}
- +
- +static struct output_properties lcd_output_properties = {
- + .set_state = lcd_video_output_set,
- + .get_status = lcd_video_output_get,
- +};
- +
- +static int crt_video_output_get(struct output_device *od)
- +{
- + return ec_read(REG_CRT_DETECT);
- +}
- +
- +static int crt_video_output_set(struct output_device *od)
- +{
- + unsigned long status;
- +
- + status = !!od->request_state;
- +
- + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_PLUG)
- + display_vo_set(CRT, status);
- +
- + return 0;
- +}
- +
- +static struct output_properties crt_output_properties = {
- + .set_state = crt_video_output_set,
- + .get_status = crt_video_output_get,
- +};
- +
- +static struct output_device *lcd_output_dev, *crt_output_dev;
- +
- +static void yeeloong_lcd_vo_set(int status)
- +{
- + if (ec_ver_small_than("EC_VER=PQ1D27")) {
- + lcd_output_dev->request_state = status;
- + lcd_video_output_set(lcd_output_dev);
- + }
- +}
- +
- +static void yeeloong_crt_vo_set(int status)
- +{
- + crt_output_dev->request_state = status;
- + crt_video_output_set(crt_output_dev);
- +}
- +
- +static int yeeloong_vo_init(void)
- +{
- + int ret;
- +
- + /* Register video output device: lcd, crt */
- + lcd_output_dev = video_output_register("LCD", NULL, NULL,
- + &lcd_output_properties);
- +
- + if (IS_ERR(lcd_output_dev)) {
- + ret = PTR_ERR(lcd_output_dev);
- + lcd_output_dev = NULL;
- + return ret;
- + }
- + /* Ensure LCD is on by default */
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- +
- + crt_output_dev = video_output_register("CRT", NULL, NULL,
- + &crt_output_properties);
- +
- + if (IS_ERR(crt_output_dev)) {
- + ret = PTR_ERR(crt_output_dev);
- + crt_output_dev = NULL;
- + return ret;
- + }
- +
- + /* Turn off CRT by default, and will be enabled when the CRT
- + * connectting event reported by SCI */
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- +
- + return 0;
- +}
- +
- +static void yeeloong_vo_exit(void)
- +{
- + if (lcd_output_dev) {
- + video_output_unregister(lcd_output_dev);
- + lcd_output_dev = NULL;
- + }
- + if (crt_output_dev) {
- + video_output_unregister(crt_output_dev);
- + crt_output_dev = NULL;
- + }
- +}
- +
- +/* hotkey subdriver */
- +
- +static struct input_dev *yeeloong_hotkey_dev;
- +
- +static const struct key_entry yeeloong_keymap[] = {
- + {KE_SW, EVENT_LID, { SW_LID } },
- + {KE_KEY, EVENT_CAMERA, { KEY_CAMERA } }, /* Fn + ESC */
- + {KE_KEY, EVENT_SLEEP, { KEY_SLEEP } }, /* Fn + F1 */
- + {KE_KEY, EVENT_DISPLAY_TOGGLE, { KEY_SWITCHVIDEOMODE } }, /* Fn + F3 */
- + {KE_KEY, EVENT_AUDIO_MUTE, { KEY_MUTE } }, /* Fn + F4 */
- + {KE_KEY, EVENT_WLAN, { KEY_WLAN } }, /* Fn + F5 */
- + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSUP } }, /* Fn + up */
- + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSDOWN } }, /* Fn + down */
- + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEUP } }, /* Fn + right */
- + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEDOWN } }, /* Fn + left */
- + {KE_END, 0}
- +};
- +
- +static struct key_entry *get_event_key_entry(int event, int status)
- +{
- + struct key_entry *ke;
- + static int old_brightness_status = -1;
- + static int old_volume_status = -1;
- +
- + ke = sparse_keymap_entry_from_scancode(yeeloong_hotkey_dev, event);
- + if (!ke)
- + return NULL;
- +
- + switch (event) {
- + case EVENT_DISPLAY_BRIGHTNESS:
- + /* current status > old one, means up */
- + if ((status < old_brightness_status) || (0 == status))
- + ke++;
- + old_brightness_status = status;
- + break;
- + case EVENT_AUDIO_VOLUME:
- + if ((status < old_volume_status) || (0 == status))
- + ke++;
- + old_volume_status = status;
- + break;
- + default:
- + break;
- + }
- +
- + return ke;
- +}
- +
- +static int report_lid_switch(int status)
- +{
- + input_report_switch(yeeloong_hotkey_dev, SW_LID, !status);
- + input_sync(yeeloong_hotkey_dev);
- +
- + return status;
- +}
- +
- +static int crt_detect_handler(int status)
- +{
- + if (status) {
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + } else {
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + }
- + return status;
- +}
- +
- +static int black_screen_handler(int status)
- +{
- + if (ec_ver_small_than("EC_VER=PQ1D26"))
- + yeeloong_lcd_vo_set(status);
- +
- + return status;
- +}
- +
- +static int display_toggle_handler(int status)
- +{
- + static int video_output_status;
- +
- + /* Only enable switch video output button
- + * when CRT is connected */
- + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_UNPLUG)
- + return 0;
- + /* 0. no CRT connected: LCD on, CRT off
- + * 1. BOTH on
- + * 2. LCD off, CRT on
- + * 3. BOTH off
- + * 4. LCD on, CRT off
- + */
- + video_output_status++;
- + if (video_output_status > 4)
- + video_output_status = 1;
- +
- + switch (video_output_status) {
- + case 1:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + break;
- + case 2:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + break;
- + case 3:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + break;
- + case 4:
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + break;
- + default:
- + /* Ensure LCD is on */
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + break;
- + }
- + return video_output_status;
- +}
- +
- +static int camera_handler(int status)
- +{
- + int value;
- +
- + value = ec_read(REG_CAMERA_CONTROL);
- + ec_write(REG_CAMERA_CONTROL, value | (1 << 1));
- +
- + return status;
- +}
- +
- +static int usb2_handler(int status)
- +{
- + pr_emerg("USB2 Over Current occurred\n");
- +
- + return status;
- +}
- +
- +static int usb0_handler(int status)
- +{
- + pr_emerg("USB0 Over Current occurred\n");
- +
- + return status;
- +}
- +
- +static int ac_bat_handler(int status)
- +{
- + if (ac_bat_initialized) {
- + power_supply_changed(&yeeloong_ac);
- + power_supply_changed(&yeeloong_bat);
- + }
- + return status;
- +}
- +
- +static void do_event_action(int event)
- +{
- + sci_handler handler;
- + int reg, status;
- + struct key_entry *ke;
- +
- + reg = 0;
- + handler = NULL;
- +
- + switch (event) {
- + case EVENT_LID:
- + reg = REG_LID_DETECT;
- + break;
- + case EVENT_DISPLAY_TOGGLE:
- + handler = display_toggle_handler;
- + break;
- + case EVENT_CRT_DETECT:
- + reg = REG_CRT_DETECT;
- + handler = crt_detect_handler;
- + break;
- + case EVENT_CAMERA:
- + reg = REG_CAMERA_STATUS;
- + handler = camera_handler;
- + break;
- + case EVENT_USB_OC2:
- + reg = REG_USB2_FLAG;
- + handler = usb2_handler;
- + break;
- + case EVENT_USB_OC0:
- + reg = REG_USB0_FLAG;
- + handler = usb0_handler;
- + break;
- + case EVENT_BLACK_SCREEN:
- + reg = REG_DISPLAY_LCD;
- + handler = black_screen_handler;
- + break;
- + case EVENT_AUDIO_MUTE:
- + reg = REG_AUDIO_MUTE;
- + break;
- + case EVENT_DISPLAY_BRIGHTNESS:
- + reg = REG_DISPLAY_BRIGHTNESS;
- + break;
- + case EVENT_AUDIO_VOLUME:
- + reg = REG_AUDIO_VOLUME;
- + break;
- + case EVENT_AC_BAT:
- + handler = ac_bat_handler;
- + break;
- + default:
- + break;
- + }
- +
- + if (reg != 0)
- + status = ec_read(reg);
- +
- + if (handler != NULL)
- + status = handler(status);
- +
- + pr_info("%s: event: %d status: %d\n", __func__, event, status);
- +
- + /* Report current key to user-space */
- + ke = get_event_key_entry(event, status);
- + if (ke) {
- + if (ke->keycode == SW_LID)
- + report_lid_switch(status);
- + else
- + sparse_keymap_report_entry(yeeloong_hotkey_dev, ke, 1,
- + true);
- + }
- +}
- +
- +/*
- + * SCI(system control interrupt) main interrupt routine
- + *
- + * We will do the query and get event number together so the interrupt routine
- + * should be longer than 120us now at least 3ms elpase for it.
- + */
- +static irqreturn_t sci_irq_handler(int irq, void *dev_id)
- +{
- + int ret, event;
- +
- + if (SCI_IRQ_NUM != irq)
- + return IRQ_NONE;
- +
- + /* Query the event number */
- + ret = ec_query_event_num();
- + if (ret < 0)
- + return IRQ_NONE;
- +
- + event = ec_get_event_num();
- + if (event < EVENT_START || event > EVENT_END)
- + return IRQ_NONE;
- +
- + /* Execute corresponding actions */
- + do_event_action(event);
- +
- + return IRQ_HANDLED;
- +}
- +
- +/*
- + * Config and init some msr and gpio register properly.
- + */
- +static int sci_irq_init(void)
- +{
- + u32 hi, lo;
- + u32 gpio_base;
- + unsigned long flags;
- + int ret;
- +
- + /* Get gpio base */
- + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
- + gpio_base = lo & 0xff00;
- +
- + /* Filter the former kb3310 interrupt for security */
- + ret = ec_query_event_num();
- + if (ret)
- + return ret;
- +
- + /* For filtering next number interrupt */
- + udelay(10000);
- +
- + /* Set gpio native registers and msrs for GPIO27 SCI EVENT PIN
- + * gpio :
- + * input, pull-up, no-invert, event-count and value 0,
- + * no-filter, no edge mode
- + * gpio27 map to Virtual gpio0
- + * msr :
- + * no primary and lpc
- + * Unrestricted Z input to IG10 from Virtual gpio 0.
- + */
- + local_irq_save(flags);
- + _rdmsr(0x80000024, &hi, &lo);
- + lo &= ~(1 << 10);
- + _wrmsr(0x80000024, hi, lo);
- + _rdmsr(0x80000025, &hi, &lo);
- + lo &= ~(1 << 10);
- + _wrmsr(0x80000025, hi, lo);
- + _rdmsr(0x80000023, &hi, &lo);
- + lo |= (0x0a << 0);
- + _wrmsr(0x80000023, hi, lo);
- + local_irq_restore(flags);
- +
- + /* Set gpio27 as sci interrupt
- + *
- + * input, pull-up, no-fliter, no-negedge, invert
- + * the sci event is just about 120us
- + */
- + asm(".set noreorder\n");
- + /* input enable */
- + outl(0x00000800, (gpio_base | 0xA0));
- + /* revert the input */
- + outl(0x00000800, (gpio_base | 0xA4));
- + /* event-int enable */
- + outl(0x00000800, (gpio_base | 0xB8));
- + asm(".set reorder\n");
- +
- + return 0;
- +}
- +
- +static struct irqaction sci_irqaction = {
- + .handler = sci_irq_handler,
- + .name = "sci",
- + .flags = IRQF_SHARED,
- +};
- +
- +static int yeeloong_hotkey_init(void)
- +{
- + int ret;
- +
- + ret = sci_irq_init();
- + if (ret)
- + return -EFAULT;
- +
- + ret = setup_irq(SCI_IRQ_NUM, &sci_irqaction);
- + if (ret)
- + return -EFAULT;
- +
- + yeeloong_hotkey_dev = input_allocate_device();
- +
- + if (!yeeloong_hotkey_dev) {
- + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
- + return -ENOMEM;
- + }
- +
- + yeeloong_hotkey_dev->name = "HotKeys";
- + yeeloong_hotkey_dev->phys = "button/input0";
- + yeeloong_hotkey_dev->id.bustype = BUS_HOST;
- + yeeloong_hotkey_dev->dev.parent = NULL;
- +
- + ret = sparse_keymap_setup(yeeloong_hotkey_dev, yeeloong_keymap, NULL);
- + if (ret) {
- + pr_err("Fail to setup input device keymap\n");
- + input_free_device(yeeloong_hotkey_dev);
- + return ret;
- + }
- +
- + ret = input_register_device(yeeloong_hotkey_dev);
- + if (ret) {
- + sparse_keymap_free(yeeloong_hotkey_dev);
- + input_free_device(yeeloong_hotkey_dev);
- + return ret;
- + }
- +
- + /* Update the current status of LID */
- + report_lid_switch(BIT_LID_DETECT_ON);
- +
- +#ifdef CONFIG_LOONGSON_SUSPEND
- + /* Install the real yeeloong_report_lid_status for pm.c */
- + yeeloong_report_lid_status = report_lid_switch;
- +#endif
- +
- + return 0;
- +}
- +
- +static void yeeloong_hotkey_exit(void)
- +{
- + /* Free irq */
- + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
- +
- +#ifdef CONFIG_LOONGSON_SUSPEND
- + /* Uninstall yeeloong_report_lid_status for pm.c */
- + if (yeeloong_report_lid_status == report_lid_switch)
- + yeeloong_report_lid_status = NULL;
- +#endif
- +
- + if (yeeloong_hotkey_dev) {
- + sparse_keymap_free(yeeloong_hotkey_dev);
- + input_unregister_device(yeeloong_hotkey_dev);
- + yeeloong_hotkey_dev = NULL;
- + }
- +}
- +
- +#ifdef CONFIG_PM
- +static void usb_ports_set(int status)
- +{
- + status = !!status;
- +
- + ec_write(REG_USB0_FLAG, status);
- + ec_write(REG_USB1_FLAG, status);
- + ec_write(REG_USB2_FLAG, status);
- +}
- +
- +static int yeeloong_suspend(struct device *dev)
- +
- +{
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
- + usb_ports_set(BIT_USB_FLAG_OFF);
- +
- + return 0;
- +}
- +
- +static int yeeloong_resume(struct device *dev)
- +{
- + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
- + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
- + usb_ports_set(BIT_USB_FLAG_ON);
- +
- + return 0;
- +}
- +
- +static const SIMPLE_DEV_PM_OPS(yeeloong_pm_ops, yeeloong_suspend,
- + yeeloong_resume);
- +#endif
- +
- +static struct platform_device_id platform_device_ids[] = {
- + {
- + .name = "yeeloong_laptop",
- + },
- + {}
- +};
- +
- +MODULE_DEVICE_TABLE(platform, platform_device_ids);
- +
- +static struct platform_driver platform_driver = {
- + .driver = {
- + .name = "yeeloong_laptop",
- + .owner = THIS_MODULE,
- +#ifdef CONFIG_PM
- + .pm = &yeeloong_pm_ops,
- +#endif
- + },
- + .id_table = platform_device_ids,
- +};
- +
- +static int __init yeeloong_init(void)
- +{
- + int ret;
- +
- + pr_info("Load YeeLoong Laptop Platform Specific Driver.\n");
- +
- + /* Register platform stuff */
- + ret = platform_driver_register(&platform_driver);
- + if (ret) {
- + pr_err("Fail to register yeeloong platform driver.\n");
- + return ret;
- + }
- +
- + ret = yeeloong_backlight_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong backlight driver.\n");
- + yeeloong_backlight_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_bat_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong battery driver.\n");
- + yeeloong_bat_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_hwmon_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong hwmon driver.\n");
- + yeeloong_hwmon_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_vo_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong video output driver.\n");
- + yeeloong_vo_exit();
- + return ret;
- + }
- +
- + ret = yeeloong_hotkey_init();
- + if (ret) {
- + pr_err("Fail to register yeeloong hotkey driver.\n");
- + yeeloong_hotkey_exit();
- + return ret;
- + }
- +
- + return 0;
- +}
- +
- +static void __exit yeeloong_exit(void)
- +{
- + yeeloong_hotkey_exit();
- + yeeloong_vo_exit();
- + yeeloong_hwmon_exit();
- + yeeloong_bat_exit();
- + yeeloong_backlight_exit();
- + platform_driver_unregister(&platform_driver);
- +
- + pr_info("Unload YeeLoong Platform Specific Driver.\n");
- +}
- +
- +module_init(yeeloong_init);
- +module_exit(yeeloong_exit);
- +
- +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Liu Junliang <liujl@lemote.com>");
- +MODULE_DESCRIPTION("YeeLoong laptop driver");
- +MODULE_LICENSE("GPL");
- diff -Nur linux-2.6.33/drivers/rtc/rtc-cmos.c linux-lemote/drivers/rtc/rtc-cmos.c
- --- linux-2.6.33/drivers/rtc/rtc-cmos.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/rtc/rtc-cmos.c 2010-03-06 16:43:22.000000000 +0100
- @@ -752,9 +752,8 @@
- /* FIXME teach the alarm code how to handle binary mode;
- * <asm-generic/rtc.h> doesn't know 12-hour mode either.
- */
- - if (is_valid_irq(rtc_irq) &&
- - (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) {
- - dev_dbg(dev, "only 24-hr BCD mode supported\n");
- + if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
- + dev_dbg(dev, "only 24-hr supported\n");
- retval = -ENXIO;
- goto cleanup1;
- }
- diff -Nur linux-2.6.33/drivers/staging/sm7xx/Kconfig linux-lemote/drivers/staging/sm7xx/Kconfig
- --- linux-2.6.33/drivers/staging/sm7xx/Kconfig 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/staging/sm7xx/Kconfig 2010-03-06 16:43:30.000000000 +0100
- @@ -6,10 +6,3 @@
- select FB_CFB_IMAGEBLIT
- help
- Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
- -
- -config FB_SM7XX_ACCEL
- - bool "Siliconmotion Acceleration functions (EXPERIMENTAL)"
- - depends on FB_SM7XX && EXPERIMENTAL
- - help
- - This will compile the Trident frame buffer device with
- - acceleration functions.
- diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtc2d.c linux-lemote/drivers/staging/sm7xx/smtc2d.c
- --- linux-2.6.33/drivers/staging/sm7xx/smtc2d.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/staging/sm7xx/smtc2d.c 1970-01-01 01:00:00.000000000 +0100
- @@ -1,979 +0,0 @@
- -/*
- - * Silicon Motion SM7XX 2D drawing engine functions.
- - *
- - * Copyright (C) 2006 Silicon Motion Technology Corp.
- - * Author: Boyod boyod.yang@siliconmotion.com.cn
- - *
- - * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- - *
- - * This file is subject to the terms and conditions of the GNU General Public
- - * License. See the file COPYING in the main directory of this archive for
- - * more details.
- - *
- - * Version 0.10.26192.21.01
- - * - Add PowerPC support
- - * - Add 2D support for Lynx -
- - * Verified on 2.6.19.2
- - * Boyod.yang <boyod.yang@siliconmotion.com.cn>
- - */
- -
- -unsigned char smtc_de_busy;
- -
- -void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData)
- -{
- - writel(nData, smtc_2DBaseAddress + nOffset);
- -}
- -
- -unsigned long SMTC_read2Dreg(unsigned long nOffset)
- -{
- - return readl(smtc_2DBaseAddress + nOffset);
- -}
- -
- -void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData)
- -{
- - writel(nData, smtc_2Ddataport + nOffset);
- -}
- -
- -/**********************************************************************
- - *
- - * deInit
- - *
- - * Purpose
- - * Drawing engine initialization.
- - *
- - **********************************************************************/
- -
- -void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
- - unsigned int bpp)
- -{
- - /* Get current power configuration. */
- - unsigned char clock;
- - clock = smtc_seqr(0x21);
- -
- - /* initialize global 'mutex lock' variable */
- - smtc_de_busy = 0;
- -
- - /* Enable 2D Drawing Engine */
- - smtc_seqw(0x21, clock & 0xF8);
- -
- - SMTC_write2Dreg(DE_CLIP_TL,
- - FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) |
- - FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) |
- - FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) |
- - FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0));
- -
- - if (bpp >= 24) {
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION,
- - nModeWidth * 3) | FIELD_VALUE(0,
- - DE_PITCH,
- - SOURCE,
- - nModeWidth
- - * 3));
- - } else {
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION,
- - nModeWidth) | FIELD_VALUE(0,
- - DE_PITCH,
- - SOURCE,
- - nModeWidth));
- - }
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - nModeWidth) | FIELD_VALUE(0,
- - DE_WINDOW_WIDTH,
- - SOURCE,
- - nModeWidth));
- -
- - switch (bpp) {
- - case 8:
- - SMTC_write2Dreg(DE_STRETCH_FORMAT,
- - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
- - NORMAL) | FIELD_VALUE(0,
- - DE_STRETCH_FORMAT,
- - PATTERN_Y,
- - 0) |
- - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
- - 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
- - PIXEL_FORMAT,
- - 8) | FIELD_SET(0,
- - DE_STRETCH_FORMAT,
- - ADDRESSING,
- - XY) |
- - FIELD_VALUE(0, DE_STRETCH_FORMAT,
- - SOURCE_HEIGHT, 3));
- - break;
- - case 24:
- - SMTC_write2Dreg(DE_STRETCH_FORMAT,
- - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
- - NORMAL) | FIELD_VALUE(0,
- - DE_STRETCH_FORMAT,
- - PATTERN_Y,
- - 0) |
- - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
- - 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
- - PIXEL_FORMAT,
- - 24) | FIELD_SET(0,
- - DE_STRETCH_FORMAT,
- - ADDRESSING,
- - XY) |
- - FIELD_VALUE(0, DE_STRETCH_FORMAT,
- - SOURCE_HEIGHT, 3));
- - break;
- - case 16:
- - default:
- - SMTC_write2Dreg(DE_STRETCH_FORMAT,
- - FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
- - NORMAL) | FIELD_VALUE(0,
- - DE_STRETCH_FORMAT,
- - PATTERN_Y,
- - 0) |
- - FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
- - 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
- - PIXEL_FORMAT,
- - 16) | FIELD_SET(0,
- - DE_STRETCH_FORMAT,
- - ADDRESSING,
- - XY) |
- - FIELD_VALUE(0, DE_STRETCH_FORMAT,
- - SOURCE_HEIGHT, 3));
- - break;
- - }
- -
- - SMTC_write2Dreg(DE_MASKS,
- - FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) |
- - FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF));
- - SMTC_write2Dreg(DE_COLOR_COMPARE_MASK,
- - FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \
- - 0xFFFFFF));
- - SMTC_write2Dreg(DE_COLOR_COMPARE,
- - FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
- -}
- -
- -void deVerticalLine(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long nX,
- - unsigned long nY,
- - unsigned long dst_height, unsigned long nColor)
- -{
- - deWaitForNotBusy();
- -
- - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- - dst_base));
- -
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
- - FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
- - SOURCE,
- - dst_pitch));
- -
- - SMTC_write2Dreg(DE_FOREGROUND,
- - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
- -
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_DESTINATION, X, nX) |
- - FIELD_VALUE(0, DE_DESTINATION, Y, nY));
- -
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X, 1) |
- - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
- -
- - SMTC_write2Dreg(DE_CONTROL,
- - FIELD_SET(0, DE_CONTROL, STATUS, START) |
- - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
- - FIELD_SET(0, DE_CONTROL, MAJOR, Y) |
- - FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) |
- - FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
- - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
- - FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) |
- - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
- -
- - smtc_de_busy = 1;
- -}
- -
- -void deHorizontalLine(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long nX,
- - unsigned long nY,
- - unsigned long dst_width, unsigned long nColor)
- -{
- - deWaitForNotBusy();
- -
- - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- - dst_base));
- -
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
- - FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
- - SOURCE,
- - dst_pitch));
- - SMTC_write2Dreg(DE_FOREGROUND,
- - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP,
- - DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X,
- - nX) | FIELD_VALUE(0,
- - DE_DESTINATION,
- - Y,
- - nY));
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X,
- - dst_width) | FIELD_VALUE(0, DE_DIMENSION,
- - Y_ET, 1));
- - SMTC_write2Dreg(DE_CONTROL,
- - FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0,
- - DE_CONTROL,
- - DIRECTION,
- - RIGHT_TO_LEFT)
- - | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0,
- - DE_CONTROL,
- - STEP_X,
- - POSITIVE)
- - | FIELD_SET(0, DE_CONTROL, STEP_Y,
- - NEGATIVE) | FIELD_SET(0, DE_CONTROL,
- - LAST_PIXEL,
- - OFF) | FIELD_SET(0,
- - DE_CONTROL,
- - COMMAND,
- - SHORT_STROKE)
- - | FIELD_SET(0, DE_CONTROL, ROP_SELECT,
- - ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP,
- - 0x0C));
- -
- - smtc_de_busy = 1;
- -}
- -
- -void deLine(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long nX1,
- - unsigned long nY1,
- - unsigned long nX2, unsigned long nY2, unsigned long nColor)
- -{
- - unsigned long nCommand =
- - FIELD_SET(0, DE_CONTROL, STATUS, START) |
- - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
- - FIELD_SET(0, DE_CONTROL, MAJOR, X) |
- - FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) |
- - FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
- - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
- - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C);
- - unsigned long DeltaX;
- - unsigned long DeltaY;
- -
- - /* Calculate delta X */
- - if (nX1 <= nX2)
- - DeltaX = nX2 - nX1;
- - else {
- - DeltaX = nX1 - nX2;
- - nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE);
- - }
- -
- - /* Calculate delta Y */
- - if (nY1 <= nY2)
- - DeltaY = nY2 - nY1;
- - else {
- - DeltaY = nY1 - nY2;
- - nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE);
- - }
- -
- - /* Determine the major axis */
- - if (DeltaX < DeltaY)
- - nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y);
- -
- - /* Vertical line? */
- - if (nX1 == nX2)
- - deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor);
- -
- - /* Horizontal line? */
- - else if (nY1 == nY2)
- - deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \
- - DeltaX, nColor);
- -
- - /* Diagonal line? */
- - else if (DeltaX == DeltaY) {
- - deWaitForNotBusy();
- -
- - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
- - ADDRESS, dst_base));
- -
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_PITCH,
- - SOURCE,
- - dst_pitch));
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_WINDOW_WIDTH,
- - SOURCE,
- - dst_pitch));
- -
- - SMTC_write2Dreg(DE_FOREGROUND,
- - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
- -
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_DESTINATION, X, 1) |
- - FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
- -
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X, 1) |
- - FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX));
- -
- - SMTC_write2Dreg(DE_CONTROL,
- - FIELD_SET(nCommand, DE_CONTROL, COMMAND,
- - SHORT_STROKE));
- - }
- -
- - /* Generic line */
- - else {
- - unsigned int k1, k2, et, w;
- - if (DeltaX < DeltaY) {
- - k1 = 2 * DeltaX;
- - et = k1 - DeltaY;
- - k2 = et - DeltaY;
- - w = DeltaY + 1;
- - } else {
- - k1 = 2 * DeltaY;
- - et = k1 - DeltaX;
- - k2 = et - DeltaX;
- - w = DeltaX + 1;
- - }
- -
- - deWaitForNotBusy();
- -
- - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
- - ADDRESS, dst_base));
- -
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_PITCH,
- - SOURCE,
- - dst_pitch));
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_WINDOW_WIDTH,
- - SOURCE,
- - dst_pitch));
- -
- - SMTC_write2Dreg(DE_FOREGROUND,
- - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
- -
- - SMTC_write2Dreg(DE_SOURCE,
- - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_SOURCE, X_K1, k1) |
- - FIELD_VALUE(0, DE_SOURCE, Y_K2, k2));
- -
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_DESTINATION, X, nX1) |
- - FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
- -
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X, w) |
- - FIELD_VALUE(0, DE_DIMENSION, Y_ET, et));
- -
- - SMTC_write2Dreg(DE_CONTROL,
- - FIELD_SET(nCommand, DE_CONTROL, COMMAND,
- - LINE_DRAW));
- - }
- -
- - smtc_de_busy = 1;
- -}
- -
- -void deFillRect(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long dst_X,
- - unsigned long dst_Y,
- - unsigned long dst_width,
- - unsigned long dst_height, unsigned long nColor)
- -{
- - deWaitForNotBusy();
- -
- - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- - dst_base));
- -
- - if (dst_pitch) {
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_PITCH,
- - SOURCE,
- - dst_pitch));
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_WINDOW_WIDTH,
- - SOURCE,
- - dst_pitch));
- - }
- -
- - SMTC_write2Dreg(DE_FOREGROUND,
- - FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
- -
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
- - FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
- -
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
- - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
- -
- - SMTC_write2Dreg(DE_CONTROL,
- - FIELD_SET(0, DE_CONTROL, STATUS, START) |
- - FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
- - FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
- - FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) |
- - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- - FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
- -
- - smtc_de_busy = 1;
- -}
- -
- -/**********************************************************************
- - *
- - * deRotatePattern
- - *
- - * Purpose
- - * Rotate the given pattern if necessary
- - *
- - * Parameters
- - * [in]
- - * pPattern - Pointer to DE_SURFACE structure containing
- - * pattern attributes
- - * patternX - X position (0-7) of pattern origin
- - * patternY - Y position (0-7) of pattern origin
- - *
- - * [out]
- - * pattern_dstaddr - Pointer to pre-allocated buffer containing
- - * rotated pattern
- - *
- - **********************************************************************/
- -void deRotatePattern(unsigned char *pattern_dstaddr,
- - unsigned long pattern_src_addr,
- - unsigned long pattern_BPP,
- - unsigned long pattern_stride, int patternX, int patternY)
- -{
- - unsigned int i;
- - unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT];
- - unsigned int x, y;
- - unsigned char *pjPatByte;
- -
- - if (pattern_dstaddr != NULL) {
- - deWaitForNotBusy();
- -
- - if (patternX || patternY) {
- - /* Rotate pattern */
- - pjPatByte = (unsigned char *)pattern;
- -
- - switch (pattern_BPP) {
- - case 8:
- - {
- - for (y = 0; y < 8; y++) {
- - unsigned char *pjBuffer =
- - pattern_dstaddr +
- - ((patternY + y) & 7) * 8;
- - for (x = 0; x < 8; x++) {
- - pjBuffer[(patternX +
- - x) & 7] =
- - pjPatByte[x];
- - }
- - pjPatByte += pattern_stride;
- - }
- - break;
- - }
- -
- - case 16:
- - {
- - for (y = 0; y < 8; y++) {
- - unsigned short *pjBuffer =
- - (unsigned short *)
- - pattern_dstaddr +
- - ((patternY + y) & 7) * 8;
- - for (x = 0; x < 8; x++) {
- - pjBuffer[(patternX +
- - x) & 7] =
- - ((unsigned short *)
- - pjPatByte)[x];
- - }
- - pjPatByte += pattern_stride;
- - }
- - break;
- - }
- -
- - case 32:
- - {
- - for (y = 0; y < 8; y++) {
- - unsigned long *pjBuffer =
- - (unsigned long *)
- - pattern_dstaddr +
- - ((patternY + y) & 7) * 8;
- - for (x = 0; x < 8; x++) {
- - pjBuffer[(patternX +
- - x) & 7] =
- - ((unsigned long *)
- - pjPatByte)[x];
- - }
- - pjPatByte += pattern_stride;
- - }
- - break;
- - }
- - }
- - } else {
- - /*Don't rotate,just copy pattern into pattern_dstaddr*/
- - for (i = 0; i < (pattern_BPP * 2); i++) {
- - ((unsigned long *)pattern_dstaddr)[i] =
- - pattern[i];
- - }
- - }
- -
- - }
- -}
- -
- -/**********************************************************************
- - *
- - * deCopy
- - *
- - * Purpose
- - * Copy a rectangular area of the source surface to a destination surface
- - *
- - * Remarks
- - * Source bitmap must have the same color depth (BPP) as the destination
- - * bitmap.
- - *
- -**********************************************************************/
- -void deCopy(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long dst_BPP,
- - unsigned long dst_X,
- - unsigned long dst_Y,
- - unsigned long dst_width,
- - unsigned long dst_height,
- - unsigned long src_base,
- - unsigned long src_pitch,
- - unsigned long src_X,
- - unsigned long src_Y, pTransparent pTransp, unsigned char nROP2)
- -{
- - unsigned long nDirection = 0;
- - unsigned long nTransparent = 0;
- - /* Direction of ROP2 operation:
- - * 1 = Left to Right,
- - * (-1) = Right to Left
- - */
- - unsigned long opSign = 1;
- - /* xWidth is in pixels */
- - unsigned long xWidth = 192 / (dst_BPP / 8);
- - unsigned long de_ctrl = 0;
- -
- - deWaitForNotBusy();
- -
- - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
- - FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
- - dst_base));
- -
- - SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE,
- - FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS,
- - src_base));
- -
- - if (dst_pitch && src_pitch) {
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_PITCH,
- - SOURCE,
- - src_pitch));
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - dst_pitch) | FIELD_VALUE(0,
- - DE_WINDOW_WIDTH,
- - SOURCE,
- - src_pitch));
- - }
- -
- - /* Set transparent bits if necessary */
- - if (pTransp != NULL) {
- - nTransparent =
- - pTransp->match | pTransp->select | pTransp->control;
- -
- - /* Set color compare register */
- - SMTC_write2Dreg(DE_COLOR_COMPARE,
- - FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR,
- - pTransp->color));
- - }
- -
- - /* Determine direction of operation */
- - if (src_Y < dst_Y) {
- - /* +----------+
- - |S |
- - | +----------+
- - | | | |
- - | | | |
- - +---|------+ |
- - | D |
- - +----------+ */
- -
- - nDirection = BOTTOM_TO_TOP;
- - } else if (src_Y > dst_Y) {
- - /* +----------+
- - |D |
- - | +----------+
- - | | | |
- - | | | |
- - +---|------+ |
- - | S |
- - +----------+ */
- -
- - nDirection = TOP_TO_BOTTOM;
- - } else {
- - /* src_Y == dst_Y */
- -
- - if (src_X <= dst_X) {
- - /* +------+---+------+
- - |S | | D|
- - | | | |
- - | | | |
- - | | | |
- - +------+---+------+ */
- -
- - nDirection = RIGHT_TO_LEFT;
- - } else {
- - /* src_X > dst_X */
- -
- - /* +------+---+------+
- - |D | | S|
- - | | | |
- - | | | |
- - | | | |
- - +------+---+------+ */
- -
- - nDirection = LEFT_TO_RIGHT;
- - }
- - }
- -
- - if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
- - src_X += dst_width - 1;
- - src_Y += dst_height - 1;
- - dst_X += dst_width - 1;
- - dst_Y += dst_height - 1;
- - opSign = (-1);
- - }
- -
- - if (dst_BPP >= 24) {
- - src_X *= 3;
- - src_Y *= 3;
- - dst_X *= 3;
- - dst_Y *= 3;
- - dst_width *= 3;
- - if ((nDirection == BOTTOM_TO_TOP)
- - || (nDirection == RIGHT_TO_LEFT)) {
- - src_X += 2;
- - dst_X += 2;
- - }
- - }
- -
- - /* Workaround for 192 byte hw bug */
- - if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) {
- - /*
- - * Perform the ROP2 operation in chunks of (xWidth *
- - * dst_height)
- - */
- - while (1) {
- - deWaitForNotBusy();
- -
- - SMTC_write2Dreg(DE_SOURCE,
- - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
- - FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
- -
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP,
- - DISABLE) | FIELD_VALUE(0,
- - DE_DESTINATION,
- - X,
- - dst_X)
- - | FIELD_VALUE(0, DE_DESTINATION, Y,
- - dst_Y));
- -
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X,
- - xWidth) | FIELD_VALUE(0,
- - DE_DIMENSION,
- - Y_ET,
- - dst_height));
- -
- - de_ctrl =
- - FIELD_VALUE(0, DE_CONTROL, ROP,
- - nROP2) | nTransparent | FIELD_SET(0,
- - DE_CONTROL,
- - ROP_SELECT,
- - ROP2)
- - | FIELD_SET(0, DE_CONTROL, COMMAND,
- - BITBLT) | ((nDirection ==
- - 1) ? FIELD_SET(0,
- - DE_CONTROL,
- - DIRECTION,
- - RIGHT_TO_LEFT)
- - : FIELD_SET(0, DE_CONTROL,
- - DIRECTION,
- - LEFT_TO_RIGHT)) |
- - FIELD_SET(0, DE_CONTROL, STATUS, START);
- -
- - SMTC_write2Dreg(DE_CONTROL, de_ctrl);
- -
- - src_X += (opSign * xWidth);
- - dst_X += (opSign * xWidth);
- - dst_width -= xWidth;
- -
- - if (dst_width <= 0) {
- - /* ROP2 operation is complete */
- - break;
- - }
- -
- - if (xWidth > dst_width)
- - xWidth = dst_width;
- - }
- - } else {
- - deWaitForNotBusy();
- - SMTC_write2Dreg(DE_SOURCE,
- - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
- - FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
- -
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
- - FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
- -
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
- - FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
- -
- - de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) |
- - nTransparent |
- - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- - FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) |
- - ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION,
- - RIGHT_TO_LEFT)
- - : FIELD_SET(0, DE_CONTROL, DIRECTION,
- - LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL,
- - STATUS, START);
- - SMTC_write2Dreg(DE_CONTROL, de_ctrl);
- - }
- -
- - smtc_de_busy = 1;
- -}
- -
- -/*
- - * This function sets the pixel format that will apply to the 2D Engine.
- - */
- -void deSetPixelFormat(unsigned long bpp)
- -{
- - unsigned long de_format;
- -
- - de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT);
- -
- - switch (bpp) {
- - case 8:
- - de_format =
- - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8);
- - break;
- - default:
- - case 16:
- - de_format =
- - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16);
- - break;
- - case 32:
- - de_format =
- - FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32);
- - break;
- - }
- -
- - SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format);
- -}
- -
- -/*
- - * System memory to Video memory monochrome expansion.
- - *
- - * Source is monochrome image in system memory. This function expands the
- - * monochrome data to color image in video memory.
- - */
- -
- -long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf,
- - long srcDelta,
- - unsigned long startBit,
- - unsigned long dBase,
- - unsigned long dPitch,
- - unsigned long bpp,
- - unsigned long dx, unsigned long dy,
- - unsigned long width, unsigned long height,
- - unsigned long fColor,
- - unsigned long bColor,
- - unsigned long rop2) {
- - unsigned long bytePerPixel;
- - unsigned long ulBytesPerScan;
- - unsigned long ul4BytesPerScan;
- - unsigned long ulBytesRemain;
- - unsigned long de_ctrl = 0;
- - unsigned char ajRemain[4];
- - long i, j;
- -
- - bytePerPixel = bpp / 8;
- -
- - /* Just make sure the start bit is within legal range */
- - startBit &= 7;
- -
- - ulBytesPerScan = (width + startBit + 7) / 8;
- - ul4BytesPerScan = ulBytesPerScan & ~3;
- - ulBytesRemain = ulBytesPerScan & 3;
- -
- - if (smtc_de_busy)
- - deWaitForNotBusy();
- -
- - /*
- - * 2D Source Base. Use 0 for HOST Blt.
- - */
- -
- - SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0);
- -
- - /*
- - * 2D Destination Base.
- - *
- - * It is an address offset (128 bit aligned) from the beginning of
- - * frame buffer.
- - */
- -
- - SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase);
- -
- - if (dPitch) {
- -
- - /*
- - * Program pitch (distance between the 1st points of two
- - * adjacent lines).
- - *
- - * Note that input pitch is BYTE value, but the 2D Pitch
- - * register uses pixel values. Need Byte to pixel convertion.
- - */
- -
- - SMTC_write2Dreg(DE_PITCH,
- - FIELD_VALUE(0, DE_PITCH, DESTINATION,
- - dPitch /
- - bytePerPixel) | FIELD_VALUE(0,
- - DE_PITCH,
- - SOURCE,
- - dPitch /
- - bytePerPixel));
- -
- - /* Screen Window width in Pixels.
- - *
- - * 2D engine uses this value to calculate the linear address in
- - * frame buffer for a given point.
- - */
- -
- - SMTC_write2Dreg(DE_WINDOW_WIDTH,
- - FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
- - (dPitch /
- - bytePerPixel)) | FIELD_VALUE(0,
- - DE_WINDOW_WIDTH,
- - SOURCE,
- - (dPitch
- - /
- - bytePerPixel)));
- - }
- - /* Note: For 2D Source in Host Write, only X_K1 field is needed, and
- - * Y_K2 field is not used. For mono bitmap, use startBit for X_K1.
- - */
- -
- - SMTC_write2Dreg(DE_SOURCE,
- - FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) |
- - FIELD_VALUE(0, DE_SOURCE, Y_K2, 0));
- -
- - SMTC_write2Dreg(DE_DESTINATION,
- - FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
- - FIELD_VALUE(0, DE_DESTINATION, X, dx) |
- - FIELD_VALUE(0, DE_DESTINATION, Y, dy));
- -
- - SMTC_write2Dreg(DE_DIMENSION,
- - FIELD_VALUE(0, DE_DIMENSION, X, width) |
- - FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));
- -
- - SMTC_write2Dreg(DE_FOREGROUND, fColor);
- - SMTC_write2Dreg(DE_BACKGROUND, bColor);
- -
- - if (bpp)
- - deSetPixelFormat(bpp);
- - /* Set the pixel format of the destination */
- -
- - de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) |
- - FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
- - FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) |
- - FIELD_SET(0, DE_CONTROL, HOST, MONO) |
- - FIELD_SET(0, DE_CONTROL, STATUS, START);
- -
- - SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency());
- -
- - /* Write MONO data (line by line) to 2D Engine data port */
- - for (i = 0; i < height; i++) {
- - /* For each line, send the data in chunks of 4 bytes */
- - for (j = 0; j < (ul4BytesPerScan / 4); j++)
- - SMTC_write2Ddataport(0,
- - *(unsigned long *)(pSrcbuf +
- - (j * 4)));
- -
- - if (ulBytesRemain) {
- - memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
- - ulBytesRemain);
- - SMTC_write2Ddataport(0, *(unsigned long *)ajRemain);
- - }
- -
- - pSrcbuf += srcDelta;
- - }
- - smtc_de_busy = 1;
- -
- - return 0;
- -}
- -
- -/*
- - * This function gets the transparency status from DE_CONTROL register.
- - * It returns a double word with the transparent fields properly set,
- - * while other fields are 0.
- - */
- -unsigned long deGetTransparency(void)
- -{
- - unsigned long de_ctrl;
- -
- - de_ctrl = SMTC_read2Dreg(DE_CONTROL);
- -
- - de_ctrl &=
- - FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) |
- - FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) |
- - FIELD_MASK(DE_CONTROL_TRANSPARENCY);
- -
- - return de_ctrl;
- -}
- diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtc2d.h linux-lemote/drivers/staging/sm7xx/smtc2d.h
- --- linux-2.6.33/drivers/staging/sm7xx/smtc2d.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/staging/sm7xx/smtc2d.h 1970-01-01 01:00:00.000000000 +0100
- @@ -1,530 +0,0 @@
- -/*
- - * Silicon Motion SM712 2D drawing engine functions.
- - *
- - * Copyright (C) 2006 Silicon Motion Technology Corp.
- - * Author: Ge Wang, gewang@siliconmotion.com
- - *
- - * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- - *
- - * This file is subject to the terms and conditions of the GNU General Public
- - * License. See the file COPYING in the main directory of this archive for
- - * more details.
- - */
- -
- -#ifndef NULL
- -#define NULL 0
- -#endif
- -
- -/* Internal macros */
- -
- -#define _F_START(f) (0 ? f)
- -#define _F_END(f) (1 ? f)
- -#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f))
- -#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f))
- -#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f))
- -#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f))
- -
- -/* Global macros */
- -
- -#define FIELD_GET(x, reg, field) \
- -( \
- - _F_NORMALIZE((x), reg ## _ ## field) \
- -)
- -
- -#define FIELD_SET(x, reg, field, value) \
- -( \
- - (x & ~_F_MASK(reg ## _ ## field)) \
- - | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
- -)
- -
- -#define FIELD_VALUE(x, reg, field, value) \
- -( \
- - (x & ~_F_MASK(reg ## _ ## field)) \
- - | _F_DENORMALIZE(value, reg ## _ ## field) \
- -)
- -
- -#define FIELD_CLEAR(reg, field) \
- -( \
- - ~_F_MASK(reg ## _ ## field) \
- -)
- -
- -/* Field Macros */
- -
- -#define FIELD_START(field) (0 ? field)
- -#define FIELD_END(field) (1 ? field)
- -#define FIELD_SIZE(field) \
- - (1 + FIELD_END(field) - FIELD_START(field))
- -
- -#define FIELD_MASK(field) \
- - (((1 << (FIELD_SIZE(field)-1)) \
- - | ((1 << (FIELD_SIZE(field)-1)) - 1)) \
- - << FIELD_START(field))
- -
- -#define FIELD_NORMALIZE(reg, field) \
- - (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
- -
- -#define FIELD_DENORMALIZE(field, value) \
- - (((value) << FIELD_START(field)) & FIELD_MASK(field))
- -
- -#define FIELD_INIT(reg, field, value) \
- - FIELD_DENORMALIZE(reg ## _ ## field, \
- - reg ## _ ## field ## _ ## value)
- -
- -#define FIELD_INIT_VAL(reg, field, value) \
- - (FIELD_DENORMALIZE(reg ## _ ## field, value))
- -
- -#define FIELD_VAL_SET(x, r, f, v) ({ \
- - x = (x & ~FIELD_MASK(r ## _ ## f)) \
- - | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \
- -})
- -
- -#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b)))
- -
- -/* Transparent info definition */
- -typedef struct {
- - unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */
- - unsigned long select; /* Transparency controlled by SRC/DST */
- - unsigned long control; /* ENABLE/DISABLE transparency */
- - unsigned long color; /* Transparent color */
- -} Transparent, *pTransparent;
- -
- -#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */
- -#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */
- -#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */
- -#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */
- -#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */
- -#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */
- -
- -#define PATTERN_WIDTH 8
- -#define PATTERN_HEIGHT 8
- -
- -#define TOP_TO_BOTTOM 0
- -#define BOTTOM_TO_TOP 1
- -#define RIGHT_TO_LEFT BOTTOM_TO_TOP
- -#define LEFT_TO_RIGHT TOP_TO_BOTTOM
- -
- -/* Constants used in Transparent structure */
- -#define MATCH_OPAQUE 0x00000000
- -#define MATCH_TRANSPARENT 0x00000400
- -#define SOURCE 0x00000000
- -#define DESTINATION 0x00000200
- -
- -/* 2D registers. */
- -
- -#define DE_SOURCE 0x000000
- -#define DE_SOURCE_WRAP 31 : 31
- -#define DE_SOURCE_WRAP_DISABLE 0
- -#define DE_SOURCE_WRAP_ENABLE 1
- -#define DE_SOURCE_X_K1 29 : 16
- -#define DE_SOURCE_Y_K2 15 : 0
- -
- -#define DE_DESTINATION 0x000004
- -#define DE_DESTINATION_WRAP 31 : 31
- -#define DE_DESTINATION_WRAP_DISABLE 0
- -#define DE_DESTINATION_WRAP_ENABLE 1
- -#define DE_DESTINATION_X 28 : 16
- -#define DE_DESTINATION_Y 15 : 0
- -
- -#define DE_DIMENSION 0x000008
- -#define DE_DIMENSION_X 28 : 16
- -#define DE_DIMENSION_Y_ET 15 : 0
- -
- -#define DE_CONTROL 0x00000C
- -#define DE_CONTROL_STATUS 31 : 31
- -#define DE_CONTROL_STATUS_STOP 0
- -#define DE_CONTROL_STATUS_START 1
- -#define DE_CONTROL_PATTERN 30 : 30
- -#define DE_CONTROL_PATTERN_MONO 0
- -#define DE_CONTROL_PATTERN_COLOR 1
- -#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29
- -#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0
- -#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1
- -#define DE_CONTROL_QUICK_START 28 : 28
- -#define DE_CONTROL_QUICK_START_DISABLE 0
- -#define DE_CONTROL_QUICK_START_ENABLE 1
- -#define DE_CONTROL_DIRECTION 27 : 27
- -#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0
- -#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1
- -#define DE_CONTROL_MAJOR 26 : 26
- -#define DE_CONTROL_MAJOR_X 0
- -#define DE_CONTROL_MAJOR_Y 1
- -#define DE_CONTROL_STEP_X 25 : 25
- -#define DE_CONTROL_STEP_X_POSITIVE 1
- -#define DE_CONTROL_STEP_X_NEGATIVE 0
- -#define DE_CONTROL_STEP_Y 24 : 24
- -#define DE_CONTROL_STEP_Y_POSITIVE 1
- -#define DE_CONTROL_STEP_Y_NEGATIVE 0
- -#define DE_CONTROL_STRETCH 23 : 23
- -#define DE_CONTROL_STRETCH_DISABLE 0
- -#define DE_CONTROL_STRETCH_ENABLE 1
- -#define DE_CONTROL_HOST 22 : 22
- -#define DE_CONTROL_HOST_COLOR 0
- -#define DE_CONTROL_HOST_MONO 1
- -#define DE_CONTROL_LAST_PIXEL 21 : 21
- -#define DE_CONTROL_LAST_PIXEL_OFF 0
- -#define DE_CONTROL_LAST_PIXEL_ON 1
- -#define DE_CONTROL_COMMAND 20 : 16
- -#define DE_CONTROL_COMMAND_BITBLT 0
- -#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1
- -#define DE_CONTROL_COMMAND_DE_TILE 2
- -#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3
- -#define DE_CONTROL_COMMAND_ALPHA_BLEND 4
- -#define DE_CONTROL_COMMAND_RLE_STRIP 5
- -#define DE_CONTROL_COMMAND_SHORT_STROKE 6
- -#define DE_CONTROL_COMMAND_LINE_DRAW 7
- -#define DE_CONTROL_COMMAND_HOST_WRITE 8
- -#define DE_CONTROL_COMMAND_HOST_READ 9
- -#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10
- -#define DE_CONTROL_COMMAND_ROTATE 11
- -#define DE_CONTROL_COMMAND_FONT 12
- -#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15
- -#define DE_CONTROL_ROP_SELECT 15 : 15
- -#define DE_CONTROL_ROP_SELECT_ROP3 0
- -#define DE_CONTROL_ROP_SELECT_ROP2 1
- -#define DE_CONTROL_ROP2_SOURCE 14 : 14
- -#define DE_CONTROL_ROP2_SOURCE_BITMAP 0
- -#define DE_CONTROL_ROP2_SOURCE_PATTERN 1
- -#define DE_CONTROL_MONO_DATA 13 : 12
- -#define DE_CONTROL_MONO_DATA_NOT_PACKED 0
- -#define DE_CONTROL_MONO_DATA_8_PACKED 1
- -#define DE_CONTROL_MONO_DATA_16_PACKED 2
- -#define DE_CONTROL_MONO_DATA_32_PACKED 3
- -#define DE_CONTROL_REPEAT_ROTATE 11 : 11
- -#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0
- -#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1
- -#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10
- -#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0
- -#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1
- -#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9
- -#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0
- -#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1
- -#define DE_CONTROL_TRANSPARENCY 8 : 8
- -#define DE_CONTROL_TRANSPARENCY_DISABLE 0
- -#define DE_CONTROL_TRANSPARENCY_ENABLE 1
- -#define DE_CONTROL_ROP 7 : 0
- -
- -/* Pseudo fields. */
- -
- -#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24
- -#define DE_CONTROL_SHORT_STROKE_DIR_225 0
- -#define DE_CONTROL_SHORT_STROKE_DIR_135 1
- -#define DE_CONTROL_SHORT_STROKE_DIR_315 2
- -#define DE_CONTROL_SHORT_STROKE_DIR_45 3
- -#define DE_CONTROL_SHORT_STROKE_DIR_270 4
- -#define DE_CONTROL_SHORT_STROKE_DIR_90 5
- -#define DE_CONTROL_SHORT_STROKE_DIR_180 8
- -#define DE_CONTROL_SHORT_STROKE_DIR_0 10
- -#define DE_CONTROL_ROTATION 25 : 24
- -#define DE_CONTROL_ROTATION_0 0
- -#define DE_CONTROL_ROTATION_270 1
- -#define DE_CONTROL_ROTATION_90 2
- -#define DE_CONTROL_ROTATION_180 3
- -
- -#define DE_PITCH 0x000010
- -#define DE_PITCH_DESTINATION 28 : 16
- -#define DE_PITCH_SOURCE 12 : 0
- -
- -#define DE_FOREGROUND 0x000014
- -#define DE_FOREGROUND_COLOR 31 : 0
- -
- -#define DE_BACKGROUND 0x000018
- -#define DE_BACKGROUND_COLOR 31 : 0
- -
- -#define DE_STRETCH_FORMAT 0x00001C
- -#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30
- -#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0
- -#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1
- -#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27
- -#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23
- -#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20
- -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0
- -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1
- -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3
- -#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2
- -#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16
- -#define DE_STRETCH_FORMAT_ADDRESSING_XY 0
- -#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15
- -#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0
- -
- -#define DE_COLOR_COMPARE 0x000020
- -#define DE_COLOR_COMPARE_COLOR 23 : 0
- -
- -#define DE_COLOR_COMPARE_MASK 0x000024
- -#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0
- -
- -#define DE_MASKS 0x000028
- -#define DE_MASKS_BYTE_MASK 31 : 16
- -#define DE_MASKS_BIT_MASK 15 : 0
- -
- -#define DE_CLIP_TL 0x00002C
- -#define DE_CLIP_TL_TOP 31 : 16
- -#define DE_CLIP_TL_STATUS 13 : 13
- -#define DE_CLIP_TL_STATUS_DISABLE 0
- -#define DE_CLIP_TL_STATUS_ENABLE 1
- -#define DE_CLIP_TL_INHIBIT 12 : 12
- -#define DE_CLIP_TL_INHIBIT_OUTSIDE 0
- -#define DE_CLIP_TL_INHIBIT_INSIDE 1
- -#define DE_CLIP_TL_LEFT 11 : 0
- -
- -#define DE_CLIP_BR 0x000030
- -#define DE_CLIP_BR_BOTTOM 31 : 16
- -#define DE_CLIP_BR_RIGHT 12 : 0
- -
- -#define DE_MONO_PATTERN_LOW 0x000034
- -#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0
- -
- -#define DE_MONO_PATTERN_HIGH 0x000038
- -#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0
- -
- -#define DE_WINDOW_WIDTH 0x00003C
- -#define DE_WINDOW_WIDTH_DESTINATION 28 : 16
- -#define DE_WINDOW_WIDTH_SOURCE 12 : 0
- -
- -#define DE_WINDOW_SOURCE_BASE 0x000040
- -#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27
- -#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0
- -#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1
- -#define DE_WINDOW_SOURCE_BASE_CS 26 : 26
- -#define DE_WINDOW_SOURCE_BASE_CS_0 0
- -#define DE_WINDOW_SOURCE_BASE_CS_1 1
- -#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0
- -
- -#define DE_WINDOW_DESTINATION_BASE 0x000044
- -#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27
- -#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0
- -#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1
- -#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26
- -#define DE_WINDOW_DESTINATION_BASE_CS_0 0
- -#define DE_WINDOW_DESTINATION_BASE_CS_1 1
- -#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0
- -
- -#define DE_ALPHA 0x000048
- -#define DE_ALPHA_VALUE 7 : 0
- -
- -#define DE_WRAP 0x00004C
- -#define DE_WRAP_X 31 : 16
- -#define DE_WRAP_Y 15 : 0
- -
- -#define DE_STATUS 0x000050
- -#define DE_STATUS_CSC 1 : 1
- -#define DE_STATUS_CSC_CLEAR 0
- -#define DE_STATUS_CSC_NOT_ACTIVE 0
- -#define DE_STATUS_CSC_ACTIVE 1
- -#define DE_STATUS_2D 0 : 0
- -#define DE_STATUS_2D_CLEAR 0
- -#define DE_STATUS_2D_NOT_ACTIVE 0
- -#define DE_STATUS_2D_ACTIVE 1
- -
- -/* Color Space Conversion registers. */
- -
- -#define CSC_Y_SOURCE_BASE 0x0000C8
- -#define CSC_Y_SOURCE_BASE_EXT 27 : 27
- -#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0
- -#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1
- -#define CSC_Y_SOURCE_BASE_CS 26 : 26
- -#define CSC_Y_SOURCE_BASE_CS_0 0
- -#define CSC_Y_SOURCE_BASE_CS_1 1
- -#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0
- -
- -#define CSC_CONSTANTS 0x0000CC
- -#define CSC_CONSTANTS_Y 31 : 24
- -#define CSC_CONSTANTS_R 23 : 16
- -#define CSC_CONSTANTS_G 15 : 8
- -#define CSC_CONSTANTS_B 7 : 0
- -
- -#define CSC_Y_SOURCE_X 0x0000D0
- -#define CSC_Y_SOURCE_X_INTEGER 26 : 16
- -#define CSC_Y_SOURCE_X_FRACTION 15 : 3
- -
- -#define CSC_Y_SOURCE_Y 0x0000D4
- -#define CSC_Y_SOURCE_Y_INTEGER 27 : 16
- -#define CSC_Y_SOURCE_Y_FRACTION 15 : 3
- -
- -#define CSC_U_SOURCE_BASE 0x0000D8
- -#define CSC_U_SOURCE_BASE_EXT 27 : 27
- -#define CSC_U_SOURCE_BASE_EXT_LOCAL 0
- -#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1
- -#define CSC_U_SOURCE_BASE_CS 26 : 26
- -#define CSC_U_SOURCE_BASE_CS_0 0
- -#define CSC_U_SOURCE_BASE_CS_1 1
- -#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0
- -
- -#define CSC_V_SOURCE_BASE 0x0000DC
- -#define CSC_V_SOURCE_BASE_EXT 27 : 27
- -#define CSC_V_SOURCE_BASE_EXT_LOCAL 0
- -#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1
- -#define CSC_V_SOURCE_BASE_CS 26 : 26
- -#define CSC_V_SOURCE_BASE_CS_0 0
- -#define CSC_V_SOURCE_BASE_CS_1 1
- -#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0
- -
- -#define CSC_SOURCE_DIMENSION 0x0000E0
- -#define CSC_SOURCE_DIMENSION_X 31 : 16
- -#define CSC_SOURCE_DIMENSION_Y 15 : 0
- -
- -#define CSC_SOURCE_PITCH 0x0000E4
- -#define CSC_SOURCE_PITCH_Y 31 : 16
- -#define CSC_SOURCE_PITCH_UV 15 : 0
- -
- -#define CSC_DESTINATION 0x0000E8
- -#define CSC_DESTINATION_WRAP 31 : 31
- -#define CSC_DESTINATION_WRAP_DISABLE 0
- -#define CSC_DESTINATION_WRAP_ENABLE 1
- -#define CSC_DESTINATION_X 27 : 16
- -#define CSC_DESTINATION_Y 11 : 0
- -
- -#define CSC_DESTINATION_DIMENSION 0x0000EC
- -#define CSC_DESTINATION_DIMENSION_X 31 : 16
- -#define CSC_DESTINATION_DIMENSION_Y 15 : 0
- -
- -#define CSC_DESTINATION_PITCH 0x0000F0
- -#define CSC_DESTINATION_PITCH_X 31 : 16
- -#define CSC_DESTINATION_PITCH_Y 15 : 0
- -
- -#define CSC_SCALE_FACTOR 0x0000F4
- -#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16
- -#define CSC_SCALE_FACTOR_VERTICAL 15 : 0
- -
- -#define CSC_DESTINATION_BASE 0x0000F8
- -#define CSC_DESTINATION_BASE_EXT 27 : 27
- -#define CSC_DESTINATION_BASE_EXT_LOCAL 0
- -#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1
- -#define CSC_DESTINATION_BASE_CS 26 : 26
- -#define CSC_DESTINATION_BASE_CS_0 0
- -#define CSC_DESTINATION_BASE_CS_1 1
- -#define CSC_DESTINATION_BASE_ADDRESS 25 : 0
- -
- -#define CSC_CONTROL 0x0000FC
- -#define CSC_CONTROL_STATUS 31 : 31
- -#define CSC_CONTROL_STATUS_STOP 0
- -#define CSC_CONTROL_STATUS_START 1
- -#define CSC_CONTROL_SOURCE_FORMAT 30 : 28
- -#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0
- -#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1
- -#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2
- -#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3
- -#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4
- -#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5
- -#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6
- -#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7
- -#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26
- -#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0
- -#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1
- -#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25
- -#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0
- -#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1
- -#define CSC_CONTROL_VERTICAL_FILTER 24 : 24
- -#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0
- -#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1
- -#define CSC_CONTROL_BYTE_ORDER 23 : 23
- -#define CSC_CONTROL_BYTE_ORDER_YUYV 0
- -#define CSC_CONTROL_BYTE_ORDER_UYVY 1
- -
- -#define DE_DATA_PORT_501 0x110000
- -#define DE_DATA_PORT_712 0x400000
- -#define DE_DATA_PORT_722 0x6000
- -
- -/* point to virtual Memory Map IO starting address */
- -extern char *smtc_RegBaseAddress;
- -/* point to virtual video memory starting address */
- -extern char *smtc_VRAMBaseAddress;
- -extern unsigned char smtc_de_busy;
- -
- -extern unsigned long memRead32(unsigned long nOffset);
- -extern void memWrite32(unsigned long nOffset, unsigned long nData);
- -extern unsigned long SMTC_read2Dreg(unsigned long nOffset);
- -
- -/* 2D functions */
- -extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
- - unsigned int bpp);
- -
- -extern void deWaitForNotBusy(void);
- -
- -extern void deVerticalLine(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long nX,
- - unsigned long nY,
- - unsigned long dst_height,
- - unsigned long nColor);
- -
- -extern void deHorizontalLine(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long nX,
- - unsigned long nY,
- - unsigned long dst_width,
- - unsigned long nColor);
- -
- -extern void deLine(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long nX1,
- - unsigned long nY1,
- - unsigned long nX2,
- - unsigned long nY2,
- - unsigned long nColor);
- -
- -extern void deFillRect(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long dst_X,
- - unsigned long dst_Y,
- - unsigned long dst_width,
- - unsigned long dst_height,
- - unsigned long nColor);
- -
- -extern void deRotatePattern(unsigned char *pattern_dstaddr,
- - unsigned long pattern_src_addr,
- - unsigned long pattern_BPP,
- - unsigned long pattern_stride,
- - int patternX,
- - int patternY);
- -
- -extern void deCopy(unsigned long dst_base,
- - unsigned long dst_pitch,
- - unsigned long dst_BPP,
- - unsigned long dst_X,
- - unsigned long dst_Y,
- - unsigned long dst_width,
- - unsigned long dst_height,
- - unsigned long src_base,
- - unsigned long src_pitch,
- - unsigned long src_X,
- - unsigned long src_Y,
- - pTransparent pTransp,
- - unsigned char nROP2);
- -
- -/*
- - * System memory to Video memory monochrome expansion.
- - *
- - * Source is monochrome image in system memory. This function expands the
- - * monochrome data to color image in video memory.
- - *
- - * @pSrcbuf: pointer to start of source buffer in system memory
- - * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top
- - * down and -ive mean button up
- - * @startBit: Mono data can start at any bit in a byte, this value should
- - * be 0 to 7
- - * @dBase: Address of destination : offset in frame buffer
- - * @dPitch: Pitch value of destination surface in BYTE
- - * @bpp: Color depth of destination surface
- - * @dx, dy: Starting coordinate of destination surface
- - * @width, height: width and height of rectange in pixel value
- - * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in
- - * the monochrome data)
- - * @rop2: ROP value
- - */
- -
- -extern long deSystemMem2VideoMemMonoBlt(
- - const char *pSrcbuf,
- - long srcDelta,
- - unsigned long startBit,
- - unsigned long dBase,
- - unsigned long dPitch,
- - unsigned long bpp,
- - unsigned long dx, unsigned long dy,
- - unsigned long width, unsigned long height,
- - unsigned long fColor,
- - unsigned long bColor,
- - unsigned long rop2);
- -
- -extern unsigned long deGetTransparency(void);
- -extern void deSetPixelFormat(unsigned long bpp);
- diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtcfb.c linux-lemote/drivers/staging/sm7xx/smtcfb.c
- --- linux-2.6.33/drivers/staging/sm7xx/smtcfb.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/staging/sm7xx/smtcfb.c 2010-03-06 16:43:30.000000000 +0100
- @@ -6,12 +6,14 @@
- * Boyod boyod.yang@siliconmotion.com.cn
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
- + * - Remove the buggy 2D support for Lynx, 2010/01/06, Wu Zhangjin
- + *
- * Version 0.10.26192.21.01
- * - Add PowerPC/Big endian support
- * - Add 2D support for Lynx
- @@ -45,7 +47,6 @@
- struct screen_info smtc_screen_info;
-
- #include "smtcfb.h"
- -#include "smtc2d.h"
-
- #ifdef DEBUG
- #define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
- @@ -107,6 +108,7 @@
- {"0x307", 1280, 1024, 8},
-
- {"0x311", 640, 480, 16},
- + {"0x313", 800, 480, 16},
- {"0x314", 800, 600, 16},
- {"0x317", 1024, 768, 16},
- {"0x31A", 1280, 1024, 16},
- @@ -120,10 +122,6 @@
- char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
- char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
-
- -char *smtc_2DBaseAddress; /* 2D engine starting address */
- -char *smtc_2Ddataport; /* 2D data port offset */
- -short smtc_2Dacceleration;
- -
- static u32 colreg[17];
- static struct par_info hw; /* hardware information */
-
- @@ -135,16 +133,6 @@
-
- #define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
-
- -void deWaitForNotBusy(void)
- -{
- - unsigned long i = 0x1000000;
- - while (i--) {
- - if ((smtc_seqr(0x16) & 0x18) == 0x10)
- - break;
- - }
- - smtc_de_busy = 0;
- -}
- -
- static void sm712_set_timing(struct smtcfb_info *sfb,
- struct par_info *ppar_info)
- {
- @@ -324,7 +312,7 @@
- return chan << bf->offset;
- }
-
- -static int smtcfb_blank(int blank_mode, struct fb_info *info)
- +static int cfb_blank(int blank_mode, struct fb_info *info)
- {
- /* clear DPMS setting */
- switch (blank_mode) {
- @@ -622,93 +610,13 @@
- }
- #endif /* ! __BIG_ENDIAN */
-
- -#include "smtc2d.c"
- -
- -void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
- -{
- - struct par_info *p = (struct par_info *)info->par;
- -
- - if (smtc_2Dacceleration) {
- - if (!area->width || !area->height)
- - return;
- -
- - deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel,
- - area->dx, area->dy, area->width, area->height,
- - p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC);
- -
- - } else
- - cfb_copyarea(info, area);
- -}
- -
- -void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
- -{
- - struct par_info *p = (struct par_info *)info->par;
- -
- - if (smtc_2Dacceleration) {
- - if (!rect->width || !rect->height)
- - return;
- - if (info->var.bits_per_pixel >= 24)
- - deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3,
- - rect->dy * 3, rect->width * 3, rect->height,
- - rect->color);
- - else
- - deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy,
- - rect->width, rect->height, rect->color);
- - } else
- - cfb_fillrect(info, rect);
- -}
- -
- -void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image)
- -{
- - struct par_info *p = (struct par_info *)info->par;
- - u32 bg_col = 0, fg_col = 0;
- -
- - if ((smtc_2Dacceleration) && (image->depth == 1)) {
- - if (smtc_de_busy)
- - deWaitForNotBusy();
- -
- - switch (info->var.bits_per_pixel) {
- - case 8:
- - bg_col = image->bg_color;
- - fg_col = image->fg_color;
- - break;
- - case 16:
- - bg_col =
- - ((u32 *) (info->pseudo_palette))[image->bg_color];
- - fg_col =
- - ((u32 *) (info->pseudo_palette))[image->fg_color];
- - break;
- - case 32:
- - bg_col =
- - ((u32 *) (info->pseudo_palette))[image->bg_color];
- - fg_col =
- - ((u32 *) (info->pseudo_palette))[image->fg_color];
- - break;
- - }
- -
- - deSystemMem2VideoMemMonoBlt(
- - image->data,
- - image->width / 8,
- - 0,
- - p->BaseAddressInVRAM,
- - 0,
- - 0,
- - image->dx, image->dy,
- - image->width, image->height,
- - fg_col, bg_col,
- - 0x0C);
- -
- - } else
- - cfb_imageblit(info, image);
- -}
- -
- static struct fb_ops smtcfb_ops = {
- .owner = THIS_MODULE,
- .fb_setcolreg = smtc_setcolreg,
- - .fb_blank = smtcfb_blank,
- - .fb_fillrect = smtcfb_fillrect,
- - .fb_imageblit = smtcfb_imageblit,
- - .fb_copyarea = smtcfb_copyarea,
- + .fb_blank = cfb_blank,
- + .fb_fillrect = cfb_fillrect,
- + .fb_imageblit = cfb_imageblit,
- + .fb_copyarea = cfb_copyarea,
- #ifdef __BIG_ENDIAN
- .fb_read = smtcfb_read,
- .fb_write = smtcfb_write,
- @@ -772,12 +680,6 @@
- hw.height = sfb->fb.var.yres;
- hw.hz = 60;
- smtc_set_timing(sfb, &hw);
- - if (smtc_2Dacceleration) {
- - printk("2D acceleration enabled!\n");
- - /* Init smtc drawing engine */
- - deInit(sfb->fb.var.xres, sfb->fb.var.yres,
- - sfb->fb.var.bits_per_pixel);
- - }
- }
-
- /*
- @@ -1004,9 +906,7 @@
- #endif
- hw.m_pMMIO = (smtc_RegBaseAddress =
- smtc_VRAMBaseAddress + 0x00700000);
- - smtc_2DBaseAddress = (hw.m_pDPR =
- - smtc_VRAMBaseAddress + 0x00408000);
- - smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712;
- + hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000;
- hw.m_pVPR = hw.m_pLFB + 0x0040c000;
- #ifdef __BIG_ENDIAN
- if (sfb->fb.var.bits_per_pixel == 32) {
- @@ -1035,27 +935,21 @@
- if (sfb->fb.var.bits_per_pixel == 32)
- smtc_seqw(0x17, 0x30);
- #endif
- -#ifdef CONFIG_FB_SM7XX_ACCEL
- - smtc_2Dacceleration = 1;
- -#endif
- break;
- case 0x720:
- sfb->fb.fix.mmio_start = pFramebufferPhysical;
- sfb->fb.fix.mmio_len = 0x00200000;
- smem_size = SM722_VIDEOMEMORYSIZE;
- - smtc_2DBaseAddress = (hw.m_pDPR =
- - ioremap(pFramebufferPhysical, 0x00a00000));
- + hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000);
- hw.m_pLFB = (smtc_VRAMBaseAddress =
- - smtc_2DBaseAddress + 0x00200000);
- + hw.m_pDPR + 0x00200000);
- hw.m_pMMIO = (smtc_RegBaseAddress =
- - smtc_2DBaseAddress + 0x000c0000);
- - smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722;
- - hw.m_pVPR = smtc_2DBaseAddress + 0x800;
- + hw.m_pDPR + 0x000c0000);
- + hw.m_pVPR = hw.m_pDPR + 0x800;
-
- smtc_seqw(0x62, 0xff);
- smtc_seqw(0x6a, 0x0d);
- smtc_seqw(0x6b, 0x02);
- - smtc_2Dacceleration = 0;
- break;
- default:
- printk(KERN_INFO
- diff -Nur linux-2.6.33/drivers/staging/sm7xx/smtcfb.h linux-lemote/drivers/staging/sm7xx/smtcfb.h
- --- linux-2.6.33/drivers/staging/sm7xx/smtcfb.h 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/staging/sm7xx/smtcfb.h 2010-03-06 16:43:30.000000000 +0100
- @@ -6,7 +6,7 @@
- * Boyod boyod.yang@siliconmotion.com.cn
- *
- * Copyright (C) 2009 Lemote, Inc.
- - * Author: Wu Zhangjin, wuzj@lemote.com
- + * Author: Wu Zhangjin, wuzhangjin@gmail.com
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- diff -Nur linux-2.6.33/drivers/staging/sm7xx/TODO linux-lemote/drivers/staging/sm7xx/TODO
- --- linux-2.6.33/drivers/staging/sm7xx/TODO 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/staging/sm7xx/TODO 2010-03-06 16:43:30.000000000 +0100
- @@ -1,5 +1,6 @@
- TODO:
- - Dual head support
- +- 2D acceleration support
- - use kernel coding style
- - checkpatch.pl clean
- - refine the code and remove unused code
- diff -Nur linux-2.6.33/drivers/usb/host/ohci-hcd.c linux-lemote/drivers/usb/host/ohci-hcd.c
- --- linux-2.6.33/drivers/usb/host/ohci-hcd.c 2010-02-24 19:52:17.000000000 +0100
- +++ linux-lemote/drivers/usb/host/ohci-hcd.c 2010-03-06 16:43:31.000000000 +0100
- @@ -832,9 +832,13 @@
- }
-
- if (ints & OHCI_INTR_WDH) {
- - spin_lock (&ohci->lock);
- - dl_done_list (ohci);
- - spin_unlock (&ohci->lock);
- + if (ohci->hcca->done_head == 0) {
- + ints &= ~OHCI_INTR_WDH;
- + } else {
- + spin_lock (&ohci->lock);
- + dl_done_list (ohci);
- + spin_unlock (&ohci->lock);
- + }
- }
-
- if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
|