12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222 |
- diff -Nur linux-2.6.34.orig/arch/mips/boot/compressed/ld.script linux-loongson/arch/mips/boot/compressed/ld.script
- --- linux-2.6.34.orig/arch/mips/boot/compressed/ld.script 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/boot/compressed/ld.script 2010-05-27 18:12:28.592215840 +0200
- @@ -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)
- diff -Nur linux-2.6.34.orig/arch/mips/configs/fuloong2e_defconfig linux-loongson/arch/mips/configs/fuloong2e_defconfig
- --- linux-2.6.34.orig/arch/mips/configs/fuloong2e_defconfig 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/configs/fuloong2e_defconfig 2010-05-27 18:12:28.602215969 +0200
- @@ -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.34-rc5
- +# Wed Apr 28 01:14: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
- @@ -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
- @@ -66,8 +69,7 @@
- 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_NEED_DMA_MAP_STATE=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
- @@ -128,13 +130,13 @@
- CONFIG_MIPS_MT_DISABLED=y
- # CONFIG_MIPS_MT_SMP is not set
- # CONFIG_MIPS_MT_SMTC is not set
- +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
- CONFIG_CPU_HAS_WB=y
- CONFIG_CPU_HAS_SYNC=y
- CONFIG_GENERIC_HARDIRQS=y
- 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 +145,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 +187,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 +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
- @@ -215,10 +215,8 @@
- CONFIG_IKCONFIG=y
- CONFIG_IKCONFIG_PROC=y
- 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
- @@ -258,7 +256,6 @@
- # CONFIG_SLUB is not set
- # CONFIG_SLOB is not set
- CONFIG_PROFILING=y
- -CONFIG_TRACEPOINTS=y
- CONFIG_OPROFILE=m
- CONFIG_HAVE_OPROFILE=y
- CONFIG_HAVE_SYSCALL_WRAPPERS=y
- @@ -266,7 +263,6 @@
- #
- # GCOV-based kernel profiling
- #
- -# CONFIG_GCOV_KERNEL is not set
- CONFIG_SLOW_WORK=y
- CONFIG_HAVE_GENERIC_DMA_COHERENT=y
- CONFIG_SLABINFO=y
- @@ -287,14 +283,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
-
- #
- @@ -304,7 +327,6 @@
- CONFIG_PCI=y
- CONFIG_PCI_DOMAINS=y
- # CONFIG_ARCH_SUPPORTS_MSI is not set
- -CONFIG_PCI_LEGACY=y
- # CONFIG_PCI_STUB is not set
- # CONFIG_PCI_IOV is not set
- CONFIG_ISA=y
- @@ -339,14 +361,13 @@
- CONFIG_HIBERNATION=y
- CONFIG_PM_STD_PARTITION="/dev/hda3"
- # CONFIG_PM_RUNTIME is not set
- +CONFIG_PM_OPS=y
- CONFIG_NET=y
- -CONFIG_COMPAT_NETLINK_MESSAGES=y
-
- #
- # Networking options
- #
- CONFIG_PACKET=y
- -CONFIG_PACKET_MMAP=y
- CONFIG_UNIX=y
- CONFIG_XFRM=y
- # CONFIG_XFRM_USER is not set
- @@ -483,7 +504,6 @@
- # 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
- @@ -491,10 +511,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 +633,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
- @@ -707,6 +727,7 @@
- #
- # SCSI device support
- #
- +CONFIG_SCSI_MOD=y
- # CONFIG_RAID_ATTRS is not set
- CONFIG_SCSI=y
- CONFIG_SCSI_DMA=y
- @@ -755,7 +776,7 @@
- #
-
- #
- -# See the help texts for more information.
- +# The newer stack is recommended.
- #
- # CONFIG_FIREWIRE is not set
- # CONFIG_IEEE1394 is not set
- @@ -764,6 +785,7 @@
- # CONFIG_DUMMY is not set
- # CONFIG_BONDING is not set
- CONFIG_MACVLAN=m
- +# CONFIG_MACVTAP is not set
- # CONFIG_EQUALIZER is not set
- # CONFIG_TUN is not set
- CONFIG_VETH=m
- @@ -798,6 +820,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
- @@ -817,6 +840,7 @@
- # CONFIG_AMD8111_ETH is not set
- # CONFIG_ADAPTEC_STARFIRE is not set
- # CONFIG_AC3200 is not set
- +# CONFIG_KSZ884X_PCI is not set
- # CONFIG_APRICOT is not set
- # CONFIG_B44 is not set
- # CONFIG_FORCEDETH is not set
- @@ -871,6 +895,8 @@
- # CONFIG_CHELSIO_T1 is not set
- CONFIG_CHELSIO_T3_DEPENDS=y
- # CONFIG_CHELSIO_T3 is not set
- +CONFIG_CHELSIO_T4_DEPENDS=y
- +# CONFIG_CHELSIO_T4 is not set
- # CONFIG_ENIC is not set
- # CONFIG_IXGBE is not set
- # CONFIG_IXGB is not set
- @@ -883,13 +909,16 @@
- # CONFIG_MLX4_CORE is not set
- # CONFIG_TEHUTI is not set
- # CONFIG_BNX2X is not set
- +# CONFIG_QLCNIC is not set
- # CONFIG_QLGE is not set
- # CONFIG_SFC is not set
- # 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
- @@ -904,6 +933,7 @@
- # CONFIG_USB_RTL8150 is not set
- # CONFIG_USB_USBNET is not set
- # CONFIG_USB_CDC_PHONET is not set
- +# CONFIG_USB_IPHETH is not set
- # CONFIG_WAN is not set
- # CONFIG_FDDI is not set
- # CONFIG_HIPPI is not set
- @@ -926,6 +956,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 +966,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 +1024,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
-
- #
- @@ -1022,6 +1055,7 @@
- CONFIG_SERIAL_CORE=y
- CONFIG_SERIAL_CORE_CONSOLE=y
- # CONFIG_SERIAL_JSM is not set
- +# CONFIG_SERIAL_TIMBERDALE is not set
- CONFIG_UNIX98_PTYS=y
- # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
- CONFIG_LEGACY_PTYS=y
- @@ -1069,6 +1103,7 @@
- #
- # CONFIG_I2C_OCORES is not set
- # CONFIG_I2C_SIMTEC is not set
- +# CONFIG_I2C_XILINX is not set
-
- #
- # External I2C/SMBus adapter drivers
- @@ -1078,27 +1113,15 @@
- # 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
- # CONFIG_I2C_PCA_ISA is not set
- # CONFIG_I2C_PCA_PLATFORM is not set
- # CONFIG_I2C_STUB is not set
- -
- -#
- -# 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
- # CONFIG_I2C_DEBUG_BUS is not set
- -# CONFIG_I2C_DEBUG_CHIP is not set
- # CONFIG_SPI is not set
-
- #
- @@ -1125,10 +1148,9 @@
- # 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_WM8994 is not set
- # CONFIG_MFD_PCF50633 is not set
- -# CONFIG_AB3100_CORE is not set
- +# CONFIG_LPC_SCH is not set
- # CONFIG_REGULATOR is not set
- # CONFIG_MEDIA_SUPPORT is not set
-
- @@ -1136,6 +1158,7 @@
- # Graphics support
- #
- CONFIG_VGA_ARB=y
- +CONFIG_VGA_ARB_MAX_GPUS=16
- # CONFIG_DRM is not set
- # CONFIG_VGASTATE is not set
- CONFIG_VIDEO_OUTPUT_CONTROL=m
- @@ -1271,6 +1294,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
- @@ -1321,6 +1345,7 @@
- CONFIG_SND_MIPS=y
- CONFIG_SND_USB=y
- # CONFIG_SND_USB_AUDIO is not set
- +# CONFIG_SND_USB_UA101 is not set
- # CONFIG_SND_USB_CAIAQ is not set
- # CONFIG_SND_SOC is not set
- # CONFIG_SOUND_PRIME is not set
- @@ -1358,7 +1383,6 @@
- CONFIG_USB_DEVICEFS=y
- # CONFIG_USB_DEVICE_CLASS is not set
- # CONFIG_USB_DYNAMIC_MINORS is not set
- -# CONFIG_USB_SUSPEND is not set
- # CONFIG_USB_OTG is not set
- CONFIG_USB_OTG_WHITELIST=y
- # CONFIG_USB_OTG_BLACKLIST_HUB is not set
- @@ -1440,7 +1464,6 @@
- # CONFIG_USB_RIO500 is not set
- # 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_CYPRESS_CY7C63 is not set
- # CONFIG_USB_CYTHERM is not set
- @@ -1453,7 +1476,6 @@
- # CONFIG_USB_IOWARRIOR is not set
- # CONFIG_USB_TEST is not set
- CONFIG_USB_ISIGHTFW=m
- -CONFIG_USB_VST=m
- # CONFIG_USB_GADGET is not set
-
- #
- @@ -1473,15 +1495,16 @@
- CONFIG_UIO_CIF=m
- # CONFIG_UIO_PDRV is not set
- # CONFIG_UIO_PDRV_GENIRQ is not set
- -# CONFIG_UIO_SMX is not set
- # CONFIG_UIO_AEC is not set
- # CONFIG_UIO_SERCOS3 is not set
- # CONFIG_UIO_PCI_GENERIC is not set
- +# CONFIG_UIO_NETX is not set
-
- #
- # TI VLYNQ
- #
- # CONFIG_STAGING is not set
- +CONFIG_MIPS_PLATFORM_DEVICES=y
-
- #
- # File systems
- @@ -1499,9 +1522,7 @@
- # CONFIG_EXT4_DEBUG is not set
- CONFIG_FS_XIP=y
- CONFIG_JBD=y
- -# CONFIG_JBD_DEBUG is not set
- CONFIG_JBD2=m
- -# CONFIG_JBD2_DEBUG is not set
- CONFIG_FS_MBCACHE=m
- CONFIG_REISERFS_FS=m
- # CONFIG_REISERFS_CHECK is not set
- @@ -1522,8 +1543,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
- @@ -1572,6 +1593,7 @@
- # CONFIG_BFS_FS is not set
- # CONFIG_EFS_FS is not set
- # CONFIG_JFFS2_FS is not set
- +# CONFIG_LOGFS is not set
- # CONFIG_CRAMFS is not set
- # CONFIG_SQUASHFS is not set
- # CONFIG_VXFS_FS is not set
- @@ -1605,6 +1627,7 @@
- CONFIG_SMB_FS=m
- CONFIG_SMB_NLS_DEFAULT=y
- CONFIG_SMB_NLS_REMOTE="cp936"
- +# CONFIG_CEPH_FS is not set
- CONFIG_CIFS=m
- CONFIG_CIFS_STATS=y
- CONFIG_CIFS_STATS2=y
- @@ -1692,24 +1715,24 @@
- # CONFIG_MAGIC_SYSRQ is not set
- # CONFIG_STRIP_ASM_SYMS is not set
- # CONFIG_UNUSED_SYMBOLS is not set
- -CONFIG_DEBUG_FS=y
- +# CONFIG_DEBUG_FS is not set
- # CONFIG_HEADERS_CHECK is not set
- # CONFIG_DEBUG_KERNEL 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_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 is not set
- # CONFIG_CMDLINE_BOOL is not set
-
- #
- @@ -1718,7 +1741,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
-
- #
- @@ -1819,7 +1846,7 @@
- #
- CONFIG_CRYPTO_ANSI_CPRNG=m
- # CONFIG_CRYPTO_HW is not set
- -CONFIG_BINARY_PRINTF=y
- +# CONFIG_BINARY_PRINTF is not set
-
- #
- # Library routines
- diff -Nur linux-2.6.34.orig/arch/mips/configs/lemote2f_defconfig linux-loongson/arch/mips/configs/lemote2f_defconfig
- --- linux-2.6.34.orig/arch/mips/configs/lemote2f_defconfig 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/configs/lemote2f_defconfig 2010-05-27 18:12:28.612213391 +0200
- @@ -1,7 +1,7 @@
- #
- # Automatically generated make config: don't edit
- -# Linux kernel version: 2.6.33-rc2
- -# Mon Jan 4 13:41:09 2010
- +# Linux kernel version: 2.6.34-rc3
- +# Sun Apr 11 04:31:19 2010
- #
- CONFIG_MIPS=y
-
- @@ -68,7 +68,7 @@
- CONFIG_SCHED_OMIT_FRAME_POINTER=y
- CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
- CONFIG_DMA_NONCOHERENT=y
- -CONFIG_DMA_NEED_PCI_MAP_STATE=y
- +CONFIG_NEED_DMA_MAP_STATE=y
- CONFIG_SYS_HAS_EARLY_PRINTK=y
- CONFIG_I8259=y
- # CONFIG_NO_IOPORT is not set
- @@ -132,6 +132,7 @@
- CONFIG_MIPS_MT_DISABLED=y
- # CONFIG_MIPS_MT_SMP is not set
- # CONFIG_MIPS_MT_SMTC is not set
- +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
- CONFIG_CPU_HAS_WB=y
- CONFIG_CPU_HAS_SYNC=y
- CONFIG_GENERIC_HARDIRQS=y
- @@ -188,9 +189,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
- @@ -213,10 +216,8 @@
- CONFIG_IKCONFIG=y
- CONFIG_IKCONFIG_PROC=y
- 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=y
- @@ -224,6 +225,7 @@
- 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
- @@ -250,13 +252,12 @@
- #
- 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=y
- -CONFIG_TRACEPOINTS=y
- CONFIG_OPROFILE=m
- CONFIG_HAVE_OPROFILE=y
- CONFIG_HAVE_SYSCALL_WRAPPERS=y
- @@ -264,11 +265,8 @@
- #
- # GCOV-based kernel profiling
- #
- -# 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
- @@ -330,7 +328,6 @@
- CONFIG_PCI=y
- CONFIG_PCI_DOMAINS=y
- # CONFIG_ARCH_SUPPORTS_MSI is not set
- -CONFIG_PCI_LEGACY=y
- # CONFIG_PCI_STUB is not set
- # CONFIG_PCI_IOV is not set
- CONFIG_ISA=y
- @@ -366,6 +363,7 @@
- CONFIG_HIBERNATION=y
- CONFIG_PM_STD_PARTITION="/dev/hda3"
- CONFIG_PM_RUNTIME=y
- +CONFIG_PM_OPS=y
- CONFIG_MIPS_EXTERNAL_TIMER=y
- CONFIG_MIPS_CPUFREQ=y
-
- @@ -393,12 +391,12 @@
- #
- CONFIG_LOONGSON2_CPUFREQ=m
- CONFIG_NET=y
- +CONFIG_COMPAT_NETLINK_MESSAGES=y
-
- #
- # Networking options
- #
- CONFIG_PACKET=y
- -CONFIG_PACKET_MMAP=y
- CONFIG_UNIX=y
- CONFIG_XFRM=y
- CONFIG_XFRM_USER=m
- @@ -515,6 +513,7 @@
- # CONFIG_ATM is not set
- CONFIG_STP=m
- CONFIG_BRIDGE=m
- +CONFIG_BRIDGE_IGMP_SNOOPING=y
- # CONFIG_NET_DSA is not set
- CONFIG_VLAN_8021Q=m
- # CONFIG_VLAN_8021Q_GVRP is not set
- @@ -584,7 +583,6 @@
- # 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
- @@ -609,18 +607,20 @@
- 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_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_INTERNAL_REGDB is not set
- CONFIG_CFG80211_WEXT=y
- CONFIG_WIRELESS_EXT_SYSFS=y
- CONFIG_LIB80211=m
- @@ -633,7 +633,6 @@
- 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
- @@ -668,10 +667,6 @@
- # 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_DRBD is not set
- # CONFIG_BLK_DEV_NBD is not set
- # CONFIG_BLK_DEV_SX8 is not set
- @@ -758,6 +753,7 @@
- #
- # SCSI device support
- #
- +CONFIG_SCSI_MOD=m
- # CONFIG_RAID_ATTRS is not set
- CONFIG_SCSI=m
- CONFIG_SCSI_DMA=y
- @@ -873,6 +869,7 @@
- # CONFIG_AMD8111_ETH is not set
- # CONFIG_ADAPTEC_STARFIRE is not set
- # CONFIG_AC3200 is not set
- +# CONFIG_KSZ884X_PCI is not set
- # CONFIG_APRICOT is not set
- # CONFIG_B44 is not set
- # CONFIG_FORCEDETH is not set
- @@ -883,7 +880,7 @@
- # 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 is not set
- # CONFIG_8139TOO_8129 is not set
- @@ -910,7 +907,7 @@
- # 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
- @@ -934,7 +931,7 @@
- # CONFIG_USB_ZD1201 is not set
- # CONFIG_USB_NET_RNDIS_WLAN is not set
- # CONFIG_RTL8180 is not set
- -# CONFIG_RTL8187 is not set
- +CONFIG_RTL8187B=m
- # CONFIG_ADM8211 is not set
- # CONFIG_MAC80211_HWSIM is not set
- # CONFIG_MWL8K is not set
- @@ -969,6 +966,7 @@
- CONFIG_USB_NET_CDCETHER=m
- CONFIG_USB_NET_CDC_EEM=m
- # CONFIG_USB_NET_DM9601 is not set
- +# CONFIG_USB_NET_SMSC75XX is not set
- # CONFIG_USB_NET_SMSC95XX is not set
- # CONFIG_USB_NET_GL620A is not set
- CONFIG_USB_NET_NET1080=m
- @@ -1006,24 +1004,24 @@
- CONFIG_INPUT=y
- CONFIG_INPUT_FF_MEMLESS=m
- CONFIG_INPUT_POLLDEV=m
- -# CONFIG_INPUT_SPARSEKMAP is not set
- +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
- @@ -1031,7 +1029,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
- @@ -1072,20 +1070,7 @@
- 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
-
- #
- @@ -1111,6 +1096,7 @@
- #
- CONFIG_SERIAL_CORE=m
- # CONFIG_SERIAL_JSM is not set
- +# CONFIG_SERIAL_TIMBERDALE is not set
- CONFIG_UNIX98_PTYS=y
- # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
- CONFIG_LEGACY_PTYS=y
- @@ -1118,7 +1104,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
- @@ -1133,7 +1118,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
- @@ -1172,6 +1160,7 @@
- # CONFIG_MFD_SM501 is not set
- # CONFIG_HTC_PASIC3 is not set
- # CONFIG_MFD_TMIO is not set
- +# CONFIG_LPC_SCH is not set
- # CONFIG_REGULATOR is not set
- CONFIG_MEDIA_SUPPORT=m
-
- @@ -1211,7 +1200,9 @@
- CONFIG_USB_M5602=m
- CONFIG_USB_STV06XX=m
- # CONFIG_USB_GL860 is not set
- +# CONFIG_USB_GSPCA_BENQ is not set
- CONFIG_USB_GSPCA_CONEX=m
- +# CONFIG_USB_GSPCA_CPIA1 is not set
- CONFIG_USB_GSPCA_ETOMS=m
- CONFIG_USB_GSPCA_FINEPIX=m
- # CONFIG_USB_GSPCA_JEILINJ is not set
- @@ -1219,9 +1210,11 @@
- CONFIG_USB_GSPCA_MR97310A=m
- CONFIG_USB_GSPCA_OV519=m
- CONFIG_USB_GSPCA_OV534=m
- +# CONFIG_USB_GSPCA_OV534_9 is not set
- CONFIG_USB_GSPCA_PAC207=m
- # CONFIG_USB_GSPCA_PAC7302 is not set
- CONFIG_USB_GSPCA_PAC7311=m
- +# CONFIG_USB_GSPCA_SN9C2028 is not set
- CONFIG_USB_GSPCA_SN9C20X=m
- CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
- CONFIG_USB_GSPCA_SONIXB=m
- @@ -1264,6 +1257,7 @@
- # Graphics support
- #
- CONFIG_VGA_ARB=y
- +CONFIG_VGA_ARB_MAX_GPUS=16
- # CONFIG_DRM is not set
- # CONFIG_VGASTATE is not set
- CONFIG_VIDEO_OUTPUT_CONTROL=y
- @@ -1351,10 +1345,7 @@
- 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=y
- CONFIG_SOUND_OSS_CORE_PRECLAIM=y
- @@ -1372,7 +1363,6 @@
- CONFIG_SND_SEQUENCER_OSS=y
- CONFIG_SND_HRTIMER=m
- CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
- -# CONFIG_SND_RTCTIMER is not set
- # CONFIG_SND_DYNAMIC_MINORS is not set
- CONFIG_SND_SUPPORT_OLD_API=y
- CONFIG_SND_VERBOSE_PROCFS=y
- @@ -1462,6 +1452,7 @@
- # CONFIG_SND_MIPS is not set
- CONFIG_SND_USB=y
- CONFIG_SND_USB_AUDIO=m
- +# CONFIG_SND_USB_UA101 is not set
- CONFIG_SND_USB_CAIAQ=m
- CONFIG_SND_USB_CAIAQ_INPUT=y
- # CONFIG_SND_SOC is not set
- @@ -1481,6 +1472,7 @@
- #
- # Special HID drivers
- #
- +# CONFIG_HID_3M_PCT is not set
- CONFIG_HID_A4TECH=m
- CONFIG_HID_APPLE=m
- CONFIG_HID_BELKIN=m
- @@ -1497,14 +1489,20 @@
- CONFIG_HID_LOGITECH=m
- CONFIG_LOGITECH_FF=y
- CONFIG_LOGIRUMBLEPAD2_FF=y
- +# CONFIG_LOGIG940_FF is not set
- +# CONFIG_HID_MAGICMOUSE is not set
- CONFIG_HID_MICROSOFT=m
- +# CONFIG_HID_MOSART is not set
- CONFIG_HID_MONTEREY=m
- CONFIG_HID_NTRIG=m
- +# CONFIG_HID_ORTEK is not set
- CONFIG_HID_PANTHERLORD=m
- CONFIG_PANTHERLORD_FF=y
- CONFIG_HID_PETALYNX=m
- +# CONFIG_HID_QUANTA is not set
- CONFIG_HID_SAMSUNG=m
- CONFIG_HID_SONY=m
- +# CONFIG_HID_STANTUM is not set
- CONFIG_HID_SUNPLUS=m
- CONFIG_HID_GREENASIA=m
- CONFIG_GREENASIA_FF=y
- @@ -1527,14 +1525,14 @@
- #
- # 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_MON=m
- CONFIG_USB_WUSB=m
- # CONFIG_USB_WUSB_CBAF is not set
-
- @@ -1633,6 +1631,7 @@
- # CONFIG_USB_SERIAL_NAVMAN is not set
- # CONFIG_USB_SERIAL_PL2303 is not set
- # CONFIG_USB_SERIAL_OTI6858 is not set
- +# CONFIG_USB_SERIAL_QCAUX is not set
- # CONFIG_USB_SERIAL_QUALCOMM is not set
- # CONFIG_USB_SERIAL_SPCP8X5 is not set
- # CONFIG_USB_SERIAL_HP4X is not set
- @@ -1646,6 +1645,7 @@
- # CONFIG_USB_SERIAL_OPTION is not set
- # CONFIG_USB_SERIAL_OMNINET is not set
- # CONFIG_USB_SERIAL_OPTICON is not set
- +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
- # CONFIG_USB_SERIAL_DEBUG is not set
-
- #
- @@ -1658,7 +1658,6 @@
- # CONFIG_USB_RIO500 is not set
- # CONFIG_USB_LEGOTOWER is not set
- # CONFIG_USB_LCD is not set
- -# CONFIG_USB_BERRY_CHARGE is not set
- CONFIG_USB_LED=m
- # CONFIG_USB_CYPRESS_CY7C63 is not set
- # CONFIG_USB_CYTHERM is not set
- @@ -1671,10 +1670,8 @@
- # CONFIG_USB_IOWARRIOR is not set
- # CONFIG_USB_TEST is not set
- # CONFIG_USB_ISIGHTFW is not set
- -# CONFIG_USB_VST 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
- @@ -1708,6 +1705,7 @@
- # CONFIG_USB_MIDI_GADGET is not set
- # CONFIG_USB_G_PRINTER is not set
- # CONFIG_USB_CDC_COMPOSITE is not set
- +# CONFIG_USB_G_NOKIA is not set
- # CONFIG_USB_G_MULTI is not set
-
- #
- @@ -1735,8 +1733,6 @@
- # 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
- @@ -1747,11 +1743,11 @@
- #
- # LED drivers
- #
- +CONFIG_LEDS_TRIGGERS=y
-
- #
- # 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
- @@ -1763,7 +1759,45 @@
- #
- # 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
- @@ -1776,14 +1810,15 @@
- # 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_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
-
- #
- @@ -1795,8 +1830,6 @@
- #
- # CONFIG_INPUT_GPIO is not set
- # CONFIG_POHMELFS is not set
- -# CONFIG_B3DFG is not set
- -# CONFIG_PLAN9AUTH is not set
- # CONFIG_LINE6_USB is not set
- # CONFIG_USB_SERIAL_QUATECH2 is not set
- # CONFIG_USB_SERIAL_QUATECH_USB2 is not set
- @@ -1815,7 +1848,11 @@
- # CONFIG_STRIP is not set
- # CONFIG_WAVELAN is not set
- CONFIG_FB_SM7XX=y
- -# CONFIG_FB_SM7XX_ACCEL is not set
- +# CONFIG_DT3155 is not set
- +# CONFIG_CRYSTALHD is not set
- +CONFIG_MIPS_PLATFORM_DEVICES=y
- +CONFIG_LEMOTE_YEELOONG2F=m
- +CONFIG_LEMOTE_LYNLOONG2F=m
-
- #
- # File systems
- @@ -1834,9 +1871,7 @@
- # 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=m
- # CONFIG_REISERFS_CHECK is not set
- @@ -1874,7 +1909,8 @@
- CONFIG_QUOTACTL=y
- CONFIG_AUTOFS_FS=m
- CONFIG_AUTOFS4_FS=m
- -# CONFIG_FUSE_FS is not set
- +CONFIG_FUSE_FS=m
- +CONFIG_CUSE=m
-
- #
- # Caches
- @@ -1929,6 +1965,7 @@
- # CONFIG_BEFS_FS is not set
- # CONFIG_BFS_FS is not set
- # CONFIG_EFS_FS is not set
- +# CONFIG_LOGFS is not set
- CONFIG_CRAMFS=m
- CONFIG_SQUASHFS=m
- CONFIG_SQUASHFS_EMBEDDED=y
- @@ -1965,6 +2002,7 @@
- CONFIG_RPCSEC_GSS_KRB5=m
- # CONFIG_RPCSEC_GSS_SPKM3 is not set
- # CONFIG_SMB_FS is not set
- +# CONFIG_CEPH_FS is not set
- CONFIG_CIFS=m
- # CONFIG_CIFS_STATS is not set
- # CONFIG_CIFS_WEAK_PW_HASH is not set
- @@ -2028,39 +2066,31 @@
- # 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=y
- +# CONFIG_DEBUG_FS is not set
- # 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_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_EARLY_PRINTK is not set
- # CONFIG_CMDLINE_BOOL is not set
-
- #
- @@ -2183,7 +2213,7 @@
- CONFIG_CRYPTO_ANSI_CPRNG=m
- CONFIG_CRYPTO_HW=y
- # CONFIG_CRYPTO_DEV_HIFN_795X is not set
- -CONFIG_BINARY_PRINTF=y
- +# CONFIG_BINARY_PRINTF is not set
-
- #
- # Library routines
- diff -Nur linux-2.6.34.orig/arch/mips/configs/lemote2f_minimal_defconfig linux-loongson/arch/mips/configs/lemote2f_minimal_defconfig
- --- linux-2.6.34.orig/arch/mips/configs/lemote2f_minimal_defconfig 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/arch/mips/configs/lemote2f_minimal_defconfig 2010-05-27 18:12:28.612213391 +0200
- @@ -0,0 +1,1383 @@
- +#
- +# Automatically generated make config: don't edit
- +# Linux kernel version: 2.6.34-rc5
- +# Wed Apr 28 01:06:41 2010
- +#
- +CONFIG_MIPS=y
- +
- +#
- +# Machine selection
- +#
- +# CONFIG_MACH_ALCHEMY is not set
- +# CONFIG_AR7 is not set
- +# CONFIG_BCM47XX is not set
- +# CONFIG_BCM63XX is not set
- +# CONFIG_MIPS_COBALT is not set
- +# CONFIG_MACH_DECSTATION is not set
- +# CONFIG_MACH_JAZZ is not set
- +# CONFIG_LASAT is not set
- +CONFIG_MACH_LOONGSON=y
- +# CONFIG_MIPS_MALTA is not set
- +# CONFIG_MIPS_SIM is not set
- +# CONFIG_NEC_MARKEINS is not set
- +# CONFIG_MACH_VR41XX is not set
- +# CONFIG_NXP_STB220 is not set
- +# CONFIG_NXP_STB225 is not set
- +# CONFIG_PNX8550_JBS is not set
- +# 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
- +# CONFIG_SGI_IP32 is not set
- +# CONFIG_SIBYTE_CRHINE is not set
- +# CONFIG_SIBYTE_CARMEL is not set
- +# CONFIG_SIBYTE_CRHONE is not set
- +# CONFIG_SIBYTE_RHONE is not set
- +# CONFIG_SIBYTE_SWARM is not set
- +# CONFIG_SIBYTE_LITTLESUR is not set
- +# CONFIG_SIBYTE_SENTOSA is not set
- +# CONFIG_SIBYTE_BIGSUR is not set
- +# CONFIG_SNI_RM is not set
- +# CONFIG_MACH_TX39XX is not set
- +# CONFIG_MACH_TX49XX is not set
- +# CONFIG_MIKROTIK_RB532 is not set
- +# CONFIG_WR_PPMC is not set
- +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
- +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
- +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
- +CONFIG_ARCH_SPARSEMEM_ENABLE=y
- +# CONFIG_LEMOTE_FULOONG2E is not set
- +CONFIG_LEMOTE_MACH2F=y
- +CONFIG_CS5536=y
- +# CONFIG_CS5536_MFGPT 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
- +CONFIG_ARCH_SUPPORTS_OPROFILE=y
- +CONFIG_GENERIC_FIND_NEXT_BIT=y
- +CONFIG_GENERIC_HWEIGHT=y
- +CONFIG_GENERIC_CALIBRATE_DELAY=y
- +CONFIG_GENERIC_CLOCKEVENTS=y
- +CONFIG_GENERIC_TIME=y
- +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_NEED_DMA_MAP_STATE=y
- +CONFIG_SYS_HAS_EARLY_PRINTK=y
- +CONFIG_I8259=y
- +# CONFIG_NO_IOPORT is not set
- +CONFIG_GENERIC_ISA_DMA=y
- +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
- +# CONFIG_CPU_BIG_ENDIAN is not set
- +CONFIG_CPU_LITTLE_ENDIAN=y
- +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
- +CONFIG_IRQ_CPU=y
- +CONFIG_BOOT_ELF32=y
- +CONFIG_MIPS_L1_CACHE_SHIFT=5
- +
- +#
- +# CPU selection
- +#
- +# CONFIG_CPU_LOONGSON2E is not set
- +CONFIG_CPU_LOONGSON2F=y
- +# CONFIG_CPU_MIPS32_R1 is not set
- +# CONFIG_CPU_MIPS32_R2 is not set
- +# CONFIG_CPU_MIPS64_R1 is not set
- +# CONFIG_CPU_MIPS64_R2 is not set
- +# CONFIG_CPU_R3000 is not set
- +# CONFIG_CPU_TX39XX is not set
- +# CONFIG_CPU_VR41XX is not set
- +# CONFIG_CPU_R4300 is not set
- +# CONFIG_CPU_R4X00 is not set
- +# CONFIG_CPU_TX49XX is not set
- +# CONFIG_CPU_R5000 is not set
- +# CONFIG_CPU_R5432 is not set
- +# CONFIG_CPU_R5500 is not set
- +# CONFIG_CPU_R6000 is not set
- +# CONFIG_CPU_NEVADA is not set
- +# CONFIG_CPU_R8000 is not set
- +# CONFIG_CPU_R10000 is not set
- +# CONFIG_CPU_RM7000 is not set
- +# CONFIG_CPU_RM9000 is not set
- +# CONFIG_CPU_SB1 is not set
- +# CONFIG_CPU_CAVIUM_OCTEON is not set
- +CONFIG_SYS_SUPPORTS_ZBOOT=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
- +#
- +# CONFIG_32BIT is not set
- +CONFIG_64BIT=y
- +# CONFIG_PAGE_SIZE_4KB is not set
- +# CONFIG_PAGE_SIZE_8KB is not set
- +CONFIG_PAGE_SIZE_16KB=y
- +# CONFIG_PAGE_SIZE_32KB is not set
- +# CONFIG_PAGE_SIZE_64KB is not set
- +CONFIG_BOARD_SCACHE=y
- +CONFIG_MIPS_MT_DISABLED=y
- +# CONFIG_MIPS_MT_SMP is not set
- +# CONFIG_MIPS_MT_SMTC is not set
- +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
- +CONFIG_CPU_HAS_WB=y
- +CONFIG_CPU_HAS_SYNC=y
- +CONFIG_GENERIC_HARDIRQS=y
- +CONFIG_GENERIC_IRQ_PROBE=y
- +CONFIG_CPU_SUPPORTS_HIGHMEM=y
- +CONFIG_SYS_SUPPORTS_HIGHMEM=y
- +CONFIG_ARCH_POPULATES_NODE_MAP=y
- +CONFIG_SELECT_MEMORY_MODEL=y
- +# CONFIG_FLATMEM_MANUAL is not set
- +# CONFIG_DISCONTIGMEM_MANUAL is not set
- +CONFIG_SPARSEMEM_MANUAL=y
- +CONFIG_SPARSEMEM=y
- +CONFIG_HAVE_MEMORY_PRESENT=y
- +CONFIG_SPARSEMEM_STATIC=y
- +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_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
- +CONFIG_HZ_250=y
- +# CONFIG_HZ_256 is not set
- +# CONFIG_HZ_1000 is not set
- +# CONFIG_HZ_1024 is not set
- +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
- +CONFIG_HZ=250
- +# CONFIG_PREEMPT_NONE is not set
- +# CONFIG_PREEMPT_VOLUNTARY is not set
- +CONFIG_PREEMPT=y
- +CONFIG_KEXEC=y
- +# CONFIG_SECCOMP is not set
- +CONFIG_LOCKDEP_SUPPORT=y
- +CONFIG_STACKTRACE_SUPPORT=y
- +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
- +CONFIG_CONSTRUCTORS=y
- +
- +#
- +# General setup
- +#
- +CONFIG_EXPERIMENTAL=y
- +CONFIG_BROKEN_ON_SMP=y
- +CONFIG_LOCK_KERNEL=y
- +CONFIG_INIT_ENV_ARG_LIMIT=32
- +CONFIG_LOCALVERSION=""
- +# CONFIG_LOCALVERSION_AUTO is not set
- +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
- +# CONFIG_POSIX_MQUEUE is not set
- +CONFIG_BSD_PROCESS_ACCT=y
- +CONFIG_BSD_PROCESS_ACCT_V3=y
- +# CONFIG_TASKSTATS is not set
- +CONFIG_AUDIT=y
- +
- +#
- +# RCU Subsystem
- +#
- +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
- +# CONFIG_TREE_RCU_TRACE is not set
- +CONFIG_IKCONFIG=y
- +CONFIG_IKCONFIG_PROC=y
- +CONFIG_LOG_BUF_SHIFT=15
- +# CONFIG_CGROUPS is not set
- +CONFIG_SYSFS_DEPRECATED=y
- +CONFIG_SYSFS_DEPRECATED_V2=y
- +# CONFIG_RELAY is not set
- +# CONFIG_NAMESPACES 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=y
- +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
- +CONFIG_SYSCTL=y
- +CONFIG_ANON_INODES=y
- +CONFIG_EMBEDDED=y
- +CONFIG_SYSCTL_SYSCALL=y
- +CONFIG_KALLSYMS=y
- +# CONFIG_KALLSYMS_EXTRA_PASS is not set
- +CONFIG_HOTPLUG=y
- +CONFIG_PRINTK=y
- +CONFIG_BUG=y
- +CONFIG_ELF_CORE=y
- +CONFIG_PCSPKR_PLATFORM=y
- +CONFIG_BASE_FULL=y
- +CONFIG_FUTEX=y
- +CONFIG_EPOLL=y
- +CONFIG_SIGNALFD=y
- +CONFIG_TIMERFD=y
- +CONFIG_EVENTFD=y
- +CONFIG_SHMEM=y
- +CONFIG_AIO=y
- +
- +#
- +# Kernel Performance Events And Counters
- +#
- +CONFIG_VM_EVENT_COUNTERS=y
- +CONFIG_PCI_QUIRKS=y
- +CONFIG_SLUB_DEBUG=y
- +CONFIG_COMPAT_BRK=y
- +# CONFIG_SLAB is not set
- +CONFIG_SLUB=y
- +# CONFIG_SLOB is not set
- +CONFIG_PROFILING=y
- +# CONFIG_OPROFILE is not set
- +CONFIG_HAVE_OPROFILE=y
- +CONFIG_HAVE_SYSCALL_WRAPPERS=y
- +
- +#
- +# GCOV-based kernel profiling
- +#
- +# CONFIG_SLOW_WORK is not set
- +CONFIG_HAVE_GENERIC_DMA_COHERENT=y
- +CONFIG_SLABINFO=y
- +CONFIG_RT_MUTEXES=y
- +CONFIG_BASE_SMALL=0
- +# CONFIG_MODULES is not set
- +CONFIG_BLOCK=y
- +# CONFIG_BLK_DEV_BSG is not set
- +# CONFIG_BLK_DEV_INTEGRITY is not set
- +CONFIG_BLOCK_COMPAT=y
- +
- +#
- +# IO Schedulers
- +#
- +CONFIG_IOSCHED_NOOP=y
- +# CONFIG_IOSCHED_DEADLINE is not set
- +# CONFIG_IOSCHED_CFQ is not set
- +# CONFIG_DEFAULT_DEADLINE is not set
- +# CONFIG_DEFAULT_CFQ is not set
- +CONFIG_DEFAULT_NOOP=y
- +CONFIG_DEFAULT_IOSCHED="noop"
- +# 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 is not set
- +
- +#
- +# Bus options (PCI, PCMCIA, EISA, ISA, TC)
- +#
- +CONFIG_HW_HAS_PCI=y
- +CONFIG_PCI=y
- +CONFIG_PCI_DOMAINS=y
- +# CONFIG_ARCH_SUPPORTS_MSI is not set
- +# CONFIG_PCI_STUB is not set
- +# CONFIG_PCI_IOV is not set
- +CONFIG_ISA=y
- +CONFIG_MMU=y
- +# CONFIG_PCCARD is not set
- +# CONFIG_HOTPLUG_PCI is not set
- +
- +#
- +# Executable file formats
- +#
- +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_MIPS32_COMPAT=y
- +CONFIG_COMPAT=y
- +CONFIG_SYSVIPC_COMPAT=y
- +CONFIG_MIPS32_O32=y
- +CONFIG_MIPS32_N32=y
- +CONFIG_BINFMT_ELF32=y
- +
- +#
- +# Power management options
- +#
- +CONFIG_ARCH_HIBERNATION_POSSIBLE=y
- +CONFIG_ARCH_SUSPEND_POSSIBLE=y
- +# CONFIG_PM is not set
- +CONFIG_NET=y
- +
- +#
- +# Networking options
- +#
- +CONFIG_PACKET=y
- +CONFIG_UNIX=y
- +# CONFIG_NET_KEY is not set
- +CONFIG_INET=y
- +# CONFIG_IP_MULTICAST is not set
- +# CONFIG_IP_ADVANCED_ROUTER is not set
- +CONFIG_IP_FIB_HASH=y
- +# CONFIG_IP_PNP is not set
- +# CONFIG_NET_IPIP is not set
- +# CONFIG_NET_IPGRE is not set
- +# CONFIG_ARPD is not set
- +# CONFIG_SYN_COOKIES is not set
- +# CONFIG_INET_AH is not set
- +# CONFIG_INET_ESP is not set
- +# CONFIG_INET_IPCOMP is not set
- +# CONFIG_INET_XFRM_TUNNEL is not set
- +# CONFIG_INET_TUNNEL is not set
- +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
- +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
- +# CONFIG_INET_XFRM_MODE_BEET is not set
- +# CONFIG_INET_LRO is not set
- +# CONFIG_INET_DIAG is not set
- +# CONFIG_TCP_CONG_ADVANCED is not set
- +CONFIG_TCP_CONG_CUBIC=y
- +CONFIG_DEFAULT_TCP_CONG="cubic"
- +# CONFIG_TCP_MD5SIG is not set
- +# CONFIG_IPV6 is not set
- +# CONFIG_NETWORK_SECMARK is not set
- +# CONFIG_NETFILTER 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_NET_DSA is not set
- +# CONFIG_VLAN_8021Q is not set
- +# CONFIG_DECNET is not set
- +# CONFIG_LLC2 is not set
- +# CONFIG_IPX is not set
- +# CONFIG_ATALK is not set
- +# CONFIG_X25 is not set
- +# CONFIG_LAPB is not set
- +# CONFIG_ECONET is not set
- +# CONFIG_WAN_ROUTER is not set
- +# CONFIG_PHONET is not set
- +# CONFIG_IEEE802154 is not set
- +# CONFIG_NET_SCHED is not set
- +# CONFIG_DCB is not set
- +
- +#
- +# Network testing
- +#
- +# CONFIG_NET_PKTGEN is not set
- +# CONFIG_HAMRADIO is not set
- +# CONFIG_CAN is not set
- +# CONFIG_IRDA is not set
- +# CONFIG_BT is not set
- +# CONFIG_AF_RXRPC is not set
- +# CONFIG_WIRELESS is not set
- +# CONFIG_WIMAX is not set
- +# CONFIG_RFKILL is not set
- +# CONFIG_NET_9P is not set
- +
- +#
- +# Device Drivers
- +#
- +
- +#
- +# Generic Driver Options
- +#
- +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
- +# CONFIG_DEVTMPFS is not set
- +CONFIG_STANDALONE=y
- +CONFIG_PREVENT_FIRMWARE_BUILD=y
- +CONFIG_FW_LOADER=y
- +CONFIG_FIRMWARE_IN_KERNEL=y
- +CONFIG_EXTRA_FIRMWARE=""
- +# CONFIG_SYS_HYPERVISOR is not set
- +# CONFIG_CONNECTOR is not set
- +# CONFIG_MTD is not set
- +# CONFIG_PARPORT is not set
- +# CONFIG_PNP is not set
- +CONFIG_BLK_DEV=y
- +# CONFIG_BLK_CPQ_DA is not set
- +# CONFIG_BLK_CPQ_CISS_DA is not set
- +# CONFIG_BLK_DEV_DAC960 is not set
- +# CONFIG_BLK_DEV_UMEM is not set
- +# CONFIG_BLK_DEV_COW_COMMON is not set
- +CONFIG_BLK_DEV_LOOP=y
- +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
- +
- +#
- +# 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
- +CONFIG_BLK_DEV_RAM=y
- +CONFIG_BLK_DEV_RAM_COUNT=16
- +CONFIG_BLK_DEV_RAM_SIZE=8192
- +# CONFIG_BLK_DEV_XIP is not set
- +# CONFIG_CDROM_PKTCDVD is not set
- +# CONFIG_ATA_OVER_ETH is not set
- +# CONFIG_BLK_DEV_HD is not set
- +# CONFIG_MISC_DEVICES is not set
- +CONFIG_HAVE_IDE=y
- +CONFIG_IDE=y
- +
- +#
- +# Please see Documentation/ide/ide.txt for help/info on IDE drives
- +#
- +CONFIG_IDE_XFER_MODE=y
- +CONFIG_IDE_TIMINGS=y
- +# CONFIG_BLK_DEV_IDE_SATA is not set
- +CONFIG_IDE_GD=y
- +CONFIG_IDE_GD_ATA=y
- +# CONFIG_IDE_GD_ATAPI is not set
- +# CONFIG_BLK_DEV_IDECD is not set
- +# CONFIG_BLK_DEV_IDETAPE is not set
- +# CONFIG_IDE_TASK_IOCTL is not set
- +# CONFIG_IDE_PROC_FS is not set
- +
- +#
- +# IDE chipset support/bugfixes
- +#
- +# CONFIG_IDE_GENERIC is not set
- +# CONFIG_BLK_DEV_PLATFORM is not set
- +CONFIG_BLK_DEV_IDEDMA_SFF=y
- +
- +#
- +# PCI IDE chipsets support
- +#
- +CONFIG_BLK_DEV_IDEPCI=y
- +# CONFIG_IDEPCI_PCIBUS_ORDER is not set
- +# 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
- +# CONFIG_BLK_DEV_ALI15X3 is not set
- +CONFIG_BLK_DEV_AMD74XX=y
- +# CONFIG_BLK_DEV_CMD64X is not set
- +# CONFIG_BLK_DEV_TRIFLEX is not set
- +# CONFIG_BLK_DEV_CS5520 is not set
- +# CONFIG_BLK_DEV_CS5530 is not set
- +# CONFIG_BLK_DEV_HPT366 is not set
- +# CONFIG_BLK_DEV_JMICRON is not set
- +# CONFIG_BLK_DEV_SC1200 is not set
- +# CONFIG_BLK_DEV_PIIX is not set
- +# CONFIG_BLK_DEV_IT8172 is not set
- +# CONFIG_BLK_DEV_IT8213 is not set
- +# CONFIG_BLK_DEV_IT821X is not set
- +# CONFIG_BLK_DEV_NS87415 is not set
- +# CONFIG_BLK_DEV_PDC202XX_OLD is not set
- +# CONFIG_BLK_DEV_PDC202XX_NEW is not set
- +# CONFIG_BLK_DEV_SVWKS is not set
- +# CONFIG_BLK_DEV_SIIMAGE is not set
- +# CONFIG_BLK_DEV_SLC90E66 is not set
- +# CONFIG_BLK_DEV_TRM290 is not set
- +# CONFIG_BLK_DEV_VIA82CXXX is not set
- +# CONFIG_BLK_DEV_TC86C001 is not set
- +
- +#
- +# Other IDE chipsets support
- +#
- +
- +#
- +# Note: most of these also require special kernel boot parameters
- +#
- +# CONFIG_BLK_DEV_4DRIVES is not set
- +# CONFIG_BLK_DEV_ALI14XX is not set
- +# CONFIG_BLK_DEV_DTC2278 is not set
- +# CONFIG_BLK_DEV_HT6560B is not set
- +# CONFIG_BLK_DEV_QD65XX is not set
- +# CONFIG_BLK_DEV_UMC8672 is not set
- +CONFIG_BLK_DEV_IDEDMA=y
- +
- +#
- +# SCSI device support
- +#
- +CONFIG_SCSI_MOD=y
- +# CONFIG_RAID_ATTRS is not set
- +CONFIG_SCSI=y
- +CONFIG_SCSI_DMA=y
- +# CONFIG_SCSI_TGT is not set
- +# CONFIG_SCSI_NETLINK is not set
- +# CONFIG_SCSI_PROC_FS is not set
- +
- +#
- +# SCSI support type (disk, tape, CD-ROM)
- +#
- +CONFIG_BLK_DEV_SD=y
- +# CONFIG_CHR_DEV_ST is not set
- +# CONFIG_CHR_DEV_OSST is not set
- +# CONFIG_BLK_DEV_SR is not set
- +# CONFIG_CHR_DEV_SG is not set
- +# CONFIG_CHR_DEV_SCH is not set
- +# CONFIG_SCSI_MULTI_LUN is not set
- +# CONFIG_SCSI_CONSTANTS is not set
- +# CONFIG_SCSI_LOGGING is not set
- +# CONFIG_SCSI_SCAN_ASYNC is not set
- +
- +#
- +# SCSI Transports
- +#
- +# CONFIG_SCSI_SPI_ATTRS is not set
- +# CONFIG_SCSI_FC_ATTRS is not set
- +# CONFIG_SCSI_ISCSI_ATTRS is not set
- +# CONFIG_SCSI_SAS_LIBSAS is not set
- +# CONFIG_SCSI_SRP_ATTRS is not set
- +# CONFIG_SCSI_LOWLEVEL is not set
- +# CONFIG_SCSI_DH is not set
- +# CONFIG_SCSI_OSD_INITIATOR is not set
- +# CONFIG_ATA is not set
- +# CONFIG_MD is not set
- +# CONFIG_FUSION is not set
- +
- +#
- +# IEEE 1394 (FireWire) support
- +#
- +
- +#
- +# You can enable one or both FireWire driver stacks.
- +#
- +
- +#
- +# The newer stack is recommended.
- +#
- +# CONFIG_FIREWIRE is not set
- +# CONFIG_IEEE1394 is not set
- +# CONFIG_I2O is not set
- +CONFIG_NETDEVICES=y
- +# CONFIG_DUMMY is not set
- +# 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_ARCNET is not set
- +# CONFIG_PHYLIB is not set
- +CONFIG_NET_ETHERNET=y
- +CONFIG_MII=y
- +# CONFIG_AX88796 is not set
- +# CONFIG_HAPPYMEAL is not set
- +# CONFIG_SUNGEM is not set
- +# CONFIG_CASSINI is not set
- +# CONFIG_NET_VENDOR_3COM is not set
- +# CONFIG_NET_VENDOR_SMC is not set
- +# 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
- +# CONFIG_AT1700 is not set
- +# CONFIG_DEPCA is not set
- +# CONFIG_HP100 is not set
- +# CONFIG_NET_ISA is not set
- +# CONFIG_IBM_NEW_EMAC_ZMII is not set
- +# CONFIG_IBM_NEW_EMAC_RGMII is not set
- +# CONFIG_IBM_NEW_EMAC_TAH is not set
- +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
- +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
- +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
- +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
- +CONFIG_NET_PCI=y
- +# CONFIG_PCNET32 is not set
- +# CONFIG_AMD8111_ETH is not set
- +# CONFIG_ADAPTEC_STARFIRE is not set
- +# CONFIG_AC3200 is not set
- +# CONFIG_KSZ884X_PCI is not set
- +# CONFIG_APRICOT is not set
- +# CONFIG_B44 is not set
- +# CONFIG_FORCEDETH is not set
- +# CONFIG_CS89x0 is not set
- +# CONFIG_TC35815 is not set
- +# CONFIG_E100 is not set
- +# CONFIG_FEALNX is not set
- +# CONFIG_NATSEMI is not set
- +# CONFIG_NE2K_PCI is not set
- +# CONFIG_8139CP is not set
- +CONFIG_8139TOO=y
- +CONFIG_8139TOO_PIO=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
- +# CONFIG_SIS900 is not set
- +# CONFIG_EPIC100 is not set
- +# CONFIG_SMSC9420 is not set
- +# CONFIG_SUNDANCE is not set
- +# CONFIG_TLAN is not set
- +# CONFIG_KS8842 is not set
- +# CONFIG_KS8851_MLL is not set
- +# CONFIG_VIA_RHINE is not set
- +# CONFIG_SC92031 is not set
- +# CONFIG_ATL2 is not set
- +CONFIG_NETDEV_1000=y
- +# CONFIG_ACENIC is not set
- +# CONFIG_DL2K is not set
- +# CONFIG_E1000 is not set
- +# CONFIG_E1000E is not set
- +# CONFIG_IP1000 is not set
- +# CONFIG_IGB is not set
- +# CONFIG_IGBVF is not set
- +# CONFIG_NS83820 is not set
- +# CONFIG_HAMACHI is not set
- +# CONFIG_YELLOWFIN is not set
- +CONFIG_R8169=y
- +# CONFIG_SIS190 is not set
- +# CONFIG_SKGE is not set
- +# CONFIG_SKY2 is not set
- +# CONFIG_VIA_VELOCITY is not set
- +# CONFIG_TIGON3 is not set
- +# CONFIG_BNX2 is not set
- +# CONFIG_CNIC is not set
- +# CONFIG_QLA3XXX is not set
- +# CONFIG_ATL1 is not set
- +# CONFIG_ATL1E is not set
- +# CONFIG_ATL1C is not set
- +# CONFIG_JME is not set
- +# CONFIG_NETDEV_10000 is not set
- +# CONFIG_TR is not set
- +# CONFIG_WLAN is not set
- +
- +#
- +# Enable WiMAX (Networking options) to see the WiMAX drivers
- +#
- +
- +#
- +# USB Network Adapters
- +#
- +# CONFIG_USB_CATC is not set
- +# 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_IPHETH 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_VMXNET3 is not set
- +# CONFIG_ISDN is not set
- +# CONFIG_PHONE is not set
- +
- +#
- +# Input device support
- +#
- +CONFIG_INPUT=y
- +CONFIG_INPUT_FF_MEMLESS=y
- +# CONFIG_INPUT_POLLDEV is not set
- +# CONFIG_INPUT_SPARSEKMAP is not set
- +
- +#
- +# Userland interfaces
- +#
- +CONFIG_INPUT_MOUSEDEV=y
- +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 is not set
- +# CONFIG_INPUT_EVBUG is not set
- +
- +#
- +# Input Device Drivers
- +#
- +CONFIG_INPUT_KEYBOARD=y
- +CONFIG_KEYBOARD_ATKBD=y
- +# CONFIG_KEYBOARD_LKKBD is not set
- +# CONFIG_KEYBOARD_NEWTON is not set
- +# CONFIG_KEYBOARD_OPENCORES is not set
- +# CONFIG_KEYBOARD_STOWAWAY is not set
- +# CONFIG_KEYBOARD_SUNKBD is not set
- +# CONFIG_KEYBOARD_XTKBD is not set
- +CONFIG_INPUT_MOUSE=y
- +CONFIG_MOUSE_PS2=y
- +# CONFIG_MOUSE_PS2_ALPS is not set
- +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
- +CONFIG_MOUSE_PS2_SYNAPTICS=y
- +# CONFIG_MOUSE_PS2_TRACKPOINT is not set
- +# CONFIG_MOUSE_PS2_ELANTECH is not set
- +# 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_BCM5974 is not set
- +# CONFIG_MOUSE_INPORT is not set
- +# CONFIG_MOUSE_LOGIBM is not set
- +# CONFIG_MOUSE_PC110PAD is not set
- +# CONFIG_MOUSE_VSXXXAA is not set
- +# CONFIG_INPUT_JOYSTICK is not set
- +# CONFIG_INPUT_TABLET is not set
- +# CONFIG_INPUT_TOUCHSCREEN is not set
- +# CONFIG_INPUT_MISC is not set
- +
- +#
- +# Hardware I/O ports
- +#
- +CONFIG_SERIO=y
- +CONFIG_SERIO_I8042=y
- +# CONFIG_SERIO_SERPORT is not set
- +# 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
- +
- +#
- +# Character devices
- +#
- +CONFIG_VT=y
- +CONFIG_CONSOLE_TRANSLATIONS=y
- +CONFIG_VT_CONSOLE=y
- +CONFIG_HW_CONSOLE=y
- +# CONFIG_VT_HW_CONSOLE_BINDING is not set
- +# CONFIG_DEVKMEM 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_PCI is not set
- +CONFIG_SERIAL_8250_NR_UARTS=4
- +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
- +# CONFIG_SERIAL_8250_EXTENDED is not set
- +
- +#
- +# Non-8250 serial port support
- +#
- +CONFIG_SERIAL_CORE=y
- +CONFIG_SERIAL_CORE_CONSOLE=y
- +# CONFIG_SERIAL_JSM is not set
- +# CONFIG_SERIAL_TIMBERDALE is not set
- +CONFIG_UNIX98_PTYS=y
- +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
- +CONFIG_LEGACY_PTYS=y
- +CONFIG_LEGACY_PTY_COUNT=16
- +# CONFIG_IPMI_HANDLER is not set
- +# CONFIG_HW_RANDOM is not set
- +# CONFIG_DTLK is not set
- +# CONFIG_R3964 is not set
- +# CONFIG_APPLICOM is not set
- +# CONFIG_RAW_DRIVER is not set
- +# CONFIG_TCG_TPM is not set
- +CONFIG_DEVPORT=y
- +# CONFIG_I2C is not set
- +# CONFIG_SPI is not set
- +
- +#
- +# PPS support
- +#
- +# CONFIG_PPS is not set
- +# CONFIG_W1 is not set
- +# CONFIG_POWER_SUPPLY is not set
- +# CONFIG_HWMON is not set
- +# CONFIG_THERMAL is not set
- +# CONFIG_WATCHDOG is not set
- +CONFIG_SSB_POSSIBLE=y
- +
- +#
- +# Sonics Silicon Backplane
- +#
- +# CONFIG_SSB is not set
- +
- +#
- +# Multifunction device drivers
- +#
- +# CONFIG_MFD_CORE is not set
- +# CONFIG_MFD_SM501 is not set
- +# CONFIG_HTC_PASIC3 is not set
- +# CONFIG_MFD_TMIO is not set
- +# CONFIG_LPC_SCH is not set
- +# CONFIG_REGULATOR is not set
- +# CONFIG_MEDIA_SUPPORT is not set
- +
- +#
- +# Graphics support
- +#
- +CONFIG_VGA_ARB=y
- +CONFIG_VGA_ARB_MAX_GPUS=16
- +# CONFIG_DRM is not set
- +# CONFIG_VGASTATE is not set
- +CONFIG_VIDEO_OUTPUT_CONTROL=y
- +CONFIG_FB=y
- +CONFIG_FIRMWARE_EDID=y
- +# CONFIG_FB_DDC is not set
- +CONFIG_FB_BOOT_VESA_SUPPORT=y
- +CONFIG_FB_CFB_FILLRECT=y
- +CONFIG_FB_CFB_COPYAREA=y
- +CONFIG_FB_CFB_IMAGEBLIT=y
- +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
- +# CONFIG_FB_SYS_FILLRECT is not set
- +# CONFIG_FB_SYS_COPYAREA is not set
- +# CONFIG_FB_SYS_IMAGEBLIT is not set
- +# CONFIG_FB_FOREIGN_ENDIAN is not set
- +# CONFIG_FB_SYS_FOPS is not set
- +# CONFIG_FB_SVGALIB is not set
- +# CONFIG_FB_MACMODES is not set
- +# CONFIG_FB_BACKLIGHT is not set
- +CONFIG_FB_MODE_HELPERS=y
- +CONFIG_FB_TILEBLITTING=y
- +
- +#
- +# Frame buffer hardware drivers
- +#
- +# CONFIG_FB_CIRRUS is not set
- +# CONFIG_FB_PM2 is not set
- +# CONFIG_FB_CYBER2000 is not set
- +# CONFIG_FB_ASILIANT is not set
- +# CONFIG_FB_IMSTT is not set
- +# CONFIG_FB_S1D13XXX is not set
- +# CONFIG_FB_NVIDIA is not set
- +# CONFIG_FB_RIVA is not set
- +# CONFIG_FB_MATROX is not set
- +# CONFIG_FB_RADEON is not set
- +# CONFIG_FB_ATY128 is not set
- +# CONFIG_FB_ATY is not set
- +# CONFIG_FB_S3 is not set
- +# CONFIG_FB_SAVAGE is not set
- +CONFIG_FB_SIS=y
- +CONFIG_FB_SIS_300=y
- +CONFIG_FB_SIS_315=y
- +# CONFIG_FB_VIA is not set
- +# CONFIG_FB_NEOMAGIC is not set
- +# CONFIG_FB_KYRO is not set
- +# CONFIG_FB_3DFX is not set
- +# CONFIG_FB_VOODOO1 is not set
- +# CONFIG_FB_VT8623 is not set
- +# CONFIG_FB_TRIDENT is not set
- +# CONFIG_FB_ARK is not set
- +# CONFIG_FB_PM3 is not set
- +# CONFIG_FB_CARMINE is not set
- +# CONFIG_FB_VIRTUAL is not set
- +# CONFIG_FB_METRONOME is not set
- +# CONFIG_FB_MB862XX is not set
- +# CONFIG_FB_BROADSHEET is not set
- +CONFIG_BACKLIGHT_LCD_SUPPORT=y
- +# CONFIG_LCD_CLASS_DEVICE is not set
- +CONFIG_BACKLIGHT_CLASS_DEVICE=y
- +CONFIG_BACKLIGHT_GENERIC=y
- +
- +#
- +# Display device support
- +#
- +# CONFIG_DISPLAY_SUPPORT is not set
- +
- +#
- +# Console display driver support
- +#
- +# CONFIG_VGA_CONSOLE is not set
- +# CONFIG_MDA_CONSOLE is not set
- +CONFIG_DUMMY_CONSOLE=y
- +CONFIG_FRAMEBUFFER_CONSOLE=y
- +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
- +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
- +CONFIG_FONTS=y
- +CONFIG_FONT_8x8=y
- +CONFIG_FONT_8x16=y
- +CONFIG_FONT_6x11=y
- +CONFIG_FONT_7x14=y
- +CONFIG_FONT_PEARL_8x8=y
- +CONFIG_FONT_ACORN_8x8=y
- +CONFIG_FONT_MINI_4x6=y
- +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_SOUND is not set
- +CONFIG_HID_SUPPORT=y
- +CONFIG_HID=y
- +CONFIG_HIDRAW=y
- +
- +#
- +# USB Input Devices
- +#
- +CONFIG_USB_HID=y
- +# CONFIG_HID_PID is not set
- +CONFIG_USB_HIDDEV=y
- +
- +#
- +# Special HID drivers
- +#
- +# CONFIG_HID_3M_PCT is not set
- +CONFIG_HID_A4TECH=y
- +CONFIG_HID_APPLE=y
- +CONFIG_HID_BELKIN=y
- +CONFIG_HID_CHERRY=y
- +CONFIG_HID_CHICONY=y
- +CONFIG_HID_CYPRESS=y
- +CONFIG_HID_DRAGONRISE=y
- +CONFIG_DRAGONRISE_FF=y
- +CONFIG_HID_EZKEY=y
- +CONFIG_HID_KYE=y
- +CONFIG_HID_GYRATION=y
- +CONFIG_HID_TWINHAN=y
- +CONFIG_HID_KENSINGTON=y
- +CONFIG_HID_LOGITECH=y
- +CONFIG_LOGITECH_FF=y
- +CONFIG_LOGIRUMBLEPAD2_FF=y
- +# CONFIG_LOGIG940_FF is not set
- +CONFIG_HID_MICROSOFT=y
- +# CONFIG_HID_MOSART is not set
- +CONFIG_HID_MONTEREY=y
- +CONFIG_HID_NTRIG=y
- +# CONFIG_HID_ORTEK is not set
- +CONFIG_HID_PANTHERLORD=y
- +CONFIG_PANTHERLORD_FF=y
- +CONFIG_HID_PETALYNX=y
- +# CONFIG_HID_QUANTA is not set
- +CONFIG_HID_SAMSUNG=y
- +CONFIG_HID_SONY=y
- +# CONFIG_HID_STANTUM is not set
- +CONFIG_HID_SUNPLUS=y
- +CONFIG_HID_GREENASIA=y
- +CONFIG_GREENASIA_FF=y
- +CONFIG_HID_SMARTJOYPLUS=y
- +CONFIG_SMARTJOYPLUS_FF=y
- +CONFIG_HID_TOPSEED=y
- +CONFIG_HID_THRUSTMASTER=y
- +CONFIG_THRUSTMASTER_FF=y
- +CONFIG_HID_ZEROPLUS=y
- +CONFIG_ZEROPLUS_FF=y
- +CONFIG_USB_SUPPORT=y
- +CONFIG_USB_ARCH_HAS_HCD=y
- +CONFIG_USB_ARCH_HAS_OHCI=y
- +CONFIG_USB_ARCH_HAS_EHCI=y
- +CONFIG_USB=y
- +# CONFIG_USB_DEBUG is not set
- +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
- +
- +#
- +# Miscellaneous USB options
- +#
- +# CONFIG_USB_DEVICEFS is not set
- +# CONFIG_USB_DEVICE_CLASS is not set
- +CONFIG_USB_DYNAMIC_MINORS=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_WUSB_CBAF is not set
- +
- +#
- +# USB Host Controller Drivers
- +#
- +# CONFIG_USB_C67X00_HCD is not set
- +# CONFIG_USB_XHCI_HCD is not set
- +CONFIG_USB_EHCI_HCD=y
- +CONFIG_USB_EHCI_ROOT_HUB_TT=y
- +# CONFIG_USB_EHCI_TT_NEWSCHED is not set
- +# CONFIG_USB_OXU210HP_HCD is not set
- +# CONFIG_USB_ISP116X_HCD is not set
- +# CONFIG_USB_ISP1760_HCD is not set
- +# CONFIG_USB_ISP1362_HCD is not set
- +CONFIG_USB_OHCI_HCD=y
- +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
- +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
- +CONFIG_USB_OHCI_LITTLE_ENDIAN=y
- +# CONFIG_USB_UHCI_HCD is not set
- +# 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
- +
- +#
- +# USB Device Class drivers
- +#
- +# CONFIG_USB_ACM is not set
- +# CONFIG_USB_PRINTER is not set
- +# CONFIG_USB_WDM is not set
- +# CONFIG_USB_TMC is not set
- +
- +#
- +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
- +#
- +
- +#
- +# also be needed; see USB_STORAGE Help for more info
- +#
- +CONFIG_USB_STORAGE=y
- +# CONFIG_USB_STORAGE_DEBUG is not set
- +# CONFIG_USB_STORAGE_DATAFAB is not set
- +# CONFIG_USB_STORAGE_FREECOM is not set
- +# CONFIG_USB_STORAGE_ISD200 is not set
- +# CONFIG_USB_STORAGE_USBAT is not set
- +# CONFIG_USB_STORAGE_SDDR09 is not set
- +# CONFIG_USB_STORAGE_SDDR55 is not set
- +# CONFIG_USB_STORAGE_JUMPSHOT is not set
- +# CONFIG_USB_STORAGE_ALAUDA is not set
- +# 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=y
- +
- +#
- +# USB Imaging devices
- +#
- +# CONFIG_USB_MDC800 is not set
- +# CONFIG_USB_MICROTEK is not set
- +
- +#
- +# USB port drivers
- +#
- +# CONFIG_USB_SERIAL is not set
- +
- +#
- +# USB Miscellaneous drivers
- +#
- +# CONFIG_USB_EMI62 is not set
- +# CONFIG_USB_EMI26 is not set
- +# CONFIG_USB_ADUTUX is not set
- +# CONFIG_USB_SEVSEG is not set
- +# CONFIG_USB_RIO500 is not set
- +# CONFIG_USB_LEGOTOWER is not set
- +# CONFIG_USB_LCD is not set
- +# CONFIG_USB_LED is not set
- +# CONFIG_USB_CYPRESS_CY7C63 is not set
- +# CONFIG_USB_CYTHERM is not set
- +# CONFIG_USB_IDMOUSE is not set
- +# CONFIG_USB_FTDI_ELAN is not set
- +# CONFIG_USB_APPLEDISPLAY is not set
- +# CONFIG_USB_SISUSBVGA is not set
- +# CONFIG_USB_LD is not set
- +# CONFIG_USB_TRANCEVIBRATOR is not set
- +# CONFIG_USB_IOWARRIOR is not set
- +# CONFIG_USB_TEST is not set
- +# CONFIG_USB_ISIGHTFW is not set
- +# CONFIG_USB_GADGET 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_MEMSTICK is not set
- +# CONFIG_NEW_LEDS is not set
- +# CONFIG_ACCESSIBILITY is not set
- +# CONFIG_INFINIBAND 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
- +
- +#
- +# TI VLYNQ
- +#
- +CONFIG_STAGING=y
- +# CONFIG_STAGING_EXCLUDE_BUILD is not set
- +# CONFIG_ET131X is not set
- +# CONFIG_USB_IP_COMMON is not set
- +# CONFIG_ECHO is not set
- +# CONFIG_ASUS_OLED is not set
- +# CONFIG_TRANZPORT is not set
- +
- +#
- +# Qualcomm MSM Camera And Video
- +#
- +
- +#
- +# Camera Sensor Selection
- +#
- +# CONFIG_INPUT_GPIO is not set
- +# CONFIG_POHMELFS is not set
- +# CONFIG_FB_UDL is not set
- +# CONFIG_VME_BUS is not set
- +
- +#
- +# RAR Register Driver
- +#
- +# 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_FB_SM7XX=y
- +# CONFIG_DT3155 is not set
- +# CONFIG_CRYSTALHD is not set
- +CONFIG_MIPS_PLATFORM_DEVICES=y
- +# CONFIG_LEMOTE_YEELOONG2F is not set
- +# CONFIG_LEMOTE_LYNLOONG2F is not set
- +
- +#
- +# File systems
- +#
- +CONFIG_EXT2_FS=y
- +CONFIG_EXT2_FS_XATTR=y
- +# CONFIG_EXT2_FS_POSIX_ACL is not set
- +# CONFIG_EXT2_FS_SECURITY 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 is not set
- +# CONFIG_EXT3_FS_SECURITY is not set
- +# CONFIG_EXT4_FS is not set
- +CONFIG_JBD=y
- +CONFIG_FS_MBCACHE=y
- +# CONFIG_REISERFS_FS is not set
- +# CONFIG_JFS_FS is not set
- +# CONFIG_FS_POSIX_ACL is not set
- +# CONFIG_XFS_FS is not set
- +# CONFIG_GFS2_FS is not set
- +# CONFIG_OCFS2_FS is not set
- +# CONFIG_BTRFS_FS is not set
- +# CONFIG_NILFS2_FS is not set
- +CONFIG_FILE_LOCKING=y
- +CONFIG_FSNOTIFY=y
- +CONFIG_DNOTIFY=y
- +CONFIG_INOTIFY=y
- +CONFIG_INOTIFY_USER=y
- +# CONFIG_QUOTA is not set
- +# CONFIG_AUTOFS_FS is not set
- +# CONFIG_AUTOFS4_FS is not set
- +# CONFIG_FUSE_FS is not set
- +
- +#
- +# Caches
- +#
- +# CONFIG_FSCACHE is not set
- +
- +#
- +# CD-ROM/DVD Filesystems
- +#
- +# CONFIG_ISO9660_FS is not set
- +# CONFIG_UDF_FS is not set
- +
- +#
- +# DOS/FAT/NT Filesystems
- +#
- +CONFIG_FAT_FS=y
- +CONFIG_MSDOS_FS=y
- +CONFIG_VFAT_FS=y
- +CONFIG_FAT_DEFAULT_CODEPAGE=437
- +CONFIG_FAT_DEFAULT_IOCHARSET="utf-8"
- +# CONFIG_NTFS_FS is not set
- +
- +#
- +# Pseudo filesystems
- +#
- +CONFIG_PROC_FS=y
- +CONFIG_PROC_KCORE=y
- +CONFIG_PROC_SYSCTL=y
- +CONFIG_PROC_PAGE_MONITOR=y
- +CONFIG_SYSFS=y
- +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_NETWORK_FILESYSTEMS is not set
- +
- +#
- +# Partition Types
- +#
- +# CONFIG_PARTITION_ADVANCED is not set
- +CONFIG_MSDOS_PARTITION=y
- +CONFIG_NLS=y
- +CONFIG_NLS_DEFAULT="utf8"
- +CONFIG_NLS_CODEPAGE_437=y
- +# 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=y
- +# 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=y
- +# CONFIG_DLM is not set
- +
- +#
- +# Kernel hacking
- +#
- +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
- +CONFIG_PRINTK_TIME=y
- +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_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_DEBUG_MEMORY_INIT is not set
- +# CONFIG_RCU_CPU_STALL_DETECTOR is not set
- +CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
- +# CONFIG_FTRACE is not set
- +# CONFIG_SAMPLES is not set
- +CONFIG_HAVE_ARCH_KGDB=y
- +# CONFIG_EARLY_PRINTK is not set
- +# CONFIG_CMDLINE_BOOL is not set
- +
- +#
- +# Security options
- +#
- +# CONFIG_KEYS is not set
- +# CONFIG_SECURITY is not set
- +# CONFIG_SECURITYFS 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_CRYPTO is not set
- +# CONFIG_BINARY_PRINTF is not set
- +
- +#
- +# Library routines
- +#
- +CONFIG_BITREVERSE=y
- +CONFIG_GENERIC_FIND_LAST_BIT=y
- +# CONFIG_CRC_CCITT is not set
- +# CONFIG_CRC16 is not set
- +# CONFIG_CRC_T10DIF is not set
- +# CONFIG_CRC_ITU_T is not set
- +CONFIG_CRC32=y
- +# CONFIG_CRC7 is not set
- +# CONFIG_LIBCRC32C is not set
- +CONFIG_AUDIT_GENERIC=y
- +CONFIG_ZLIB_INFLATE=y
- +CONFIG_LZO_DECOMPRESS=y
- +CONFIG_DECOMPRESS_GZIP=y
- +CONFIG_DECOMPRESS_BZIP2=y
- +CONFIG_DECOMPRESS_LZMA=y
- +CONFIG_DECOMPRESS_LZO=y
- +CONFIG_HAS_IOMEM=y
- +CONFIG_HAS_IOPORT=y
- +CONFIG_HAS_DMA=y
- +CONFIG_NLATTR=y
- diff -Nur linux-2.6.34.orig/arch/mips/include/asm/dma-mapping.h linux-loongson/arch/mips/include/asm/dma-mapping.h
- --- linux-2.6.34.orig/arch/mips/include/asm/dma-mapping.h 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/include/asm/dma-mapping.h 2010-05-27 18:12:28.622215656 +0200
- @@ -74,4 +74,8 @@
- extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction direction);
-
- +#define ARCH_HAS_DMA_MMAP_COHERENT
- +extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- + void *cpu_addr, dma_addr_t handle, size_t size);
- +
- #endif /* _ASM_DMA_MAPPING_H */
- diff -Nur linux-2.6.34.orig/arch/mips/include/asm/ftrace.h linux-loongson/arch/mips/include/asm/ftrace.h
- --- linux-2.6.34.orig/arch/mips/include/asm/ftrace.h 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/include/asm/ftrace.h 2010-05-27 18:12:28.642214121 +0200
- @@ -3,7 +3,7 @@
- * License. See the file "COPYING" in the main directory of this archive for
- * more details.
- *
- - * Copyright (C) 2009 DSLab, Lanzhou University, China
- + * Copyright (C) 2009, 2010 DSLab, Lanzhou University, China
- * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- */
-
- @@ -19,6 +19,14 @@
- extern void _mcount(void);
- #define mcount _mcount
-
- +/*
- + * If the Instruction Pointer is in module space (0xc0000000), return true;
- + * otherwise, it is in kernel space (0x80000000), return false.
- + *
- + * FIXME: This may not work in some cases.
- + */
- +#define in_module(ip) (unlikely((ip) & 0x40000000))
- +
- #define safe_load(load, src, dst, error) \
- do { \
- asm volatile ( \
- @@ -83,8 +91,8 @@
-
- struct dyn_arch_ftrace {
- };
- -
- #endif /* CONFIG_DYNAMIC_FTRACE */
- +
- #endif /* __ASSEMBLY__ */
- #endif /* CONFIG_FUNCTION_TRACER */
- #endif /* _ASM_MIPS_FTRACE_H */
- diff -Nur linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h linux-loongson/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
- --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-05-27 18:12:28.712212405 +0200
- @@ -52,6 +52,8 @@
- #define cpu_has_tx39_cache 0
- #define cpu_has_userlocal 0
- #define cpu_has_vce 0
- +#define cpu_has_veic 0
- +#define cpu_has_vint 0
- #define cpu_has_vtag_icache 0
- #define cpu_has_watch 1
-
- diff -Nur linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-loongson/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
- --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-05-27 18:12:28.712212405 +0200
- @@ -255,21 +255,12 @@
- * IDE STANDARD
- */
- #define IDE_CAP 0x00
- -#define IDE_CONFIG 0x01
- -#define IDE_SMI 0x02
- -#define IDE_ERROR 0x03
- -#define IDE_PM 0x04
- -#define IDE_DIAG 0x05
- -
- -/*
- - * IDE SPEC.
- - */
- #define IDE_IO_BAR 0x08
- #define IDE_CFG 0x10
- #define IDE_DTC 0x12
- #define IDE_CAST 0x13
- #define IDE_ETC 0x14
- -#define IDE_INTERNAL_PM 0x15
- +#define IDE_PM 0x15
-
- /*
- * ACC STANDARD
- @@ -301,5 +292,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.34.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-loongson/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
- --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-05-27 18:12:28.712212405 +0200
- @@ -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.34.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h linux-loongson/arch/mips/include/asm/mach-loongson/ec_kb3310b.h
- --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 2010-05-27 18:12:28.712212405 +0200
- @@ -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_SWITCHVIDEOMODE, /* 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_DISPLAYTOGGLE, /* Fn+F2, Turn on/off backlight */
- + EVENT_AUDIO_MUTE, /* Fn+F4, Mute on/off */
- + EVENT_DISPLAY_BRIGHTNESS,/* Fn+^/V, LCD backlight brightness adjust */
- + EVENT_AC_BAT, /* AC & Battery relative issue */
- + EVENT_AUDIO_VOLUME, /* Fn+<|>, 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.34.orig/arch/mips/include/asm/mach-loongson/gpio.h linux-loongson/arch/mips/include/asm/mach-loongson/gpio.h
- --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/gpio.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/arch/mips/include/asm/mach-loongson/gpio.h 2010-05-27 18:12:28.712212405 +0200
- @@ -0,0 +1,35 @@
- +/*
- + * STLS2F GPIO Support
- + *
- + * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
- + * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.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 __STLS2F_GPIO_H
- +#define __STLS2F_GPIO_H
- +
- +#include <asm-generic/gpio.h>
- +
- +extern void gpio_set_value(unsigned gpio, int value);
- +extern int gpio_get_value(unsigned gpio);
- +extern int gpio_cansleep(unsigned gpio);
- +
- +/* The chip can do interrupt
- + * but it has not been tested and doc not clear
- + */
- +static inline int gpio_to_irq(int gpio)
- +{
- + return -EINVAL;
- +}
- +
- +static inline int irq_to_gpio(int gpio)
- +{
- + return -EINVAL;
- +}
- +
- +#endif /* __STLS2F_GPIO_H */
- diff -Nur linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/loongson.h linux-loongson/arch/mips/include/asm/mach-loongson/loongson.h
- --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/loongson.h 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/include/asm/mach-loongson/loongson.h 2010-05-27 18:12:28.712212405 +0200
- @@ -42,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.34.orig/arch/mips/Kconfig linux-loongson/arch/mips/Kconfig
- --- linux-2.6.34.orig/arch/mips/Kconfig 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/Kconfig 2010-05-27 18:12:28.582214052 +0200
- @@ -180,7 +180,7 @@
-
- config MACH_LOONGSON
- bool "Loongson family of machines"
- - select SYS_SUPPORTS_ZBOOT
- + select SYS_SUPPORTS_ZBOOT_UART16550
- help
- This enables the support of Loongson family of machines.
-
- @@ -1075,6 +1075,8 @@
- bool "Loongson 2F"
- depends on SYS_HAS_CPU_LOONGSON2F
- select CPU_LOONGSON2
- + select GENERIC_GPIO
- + select ARCH_REQUIRE_GPIOLIB
- help
- The Loongson 2F processor implements the MIPS III instruction set
- with many extensions.
- @@ -1965,6 +1967,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.34.orig/arch/mips/kernel/csrc-r4k.c linux-loongson/arch/mips/kernel/csrc-r4k.c
- --- linux-2.6.34.orig/arch/mips/kernel/csrc-r4k.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/kernel/csrc-r4k.c 2010-05-27 18:12:28.882214141 +0200
- @@ -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.34.orig/arch/mips/kernel/ftrace.c linux-loongson/arch/mips/kernel/ftrace.c
- --- linux-2.6.34.orig/arch/mips/kernel/ftrace.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/kernel/ftrace.c 2010-05-27 18:12:28.882214141 +0200
- @@ -2,7 +2,7 @@
- * Code for replacing ftrace calls with jumps.
- *
- * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
- - * Copyright (C) 2009 DSLab, Lanzhou University, China
- + * Copyright (C) 2009, 2010 DSLab, Lanzhou University, China
- * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * Thanks goes to Steven Rostedt for writing the original x86 version.
- @@ -15,15 +15,51 @@
- #include <asm/cacheflush.h>
- #include <asm/asm.h>
- #include <asm/asm-offsets.h>
- +#include <asm/uasm.h>
- +
- +#define INSN_S_R_SP 0xafb00000 /* s{d,w} R, offset(sp) */
-
- #ifdef CONFIG_DYNAMIC_FTRACE
-
- -#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */
- -#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */
- -#define jump_insn_encode(op_code, addr) \
- - ((unsigned int)((op_code) | (((addr) >> 2) & ADDR_MASK)))
- +/* Before linking, the following instructions are fixed. */
- +#ifdef CONFIG_CPU_LOONGSON2F
- +#define INSN_NOP 0x00200825 /* or at, at, zero */
- +#else
- +#define INSN_NOP 0x00000000 /* nop */
- +#endif
- +#define INSN_B_1F_16 0x10000004 /* b 1f; offset = (16 >> 2) */
- +#define INSN_B_1F_20 0x10000005 /* b 1f; offset = (20 >> 2) */
- +
- +/* After linking, the following instructions are fixed. */
- +static unsigned int insn_jal_ftrace_caller __read_mostly;
- +static unsigned int insn_lui_v1_hi16_mcount __read_mostly;
- +static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly;
- +
- +/* The following instructions are encoded in the run-time */
- +/* insn: jal func; op_code|addr : 31...26|25 ....0 */
- +#define INSN_JAL(addr) \
- + ((unsigned int)(0x0c000000 | (((addr) >> 2) & 0x03ffffff)))
-
- -static unsigned int ftrace_nop = 0x00000000;
- +static inline void ftrace_dyn_arch_init_insns(void)
- +{
- + u32 *buf;
- + unsigned int v1;
- +
- + /* lui v1, hi16_mcount */
- + v1 = 3;
- + buf = (u32 *)&insn_lui_v1_hi16_mcount;
- + UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR);
- +
- + /* jal (ftrace_caller + 8), jump over the first two instruction */
- + buf = (u32 *)&insn_jal_ftrace_caller;
- + uasm_i_jal(&buf, (FTRACE_ADDR + 8));
- +
- +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
- + /* j ftrace_graph_caller */
- + buf = (u32 *)&insn_j_ftrace_graph_caller;
- + uasm_i_j(&buf, (unsigned long)ftrace_graph_caller);
- +#endif
- +}
-
- static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
- {
- @@ -31,7 +67,6 @@
-
- /* *(unsigned int *)ip = new_code; */
- safe_store_code(new_code, ip, faulted);
- -
- if (unlikely(faulted))
- return -EFAULT;
-
- @@ -40,84 +75,82 @@
- return 0;
- }
-
- -static int lui_v1;
- -static int jal_mcount;
- -
- int ftrace_make_nop(struct module *mod,
- struct dyn_ftrace *rec, unsigned long addr)
- {
- unsigned int new;
- - int faulted;
- unsigned long ip = rec->ip;
-
- - /* We have compiled module with -mlong-calls, but compiled the kernel
- - * without it, we need to cope with them respectively. */
- - if (ip & 0x40000000) {
- - /* record it for ftrace_make_call */
- - if (lui_v1 == 0) {
- - /* lui_v1 = *(unsigned int *)ip; */
- - safe_load_code(lui_v1, ip, faulted);
- -
- - if (unlikely(faulted))
- - return -EFAULT;
- - }
- -
- - /* lui v1, hi_16bit_of_mcount --> b 1f (0x10000004)
- - * addiu v1, v1, low_16bit_of_mcount
- - * move at, ra
- - * jalr v1
- - * nop
- - * 1f: (ip + 12)
- - */
- - new = 0x10000004;
- - } else {
- - /* record/calculate it for ftrace_make_call */
- - if (jal_mcount == 0) {
- - /* We can record it directly like this:
- - * jal_mcount = *(unsigned int *)ip;
- - * Herein, jump over the first two nop instructions */
- - jal_mcount = jump_insn_encode(JAL, (MCOUNT_ADDR + 8));
- - }
- + /*
- + * We have compiled modules with -mlong-calls, but compiled kernel
- + * without it, therefore, need to cope with them respectively.
- + *
- + * For module:
- + *
- + * lui v1, hi16_mcount --> b 1f
- + * addiu v1, v1, lo16_mcount
- + * move at, ra
- + * jalr v1
- + * nop
- + * 1f: (ip + 16)
- + * For kernel:
- + *
- + * move at, ra
- + * jal _mcount --> nop
- + *
- + * And with the -mmcount-ra-address option, the offset may be 20 for
- + * leaf fuction and 24 for non-leaf function.
- + */
-
- - /* move at, ra
- - * jalr v1 --> nop
- - */
- - new = ftrace_nop;
- + if (!in_module(ip))
- + new = INSN_NOP;
- + else {
- +#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
- + new = INSN_B_1F_20;
- +#else
- + new = INSN_B_1F_16;
- +#endif
- }
- +
- return ftrace_modify_code(ip, new);
- }
-
- -static int modified; /* initialized as 0 by default */
- -
- int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
- {
- unsigned int new;
- unsigned long ip = rec->ip;
-
- - /* We just need to remove the "b ftrace_stub" at the fist time! */
- - if (modified == 0) {
- - modified = 1;
- - ftrace_modify_code(addr, ftrace_nop);
- - }
- - /* ip, module: 0xc0000000, kernel: 0x80000000 */
- - new = (ip & 0x40000000) ? lui_v1 : jal_mcount;
- + new = in_module(ip) ? insn_lui_v1_hi16_mcount : insn_jal_ftrace_caller;
-
- return ftrace_modify_code(ip, new);
- }
-
- -#define FTRACE_CALL_IP ((unsigned long)(&ftrace_call))
- -
- int ftrace_update_ftrace_func(ftrace_func_t func)
- {
- unsigned int new;
-
- - new = jump_insn_encode(JAL, (unsigned long)func);
- + new = INSN_JAL((unsigned long)func);
-
- - return ftrace_modify_code(FTRACE_CALL_IP, new);
- + return ftrace_modify_code((unsigned long)(&ftrace_call), new);
- }
-
- int __init ftrace_dyn_arch_init(void *data)
- {
- + ftrace_dyn_arch_init_insns();
- +
- + /*
- + * We are safe to remove the "b ftrace_stub" for the current
- + * ftrace_caller() is almost empty (only the stack operations), and
- + * most importantly, the calling to mcount will be disabled later in
- + * ftrace_init(), then there is no 'big' overhead. And in the future,
- + * we are hoping the function_trace_stop is initialized as 1 then we
- + * can eventually remove that 'useless' "b ftrace_stub" and the
- + * following nop. Currently, although we can call ftrace_stop() to set
- + * function_trace_stop as 1, but it will change the behavior of the
- + * Function Tracer.
- + */
- + ftrace_modify_code(MCOUNT_ADDR, INSN_NOP);
- +
- /* The return code is retured via data */
- *(unsigned long *)data = 0;
-
- @@ -128,30 +161,24 @@
- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-
- #ifdef CONFIG_DYNAMIC_FTRACE
- -
- extern void ftrace_graph_call(void);
- -#define JMP 0x08000000 /* jump to target directly */
- -#define CALL_FTRACE_GRAPH_CALLER \
- - jump_insn_encode(JMP, (unsigned long)(&ftrace_graph_caller))
- #define FTRACE_GRAPH_CALL_IP ((unsigned long)(&ftrace_graph_call))
-
- int ftrace_enable_ftrace_graph_caller(void)
- {
- return ftrace_modify_code(FTRACE_GRAPH_CALL_IP,
- - CALL_FTRACE_GRAPH_CALLER);
- + insn_j_ftrace_graph_caller);
- }
-
- int ftrace_disable_ftrace_graph_caller(void)
- {
- - return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, ftrace_nop);
- + return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, INSN_NOP);
- }
- -
- #endif /* !CONFIG_DYNAMIC_FTRACE */
-
- #ifndef KBUILD_MCOUNT_RA_ADDRESS
- -#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */
- -#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */
- -#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
- +#define INSN_S_RA_SP 0xafbf0000 /* s{d,w} ra, offset(sp) */
- +#define STACK_OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
-
- unsigned long ftrace_get_parent_addr(unsigned long self_addr,
- unsigned long parent,
- @@ -162,35 +189,35 @@
- unsigned int code;
- int faulted;
-
- - /* in module or kernel? */
- - if (self_addr & 0x40000000) {
- - /* module: move to the instruction "lui v1, HI_16BIT_OF_MCOUNT" */
- - ip = self_addr - 20;
- - } else {
- - /* kernel: move to the instruction "move ra, at" */
- - ip = self_addr - 12;
- - }
- + /*
- + * For module, move the ip from calling site of mcount to the
- + * instruction "lui v1, hi_16bit_of_mcount"(offset is 20), but for
- + * kernel, move to the instruction "move ra, at"(offset is 12)
- + */
- + ip = self_addr - (in_module(self_addr) ? 20 : 12);
-
- - /* search the text until finding the non-store instruction or "s{d,w}
- - * ra, offset(sp)" instruction */
- + /*
- + * search the text until finding the non-store instruction or "s{d,w}
- + * ra, offset(sp)" instruction
- + */
- do {
- ip -= 4;
-
- /* get the code at "ip": code = *(unsigned int *)ip; */
- safe_load_code(code, ip, faulted);
- -
- if (unlikely(faulted))
- return 0;
-
- - /* If we hit the non-store instruction before finding where the
- + /*
- + * If we hit the non-store instruction before finding where the
- * ra is stored, then this is a leaf function and it does not
- - * store the ra on the stack. */
- - if ((code & S_R_SP) != S_R_SP)
- + * store the ra on the stack.
- + */
- + if ((code & INSN_S_R_SP) != INSN_S_R_SP)
- return parent_addr;
- + } while (((code & INSN_S_RA_SP) != INSN_S_RA_SP));
-
- - } while (((code & S_RA_SP) != S_RA_SP));
- -
- - sp = fp + (code & OFFSET_MASK);
- + sp = fp + (code & STACK_OFFSET_MASK);
-
- /* ra = *(unsigned long *)sp; */
- safe_load_stack(ra, sp, faulted);
- @@ -201,8 +228,7 @@
- return sp;
- return 0;
- }
- -
- -#endif
- +#endif /* !KBUILD_MCOUNT_RA_ADDRESS */
-
- /*
- * Hook the return address and push it in the stack of return addrs
- @@ -211,16 +237,17 @@
- void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
- unsigned long fp)
- {
- + int faulted;
- unsigned long old;
- struct ftrace_graph_ent trace;
- unsigned long return_hooker = (unsigned long)
- &return_to_handler;
- - int faulted;
-
- if (unlikely(atomic_read(¤t->tracing_graph_pause)))
- return;
-
- - /* "parent" is the stack address saved the return address of the caller
- + /*
- + * "parent" is the stack address saved the return address of the caller
- * of _mcount.
- *
- * if the gcc < 4.5, a leaf function does not save the return address
- @@ -241,12 +268,14 @@
- if (unlikely(faulted))
- goto out;
- #ifndef KBUILD_MCOUNT_RA_ADDRESS
- - parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old,
- - (unsigned long)parent,
- - fp);
- - /* If fails when getting the stack address of the non-leaf function's
- - * ra, stop function graph tracer and return */
- - if (parent == 0)
- + parent = (unsigned long *)ftrace_get_parent_addr(
- + self_addr, old, (unsigned long)parent, fp);
- +
- + /*
- + * If fails on getting the stack address of the non-leaf function's ra,
- + * stop function graph tracer and return
- + */
- + if (unlikely(parent == 0))
- goto out;
- #endif
- /* *parent = return_hooker; */
- diff -Nur linux-2.6.34.orig/arch/mips/kernel/mcount.S linux-loongson/arch/mips/kernel/mcount.S
- --- linux-2.6.34.orig/arch/mips/kernel/mcount.S 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/kernel/mcount.S 2010-05-27 18:12:28.882214141 +0200
- @@ -6,6 +6,7 @@
- * more details.
- *
- * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
- + * Copyright (C) 2010 DSLab, Lanzhou University, China
- * Author: Wu Zhangjin <wuzhangjin@gmail.com>
- */
-
- @@ -45,8 +46,6 @@
- PTR_L a5, PT_R9(sp)
- PTR_L a6, PT_R10(sp)
- PTR_L a7, PT_R11(sp)
- -#endif
- -#ifdef CONFIG_64BIT
- PTR_ADDIU sp, PT_SIZE
- #else
- PTR_ADDIU sp, (PT_SIZE + 8)
- @@ -71,14 +70,14 @@
-
- MCOUNT_SAVE_REGS
- #ifdef KBUILD_MCOUNT_RA_ADDRESS
- - PTR_S t0, PT_R12(sp) /* t0 saved the location of the return address(at) by -mmcount-ra-address */
- + PTR_S $12, PT_R12(sp) /* save location of parent's return address */
- #endif
-
- - move a0, ra /* arg1: next ip, selfaddr */
- + move a0, ra /* arg1: self return address */
- .globl ftrace_call
- ftrace_call:
- nop /* a placeholder for the call to a real tracing function */
- - move a1, AT /* arg2: the caller's next ip, parent */
- + move a1, AT /* arg2: parent's return address */
-
- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
- .globl ftrace_graph_call
- @@ -119,9 +118,9 @@
- static_trace:
- MCOUNT_SAVE_REGS
-
- - move a0, ra /* arg1: next ip, selfaddr */
- + move a0, ra /* arg1: self return address */
- jalr t2 /* (1) call *ftrace_trace_function */
- - move a1, AT /* arg2: the caller's next ip, parent */
- + move a1, AT /* arg2: parent's return address */
-
- MCOUNT_RESTORE_REGS
- .globl ftrace_stub
- @@ -134,28 +133,36 @@
- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-
- NESTED(ftrace_graph_caller, PT_SIZE, ra)
- -#ifdef CONFIG_DYNAMIC_FTRACE
- - PTR_L a1, PT_R31(sp) /* load the original ra from the stack */
- -#ifdef KBUILD_MCOUNT_RA_ADDRESS
- - PTR_L t0, PT_R12(sp) /* load the original t0 from the stack */
- -#endif
- -#else
- +#ifndef CONFIG_DYNAMIC_FTRACE
- MCOUNT_SAVE_REGS
- - move a1, ra /* arg2: next ip, selfaddr */
- #endif
-
- + /* arg1: Get the location of the parent's return address */
- #ifdef KBUILD_MCOUNT_RA_ADDRESS
- - bnez t0, 1f /* non-leaf func: t0 saved the location of the return address */
- +#ifdef CONFIG_DYNAMIC_FTRACE
- + PTR_L a0, PT_R12(sp)
- +#else
- + move a0, $12
- +#endif
- + bnez a0, 1f /* arg1: non-leaf func: stored in $12 */
- nop
- - PTR_LA t0, PT_R1(sp) /* leaf func: get the location of at(old ra) from our own stack */
- -1: move a0, t0 /* arg1: the location of the return address */
- +#endif
- + PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */
- +
- +1:
- + /* arg2: Get self return address */
- +#ifdef CONFIG_DYNAMIC_FTRACE
- + PTR_L a1, PT_R31(sp)
- #else
- - PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */
- + move a1, ra
- #endif
- +
- jal prepare_ftrace_return
- +
- + /* arg3: Get frame pointer of current stack */
- #ifdef CONFIG_FRAME_POINTER
- - move a2, fp /* arg3: frame pointer */
- -#else
- + move a2, fp
- +#else /* ! CONFIG_FRAME_POINTER */
- #ifdef CONFIG_64BIT
- PTR_LA a2, PT_SIZE(sp)
- #else
- diff -Nur linux-2.6.34.orig/arch/mips/kernel/time.c linux-loongson/arch/mips/kernel/time.c
- --- linux-2.6.34.orig/arch/mips/kernel/time.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/kernel/time.c 2010-05-27 18:12:28.892213481 +0200
- @@ -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.34.orig/arch/mips/loongson/common/cmdline.c linux-loongson/arch/mips/loongson/common/cmdline.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/cmdline.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/common/cmdline.c 2010-05-27 18:12:28.902214422 +0200
- @@ -17,10 +17,15 @@
- * 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>
-
- +/* 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;
- @@ -50,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.34.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-loongson/arch/mips/loongson/common/cs5536/cs5536_acc.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-05-27 18:12:28.902214422 +0200
- @@ -18,7 +18,7 @@
-
- void pci_acc_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -66,75 +66,73 @@
- u32 pci_acc_read_reg(int reg)
- {
- u32 hi, lo;
- - u32 conf_data = 0;
- + u32 cfg = 0;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
- if (((lo & 0xfff00000) || (hi & 0x000000ff))
- && ((hi & 0xf0000000) == 0xa0000000))
- - conf_data |= PCI_COMMAND_IO;
- + cfg |= PCI_COMMAND_IO;
- _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
- if ((lo & 0x300) == 0x300)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_ACC_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_ACC_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- - conf_data =
- - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- - PCI_NORMAL_LATENCY_TIMER);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- + PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_ACC_FLAG) {
- - conf_data = CS5536_ACC_RANGE |
- + cfg = CS5536_ACC_RANGE |
- PCI_BASE_ADDRESS_SPACE_IO;
- lo &= ~SOFT_BAR_ACC_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
- - conf_data = (hi & 0x000000ff) << 12;
- - conf_data |= (lo & 0xfff00000) >> 20;
- - conf_data |= 0x01;
- - conf_data &= ~0x02;
- + cfg = (hi & 0x000000ff) << 12;
- + cfg |= (lo & 0xfff00000) >> 20;
- + cfg |= 0x01;
- + cfg &= ~0x02;
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_USB_POINTER;
- + cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
- break;
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ehci.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-05-27 18:12:28.902214422 +0200
- @@ -18,7 +18,7 @@
-
- void pci_ehci_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -49,6 +49,8 @@
- lo |= SOFT_BAR_EHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else if ((value & 0x01) == 0x00) {
- + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- + lo = value;
- _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
-
- value &= 0xfffffff0;
- @@ -76,83 +78,81 @@
-
- u32 pci_ehci_read_reg(int reg)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- if (hi & PCI_COMMAND_MASTER)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- if (hi & PCI_COMMAND_MEMORY)
- - conf_data |= PCI_COMMAND_MEMORY;
- + cfg |= PCI_COMMAND_MEMORY;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_EHCI_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- - conf_data =
- - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- - PCI_NORMAL_LATENCY_TIMER);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- + PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_EHCI_FLAG) {
- - conf_data = CS5536_EHCI_RANGE |
- + cfg = CS5536_EHCI_RANGE |
- PCI_BASE_ADDRESS_SPACE_MEMORY;
- lo &= ~SOFT_BAR_EHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = lo & 0xfffff000;
- + cfg = lo & 0xfffff000;
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_USB_POINTER;
- + cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- break;
- case PCI_EHCI_LEGSMIEN_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = (hi & 0x003f0000) >> 16;
- + cfg = (hi & 0x003f0000) >> 16;
- break;
- case PCI_EHCI_LEGSMISTS_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = (hi & 0x3f000000) >> 24;
- + cfg = (hi & 0x3f000000) >> 24;
- break;
- case PCI_EHCI_FLADJ_REG:
- _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
- - conf_data = hi & 0x00003f00;
- + cfg = hi & 0x00003f00;
- break;
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ide.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-05-27 18:12:28.902214422 +0200
- @@ -18,7 +18,7 @@
-
- void pci_ide_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -51,6 +51,7 @@
- lo |= SOFT_BAR_IDE_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else if (value & 0x01) {
- + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
- lo = (value & 0xfffffff0) | 0x1;
- _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
-
- @@ -65,21 +66,22 @@
- _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
- lo |= 0x01;
- _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
- - } else
- + } else {
- + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
- + lo = value;
- _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
- + }
- break;
- - case PCI_IDE_DTC_REG:
- - _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
- - break;
- - case PCI_IDE_CAST_REG:
- - _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
- - break;
- - case PCI_IDE_ETC_REG:
- - _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
- - break;
- - case PCI_IDE_PM_REG:
- - _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
- - break;
- +#define SET_PCI_IDE_REG(r) \
- + case PCI_IDE_##r##_REG: \
- + _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &lo); \
- + lo = value; \
- + _wrmsr(IDE_MSR_REG(IDE_##r), hi, lo); \
- + break;
- + SET_PCI_IDE_REG(DTC)
- + SET_PCI_IDE_REG(CAST)
- + SET_PCI_IDE_REG(ETC)
- + SET_PCI_IDE_REG(PM)
- default:
- break;
- }
- @@ -87,93 +89,82 @@
-
- u32 pci_ide_read_reg(int reg)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
- if (lo & 0xfffffff0)
- - conf_data |= PCI_COMMAND_IO;
- + cfg |= PCI_COMMAND_IO;
- _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
- if ((lo & 0x30) == 0x30)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_IDE_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_IDE_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
- hi &= 0x000000f8;
- - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
- break;
- case PCI_BAR4_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_IDE_FLAG) {
- - conf_data = CS5536_IDE_RANGE |
- + cfg = CS5536_IDE_RANGE |
- PCI_BASE_ADDRESS_SPACE_IO;
- lo &= ~SOFT_BAR_IDE_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
- - conf_data = lo & 0xfffffff0;
- - conf_data |= 0x01;
- - conf_data &= ~0x02;
- + cfg = lo & 0xfffffff0;
- + cfg |= 0x01;
- + cfg &= ~0x02;
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_POINTER;
- + cfg = PCI_CAPLIST_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
- - break;
- - case PCI_IDE_CFG_REG:
- - _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
- - conf_data = lo;
- - break;
- - case PCI_IDE_DTC_REG:
- - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
- - conf_data = lo;
- - break;
- - case PCI_IDE_CAST_REG:
- - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
- - conf_data = lo;
- - break;
- - case PCI_IDE_ETC_REG:
- - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
- - conf_data = lo;
- - case PCI_IDE_PM_REG:
- - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
- - conf_data = lo;
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
- break;
- +#define GET_PCI_IDE_REG(r) \
- + case PCI_IDE_##r##_REG: \
- + _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &cfg); \
- + break;
- + GET_PCI_IDE_REG(CFG)
- + GET_PCI_IDE_REG(DTC)
- + GET_PCI_IDE_REG(CAST)
- + GET_PCI_IDE_REG(ETC)
- + GET_PCI_IDE_REG(PM)
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_isa.c linux-loongson/arch/mips/loongson/common/cs5536/cs5536_isa.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-05-27 18:12:28.902214422 +0200
- @@ -61,7 +61,7 @@
- for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
- _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
- hi |= 0x01;
- - _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
- + _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
- }
- }
-
- @@ -76,7 +76,7 @@
- for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
- _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
- hi &= ~0x01;
- - _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
- + _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
- }
- }
-
- @@ -86,7 +86,7 @@
-
- void pci_isa_write_bar(int n, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- if (value == PCI_BAR_RANGE_MASK) {
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- @@ -95,7 +95,7 @@
- } else if (value & 0x01) {
- /* NATIVE reg */
- hi = 0x0000f001;
- - lo &= bar_space_range[n];
- + lo = value & bar_space_range[n];
- _wrmsr(divil_msr_reg[n], hi, lo);
-
- /* RCONFx is 4bytes in units for I/O space */
- @@ -112,21 +112,21 @@
-
- u32 pci_isa_read_bar(int n)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & soft_bar_flag[n]) {
- - conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
- + cfg = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
- lo &= ~soft_bar_flag[n];
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(divil_msr_reg[n], &hi, &lo);
- - conf_data = lo & bar_space_range[n];
- - conf_data |= 0x01;
- - conf_data &= ~0x02;
- + cfg = lo & bar_space_range[n];
- + cfg |= 0x01;
- + cfg &= ~0x02;
- }
- - return conf_data;
- + return cfg;
- }
-
- /*
- @@ -136,7 +136,7 @@
- */
- void pci_isa_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
- u32 temp;
-
- switch (reg) {
- @@ -230,45 +230,45 @@
- */
- u32 pci_isa_read_reg(int reg)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- /* we just check the first LBAR for the IO enable bit, */
- /* maybe we should changed later. */
- _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
- if (hi & 0x01)
- - conf_data |= PCI_COMMAND_IO;
- + cfg |= PCI_COMMAND_IO;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_FAST_BACK;
-
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_TAS_ERR_FLAG)
- - conf_data |= PCI_STATUS_SIG_TARGET_ABORT;
- + cfg |= PCI_STATUS_SIG_TARGET_ABORT;
- if (lo & SB_TAR_ERR_FLAG)
- - conf_data |= PCI_STATUS_REC_TARGET_ABORT;
- + cfg |= PCI_STATUS_REC_TARGET_ABORT;
- if (lo & SB_MAR_ERR_FLAG)
- - conf_data |= PCI_STATUS_REC_MASTER_ABORT;
- + cfg |= PCI_STATUS_REC_MASTER_ABORT;
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_DETECTED_PARITY;
- + cfg |= PCI_STATUS_DETECTED_PARITY;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_ISA_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_ISA_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
- hi &= 0x000000f8;
- - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
- break;
- /*
- * we only use the LBAR of DIVIL, no RCONF used.
- @@ -292,25 +292,25 @@
- return pci_isa_read_bar(5);
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_POINTER;
- + cfg = PCI_CAPLIST_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- /* no interrupt used here */
- - conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
- + cfg = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
- break;
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ohci.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-05-27 18:12:28.902214422 +0200
- @@ -18,7 +18,7 @@
-
- void pci_ohci_write_reg(int reg, u32 value)
- {
- - u32 hi = 0, lo = value;
- + u32 hi, lo;
-
- switch (reg) {
- case PCI_COMMAND:
- @@ -49,6 +49,8 @@
- lo |= SOFT_BAR_OHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else if ((value & 0x01) == 0x00) {
- + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
- + lo = value;
- _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
-
- value &= 0xfffffff0;
- @@ -71,77 +73,75 @@
-
- u32 pci_ohci_read_reg(int reg)
- {
- - u32 conf_data = 0;
- + u32 cfg = 0;
- u32 hi, lo;
-
- switch (reg) {
- case PCI_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID,
- + CS5536_VENDOR_ID);
- break;
- case PCI_COMMAND:
- _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
- if (hi & PCI_COMMAND_MASTER)
- - conf_data |= PCI_COMMAND_MASTER;
- + cfg |= PCI_COMMAND_MASTER;
- if (hi & PCI_COMMAND_MEMORY)
- - conf_data |= PCI_COMMAND_MEMORY;
- + cfg |= PCI_COMMAND_MEMORY;
- break;
- case PCI_STATUS:
- - conf_data |= PCI_STATUS_66MHZ;
- - conf_data |= PCI_STATUS_FAST_BACK;
- + cfg |= PCI_STATUS_66MHZ;
- + cfg |= PCI_STATUS_FAST_BACK;
- _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
- if (lo & SB_PARE_ERR_FLAG)
- - conf_data |= PCI_STATUS_PARITY;
- - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
- + cfg |= PCI_STATUS_PARITY;
- + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
- break;
- case PCI_CLASS_REVISION:
- _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
- - conf_data = lo & 0x000000ff;
- - conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
- + cfg = lo & 0x000000ff;
- + cfg |= (CS5536_OHCI_CLASS_CODE << 8);
- break;
- case PCI_CACHE_LINE_SIZE:
- - conf_data =
- - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- - PCI_NORMAL_LATENCY_TIMER);
- + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
- + PCI_NORMAL_LATENCY_TIMER);
- break;
- case PCI_BAR0_REG:
- _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
- if (lo & SOFT_BAR_OHCI_FLAG) {
- - conf_data = CS5536_OHCI_RANGE |
- + cfg = CS5536_OHCI_RANGE |
- PCI_BASE_ADDRESS_SPACE_MEMORY;
- lo &= ~SOFT_BAR_OHCI_FLAG;
- _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
- } else {
- _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
- - conf_data = lo & 0xffffff00;
- - conf_data &= ~0x0000000f; /* 32bit mem */
- + cfg = lo & 0xffffff00;
- + cfg &= ~0x0000000f; /* 32bit mem */
- }
- break;
- case PCI_CARDBUS_CIS:
- - conf_data = PCI_CARDBUS_CIS_POINTER;
- + cfg = PCI_CARDBUS_CIS_POINTER;
- break;
- case PCI_SUBSYSTEM_VENDOR_ID:
- - conf_data =
- - CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
- + cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID,
- + CS5536_SUB_VENDOR_ID);
- break;
- case PCI_ROM_ADDRESS:
- - conf_data = PCI_EXPANSION_ROM_BAR;
- + cfg = PCI_EXPANSION_ROM_BAR;
- break;
- case PCI_CAPABILITY_LIST:
- - conf_data = PCI_CAPLIST_USB_POINTER;
- + cfg = PCI_CAPLIST_USB_POINTER;
- break;
- case PCI_INTERRUPT_LINE:
- - conf_data =
- - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
- break;
- case PCI_OHCI_INT_REG:
- _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
- if ((lo & 0x00000f00) == CS5536_USB_INTR)
- - conf_data = 1;
- + cfg = 1;
- break;
- default:
- break;
- }
-
- - return conf_data;
- + return cfg;
- }
- diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/gpio.c linux-loongson/arch/mips/loongson/common/gpio.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/gpio.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/arch/mips/loongson/common/gpio.c 2010-05-27 18:12:28.902214422 +0200
- @@ -0,0 +1,139 @@
- +/*
- + * STLS2F GPIO Support
- + *
- + * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
- + * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.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/kernel.h>
- +#include <linux/init.h>
- +#include <linux/module.h>
- +#include <linux/spinlock.h>
- +#include <linux/err.h>
- +#include <asm/types.h>
- +#include <loongson.h>
- +#include <linux/gpio.h>
- +
- +#define STLS2F_N_GPIO 4
- +#define STLS2F_GPIO_IN_OFFSET 16
- +
- +static DEFINE_SPINLOCK(gpio_lock);
- +
- +int gpio_get_value(unsigned gpio)
- +{
- + u32 val;
- + u32 mask;
- +
- + if (gpio >= STLS2F_N_GPIO)
- + return __gpio_get_value(gpio);
- +
- + mask = 1 << (gpio + STLS2F_GPIO_IN_OFFSET);
- + spin_lock(&gpio_lock);
- + val = LOONGSON_GPIODATA;
- + spin_unlock(&gpio_lock);
- +
- + return ((val & mask) != 0);
- +}
- +EXPORT_SYMBOL(gpio_get_value);
- +
- +void gpio_set_value(unsigned gpio, int state)
- +{
- + u32 val;
- + u32 mask;
- +
- + if (gpio >= STLS2F_N_GPIO) {
- + __gpio_set_value(gpio, state);
- + return ;
- + }
- +
- + mask = 1 << gpio;
- +
- + spin_lock(&gpio_lock);
- + val = LOONGSON_GPIODATA;
- + if (state)
- + val |= mask;
- + else
- + val &= (~mask);
- + LOONGSON_GPIODATA = val;
- + spin_unlock(&gpio_lock);
- +}
- +EXPORT_SYMBOL(gpio_set_value);
- +
- +int gpio_cansleep(unsigned gpio)
- +{
- + if (gpio < STLS2F_N_GPIO)
- + return 0;
- + else
- + return __gpio_cansleep(gpio);
- +}
- +EXPORT_SYMBOL(gpio_cansleep);
- +
- +static int ls2f_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
- +{
- + u32 temp;
- + u32 mask;
- +
- + if (gpio >= STLS2F_N_GPIO)
- + return -EINVAL;
- +
- + spin_lock(&gpio_lock);
- + mask = 1 << gpio;
- + temp = LOONGSON_GPIOIE;
- + temp |= mask;
- + LOONGSON_GPIOIE = temp;
- + spin_unlock(&gpio_lock);
- +
- + return 0;
- +}
- +
- +static int ls2f_gpio_direction_output(struct gpio_chip *chip,
- + unsigned gpio, int level)
- +{
- + u32 temp;
- + u32 mask;
- +
- + if (gpio >= STLS2F_N_GPIO)
- + return -EINVAL;
- +
- + gpio_set_value(gpio, level);
- + spin_lock(&gpio_lock);
- + mask = 1 << gpio;
- + temp = LOONGSON_GPIOIE;
- + temp &= (~mask);
- + LOONGSON_GPIOIE = temp;
- + spin_unlock(&gpio_lock);
- +
- + return 0;
- +}
- +
- +static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
- +{
- + return gpio_get_value(gpio);
- +}
- +
- +static void ls2f_gpio_set_value(struct gpio_chip *chip,
- + unsigned gpio, int value)
- +{
- + gpio_set_value(gpio, value);
- +}
- +
- +static struct gpio_chip ls2f_chip = {
- + .label = "ls2f",
- + .direction_input = ls2f_gpio_direction_input,
- + .get = ls2f_gpio_get_value,
- + .direction_output = ls2f_gpio_direction_output,
- + .set = ls2f_gpio_set_value,
- + .base = 0,
- + .ngpio = STLS2F_N_GPIO,
- +};
- +
- +static int __init ls2f_gpio_setup(void)
- +{
- + return gpiochip_add(&ls2f_chip);
- +}
- +arch_initcall(ls2f_gpio_setup);
- diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/Makefile linux-loongson/arch/mips/loongson/common/Makefile
- --- linux-2.6.34.orig/arch/mips/loongson/common/Makefile 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/common/Makefile 2010-05-27 18:12:28.902214422 +0200
- @@ -4,6 +4,7 @@
-
- obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
- pci.o bonito-irq.o mem.o machtype.o platform.o
- +obj-$(CONFIG_GENERIC_GPIO) += gpio.o
-
- #
- # Serial port support
- @@ -23,3 +24,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.34.orig/arch/mips/loongson/common/mtd.c linux-loongson/arch/mips/loongson/common/mtd.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/mtd.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/arch/mips/loongson/common/mtd.c 2010-05-27 18:12:28.902214422 +0200
- @@ -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.34.orig/arch/mips/loongson/common/rtc.c linux-loongson/arch/mips/loongson/common/rtc.c
- --- linux-2.6.34.orig/arch/mips/loongson/common/rtc.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/arch/mips/loongson/common/rtc.c 2010-05-27 18:12:28.902214422 +0200
- @@ -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.34.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-loongson/arch/mips/loongson/lemote-2f/ec_kb3310b.c
- --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-05-27 18:12:28.902214422 +0200
- @@ -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);
- @@ -78,12 +78,9 @@
- spin_unlock_irqrestore(&port_access_lock, flags);
-
- 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);
- + }
-
- return ret;
- }
- @@ -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.34.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-loongson/arch/mips/loongson/lemote-2f/ec_kb3310b.h
- --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/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.34.orig/arch/mips/loongson/lemote-2f/Makefile linux-loongson/arch/mips/loongson/lemote-2f/Makefile
- --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/Makefile 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/lemote-2f/Makefile 2010-05-27 18:12:28.902214422 +0200
- @@ -2,7 +2,7 @@
- # Makefile for lemote loongson2f family machines
- #
-
- -obj-y += machtype.o 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.34.orig/arch/mips/loongson/lemote-2f/platform.c linux-loongson/arch/mips/loongson/lemote-2f/platform.c
- --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/platform.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/arch/mips/loongson/lemote-2f/platform.c 2010-05-27 18:12:28.902214422 +0200
- @@ -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.34.orig/arch/mips/loongson/lemote-2f/pm.c linux-loongson/arch/mips/loongson/lemote-2f/pm.c
- --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/pm.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/lemote-2f/pm.c 2010-05-27 18:12:28.902214422 +0200
- @@ -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.34.orig/arch/mips/loongson/lemote-2f/reset.c linux-loongson/arch/mips/loongson/lemote-2f/reset.c
- --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/reset.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/loongson/lemote-2f/reset.c 2010-05-27 18:12:28.902214422 +0200
- @@ -20,7 +20,7 @@
- #include <loongson.h>
-
- #include <cs5536/cs5536.h>
- -#include "ec_kb3310b.h"
- +#include <ec_kb3310b.h>
-
- static void reset_cpu(void)
- {
- diff -Nur linux-2.6.34.orig/arch/mips/mm/dma-default.c linux-loongson/arch/mips/mm/dma-default.c
- --- linux-2.6.34.orig/arch/mips/mm/dma-default.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/mm/dma-default.c 2010-05-27 18:12:28.932213915 +0200
- @@ -375,3 +375,16 @@
- }
-
- EXPORT_SYMBOL(dma_cache_sync);
- +
- +int __weak dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- + void *cpu_addr, dma_addr_t handle, size_t size)
- +{
- + struct page *pg;
- + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- + cpu_addr = (void *)dma_addr_to_virt(dev, handle);
- + pg = virt_to_page(cpu_addr);
- + return remap_pfn_range(vma, vma->vm_start,
- + page_to_pfn(pg) + vma->vm_pgoff,
- + size, vma->vm_page_prot);
- +}
- +EXPORT_SYMBOL(dma_mmap_coherent);
- diff -Nur linux-2.6.34.orig/arch/mips/oprofile/op_model_loongson2.c linux-loongson/arch/mips/oprofile/op_model_loongson2.c
- --- linux-2.6.34.orig/arch/mips/oprofile/op_model_loongson2.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/arch/mips/oprofile/op_model_loongson2.c 2010-05-27 18:12:28.962214357 +0200
- @@ -8,7 +8,6 @@
- * 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.
- - *
- */
- #include <linux/init.h>
- #include <linux/oprofile.h>
- @@ -17,24 +16,18 @@
- #include <loongson.h> /* LOONGSON2_PERFCNT_IRQ */
- #include "op_impl.h"
-
- -/*
- - * a patch should be sent to oprofile with the loongson-specific support.
- - * otherwise, the oprofile tool will not recognize this and complain about
- - * "cpu_type 'unset' is not valid".
- - */
- #define LOONGSON2_CPU_TYPE "mips/loongson2"
-
- -#define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5)
- -#define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9)
- -
- -#define LOONGSON2_PERFCNT_EXL (1UL << 0)
- -#define LOONGSON2_PERFCNT_KERNEL (1UL << 1)
- -#define LOONGSON2_PERFCNT_SUPERVISOR (1UL << 2)
- -#define LOONGSON2_PERFCNT_USER (1UL << 3)
- -#define LOONGSON2_PERFCNT_INT_EN (1UL << 4)
- #define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31)
-
- -/* Loongson2 performance counter register */
- +#define LOONGSON2_PERFCTRL_EXL (1UL << 0)
- +#define LOONGSON2_PERFCTRL_KERNEL (1UL << 1)
- +#define LOONGSON2_PERFCTRL_SUPERVISOR (1UL << 2)
- +#define LOONGSON2_PERFCTRL_USER (1UL << 3)
- +#define LOONGSON2_PERFCTRL_ENABLE (1UL << 4)
- +#define LOONGSON2_PERFCTRL_EVENT(idx, event) \
- + (((event) & 0x0f) << ((idx) ? 9 : 5))
- +
- #define read_c0_perfctrl() __read_64bit_c0_register($24, 0)
- #define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val)
- #define read_c0_perfcnt() __read_64bit_c0_register($25, 0)
- @@ -49,7 +42,12 @@
-
- static char *oprofid = "LoongsonPerf";
- static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
- -/* Compute all of the registers in preparation for enabling profiling. */
- +
- +static void reset_counters(void *arg)
- +{
- + write_c0_perfctrl(0);
- + write_c0_perfcnt(0);
- +}
-
- static void loongson2_reg_setup(struct op_counter_config *cfg)
- {
- @@ -57,41 +55,38 @@
-
- reg.reset_counter1 = 0;
- reg.reset_counter2 = 0;
- - /* Compute the performance counter ctrl word. */
- - /* For now count kernel and user mode */
- +
- + /*
- + * Compute the performance counter ctrl word.
- + * For now, count kernel and user mode.
- + */
- if (cfg[0].enabled) {
- - ctrl |= LOONGSON2_COUNTER1_EVENT(cfg[0].event);
- + ctrl |= LOONGSON2_PERFCTRL_EVENT(0, cfg[0].event);
- reg.reset_counter1 = 0x80000000ULL - cfg[0].count;
- }
-
- if (cfg[1].enabled) {
- - ctrl |= LOONGSON2_COUNTER2_EVENT(cfg[1].event);
- - reg.reset_counter2 = (0x80000000ULL - cfg[1].count);
- + ctrl |= LOONGSON2_PERFCTRL_EVENT(1, cfg[1].event);
- + reg.reset_counter2 = 0x80000000ULL - cfg[1].count;
- }
-
- if (cfg[0].enabled || cfg[1].enabled) {
- - ctrl |= LOONGSON2_PERFCNT_EXL | LOONGSON2_PERFCNT_INT_EN;
- + ctrl |= LOONGSON2_PERFCTRL_EXL | LOONGSON2_PERFCTRL_ENABLE;
- if (cfg[0].kernel || cfg[1].kernel)
- - ctrl |= LOONGSON2_PERFCNT_KERNEL;
- + ctrl |= LOONGSON2_PERFCTRL_KERNEL;
- if (cfg[0].user || cfg[1].user)
- - ctrl |= LOONGSON2_PERFCNT_USER;
- + ctrl |= LOONGSON2_PERFCTRL_USER;
- }
-
- reg.ctrl = ctrl;
-
- reg.cnt1_enabled = cfg[0].enabled;
- reg.cnt2_enabled = cfg[1].enabled;
- -
- }
-
- -/* Program all of the registers in preparation for enabling profiling. */
- -
- static void loongson2_cpu_setup(void *args)
- {
- - uint64_t perfcount;
- -
- - perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1;
- - write_c0_perfcnt(perfcount);
- + write_c0_perfcnt((reg.reset_counter2 << 32) | reg.reset_counter1);
- }
-
- static void loongson2_cpu_start(void *args)
- @@ -114,15 +109,8 @@
- struct pt_regs *regs = get_irq_regs();
- int enabled;
-
- - /*
- - * LOONGSON2 defines two 32-bit performance counters.
- - * To avoid a race updating the registers we need to stop the counters
- - * while we're messing with
- - * them ...
- - */
- -
- /* Check whether the irq belongs to me */
- - enabled = read_c0_perfctrl() & LOONGSON2_PERFCNT_INT_EN;
- + enabled = read_c0_perfctrl() & LOONGSON2_PERFCTRL_ENABLE;
- if (!enabled)
- return IRQ_NONE;
- enabled = reg.cnt1_enabled | reg.cnt2_enabled;
- @@ -157,7 +145,7 @@
-
- static void loongson2_exit(void)
- {
- - write_c0_perfctrl(0);
- + reset_counters(NULL);
- free_irq(LOONGSON2_PERFCNT_IRQ, oprofid);
- }
-
- diff -Nur linux-2.6.34.orig/drivers/ide/ide-iops.c linux-loongson/drivers/ide/ide-iops.c
- --- linux-2.6.34.orig/drivers/ide/ide-iops.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/ide/ide-iops.c 2010-05-27 18:12:36.363472774 +0200
- @@ -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.34.orig/drivers/net/Kconfig linux-loongson/drivers/net/Kconfig
- --- linux-2.6.34.orig/drivers/net/Kconfig 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/net/Kconfig 2010-05-27 18:15:36.182214625 +0200
- @@ -2432,6 +2432,13 @@
- Some boards that use the Discovery chipset are the Momenco
- Ocelot C and Jaguar ATX and Pegasos II.
-
- +config TITAN_GE
- + bool "PMC-Sierra TITAN Gigabit Ethernet Support"
- + depends on PMC_YOSEMITE
- + help
- + This enables support for the the integrated ethernet of
- + PMC-Sierra's Titan SoC.
- +
- config XILINX_LL_TEMAC
- tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
- select PHYLIB
- diff -Nur linux-2.6.34.orig/drivers/net/Makefile linux-loongson/drivers/net/Makefile
- --- linux-2.6.34.orig/drivers/net/Makefile 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/net/Makefile 2010-05-27 18:15:36.182214625 +0200
- @@ -154,6 +154,8 @@
- obj-$(CONFIG_QLCNIC) += qlcnic/
- obj-$(CONFIG_QLGE) += qlge/
-
- +obj-$(CONFIG_TITAN_GE) += titan_mdio.o titan_ge.o
- +
- obj-$(CONFIG_PPP) += ppp_generic.o
- obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
- obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
- diff -Nur linux-2.6.34.orig/drivers/net/titan_ge.c linux-loongson/drivers/net/titan_ge.c
- --- linux-2.6.34.orig/drivers/net/titan_ge.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/titan_ge.c 2010-05-27 18:12:39.084716399 +0200
- @@ -0,0 +1,2069 @@
- +/*
- + * drivers/net/titan_ge.c - Driver for Titan ethernet ports
- + *
- + * Copyright (C) 2003 PMC-Sierra Inc.
- + * Author : Manish Lachwani (lachwani@pmc-sierra.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- + */
- +
- +/*
- + * The MAC unit of the Titan consists of the following:
- + *
- + * -> XDMA Engine to move data to from the memory to the MAC packet FIFO
- + * -> FIFO is where the incoming and outgoing data is placed
- + * -> TRTG is the unit that pulls the data from the FIFO for Tx and pushes
- + * the data into the FIFO for Rx
- + * -> TMAC is the outgoing MAC interface and RMAC is the incoming.
- + * -> AFX is the address filtering block
- + * -> GMII block to communicate with the PHY
- + *
- + * Rx will look like the following:
- + * GMII --> RMAC --> AFX --> TRTG --> Rx FIFO --> XDMA --> CPU memory
- + *
- + * Tx will look like the following:
- + * CPU memory --> XDMA --> Tx FIFO --> TRTG --> TMAC --> GMII
- + *
- + * The Titan driver has support for the following performance features:
- + * -> Rx side checksumming
- + * -> Jumbo Frames
- + * -> Interrupt Coalscing
- + * -> Rx NAPI
- + * -> SKB Recycling
- + * -> Transmit/Receive descriptors in SRAM
- + * -> Fast routing for IP forwarding
- + */
- +
- +#include <linux/dma-mapping.h>
- +#include <linux/module.h>
- +#include <linux/kernel.h>
- +#include <linux/sched.h>
- +#include <linux/ioport.h>
- +#include <linux/interrupt.h>
- +#include <linux/slab.h>
- +#include <linux/string.h>
- +#include <linux/errno.h>
- +#include <linux/ip.h>
- +#include <linux/init.h>
- +#include <linux/in.h>
- +#include <linux/platform_device.h>
- +#include <linux/netdevice.h>
- +#include <linux/etherdevice.h>
- +#include <linux/skbuff.h>
- +#include <linux/mii.h>
- +#include <linux/delay.h>
- +#include <linux/skbuff.h>
- +#include <linux/prefetch.h>
- +
- +/* For MII specifc registers, titan_mdio.h should be included */
- +#include <net/ip.h>
- +
- +#include <asm/bitops.h>
- +#include <asm/io.h>
- +#include <asm/types.h>
- +#include <asm/pgtable.h>
- +#include <asm/system.h>
- +#include <asm/titan_dep.h>
- +
- +#include "titan_ge.h"
- +#include "titan_mdio.h"
- +
- +/* Static Function Declarations */
- +static int titan_ge_eth_open(struct net_device *);
- +static void titan_ge_eth_stop(struct net_device *);
- +static struct net_device_stats *titan_ge_get_stats(struct net_device *);
- +static int titan_ge_init_rx_desc_ring(titan_ge_port_info *, int, int,
- + unsigned long, unsigned long,
- + unsigned long);
- +static int titan_ge_init_tx_desc_ring(titan_ge_port_info *, int,
- + unsigned long, unsigned long);
- +
- +static int titan_ge_open(struct net_device *);
- +static int titan_ge_start_xmit(struct sk_buff *, struct net_device *);
- +static int titan_ge_stop(struct net_device *);
- +
- +static unsigned long titan_ge_tx_coal(unsigned long, int);
- +
- +static void titan_ge_port_reset(unsigned int);
- +static int titan_ge_free_tx_queue(titan_ge_port_info *);
- +static int titan_ge_rx_task(struct net_device *, titan_ge_port_info *);
- +static int titan_ge_port_start(struct net_device *, titan_ge_port_info *);
- +
- +static int titan_ge_return_tx_desc(titan_ge_port_info *, int);
- +
- +/*
- + * Some configuration for the FIFO and the XDMA channel needs
- + * to be done only once for all the ports. This flag controls
- + * that
- + */
- +static unsigned long config_done;
- +
- +/*
- + * One time out of memory flag
- + */
- +static unsigned int oom_flag;
- +
- +static int titan_ge_poll(struct net_device *netdev, int *budget);
- +
- +static int titan_ge_receive_queue(struct net_device *, unsigned int);
- +
- +static struct platform_device *titan_ge_device[3];
- +
- +/* MAC Address */
- +extern unsigned char titan_ge_mac_addr_base[6];
- +
- +unsigned long titan_ge_base;
- +static unsigned long titan_ge_sram;
- +
- +static char titan_string[] = "titan";
- +
- +/*
- + * The Titan GE has two alignment requirements:
- + * -> skb->data to be cacheline aligned (32 byte)
- + * -> IP header alignment to 16 bytes
- + *
- + * The latter is not implemented. So, that results in an extra copy on
- + * the Rx. This is a big performance hog. For the former case, the
- + * dev_alloc_skb() has been replaced with titan_ge_alloc_skb(). The size
- + * requested is calculated:
- + *
- + * Ethernet Frame Size : 1518
- + * Ethernet Header : 14
- + * Future Titan change for IP header alignment : 2
- + *
- + * Hence, we allocate (1518 + 14 + 2+ 64) = 1580 bytes. For IP header
- + * alignment, we use skb_reserve().
- + */
- +
- +#define ALIGNED_RX_SKB_ADDR(addr) \
- + ((((unsigned long)(addr) + (64UL - 1UL)) \
- + & ~(64UL - 1UL)) - (unsigned long)(addr))
- +
- +#define titan_ge_alloc_skb(__length, __gfp_flags) \
- +({ struct sk_buff *__skb; \
- + __skb = alloc_skb((__length) + 64, (__gfp_flags)); \
- + if(__skb) { \
- + int __offset = (int) ALIGNED_RX_SKB_ADDR(__skb->data); \
- + if(__offset) \
- + skb_reserve(__skb, __offset); \
- + } \
- + __skb; \
- +})
- +
- +/*
- + * Configure the GMII block of the Titan based on what the PHY tells us
- + */
- +static void titan_ge_gmii_config(int port_num)
- +{
- + unsigned int reg_data = 0, phy_reg;
- + int err;
- +
- + err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
- +
- + if (err == TITAN_GE_MDIO_ERROR) {
- + printk(KERN_ERR
- + "Could not read PHY control register 0x11 \n");
- + printk(KERN_ERR
- + "Setting speed to 1000 Mbps and Duplex to Full \n");
- +
- + return;
- + }
- +
- + err = titan_ge_mdio_write(port_num, TITAN_GE_MDIO_PHY_IE, 0);
- +
- + if (phy_reg & 0x8000) {
- + if (phy_reg & 0x2000) {
- + /* Full Duplex and 1000 Mbps */
- + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
- + (port_num << 12)), 0x201);
- + } else {
- + /* Half Duplex and 1000 Mbps */
- + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
- + (port_num << 12)), 0x2201);
- + }
- + }
- + if (phy_reg & 0x4000) {
- + if (phy_reg & 0x2000) {
- + /* Full Duplex and 100 Mbps */
- + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
- + (port_num << 12)), 0x100);
- + } else {
- + /* Half Duplex and 100 Mbps */
- + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
- + (port_num << 12)), 0x2100);
- + }
- + }
- + reg_data = TITAN_GE_READ(TITAN_GE_GMII_CONFIG_GENERAL +
- + (port_num << 12));
- + reg_data |= 0x3;
- + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_GENERAL +
- + (port_num << 12)), reg_data);
- +}
- +
- +/*
- + * Enable the TMAC if it is not
- + */
- +static void titan_ge_enable_tx(unsigned int port_num)
- +{
- + unsigned long reg_data;
- +
- + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
- + if (!(reg_data & 0x8000)) {
- + printk("TMAC disabled for port %d!! \n", port_num);
- +
- + reg_data |= 0x0001; /* Enable TMAC */
- + reg_data |= 0x4000; /* CRC Check Enable */
- + reg_data |= 0x2000; /* Padding enable */
- + reg_data |= 0x0800; /* CRC Add enable */
- + reg_data |= 0x0080; /* PAUSE frame */
- +
- + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
- + (port_num << 12)), reg_data);
- + }
- +}
- +
- +/*
- + * Tx Timeout function
- + */
- +static void titan_ge_tx_timeout(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- +
- + printk(KERN_INFO "%s: TX timeout ", netdev->name);
- + printk(KERN_INFO "Resetting card \n");
- +
- + /* Do the reset outside of interrupt context */
- + schedule_work(&titan_ge_eth->tx_timeout_task);
- +}
- +
- +/*
- + * Update the AFX tables for UC and MC for slice 0 only
- + */
- +static void titan_ge_update_afx(titan_ge_port_info * titan_ge_eth)
- +{
- + int port = titan_ge_eth->port_num;
- + unsigned int i;
- + volatile unsigned long reg_data = 0;
- + u8 p_addr[6];
- +
- + memcpy(p_addr, titan_ge_eth->port_mac_addr, 6);
- +
- + /* Set the MAC address here for TMAC and RMAC */
- + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port << 12)),
- + ((p_addr[5] << 8) | p_addr[4]));
- + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port << 12)),
- + ((p_addr[3] << 8) | p_addr[2]));
- + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port << 12)),
- + ((p_addr[1] << 8) | p_addr[0]));
- +
- + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port << 12)),
- + ((p_addr[5] << 8) | p_addr[4]));
- + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port << 12)),
- + ((p_addr[3] << 8) | p_addr[2]));
- + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port << 12)),
- + ((p_addr[1] << 8) | p_addr[0]));
- +
- + TITAN_GE_WRITE((0x112c | (port << 12)), 0x1);
- + /* Configure the eight address filters */
- + for (i = 0; i < 8; i++) {
- + /* Select each of the eight filters */
- + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 +
- + (port << 12)), i);
- +
- + /* Configure the match */
- + reg_data = 0x9; /* Forward Enable Bit */
- + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 +
- + (port << 12)), reg_data);
- +
- + /* Finally, AFX Exact Match Address Registers */
- + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_LOW + (port << 12)),
- + ((p_addr[1] << 8) | p_addr[0]));
- + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_MID + (port << 12)),
- + ((p_addr[3] << 8) | p_addr[2]));
- + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_HIGH + (port << 12)),
- + ((p_addr[5] << 8) | p_addr[4]));
- +
- + /* VLAN id set to 0 */
- + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_VID +
- + (port << 12)), 0);
- + }
- +}
- +
- +/*
- + * Actual Routine to reset the adapter when the timeout occurred
- + */
- +static void titan_ge_tx_timeout_task(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + int port = titan_ge_eth->port_num;
- +
- + printk("Titan GE: Transmit timed out. Resetting ... \n");
- +
- + /* Dump debug info */
- + printk(KERN_ERR "TRTG cause : %x \n",
- + TITAN_GE_READ(0x100c + (port << 12)));
- +
- + /* Fix this for the other ports */
- + printk(KERN_ERR "FIFO cause : %x \n", TITAN_GE_READ(0x482c));
- + printk(KERN_ERR "IE cause : %x \n", TITAN_GE_READ(0x0040));
- + printk(KERN_ERR "XDMA GDI ERROR : %x \n",
- + TITAN_GE_READ(0x5008 + (port << 8)));
- + printk(KERN_ERR "CHANNEL ERROR: %x \n",
- + TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT
- + + (port << 8)));
- +
- + netif_device_detach(netdev);
- + titan_ge_port_reset(titan_ge_eth->port_num);
- + titan_ge_port_start(netdev, titan_ge_eth);
- + netif_device_attach(netdev);
- +}
- +
- +/*
- + * Change the MTU of the Ethernet Device
- + */
- +static int titan_ge_change_mtu(struct net_device *netdev, int new_mtu)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned long flags;
- +
- + if ((new_mtu > 9500) || (new_mtu < 64))
- + return -EINVAL;
- +
- + spin_lock_irqsave(&titan_ge_eth->lock, flags);
- +
- + netdev->mtu = new_mtu;
- +
- + /* Now we have to reopen the interface so that SKBs with the new
- + * size will be allocated */
- +
- + if (netif_running(netdev)) {
- + titan_ge_eth_stop(netdev);
- +
- + if (titan_ge_eth_open(netdev) != TITAN_OK) {
- + printk(KERN_ERR
- + "%s: Fatal error on opening device\n",
- + netdev->name);
- + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
- + return -1;
- + }
- + }
- +
- + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
- + return 0;
- +}
- +
- +/*
- + * Titan Gbe Interrupt Handler. All the three ports send interrupt to one line
- + * only. Once an interrupt is triggered, figure out the port and then check
- + * the channel.
- + */
- +static irqreturn_t titan_ge_int_handler(int irq, void *dev_id)
- +{
- + struct net_device *netdev = (struct net_device *) dev_id;
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + unsigned int reg_data;
- + unsigned int eth_int_cause_error = 0, is;
- + unsigned long eth_int_cause1;
- + int err = 0;
- +#ifdef CONFIG_SMP
- + unsigned long eth_int_cause2;
- +#endif
- +
- + /* Ack the CPU interrupt */
- + switch (port_num) {
- + case 0:
- + is = OCD_READ(RM9000x2_OCD_INTP0STATUS1);
- + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR1, is);
- +
- +#ifdef CONFIG_SMP
- + is = OCD_READ(RM9000x2_OCD_INTP1STATUS1);
- + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR1, is);
- +#endif
- + break;
- +
- + case 1:
- + is = OCD_READ(RM9000x2_OCD_INTP0STATUS0);
- + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR0, is);
- +
- +#ifdef CONFIG_SMP
- + is = OCD_READ(RM9000x2_OCD_INTP1STATUS0);
- + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR0, is);
- +#endif
- + break;
- +
- + case 2:
- + is = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
- + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR4, is);
- +
- +#ifdef CONFIG_SMP
- + is = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
- + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR4, is);
- +#endif
- + }
- +
- + eth_int_cause1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
- +#ifdef CONFIG_SMP
- + eth_int_cause2 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_B);
- +#endif
- +
- + /* Spurious interrupt */
- +#ifdef CONFIG_SMP
- + if ( (eth_int_cause1 == 0) && (eth_int_cause2 == 0)) {
- +#else
- + if (eth_int_cause1 == 0) {
- +#endif
- + eth_int_cause_error = TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT +
- + (port_num << 8));
- +
- + if (eth_int_cause_error == 0)
- + return IRQ_NONE;
- + }
- +
- + /* Handle Tx first. No need to ack interrupts */
- +#ifdef CONFIG_SMP
- + if ( (eth_int_cause1 & 0x20202) ||
- + (eth_int_cause2 & 0x20202) )
- +#else
- + if (eth_int_cause1 & 0x20202)
- +#endif
- + titan_ge_free_tx_queue(titan_ge_eth);
- +
- + /* Handle the Rx next */
- +#ifdef CONFIG_SMP
- + if ( (eth_int_cause1 & 0x10101) ||
- + (eth_int_cause2 & 0x10101)) {
- +#else
- + if (eth_int_cause1 & 0x10101) {
- +#endif
- + if (netif_rx_schedule_prep(netdev)) {
- + unsigned int ack;
- +
- + ack = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
- + /* Disable Tx and Rx both */
- + if (port_num == 0)
- + ack &= ~(0x3);
- + if (port_num == 1)
- + ack &= ~(0x300);
- +
- + if (port_num == 2)
- + ack &= ~(0x30000);
- +
- + /* Interrupts have been disabled */
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, ack);
- +
- + __netif_rx_schedule(netdev);
- + }
- + }
- +
- + /* Handle error interrupts */
- + if (eth_int_cause_error && (eth_int_cause_error != 0x2)) {
- + printk(KERN_ERR
- + "XDMA Channel Error : %x on port %d\n",
- + eth_int_cause_error, port_num);
- +
- + printk(KERN_ERR
- + "XDMA GDI Hardware error : %x on port %d\n",
- + TITAN_GE_READ(0x5008 + (port_num << 8)), port_num);
- +
- + printk(KERN_ERR
- + "XDMA currently has %d Rx descriptors \n",
- + TITAN_GE_READ(0x5048 + (port_num << 8)));
- +
- + printk(KERN_ERR
- + "XDMA currently has prefetcted %d Rx descriptors \n",
- + TITAN_GE_READ(0x505c + (port_num << 8)));
- +
- + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT +
- + (port_num << 8)), eth_int_cause_error);
- + }
- +
- + /*
- + * PHY interrupt to inform abt the changes. Reading the
- + * PHY Status register will clear the interrupt
- + */
- + if ((!(eth_int_cause1 & 0x30303)) &&
- + (eth_int_cause_error == 0)) {
- + err =
- + titan_ge_mdio_read(port_num,
- + TITAN_GE_MDIO_PHY_IS, ®_data);
- +
- + if (reg_data & 0x0400) {
- + /* Link status change */
- + titan_ge_mdio_read(port_num,
- + TITAN_GE_MDIO_PHY_STATUS, ®_data);
- + if (!(reg_data & 0x0400)) {
- + /* Link is down */
- + netif_carrier_off(netdev);
- + netif_stop_queue(netdev);
- + } else {
- + /* Link is up */
- + netif_carrier_on(netdev);
- + netif_wake_queue(netdev);
- +
- + /* Enable the queue */
- + titan_ge_enable_tx(port_num);
- + }
- + }
- + }
- +
- + return IRQ_HANDLED;
- +}
- +
- +/*
- + * Multicast and Promiscuous mode set. The
- + * set_multi entry point is called whenever the
- + * multicast address list or the network interface
- + * flags are updated.
- + */
- +static void titan_ge_set_multi(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + unsigned long reg_data;
- +
- + reg_data = TITAN_GE_READ(TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
- + (port_num << 12));
- +
- + if (netdev->flags & IFF_PROMISC) {
- + reg_data |= 0x2;
- + }
- + else if (netdev->flags & IFF_ALLMULTI) {
- + reg_data |= 0x01;
- + reg_data |= 0x400; /* Use the 64-bit Multicast Hash bin */
- + }
- + else {
- + reg_data = 0x2;
- + }
- +
- + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
- + (port_num << 12)), reg_data);
- + if (reg_data & 0x01) {
- + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_LOW +
- + (port_num << 12)), 0xffff);
- + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDLOW +
- + (port_num << 12)), 0xffff);
- + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDHI +
- + (port_num << 12)), 0xffff);
- + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_HI +
- + (port_num << 12)), 0xffff);
- + }
- +}
- +
- +/*
- + * Open the network device
- + */
- +static int titan_ge_open(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + unsigned int irq = TITAN_ETH_PORT_IRQ - port_num;
- + int retval;
- +
- + retval = request_irq(irq, titan_ge_int_handler,
- + SA_INTERRUPT | SA_SAMPLE_RANDOM , netdev->name, netdev);
- +
- + if (retval != 0) {
- + printk(KERN_ERR "Cannot assign IRQ number to TITAN GE \n");
- + return -1;
- + }
- +
- + netdev->irq = irq;
- + printk(KERN_INFO "Assigned IRQ %d to port %d\n", irq, port_num);
- +
- + spin_lock_irq(&(titan_ge_eth->lock));
- +
- + if (titan_ge_eth_open(netdev) != TITAN_OK) {
- + spin_unlock_irq(&(titan_ge_eth->lock));
- + printk("%s: Error opening interface \n", netdev->name);
- + free_irq(netdev->irq, netdev);
- + return -EBUSY;
- + }
- +
- + spin_unlock_irq(&(titan_ge_eth->lock));
- +
- + return 0;
- +}
- +
- +/*
- + * Allocate the SKBs for the Rx ring. Also used
- + * for refilling the queue
- + */
- +static int titan_ge_rx_task(struct net_device *netdev,
- + titan_ge_port_info *titan_ge_port)
- +{
- + struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
- + volatile titan_ge_rx_desc *rx_desc;
- + struct sk_buff *skb;
- + int rx_used_desc;
- + int count = 0;
- +
- + while (titan_ge_port->rx_ring_skbs < titan_ge_port->rx_ring_size) {
- +
- + /* First try to get the skb from the recycler */
- +#ifdef TITAN_GE_JUMBO_FRAMES
- + skb = titan_ge_alloc_skb(TITAN_GE_JUMBO_BUFSIZE, GFP_ATOMIC);
- +#else
- + skb = titan_ge_alloc_skb(TITAN_GE_STD_BUFSIZE, GFP_ATOMIC);
- +#endif
- + if (unlikely(!skb)) {
- + /* OOM, set the flag */
- + printk("OOM \n");
- + oom_flag = 1;
- + break;
- + }
- + count++;
- + skb->dev = netdev;
- +
- + titan_ge_port->rx_ring_skbs++;
- +
- + rx_used_desc = titan_ge_port->rx_used_desc_q;
- + rx_desc = &(titan_ge_port->rx_desc_area[rx_used_desc]);
- +
- +#ifdef TITAN_GE_JUMBO_FRAMES
- + rx_desc->buffer_addr = dma_map_single(device, skb->data,
- + TITAN_GE_JUMBO_BUFSIZE - 2, DMA_FROM_DEVICE);
- +#else
- + rx_desc->buffer_addr = dma_map_single(device, skb->data,
- + TITAN_GE_STD_BUFSIZE - 2, DMA_FROM_DEVICE);
- +#endif
- +
- + titan_ge_port->rx_skb[rx_used_desc] = skb;
- + rx_desc->cmd_sts = TITAN_GE_RX_BUFFER_OWNED;
- +
- + titan_ge_port->rx_used_desc_q =
- + (rx_used_desc + 1) % TITAN_GE_RX_QUEUE;
- + }
- +
- + return count;
- +}
- +
- +/*
- + * Actual init of the Tital GE port. There is one register for
- + * the channel configuration
- + */
- +static void titan_port_init(struct net_device *netdev,
- + titan_ge_port_info * titan_ge_eth)
- +{
- + unsigned long reg_data;
- +
- + titan_ge_port_reset(titan_ge_eth->port_num);
- +
- + /* First reset the TMAC */
- + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
- + reg_data |= 0x80000000;
- + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
- +
- + udelay(30);
- +
- + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
- + reg_data &= ~(0xc0000000);
- + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
- +
- + /* Now reset the RMAC */
- + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
- + reg_data |= 0x00080000;
- + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
- +
- + udelay(30);
- +
- + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
- + reg_data &= ~(0x000c0000);
- + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
- +}
- +
- +/*
- + * Start the port. All the hardware specific configuration
- + * for the XDMA, Tx FIFO, Rx FIFO, TMAC, RMAC, TRTG and AFX
- + * go here
- + */
- +static int titan_ge_port_start(struct net_device *netdev,
- + titan_ge_port_info * titan_port)
- +{
- + volatile unsigned long reg_data, reg_data1;
- + int port_num = titan_port->port_num;
- + int count = 0;
- + unsigned long reg_data_1;
- +
- + if (config_done == 0) {
- + reg_data = TITAN_GE_READ(0x0004);
- + reg_data |= 0x100;
- + TITAN_GE_WRITE(0x0004, reg_data);
- +
- + reg_data &= ~(0x100);
- + TITAN_GE_WRITE(0x0004, reg_data);
- +
- + /* Turn on GMII/MII mode and turn off TBI mode */
- + reg_data = TITAN_GE_READ(TITAN_GE_TSB_CTRL_1);
- + reg_data |= 0x00000700;
- + reg_data &= ~(0x00800000); /* Fencing */
- +
- + TITAN_GE_WRITE(0x000c, 0x00001100);
- +
- + TITAN_GE_WRITE(TITAN_GE_TSB_CTRL_1, reg_data);
- +
- + /* Set the CPU Resource Limit register */
- + TITAN_GE_WRITE(0x00f8, 0x8);
- +
- + /* Be conservative when using the BIU buffers */
- + TITAN_GE_WRITE(0x0068, 0x4);
- + }
- +
- + titan_port->tx_threshold = 0;
- + titan_port->rx_threshold = 0;
- +
- + /* We need to write the descriptors for Tx and Rx */
- + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_TX_DESC + (port_num << 8)),
- + (unsigned long) titan_port->tx_dma);
- + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_RX_DESC + (port_num << 8)),
- + (unsigned long) titan_port->rx_dma);
- +
- + if (config_done == 0) {
- + /* Step 1: XDMA config */
- + reg_data = TITAN_GE_READ(TITAN_GE_XDMA_CONFIG);
- + reg_data &= ~(0x80000000); /* clear reset */
- + reg_data |= 0x1 << 29; /* sparse tx descriptor spacing */
- + reg_data |= 0x1 << 28; /* sparse rx descriptor spacing */
- + reg_data |= (0x1 << 23) | (0x1 << 24); /* Descriptor Coherency */
- + reg_data |= (0x1 << 21) | (0x1 << 22); /* Data Coherency */
- + TITAN_GE_WRITE(TITAN_GE_XDMA_CONFIG, reg_data);
- + }
- +
- + /* IR register for the XDMA */
- + reg_data = TITAN_GE_READ(TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8));
- + reg_data |= 0x80068000; /* No Rx_OOD */
- + TITAN_GE_WRITE((TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8)), reg_data);
- +
- + /* Start the Tx and Rx XDMA controller */
- + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG + (port_num << 8));
- + reg_data &= 0x4fffffff; /* Clear tx reset */
- + reg_data &= 0xfff4ffff; /* Clear rx reset */
- +
- +#ifdef TITAN_GE_JUMBO_FRAMES
- + reg_data |= 0xa0 | 0x30030000;
- +#else
- + reg_data |= 0x40 | 0x20030000;
- +#endif
- +
- +#ifndef CONFIG_SMP
- + reg_data &= ~(0x10);
- + reg_data |= 0x0f; /* All of the packet */
- +#endif
- +
- + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG + (port_num << 8)), reg_data);
- +
- + /* Rx desc count */
- + count = titan_ge_rx_task(netdev, titan_port);
- + TITAN_GE_WRITE((0x5048 + (port_num << 8)), count);
- + count = TITAN_GE_READ(0x5048 + (port_num << 8));
- +
- + udelay(30);
- +
- + /*
- + * Step 2: Configure the SDQPF, i.e. FIFO
- + */
- + if (config_done == 0) {
- + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
- + reg_data = 0x1;
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
- + reg_data &= ~(0x1);
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
- + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
- +
- + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
- + reg_data = 0x1;
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
- + reg_data &= ~(0x1);
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
- + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
- + }
- + /*
- + * Enable RX FIFO 0, 4 and 8
- + */
- + if (port_num == 0) {
- + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_0);
- +
- + reg_data |= 0x100000;
- + reg_data |= (0xff << 10);
- +
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
- + /*
- + * BAV2,BAV and DAV settings for the Rx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x4844);
- + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
- + TITAN_GE_WRITE(0x4844, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
- +
- + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_0);
- + reg_data |= 0x100000;
- +
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
- +
- + reg_data |= (0xff << 10);
- +
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
- +
- + /*
- + * BAV2, BAV and DAV settings for the Tx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x4944);
- + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
- +
- + TITAN_GE_WRITE(0x4944, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
- +
- + }
- +
- + if (port_num == 1) {
- + reg_data = TITAN_GE_READ(0x4870);
- +
- + reg_data |= 0x100000;
- + reg_data |= (0xff << 10) | (0xff + 1);
- +
- + TITAN_GE_WRITE(0x4870, reg_data);
- + /*
- + * BAV2,BAV and DAV settings for the Rx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x4874);
- + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
- + TITAN_GE_WRITE(0x4874, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(0x4870, reg_data);
- +
- + reg_data = TITAN_GE_READ(0x494c);
- + reg_data |= 0x100000;
- +
- + TITAN_GE_WRITE(0x494c, reg_data);
- + reg_data |= (0xff << 10) | (0xff + 1);
- + TITAN_GE_WRITE(0x494c, reg_data);
- +
- + /*
- + * BAV2, BAV and DAV settings for the Tx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x4950);
- + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
- +
- + TITAN_GE_WRITE(0x4950, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(0x494c, reg_data);
- + }
- +
- + /*
- + * Titan 1.2 revision does support port #2
- + */
- + if (port_num == 2) {
- + /*
- + * Put the descriptors in the SRAM
- + */
- + reg_data = TITAN_GE_READ(0x48a0);
- +
- + reg_data |= 0x100000;
- + reg_data |= (0xff << 10) | (2*(0xff + 1));
- +
- + TITAN_GE_WRITE(0x48a0, reg_data);
- + /*
- + * BAV2,BAV and DAV settings for the Rx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x48a4);
- + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
- + TITAN_GE_WRITE(0x48a4, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(0x48a0, reg_data);
- +
- + reg_data = TITAN_GE_READ(0x4958);
- + reg_data |= 0x100000;
- +
- + TITAN_GE_WRITE(0x4958, reg_data);
- + reg_data |= (0xff << 10) | (2*(0xff + 1));
- + TITAN_GE_WRITE(0x4958, reg_data);
- +
- + /*
- + * BAV2, BAV and DAV settings for the Tx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x495c);
- + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
- +
- + TITAN_GE_WRITE(0x495c, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(0x4958, reg_data);
- + }
- +
- + if (port_num == 2) {
- + reg_data = TITAN_GE_READ(0x48a0);
- +
- + reg_data |= 0x100000;
- + reg_data |= (0xff << 10) | (2*(0xff + 1));
- +
- + TITAN_GE_WRITE(0x48a0, reg_data);
- + /*
- + * BAV2,BAV and DAV settings for the Rx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x48a4);
- + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
- + TITAN_GE_WRITE(0x48a4, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(0x48a0, reg_data);
- +
- + reg_data = TITAN_GE_READ(0x4958);
- + reg_data |= 0x100000;
- +
- + TITAN_GE_WRITE(0x4958, reg_data);
- + reg_data |= (0xff << 10) | (2*(0xff + 1));
- + TITAN_GE_WRITE(0x4958, reg_data);
- +
- + /*
- + * BAV2, BAV and DAV settings for the Tx FIFO
- + */
- + reg_data1 = TITAN_GE_READ(0x495c);
- + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
- +
- + TITAN_GE_WRITE(0x495c, reg_data1);
- +
- + reg_data &= ~(0x00100000);
- + reg_data |= 0x200000;
- +
- + TITAN_GE_WRITE(0x4958, reg_data);
- + }
- +
- + /*
- + * Step 3: TRTG block enable
- + */
- + reg_data = TITAN_GE_READ(TITAN_GE_TRTG_CONFIG + (port_num << 12));
- +
- + /*
- + * This is the 1.2 revision of the chip. It has fix for the
- + * IP header alignment. Now, the IP header begins at an
- + * aligned address and this wont need an extra copy in the
- + * driver. This performance drawback existed in the previous
- + * versions of the silicon
- + */
- + reg_data_1 = TITAN_GE_READ(0x103c + (port_num << 12));
- + reg_data_1 |= 0x40000000;
- + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
- +
- + reg_data_1 |= 0x04000000;
- + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
- +
- + mdelay(5);
- +
- + reg_data_1 &= ~(0x04000000);
- + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
- +
- + mdelay(5);
- +
- + reg_data |= 0x0001;
- + TITAN_GE_WRITE((TITAN_GE_TRTG_CONFIG + (port_num << 12)), reg_data);
- +
- + /*
- + * Step 4: Start the Tx activity
- + */
- + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_2 + (port_num << 12)), 0xe197);
- +#ifdef TITAN_GE_JUMBO_FRAMES
- + TITAN_GE_WRITE((0x1258 + (port_num << 12)), 0x4000);
- +#endif
- + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
- + reg_data |= 0x0001; /* Enable TMAC */
- + reg_data |= 0x6c70; /* PAUSE also set */
- +
- + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + (port_num << 12)), reg_data);
- +
- + udelay(30);
- +
- + /* Destination Address drop bit */
- + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_2 + (port_num << 12));
- + reg_data |= 0x218; /* DA_DROP bit and pause */
- + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_2 + (port_num << 12)), reg_data);
- +
- + TITAN_GE_WRITE((0x1218 + (port_num << 12)), 0x3);
- +
- +#ifdef TITAN_GE_JUMBO_FRAMES
- + TITAN_GE_WRITE((0x1208 + (port_num << 12)), 0x4000);
- +#endif
- + /* Start the Rx activity */
- + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
- + reg_data |= 0x0001; /* RMAC Enable */
- + reg_data |= 0x0010; /* CRC Check enable */
- + reg_data |= 0x0040; /* Min Frame check enable */
- + reg_data |= 0x4400; /* Max Frame check enable */
- +
- + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
- +
- + udelay(30);
- +
- + /*
- + * Enable the Interrupts for Tx and Rx
- + */
- + reg_data1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
- +
- + if (port_num == 0) {
- + reg_data1 |= 0x3;
- +#ifdef CONFIG_SMP
- + TITAN_GE_WRITE(0x0038, 0x003);
- +#else
- + TITAN_GE_WRITE(0x0038, 0x303);
- +#endif
- + }
- +
- + if (port_num == 1) {
- + reg_data1 |= 0x300;
- + }
- +
- + if (port_num == 2)
- + reg_data1 |= 0x30000;
- +
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data1);
- + TITAN_GE_WRITE(0x003c, 0x300);
- +
- + if (config_done == 0) {
- + TITAN_GE_WRITE(0x0024, 0x04000024); /* IRQ vector */
- + TITAN_GE_WRITE(0x0020, 0x000fb000); /* INTMSG base */
- + }
- +
- + /* Priority */
- + reg_data = TITAN_GE_READ(0x1038 + (port_num << 12));
- + reg_data &= ~(0x00f00000);
- + TITAN_GE_WRITE((0x1038 + (port_num << 12)), reg_data);
- +
- + /* Step 5: GMII config */
- + titan_ge_gmii_config(port_num);
- +
- + if (config_done == 0) {
- + TITAN_GE_WRITE(0x1a80, 0);
- + config_done = 1;
- + }
- +
- + return TITAN_OK;
- +}
- +
- +/*
- + * Function to queue the packet for the Ethernet device
- + */
- +static void titan_ge_tx_queue(titan_ge_port_info * titan_ge_eth,
- + struct sk_buff * skb)
- +{
- + struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev;
- + unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q;
- + volatile titan_ge_tx_desc *tx_curr;
- + int port_num = titan_ge_eth->port_num;
- +
- + tx_curr = &(titan_ge_eth->tx_desc_area[curr_desc]);
- + tx_curr->buffer_addr =
- + dma_map_single(device, skb->data, skb_headlen(skb),
- + DMA_TO_DEVICE);
- +
- + titan_ge_eth->tx_skb[curr_desc] = (struct sk_buff *) skb;
- + tx_curr->buffer_len = skb_headlen(skb);
- +
- + /* Last descriptor enables interrupt and changes ownership */
- + tx_curr->cmd_sts = 0x1 | (1 << 15) | (1 << 5);
- +
- + /* Kick the XDMA to start the transfer from memory to the FIFO */
- + TITAN_GE_WRITE((0x5044 + (port_num << 8)), 0x1);
- +
- + /* Current descriptor updated */
- + titan_ge_eth->tx_curr_desc_q = (curr_desc + 1) % TITAN_GE_TX_QUEUE;
- +
- + /* Prefetch the next descriptor */
- + prefetch((const void *)
- + &titan_ge_eth->tx_desc_area[titan_ge_eth->tx_curr_desc_q]);
- +}
- +
- +/*
- + * Actually does the open of the Ethernet device
- + */
- +static int titan_ge_eth_open(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + struct device *device = &titan_ge_device[port_num]->dev;
- + unsigned long reg_data;
- + unsigned int phy_reg;
- + int err = 0;
- +
- + /* Stop the Rx activity */
- + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
- + reg_data &= ~(0x00000001);
- + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
- +
- + /* Clear the port interrupts */
- + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT + (port_num << 8)), 0x0);
- +
- + if (config_done == 0) {
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0);
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_B, 0);
- + }
- +
- + /* Set the MAC Address */
- + memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
- +
- + if (config_done == 0)
- + titan_port_init(netdev, titan_ge_eth);
- +
- + titan_ge_update_afx(titan_ge_eth);
- +
- + /* Allocate the Tx ring now */
- + titan_ge_eth->tx_ring_skbs = 0;
- + titan_ge_eth->tx_ring_size = TITAN_GE_TX_QUEUE;
- +
- + /* Allocate space in the SRAM for the descriptors */
- + titan_ge_eth->tx_desc_area = (titan_ge_tx_desc *)
- + (titan_ge_sram + TITAN_TX_RING_BYTES * port_num);
- + titan_ge_eth->tx_dma = TITAN_SRAM_BASE + TITAN_TX_RING_BYTES * port_num;
- +
- + if (!titan_ge_eth->tx_desc_area) {
- + printk(KERN_ERR
- + "%s: Cannot allocate Tx Ring (size %d bytes) for port %d\n",
- + netdev->name, TITAN_TX_RING_BYTES, port_num);
- + return -ENOMEM;
- + }
- +
- + memset(titan_ge_eth->tx_desc_area, 0, titan_ge_eth->tx_desc_area_size);
- +
- + /* Now initialize the Tx descriptor ring */
- + titan_ge_init_tx_desc_ring(titan_ge_eth,
- + titan_ge_eth->tx_ring_size,
- + (unsigned long) titan_ge_eth->tx_desc_area,
- + (unsigned long) titan_ge_eth->tx_dma);
- +
- + /* Allocate the Rx ring now */
- + titan_ge_eth->rx_ring_size = TITAN_GE_RX_QUEUE;
- + titan_ge_eth->rx_ring_skbs = 0;
- +
- + titan_ge_eth->rx_desc_area =
- + (titan_ge_rx_desc *)(titan_ge_sram + 0x1000 + TITAN_RX_RING_BYTES * port_num);
- +
- + titan_ge_eth->rx_dma = TITAN_SRAM_BASE + 0x1000 + TITAN_RX_RING_BYTES * port_num;
- +
- + if (!titan_ge_eth->rx_desc_area) {
- + printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n",
- + netdev->name, TITAN_RX_RING_BYTES);
- +
- + printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
- + netdev->name);
- +
- + dma_free_coherent(device, titan_ge_eth->tx_desc_area_size,
- + (void *) titan_ge_eth->tx_desc_area,
- + titan_ge_eth->tx_dma);
- +
- + return -ENOMEM;
- + }
- +
- + memset(titan_ge_eth->rx_desc_area, 0, titan_ge_eth->rx_desc_area_size);
- +
- + /* Now initialize the Rx ring */
- +#ifdef TITAN_GE_JUMBO_FRAMES
- + if ((titan_ge_init_rx_desc_ring
- + (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_JUMBO_BUFSIZE,
- + (unsigned long) titan_ge_eth->rx_desc_area, 0,
- + (unsigned long) titan_ge_eth->rx_dma)) == 0)
- +#else
- + if ((titan_ge_init_rx_desc_ring
- + (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_STD_BUFSIZE,
- + (unsigned long) titan_ge_eth->rx_desc_area, 0,
- + (unsigned long) titan_ge_eth->rx_dma)) == 0)
- +#endif
- + panic("%s: Error initializing RX Ring\n", netdev->name);
- +
- + /* Fill the Rx ring with the SKBs */
- + titan_ge_port_start(netdev, titan_ge_eth);
- +
- + /*
- + * Check if Interrupt Coalscing needs to be turned on. The
- + * values specified in the register is multiplied by
- + * (8 x 64 nanoseconds) to determine when an interrupt should
- + * be sent to the CPU.
- + */
- +
- + if (TITAN_GE_TX_COAL) {
- + titan_ge_eth->tx_int_coal =
- + titan_ge_tx_coal(TITAN_GE_TX_COAL, port_num);
- + }
- +
- + err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
- + if (err == TITAN_GE_MDIO_ERROR) {
- + printk(KERN_ERR
- + "Could not read PHY control register 0x11 \n");
- + return TITAN_ERROR;
- + }
- + if (!(phy_reg & 0x0400)) {
- + netif_carrier_off(netdev);
- + netif_stop_queue(netdev);
- + return TITAN_ERROR;
- + } else {
- + netif_carrier_on(netdev);
- + netif_start_queue(netdev);
- + }
- +
- + return TITAN_OK;
- +}
- +
- +/*
- + * Queue the packet for Tx. Currently no support for zero copy,
- + * checksum offload and Scatter Gather. The chip does support
- + * Scatter Gather only. But, that wont help here since zero copy
- + * requires support for Tx checksumming also.
- + */
- +int titan_ge_start_xmit(struct sk_buff *skb, struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned long flags;
- + struct net_device_stats *stats;
- +//printk("titan_ge_start_xmit\n");
- +
- + stats = &titan_ge_eth->stats;
- + spin_lock_irqsave(&titan_ge_eth->lock, flags);
- +
- + if ((TITAN_GE_TX_QUEUE - titan_ge_eth->tx_ring_skbs) <=
- + (skb_shinfo(skb)->nr_frags + 1)) {
- + netif_stop_queue(netdev);
- + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
- + printk(KERN_ERR "Tx OOD \n");
- + return 1;
- + }
- +
- + titan_ge_tx_queue(titan_ge_eth, skb);
- + titan_ge_eth->tx_ring_skbs++;
- +
- + if (TITAN_GE_TX_QUEUE <= (titan_ge_eth->tx_ring_skbs + 4)) {
- + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
- + titan_ge_free_tx_queue(titan_ge_eth);
- + spin_lock_irqsave(&titan_ge_eth->lock, flags);
- + }
- +
- + stats->tx_bytes += skb->len;
- + stats->tx_packets++;
- +
- + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
- +
- + netdev->trans_start = jiffies;
- +
- + return 0;
- +}
- +
- +/*
- + * Actually does the Rx. Rx side checksumming supported.
- + */
- +static int titan_ge_rx(struct net_device *netdev, int port_num,
- + titan_ge_port_info * titan_ge_port,
- + titan_ge_packet * packet)
- +{
- + int rx_curr_desc, rx_used_desc;
- + volatile titan_ge_rx_desc *rx_desc;
- +
- + rx_curr_desc = titan_ge_port->rx_curr_desc_q;
- + rx_used_desc = titan_ge_port->rx_used_desc_q;
- +
- + if (((rx_curr_desc + 1) % TITAN_GE_RX_QUEUE) == rx_used_desc)
- + return TITAN_ERROR;
- +
- + rx_desc = &(titan_ge_port->rx_desc_area[rx_curr_desc]);
- +
- + if (rx_desc->cmd_sts & TITAN_GE_RX_BUFFER_OWNED)
- + return TITAN_ERROR;
- +
- + packet->skb = titan_ge_port->rx_skb[rx_curr_desc];
- + packet->len = (rx_desc->cmd_sts & 0x7fff);
- +
- + /*
- + * At this point, we dont know if the checksumming
- + * actually helps relieve CPU. So, keep it for
- + * port 0 only
- + */
- + packet->checksum = ntohs((rx_desc->buffer & 0xffff0000) >> 16);
- + packet->cmd_sts = rx_desc->cmd_sts;
- +
- + titan_ge_port->rx_curr_desc_q = (rx_curr_desc + 1) % TITAN_GE_RX_QUEUE;
- +
- + /* Prefetch the next descriptor */
- + prefetch((const void *)
- + &titan_ge_port->rx_desc_area[titan_ge_port->rx_curr_desc_q + 1]);
- +
- + return TITAN_OK;
- +}
- +
- +/*
- + * Free the Tx queue of the used SKBs
- + */
- +static int titan_ge_free_tx_queue(titan_ge_port_info *titan_ge_eth)
- +{
- + unsigned long flags;
- +
- + /* Take the lock */
- + spin_lock_irqsave(&(titan_ge_eth->lock), flags);
- +
- + while (titan_ge_return_tx_desc(titan_ge_eth, titan_ge_eth->port_num) == 0)
- + if (titan_ge_eth->tx_ring_skbs != 1)
- + titan_ge_eth->tx_ring_skbs--;
- +
- + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
- +
- + return TITAN_OK;
- +}
- +
- +/*
- + * Threshold beyond which we do the cleaning of
- + * Tx queue and new allocation for the Rx
- + * queue
- + */
- +#define TX_THRESHOLD 4
- +#define RX_THRESHOLD 10
- +
- +/*
- + * Receive the packets and send it to the kernel.
- + */
- +static int titan_ge_receive_queue(struct net_device *netdev, unsigned int max)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + titan_ge_packet packet;
- + struct net_device_stats *stats;
- + struct sk_buff *skb;
- + unsigned long received_packets = 0;
- + unsigned int ack;
- +
- + stats = &titan_ge_eth->stats;
- +
- + while ((--max)
- + && (titan_ge_rx(netdev, port_num, titan_ge_eth, &packet) == TITAN_OK)) {
- + skb = (struct sk_buff *) packet.skb;
- +
- + titan_ge_eth->rx_ring_skbs--;
- +
- + if (--titan_ge_eth->rx_work_limit < 0)
- + break;
- + received_packets++;
- +
- + stats->rx_packets++;
- + stats->rx_bytes += packet.len;
- +
- + if ((packet.cmd_sts & TITAN_GE_RX_PERR) ||
- + (packet.cmd_sts & TITAN_GE_RX_OVERFLOW_ERROR) ||
- + (packet.cmd_sts & TITAN_GE_RX_TRUNC) ||
- + (packet.cmd_sts & TITAN_GE_RX_CRC_ERROR)) {
- + stats->rx_dropped++;
- + dev_kfree_skb_any(skb);
- +
- + continue;
- + }
- + /*
- + * Either support fast path or slow path. Decision
- + * making can really slow down the performance. The
- + * idea is to cut down the number of checks and improve
- + * the fastpath.
- + */
- +
- + skb_put(skb, packet.len - 2);
- +
- + /*
- + * Increment data pointer by two since thats where
- + * the MAC starts
- + */
- + skb_reserve(skb, 2);
- + skb->protocol = eth_type_trans(skb, netdev);
- + netif_receive_skb(skb);
- +
- + if (titan_ge_eth->rx_threshold > RX_THRESHOLD) {
- + ack = titan_ge_rx_task(netdev, titan_ge_eth);
- + TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
- + titan_ge_eth->rx_threshold = 0;
- + } else
- + titan_ge_eth->rx_threshold++;
- +
- + if (titan_ge_eth->tx_threshold > TX_THRESHOLD) {
- + titan_ge_eth->tx_threshold = 0;
- + titan_ge_free_tx_queue(titan_ge_eth);
- + }
- + else
- + titan_ge_eth->tx_threshold++;
- +
- + }
- + return received_packets;
- +}
- +
- +
- +/*
- + * Enable the Rx side interrupts
- + */
- +static void titan_ge_enable_int(unsigned int port_num,
- + titan_ge_port_info *titan_ge_eth,
- + struct net_device *netdev)
- +{
- + unsigned long reg_data = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
- +
- + if (port_num == 0)
- + reg_data |= 0x3;
- + if (port_num == 1)
- + reg_data |= 0x300;
- + if (port_num == 2)
- + reg_data |= 0x30000;
- +
- + /* Re-enable interrupts */
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data);
- +}
- +
- +/*
- + * Main function to handle the polling for Rx side NAPI.
- + * Receive interrupts have been disabled at this point.
- + * The poll schedules the transmit followed by receive.
- + */
- +static int titan_ge_poll(struct net_device *netdev, int *budget)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + int port_num = titan_ge_eth->port_num;
- + int work_done = 0;
- + unsigned long flags, status;
- +
- + titan_ge_eth->rx_work_limit = *budget;
- + if (titan_ge_eth->rx_work_limit > netdev->quota)
- + titan_ge_eth->rx_work_limit = netdev->quota;
- +
- + do {
- + /* Do the transmit cleaning work here */
- + titan_ge_free_tx_queue(titan_ge_eth);
- +
- + /* Ack the Rx interrupts */
- + if (port_num == 0)
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x3);
- + if (port_num == 1)
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x300);
- + if (port_num == 2)
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x30000);
- +
- + work_done += titan_ge_receive_queue(netdev, 0);
- +
- + /* Out of quota and there is work to be done */
- + if (titan_ge_eth->rx_work_limit < 0)
- + goto not_done;
- +
- + /* Receive alloc_skb could lead to OOM */
- + if (oom_flag == 1) {
- + oom_flag = 0;
- + goto oom;
- + }
- +
- + status = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
- + } while (status & 0x30300);
- +
- + /* If we are here, then no more interrupts to process */
- + goto done;
- +
- +not_done:
- + *budget -= work_done;
- + netdev->quota -= work_done;
- + return 1;
- +
- +oom:
- + printk(KERN_ERR "OOM \n");
- + netif_rx_complete(netdev);
- + return 0;
- +
- +done:
- + /*
- + * No more packets on the poll list. Turn the interrupts
- + * back on and we should be able to catch the new
- + * packets in the interrupt handler
- + */
- + if (!work_done)
- + work_done = 1;
- +
- + *budget -= work_done;
- + netdev->quota -= work_done;
- +
- + spin_lock_irqsave(&titan_ge_eth->lock, flags);
- +
- + /* Remove us from the poll list */
- + netif_rx_complete(netdev);
- +
- + /* Re-enable interrupts */
- + titan_ge_enable_int(port_num, titan_ge_eth, netdev);
- +
- + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
- +
- + return 0;
- +}
- +
- +/*
- + * Close the network device
- + */
- +int titan_ge_stop(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- +
- + spin_lock_irq(&(titan_ge_eth->lock));
- + titan_ge_eth_stop(netdev);
- + free_irq(netdev->irq, netdev);
- + spin_unlock_irq(&titan_ge_eth->lock);
- +
- + return TITAN_OK;
- +}
- +
- +/*
- + * Free the Tx ring
- + */
- +static void titan_ge_free_tx_rings(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + unsigned int curr;
- + unsigned long reg_data;
- +
- + /* Stop the Tx DMA */
- + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
- + (port_num << 8));
- + reg_data |= 0xc0000000;
- + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
- + (port_num << 8)), reg_data);
- +
- + /* Disable the TMAC */
- + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
- + (port_num << 12));
- + reg_data &= ~(0x00000001);
- + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
- + (port_num << 12)), reg_data);
- +
- + for (curr = 0;
- + (titan_ge_eth->tx_ring_skbs) && (curr < TITAN_GE_TX_QUEUE);
- + curr++) {
- + if (titan_ge_eth->tx_skb[curr]) {
- + dev_kfree_skb(titan_ge_eth->tx_skb[curr]);
- + titan_ge_eth->tx_ring_skbs--;
- + }
- + }
- +
- + if (titan_ge_eth->tx_ring_skbs != 0)
- + printk
- + ("%s: Error on Tx descriptor free - could not free %d"
- + " descriptors\n", netdev->name,
- + titan_ge_eth->tx_ring_skbs);
- +
- +#ifndef TITAN_RX_RING_IN_SRAM
- + dma_free_coherent(&titan_ge_device[port_num]->dev,
- + titan_ge_eth->tx_desc_area_size,
- + (void *) titan_ge_eth->tx_desc_area,
- + titan_ge_eth->tx_dma);
- +#endif
- +}
- +
- +/*
- + * Free the Rx ring
- + */
- +static void titan_ge_free_rx_rings(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + unsigned int curr;
- + unsigned long reg_data;
- +
- + /* Stop the Rx DMA */
- + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
- + (port_num << 8));
- + reg_data |= 0x000c0000;
- + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
- + (port_num << 8)), reg_data);
- +
- + /* Disable the RMAC */
- + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
- + (port_num << 12));
- + reg_data &= ~(0x00000001);
- + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
- + (port_num << 12)), reg_data);
- +
- + for (curr = 0;
- + titan_ge_eth->rx_ring_skbs && (curr < TITAN_GE_RX_QUEUE);
- + curr++) {
- + if (titan_ge_eth->rx_skb[curr]) {
- + dev_kfree_skb(titan_ge_eth->rx_skb[curr]);
- + titan_ge_eth->rx_ring_skbs--;
- + }
- + }
- +
- + if (titan_ge_eth->rx_ring_skbs != 0)
- + printk(KERN_ERR
- + "%s: Error in freeing Rx Ring. %d skb's still"
- + " stuck in RX Ring - ignoring them\n", netdev->name,
- + titan_ge_eth->rx_ring_skbs);
- +
- +#ifndef TITAN_RX_RING_IN_SRAM
- + dma_free_coherent(&titan_ge_device[port_num]->dev,
- + titan_ge_eth->rx_desc_area_size,
- + (void *) titan_ge_eth->rx_desc_area,
- + titan_ge_eth->rx_dma);
- +#endif
- +}
- +
- +/*
- + * Actually does the stop of the Ethernet device
- + */
- +static void titan_ge_eth_stop(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- +
- + netif_stop_queue(netdev);
- +
- + titan_ge_port_reset(titan_ge_eth->port_num);
- +
- + titan_ge_free_tx_rings(netdev);
- + titan_ge_free_rx_rings(netdev);
- +
- + /* Disable the Tx and Rx Interrupts for all channels */
- + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, 0x0);
- +}
- +
- +/*
- + * Update the MAC address. Note that we have to write the
- + * address in three station registers, 16 bits each. And this
- + * has to be done for TMAC and RMAC
- + */
- +static void titan_ge_update_mac_address(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- + unsigned int port_num = titan_ge_eth->port_num;
- + u8 p_addr[6];
- +
- + memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
- + memcpy(p_addr, netdev->dev_addr, 6);
- +
- + /* Update the Address Filtering Match tables */
- + titan_ge_update_afx(titan_ge_eth);
- +
- + printk("Station MAC : %d %d %d %d %d %d \n",
- + p_addr[5], p_addr[4], p_addr[3],
- + p_addr[2], p_addr[1], p_addr[0]);
- +
- + /* Set the MAC address here for TMAC and RMAC */
- + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port_num << 12)),
- + ((p_addr[5] << 8) | p_addr[4]));
- + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port_num << 12)),
- + ((p_addr[3] << 8) | p_addr[2]));
- + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port_num << 12)),
- + ((p_addr[1] << 8) | p_addr[0]));
- +
- + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port_num << 12)),
- + ((p_addr[5] << 8) | p_addr[4]));
- + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port_num << 12)),
- + ((p_addr[3] << 8) | p_addr[2]));
- + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port_num << 12)),
- + ((p_addr[1] << 8) | p_addr[0]));
- +}
- +
- +/*
- + * Set the MAC address of the Ethernet device
- + */
- +static int titan_ge_set_mac_address(struct net_device *dev, void *addr)
- +{
- + titan_ge_port_info *tp = netdev_priv(dev);
- + struct sockaddr *sa = addr;
- +
- + memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
- +
- + spin_lock_irq(&tp->lock);
- + titan_ge_update_mac_address(dev);
- + spin_unlock_irq(&tp->lock);
- +
- + return 0;
- +}
- +
- +/*
- + * Get the Ethernet device stats
- + */
- +static struct net_device_stats *titan_ge_get_stats(struct net_device *netdev)
- +{
- + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
- +
- + return &titan_ge_eth->stats;
- +}
- +
- +/*
- + * Initialize the Rx descriptor ring for the Titan Ge
- + */
- +static int titan_ge_init_rx_desc_ring(titan_ge_port_info * titan_eth_port,
- + int rx_desc_num,
- + int rx_buff_size,
- + unsigned long rx_desc_base_addr,
- + unsigned long rx_buff_base_addr,
- + unsigned long rx_dma)
- +{
- + volatile titan_ge_rx_desc *rx_desc;
- + unsigned long buffer_addr;
- + int index;
- + unsigned long titan_ge_rx_desc_bus = rx_dma;
- +
- + buffer_addr = rx_buff_base_addr;
- + rx_desc = (titan_ge_rx_desc *) rx_desc_base_addr;
- +
- + /* Check alignment */
- + if (rx_buff_base_addr & 0xF)
- + return 0;
- +
- + /* Check Rx buffer size */
- + if ((rx_buff_size < 8) || (rx_buff_size > TITAN_GE_MAX_RX_BUFFER))
- + return 0;
- +
- + /* 64-bit alignment
- + if ((rx_buff_base_addr + rx_buff_size) & 0x7)
- + return 0; */
- +
- + /* Initialize the Rx desc ring */
- + for (index = 0; index < rx_desc_num; index++) {
- + titan_ge_rx_desc_bus += sizeof(titan_ge_rx_desc);
- + rx_desc[index].cmd_sts = 0;
- + rx_desc[index].buffer_addr = buffer_addr;
- + titan_eth_port->rx_skb[index] = NULL;
- + buffer_addr += rx_buff_size;
- + }
- +
- + titan_eth_port->rx_curr_desc_q = 0;
- + titan_eth_port->rx_used_desc_q = 0;
- +
- + titan_eth_port->rx_desc_area = (titan_ge_rx_desc *) rx_desc_base_addr;
- + titan_eth_port->rx_desc_area_size =
- + rx_desc_num * sizeof(titan_ge_rx_desc);
- +
- + titan_eth_port->rx_dma = rx_dma;
- +
- + return TITAN_OK;
- +}
- +
- +/*
- + * Initialize the Tx descriptor ring. Descriptors in the SRAM
- + */
- +static int titan_ge_init_tx_desc_ring(titan_ge_port_info * titan_ge_port,
- + int tx_desc_num,
- + unsigned long tx_desc_base_addr,
- + unsigned long tx_dma)
- +{
- + titan_ge_tx_desc *tx_desc;
- + int index;
- + unsigned long titan_ge_tx_desc_bus = tx_dma;
- +
- + if (tx_desc_base_addr & 0xF)
- + return 0;
- +
- + tx_desc = (titan_ge_tx_desc *) tx_desc_base_addr;
- +
- + for (index = 0; index < tx_desc_num; index++) {
- + titan_ge_port->tx_dma_array[index] =
- + (dma_addr_t) titan_ge_tx_desc_bus;
- + titan_ge_tx_desc_bus += sizeof(titan_ge_tx_desc);
- + tx_desc[index].cmd_sts = 0x0000;
- + tx_desc[index].buffer_len = 0;
- + tx_desc[index].buffer_addr = 0x00000000;
- + titan_ge_port->tx_skb[index] = NULL;
- + }
- +
- + titan_ge_port->tx_curr_desc_q = 0;
- + titan_ge_port->tx_used_desc_q = 0;
- +
- + titan_ge_port->tx_desc_area = (titan_ge_tx_desc *) tx_desc_base_addr;
- + titan_ge_port->tx_desc_area_size =
- + tx_desc_num * sizeof(titan_ge_tx_desc);
- +
- + titan_ge_port->tx_dma = tx_dma;
- + return TITAN_OK;
- +}
- +
- +/*
- + * Initialize the device as an Ethernet device
- + */
- +static int __init titan_ge_probe(struct device *device)
- +{
- + titan_ge_port_info *titan_ge_eth;
- + struct net_device *netdev;
- + int port = to_platform_device(device)->id;
- + int err;
- +
- + netdev = alloc_etherdev(sizeof(titan_ge_port_info));
- + if (!netdev) {
- + err = -ENODEV;
- + goto out;
- + }
- +
- + netdev->open = titan_ge_open;
- + netdev->stop = titan_ge_stop;
- + netdev->hard_start_xmit = titan_ge_start_xmit;
- + netdev->get_stats = titan_ge_get_stats;
- + netdev->set_multicast_list = titan_ge_set_multi;
- + netdev->set_mac_address = titan_ge_set_mac_address;
- +
- + /* Tx timeout */
- + netdev->tx_timeout = titan_ge_tx_timeout;
- + netdev->watchdog_timeo = 2 * HZ;
- +
- + /* Set these to very high values */
- + netdev->poll = titan_ge_poll;
- + netdev->weight = 64;
- +
- + netdev->tx_queue_len = TITAN_GE_TX_QUEUE;
- + netif_carrier_off(netdev);
- + netdev->base_addr = 0;
- +
- + netdev->change_mtu = titan_ge_change_mtu;
- +
- + titan_ge_eth = netdev_priv(netdev);
- + /* Allocation of memory for the driver structures */
- +
- + titan_ge_eth->port_num = port;
- +
- + /* Configure the Tx timeout handler */
- + INIT_WORK(&titan_ge_eth->tx_timeout_task,
- + (void (*)(void *)) titan_ge_tx_timeout_task, netdev);
- +
- + spin_lock_init(&titan_ge_eth->lock);
- +
- + /* set MAC addresses */
- + memcpy(netdev->dev_addr, titan_ge_mac_addr_base, 6);
- + netdev->dev_addr[5] += port;
- +
- + err = register_netdev(netdev);
- +
- + if (err)
- + goto out_free_netdev;
- +
- + printk(KERN_NOTICE
- + "%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
- + netdev->name, port, netdev->dev_addr[0],
- + netdev->dev_addr[1], netdev->dev_addr[2],
- + netdev->dev_addr[3], netdev->dev_addr[4],
- + netdev->dev_addr[5]);
- +
- + printk(KERN_NOTICE "Rx NAPI supported, Tx Coalescing ON \n");
- +
- + return 0;
- +
- +out_free_netdev:
- + kfree(netdev);
- +
- +out:
- + return err;
- +}
- +
- +static void __devexit titan_device_remove(struct device *device)
- +{
- +}
- +
- +/*
- + * Reset the Ethernet port
- + */
- +static void titan_ge_port_reset(unsigned int port_num)
- +{
- + unsigned int reg_data;
- +
- + /* Stop the Tx port activity */
- + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
- + (port_num << 12));
- + reg_data &= ~(0x0001);
- + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
- + (port_num << 12)), reg_data);
- +
- + /* Stop the Rx port activity */
- + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
- + (port_num << 12));
- + reg_data &= ~(0x0001);
- + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
- + (port_num << 12)), reg_data);
- +
- + return;
- +}
- +
- +/*
- + * Return the Tx desc after use by the XDMA
- + */
- +static int titan_ge_return_tx_desc(titan_ge_port_info * titan_ge_eth, int port)
- +{
- + int tx_desc_used;
- + struct sk_buff *skb;
- +
- + tx_desc_used = titan_ge_eth->tx_used_desc_q;
- +
- + /* return right away */
- + if (tx_desc_used == titan_ge_eth->tx_curr_desc_q)
- + return TITAN_ERROR;
- +
- + /* Now the critical stuff */
- + skb = titan_ge_eth->tx_skb[tx_desc_used];
- +
- + dev_kfree_skb_any(skb);
- +
- + titan_ge_eth->tx_skb[tx_desc_used] = NULL;
- + titan_ge_eth->tx_used_desc_q =
- + (tx_desc_used + 1) % TITAN_GE_TX_QUEUE;
- +
- + return 0;
- +}
- +
- +/*
- + * Coalescing for the Tx path
- + */
- +static unsigned long titan_ge_tx_coal(unsigned long delay, int port)
- +{
- + unsigned long rx_delay;
- +
- + rx_delay = TITAN_GE_READ(TITAN_GE_INT_COALESCING);
- + delay = (delay << 16) | rx_delay;
- +
- + TITAN_GE_WRITE(TITAN_GE_INT_COALESCING, delay);
- + TITAN_GE_WRITE(0x5038, delay);
- +
- + return delay;
- +}
- +
- +static struct device_driver titan_soc_driver = {
- + .name = titan_string,
- + .bus = &platform_bus_type,
- + .probe = titan_ge_probe,
- + .remove = __devexit_p(titan_device_remove),
- +};
- +
- +static void titan_platform_release (struct device *device)
- +{
- + struct platform_device *pldev;
- +
- + /* free device */
- + pldev = to_platform_device (device);
- + kfree (pldev);
- +}
- +
- +/*
- + * Register the Titan GE with the kernel
- + */
- +static int __init titan_ge_init_module(void)
- +{
- + struct platform_device *pldev;
- + unsigned int version, device;
- + int i;
- +
- + printk(KERN_NOTICE
- + "PMC-Sierra TITAN 10/100/1000 Ethernet Driver \n");
- +
- + titan_ge_base = (unsigned long) ioremap(TITAN_GE_BASE, TITAN_GE_SIZE);
- + if (!titan_ge_base) {
- + printk("Mapping Titan GE failed\n");
- + goto out;
- + }
- +
- + device = TITAN_GE_READ(TITAN_GE_DEVICE_ID);
- + version = (device & 0x000f0000) >> 16;
- + device &= 0x0000ffff;
- +
- + printk(KERN_NOTICE "Device Id : %x, Version : %x \n", device, version);
- +
- +#ifdef TITAN_RX_RING_IN_SRAM
- + titan_ge_sram = (unsigned long) ioremap(TITAN_SRAM_BASE,
- + TITAN_SRAM_SIZE);
- + if (!titan_ge_sram) {
- + printk("Mapping Titan SRAM failed\n");
- + goto out_unmap_ge;
- + }
- +#endif
- +
- + if (driver_register(&titan_soc_driver)) {
- + printk(KERN_ERR "Driver registration failed\n");
- + goto out_unmap_sram;
- + }
- +
- + for (i = 0; i < 3; i++) {
- + titan_ge_device[i] = NULL;
- +
- + if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
- + continue;
- +
- + memset (pldev, 0, sizeof (*pldev));
- + pldev->name = titan_string;
- + pldev->id = i;
- + pldev->dev.release = titan_platform_release;
- + titan_ge_device[i] = pldev;
- +
- + if (platform_device_register (pldev)) {
- + kfree (pldev);
- + titan_ge_device[i] = NULL;
- + continue;
- + }
- +
- + if (!pldev->dev.driver) {
- + /*
- + * The driver was not bound to this device, there was
- + * no hardware at this address. Unregister it, as the
- + * release fuction will take care of freeing the
- + * allocated structure
- + */
- + titan_ge_device[i] = NULL;
- + platform_device_unregister (pldev);
- + }
- + }
- +
- + return 0;
- +
- +out_unmap_sram:
- + iounmap((void *)titan_ge_sram);
- +
- +out_unmap_ge:
- + iounmap((void *)titan_ge_base);
- +
- +out:
- + return -ENOMEM;
- +}
- +
- +/*
- + * Unregister the Titan GE from the kernel
- + */
- +static void __exit titan_ge_cleanup_module(void)
- +{
- + int i;
- +
- + driver_unregister(&titan_soc_driver);
- +
- + for (i = 0; i < 3; i++) {
- + if (titan_ge_device[i]) {
- + platform_device_unregister (titan_ge_device[i]);
- + titan_ge_device[i] = NULL;
- + }
- + }
- +
- + iounmap((void *)titan_ge_sram);
- + iounmap((void *)titan_ge_base);
- +}
- +
- +MODULE_AUTHOR("Manish Lachwani <lachwani@pmc-sierra.com>");
- +MODULE_DESCRIPTION("Titan GE Ethernet driver");
- +MODULE_LICENSE("GPL");
- +
- +module_init(titan_ge_init_module);
- +module_exit(titan_ge_cleanup_module);
- diff -Nur linux-2.6.34.orig/drivers/net/titan_ge.h linux-loongson/drivers/net/titan_ge.h
- --- linux-2.6.34.orig/drivers/net/titan_ge.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/titan_ge.h 2010-05-27 18:12:39.084716399 +0200
- @@ -0,0 +1,415 @@
- +#ifndef _TITAN_GE_H_
- +#define _TITAN_GE_H_
- +
- +#include <linux/module.h>
- +#include <linux/kernel.h>
- +#include <linux/spinlock.h>
- +#include <asm/byteorder.h>
- +
- +/*
- + * These functions should be later moved to a more generic location since there
- + * will be others accessing it also
- + */
- +
- +/*
- + * This is the way it works: LKB5 Base is at 0x0128. TITAN_BASE is defined in
- + * include/asm/titan_dep.h. TITAN_GE_BASE is the value in the TITAN_GE_LKB5
- + * register.
- + */
- +
- +#define TITAN_GE_BASE 0xfe000000UL
- +#define TITAN_GE_SIZE 0x10000UL
- +
- +extern unsigned long titan_ge_base;
- +
- +#define TITAN_GE_WRITE(offset, data) \
- + *(volatile u32 *)(titan_ge_base + (offset)) = (data)
- +
- +#define TITAN_GE_READ(offset) *(volatile u32 *)(titan_ge_base + (offset))
- +
- +#ifndef msec_delay
- +#define msec_delay(x) do { if(in_interrupt()) { \
- + /* Don't mdelay in interrupt context! */ \
- + BUG(); \
- + } else { \
- + set_current_state(TASK_UNINTERRUPTIBLE); \
- + schedule_timeout((x * HZ)/1000); \
- + } } while(0)
- +#endif
- +
- +#define TITAN_GE_PORT_0
- +
- +#define TITAN_SRAM_BASE ((OCD_READ(RM9000x2_OCD_LKB13) & ~1) << 4)
- +#define TITAN_SRAM_SIZE 0x2000UL
- +
- +/*
- + * We may need these constants
- + */
- +#define TITAN_BIT0 0x00000001
- +#define TITAN_BIT1 0x00000002
- +#define TITAN_BIT2 0x00000004
- +#define TITAN_BIT3 0x00000008
- +#define TITAN_BIT4 0x00000010
- +#define TITAN_BIT5 0x00000020
- +#define TITAN_BIT6 0x00000040
- +#define TITAN_BIT7 0x00000080
- +#define TITAN_BIT8 0x00000100
- +#define TITAN_BIT9 0x00000200
- +#define TITAN_BIT10 0x00000400
- +#define TITAN_BIT11 0x00000800
- +#define TITAN_BIT12 0x00001000
- +#define TITAN_BIT13 0x00002000
- +#define TITAN_BIT14 0x00004000
- +#define TITAN_BIT15 0x00008000
- +#define TITAN_BIT16 0x00010000
- +#define TITAN_BIT17 0x00020000
- +#define TITAN_BIT18 0x00040000
- +#define TITAN_BIT19 0x00080000
- +#define TITAN_BIT20 0x00100000
- +#define TITAN_BIT21 0x00200000
- +#define TITAN_BIT22 0x00400000
- +#define TITAN_BIT23 0x00800000
- +#define TITAN_BIT24 0x01000000
- +#define TITAN_BIT25 0x02000000
- +#define TITAN_BIT26 0x04000000
- +#define TITAN_BIT27 0x08000000
- +#define TITAN_BIT28 0x10000000
- +#define TITAN_BIT29 0x20000000
- +#define TITAN_BIT30 0x40000000
- +#define TITAN_BIT31 0x80000000
- +
- +/* Flow Control */
- +#define TITAN_GE_FC_NONE 0x0
- +#define TITAN_GE_FC_FULL 0x1
- +#define TITAN_GE_FC_TX_PAUSE 0x2
- +#define TITAN_GE_FC_RX_PAUSE 0x3
- +
- +/* Duplex Settings */
- +#define TITAN_GE_FULL_DUPLEX 0x1
- +#define TITAN_GE_HALF_DUPLEX 0x2
- +
- +/* Speed settings */
- +#define TITAN_GE_SPEED_1000 0x1
- +#define TITAN_GE_SPEED_100 0x2
- +#define TITAN_GE_SPEED_10 0x3
- +
- +/* Debugging info only */
- +#undef TITAN_DEBUG
- +
- +/* Keep the rings in the Titan's SSRAM */
- +#define TITAN_RX_RING_IN_SRAM
- +
- +#ifdef CONFIG_64BIT
- +#define TITAN_GE_IE_MASK 0xfffffffffb001b64
- +#define TITAN_GE_IE_STATUS 0xfffffffffb001b60
- +#else
- +#define TITAN_GE_IE_MASK 0xfb001b64
- +#define TITAN_GE_IE_STATUS 0xfb001b60
- +#endif
- +
- +/* Support for Jumbo Frames */
- +#undef TITAN_GE_JUMBO_FRAMES
- +
- +/* Rx buffer size */
- +#ifdef TITAN_GE_JUMBO_FRAMES
- +#define TITAN_GE_JUMBO_BUFSIZE 9080
- +#else
- +#define TITAN_GE_STD_BUFSIZE 1580
- +#endif
- +
- +/*
- + * Tx and Rx Interrupt Coalescing parameter. These values are
- + * for 1 Ghz processor. Rx coalescing can be taken care of
- + * by NAPI. NAPI is adaptive and hence useful. Tx coalescing
- + * is not adaptive. Hence, these values need to be adjusted
- + * based on load, CPU speed etc.
- + */
- +#define TITAN_GE_RX_COAL 150
- +#define TITAN_GE_TX_COAL 300
- +
- +#if defined(__BIG_ENDIAN)
- +
- +/* Define the Rx descriptor */
- +typedef struct eth_rx_desc {
- + u32 reserved; /* Unused */
- + u32 buffer_addr; /* CPU buffer address */
- + u32 cmd_sts; /* Command and Status */
- + u32 buffer; /* XDMA buffer address */
- +} titan_ge_rx_desc;
- +
- +/* Define the Tx descriptor */
- +typedef struct eth_tx_desc {
- + u16 cmd_sts; /* Command, Status and Buffer count */
- + u16 buffer_len; /* Length of the buffer */
- + u32 buffer_addr; /* Physical address of the buffer */
- +} titan_ge_tx_desc;
- +
- +#elif defined(__LITTLE_ENDIAN)
- +
- +/* Define the Rx descriptor */
- +typedef struct eth_rx_desc {
- + u32 buffer_addr; /* CPU buffer address */
- + u32 reserved; /* Unused */
- + u32 buffer; /* XDMA buffer address */
- + u32 cmd_sts; /* Command and Status */
- +} titan_ge_rx_desc;
- +
- +/* Define the Tx descriptor */
- +typedef struct eth_tx_desc {
- + u32 buffer_addr; /* Physical address of the buffer */
- + u16 buffer_len; /* Length of the buffer */
- + u16 cmd_sts; /* Command, Status and Buffer count */
- +} titan_ge_tx_desc;
- +#endif
- +
- +/* Default Tx Queue Size */
- +#define TITAN_GE_TX_QUEUE 128
- +#define TITAN_TX_RING_BYTES (TITAN_GE_TX_QUEUE * sizeof(struct eth_tx_desc))
- +
- +/* Default Rx Queue Size */
- +#define TITAN_GE_RX_QUEUE 64
- +#define TITAN_RX_RING_BYTES (TITAN_GE_RX_QUEUE * sizeof(struct eth_rx_desc))
- +
- +/* Packet Structure */
- +typedef struct _pkt_info {
- + unsigned int len;
- + unsigned int cmd_sts;
- + unsigned int buffer;
- + struct sk_buff *skb;
- + unsigned int checksum;
- +} titan_ge_packet;
- +
- +
- +#define PHYS_CNT 3
- +
- +/* Titan Port specific data structure */
- +typedef struct _eth_port_ctrl {
- + unsigned int port_num;
- + u8 port_mac_addr[6];
- +
- + /* Rx descriptor pointers */
- + int rx_curr_desc_q, rx_used_desc_q;
- +
- + /* Tx descriptor pointers */
- + int tx_curr_desc_q, tx_used_desc_q;
- +
- + /* Rx descriptor area */
- + volatile titan_ge_rx_desc *rx_desc_area;
- + unsigned int rx_desc_area_size;
- + struct sk_buff* rx_skb[TITAN_GE_RX_QUEUE];
- +
- + /* Tx Descriptor area */
- + volatile titan_ge_tx_desc *tx_desc_area;
- + unsigned int tx_desc_area_size;
- + struct sk_buff* tx_skb[TITAN_GE_TX_QUEUE];
- +
- + /* Timeout task */
- + struct work_struct tx_timeout_task;
- +
- + /* DMA structures and handles */
- + dma_addr_t tx_dma;
- + dma_addr_t rx_dma;
- + dma_addr_t tx_dma_array[TITAN_GE_TX_QUEUE];
- +
- + /* Device lock */
- + spinlock_t lock;
- +
- + unsigned int tx_ring_skbs;
- + unsigned int rx_ring_size;
- + unsigned int tx_ring_size;
- + unsigned int rx_ring_skbs;
- +
- + struct net_device_stats stats;
- +
- + /* Tx and Rx coalescing */
- + unsigned long rx_int_coal;
- + unsigned long tx_int_coal;
- +
- + /* Threshold for replenishing the Rx and Tx rings */
- + unsigned int tx_threshold;
- + unsigned int rx_threshold;
- +
- + /* NAPI work limit */
- + unsigned int rx_work_limit;
- +} titan_ge_port_info;
- +
- +/* Titan specific constants */
- +#define TITAN_ETH_PORT_IRQ 3
- +
- +/* Max Rx buffer */
- +#define TITAN_GE_MAX_RX_BUFFER 65536
- +
- +/* Tx and Rx Error */
- +#define TITAN_GE_ERROR
- +
- +/* Rx Descriptor Command and Status */
- +
- +#define TITAN_GE_RX_CRC_ERROR TITAN_BIT27 /* crc error */
- +#define TITAN_GE_RX_OVERFLOW_ERROR TITAN_BIT15 /* overflow */
- +#define TITAN_GE_RX_BUFFER_OWNED TITAN_BIT21 /* buffer ownership */
- +#define TITAN_GE_RX_STP TITAN_BIT31 /* start of packet */
- +#define TITAN_GE_RX_BAM TITAN_BIT30 /* broadcast address match */
- +#define TITAN_GE_RX_PAM TITAN_BIT28 /* physical address match */
- +#define TITAN_GE_RX_LAFM TITAN_BIT29 /* logical address filter match */
- +#define TITAN_GE_RX_VLAN TITAN_BIT26 /* virtual lans */
- +#define TITAN_GE_RX_PERR TITAN_BIT19 /* packet error */
- +#define TITAN_GE_RX_TRUNC TITAN_BIT20 /* packet size greater than 32 buffers */
- +
- +/* Tx Descriptor Command */
- +#define TITAN_GE_TX_BUFFER_OWNED TITAN_BIT5 /* buffer ownership */
- +#define TITAN_GE_TX_ENABLE_INTERRUPT TITAN_BIT15 /* Interrupt Enable */
- +
- +/* Return Status */
- +#define TITAN_OK 0x1 /* Good Status */
- +#define TITAN_ERROR 0x2 /* Error Status */
- +
- +/* MIB specific register offset */
- +#define TITAN_GE_MSTATX_STATS_BASE_LOW 0x0800 /* MSTATX COUNTL[15:0] */
- +#define TITAN_GE_MSTATX_STATS_BASE_MID 0x0804 /* MSTATX COUNTM[15:0] */
- +#define TITAN_GE_MSTATX_STATS_BASE_HI 0x0808 /* MSTATX COUNTH[7:0] */
- +#define TITAN_GE_MSTATX_CONTROL 0x0828 /* MSTATX Control */
- +#define TITAN_GE_MSTATX_VARIABLE_SELECT 0x082C /* MSTATX Variable Select */
- +
- +/* MIB counter offsets, add to the TITAN_GE_MSTATX_STATS_BASE_XXX */
- +#define TITAN_GE_MSTATX_RXFRAMESOK 0x0040
- +#define TITAN_GE_MSTATX_RXOCTETSOK 0x0050
- +#define TITAN_GE_MSTATX_RXFRAMES 0x0060
- +#define TITAN_GE_MSTATX_RXOCTETS 0x0070
- +#define TITAN_GE_MSTATX_RXUNICASTFRAMESOK 0x0080
- +#define TITAN_GE_MSTATX_RXBROADCASTFRAMESOK 0x0090
- +#define TITAN_GE_MSTATX_RXMULTICASTFRAMESOK 0x00A0
- +#define TITAN_GE_MSTATX_RXTAGGEDFRAMESOK 0x00B0
- +#define TITAN_GE_MSTATX_RXMACPAUSECONTROLFRAMESOK 0x00C0
- +#define TITAN_GE_MSTATX_RXMACCONTROLFRAMESOK 0x00D0
- +#define TITAN_GE_MSTATX_RXFCSERROR 0x00E0
- +#define TITAN_GE_MSTATX_RXALIGNMENTERROR 0x00F0
- +#define TITAN_GE_MSTATX_RXSYMBOLERROR 0x0100
- +#define TITAN_GE_MSTATX_RXLAYER1ERROR 0x0110
- +#define TITAN_GE_MSTATX_RXINRANGELENGTHERROR 0x0120
- +#define TITAN_GE_MSTATX_RXLONGLENGTHERROR 0x0130
- +#define TITAN_GE_MSTATX_RXLONGLENGTHCRCERROR 0x0140
- +#define TITAN_GE_MSTATX_RXSHORTLENGTHERROR 0x0150
- +#define TITAN_GE_MSTATX_RXSHORTLLENGTHCRCERROR 0x0160
- +#define TITAN_GE_MSTATX_RXFRAMES64OCTETS 0x0170
- +#define TITAN_GE_MSTATX_RXFRAMES65TO127OCTETS 0x0180
- +#define TITAN_GE_MSTATX_RXFRAMES128TO255OCTETS 0x0190
- +#define TITAN_GE_MSTATX_RXFRAMES256TO511OCTETS 0x01A0
- +#define TITAN_GE_MSTATX_RXFRAMES512TO1023OCTETS 0x01B0
- +#define TITAN_GE_MSTATX_RXFRAMES1024TO1518OCTETS 0x01C0
- +#define TITAN_GE_MSTATX_RXFRAMES1519TOMAXSIZE 0x01D0
- +#define TITAN_GE_MSTATX_RXSTATIONADDRESSFILTERED 0x01E0
- +#define TITAN_GE_MSTATX_RXVARIABLE 0x01F0
- +#define TITAN_GE_MSTATX_GENERICADDRESSFILTERED 0x0200
- +#define TITAN_GE_MSTATX_UNICASTFILTERED 0x0210
- +#define TITAN_GE_MSTATX_MULTICASTFILTERED 0x0220
- +#define TITAN_GE_MSTATX_BROADCASTFILTERED 0x0230
- +#define TITAN_GE_MSTATX_HASHFILTERED 0x0240
- +#define TITAN_GE_MSTATX_TXFRAMESOK 0x0250
- +#define TITAN_GE_MSTATX_TXOCTETSOK 0x0260
- +#define TITAN_GE_MSTATX_TXOCTETS 0x0270
- +#define TITAN_GE_MSTATX_TXTAGGEDFRAMESOK 0x0280
- +#define TITAN_GE_MSTATX_TXMACPAUSECONTROLFRAMESOK 0x0290
- +#define TITAN_GE_MSTATX_TXFCSERROR 0x02A0
- +#define TITAN_GE_MSTATX_TXSHORTLENGTHERROR 0x02B0
- +#define TITAN_GE_MSTATX_TXLONGLENGTHERROR 0x02C0
- +#define TITAN_GE_MSTATX_TXSYSTEMERROR 0x02D0
- +#define TITAN_GE_MSTATX_TXMACERROR 0x02E0
- +#define TITAN_GE_MSTATX_TXCARRIERSENSEERROR 0x02F0
- +#define TITAN_GE_MSTATX_TXSQETESTERROR 0x0300
- +#define TITAN_GE_MSTATX_TXUNICASTFRAMESOK 0x0310
- +#define TITAN_GE_MSTATX_TXBROADCASTFRAMESOK 0x0320
- +#define TITAN_GE_MSTATX_TXMULTICASTFRAMESOK 0x0330
- +#define TITAN_GE_MSTATX_TXUNICASTFRAMESATTEMPTED 0x0340
- +#define TITAN_GE_MSTATX_TXBROADCASTFRAMESATTEMPTED 0x0350
- +#define TITAN_GE_MSTATX_TXMULTICASTFRAMESATTEMPTED 0x0360
- +#define TITAN_GE_MSTATX_TXFRAMES64OCTETS 0x0370
- +#define TITAN_GE_MSTATX_TXFRAMES65TO127OCTETS 0x0380
- +#define TITAN_GE_MSTATX_TXFRAMES128TO255OCTETS 0x0390
- +#define TITAN_GE_MSTATX_TXFRAMES256TO511OCTETS 0x03A0
- +#define TITAN_GE_MSTATX_TXFRAMES512TO1023OCTETS 0x03B0
- +#define TITAN_GE_MSTATX_TXFRAMES1024TO1518OCTETS 0x03C0
- +#define TITAN_GE_MSTATX_TXFRAMES1519TOMAXSIZE 0x03D0
- +#define TITAN_GE_MSTATX_TXVARIABLE 0x03E0
- +#define TITAN_GE_MSTATX_RXSYSTEMERROR 0x03F0
- +#define TITAN_GE_MSTATX_SINGLECOLLISION 0x0400
- +#define TITAN_GE_MSTATX_MULTIPLECOLLISION 0x0410
- +#define TITAN_GE_MSTATX_DEFERREDXMISSIONS 0x0420
- +#define TITAN_GE_MSTATX_LATECOLLISIONS 0x0430
- +#define TITAN_GE_MSTATX_ABORTEDDUETOXSCOLLS 0x0440
- +
- +/* Interrupt specific defines */
- +#define TITAN_GE_DEVICE_ID 0x0000 /* Device ID */
- +#define TITAN_GE_RESET 0x0004 /* Reset reg */
- +#define TITAN_GE_TSB_CTRL_0 0x000C /* TSB Control reg 0 */
- +#define TITAN_GE_TSB_CTRL_1 0x0010 /* TSB Control reg 1 */
- +#define TITAN_GE_INTR_GRP0_STATUS 0x0040 /* General Interrupt Group 0 Status */
- +#define TITAN_GE_INTR_XDMA_CORE_A 0x0048 /* XDMA Channel Interrupt Status, Core A*/
- +#define TITAN_GE_INTR_XDMA_CORE_B 0x004C /* XDMA Channel Interrupt Status, Core B*/
- +#define TITAN_GE_INTR_XDMA_IE 0x0058 /* XDMA Channel Interrupt Enable */
- +#define TITAN_GE_SDQPF_ECC_INTR 0x480C /* SDQPF ECC Interrupt Status */
- +#define TITAN_GE_SDQPF_RXFIFO_CTL 0x4828 /* SDQPF RxFifo Control and Interrupt Enb*/
- +#define TITAN_GE_SDQPF_RXFIFO_INTR 0x482C /* SDQPF RxFifo Interrupt Status */
- +#define TITAN_GE_SDQPF_TXFIFO_CTL 0x4928 /* SDQPF TxFifo Control and Interrupt Enb*/
- +#define TITAN_GE_SDQPF_TXFIFO_INTR 0x492C /* SDQPF TxFifo Interrupt Status */
- +#define TITAN_GE_SDQPF_RXFIFO_0 0x4840 /* SDQPF RxFIFO Enable */
- +#define TITAN_GE_SDQPF_TXFIFO_0 0x4940 /* SDQPF TxFIFO Enable */
- +#define TITAN_GE_XDMA_CONFIG 0x5000 /* XDMA Global Configuration */
- +#define TITAN_GE_XDMA_INTR_SUMMARY 0x5010 /* XDMA Interrupt Summary */
- +#define TITAN_GE_XDMA_BUFADDRPRE 0x5018 /* XDMA Buffer Address Prefix */
- +#define TITAN_GE_XDMA_DESCADDRPRE 0x501C /* XDMA Descriptor Address Prefix */
- +#define TITAN_GE_XDMA_PORTWEIGHT 0x502C /* XDMA Port Weight Configuration */
- +
- +/* Rx MAC defines */
- +#define TITAN_GE_RMAC_CONFIG_1 0x1200 /* RMAC Configuration 1 */
- +#define TITAN_GE_RMAC_CONFIG_2 0x1204 /* RMAC Configuration 2 */
- +#define TITAN_GE_RMAC_MAX_FRAME_LEN 0x1208 /* RMAC Max Frame Length */
- +#define TITAN_GE_RMAC_STATION_HI 0x120C /* Rx Station Address High */
- +#define TITAN_GE_RMAC_STATION_MID 0x1210 /* Rx Station Address Middle */
- +#define TITAN_GE_RMAC_STATION_LOW 0x1214 /* Rx Station Address Low */
- +#define TITAN_GE_RMAC_LINK_CONFIG 0x1218 /* RMAC Link Configuration */
- +
- +/* Tx MAC defines */
- +#define TITAN_GE_TMAC_CONFIG_1 0x1240 /* TMAC Configuration 1 */
- +#define TITAN_GE_TMAC_CONFIG_2 0x1244 /* TMAC Configuration 2 */
- +#define TITAN_GE_TMAC_IPG 0x1248 /* TMAC Inter-Packet Gap */
- +#define TITAN_GE_TMAC_STATION_HI 0x124C /* Tx Station Address High */
- +#define TITAN_GE_TMAC_STATION_MID 0x1250 /* Tx Station Address Middle */
- +#define TITAN_GE_TMAC_STATION_LOW 0x1254 /* Tx Station Address Low */
- +#define TITAN_GE_TMAC_MAX_FRAME_LEN 0x1258 /* TMAC Max Frame Length */
- +#define TITAN_GE_TMAC_MIN_FRAME_LEN 0x125C /* TMAC Min Frame Length */
- +#define TITAN_GE_TMAC_PAUSE_FRAME_TIME 0x1260 /* TMAC Pause Frame Time */
- +#define TITAN_GE_TMAC_PAUSE_FRAME_INTERVAL 0x1264 /* TMAC Pause Frame Interval */
- +
- +/* GMII register */
- +#define TITAN_GE_GMII_INTERRUPT_STATUS 0x1348 /* GMII Interrupt Status */
- +#define TITAN_GE_GMII_CONFIG_GENERAL 0x134C /* GMII Configuration General */
- +#define TITAN_GE_GMII_CONFIG_MODE 0x1350 /* GMII Configuration Mode */
- +
- +/* Tx and Rx XDMA defines */
- +#define TITAN_GE_INT_COALESCING 0x5030 /* Interrupt Coalescing */
- +#define TITAN_GE_CHANNEL0_CONFIG 0x5040 /* Channel 0 XDMA config */
- +#define TITAN_GE_CHANNEL0_INTERRUPT 0x504c /* Channel 0 Interrupt Status */
- +#define TITAN_GE_GDI_INTERRUPT_ENABLE 0x5050 /* IE for the GDI Errors */
- +#define TITAN_GE_CHANNEL0_PACKET 0x5060 /* Channel 0 Packet count */
- +#define TITAN_GE_CHANNEL0_BYTE 0x5064 /* Channel 0 Byte count */
- +#define TITAN_GE_CHANNEL0_TX_DESC 0x5054 /* Channel 0 Tx first desc */
- +#define TITAN_GE_CHANNEL0_RX_DESC 0x5058 /* Channel 0 Rx first desc */
- +
- +/* AFX (Address Filter Exact) register offsets for Slice 0 */
- +#define TITAN_GE_AFX_EXACT_MATCH_LOW 0x1100 /* AFX Exact Match Address Low*/
- +#define TITAN_GE_AFX_EXACT_MATCH_MID 0x1104 /* AFX Exact Match Address Mid*/
- +#define TITAN_GE_AFX_EXACT_MATCH_HIGH 0x1108 /* AFX Exact Match Address Hi */
- +#define TITAN_GE_AFX_EXACT_MATCH_VID 0x110C /* AFX Exact Match VID */
- +#define TITAN_GE_AFX_MULTICAST_HASH_LOW 0x1110 /* AFX Multicast HASH Low */
- +#define TITAN_GE_AFX_MULTICAST_HASH_MIDLOW 0x1114 /* AFX Multicast HASH MidLow */
- +#define TITAN_GE_AFX_MULTICAST_HASH_MIDHI 0x1118 /* AFX Multicast HASH MidHi */
- +#define TITAN_GE_AFX_MULTICAST_HASH_HI 0x111C /* AFX Multicast HASH Hi */
- +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 0x1120 /* AFX Address Filter Ctrl 0 */
- +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 0x1124 /* AFX Address Filter Ctrl 1 */
- +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 0x1128 /* AFX Address Filter Ctrl 2 */
- +
- +/* Traffic Groomer block */
- +#define TITAN_GE_TRTG_CONFIG 0x1000 /* TRTG Config */
- +
- +#endif /* _TITAN_GE_H_ */
- +
- diff -Nur linux-2.6.34.orig/drivers/net/titan_mdio.c linux-loongson/drivers/net/titan_mdio.c
- --- linux-2.6.34.orig/drivers/net/titan_mdio.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/titan_mdio.c 2010-05-27 18:12:39.084716399 +0200
- @@ -0,0 +1,217 @@
- +/*
- + * drivers/net/titan_mdio.c - Driver for Titan ethernet ports
- + *
- + * Copyright (C) 2003 PMC-Sierra Inc.
- + * Author : Manish Lachwani (lachwani@pmc-sierra.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- + *
- + * Management Data IO (MDIO) driver for the Titan GMII. Interacts with the Marvel PHY
- + * on the Titan. No support for the TBI as yet.
- + *
- + */
- +
- +#include "titan_mdio.h"
- +
- +#define MDIO_DEBUG
- +
- +/*
- + * Local constants
- + */
- +#define MAX_CLKA 1023
- +#define MAX_PHY_DEV 31
- +#define MAX_PHY_REG 31
- +#define WRITEADDRS_OPCODE 0x0
- +#define READ_OPCODE 0x2
- +#define WRITE_OPCODE 0x1
- +#define MAX_MDIO_POLL 100
- +
- +/*
- + * Titan MDIO and SCMB registers
- + */
- +#define TITAN_GE_SCMB_CONTROL 0x01c0 /* SCMB Control */
- +#define TITAN_GE_SCMB_CLKA 0x01c4 /* SCMB Clock A */
- +#define TITAN_GE_MDIO_COMMAND 0x01d0 /* MDIO Command */
- +#define TITAN_GE_MDIO_DEVICE_PORT_ADDRESS 0x01d4 /* MDIO Device and Port addrs */
- +#define TITAN_GE_MDIO_DATA 0x01d8 /* MDIO Data */
- +#define TITAN_GE_MDIO_INTERRUPTS 0x01dC /* MDIO Interrupts */
- +
- +/*
- + * Function to poll the MDIO
- + */
- +static int titan_ge_mdio_poll(void)
- +{
- + int i, val;
- +
- + for (i = 0; i < MAX_MDIO_POLL; i++) {
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
- +
- + if (!(val & 0x8000))
- + return TITAN_GE_MDIO_GOOD;
- + }
- +
- + return TITAN_GE_MDIO_ERROR;
- +}
- +
- +
- +/*
- + * Initialize and configure the MDIO
- + */
- +int titan_ge_mdio_setup(titan_ge_mdio_config *titan_mdio)
- +{
- + unsigned long val;
- +
- + /* Reset the SCMB and program into MDIO mode*/
- + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x9000);
- + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x1000);
- +
- + /* CLK A */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_SCMB_CLKA);
- + val = ( (val & ~(0x03ff)) | (titan_mdio->clka & 0x03ff));
- + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CLKA, val);
- +
- + /* Preamble Suppresion */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
- + val = ( (val & ~(0x0001)) | (titan_mdio->mdio_spre & 0x0001));
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
- +
- + /* MDIO mode */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
- + val = ( (val & ~(0x4000)) | (titan_mdio->mdio_mode & 0x4000));
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
- +
- + return TITAN_GE_MDIO_GOOD;
- +}
- +
- +/*
- + * Set the PHY address in indirect mode
- + */
- +int titan_ge_mdio_inaddrs(int dev_addr, int reg_addr)
- +{
- + volatile unsigned long val;
- +
- + /* Setup the PHY device */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
- + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
- + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
- +
- + /* Write the new address */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
- + val = ( (val & ~(0x0300)) | ( (WRITEADDRS_OPCODE << 8) & 0x0300));
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
- +
- + return TITAN_GE_MDIO_GOOD;
- +}
- +
- +/*
- + * Read the MDIO register. This is what the individual parametes mean:
- + *
- + * dev_addr : PHY ID
- + * reg_addr : register offset
- + *
- + * See the spec for the Titan MAC. We operate in the Direct Mode.
- + */
- +
- +#define MAX_RETRIES 2
- +
- +int titan_ge_mdio_read(int dev_addr, int reg_addr, unsigned int *pdata)
- +{
- + volatile unsigned long val;
- + int retries = 0;
- +
- + /* Setup the PHY device */
- +
- +again:
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
- + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
- + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
- + val |= 0x4000;
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
- +
- + udelay(30);
- +
- + /* Issue the read command */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
- + val = ( (val & ~(0x0300)) | ( (READ_OPCODE << 8) & 0x0300));
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
- +
- + udelay(30);
- +
- + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
- + return TITAN_GE_MDIO_ERROR;
- +
- + *pdata = (unsigned int)TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DATA);
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
- +
- + udelay(30);
- +
- + if (val & 0x2) {
- + if (retries == MAX_RETRIES)
- + return TITAN_GE_MDIO_ERROR;
- + else {
- + retries++;
- + goto again;
- + }
- + }
- +
- + return TITAN_GE_MDIO_GOOD;
- +}
- +
- +/*
- + * Write to the MDIO register
- + *
- + * dev_addr : PHY ID
- + * reg_addr : register that needs to be written to
- + *
- + */
- +int titan_ge_mdio_write(int dev_addr, int reg_addr, unsigned int data)
- +{
- + volatile unsigned long val;
- +
- + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
- + return TITAN_GE_MDIO_ERROR;
- +
- + /* Setup the PHY device */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
- + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
- + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
- + val |= 0x4000;
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
- +
- + udelay(30);
- +
- + /* Setup the data to write */
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DATA, data);
- +
- + udelay(30);
- +
- + /* Issue the write command */
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
- + val = ( (val & ~(0x0300)) | ( (WRITE_OPCODE << 8) & 0x0300));
- + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
- +
- + udelay(30);
- +
- + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
- + return TITAN_GE_MDIO_ERROR;
- +
- + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
- + if (val & 0x2)
- + return TITAN_GE_MDIO_ERROR;
- +
- + return TITAN_GE_MDIO_GOOD;
- +}
- +
- diff -Nur linux-2.6.34.orig/drivers/net/titan_mdio.h linux-loongson/drivers/net/titan_mdio.h
- --- linux-2.6.34.orig/drivers/net/titan_mdio.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/titan_mdio.h 2010-05-27 18:12:39.084716399 +0200
- @@ -0,0 +1,56 @@
- +/*
- + * MDIO used to interact with the PHY when using GMII/MII
- + */
- +#ifndef _TITAN_MDIO_H
- +#define _TITAN_MDIO_H
- +
- +#include <linux/netdevice.h>
- +#include <linux/workqueue.h>
- +#include <linux/delay.h>
- +#include "titan_ge.h"
- +
- +
- +#define TITAN_GE_MDIO_ERROR (-9000)
- +#define TITAN_GE_MDIO_GOOD 0
- +
- +#define TITAN_GE_MDIO_BASE titan_ge_base
- +
- +#define TITAN_GE_MDIO_READ(offset) \
- + *(volatile u32 *)(titan_ge_base + (offset))
- +
- +#define TITAN_GE_MDIO_WRITE(offset, data) \
- + *(volatile u32 *)(titan_ge_base + (offset)) = (data)
- +
- +
- +/* GMII specific registers */
- +#define TITAN_GE_MARVEL_PHY_ID 0x00
- +#define TITAN_PHY_AUTONEG_ADV 0x04
- +#define TITAN_PHY_LP_ABILITY 0x05
- +#define TITAN_GE_MDIO_MII_CTRL 0x09
- +#define TITAN_GE_MDIO_MII_EXTENDED 0x0f
- +#define TITAN_GE_MDIO_PHY_CTRL 0x10
- +#define TITAN_GE_MDIO_PHY_STATUS 0x11
- +#define TITAN_GE_MDIO_PHY_IE 0x12
- +#define TITAN_GE_MDIO_PHY_IS 0x13
- +#define TITAN_GE_MDIO_PHY_LED 0x18
- +#define TITAN_GE_MDIO_PHY_LED_OVER 0x19
- +#define PHY_ANEG_TIME_WAIT 45 /* 45 seconds wait time */
- +
- +/*
- + * MDIO Config Structure
- + */
- +typedef struct {
- + unsigned int clka;
- + int mdio_spre;
- + int mdio_mode;
- +} titan_ge_mdio_config;
- +
- +/*
- + * Function Prototypes
- + */
- +int titan_ge_mdio_setup(titan_ge_mdio_config *);
- +int titan_ge_mdio_inaddrs(int, int);
- +int titan_ge_mdio_read(int, int, unsigned int *);
- +int titan_ge_mdio_write(int, int, unsigned int);
- +
- +#endif /* _TITAN_MDIO_H */
- diff -Nur linux-2.6.34.orig/drivers/net/wireless/Kconfig linux-loongson/drivers/net/wireless/Kconfig
- --- linux-2.6.34.orig/drivers/net/wireless/Kconfig 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/net/wireless/Kconfig 2010-05-27 18:15:37.400979385 +0200
- @@ -268,7 +268,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.
- @@ -295,6 +295,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.34.orig/drivers/net/wireless/Makefile linux-loongson/drivers/net/wireless/Makefile
- --- linux-2.6.34.orig/drivers/net/wireless/Makefile 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/net/wireless/Makefile 2010-05-27 18:12:39.124712905 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/dot11d.h linux-loongson/drivers/net/wireless/rtl8187b/dot11d.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/dot11d.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/dot11d.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/arc4.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/arc4.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/internal.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/internal.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/internal.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/internal.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/readme linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/readme
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/readme 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/readme 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/Makefile linux-loongson/drivers/net/wireless/rtl8187b/Makefile
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/Makefile 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/msh_class.h linux-loongson/drivers/net/wireless/rtl8187b/msh_class.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/msh_class.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/msh_class.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_hw.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_hw.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_hw.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_hw.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8187_core.c linux-loongson/drivers/net/wireless/rtl8187b/r8187_core.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_core.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_core.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8187.h linux-loongson/drivers/net/wireless/rtl8187b/r8187.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8187_led.c linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_led.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8187_led.h linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.h
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_led.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.h 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/r8187_rfkill.c linux-loongson/drivers/net/wireless/rtl8187b/r8187_rfkill.c
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_rfkill.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_rfkill.c 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/net/wireless/rtl8187b/readme linux-loongson/drivers/net/wireless/rtl8187b/readme
- --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/readme 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/net/wireless/rtl8187b/readme 2010-05-27 18:12:39.532222207 +0200
- @@ -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.34.orig/drivers/platform/Kconfig linux-loongson/drivers/platform/Kconfig
- --- linux-2.6.34.orig/drivers/platform/Kconfig 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/platform/Kconfig 2010-05-27 18:12:39.983464277 +0200
- @@ -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.34.orig/drivers/platform/Makefile linux-loongson/drivers/platform/Makefile
- --- linux-2.6.34.orig/drivers/platform/Makefile 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/platform/Makefile 2010-05-27 18:12:39.983464277 +0200
- @@ -3,3 +3,4 @@
- #
-
- obj-$(CONFIG_X86) += x86/
- +obj-$(CONFIG_MIPS) += mips/
- diff -Nur linux-2.6.34.orig/drivers/platform/mips/Kconfig linux-loongson/drivers/platform/mips/Kconfig
- --- linux-2.6.34.orig/drivers/platform/mips/Kconfig 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/platform/mips/Kconfig 2010-05-27 18:12:39.983464277 +0200
- @@ -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.34.orig/drivers/platform/mips/lynloong_pc.c linux-loongson/drivers/platform/mips/lynloong_pc.c
- --- linux-2.6.34.orig/drivers/platform/mips/lynloong_pc.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/platform/mips/lynloong_pc.c 2010-05-27 18:12:39.993464274 +0200
- @@ -0,0 +1,513 @@
- +/*
- + * 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;
- + struct backlight_properties props;
- +
- + /* 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);
- +
- + memset(&props, 0, sizeof(struct backlight_properties));
- + props.max_brightness = MAX_BRIGHTNESS;
- + lynloong_backlight_dev = backlight_device_register("backlight0", NULL,
- + NULL, &backlight_ops, &props);
- +
- + if (IS_ERR(lynloong_backlight_dev)) {
- + ret = PTR_ERR(lynloong_backlight_dev);
- + return ret;
- + }
- +
- + 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.34.orig/drivers/platform/mips/Makefile linux-loongson/drivers/platform/mips/Makefile
- --- linux-2.6.34.orig/drivers/platform/mips/Makefile 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/platform/mips/Makefile 2010-05-27 18:12:39.993464274 +0200
- @@ -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.34.orig/drivers/platform/mips/yeeloong_ecrom.c linux-loongson/drivers/platform/mips/yeeloong_ecrom.c
- --- linux-2.6.34.orig/drivers/platform/mips/yeeloong_ecrom.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/platform/mips/yeeloong_ecrom.c 2010-05-27 18:12:39.993464274 +0200
- @@ -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.34.orig/drivers/platform/mips/yeeloong_laptop.c linux-loongson/drivers/platform/mips/yeeloong_laptop.c
- --- linux-2.6.34.orig/drivers/platform/mips/yeeloong_laptop.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-loongson/drivers/platform/mips/yeeloong_laptop.c 2010-05-27 18:12:39.993464274 +0200
- @@ -0,0 +1,1200 @@
- +/*
- + * 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_version_before(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';
- + }
- +
- + return (strncasecmp(ec_ver, version, 64) < 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;
- + struct backlight_properties props;
- +
- + memset(&props, 0, sizeof(struct backlight_properties));
- + props.max_brightness = MAX_BRIGHTNESS;
- + yeeloong_backlight_dev = backlight_device_register("backlight0", NULL,
- + NULL, &backlight_ops, &props);
- +
- + if (IS_ERR(yeeloong_backlight_dev)) {
- + ret = PTR_ERR(yeeloong_backlight_dev);
- + yeeloong_backlight_dev = NULL;
- + return ret;
- + }
- +
- + 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 : 0;
- + 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;
- + case POWER_SUPPLY_PROP_CHARGE_NOW: /* 1/100(%)*1000 繕Ah */
- + val->intval = curr_cap * get_bat_info(FULLCHG_CAP) * 10;
- + 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_VOL) * 1000; /* mV -> 繕V */
- + break;
- + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- + val->intval = get_bat_info(DESIGN_CAP) * 1000; /* mAh->繕Ah */
- + break;
- + case POWER_SUPPLY_PROP_CHARGE_FULL:
- + val->intval = get_bat_info(FULLCHG_CAP) * 1000; /* 繕Ah */
- + 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_CHARGE_FULL,
- + POWER_SUPPLY_PROP_CHARGE_NOW,
- + 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)
- +{
- + 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_DISPLAYTOGGLE, { KEY_DISPLAYTOGGLE } }, /* Fn + F2 */
- + {KE_KEY, EVENT_SWITCHVIDEOMODE, { 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 displaytoggle_handler(int status)
- +{
- + /* EC(>=PQ1D26) does this job for us, we can not do it again,
- + * otherwise, the brightness will not resume to the normal level! */
- + if (ec_version_before("EC_VER=PQ1D26"))
- + yeeloong_lcd_vo_set(status);
- +
- + return status;
- +}
- +
- +static int switchvideomode_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_SWITCHVIDEOMODE:
- + handler = switchvideomode_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_DISPLAYTOGGLE:
- + reg = REG_DISPLAY_LCD;
- + handler = displaytoggle_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)
- +
- +{
- + if (ec_version_before("EC_VER=PQ1D27"))
- + 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)
- +{
- + if (ec_version_before("EC_VER=PQ1D27"))
- + 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.34.orig/drivers/rtc/rtc-cmos.c linux-loongson/drivers/rtc/rtc-cmos.c
- --- linux-2.6.34.orig/drivers/rtc/rtc-cmos.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/rtc/rtc-cmos.c 2010-05-27 18:15:37.623465175 +0200
- @@ -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.34.orig/drivers/staging/sm7xx/smtcfb.c linux-loongson/drivers/staging/sm7xx/smtcfb.c
- --- linux-2.6.34.orig/drivers/staging/sm7xx/smtcfb.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/staging/sm7xx/smtcfb.c 2010-05-27 18:15:38.733462789 +0200
- @@ -12,6 +12,8 @@
- * 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
- @@ -107,6 +109,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},
- diff -Nur linux-2.6.34.orig/drivers/usb/host/ohci-hcd.c linux-loongson/drivers/usb/host/ohci-hcd.c
- --- linux-2.6.34.orig/drivers/usb/host/ohci-hcd.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/usb/host/ohci-hcd.c 2010-05-27 18:15:39.022214534 +0200
- @@ -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)) {
- diff -Nur linux-2.6.34.orig/drivers/video/tdfxfb.c linux-loongson/drivers/video/tdfxfb.c
- --- linux-2.6.34.orig/drivers/video/tdfxfb.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/drivers/video/tdfxfb.c 2010-05-27 18:12:44.063464481 +0200
- @@ -1571,8 +1571,8 @@
- if (default_par->mtrr_handle >= 0)
- mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
- info->fix.smem_len);
- - release_mem_region(pci_resource_start(pdev, 2),
- - pci_resource_len(pdev, 2));
- + release_region(pci_resource_start(pdev, 2),
- + pci_resource_len(pdev, 2));
- out_err_screenbase:
- if (info->screen_base)
- iounmap(info->screen_base);
- diff -Nur linux-2.6.34.orig/net/rfkill/core.c linux-loongson/net/rfkill/core.c
- --- linux-2.6.34.orig/net/rfkill/core.c 2010-05-16 23:17:36.000000000 +0200
- +++ linux-loongson/net/rfkill/core.c 2010-05-27 18:15:42.770974885 +0200
- @@ -112,7 +112,7 @@
- static DEFINE_MUTEX(rfkill_global_mutex);
- static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */
-
- -static unsigned int rfkill_default_state = 1;
- +static unsigned int rfkill_default_state; /* default: 0 = radio off */
- module_param_named(default_state, rfkill_default_state, uint, 0444);
- MODULE_PARM_DESC(default_state,
- "Default initial state for all radio types, 0 = radio off");
|