lemote.patch 1.2 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222
  1. diff -Nur linux-2.6.34.orig/arch/mips/boot/compressed/ld.script linux-loongson/arch/mips/boot/compressed/ld.script
  2. --- linux-2.6.34.orig/arch/mips/boot/compressed/ld.script 2010-05-16 23:17:36.000000000 +0200
  3. +++ linux-loongson/arch/mips/boot/compressed/ld.script 2010-05-27 18:12:28.592215840 +0200
  4. @@ -2,7 +2,7 @@
  5. * ld.script for compressed kernel support of MIPS
  6. *
  7. * Copyright (C) 2009 Lemote Inc.
  8. - * Author: Wu Zhangjin <wuzj@lemote.com>
  9. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  10. */
  11. OUTPUT_ARCH(mips)
  12. diff -Nur linux-2.6.34.orig/arch/mips/configs/fuloong2e_defconfig linux-loongson/arch/mips/configs/fuloong2e_defconfig
  13. --- linux-2.6.34.orig/arch/mips/configs/fuloong2e_defconfig 2010-05-16 23:17:36.000000000 +0200
  14. +++ linux-loongson/arch/mips/configs/fuloong2e_defconfig 2010-05-27 18:12:28.602215969 +0200
  15. @@ -1,7 +1,7 @@
  16. #
  17. # Automatically generated make config: don't edit
  18. -# Linux kernel version: 2.6.32-rc4
  19. -# Fri Oct 16 13:18:01 2009
  20. +# Linux kernel version: 2.6.34-rc5
  21. +# Wed Apr 28 01:14:53 2010
  22. #
  23. CONFIG_MIPS=y
  24. @@ -27,6 +27,7 @@
  25. # CONFIG_PNX8550_STB810 is not set
  26. # CONFIG_PMC_MSP is not set
  27. # CONFIG_PMC_YOSEMITE is not set
  28. +# CONFIG_POWERTV is not set
  29. # CONFIG_SGI_IP22 is not set
  30. # CONFIG_SGI_IP27 is not set
  31. # CONFIG_SGI_IP28 is not set
  32. @@ -49,6 +50,8 @@
  33. # CONFIG_ALCHEMY_GPIO_INDIRECT is not set
  34. CONFIG_ARCH_SPARSEMEM_ENABLE=y
  35. CONFIG_LEMOTE_FULOONG2E=y
  36. +# CONFIG_LEMOTE_MACH2F is not set
  37. +CONFIG_LOONGSON_UART_BASE=y
  38. CONFIG_RWSEM_GENERIC_SPINLOCK=y
  39. # CONFIG_ARCH_HAS_ILOG2_U32 is not set
  40. # CONFIG_ARCH_HAS_ILOG2_U64 is not set
  41. @@ -66,8 +69,7 @@
  42. CONFIG_CSRC_R4K_LIB=y
  43. CONFIG_CSRC_R4K=y
  44. CONFIG_DMA_NONCOHERENT=y
  45. -CONFIG_DMA_NEED_PCI_MAP_STATE=y
  46. -CONFIG_EARLY_PRINTK=y
  47. +CONFIG_NEED_DMA_MAP_STATE=y
  48. CONFIG_SYS_HAS_EARLY_PRINTK=y
  49. CONFIG_I8259=y
  50. # CONFIG_NO_IOPORT is not set
  51. @@ -84,6 +86,7 @@
  52. # CPU selection
  53. #
  54. CONFIG_CPU_LOONGSON2E=y
  55. +# CONFIG_CPU_LOONGSON2F is not set
  56. # CONFIG_CPU_MIPS32_R1 is not set
  57. # CONFIG_CPU_MIPS32_R2 is not set
  58. # CONFIG_CPU_MIPS64_R1 is not set
  59. @@ -106,7 +109,6 @@
  60. # CONFIG_CPU_SB1 is not set
  61. # CONFIG_CPU_CAVIUM_OCTEON is not set
  62. CONFIG_SYS_SUPPORTS_ZBOOT=y
  63. -CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
  64. CONFIG_CPU_LOONGSON2=y
  65. CONFIG_SYS_HAS_CPU_LOONGSON2E=y
  66. CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
  67. @@ -128,13 +130,13 @@
  68. CONFIG_MIPS_MT_DISABLED=y
  69. # CONFIG_MIPS_MT_SMP is not set
  70. # CONFIG_MIPS_MT_SMTC is not set
  71. +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
  72. CONFIG_CPU_HAS_WB=y
  73. CONFIG_CPU_HAS_SYNC=y
  74. CONFIG_GENERIC_HARDIRQS=y
  75. CONFIG_GENERIC_IRQ_PROBE=y
  76. CONFIG_CPU_SUPPORTS_HIGHMEM=y
  77. CONFIG_SYS_SUPPORTS_HIGHMEM=y
  78. -CONFIG_ARCH_FLATMEM_ENABLE=y
  79. CONFIG_ARCH_POPULATES_NODE_MAP=y
  80. CONFIG_SELECT_MEMORY_MODEL=y
  81. # CONFIG_FLATMEM_MANUAL is not set
  82. @@ -143,23 +145,18 @@
  83. CONFIG_SPARSEMEM=y
  84. CONFIG_HAVE_MEMORY_PRESENT=y
  85. CONFIG_SPARSEMEM_STATIC=y
  86. -
  87. -#
  88. -# Memory hotplug is currently incompatible with Software Suspend
  89. -#
  90. CONFIG_PAGEFLAGS_EXTENDED=y
  91. CONFIG_SPLIT_PTLOCK_CPUS=4
  92. CONFIG_PHYS_ADDR_T_64BIT=y
  93. CONFIG_ZONE_DMA_FLAG=0
  94. CONFIG_VIRT_TO_BUS=y
  95. -CONFIG_HAVE_MLOCK=y
  96. -CONFIG_HAVE_MLOCKED_PAGE_BIT=y
  97. # CONFIG_KSM is not set
  98. CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  99. CONFIG_TICK_ONESHOT=y
  100. CONFIG_NO_HZ=y
  101. CONFIG_HIGH_RES_TIMERS=y
  102. CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
  103. +CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK=y
  104. # CONFIG_HZ_48 is not set
  105. # CONFIG_HZ_100 is not set
  106. # CONFIG_HZ_128 is not set
  107. @@ -190,9 +187,11 @@
  108. CONFIG_HAVE_KERNEL_GZIP=y
  109. CONFIG_HAVE_KERNEL_BZIP2=y
  110. CONFIG_HAVE_KERNEL_LZMA=y
  111. +CONFIG_HAVE_KERNEL_LZO=y
  112. CONFIG_KERNEL_GZIP=y
  113. # CONFIG_KERNEL_BZIP2 is not set
  114. # CONFIG_KERNEL_LZMA is not set
  115. +# CONFIG_KERNEL_LZO is not set
  116. CONFIG_SWAP=y
  117. CONFIG_SYSVIPC=y
  118. CONFIG_SYSVIPC_SYSCTL=y
  119. @@ -208,6 +207,7 @@
  120. #
  121. CONFIG_TREE_RCU=y
  122. # CONFIG_TREE_PREEMPT_RCU is not set
  123. +# CONFIG_TINY_RCU is not set
  124. # CONFIG_RCU_TRACE is not set
  125. CONFIG_RCU_FANOUT=64
  126. # CONFIG_RCU_FANOUT_EXACT is not set
  127. @@ -215,10 +215,8 @@
  128. CONFIG_IKCONFIG=y
  129. CONFIG_IKCONFIG_PROC=y
  130. CONFIG_LOG_BUF_SHIFT=14
  131. -# CONFIG_GROUP_SCHED is not set
  132. # CONFIG_CGROUPS is not set
  133. -CONFIG_SYSFS_DEPRECATED=y
  134. -CONFIG_SYSFS_DEPRECATED_V2=y
  135. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  136. # CONFIG_RELAY is not set
  137. CONFIG_NAMESPACES=y
  138. # CONFIG_UTS_NS is not set
  139. @@ -258,7 +256,6 @@
  140. # CONFIG_SLUB is not set
  141. # CONFIG_SLOB is not set
  142. CONFIG_PROFILING=y
  143. -CONFIG_TRACEPOINTS=y
  144. CONFIG_OPROFILE=m
  145. CONFIG_HAVE_OPROFILE=y
  146. CONFIG_HAVE_SYSCALL_WRAPPERS=y
  147. @@ -266,7 +263,6 @@
  148. #
  149. # GCOV-based kernel profiling
  150. #
  151. -# CONFIG_GCOV_KERNEL is not set
  152. CONFIG_SLOW_WORK=y
  153. CONFIG_HAVE_GENERIC_DMA_COHERENT=y
  154. CONFIG_SLABINFO=y
  155. @@ -287,14 +283,41 @@
  156. # IO Schedulers
  157. #
  158. CONFIG_IOSCHED_NOOP=y
  159. -CONFIG_IOSCHED_AS=y
  160. CONFIG_IOSCHED_DEADLINE=y
  161. CONFIG_IOSCHED_CFQ=y
  162. -# CONFIG_DEFAULT_AS is not set
  163. # CONFIG_DEFAULT_DEADLINE is not set
  164. CONFIG_DEFAULT_CFQ=y
  165. # CONFIG_DEFAULT_NOOP is not set
  166. CONFIG_DEFAULT_IOSCHED="cfq"
  167. +# CONFIG_INLINE_SPIN_TRYLOCK is not set
  168. +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
  169. +# CONFIG_INLINE_SPIN_LOCK is not set
  170. +# CONFIG_INLINE_SPIN_LOCK_BH is not set
  171. +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
  172. +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
  173. +CONFIG_INLINE_SPIN_UNLOCK=y
  174. +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
  175. +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
  176. +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
  177. +# CONFIG_INLINE_READ_TRYLOCK is not set
  178. +# CONFIG_INLINE_READ_LOCK is not set
  179. +# CONFIG_INLINE_READ_LOCK_BH is not set
  180. +# CONFIG_INLINE_READ_LOCK_IRQ is not set
  181. +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
  182. +CONFIG_INLINE_READ_UNLOCK=y
  183. +# CONFIG_INLINE_READ_UNLOCK_BH is not set
  184. +CONFIG_INLINE_READ_UNLOCK_IRQ=y
  185. +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
  186. +# CONFIG_INLINE_WRITE_TRYLOCK is not set
  187. +# CONFIG_INLINE_WRITE_LOCK is not set
  188. +# CONFIG_INLINE_WRITE_LOCK_BH is not set
  189. +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
  190. +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
  191. +CONFIG_INLINE_WRITE_UNLOCK=y
  192. +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
  193. +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
  194. +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
  195. +# CONFIG_MUTEX_SPIN_ON_OWNER is not set
  196. CONFIG_FREEZER=y
  197. #
  198. @@ -304,7 +327,6 @@
  199. CONFIG_PCI=y
  200. CONFIG_PCI_DOMAINS=y
  201. # CONFIG_ARCH_SUPPORTS_MSI is not set
  202. -CONFIG_PCI_LEGACY=y
  203. # CONFIG_PCI_STUB is not set
  204. # CONFIG_PCI_IOV is not set
  205. CONFIG_ISA=y
  206. @@ -339,14 +361,13 @@
  207. CONFIG_HIBERNATION=y
  208. CONFIG_PM_STD_PARTITION="/dev/hda3"
  209. # CONFIG_PM_RUNTIME is not set
  210. +CONFIG_PM_OPS=y
  211. CONFIG_NET=y
  212. -CONFIG_COMPAT_NETLINK_MESSAGES=y
  213. #
  214. # Networking options
  215. #
  216. CONFIG_PACKET=y
  217. -CONFIG_PACKET_MMAP=y
  218. CONFIG_UNIX=y
  219. CONFIG_XFRM=y
  220. # CONFIG_XFRM_USER is not set
  221. @@ -483,7 +504,6 @@
  222. # Network testing
  223. #
  224. # CONFIG_NET_PKTGEN is not set
  225. -# CONFIG_NET_DROP_MONITOR is not set
  226. # CONFIG_HAMRADIO is not set
  227. # CONFIG_CAN is not set
  228. # CONFIG_IRDA is not set
  229. @@ -491,10 +511,6 @@
  230. # CONFIG_AF_RXRPC is not set
  231. CONFIG_WIRELESS=y
  232. # CONFIG_CFG80211 is not set
  233. -CONFIG_CFG80211_DEFAULT_PS_VALUE=0
  234. -CONFIG_WIRELESS_OLD_REGULATORY=y
  235. -CONFIG_WIRELESS_EXT=y
  236. -CONFIG_WIRELESS_EXT_SYSFS=y
  237. # CONFIG_LIB80211 is not set
  238. #
  239. @@ -617,6 +633,10 @@
  240. # CONFIG_BLK_DEV_COW_COMMON is not set
  241. CONFIG_BLK_DEV_LOOP=y
  242. CONFIG_BLK_DEV_CRYPTOLOOP=m
  243. +
  244. +#
  245. +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
  246. +#
  247. # CONFIG_BLK_DEV_NBD is not set
  248. # CONFIG_BLK_DEV_SX8 is not set
  249. # CONFIG_BLK_DEV_UB is not set
  250. @@ -707,6 +727,7 @@
  251. #
  252. # SCSI device support
  253. #
  254. +CONFIG_SCSI_MOD=y
  255. # CONFIG_RAID_ATTRS is not set
  256. CONFIG_SCSI=y
  257. CONFIG_SCSI_DMA=y
  258. @@ -755,7 +776,7 @@
  259. #
  260. #
  261. -# See the help texts for more information.
  262. +# The newer stack is recommended.
  263. #
  264. # CONFIG_FIREWIRE is not set
  265. # CONFIG_IEEE1394 is not set
  266. @@ -764,6 +785,7 @@
  267. # CONFIG_DUMMY is not set
  268. # CONFIG_BONDING is not set
  269. CONFIG_MACVLAN=m
  270. +# CONFIG_MACVTAP is not set
  271. # CONFIG_EQUALIZER is not set
  272. # CONFIG_TUN is not set
  273. CONFIG_VETH=m
  274. @@ -798,6 +820,7 @@
  275. # CONFIG_SMC91X is not set
  276. # CONFIG_DM9000 is not set
  277. # CONFIG_ETHOC is not set
  278. +# CONFIG_SMSC911X is not set
  279. # CONFIG_NET_VENDOR_RACAL is not set
  280. # CONFIG_DNET is not set
  281. # CONFIG_NET_TULIP is not set
  282. @@ -817,6 +840,7 @@
  283. # CONFIG_AMD8111_ETH is not set
  284. # CONFIG_ADAPTEC_STARFIRE is not set
  285. # CONFIG_AC3200 is not set
  286. +# CONFIG_KSZ884X_PCI is not set
  287. # CONFIG_APRICOT is not set
  288. # CONFIG_B44 is not set
  289. # CONFIG_FORCEDETH is not set
  290. @@ -871,6 +895,8 @@
  291. # CONFIG_CHELSIO_T1 is not set
  292. CONFIG_CHELSIO_T3_DEPENDS=y
  293. # CONFIG_CHELSIO_T3 is not set
  294. +CONFIG_CHELSIO_T4_DEPENDS=y
  295. +# CONFIG_CHELSIO_T4 is not set
  296. # CONFIG_ENIC is not set
  297. # CONFIG_IXGBE is not set
  298. # CONFIG_IXGB is not set
  299. @@ -883,13 +909,16 @@
  300. # CONFIG_MLX4_CORE is not set
  301. # CONFIG_TEHUTI is not set
  302. # CONFIG_BNX2X is not set
  303. +# CONFIG_QLCNIC is not set
  304. # CONFIG_QLGE is not set
  305. # CONFIG_SFC is not set
  306. # CONFIG_BE2NET is not set
  307. # CONFIG_TR is not set
  308. CONFIG_WLAN=y
  309. -# CONFIG_WLAN_PRE80211 is not set
  310. -# CONFIG_WLAN_80211 is not set
  311. +# CONFIG_ATMEL is not set
  312. +# CONFIG_PRISM54 is not set
  313. +# CONFIG_USB_ZD1201 is not set
  314. +# CONFIG_HOSTAP is not set
  315. #
  316. # Enable WiMAX (Networking options) to see the WiMAX drivers
  317. @@ -904,6 +933,7 @@
  318. # CONFIG_USB_RTL8150 is not set
  319. # CONFIG_USB_USBNET is not set
  320. # CONFIG_USB_CDC_PHONET is not set
  321. +# CONFIG_USB_IPHETH is not set
  322. # CONFIG_WAN is not set
  323. # CONFIG_FDDI is not set
  324. # CONFIG_HIPPI is not set
  325. @@ -926,6 +956,7 @@
  326. # CONFIG_NETCONSOLE is not set
  327. # CONFIG_NETPOLL is not set
  328. # CONFIG_NET_POLL_CONTROLLER is not set
  329. +# CONFIG_VMXNET3 is not set
  330. # CONFIG_ISDN is not set
  331. # CONFIG_PHONE is not set
  332. @@ -935,6 +966,7 @@
  333. CONFIG_INPUT=y
  334. CONFIG_INPUT_FF_MEMLESS=y
  335. # CONFIG_INPUT_POLLDEV is not set
  336. +# CONFIG_INPUT_SPARSEKMAP is not set
  337. #
  338. # Userland interfaces
  339. @@ -992,6 +1024,7 @@
  340. # CONFIG_SERIO_PCIPS2 is not set
  341. CONFIG_SERIO_LIBPS2=y
  342. # CONFIG_SERIO_RAW is not set
  343. +# CONFIG_SERIO_ALTERA_PS2 is not set
  344. # CONFIG_GAMEPORT is not set
  345. #
  346. @@ -1022,6 +1055,7 @@
  347. CONFIG_SERIAL_CORE=y
  348. CONFIG_SERIAL_CORE_CONSOLE=y
  349. # CONFIG_SERIAL_JSM is not set
  350. +# CONFIG_SERIAL_TIMBERDALE is not set
  351. CONFIG_UNIX98_PTYS=y
  352. # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
  353. CONFIG_LEGACY_PTYS=y
  354. @@ -1069,6 +1103,7 @@
  355. #
  356. # CONFIG_I2C_OCORES is not set
  357. # CONFIG_I2C_SIMTEC is not set
  358. +# CONFIG_I2C_XILINX is not set
  359. #
  360. # External I2C/SMBus adapter drivers
  361. @@ -1078,27 +1113,15 @@
  362. # CONFIG_I2C_TINY_USB is not set
  363. #
  364. -# Graphics adapter I2C/DDC channel drivers
  365. -#
  366. -# CONFIG_I2C_VOODOO3 is not set
  367. -
  368. -#
  369. # Other I2C/SMBus bus drivers
  370. #
  371. # CONFIG_I2C_ELEKTOR is not set
  372. # CONFIG_I2C_PCA_ISA is not set
  373. # CONFIG_I2C_PCA_PLATFORM is not set
  374. # CONFIG_I2C_STUB is not set
  375. -
  376. -#
  377. -# Miscellaneous I2C Chip support
  378. -#
  379. -# CONFIG_DS1682 is not set
  380. -# CONFIG_SENSORS_TSL2550 is not set
  381. # CONFIG_I2C_DEBUG_CORE is not set
  382. # CONFIG_I2C_DEBUG_ALGO is not set
  383. # CONFIG_I2C_DEBUG_BUS is not set
  384. -# CONFIG_I2C_DEBUG_CHIP is not set
  385. # CONFIG_SPI is not set
  386. #
  387. @@ -1125,10 +1148,9 @@
  388. # CONFIG_HTC_PASIC3 is not set
  389. # CONFIG_MFD_TMIO is not set
  390. # CONFIG_MFD_WM8400 is not set
  391. -# CONFIG_MFD_WM831X is not set
  392. -# CONFIG_MFD_WM8350_I2C is not set
  393. +# CONFIG_MFD_WM8994 is not set
  394. # CONFIG_MFD_PCF50633 is not set
  395. -# CONFIG_AB3100_CORE is not set
  396. +# CONFIG_LPC_SCH is not set
  397. # CONFIG_REGULATOR is not set
  398. # CONFIG_MEDIA_SUPPORT is not set
  399. @@ -1136,6 +1158,7 @@
  400. # Graphics support
  401. #
  402. CONFIG_VGA_ARB=y
  403. +CONFIG_VGA_ARB_MAX_GPUS=16
  404. # CONFIG_DRM is not set
  405. # CONFIG_VGASTATE is not set
  406. CONFIG_VIDEO_OUTPUT_CONTROL=m
  407. @@ -1271,6 +1294,7 @@
  408. # CONFIG_SND_OXYGEN is not set
  409. # CONFIG_SND_CS4281 is not set
  410. # CONFIG_SND_CS46XX is not set
  411. +# CONFIG_SND_CS5535AUDIO is not set
  412. # CONFIG_SND_CTXFI is not set
  413. # CONFIG_SND_DARLA20 is not set
  414. # CONFIG_SND_GINA20 is not set
  415. @@ -1321,6 +1345,7 @@
  416. CONFIG_SND_MIPS=y
  417. CONFIG_SND_USB=y
  418. # CONFIG_SND_USB_AUDIO is not set
  419. +# CONFIG_SND_USB_UA101 is not set
  420. # CONFIG_SND_USB_CAIAQ is not set
  421. # CONFIG_SND_SOC is not set
  422. # CONFIG_SOUND_PRIME is not set
  423. @@ -1358,7 +1383,6 @@
  424. CONFIG_USB_DEVICEFS=y
  425. # CONFIG_USB_DEVICE_CLASS is not set
  426. # CONFIG_USB_DYNAMIC_MINORS is not set
  427. -# CONFIG_USB_SUSPEND is not set
  428. # CONFIG_USB_OTG is not set
  429. CONFIG_USB_OTG_WHITELIST=y
  430. # CONFIG_USB_OTG_BLACKLIST_HUB is not set
  431. @@ -1440,7 +1464,6 @@
  432. # CONFIG_USB_RIO500 is not set
  433. # CONFIG_USB_LEGOTOWER is not set
  434. # CONFIG_USB_LCD is not set
  435. -# CONFIG_USB_BERRY_CHARGE is not set
  436. # CONFIG_USB_LED is not set
  437. # CONFIG_USB_CYPRESS_CY7C63 is not set
  438. # CONFIG_USB_CYTHERM is not set
  439. @@ -1453,7 +1476,6 @@
  440. # CONFIG_USB_IOWARRIOR is not set
  441. # CONFIG_USB_TEST is not set
  442. CONFIG_USB_ISIGHTFW=m
  443. -CONFIG_USB_VST=m
  444. # CONFIG_USB_GADGET is not set
  445. #
  446. @@ -1473,15 +1495,16 @@
  447. CONFIG_UIO_CIF=m
  448. # CONFIG_UIO_PDRV is not set
  449. # CONFIG_UIO_PDRV_GENIRQ is not set
  450. -# CONFIG_UIO_SMX is not set
  451. # CONFIG_UIO_AEC is not set
  452. # CONFIG_UIO_SERCOS3 is not set
  453. # CONFIG_UIO_PCI_GENERIC is not set
  454. +# CONFIG_UIO_NETX is not set
  455. #
  456. # TI VLYNQ
  457. #
  458. # CONFIG_STAGING is not set
  459. +CONFIG_MIPS_PLATFORM_DEVICES=y
  460. #
  461. # File systems
  462. @@ -1499,9 +1522,7 @@
  463. # CONFIG_EXT4_DEBUG is not set
  464. CONFIG_FS_XIP=y
  465. CONFIG_JBD=y
  466. -# CONFIG_JBD_DEBUG is not set
  467. CONFIG_JBD2=m
  468. -# CONFIG_JBD2_DEBUG is not set
  469. CONFIG_FS_MBCACHE=m
  470. CONFIG_REISERFS_FS=m
  471. # CONFIG_REISERFS_CHECK is not set
  472. @@ -1522,8 +1543,8 @@
  473. # CONFIG_QUOTA is not set
  474. CONFIG_AUTOFS_FS=y
  475. CONFIG_AUTOFS4_FS=y
  476. -CONFIG_FUSE_FS=y
  477. -# CONFIG_CUSE is not set
  478. +CONFIG_FUSE_FS=m
  479. +CONFIG_CUSE=m
  480. #
  481. # Caches
  482. @@ -1572,6 +1593,7 @@
  483. # CONFIG_BFS_FS is not set
  484. # CONFIG_EFS_FS is not set
  485. # CONFIG_JFFS2_FS is not set
  486. +# CONFIG_LOGFS is not set
  487. # CONFIG_CRAMFS is not set
  488. # CONFIG_SQUASHFS is not set
  489. # CONFIG_VXFS_FS is not set
  490. @@ -1605,6 +1627,7 @@
  491. CONFIG_SMB_FS=m
  492. CONFIG_SMB_NLS_DEFAULT=y
  493. CONFIG_SMB_NLS_REMOTE="cp936"
  494. +# CONFIG_CEPH_FS is not set
  495. CONFIG_CIFS=m
  496. CONFIG_CIFS_STATS=y
  497. CONFIG_CIFS_STATS2=y
  498. @@ -1692,24 +1715,24 @@
  499. # CONFIG_MAGIC_SYSRQ is not set
  500. # CONFIG_STRIP_ASM_SYMS is not set
  501. # CONFIG_UNUSED_SYMBOLS is not set
  502. -CONFIG_DEBUG_FS=y
  503. +# CONFIG_DEBUG_FS is not set
  504. # CONFIG_HEADERS_CHECK is not set
  505. # CONFIG_DEBUG_KERNEL is not set
  506. -CONFIG_STACKTRACE=y
  507. # CONFIG_DEBUG_MEMORY_INIT is not set
  508. # CONFIG_RCU_CPU_STALL_DETECTOR is not set
  509. CONFIG_SYSCTL_SYSCALL_CHECK=y
  510. -CONFIG_NOP_TRACER=y
  511. +CONFIG_HAVE_FUNCTION_TRACER=y
  512. +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
  513. +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
  514. +CONFIG_HAVE_DYNAMIC_FTRACE=y
  515. +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
  516. CONFIG_RING_BUFFER=y
  517. -CONFIG_EVENT_TRACING=y
  518. -CONFIG_CONTEXT_SWITCH_TRACER=y
  519. CONFIG_RING_BUFFER_ALLOW_SWAP=y
  520. -CONFIG_TRACING=y
  521. CONFIG_TRACING_SUPPORT=y
  522. # CONFIG_FTRACE is not set
  523. -# CONFIG_DYNAMIC_DEBUG is not set
  524. # CONFIG_SAMPLES is not set
  525. CONFIG_HAVE_ARCH_KGDB=y
  526. +# CONFIG_EARLY_PRINTK is not set
  527. # CONFIG_CMDLINE_BOOL is not set
  528. #
  529. @@ -1718,7 +1741,11 @@
  530. # CONFIG_KEYS is not set
  531. # CONFIG_SECURITY is not set
  532. # CONFIG_SECURITYFS is not set
  533. -CONFIG_SECURITY_FILE_CAPABILITIES=y
  534. +# CONFIG_DEFAULT_SECURITY_SELINUX is not set
  535. +# CONFIG_DEFAULT_SECURITY_SMACK is not set
  536. +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
  537. +CONFIG_DEFAULT_SECURITY_DAC=y
  538. +CONFIG_DEFAULT_SECURITY=""
  539. CONFIG_CRYPTO=y
  540. #
  541. @@ -1819,7 +1846,7 @@
  542. #
  543. CONFIG_CRYPTO_ANSI_CPRNG=m
  544. # CONFIG_CRYPTO_HW is not set
  545. -CONFIG_BINARY_PRINTF=y
  546. +# CONFIG_BINARY_PRINTF is not set
  547. #
  548. # Library routines
  549. diff -Nur linux-2.6.34.orig/arch/mips/configs/lemote2f_defconfig linux-loongson/arch/mips/configs/lemote2f_defconfig
  550. --- linux-2.6.34.orig/arch/mips/configs/lemote2f_defconfig 2010-05-16 23:17:36.000000000 +0200
  551. +++ linux-loongson/arch/mips/configs/lemote2f_defconfig 2010-05-27 18:12:28.612213391 +0200
  552. @@ -1,7 +1,7 @@
  553. #
  554. # Automatically generated make config: don't edit
  555. -# Linux kernel version: 2.6.33-rc2
  556. -# Mon Jan 4 13:41:09 2010
  557. +# Linux kernel version: 2.6.34-rc3
  558. +# Sun Apr 11 04:31:19 2010
  559. #
  560. CONFIG_MIPS=y
  561. @@ -68,7 +68,7 @@
  562. CONFIG_SCHED_OMIT_FRAME_POINTER=y
  563. CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
  564. CONFIG_DMA_NONCOHERENT=y
  565. -CONFIG_DMA_NEED_PCI_MAP_STATE=y
  566. +CONFIG_NEED_DMA_MAP_STATE=y
  567. CONFIG_SYS_HAS_EARLY_PRINTK=y
  568. CONFIG_I8259=y
  569. # CONFIG_NO_IOPORT is not set
  570. @@ -132,6 +132,7 @@
  571. CONFIG_MIPS_MT_DISABLED=y
  572. # CONFIG_MIPS_MT_SMP is not set
  573. # CONFIG_MIPS_MT_SMTC is not set
  574. +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
  575. CONFIG_CPU_HAS_WB=y
  576. CONFIG_CPU_HAS_SYNC=y
  577. CONFIG_GENERIC_HARDIRQS=y
  578. @@ -188,9 +189,11 @@
  579. CONFIG_HAVE_KERNEL_GZIP=y
  580. CONFIG_HAVE_KERNEL_BZIP2=y
  581. CONFIG_HAVE_KERNEL_LZMA=y
  582. +CONFIG_HAVE_KERNEL_LZO=y
  583. CONFIG_KERNEL_GZIP=y
  584. # CONFIG_KERNEL_BZIP2 is not set
  585. # CONFIG_KERNEL_LZMA is not set
  586. +# CONFIG_KERNEL_LZO is not set
  587. CONFIG_SWAP=y
  588. CONFIG_SYSVIPC=y
  589. CONFIG_SYSVIPC_SYSCTL=y
  590. @@ -213,10 +216,8 @@
  591. CONFIG_IKCONFIG=y
  592. CONFIG_IKCONFIG_PROC=y
  593. CONFIG_LOG_BUF_SHIFT=15
  594. -# CONFIG_GROUP_SCHED is not set
  595. # CONFIG_CGROUPS is not set
  596. -CONFIG_SYSFS_DEPRECATED=y
  597. -CONFIG_SYSFS_DEPRECATED_V2=y
  598. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  599. # CONFIG_RELAY is not set
  600. # CONFIG_NAMESPACES is not set
  601. CONFIG_BLK_DEV_INITRD=y
  602. @@ -224,6 +225,7 @@
  603. CONFIG_RD_GZIP=y
  604. CONFIG_RD_BZIP2=y
  605. CONFIG_RD_LZMA=y
  606. +# CONFIG_RD_LZO is not set
  607. # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
  608. CONFIG_SYSCTL=y
  609. CONFIG_ANON_INODES=y
  610. @@ -250,13 +252,12 @@
  611. #
  612. CONFIG_VM_EVENT_COUNTERS=y
  613. CONFIG_PCI_QUIRKS=y
  614. -CONFIG_SLUB_DEBUG=y
  615. +# CONFIG_SLUB_DEBUG is not set
  616. CONFIG_COMPAT_BRK=y
  617. # CONFIG_SLAB is not set
  618. CONFIG_SLUB=y
  619. # CONFIG_SLOB is not set
  620. CONFIG_PROFILING=y
  621. -CONFIG_TRACEPOINTS=y
  622. CONFIG_OPROFILE=m
  623. CONFIG_HAVE_OPROFILE=y
  624. CONFIG_HAVE_SYSCALL_WRAPPERS=y
  625. @@ -264,11 +265,8 @@
  626. #
  627. # GCOV-based kernel profiling
  628. #
  629. -# CONFIG_GCOV_KERNEL is not set
  630. CONFIG_SLOW_WORK=y
  631. -# CONFIG_SLOW_WORK_DEBUG is not set
  632. CONFIG_HAVE_GENERIC_DMA_COHERENT=y
  633. -CONFIG_SLABINFO=y
  634. CONFIG_RT_MUTEXES=y
  635. CONFIG_BASE_SMALL=0
  636. CONFIG_MODULES=y
  637. @@ -330,7 +328,6 @@
  638. CONFIG_PCI=y
  639. CONFIG_PCI_DOMAINS=y
  640. # CONFIG_ARCH_SUPPORTS_MSI is not set
  641. -CONFIG_PCI_LEGACY=y
  642. # CONFIG_PCI_STUB is not set
  643. # CONFIG_PCI_IOV is not set
  644. CONFIG_ISA=y
  645. @@ -366,6 +363,7 @@
  646. CONFIG_HIBERNATION=y
  647. CONFIG_PM_STD_PARTITION="/dev/hda3"
  648. CONFIG_PM_RUNTIME=y
  649. +CONFIG_PM_OPS=y
  650. CONFIG_MIPS_EXTERNAL_TIMER=y
  651. CONFIG_MIPS_CPUFREQ=y
  652. @@ -393,12 +391,12 @@
  653. #
  654. CONFIG_LOONGSON2_CPUFREQ=m
  655. CONFIG_NET=y
  656. +CONFIG_COMPAT_NETLINK_MESSAGES=y
  657. #
  658. # Networking options
  659. #
  660. CONFIG_PACKET=y
  661. -CONFIG_PACKET_MMAP=y
  662. CONFIG_UNIX=y
  663. CONFIG_XFRM=y
  664. CONFIG_XFRM_USER=m
  665. @@ -515,6 +513,7 @@
  666. # CONFIG_ATM is not set
  667. CONFIG_STP=m
  668. CONFIG_BRIDGE=m
  669. +CONFIG_BRIDGE_IGMP_SNOOPING=y
  670. # CONFIG_NET_DSA is not set
  671. CONFIG_VLAN_8021Q=m
  672. # CONFIG_VLAN_8021Q_GVRP is not set
  673. @@ -584,7 +583,6 @@
  674. # Network testing
  675. #
  676. # CONFIG_NET_PKTGEN is not set
  677. -# CONFIG_NET_DROP_MONITOR is not set
  678. # CONFIG_HAMRADIO is not set
  679. # CONFIG_CAN is not set
  680. # CONFIG_IRDA is not set
  681. @@ -609,18 +607,20 @@
  682. CONFIG_BT_HCIBFUSB=m
  683. CONFIG_BT_HCIVHCI=m
  684. # CONFIG_BT_MRVL is not set
  685. +# CONFIG_BT_ATH3K is not set
  686. # CONFIG_AF_RXRPC is not set
  687. CONFIG_FIB_RULES=y
  688. CONFIG_WIRELESS=y
  689. +CONFIG_WIRELESS_EXT=y
  690. CONFIG_WEXT_CORE=y
  691. CONFIG_WEXT_PROC=y
  692. +CONFIG_WEXT_PRIV=y
  693. CONFIG_CFG80211=m
  694. # CONFIG_NL80211_TESTMODE is not set
  695. # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
  696. # CONFIG_CFG80211_REG_DEBUG is not set
  697. CONFIG_CFG80211_DEFAULT_PS=y
  698. -# CONFIG_CFG80211_DEBUGFS is not set
  699. -# CONFIG_WIRELESS_OLD_REGULATORY is not set
  700. +# CONFIG_CFG80211_INTERNAL_REGDB is not set
  701. CONFIG_CFG80211_WEXT=y
  702. CONFIG_WIRELESS_EXT_SYSFS=y
  703. CONFIG_LIB80211=m
  704. @@ -633,7 +633,6 @@
  705. CONFIG_MAC80211_RC_DEFAULT="minstrel"
  706. # CONFIG_MAC80211_MESH is not set
  707. CONFIG_MAC80211_LEDS=y
  708. -# CONFIG_MAC80211_DEBUGFS is not set
  709. # CONFIG_MAC80211_DEBUG_MENU is not set
  710. # CONFIG_WIMAX is not set
  711. CONFIG_RFKILL=m
  712. @@ -668,10 +667,6 @@
  713. # CONFIG_BLK_DEV_COW_COMMON is not set
  714. CONFIG_BLK_DEV_LOOP=y
  715. CONFIG_BLK_DEV_CRYPTOLOOP=m
  716. -
  717. -#
  718. -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
  719. -#
  720. # CONFIG_BLK_DEV_DRBD is not set
  721. # CONFIG_BLK_DEV_NBD is not set
  722. # CONFIG_BLK_DEV_SX8 is not set
  723. @@ -758,6 +753,7 @@
  724. #
  725. # SCSI device support
  726. #
  727. +CONFIG_SCSI_MOD=m
  728. # CONFIG_RAID_ATTRS is not set
  729. CONFIG_SCSI=m
  730. CONFIG_SCSI_DMA=y
  731. @@ -873,6 +869,7 @@
  732. # CONFIG_AMD8111_ETH is not set
  733. # CONFIG_ADAPTEC_STARFIRE is not set
  734. # CONFIG_AC3200 is not set
  735. +# CONFIG_KSZ884X_PCI is not set
  736. # CONFIG_APRICOT is not set
  737. # CONFIG_B44 is not set
  738. # CONFIG_FORCEDETH is not set
  739. @@ -883,7 +880,7 @@
  740. # CONFIG_NATSEMI is not set
  741. # CONFIG_NE2K_PCI is not set
  742. # CONFIG_8139CP is not set
  743. -CONFIG_8139TOO=y
  744. +CONFIG_8139TOO=m
  745. # CONFIG_8139TOO_PIO is not set
  746. # CONFIG_8139TOO_TUNE_TWISTER is not set
  747. # CONFIG_8139TOO_8129 is not set
  748. @@ -910,7 +907,7 @@
  749. # CONFIG_NS83820 is not set
  750. # CONFIG_HAMACHI is not set
  751. # CONFIG_YELLOWFIN is not set
  752. -CONFIG_R8169=y
  753. +CONFIG_R8169=m
  754. CONFIG_R8169_VLAN=y
  755. # CONFIG_SIS190 is not set
  756. # CONFIG_SKGE is not set
  757. @@ -934,7 +931,7 @@
  758. # CONFIG_USB_ZD1201 is not set
  759. # CONFIG_USB_NET_RNDIS_WLAN is not set
  760. # CONFIG_RTL8180 is not set
  761. -# CONFIG_RTL8187 is not set
  762. +CONFIG_RTL8187B=m
  763. # CONFIG_ADM8211 is not set
  764. # CONFIG_MAC80211_HWSIM is not set
  765. # CONFIG_MWL8K is not set
  766. @@ -969,6 +966,7 @@
  767. CONFIG_USB_NET_CDCETHER=m
  768. CONFIG_USB_NET_CDC_EEM=m
  769. # CONFIG_USB_NET_DM9601 is not set
  770. +# CONFIG_USB_NET_SMSC75XX is not set
  771. # CONFIG_USB_NET_SMSC95XX is not set
  772. # CONFIG_USB_NET_GL620A is not set
  773. CONFIG_USB_NET_NET1080=m
  774. @@ -1006,24 +1004,24 @@
  775. CONFIG_INPUT=y
  776. CONFIG_INPUT_FF_MEMLESS=m
  777. CONFIG_INPUT_POLLDEV=m
  778. -# CONFIG_INPUT_SPARSEKMAP is not set
  779. +CONFIG_INPUT_SPARSEKMAP=m
  780. #
  781. # Userland interfaces
  782. #
  783. -CONFIG_INPUT_MOUSEDEV=y
  784. +CONFIG_INPUT_MOUSEDEV=m
  785. CONFIG_INPUT_MOUSEDEV_PSAUX=y
  786. CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
  787. CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
  788. # CONFIG_INPUT_JOYDEV is not set
  789. -CONFIG_INPUT_EVDEV=y
  790. +CONFIG_INPUT_EVDEV=m
  791. # CONFIG_INPUT_EVBUG is not set
  792. #
  793. # Input Device Drivers
  794. #
  795. CONFIG_INPUT_KEYBOARD=y
  796. -CONFIG_KEYBOARD_ATKBD=y
  797. +CONFIG_KEYBOARD_ATKBD=m
  798. # CONFIG_KEYBOARD_LKKBD is not set
  799. # CONFIG_KEYBOARD_NEWTON is not set
  800. # CONFIG_KEYBOARD_OPENCORES is not set
  801. @@ -1031,7 +1029,7 @@
  802. # CONFIG_KEYBOARD_SUNKBD is not set
  803. # CONFIG_KEYBOARD_XTKBD is not set
  804. CONFIG_INPUT_MOUSE=y
  805. -CONFIG_MOUSE_PS2=y
  806. +CONFIG_MOUSE_PS2=m
  807. # CONFIG_MOUSE_PS2_ALPS is not set
  808. # CONFIG_MOUSE_PS2_LOGIPS2PP is not set
  809. CONFIG_MOUSE_PS2_SYNAPTICS=y
  810. @@ -1072,20 +1070,7 @@
  811. CONFIG_HW_CONSOLE=y
  812. # CONFIG_VT_HW_CONSOLE_BINDING is not set
  813. CONFIG_DEVKMEM=y
  814. -CONFIG_SERIAL_NONSTANDARD=y
  815. -# CONFIG_COMPUTONE is not set
  816. -# CONFIG_ROCKETPORT is not set
  817. -# CONFIG_CYCLADES is not set
  818. -# CONFIG_DIGIEPCA is not set
  819. -# CONFIG_MOXA_INTELLIO is not set
  820. -# CONFIG_MOXA_SMARTIO is not set
  821. -# CONFIG_ISI is not set
  822. -# CONFIG_SYNCLINKMP is not set
  823. -# CONFIG_SYNCLINK_GT is not set
  824. -# CONFIG_N_HDLC is not set
  825. -# CONFIG_RISCOM8 is not set
  826. -# CONFIG_SPECIALIX is not set
  827. -# CONFIG_STALDRV is not set
  828. +# CONFIG_SERIAL_NONSTANDARD is not set
  829. # CONFIG_NOZOMI is not set
  830. #
  831. @@ -1111,6 +1096,7 @@
  832. #
  833. CONFIG_SERIAL_CORE=m
  834. # CONFIG_SERIAL_JSM is not set
  835. +# CONFIG_SERIAL_TIMBERDALE is not set
  836. CONFIG_UNIX98_PTYS=y
  837. # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
  838. CONFIG_LEGACY_PTYS=y
  839. @@ -1118,7 +1104,6 @@
  840. # CONFIG_IPMI_HANDLER is not set
  841. CONFIG_HW_RANDOM=y
  842. # CONFIG_HW_RANDOM_TIMERIOMEM is not set
  843. -CONFIG_RTC=y
  844. # CONFIG_DTLK is not set
  845. # CONFIG_R3964 is not set
  846. # CONFIG_APPLICOM is not set
  847. @@ -1133,7 +1118,10 @@
  848. #
  849. # CONFIG_PPS is not set
  850. # CONFIG_W1 is not set
  851. -# CONFIG_POWER_SUPPLY is not set
  852. +CONFIG_POWER_SUPPLY=m
  853. +# CONFIG_POWER_SUPPLY_DEBUG is not set
  854. +# CONFIG_PDA_POWER is not set
  855. +# CONFIG_BATTERY_DS2760 is not set
  856. CONFIG_HWMON=y
  857. # CONFIG_HWMON_VID is not set
  858. # CONFIG_HWMON_DEBUG_CHIP is not set
  859. @@ -1172,6 +1160,7 @@
  860. # CONFIG_MFD_SM501 is not set
  861. # CONFIG_HTC_PASIC3 is not set
  862. # CONFIG_MFD_TMIO is not set
  863. +# CONFIG_LPC_SCH is not set
  864. # CONFIG_REGULATOR is not set
  865. CONFIG_MEDIA_SUPPORT=m
  866. @@ -1211,7 +1200,9 @@
  867. CONFIG_USB_M5602=m
  868. CONFIG_USB_STV06XX=m
  869. # CONFIG_USB_GL860 is not set
  870. +# CONFIG_USB_GSPCA_BENQ is not set
  871. CONFIG_USB_GSPCA_CONEX=m
  872. +# CONFIG_USB_GSPCA_CPIA1 is not set
  873. CONFIG_USB_GSPCA_ETOMS=m
  874. CONFIG_USB_GSPCA_FINEPIX=m
  875. # CONFIG_USB_GSPCA_JEILINJ is not set
  876. @@ -1219,9 +1210,11 @@
  877. CONFIG_USB_GSPCA_MR97310A=m
  878. CONFIG_USB_GSPCA_OV519=m
  879. CONFIG_USB_GSPCA_OV534=m
  880. +# CONFIG_USB_GSPCA_OV534_9 is not set
  881. CONFIG_USB_GSPCA_PAC207=m
  882. # CONFIG_USB_GSPCA_PAC7302 is not set
  883. CONFIG_USB_GSPCA_PAC7311=m
  884. +# CONFIG_USB_GSPCA_SN9C2028 is not set
  885. CONFIG_USB_GSPCA_SN9C20X=m
  886. CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
  887. CONFIG_USB_GSPCA_SONIXB=m
  888. @@ -1264,6 +1257,7 @@
  889. # Graphics support
  890. #
  891. CONFIG_VGA_ARB=y
  892. +CONFIG_VGA_ARB_MAX_GPUS=16
  893. # CONFIG_DRM is not set
  894. # CONFIG_VGASTATE is not set
  895. CONFIG_VIDEO_OUTPUT_CONTROL=y
  896. @@ -1351,10 +1345,7 @@
  897. CONFIG_FONT_SUN8x16=y
  898. CONFIG_FONT_SUN12x22=y
  899. CONFIG_FONT_10x18=y
  900. -CONFIG_LOGO=y
  901. -# CONFIG_LOGO_LINUX_MONO is not set
  902. -# CONFIG_LOGO_LINUX_VGA16 is not set
  903. -CONFIG_LOGO_LINUX_CLUT224=y
  904. +# CONFIG_LOGO is not set
  905. CONFIG_SOUND=m
  906. CONFIG_SOUND_OSS_CORE=y
  907. CONFIG_SOUND_OSS_CORE_PRECLAIM=y
  908. @@ -1372,7 +1363,6 @@
  909. CONFIG_SND_SEQUENCER_OSS=y
  910. CONFIG_SND_HRTIMER=m
  911. CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
  912. -# CONFIG_SND_RTCTIMER is not set
  913. # CONFIG_SND_DYNAMIC_MINORS is not set
  914. CONFIG_SND_SUPPORT_OLD_API=y
  915. CONFIG_SND_VERBOSE_PROCFS=y
  916. @@ -1462,6 +1452,7 @@
  917. # CONFIG_SND_MIPS is not set
  918. CONFIG_SND_USB=y
  919. CONFIG_SND_USB_AUDIO=m
  920. +# CONFIG_SND_USB_UA101 is not set
  921. CONFIG_SND_USB_CAIAQ=m
  922. CONFIG_SND_USB_CAIAQ_INPUT=y
  923. # CONFIG_SND_SOC is not set
  924. @@ -1481,6 +1472,7 @@
  925. #
  926. # Special HID drivers
  927. #
  928. +# CONFIG_HID_3M_PCT is not set
  929. CONFIG_HID_A4TECH=m
  930. CONFIG_HID_APPLE=m
  931. CONFIG_HID_BELKIN=m
  932. @@ -1497,14 +1489,20 @@
  933. CONFIG_HID_LOGITECH=m
  934. CONFIG_LOGITECH_FF=y
  935. CONFIG_LOGIRUMBLEPAD2_FF=y
  936. +# CONFIG_LOGIG940_FF is not set
  937. +# CONFIG_HID_MAGICMOUSE is not set
  938. CONFIG_HID_MICROSOFT=m
  939. +# CONFIG_HID_MOSART is not set
  940. CONFIG_HID_MONTEREY=m
  941. CONFIG_HID_NTRIG=m
  942. +# CONFIG_HID_ORTEK is not set
  943. CONFIG_HID_PANTHERLORD=m
  944. CONFIG_PANTHERLORD_FF=y
  945. CONFIG_HID_PETALYNX=m
  946. +# CONFIG_HID_QUANTA is not set
  947. CONFIG_HID_SAMSUNG=m
  948. CONFIG_HID_SONY=m
  949. +# CONFIG_HID_STANTUM is not set
  950. CONFIG_HID_SUNPLUS=m
  951. CONFIG_HID_GREENASIA=m
  952. CONFIG_GREENASIA_FF=y
  953. @@ -1527,14 +1525,14 @@
  954. #
  955. # Miscellaneous USB options
  956. #
  957. -CONFIG_USB_DEVICEFS=y
  958. +# CONFIG_USB_DEVICEFS is not set
  959. # CONFIG_USB_DEVICE_CLASS is not set
  960. CONFIG_USB_DYNAMIC_MINORS=y
  961. CONFIG_USB_SUSPEND=y
  962. # CONFIG_USB_OTG is not set
  963. CONFIG_USB_OTG_WHITELIST=y
  964. # CONFIG_USB_OTG_BLACKLIST_HUB is not set
  965. -CONFIG_USB_MON=y
  966. +CONFIG_USB_MON=m
  967. CONFIG_USB_WUSB=m
  968. # CONFIG_USB_WUSB_CBAF is not set
  969. @@ -1633,6 +1631,7 @@
  970. # CONFIG_USB_SERIAL_NAVMAN is not set
  971. # CONFIG_USB_SERIAL_PL2303 is not set
  972. # CONFIG_USB_SERIAL_OTI6858 is not set
  973. +# CONFIG_USB_SERIAL_QCAUX is not set
  974. # CONFIG_USB_SERIAL_QUALCOMM is not set
  975. # CONFIG_USB_SERIAL_SPCP8X5 is not set
  976. # CONFIG_USB_SERIAL_HP4X is not set
  977. @@ -1646,6 +1645,7 @@
  978. # CONFIG_USB_SERIAL_OPTION is not set
  979. # CONFIG_USB_SERIAL_OMNINET is not set
  980. # CONFIG_USB_SERIAL_OPTICON is not set
  981. +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
  982. # CONFIG_USB_SERIAL_DEBUG is not set
  983. #
  984. @@ -1658,7 +1658,6 @@
  985. # CONFIG_USB_RIO500 is not set
  986. # CONFIG_USB_LEGOTOWER is not set
  987. # CONFIG_USB_LCD is not set
  988. -# CONFIG_USB_BERRY_CHARGE is not set
  989. CONFIG_USB_LED=m
  990. # CONFIG_USB_CYPRESS_CY7C63 is not set
  991. # CONFIG_USB_CYTHERM is not set
  992. @@ -1671,10 +1670,8 @@
  993. # CONFIG_USB_IOWARRIOR is not set
  994. # CONFIG_USB_TEST is not set
  995. # CONFIG_USB_ISIGHTFW is not set
  996. -# CONFIG_USB_VST is not set
  997. CONFIG_USB_GADGET=m
  998. # CONFIG_USB_GADGET_DEBUG_FILES is not set
  999. -# CONFIG_USB_GADGET_DEBUG_FS is not set
  1000. CONFIG_USB_GADGET_VBUS_DRAW=2
  1001. CONFIG_USB_GADGET_SELECTED=y
  1002. # CONFIG_USB_GADGET_AT91 is not set
  1003. @@ -1708,6 +1705,7 @@
  1004. # CONFIG_USB_MIDI_GADGET is not set
  1005. # CONFIG_USB_G_PRINTER is not set
  1006. # CONFIG_USB_CDC_COMPOSITE is not set
  1007. +# CONFIG_USB_G_NOKIA is not set
  1008. # CONFIG_USB_G_MULTI is not set
  1009. #
  1010. @@ -1735,8 +1733,6 @@
  1011. # MMC/SD/SDIO Host Controller Drivers
  1012. #
  1013. # CONFIG_MMC_SDHCI is not set
  1014. -# CONFIG_MMC_AT91 is not set
  1015. -# CONFIG_MMC_ATMELMCI is not set
  1016. # CONFIG_MMC_TIFM_SD is not set
  1017. # CONFIG_MMC_CB710 is not set
  1018. # CONFIG_MMC_VIA_SDMMC is not set
  1019. @@ -1747,11 +1743,11 @@
  1020. #
  1021. # LED drivers
  1022. #
  1023. +CONFIG_LEDS_TRIGGERS=y
  1024. #
  1025. # LED Triggers
  1026. #
  1027. -CONFIG_LEDS_TRIGGERS=y
  1028. # CONFIG_LEDS_TRIGGER_TIMER is not set
  1029. # CONFIG_LEDS_TRIGGER_IDE_DISK is not set
  1030. # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
  1031. @@ -1763,7 +1759,45 @@
  1032. #
  1033. # CONFIG_ACCESSIBILITY is not set
  1034. # CONFIG_INFINIBAND is not set
  1035. -# CONFIG_RTC_CLASS is not set
  1036. +CONFIG_RTC_LIB=y
  1037. +CONFIG_RTC_CLASS=y
  1038. +CONFIG_RTC_HCTOSYS=y
  1039. +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
  1040. +# CONFIG_RTC_DEBUG is not set
  1041. +
  1042. +#
  1043. +# RTC interfaces
  1044. +#
  1045. +CONFIG_RTC_INTF_SYSFS=y
  1046. +CONFIG_RTC_INTF_PROC=y
  1047. +CONFIG_RTC_INTF_DEV=y
  1048. +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
  1049. +# CONFIG_RTC_DRV_TEST is not set
  1050. +
  1051. +#
  1052. +# SPI RTC drivers
  1053. +#
  1054. +
  1055. +#
  1056. +# Platform RTC drivers
  1057. +#
  1058. +CONFIG_RTC_DRV_CMOS=y
  1059. +# CONFIG_RTC_DRV_DS1286 is not set
  1060. +# CONFIG_RTC_DRV_DS1511 is not set
  1061. +# CONFIG_RTC_DRV_DS1553 is not set
  1062. +# CONFIG_RTC_DRV_DS1742 is not set
  1063. +# CONFIG_RTC_DRV_STK17TA8 is not set
  1064. +# CONFIG_RTC_DRV_M48T86 is not set
  1065. +# CONFIG_RTC_DRV_M48T35 is not set
  1066. +# CONFIG_RTC_DRV_M48T59 is not set
  1067. +# CONFIG_RTC_DRV_MSM6242 is not set
  1068. +# CONFIG_RTC_DRV_BQ4802 is not set
  1069. +# CONFIG_RTC_DRV_RP5C01 is not set
  1070. +# CONFIG_RTC_DRV_V3020 is not set
  1071. +
  1072. +#
  1073. +# on-CPU RTC drivers
  1074. +#
  1075. # CONFIG_DMADEVICES is not set
  1076. # CONFIG_AUXDISPLAY is not set
  1077. # CONFIG_UIO is not set
  1078. @@ -1776,14 +1810,15 @@
  1079. # CONFIG_ET131X is not set
  1080. # CONFIG_USB_IP_COMMON is not set
  1081. # CONFIG_W35UND is not set
  1082. +# CONFIG_PRISM2_USB is not set
  1083. # CONFIG_ECHO is not set
  1084. # CONFIG_OTUS is not set
  1085. # CONFIG_COMEDI is not set
  1086. # CONFIG_ASUS_OLED is not set
  1087. -# CONFIG_ALTERA_PCIE_CHDMA is not set
  1088. # CONFIG_R8187SE is not set
  1089. +# CONFIG_RTL8192SU is not set
  1090. +# CONFIG_RTL8192U is not set
  1091. # CONFIG_RTL8192E is not set
  1092. -# CONFIG_INPUT_MIMIO is not set
  1093. # CONFIG_TRANZPORT is not set
  1094. #
  1095. @@ -1795,8 +1830,6 @@
  1096. #
  1097. # CONFIG_INPUT_GPIO is not set
  1098. # CONFIG_POHMELFS is not set
  1099. -# CONFIG_B3DFG is not set
  1100. -# CONFIG_PLAN9AUTH is not set
  1101. # CONFIG_LINE6_USB is not set
  1102. # CONFIG_USB_SERIAL_QUATECH2 is not set
  1103. # CONFIG_USB_SERIAL_QUATECH_USB2 is not set
  1104. @@ -1815,7 +1848,11 @@
  1105. # CONFIG_STRIP is not set
  1106. # CONFIG_WAVELAN is not set
  1107. CONFIG_FB_SM7XX=y
  1108. -# CONFIG_FB_SM7XX_ACCEL is not set
  1109. +# CONFIG_DT3155 is not set
  1110. +# CONFIG_CRYSTALHD is not set
  1111. +CONFIG_MIPS_PLATFORM_DEVICES=y
  1112. +CONFIG_LEMOTE_YEELOONG2F=m
  1113. +CONFIG_LEMOTE_LYNLOONG2F=m
  1114. #
  1115. # File systems
  1116. @@ -1834,9 +1871,7 @@
  1117. # CONFIG_EXT4_FS_SECURITY is not set
  1118. # CONFIG_EXT4_DEBUG is not set
  1119. CONFIG_JBD=y
  1120. -# CONFIG_JBD_DEBUG is not set
  1121. CONFIG_JBD2=y
  1122. -# CONFIG_JBD2_DEBUG is not set
  1123. CONFIG_FS_MBCACHE=y
  1124. CONFIG_REISERFS_FS=m
  1125. # CONFIG_REISERFS_CHECK is not set
  1126. @@ -1874,7 +1909,8 @@
  1127. CONFIG_QUOTACTL=y
  1128. CONFIG_AUTOFS_FS=m
  1129. CONFIG_AUTOFS4_FS=m
  1130. -# CONFIG_FUSE_FS is not set
  1131. +CONFIG_FUSE_FS=m
  1132. +CONFIG_CUSE=m
  1133. #
  1134. # Caches
  1135. @@ -1929,6 +1965,7 @@
  1136. # CONFIG_BEFS_FS is not set
  1137. # CONFIG_BFS_FS is not set
  1138. # CONFIG_EFS_FS is not set
  1139. +# CONFIG_LOGFS is not set
  1140. CONFIG_CRAMFS=m
  1141. CONFIG_SQUASHFS=m
  1142. CONFIG_SQUASHFS_EMBEDDED=y
  1143. @@ -1965,6 +2002,7 @@
  1144. CONFIG_RPCSEC_GSS_KRB5=m
  1145. # CONFIG_RPCSEC_GSS_SPKM3 is not set
  1146. # CONFIG_SMB_FS is not set
  1147. +# CONFIG_CEPH_FS is not set
  1148. CONFIG_CIFS=m
  1149. # CONFIG_CIFS_STATS is not set
  1150. # CONFIG_CIFS_WEAK_PW_HASH is not set
  1151. @@ -2028,39 +2066,31 @@
  1152. # Kernel hacking
  1153. #
  1154. CONFIG_TRACE_IRQFLAGS_SUPPORT=y
  1155. -CONFIG_PRINTK_TIME=y
  1156. +# CONFIG_PRINTK_TIME is not set
  1157. CONFIG_ENABLE_WARN_DEPRECATED=y
  1158. CONFIG_ENABLE_MUST_CHECK=y
  1159. CONFIG_FRAME_WARN=1024
  1160. # CONFIG_MAGIC_SYSRQ is not set
  1161. CONFIG_STRIP_ASM_SYMS=y
  1162. # CONFIG_UNUSED_SYMBOLS is not set
  1163. -CONFIG_DEBUG_FS=y
  1164. +# CONFIG_DEBUG_FS is not set
  1165. # CONFIG_HEADERS_CHECK is not set
  1166. # CONFIG_DEBUG_KERNEL is not set
  1167. -# CONFIG_SLUB_DEBUG_ON is not set
  1168. -# CONFIG_SLUB_STATS is not set
  1169. -CONFIG_STACKTRACE=y
  1170. # CONFIG_DEBUG_MEMORY_INIT is not set
  1171. # CONFIG_RCU_CPU_STALL_DETECTOR is not set
  1172. CONFIG_SYSCTL_SYSCALL_CHECK=y
  1173. -CONFIG_NOP_TRACER=y
  1174. CONFIG_HAVE_FUNCTION_TRACER=y
  1175. CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
  1176. CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
  1177. CONFIG_HAVE_DYNAMIC_FTRACE=y
  1178. CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
  1179. CONFIG_RING_BUFFER=y
  1180. -CONFIG_EVENT_TRACING=y
  1181. -CONFIG_CONTEXT_SWITCH_TRACER=y
  1182. CONFIG_RING_BUFFER_ALLOW_SWAP=y
  1183. -CONFIG_TRACING=y
  1184. CONFIG_TRACING_SUPPORT=y
  1185. # CONFIG_FTRACE is not set
  1186. -# CONFIG_DYNAMIC_DEBUG is not set
  1187. # CONFIG_SAMPLES is not set
  1188. CONFIG_HAVE_ARCH_KGDB=y
  1189. -CONFIG_EARLY_PRINTK=y
  1190. +# CONFIG_EARLY_PRINTK is not set
  1191. # CONFIG_CMDLINE_BOOL is not set
  1192. #
  1193. @@ -2183,7 +2213,7 @@
  1194. CONFIG_CRYPTO_ANSI_CPRNG=m
  1195. CONFIG_CRYPTO_HW=y
  1196. # CONFIG_CRYPTO_DEV_HIFN_795X is not set
  1197. -CONFIG_BINARY_PRINTF=y
  1198. +# CONFIG_BINARY_PRINTF is not set
  1199. #
  1200. # Library routines
  1201. diff -Nur linux-2.6.34.orig/arch/mips/configs/lemote2f_minimal_defconfig linux-loongson/arch/mips/configs/lemote2f_minimal_defconfig
  1202. --- linux-2.6.34.orig/arch/mips/configs/lemote2f_minimal_defconfig 1970-01-01 01:00:00.000000000 +0100
  1203. +++ linux-loongson/arch/mips/configs/lemote2f_minimal_defconfig 2010-05-27 18:12:28.612213391 +0200
  1204. @@ -0,0 +1,1383 @@
  1205. +#
  1206. +# Automatically generated make config: don't edit
  1207. +# Linux kernel version: 2.6.34-rc5
  1208. +# Wed Apr 28 01:06:41 2010
  1209. +#
  1210. +CONFIG_MIPS=y
  1211. +
  1212. +#
  1213. +# Machine selection
  1214. +#
  1215. +# CONFIG_MACH_ALCHEMY is not set
  1216. +# CONFIG_AR7 is not set
  1217. +# CONFIG_BCM47XX is not set
  1218. +# CONFIG_BCM63XX is not set
  1219. +# CONFIG_MIPS_COBALT is not set
  1220. +# CONFIG_MACH_DECSTATION is not set
  1221. +# CONFIG_MACH_JAZZ is not set
  1222. +# CONFIG_LASAT is not set
  1223. +CONFIG_MACH_LOONGSON=y
  1224. +# CONFIG_MIPS_MALTA is not set
  1225. +# CONFIG_MIPS_SIM is not set
  1226. +# CONFIG_NEC_MARKEINS is not set
  1227. +# CONFIG_MACH_VR41XX is not set
  1228. +# CONFIG_NXP_STB220 is not set
  1229. +# CONFIG_NXP_STB225 is not set
  1230. +# CONFIG_PNX8550_JBS is not set
  1231. +# CONFIG_PNX8550_STB810 is not set
  1232. +# CONFIG_PMC_MSP is not set
  1233. +# CONFIG_PMC_YOSEMITE is not set
  1234. +# CONFIG_POWERTV is not set
  1235. +# CONFIG_SGI_IP22 is not set
  1236. +# CONFIG_SGI_IP27 is not set
  1237. +# CONFIG_SGI_IP28 is not set
  1238. +# CONFIG_SGI_IP32 is not set
  1239. +# CONFIG_SIBYTE_CRHINE is not set
  1240. +# CONFIG_SIBYTE_CARMEL is not set
  1241. +# CONFIG_SIBYTE_CRHONE is not set
  1242. +# CONFIG_SIBYTE_RHONE is not set
  1243. +# CONFIG_SIBYTE_SWARM is not set
  1244. +# CONFIG_SIBYTE_LITTLESUR is not set
  1245. +# CONFIG_SIBYTE_SENTOSA is not set
  1246. +# CONFIG_SIBYTE_BIGSUR is not set
  1247. +# CONFIG_SNI_RM is not set
  1248. +# CONFIG_MACH_TX39XX is not set
  1249. +# CONFIG_MACH_TX49XX is not set
  1250. +# CONFIG_MIKROTIK_RB532 is not set
  1251. +# CONFIG_WR_PPMC is not set
  1252. +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
  1253. +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
  1254. +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
  1255. +CONFIG_ARCH_SPARSEMEM_ENABLE=y
  1256. +# CONFIG_LEMOTE_FULOONG2E is not set
  1257. +CONFIG_LEMOTE_MACH2F=y
  1258. +CONFIG_CS5536=y
  1259. +# CONFIG_CS5536_MFGPT is not set
  1260. +CONFIG_LOONGSON_UART_BASE=y
  1261. +CONFIG_RWSEM_GENERIC_SPINLOCK=y
  1262. +# CONFIG_ARCH_HAS_ILOG2_U32 is not set
  1263. +# CONFIG_ARCH_HAS_ILOG2_U64 is not set
  1264. +CONFIG_ARCH_SUPPORTS_OPROFILE=y
  1265. +CONFIG_GENERIC_FIND_NEXT_BIT=y
  1266. +CONFIG_GENERIC_HWEIGHT=y
  1267. +CONFIG_GENERIC_CALIBRATE_DELAY=y
  1268. +CONFIG_GENERIC_CLOCKEVENTS=y
  1269. +CONFIG_GENERIC_TIME=y
  1270. +CONFIG_GENERIC_CMOS_UPDATE=y
  1271. +CONFIG_SCHED_OMIT_FRAME_POINTER=y
  1272. +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
  1273. +CONFIG_CEVT_R4K_LIB=y
  1274. +CONFIG_CEVT_R4K=y
  1275. +CONFIG_CSRC_R4K_LIB=y
  1276. +CONFIG_CSRC_R4K=y
  1277. +CONFIG_DMA_NONCOHERENT=y
  1278. +CONFIG_NEED_DMA_MAP_STATE=y
  1279. +CONFIG_SYS_HAS_EARLY_PRINTK=y
  1280. +CONFIG_I8259=y
  1281. +# CONFIG_NO_IOPORT is not set
  1282. +CONFIG_GENERIC_ISA_DMA=y
  1283. +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
  1284. +# CONFIG_CPU_BIG_ENDIAN is not set
  1285. +CONFIG_CPU_LITTLE_ENDIAN=y
  1286. +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
  1287. +CONFIG_IRQ_CPU=y
  1288. +CONFIG_BOOT_ELF32=y
  1289. +CONFIG_MIPS_L1_CACHE_SHIFT=5
  1290. +
  1291. +#
  1292. +# CPU selection
  1293. +#
  1294. +# CONFIG_CPU_LOONGSON2E is not set
  1295. +CONFIG_CPU_LOONGSON2F=y
  1296. +# CONFIG_CPU_MIPS32_R1 is not set
  1297. +# CONFIG_CPU_MIPS32_R2 is not set
  1298. +# CONFIG_CPU_MIPS64_R1 is not set
  1299. +# CONFIG_CPU_MIPS64_R2 is not set
  1300. +# CONFIG_CPU_R3000 is not set
  1301. +# CONFIG_CPU_TX39XX is not set
  1302. +# CONFIG_CPU_VR41XX is not set
  1303. +# CONFIG_CPU_R4300 is not set
  1304. +# CONFIG_CPU_R4X00 is not set
  1305. +# CONFIG_CPU_TX49XX is not set
  1306. +# CONFIG_CPU_R5000 is not set
  1307. +# CONFIG_CPU_R5432 is not set
  1308. +# CONFIG_CPU_R5500 is not set
  1309. +# CONFIG_CPU_R6000 is not set
  1310. +# CONFIG_CPU_NEVADA is not set
  1311. +# CONFIG_CPU_R8000 is not set
  1312. +# CONFIG_CPU_R10000 is not set
  1313. +# CONFIG_CPU_RM7000 is not set
  1314. +# CONFIG_CPU_RM9000 is not set
  1315. +# CONFIG_CPU_SB1 is not set
  1316. +# CONFIG_CPU_CAVIUM_OCTEON is not set
  1317. +CONFIG_SYS_SUPPORTS_ZBOOT=y
  1318. +CONFIG_CPU_LOONGSON2=y
  1319. +CONFIG_SYS_HAS_CPU_LOONGSON2F=y
  1320. +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
  1321. +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
  1322. +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
  1323. +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
  1324. +CONFIG_CPU_SUPPORTS_CPUFREQ=y
  1325. +CONFIG_CPU_SUPPORTS_ADDRWINCFG=y
  1326. +CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED=y
  1327. +
  1328. +#
  1329. +# Kernel type
  1330. +#
  1331. +# CONFIG_32BIT is not set
  1332. +CONFIG_64BIT=y
  1333. +# CONFIG_PAGE_SIZE_4KB is not set
  1334. +# CONFIG_PAGE_SIZE_8KB is not set
  1335. +CONFIG_PAGE_SIZE_16KB=y
  1336. +# CONFIG_PAGE_SIZE_32KB is not set
  1337. +# CONFIG_PAGE_SIZE_64KB is not set
  1338. +CONFIG_BOARD_SCACHE=y
  1339. +CONFIG_MIPS_MT_DISABLED=y
  1340. +# CONFIG_MIPS_MT_SMP is not set
  1341. +# CONFIG_MIPS_MT_SMTC is not set
  1342. +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
  1343. +CONFIG_CPU_HAS_WB=y
  1344. +CONFIG_CPU_HAS_SYNC=y
  1345. +CONFIG_GENERIC_HARDIRQS=y
  1346. +CONFIG_GENERIC_IRQ_PROBE=y
  1347. +CONFIG_CPU_SUPPORTS_HIGHMEM=y
  1348. +CONFIG_SYS_SUPPORTS_HIGHMEM=y
  1349. +CONFIG_ARCH_POPULATES_NODE_MAP=y
  1350. +CONFIG_SELECT_MEMORY_MODEL=y
  1351. +# CONFIG_FLATMEM_MANUAL is not set
  1352. +# CONFIG_DISCONTIGMEM_MANUAL is not set
  1353. +CONFIG_SPARSEMEM_MANUAL=y
  1354. +CONFIG_SPARSEMEM=y
  1355. +CONFIG_HAVE_MEMORY_PRESENT=y
  1356. +CONFIG_SPARSEMEM_STATIC=y
  1357. +CONFIG_PAGEFLAGS_EXTENDED=y
  1358. +CONFIG_SPLIT_PTLOCK_CPUS=4
  1359. +CONFIG_PHYS_ADDR_T_64BIT=y
  1360. +CONFIG_ZONE_DMA_FLAG=0
  1361. +CONFIG_VIRT_TO_BUS=y
  1362. +# CONFIG_KSM is not set
  1363. +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  1364. +CONFIG_TICK_ONESHOT=y
  1365. +CONFIG_NO_HZ=y
  1366. +CONFIG_HIGH_RES_TIMERS=y
  1367. +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
  1368. +CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK=y
  1369. +# CONFIG_HZ_48 is not set
  1370. +# CONFIG_HZ_100 is not set
  1371. +# CONFIG_HZ_128 is not set
  1372. +CONFIG_HZ_250=y
  1373. +# CONFIG_HZ_256 is not set
  1374. +# CONFIG_HZ_1000 is not set
  1375. +# CONFIG_HZ_1024 is not set
  1376. +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
  1377. +CONFIG_HZ=250
  1378. +# CONFIG_PREEMPT_NONE is not set
  1379. +# CONFIG_PREEMPT_VOLUNTARY is not set
  1380. +CONFIG_PREEMPT=y
  1381. +CONFIG_KEXEC=y
  1382. +# CONFIG_SECCOMP is not set
  1383. +CONFIG_LOCKDEP_SUPPORT=y
  1384. +CONFIG_STACKTRACE_SUPPORT=y
  1385. +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
  1386. +CONFIG_CONSTRUCTORS=y
  1387. +
  1388. +#
  1389. +# General setup
  1390. +#
  1391. +CONFIG_EXPERIMENTAL=y
  1392. +CONFIG_BROKEN_ON_SMP=y
  1393. +CONFIG_LOCK_KERNEL=y
  1394. +CONFIG_INIT_ENV_ARG_LIMIT=32
  1395. +CONFIG_LOCALVERSION=""
  1396. +# CONFIG_LOCALVERSION_AUTO is not set
  1397. +CONFIG_HAVE_KERNEL_GZIP=y
  1398. +CONFIG_HAVE_KERNEL_BZIP2=y
  1399. +CONFIG_HAVE_KERNEL_LZMA=y
  1400. +CONFIG_HAVE_KERNEL_LZO=y
  1401. +CONFIG_KERNEL_GZIP=y
  1402. +# CONFIG_KERNEL_BZIP2 is not set
  1403. +# CONFIG_KERNEL_LZMA is not set
  1404. +# CONFIG_KERNEL_LZO is not set
  1405. +CONFIG_SWAP=y
  1406. +CONFIG_SYSVIPC=y
  1407. +CONFIG_SYSVIPC_SYSCTL=y
  1408. +# CONFIG_POSIX_MQUEUE is not set
  1409. +CONFIG_BSD_PROCESS_ACCT=y
  1410. +CONFIG_BSD_PROCESS_ACCT_V3=y
  1411. +# CONFIG_TASKSTATS is not set
  1412. +CONFIG_AUDIT=y
  1413. +
  1414. +#
  1415. +# RCU Subsystem
  1416. +#
  1417. +CONFIG_TREE_RCU=y
  1418. +# CONFIG_TREE_PREEMPT_RCU is not set
  1419. +# CONFIG_TINY_RCU is not set
  1420. +# CONFIG_RCU_TRACE is not set
  1421. +CONFIG_RCU_FANOUT=64
  1422. +# CONFIG_RCU_FANOUT_EXACT is not set
  1423. +# CONFIG_TREE_RCU_TRACE is not set
  1424. +CONFIG_IKCONFIG=y
  1425. +CONFIG_IKCONFIG_PROC=y
  1426. +CONFIG_LOG_BUF_SHIFT=15
  1427. +# CONFIG_CGROUPS is not set
  1428. +CONFIG_SYSFS_DEPRECATED=y
  1429. +CONFIG_SYSFS_DEPRECATED_V2=y
  1430. +# CONFIG_RELAY is not set
  1431. +# CONFIG_NAMESPACES is not set
  1432. +CONFIG_BLK_DEV_INITRD=y
  1433. +CONFIG_INITRAMFS_SOURCE=""
  1434. +CONFIG_RD_GZIP=y
  1435. +CONFIG_RD_BZIP2=y
  1436. +CONFIG_RD_LZMA=y
  1437. +CONFIG_RD_LZO=y
  1438. +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
  1439. +CONFIG_SYSCTL=y
  1440. +CONFIG_ANON_INODES=y
  1441. +CONFIG_EMBEDDED=y
  1442. +CONFIG_SYSCTL_SYSCALL=y
  1443. +CONFIG_KALLSYMS=y
  1444. +# CONFIG_KALLSYMS_EXTRA_PASS is not set
  1445. +CONFIG_HOTPLUG=y
  1446. +CONFIG_PRINTK=y
  1447. +CONFIG_BUG=y
  1448. +CONFIG_ELF_CORE=y
  1449. +CONFIG_PCSPKR_PLATFORM=y
  1450. +CONFIG_BASE_FULL=y
  1451. +CONFIG_FUTEX=y
  1452. +CONFIG_EPOLL=y
  1453. +CONFIG_SIGNALFD=y
  1454. +CONFIG_TIMERFD=y
  1455. +CONFIG_EVENTFD=y
  1456. +CONFIG_SHMEM=y
  1457. +CONFIG_AIO=y
  1458. +
  1459. +#
  1460. +# Kernel Performance Events And Counters
  1461. +#
  1462. +CONFIG_VM_EVENT_COUNTERS=y
  1463. +CONFIG_PCI_QUIRKS=y
  1464. +CONFIG_SLUB_DEBUG=y
  1465. +CONFIG_COMPAT_BRK=y
  1466. +# CONFIG_SLAB is not set
  1467. +CONFIG_SLUB=y
  1468. +# CONFIG_SLOB is not set
  1469. +CONFIG_PROFILING=y
  1470. +# CONFIG_OPROFILE is not set
  1471. +CONFIG_HAVE_OPROFILE=y
  1472. +CONFIG_HAVE_SYSCALL_WRAPPERS=y
  1473. +
  1474. +#
  1475. +# GCOV-based kernel profiling
  1476. +#
  1477. +# CONFIG_SLOW_WORK is not set
  1478. +CONFIG_HAVE_GENERIC_DMA_COHERENT=y
  1479. +CONFIG_SLABINFO=y
  1480. +CONFIG_RT_MUTEXES=y
  1481. +CONFIG_BASE_SMALL=0
  1482. +# CONFIG_MODULES is not set
  1483. +CONFIG_BLOCK=y
  1484. +# CONFIG_BLK_DEV_BSG is not set
  1485. +# CONFIG_BLK_DEV_INTEGRITY is not set
  1486. +CONFIG_BLOCK_COMPAT=y
  1487. +
  1488. +#
  1489. +# IO Schedulers
  1490. +#
  1491. +CONFIG_IOSCHED_NOOP=y
  1492. +# CONFIG_IOSCHED_DEADLINE is not set
  1493. +# CONFIG_IOSCHED_CFQ is not set
  1494. +# CONFIG_DEFAULT_DEADLINE is not set
  1495. +# CONFIG_DEFAULT_CFQ is not set
  1496. +CONFIG_DEFAULT_NOOP=y
  1497. +CONFIG_DEFAULT_IOSCHED="noop"
  1498. +# CONFIG_INLINE_SPIN_TRYLOCK is not set
  1499. +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
  1500. +# CONFIG_INLINE_SPIN_LOCK is not set
  1501. +# CONFIG_INLINE_SPIN_LOCK_BH is not set
  1502. +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
  1503. +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
  1504. +# CONFIG_INLINE_SPIN_UNLOCK is not set
  1505. +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
  1506. +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
  1507. +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
  1508. +# CONFIG_INLINE_READ_TRYLOCK is not set
  1509. +# CONFIG_INLINE_READ_LOCK is not set
  1510. +# CONFIG_INLINE_READ_LOCK_BH is not set
  1511. +# CONFIG_INLINE_READ_LOCK_IRQ is not set
  1512. +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
  1513. +# CONFIG_INLINE_READ_UNLOCK is not set
  1514. +# CONFIG_INLINE_READ_UNLOCK_BH is not set
  1515. +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
  1516. +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
  1517. +# CONFIG_INLINE_WRITE_TRYLOCK is not set
  1518. +# CONFIG_INLINE_WRITE_LOCK is not set
  1519. +# CONFIG_INLINE_WRITE_LOCK_BH is not set
  1520. +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
  1521. +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
  1522. +# CONFIG_INLINE_WRITE_UNLOCK is not set
  1523. +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
  1524. +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
  1525. +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
  1526. +# CONFIG_MUTEX_SPIN_ON_OWNER is not set
  1527. +# CONFIG_FREEZER is not set
  1528. +
  1529. +#
  1530. +# Bus options (PCI, PCMCIA, EISA, ISA, TC)
  1531. +#
  1532. +CONFIG_HW_HAS_PCI=y
  1533. +CONFIG_PCI=y
  1534. +CONFIG_PCI_DOMAINS=y
  1535. +# CONFIG_ARCH_SUPPORTS_MSI is not set
  1536. +# CONFIG_PCI_STUB is not set
  1537. +# CONFIG_PCI_IOV is not set
  1538. +CONFIG_ISA=y
  1539. +CONFIG_MMU=y
  1540. +# CONFIG_PCCARD is not set
  1541. +# CONFIG_HOTPLUG_PCI is not set
  1542. +
  1543. +#
  1544. +# Executable file formats
  1545. +#
  1546. +CONFIG_BINFMT_ELF=y
  1547. +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  1548. +# CONFIG_HAVE_AOUT is not set
  1549. +# CONFIG_BINFMT_MISC is not set
  1550. +CONFIG_MIPS32_COMPAT=y
  1551. +CONFIG_COMPAT=y
  1552. +CONFIG_SYSVIPC_COMPAT=y
  1553. +CONFIG_MIPS32_O32=y
  1554. +CONFIG_MIPS32_N32=y
  1555. +CONFIG_BINFMT_ELF32=y
  1556. +
  1557. +#
  1558. +# Power management options
  1559. +#
  1560. +CONFIG_ARCH_HIBERNATION_POSSIBLE=y
  1561. +CONFIG_ARCH_SUSPEND_POSSIBLE=y
  1562. +# CONFIG_PM is not set
  1563. +CONFIG_NET=y
  1564. +
  1565. +#
  1566. +# Networking options
  1567. +#
  1568. +CONFIG_PACKET=y
  1569. +CONFIG_UNIX=y
  1570. +# CONFIG_NET_KEY is not set
  1571. +CONFIG_INET=y
  1572. +# CONFIG_IP_MULTICAST is not set
  1573. +# CONFIG_IP_ADVANCED_ROUTER is not set
  1574. +CONFIG_IP_FIB_HASH=y
  1575. +# CONFIG_IP_PNP is not set
  1576. +# CONFIG_NET_IPIP is not set
  1577. +# CONFIG_NET_IPGRE is not set
  1578. +# CONFIG_ARPD is not set
  1579. +# CONFIG_SYN_COOKIES is not set
  1580. +# CONFIG_INET_AH is not set
  1581. +# CONFIG_INET_ESP is not set
  1582. +# CONFIG_INET_IPCOMP is not set
  1583. +# CONFIG_INET_XFRM_TUNNEL is not set
  1584. +# CONFIG_INET_TUNNEL is not set
  1585. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  1586. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  1587. +# CONFIG_INET_XFRM_MODE_BEET is not set
  1588. +# CONFIG_INET_LRO is not set
  1589. +# CONFIG_INET_DIAG is not set
  1590. +# CONFIG_TCP_CONG_ADVANCED is not set
  1591. +CONFIG_TCP_CONG_CUBIC=y
  1592. +CONFIG_DEFAULT_TCP_CONG="cubic"
  1593. +# CONFIG_TCP_MD5SIG is not set
  1594. +# CONFIG_IPV6 is not set
  1595. +# CONFIG_NETWORK_SECMARK is not set
  1596. +# CONFIG_NETFILTER is not set
  1597. +# CONFIG_IP_DCCP is not set
  1598. +# CONFIG_IP_SCTP is not set
  1599. +# CONFIG_RDS is not set
  1600. +# CONFIG_TIPC is not set
  1601. +# CONFIG_ATM is not set
  1602. +# CONFIG_BRIDGE is not set
  1603. +# CONFIG_NET_DSA is not set
  1604. +# CONFIG_VLAN_8021Q is not set
  1605. +# CONFIG_DECNET is not set
  1606. +# CONFIG_LLC2 is not set
  1607. +# CONFIG_IPX is not set
  1608. +# CONFIG_ATALK is not set
  1609. +# CONFIG_X25 is not set
  1610. +# CONFIG_LAPB is not set
  1611. +# CONFIG_ECONET is not set
  1612. +# CONFIG_WAN_ROUTER is not set
  1613. +# CONFIG_PHONET is not set
  1614. +# CONFIG_IEEE802154 is not set
  1615. +# CONFIG_NET_SCHED is not set
  1616. +# CONFIG_DCB is not set
  1617. +
  1618. +#
  1619. +# Network testing
  1620. +#
  1621. +# CONFIG_NET_PKTGEN is not set
  1622. +# CONFIG_HAMRADIO is not set
  1623. +# CONFIG_CAN is not set
  1624. +# CONFIG_IRDA is not set
  1625. +# CONFIG_BT is not set
  1626. +# CONFIG_AF_RXRPC is not set
  1627. +# CONFIG_WIRELESS is not set
  1628. +# CONFIG_WIMAX is not set
  1629. +# CONFIG_RFKILL is not set
  1630. +# CONFIG_NET_9P is not set
  1631. +
  1632. +#
  1633. +# Device Drivers
  1634. +#
  1635. +
  1636. +#
  1637. +# Generic Driver Options
  1638. +#
  1639. +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
  1640. +# CONFIG_DEVTMPFS is not set
  1641. +CONFIG_STANDALONE=y
  1642. +CONFIG_PREVENT_FIRMWARE_BUILD=y
  1643. +CONFIG_FW_LOADER=y
  1644. +CONFIG_FIRMWARE_IN_KERNEL=y
  1645. +CONFIG_EXTRA_FIRMWARE=""
  1646. +# CONFIG_SYS_HYPERVISOR is not set
  1647. +# CONFIG_CONNECTOR is not set
  1648. +# CONFIG_MTD is not set
  1649. +# CONFIG_PARPORT is not set
  1650. +# CONFIG_PNP is not set
  1651. +CONFIG_BLK_DEV=y
  1652. +# CONFIG_BLK_CPQ_DA is not set
  1653. +# CONFIG_BLK_CPQ_CISS_DA is not set
  1654. +# CONFIG_BLK_DEV_DAC960 is not set
  1655. +# CONFIG_BLK_DEV_UMEM is not set
  1656. +# CONFIG_BLK_DEV_COW_COMMON is not set
  1657. +CONFIG_BLK_DEV_LOOP=y
  1658. +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  1659. +
  1660. +#
  1661. +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
  1662. +#
  1663. +# CONFIG_BLK_DEV_NBD is not set
  1664. +# CONFIG_BLK_DEV_SX8 is not set
  1665. +# CONFIG_BLK_DEV_UB is not set
  1666. +CONFIG_BLK_DEV_RAM=y
  1667. +CONFIG_BLK_DEV_RAM_COUNT=16
  1668. +CONFIG_BLK_DEV_RAM_SIZE=8192
  1669. +# CONFIG_BLK_DEV_XIP is not set
  1670. +# CONFIG_CDROM_PKTCDVD is not set
  1671. +# CONFIG_ATA_OVER_ETH is not set
  1672. +# CONFIG_BLK_DEV_HD is not set
  1673. +# CONFIG_MISC_DEVICES is not set
  1674. +CONFIG_HAVE_IDE=y
  1675. +CONFIG_IDE=y
  1676. +
  1677. +#
  1678. +# Please see Documentation/ide/ide.txt for help/info on IDE drives
  1679. +#
  1680. +CONFIG_IDE_XFER_MODE=y
  1681. +CONFIG_IDE_TIMINGS=y
  1682. +# CONFIG_BLK_DEV_IDE_SATA is not set
  1683. +CONFIG_IDE_GD=y
  1684. +CONFIG_IDE_GD_ATA=y
  1685. +# CONFIG_IDE_GD_ATAPI is not set
  1686. +# CONFIG_BLK_DEV_IDECD is not set
  1687. +# CONFIG_BLK_DEV_IDETAPE is not set
  1688. +# CONFIG_IDE_TASK_IOCTL is not set
  1689. +# CONFIG_IDE_PROC_FS is not set
  1690. +
  1691. +#
  1692. +# IDE chipset support/bugfixes
  1693. +#
  1694. +# CONFIG_IDE_GENERIC is not set
  1695. +# CONFIG_BLK_DEV_PLATFORM is not set
  1696. +CONFIG_BLK_DEV_IDEDMA_SFF=y
  1697. +
  1698. +#
  1699. +# PCI IDE chipsets support
  1700. +#
  1701. +CONFIG_BLK_DEV_IDEPCI=y
  1702. +# CONFIG_IDEPCI_PCIBUS_ORDER is not set
  1703. +# CONFIG_BLK_DEV_GENERIC is not set
  1704. +# CONFIG_BLK_DEV_OPTI621 is not set
  1705. +CONFIG_BLK_DEV_IDEDMA_PCI=y
  1706. +# CONFIG_BLK_DEV_AEC62XX is not set
  1707. +# CONFIG_BLK_DEV_ALI15X3 is not set
  1708. +CONFIG_BLK_DEV_AMD74XX=y
  1709. +# CONFIG_BLK_DEV_CMD64X is not set
  1710. +# CONFIG_BLK_DEV_TRIFLEX is not set
  1711. +# CONFIG_BLK_DEV_CS5520 is not set
  1712. +# CONFIG_BLK_DEV_CS5530 is not set
  1713. +# CONFIG_BLK_DEV_HPT366 is not set
  1714. +# CONFIG_BLK_DEV_JMICRON is not set
  1715. +# CONFIG_BLK_DEV_SC1200 is not set
  1716. +# CONFIG_BLK_DEV_PIIX is not set
  1717. +# CONFIG_BLK_DEV_IT8172 is not set
  1718. +# CONFIG_BLK_DEV_IT8213 is not set
  1719. +# CONFIG_BLK_DEV_IT821X is not set
  1720. +# CONFIG_BLK_DEV_NS87415 is not set
  1721. +# CONFIG_BLK_DEV_PDC202XX_OLD is not set
  1722. +# CONFIG_BLK_DEV_PDC202XX_NEW is not set
  1723. +# CONFIG_BLK_DEV_SVWKS is not set
  1724. +# CONFIG_BLK_DEV_SIIMAGE is not set
  1725. +# CONFIG_BLK_DEV_SLC90E66 is not set
  1726. +# CONFIG_BLK_DEV_TRM290 is not set
  1727. +# CONFIG_BLK_DEV_VIA82CXXX is not set
  1728. +# CONFIG_BLK_DEV_TC86C001 is not set
  1729. +
  1730. +#
  1731. +# Other IDE chipsets support
  1732. +#
  1733. +
  1734. +#
  1735. +# Note: most of these also require special kernel boot parameters
  1736. +#
  1737. +# CONFIG_BLK_DEV_4DRIVES is not set
  1738. +# CONFIG_BLK_DEV_ALI14XX is not set
  1739. +# CONFIG_BLK_DEV_DTC2278 is not set
  1740. +# CONFIG_BLK_DEV_HT6560B is not set
  1741. +# CONFIG_BLK_DEV_QD65XX is not set
  1742. +# CONFIG_BLK_DEV_UMC8672 is not set
  1743. +CONFIG_BLK_DEV_IDEDMA=y
  1744. +
  1745. +#
  1746. +# SCSI device support
  1747. +#
  1748. +CONFIG_SCSI_MOD=y
  1749. +# CONFIG_RAID_ATTRS is not set
  1750. +CONFIG_SCSI=y
  1751. +CONFIG_SCSI_DMA=y
  1752. +# CONFIG_SCSI_TGT is not set
  1753. +# CONFIG_SCSI_NETLINK is not set
  1754. +# CONFIG_SCSI_PROC_FS is not set
  1755. +
  1756. +#
  1757. +# SCSI support type (disk, tape, CD-ROM)
  1758. +#
  1759. +CONFIG_BLK_DEV_SD=y
  1760. +# CONFIG_CHR_DEV_ST is not set
  1761. +# CONFIG_CHR_DEV_OSST is not set
  1762. +# CONFIG_BLK_DEV_SR is not set
  1763. +# CONFIG_CHR_DEV_SG is not set
  1764. +# CONFIG_CHR_DEV_SCH is not set
  1765. +# CONFIG_SCSI_MULTI_LUN is not set
  1766. +# CONFIG_SCSI_CONSTANTS is not set
  1767. +# CONFIG_SCSI_LOGGING is not set
  1768. +# CONFIG_SCSI_SCAN_ASYNC is not set
  1769. +
  1770. +#
  1771. +# SCSI Transports
  1772. +#
  1773. +# CONFIG_SCSI_SPI_ATTRS is not set
  1774. +# CONFIG_SCSI_FC_ATTRS is not set
  1775. +# CONFIG_SCSI_ISCSI_ATTRS is not set
  1776. +# CONFIG_SCSI_SAS_LIBSAS is not set
  1777. +# CONFIG_SCSI_SRP_ATTRS is not set
  1778. +# CONFIG_SCSI_LOWLEVEL is not set
  1779. +# CONFIG_SCSI_DH is not set
  1780. +# CONFIG_SCSI_OSD_INITIATOR is not set
  1781. +# CONFIG_ATA is not set
  1782. +# CONFIG_MD is not set
  1783. +# CONFIG_FUSION is not set
  1784. +
  1785. +#
  1786. +# IEEE 1394 (FireWire) support
  1787. +#
  1788. +
  1789. +#
  1790. +# You can enable one or both FireWire driver stacks.
  1791. +#
  1792. +
  1793. +#
  1794. +# The newer stack is recommended.
  1795. +#
  1796. +# CONFIG_FIREWIRE is not set
  1797. +# CONFIG_IEEE1394 is not set
  1798. +# CONFIG_I2O is not set
  1799. +CONFIG_NETDEVICES=y
  1800. +# CONFIG_DUMMY is not set
  1801. +# CONFIG_BONDING is not set
  1802. +# CONFIG_MACVLAN is not set
  1803. +# CONFIG_EQUALIZER is not set
  1804. +# CONFIG_TUN is not set
  1805. +# CONFIG_VETH is not set
  1806. +# CONFIG_ARCNET is not set
  1807. +# CONFIG_PHYLIB is not set
  1808. +CONFIG_NET_ETHERNET=y
  1809. +CONFIG_MII=y
  1810. +# CONFIG_AX88796 is not set
  1811. +# CONFIG_HAPPYMEAL is not set
  1812. +# CONFIG_SUNGEM is not set
  1813. +# CONFIG_CASSINI is not set
  1814. +# CONFIG_NET_VENDOR_3COM is not set
  1815. +# CONFIG_NET_VENDOR_SMC is not set
  1816. +# CONFIG_SMC91X is not set
  1817. +# CONFIG_DM9000 is not set
  1818. +# CONFIG_ETHOC is not set
  1819. +# CONFIG_SMSC911X is not set
  1820. +# CONFIG_NET_VENDOR_RACAL is not set
  1821. +# CONFIG_DNET is not set
  1822. +# CONFIG_NET_TULIP is not set
  1823. +# CONFIG_AT1700 is not set
  1824. +# CONFIG_DEPCA is not set
  1825. +# CONFIG_HP100 is not set
  1826. +# CONFIG_NET_ISA is not set
  1827. +# CONFIG_IBM_NEW_EMAC_ZMII is not set
  1828. +# CONFIG_IBM_NEW_EMAC_RGMII is not set
  1829. +# CONFIG_IBM_NEW_EMAC_TAH is not set
  1830. +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
  1831. +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
  1832. +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
  1833. +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
  1834. +CONFIG_NET_PCI=y
  1835. +# CONFIG_PCNET32 is not set
  1836. +# CONFIG_AMD8111_ETH is not set
  1837. +# CONFIG_ADAPTEC_STARFIRE is not set
  1838. +# CONFIG_AC3200 is not set
  1839. +# CONFIG_KSZ884X_PCI is not set
  1840. +# CONFIG_APRICOT is not set
  1841. +# CONFIG_B44 is not set
  1842. +# CONFIG_FORCEDETH is not set
  1843. +# CONFIG_CS89x0 is not set
  1844. +# CONFIG_TC35815 is not set
  1845. +# CONFIG_E100 is not set
  1846. +# CONFIG_FEALNX is not set
  1847. +# CONFIG_NATSEMI is not set
  1848. +# CONFIG_NE2K_PCI is not set
  1849. +# CONFIG_8139CP is not set
  1850. +CONFIG_8139TOO=y
  1851. +CONFIG_8139TOO_PIO=y
  1852. +# CONFIG_8139TOO_TUNE_TWISTER is not set
  1853. +# CONFIG_8139TOO_8129 is not set
  1854. +# CONFIG_8139_OLD_RX_RESET is not set
  1855. +# CONFIG_R6040 is not set
  1856. +# CONFIG_SIS900 is not set
  1857. +# CONFIG_EPIC100 is not set
  1858. +# CONFIG_SMSC9420 is not set
  1859. +# CONFIG_SUNDANCE is not set
  1860. +# CONFIG_TLAN is not set
  1861. +# CONFIG_KS8842 is not set
  1862. +# CONFIG_KS8851_MLL is not set
  1863. +# CONFIG_VIA_RHINE is not set
  1864. +# CONFIG_SC92031 is not set
  1865. +# CONFIG_ATL2 is not set
  1866. +CONFIG_NETDEV_1000=y
  1867. +# CONFIG_ACENIC is not set
  1868. +# CONFIG_DL2K is not set
  1869. +# CONFIG_E1000 is not set
  1870. +# CONFIG_E1000E is not set
  1871. +# CONFIG_IP1000 is not set
  1872. +# CONFIG_IGB is not set
  1873. +# CONFIG_IGBVF is not set
  1874. +# CONFIG_NS83820 is not set
  1875. +# CONFIG_HAMACHI is not set
  1876. +# CONFIG_YELLOWFIN is not set
  1877. +CONFIG_R8169=y
  1878. +# CONFIG_SIS190 is not set
  1879. +# CONFIG_SKGE is not set
  1880. +# CONFIG_SKY2 is not set
  1881. +# CONFIG_VIA_VELOCITY is not set
  1882. +# CONFIG_TIGON3 is not set
  1883. +# CONFIG_BNX2 is not set
  1884. +# CONFIG_CNIC is not set
  1885. +# CONFIG_QLA3XXX is not set
  1886. +# CONFIG_ATL1 is not set
  1887. +# CONFIG_ATL1E is not set
  1888. +# CONFIG_ATL1C is not set
  1889. +# CONFIG_JME is not set
  1890. +# CONFIG_NETDEV_10000 is not set
  1891. +# CONFIG_TR is not set
  1892. +# CONFIG_WLAN is not set
  1893. +
  1894. +#
  1895. +# Enable WiMAX (Networking options) to see the WiMAX drivers
  1896. +#
  1897. +
  1898. +#
  1899. +# USB Network Adapters
  1900. +#
  1901. +# CONFIG_USB_CATC is not set
  1902. +# CONFIG_USB_KAWETH is not set
  1903. +# CONFIG_USB_PEGASUS is not set
  1904. +# CONFIG_USB_RTL8150 is not set
  1905. +# CONFIG_USB_USBNET is not set
  1906. +# CONFIG_USB_IPHETH is not set
  1907. +# CONFIG_WAN is not set
  1908. +# CONFIG_FDDI is not set
  1909. +# CONFIG_HIPPI is not set
  1910. +# CONFIG_PPP is not set
  1911. +# CONFIG_SLIP is not set
  1912. +# CONFIG_NET_FC is not set
  1913. +# CONFIG_NETCONSOLE is not set
  1914. +# CONFIG_NETPOLL is not set
  1915. +# CONFIG_NET_POLL_CONTROLLER is not set
  1916. +# CONFIG_VMXNET3 is not set
  1917. +# CONFIG_ISDN is not set
  1918. +# CONFIG_PHONE is not set
  1919. +
  1920. +#
  1921. +# Input device support
  1922. +#
  1923. +CONFIG_INPUT=y
  1924. +CONFIG_INPUT_FF_MEMLESS=y
  1925. +# CONFIG_INPUT_POLLDEV is not set
  1926. +# CONFIG_INPUT_SPARSEKMAP is not set
  1927. +
  1928. +#
  1929. +# Userland interfaces
  1930. +#
  1931. +CONFIG_INPUT_MOUSEDEV=y
  1932. +CONFIG_INPUT_MOUSEDEV_PSAUX=y
  1933. +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
  1934. +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
  1935. +# CONFIG_INPUT_JOYDEV is not set
  1936. +# CONFIG_INPUT_EVDEV is not set
  1937. +# CONFIG_INPUT_EVBUG is not set
  1938. +
  1939. +#
  1940. +# Input Device Drivers
  1941. +#
  1942. +CONFIG_INPUT_KEYBOARD=y
  1943. +CONFIG_KEYBOARD_ATKBD=y
  1944. +# CONFIG_KEYBOARD_LKKBD is not set
  1945. +# CONFIG_KEYBOARD_NEWTON is not set
  1946. +# CONFIG_KEYBOARD_OPENCORES is not set
  1947. +# CONFIG_KEYBOARD_STOWAWAY is not set
  1948. +# CONFIG_KEYBOARD_SUNKBD is not set
  1949. +# CONFIG_KEYBOARD_XTKBD is not set
  1950. +CONFIG_INPUT_MOUSE=y
  1951. +CONFIG_MOUSE_PS2=y
  1952. +# CONFIG_MOUSE_PS2_ALPS is not set
  1953. +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
  1954. +CONFIG_MOUSE_PS2_SYNAPTICS=y
  1955. +# CONFIG_MOUSE_PS2_TRACKPOINT is not set
  1956. +# CONFIG_MOUSE_PS2_ELANTECH is not set
  1957. +# CONFIG_MOUSE_PS2_SENTELIC is not set
  1958. +# CONFIG_MOUSE_PS2_TOUCHKIT is not set
  1959. +# CONFIG_MOUSE_SERIAL is not set
  1960. +# CONFIG_MOUSE_APPLETOUCH is not set
  1961. +# CONFIG_MOUSE_BCM5974 is not set
  1962. +# CONFIG_MOUSE_INPORT is not set
  1963. +# CONFIG_MOUSE_LOGIBM is not set
  1964. +# CONFIG_MOUSE_PC110PAD is not set
  1965. +# CONFIG_MOUSE_VSXXXAA is not set
  1966. +# CONFIG_INPUT_JOYSTICK is not set
  1967. +# CONFIG_INPUT_TABLET is not set
  1968. +# CONFIG_INPUT_TOUCHSCREEN is not set
  1969. +# CONFIG_INPUT_MISC is not set
  1970. +
  1971. +#
  1972. +# Hardware I/O ports
  1973. +#
  1974. +CONFIG_SERIO=y
  1975. +CONFIG_SERIO_I8042=y
  1976. +# CONFIG_SERIO_SERPORT is not set
  1977. +# CONFIG_SERIO_PCIPS2 is not set
  1978. +CONFIG_SERIO_LIBPS2=y
  1979. +# CONFIG_SERIO_RAW is not set
  1980. +# CONFIG_SERIO_ALTERA_PS2 is not set
  1981. +# CONFIG_GAMEPORT is not set
  1982. +
  1983. +#
  1984. +# Character devices
  1985. +#
  1986. +CONFIG_VT=y
  1987. +CONFIG_CONSOLE_TRANSLATIONS=y
  1988. +CONFIG_VT_CONSOLE=y
  1989. +CONFIG_HW_CONSOLE=y
  1990. +# CONFIG_VT_HW_CONSOLE_BINDING is not set
  1991. +# CONFIG_DEVKMEM is not set
  1992. +# CONFIG_SERIAL_NONSTANDARD is not set
  1993. +# CONFIG_NOZOMI is not set
  1994. +
  1995. +#
  1996. +# Serial drivers
  1997. +#
  1998. +CONFIG_SERIAL_8250=y
  1999. +CONFIG_SERIAL_8250_CONSOLE=y
  2000. +# CONFIG_SERIAL_8250_PCI is not set
  2001. +CONFIG_SERIAL_8250_NR_UARTS=4
  2002. +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
  2003. +# CONFIG_SERIAL_8250_EXTENDED is not set
  2004. +
  2005. +#
  2006. +# Non-8250 serial port support
  2007. +#
  2008. +CONFIG_SERIAL_CORE=y
  2009. +CONFIG_SERIAL_CORE_CONSOLE=y
  2010. +# CONFIG_SERIAL_JSM is not set
  2011. +# CONFIG_SERIAL_TIMBERDALE is not set
  2012. +CONFIG_UNIX98_PTYS=y
  2013. +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
  2014. +CONFIG_LEGACY_PTYS=y
  2015. +CONFIG_LEGACY_PTY_COUNT=16
  2016. +# CONFIG_IPMI_HANDLER is not set
  2017. +# CONFIG_HW_RANDOM is not set
  2018. +# CONFIG_DTLK is not set
  2019. +# CONFIG_R3964 is not set
  2020. +# CONFIG_APPLICOM is not set
  2021. +# CONFIG_RAW_DRIVER is not set
  2022. +# CONFIG_TCG_TPM is not set
  2023. +CONFIG_DEVPORT=y
  2024. +# CONFIG_I2C is not set
  2025. +# CONFIG_SPI is not set
  2026. +
  2027. +#
  2028. +# PPS support
  2029. +#
  2030. +# CONFIG_PPS is not set
  2031. +# CONFIG_W1 is not set
  2032. +# CONFIG_POWER_SUPPLY is not set
  2033. +# CONFIG_HWMON is not set
  2034. +# CONFIG_THERMAL is not set
  2035. +# CONFIG_WATCHDOG is not set
  2036. +CONFIG_SSB_POSSIBLE=y
  2037. +
  2038. +#
  2039. +# Sonics Silicon Backplane
  2040. +#
  2041. +# CONFIG_SSB is not set
  2042. +
  2043. +#
  2044. +# Multifunction device drivers
  2045. +#
  2046. +# CONFIG_MFD_CORE is not set
  2047. +# CONFIG_MFD_SM501 is not set
  2048. +# CONFIG_HTC_PASIC3 is not set
  2049. +# CONFIG_MFD_TMIO is not set
  2050. +# CONFIG_LPC_SCH is not set
  2051. +# CONFIG_REGULATOR is not set
  2052. +# CONFIG_MEDIA_SUPPORT is not set
  2053. +
  2054. +#
  2055. +# Graphics support
  2056. +#
  2057. +CONFIG_VGA_ARB=y
  2058. +CONFIG_VGA_ARB_MAX_GPUS=16
  2059. +# CONFIG_DRM is not set
  2060. +# CONFIG_VGASTATE is not set
  2061. +CONFIG_VIDEO_OUTPUT_CONTROL=y
  2062. +CONFIG_FB=y
  2063. +CONFIG_FIRMWARE_EDID=y
  2064. +# CONFIG_FB_DDC is not set
  2065. +CONFIG_FB_BOOT_VESA_SUPPORT=y
  2066. +CONFIG_FB_CFB_FILLRECT=y
  2067. +CONFIG_FB_CFB_COPYAREA=y
  2068. +CONFIG_FB_CFB_IMAGEBLIT=y
  2069. +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
  2070. +# CONFIG_FB_SYS_FILLRECT is not set
  2071. +# CONFIG_FB_SYS_COPYAREA is not set
  2072. +# CONFIG_FB_SYS_IMAGEBLIT is not set
  2073. +# CONFIG_FB_FOREIGN_ENDIAN is not set
  2074. +# CONFIG_FB_SYS_FOPS is not set
  2075. +# CONFIG_FB_SVGALIB is not set
  2076. +# CONFIG_FB_MACMODES is not set
  2077. +# CONFIG_FB_BACKLIGHT is not set
  2078. +CONFIG_FB_MODE_HELPERS=y
  2079. +CONFIG_FB_TILEBLITTING=y
  2080. +
  2081. +#
  2082. +# Frame buffer hardware drivers
  2083. +#
  2084. +# CONFIG_FB_CIRRUS is not set
  2085. +# CONFIG_FB_PM2 is not set
  2086. +# CONFIG_FB_CYBER2000 is not set
  2087. +# CONFIG_FB_ASILIANT is not set
  2088. +# CONFIG_FB_IMSTT is not set
  2089. +# CONFIG_FB_S1D13XXX is not set
  2090. +# CONFIG_FB_NVIDIA is not set
  2091. +# CONFIG_FB_RIVA is not set
  2092. +# CONFIG_FB_MATROX is not set
  2093. +# CONFIG_FB_RADEON is not set
  2094. +# CONFIG_FB_ATY128 is not set
  2095. +# CONFIG_FB_ATY is not set
  2096. +# CONFIG_FB_S3 is not set
  2097. +# CONFIG_FB_SAVAGE is not set
  2098. +CONFIG_FB_SIS=y
  2099. +CONFIG_FB_SIS_300=y
  2100. +CONFIG_FB_SIS_315=y
  2101. +# CONFIG_FB_VIA is not set
  2102. +# CONFIG_FB_NEOMAGIC is not set
  2103. +# CONFIG_FB_KYRO is not set
  2104. +# CONFIG_FB_3DFX is not set
  2105. +# CONFIG_FB_VOODOO1 is not set
  2106. +# CONFIG_FB_VT8623 is not set
  2107. +# CONFIG_FB_TRIDENT is not set
  2108. +# CONFIG_FB_ARK is not set
  2109. +# CONFIG_FB_PM3 is not set
  2110. +# CONFIG_FB_CARMINE is not set
  2111. +# CONFIG_FB_VIRTUAL is not set
  2112. +# CONFIG_FB_METRONOME is not set
  2113. +# CONFIG_FB_MB862XX is not set
  2114. +# CONFIG_FB_BROADSHEET is not set
  2115. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  2116. +# CONFIG_LCD_CLASS_DEVICE is not set
  2117. +CONFIG_BACKLIGHT_CLASS_DEVICE=y
  2118. +CONFIG_BACKLIGHT_GENERIC=y
  2119. +
  2120. +#
  2121. +# Display device support
  2122. +#
  2123. +# CONFIG_DISPLAY_SUPPORT is not set
  2124. +
  2125. +#
  2126. +# Console display driver support
  2127. +#
  2128. +# CONFIG_VGA_CONSOLE is not set
  2129. +# CONFIG_MDA_CONSOLE is not set
  2130. +CONFIG_DUMMY_CONSOLE=y
  2131. +CONFIG_FRAMEBUFFER_CONSOLE=y
  2132. +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
  2133. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  2134. +CONFIG_FONTS=y
  2135. +CONFIG_FONT_8x8=y
  2136. +CONFIG_FONT_8x16=y
  2137. +CONFIG_FONT_6x11=y
  2138. +CONFIG_FONT_7x14=y
  2139. +CONFIG_FONT_PEARL_8x8=y
  2140. +CONFIG_FONT_ACORN_8x8=y
  2141. +CONFIG_FONT_MINI_4x6=y
  2142. +CONFIG_FONT_SUN8x16=y
  2143. +CONFIG_FONT_SUN12x22=y
  2144. +CONFIG_FONT_10x18=y
  2145. +CONFIG_LOGO=y
  2146. +# CONFIG_LOGO_LINUX_MONO is not set
  2147. +# CONFIG_LOGO_LINUX_VGA16 is not set
  2148. +CONFIG_LOGO_LINUX_CLUT224=y
  2149. +# CONFIG_SOUND is not set
  2150. +CONFIG_HID_SUPPORT=y
  2151. +CONFIG_HID=y
  2152. +CONFIG_HIDRAW=y
  2153. +
  2154. +#
  2155. +# USB Input Devices
  2156. +#
  2157. +CONFIG_USB_HID=y
  2158. +# CONFIG_HID_PID is not set
  2159. +CONFIG_USB_HIDDEV=y
  2160. +
  2161. +#
  2162. +# Special HID drivers
  2163. +#
  2164. +# CONFIG_HID_3M_PCT is not set
  2165. +CONFIG_HID_A4TECH=y
  2166. +CONFIG_HID_APPLE=y
  2167. +CONFIG_HID_BELKIN=y
  2168. +CONFIG_HID_CHERRY=y
  2169. +CONFIG_HID_CHICONY=y
  2170. +CONFIG_HID_CYPRESS=y
  2171. +CONFIG_HID_DRAGONRISE=y
  2172. +CONFIG_DRAGONRISE_FF=y
  2173. +CONFIG_HID_EZKEY=y
  2174. +CONFIG_HID_KYE=y
  2175. +CONFIG_HID_GYRATION=y
  2176. +CONFIG_HID_TWINHAN=y
  2177. +CONFIG_HID_KENSINGTON=y
  2178. +CONFIG_HID_LOGITECH=y
  2179. +CONFIG_LOGITECH_FF=y
  2180. +CONFIG_LOGIRUMBLEPAD2_FF=y
  2181. +# CONFIG_LOGIG940_FF is not set
  2182. +CONFIG_HID_MICROSOFT=y
  2183. +# CONFIG_HID_MOSART is not set
  2184. +CONFIG_HID_MONTEREY=y
  2185. +CONFIG_HID_NTRIG=y
  2186. +# CONFIG_HID_ORTEK is not set
  2187. +CONFIG_HID_PANTHERLORD=y
  2188. +CONFIG_PANTHERLORD_FF=y
  2189. +CONFIG_HID_PETALYNX=y
  2190. +# CONFIG_HID_QUANTA is not set
  2191. +CONFIG_HID_SAMSUNG=y
  2192. +CONFIG_HID_SONY=y
  2193. +# CONFIG_HID_STANTUM is not set
  2194. +CONFIG_HID_SUNPLUS=y
  2195. +CONFIG_HID_GREENASIA=y
  2196. +CONFIG_GREENASIA_FF=y
  2197. +CONFIG_HID_SMARTJOYPLUS=y
  2198. +CONFIG_SMARTJOYPLUS_FF=y
  2199. +CONFIG_HID_TOPSEED=y
  2200. +CONFIG_HID_THRUSTMASTER=y
  2201. +CONFIG_THRUSTMASTER_FF=y
  2202. +CONFIG_HID_ZEROPLUS=y
  2203. +CONFIG_ZEROPLUS_FF=y
  2204. +CONFIG_USB_SUPPORT=y
  2205. +CONFIG_USB_ARCH_HAS_HCD=y
  2206. +CONFIG_USB_ARCH_HAS_OHCI=y
  2207. +CONFIG_USB_ARCH_HAS_EHCI=y
  2208. +CONFIG_USB=y
  2209. +# CONFIG_USB_DEBUG is not set
  2210. +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
  2211. +
  2212. +#
  2213. +# Miscellaneous USB options
  2214. +#
  2215. +# CONFIG_USB_DEVICEFS is not set
  2216. +# CONFIG_USB_DEVICE_CLASS is not set
  2217. +CONFIG_USB_DYNAMIC_MINORS=y
  2218. +# CONFIG_USB_OTG is not set
  2219. +CONFIG_USB_OTG_WHITELIST=y
  2220. +# CONFIG_USB_OTG_BLACKLIST_HUB is not set
  2221. +CONFIG_USB_MON=y
  2222. +# CONFIG_USB_WUSB is not set
  2223. +# CONFIG_USB_WUSB_CBAF is not set
  2224. +
  2225. +#
  2226. +# USB Host Controller Drivers
  2227. +#
  2228. +# CONFIG_USB_C67X00_HCD is not set
  2229. +# CONFIG_USB_XHCI_HCD is not set
  2230. +CONFIG_USB_EHCI_HCD=y
  2231. +CONFIG_USB_EHCI_ROOT_HUB_TT=y
  2232. +# CONFIG_USB_EHCI_TT_NEWSCHED is not set
  2233. +# CONFIG_USB_OXU210HP_HCD is not set
  2234. +# CONFIG_USB_ISP116X_HCD is not set
  2235. +# CONFIG_USB_ISP1760_HCD is not set
  2236. +# CONFIG_USB_ISP1362_HCD is not set
  2237. +CONFIG_USB_OHCI_HCD=y
  2238. +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
  2239. +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
  2240. +CONFIG_USB_OHCI_LITTLE_ENDIAN=y
  2241. +# CONFIG_USB_UHCI_HCD is not set
  2242. +# CONFIG_USB_SL811_HCD is not set
  2243. +# CONFIG_USB_R8A66597_HCD is not set
  2244. +# CONFIG_USB_WHCI_HCD is not set
  2245. +# CONFIG_USB_HWA_HCD is not set
  2246. +
  2247. +#
  2248. +# USB Device Class drivers
  2249. +#
  2250. +# CONFIG_USB_ACM is not set
  2251. +# CONFIG_USB_PRINTER is not set
  2252. +# CONFIG_USB_WDM is not set
  2253. +# CONFIG_USB_TMC is not set
  2254. +
  2255. +#
  2256. +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
  2257. +#
  2258. +
  2259. +#
  2260. +# also be needed; see USB_STORAGE Help for more info
  2261. +#
  2262. +CONFIG_USB_STORAGE=y
  2263. +# CONFIG_USB_STORAGE_DEBUG is not set
  2264. +# CONFIG_USB_STORAGE_DATAFAB is not set
  2265. +# CONFIG_USB_STORAGE_FREECOM is not set
  2266. +# CONFIG_USB_STORAGE_ISD200 is not set
  2267. +# CONFIG_USB_STORAGE_USBAT is not set
  2268. +# CONFIG_USB_STORAGE_SDDR09 is not set
  2269. +# CONFIG_USB_STORAGE_SDDR55 is not set
  2270. +# CONFIG_USB_STORAGE_JUMPSHOT is not set
  2271. +# CONFIG_USB_STORAGE_ALAUDA is not set
  2272. +# CONFIG_USB_STORAGE_ONETOUCH is not set
  2273. +# CONFIG_USB_STORAGE_KARMA is not set
  2274. +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
  2275. +CONFIG_USB_LIBUSUAL=y
  2276. +
  2277. +#
  2278. +# USB Imaging devices
  2279. +#
  2280. +# CONFIG_USB_MDC800 is not set
  2281. +# CONFIG_USB_MICROTEK is not set
  2282. +
  2283. +#
  2284. +# USB port drivers
  2285. +#
  2286. +# CONFIG_USB_SERIAL is not set
  2287. +
  2288. +#
  2289. +# USB Miscellaneous drivers
  2290. +#
  2291. +# CONFIG_USB_EMI62 is not set
  2292. +# CONFIG_USB_EMI26 is not set
  2293. +# CONFIG_USB_ADUTUX is not set
  2294. +# CONFIG_USB_SEVSEG is not set
  2295. +# CONFIG_USB_RIO500 is not set
  2296. +# CONFIG_USB_LEGOTOWER is not set
  2297. +# CONFIG_USB_LCD is not set
  2298. +# CONFIG_USB_LED is not set
  2299. +# CONFIG_USB_CYPRESS_CY7C63 is not set
  2300. +# CONFIG_USB_CYTHERM is not set
  2301. +# CONFIG_USB_IDMOUSE is not set
  2302. +# CONFIG_USB_FTDI_ELAN is not set
  2303. +# CONFIG_USB_APPLEDISPLAY is not set
  2304. +# CONFIG_USB_SISUSBVGA is not set
  2305. +# CONFIG_USB_LD is not set
  2306. +# CONFIG_USB_TRANCEVIBRATOR is not set
  2307. +# CONFIG_USB_IOWARRIOR is not set
  2308. +# CONFIG_USB_TEST is not set
  2309. +# CONFIG_USB_ISIGHTFW is not set
  2310. +# CONFIG_USB_GADGET is not set
  2311. +
  2312. +#
  2313. +# OTG and related infrastructure
  2314. +#
  2315. +# CONFIG_NOP_USB_XCEIV is not set
  2316. +# CONFIG_UWB is not set
  2317. +# CONFIG_MMC is not set
  2318. +# CONFIG_MEMSTICK is not set
  2319. +# CONFIG_NEW_LEDS is not set
  2320. +# CONFIG_ACCESSIBILITY is not set
  2321. +# CONFIG_INFINIBAND is not set
  2322. +CONFIG_RTC_LIB=y
  2323. +CONFIG_RTC_CLASS=y
  2324. +CONFIG_RTC_HCTOSYS=y
  2325. +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
  2326. +# CONFIG_RTC_DEBUG is not set
  2327. +
  2328. +#
  2329. +# RTC interfaces
  2330. +#
  2331. +CONFIG_RTC_INTF_SYSFS=y
  2332. +CONFIG_RTC_INTF_PROC=y
  2333. +CONFIG_RTC_INTF_DEV=y
  2334. +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
  2335. +# CONFIG_RTC_DRV_TEST is not set
  2336. +
  2337. +#
  2338. +# SPI RTC drivers
  2339. +#
  2340. +
  2341. +#
  2342. +# Platform RTC drivers
  2343. +#
  2344. +CONFIG_RTC_DRV_CMOS=y
  2345. +# CONFIG_RTC_DRV_DS1286 is not set
  2346. +# CONFIG_RTC_DRV_DS1511 is not set
  2347. +# CONFIG_RTC_DRV_DS1553 is not set
  2348. +# CONFIG_RTC_DRV_DS1742 is not set
  2349. +# CONFIG_RTC_DRV_STK17TA8 is not set
  2350. +# CONFIG_RTC_DRV_M48T86 is not set
  2351. +# CONFIG_RTC_DRV_M48T35 is not set
  2352. +# CONFIG_RTC_DRV_M48T59 is not set
  2353. +# CONFIG_RTC_DRV_MSM6242 is not set
  2354. +# CONFIG_RTC_DRV_BQ4802 is not set
  2355. +# CONFIG_RTC_DRV_RP5C01 is not set
  2356. +# CONFIG_RTC_DRV_V3020 is not set
  2357. +
  2358. +#
  2359. +# on-CPU RTC drivers
  2360. +#
  2361. +# CONFIG_DMADEVICES is not set
  2362. +# CONFIG_AUXDISPLAY is not set
  2363. +# CONFIG_UIO is not set
  2364. +
  2365. +#
  2366. +# TI VLYNQ
  2367. +#
  2368. +CONFIG_STAGING=y
  2369. +# CONFIG_STAGING_EXCLUDE_BUILD is not set
  2370. +# CONFIG_ET131X is not set
  2371. +# CONFIG_USB_IP_COMMON is not set
  2372. +# CONFIG_ECHO is not set
  2373. +# CONFIG_ASUS_OLED is not set
  2374. +# CONFIG_TRANZPORT is not set
  2375. +
  2376. +#
  2377. +# Qualcomm MSM Camera And Video
  2378. +#
  2379. +
  2380. +#
  2381. +# Camera Sensor Selection
  2382. +#
  2383. +# CONFIG_INPUT_GPIO is not set
  2384. +# CONFIG_POHMELFS is not set
  2385. +# CONFIG_FB_UDL is not set
  2386. +# CONFIG_VME_BUS is not set
  2387. +
  2388. +#
  2389. +# RAR Register Driver
  2390. +#
  2391. +# CONFIG_RAR_REGISTER is not set
  2392. +# CONFIG_IIO is not set
  2393. +# CONFIG_RAMZSWAP is not set
  2394. +# CONFIG_BATMAN_ADV is not set
  2395. +# CONFIG_STRIP is not set
  2396. +CONFIG_FB_SM7XX=y
  2397. +# CONFIG_DT3155 is not set
  2398. +# CONFIG_CRYSTALHD is not set
  2399. +CONFIG_MIPS_PLATFORM_DEVICES=y
  2400. +# CONFIG_LEMOTE_YEELOONG2F is not set
  2401. +# CONFIG_LEMOTE_LYNLOONG2F is not set
  2402. +
  2403. +#
  2404. +# File systems
  2405. +#
  2406. +CONFIG_EXT2_FS=y
  2407. +CONFIG_EXT2_FS_XATTR=y
  2408. +# CONFIG_EXT2_FS_POSIX_ACL is not set
  2409. +# CONFIG_EXT2_FS_SECURITY is not set
  2410. +# CONFIG_EXT2_FS_XIP is not set
  2411. +CONFIG_EXT3_FS=y
  2412. +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
  2413. +CONFIG_EXT3_FS_XATTR=y
  2414. +# CONFIG_EXT3_FS_POSIX_ACL is not set
  2415. +# CONFIG_EXT3_FS_SECURITY is not set
  2416. +# CONFIG_EXT4_FS is not set
  2417. +CONFIG_JBD=y
  2418. +CONFIG_FS_MBCACHE=y
  2419. +# CONFIG_REISERFS_FS is not set
  2420. +# CONFIG_JFS_FS is not set
  2421. +# CONFIG_FS_POSIX_ACL is not set
  2422. +# CONFIG_XFS_FS is not set
  2423. +# CONFIG_GFS2_FS is not set
  2424. +# CONFIG_OCFS2_FS is not set
  2425. +# CONFIG_BTRFS_FS is not set
  2426. +# CONFIG_NILFS2_FS is not set
  2427. +CONFIG_FILE_LOCKING=y
  2428. +CONFIG_FSNOTIFY=y
  2429. +CONFIG_DNOTIFY=y
  2430. +CONFIG_INOTIFY=y
  2431. +CONFIG_INOTIFY_USER=y
  2432. +# CONFIG_QUOTA is not set
  2433. +# CONFIG_AUTOFS_FS is not set
  2434. +# CONFIG_AUTOFS4_FS is not set
  2435. +# CONFIG_FUSE_FS is not set
  2436. +
  2437. +#
  2438. +# Caches
  2439. +#
  2440. +# CONFIG_FSCACHE is not set
  2441. +
  2442. +#
  2443. +# CD-ROM/DVD Filesystems
  2444. +#
  2445. +# CONFIG_ISO9660_FS is not set
  2446. +# CONFIG_UDF_FS is not set
  2447. +
  2448. +#
  2449. +# DOS/FAT/NT Filesystems
  2450. +#
  2451. +CONFIG_FAT_FS=y
  2452. +CONFIG_MSDOS_FS=y
  2453. +CONFIG_VFAT_FS=y
  2454. +CONFIG_FAT_DEFAULT_CODEPAGE=437
  2455. +CONFIG_FAT_DEFAULT_IOCHARSET="utf-8"
  2456. +# CONFIG_NTFS_FS is not set
  2457. +
  2458. +#
  2459. +# Pseudo filesystems
  2460. +#
  2461. +CONFIG_PROC_FS=y
  2462. +CONFIG_PROC_KCORE=y
  2463. +CONFIG_PROC_SYSCTL=y
  2464. +CONFIG_PROC_PAGE_MONITOR=y
  2465. +CONFIG_SYSFS=y
  2466. +CONFIG_TMPFS=y
  2467. +# CONFIG_TMPFS_POSIX_ACL is not set
  2468. +# CONFIG_HUGETLB_PAGE is not set
  2469. +# CONFIG_CONFIGFS_FS is not set
  2470. +# CONFIG_MISC_FILESYSTEMS is not set
  2471. +# CONFIG_NETWORK_FILESYSTEMS is not set
  2472. +
  2473. +#
  2474. +# Partition Types
  2475. +#
  2476. +# CONFIG_PARTITION_ADVANCED is not set
  2477. +CONFIG_MSDOS_PARTITION=y
  2478. +CONFIG_NLS=y
  2479. +CONFIG_NLS_DEFAULT="utf8"
  2480. +CONFIG_NLS_CODEPAGE_437=y
  2481. +# CONFIG_NLS_CODEPAGE_737 is not set
  2482. +# CONFIG_NLS_CODEPAGE_775 is not set
  2483. +# CONFIG_NLS_CODEPAGE_850 is not set
  2484. +# CONFIG_NLS_CODEPAGE_852 is not set
  2485. +# CONFIG_NLS_CODEPAGE_855 is not set
  2486. +# CONFIG_NLS_CODEPAGE_857 is not set
  2487. +# CONFIG_NLS_CODEPAGE_860 is not set
  2488. +# CONFIG_NLS_CODEPAGE_861 is not set
  2489. +# CONFIG_NLS_CODEPAGE_862 is not set
  2490. +# CONFIG_NLS_CODEPAGE_863 is not set
  2491. +# CONFIG_NLS_CODEPAGE_864 is not set
  2492. +# CONFIG_NLS_CODEPAGE_865 is not set
  2493. +# CONFIG_NLS_CODEPAGE_866 is not set
  2494. +# CONFIG_NLS_CODEPAGE_869 is not set
  2495. +# CONFIG_NLS_CODEPAGE_936 is not set
  2496. +# CONFIG_NLS_CODEPAGE_950 is not set
  2497. +# CONFIG_NLS_CODEPAGE_932 is not set
  2498. +# CONFIG_NLS_CODEPAGE_949 is not set
  2499. +# CONFIG_NLS_CODEPAGE_874 is not set
  2500. +# CONFIG_NLS_ISO8859_8 is not set
  2501. +# CONFIG_NLS_CODEPAGE_1250 is not set
  2502. +# CONFIG_NLS_CODEPAGE_1251 is not set
  2503. +CONFIG_NLS_ASCII=y
  2504. +# CONFIG_NLS_ISO8859_1 is not set
  2505. +# CONFIG_NLS_ISO8859_2 is not set
  2506. +# CONFIG_NLS_ISO8859_3 is not set
  2507. +# CONFIG_NLS_ISO8859_4 is not set
  2508. +# CONFIG_NLS_ISO8859_5 is not set
  2509. +# CONFIG_NLS_ISO8859_6 is not set
  2510. +# CONFIG_NLS_ISO8859_7 is not set
  2511. +# CONFIG_NLS_ISO8859_9 is not set
  2512. +# CONFIG_NLS_ISO8859_13 is not set
  2513. +# CONFIG_NLS_ISO8859_14 is not set
  2514. +# CONFIG_NLS_ISO8859_15 is not set
  2515. +# CONFIG_NLS_KOI8_R is not set
  2516. +# CONFIG_NLS_KOI8_U is not set
  2517. +CONFIG_NLS_UTF8=y
  2518. +# CONFIG_DLM is not set
  2519. +
  2520. +#
  2521. +# Kernel hacking
  2522. +#
  2523. +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
  2524. +CONFIG_PRINTK_TIME=y
  2525. +CONFIG_ENABLE_WARN_DEPRECATED=y
  2526. +CONFIG_ENABLE_MUST_CHECK=y
  2527. +CONFIG_FRAME_WARN=1024
  2528. +# CONFIG_MAGIC_SYSRQ is not set
  2529. +CONFIG_STRIP_ASM_SYMS=y
  2530. +# CONFIG_UNUSED_SYMBOLS is not set
  2531. +# CONFIG_DEBUG_FS is not set
  2532. +# CONFIG_HEADERS_CHECK is not set
  2533. +# CONFIG_DEBUG_KERNEL is not set
  2534. +# CONFIG_SLUB_DEBUG_ON is not set
  2535. +# CONFIG_SLUB_STATS is not set
  2536. +# CONFIG_DEBUG_MEMORY_INIT is not set
  2537. +# CONFIG_RCU_CPU_STALL_DETECTOR is not set
  2538. +CONFIG_SYSCTL_SYSCALL_CHECK=y
  2539. +CONFIG_HAVE_FUNCTION_TRACER=y
  2540. +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
  2541. +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
  2542. +CONFIG_HAVE_DYNAMIC_FTRACE=y
  2543. +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
  2544. +CONFIG_TRACING_SUPPORT=y
  2545. +# CONFIG_FTRACE is not set
  2546. +# CONFIG_SAMPLES is not set
  2547. +CONFIG_HAVE_ARCH_KGDB=y
  2548. +# CONFIG_EARLY_PRINTK is not set
  2549. +# CONFIG_CMDLINE_BOOL is not set
  2550. +
  2551. +#
  2552. +# Security options
  2553. +#
  2554. +# CONFIG_KEYS is not set
  2555. +# CONFIG_SECURITY is not set
  2556. +# CONFIG_SECURITYFS is not set
  2557. +# CONFIG_DEFAULT_SECURITY_SELINUX is not set
  2558. +# CONFIG_DEFAULT_SECURITY_SMACK is not set
  2559. +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
  2560. +CONFIG_DEFAULT_SECURITY_DAC=y
  2561. +CONFIG_DEFAULT_SECURITY=""
  2562. +# CONFIG_CRYPTO is not set
  2563. +# CONFIG_BINARY_PRINTF is not set
  2564. +
  2565. +#
  2566. +# Library routines
  2567. +#
  2568. +CONFIG_BITREVERSE=y
  2569. +CONFIG_GENERIC_FIND_LAST_BIT=y
  2570. +# CONFIG_CRC_CCITT is not set
  2571. +# CONFIG_CRC16 is not set
  2572. +# CONFIG_CRC_T10DIF is not set
  2573. +# CONFIG_CRC_ITU_T is not set
  2574. +CONFIG_CRC32=y
  2575. +# CONFIG_CRC7 is not set
  2576. +# CONFIG_LIBCRC32C is not set
  2577. +CONFIG_AUDIT_GENERIC=y
  2578. +CONFIG_ZLIB_INFLATE=y
  2579. +CONFIG_LZO_DECOMPRESS=y
  2580. +CONFIG_DECOMPRESS_GZIP=y
  2581. +CONFIG_DECOMPRESS_BZIP2=y
  2582. +CONFIG_DECOMPRESS_LZMA=y
  2583. +CONFIG_DECOMPRESS_LZO=y
  2584. +CONFIG_HAS_IOMEM=y
  2585. +CONFIG_HAS_IOPORT=y
  2586. +CONFIG_HAS_DMA=y
  2587. +CONFIG_NLATTR=y
  2588. diff -Nur linux-2.6.34.orig/arch/mips/include/asm/dma-mapping.h linux-loongson/arch/mips/include/asm/dma-mapping.h
  2589. --- linux-2.6.34.orig/arch/mips/include/asm/dma-mapping.h 2010-05-16 23:17:36.000000000 +0200
  2590. +++ linux-loongson/arch/mips/include/asm/dma-mapping.h 2010-05-27 18:12:28.622215656 +0200
  2591. @@ -74,4 +74,8 @@
  2592. extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
  2593. enum dma_data_direction direction);
  2594. +#define ARCH_HAS_DMA_MMAP_COHERENT
  2595. +extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
  2596. + void *cpu_addr, dma_addr_t handle, size_t size);
  2597. +
  2598. #endif /* _ASM_DMA_MAPPING_H */
  2599. diff -Nur linux-2.6.34.orig/arch/mips/include/asm/ftrace.h linux-loongson/arch/mips/include/asm/ftrace.h
  2600. --- linux-2.6.34.orig/arch/mips/include/asm/ftrace.h 2010-05-16 23:17:36.000000000 +0200
  2601. +++ linux-loongson/arch/mips/include/asm/ftrace.h 2010-05-27 18:12:28.642214121 +0200
  2602. @@ -3,7 +3,7 @@
  2603. * License. See the file "COPYING" in the main directory of this archive for
  2604. * more details.
  2605. *
  2606. - * Copyright (C) 2009 DSLab, Lanzhou University, China
  2607. + * Copyright (C) 2009, 2010 DSLab, Lanzhou University, China
  2608. * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2609. */
  2610. @@ -19,6 +19,14 @@
  2611. extern void _mcount(void);
  2612. #define mcount _mcount
  2613. +/*
  2614. + * If the Instruction Pointer is in module space (0xc0000000), return true;
  2615. + * otherwise, it is in kernel space (0x80000000), return false.
  2616. + *
  2617. + * FIXME: This may not work in some cases.
  2618. + */
  2619. +#define in_module(ip) (unlikely((ip) & 0x40000000))
  2620. +
  2621. #define safe_load(load, src, dst, error) \
  2622. do { \
  2623. asm volatile ( \
  2624. @@ -83,8 +91,8 @@
  2625. struct dyn_arch_ftrace {
  2626. };
  2627. -
  2628. #endif /* CONFIG_DYNAMIC_FTRACE */
  2629. +
  2630. #endif /* __ASSEMBLY__ */
  2631. #endif /* CONFIG_FUNCTION_TRACER */
  2632. #endif /* _ASM_MIPS_FTRACE_H */
  2633. 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
  2634. --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-05-16 23:17:36.000000000 +0200
  2635. +++ linux-loongson/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h 2010-05-27 18:12:28.712212405 +0200
  2636. @@ -52,6 +52,8 @@
  2637. #define cpu_has_tx39_cache 0
  2638. #define cpu_has_userlocal 0
  2639. #define cpu_has_vce 0
  2640. +#define cpu_has_veic 0
  2641. +#define cpu_has_vint 0
  2642. #define cpu_has_vtag_icache 0
  2643. #define cpu_has_watch 1
  2644. 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
  2645. --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-05-16 23:17:36.000000000 +0200
  2646. +++ linux-loongson/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h 2010-05-27 18:12:28.712212405 +0200
  2647. @@ -255,21 +255,12 @@
  2648. * IDE STANDARD
  2649. */
  2650. #define IDE_CAP 0x00
  2651. -#define IDE_CONFIG 0x01
  2652. -#define IDE_SMI 0x02
  2653. -#define IDE_ERROR 0x03
  2654. -#define IDE_PM 0x04
  2655. -#define IDE_DIAG 0x05
  2656. -
  2657. -/*
  2658. - * IDE SPEC.
  2659. - */
  2660. #define IDE_IO_BAR 0x08
  2661. #define IDE_CFG 0x10
  2662. #define IDE_DTC 0x12
  2663. #define IDE_CAST 0x13
  2664. #define IDE_ETC 0x14
  2665. -#define IDE_INTERNAL_PM 0x15
  2666. +#define IDE_PM 0x15
  2667. /*
  2668. * ACC STANDARD
  2669. @@ -301,5 +292,40 @@
  2670. /* GPIO : I/O SPACE; REG : 32BITS */
  2671. #define GPIOL_OUT_VAL 0x00
  2672. #define GPIOL_OUT_EN 0x04
  2673. +#define GPIOL_OUT_AUX1_SEL 0x10
  2674. +/* SMB : I/O SPACE, REG : 8BITS WIDTH */
  2675. +#define SMB_SDA 0x00
  2676. +#define SMB_STS 0x01
  2677. +#define SMB_STS_SLVSTP (1 << 7)
  2678. +#define SMB_STS_SDAST (1 << 6)
  2679. +#define SMB_STS_BER (1 << 5)
  2680. +#define SMB_STS_NEGACK (1 << 4)
  2681. +#define SMB_STS_STASTR (1 << 3)
  2682. +#define SMB_STS_NMATCH (1 << 2)
  2683. +#define SMB_STS_MASTER (1 << 1)
  2684. +#define SMB_STS_XMIT (1 << 0)
  2685. +#define SMB_CTRL_STS 0x02
  2686. +#define SMB_CSTS_TGSTL (1 << 5)
  2687. +#define SMB_CSTS_TSDA (1 << 4)
  2688. +#define SMB_CSTS_GCMTCH (1 << 3)
  2689. +#define SMB_CSTS_MATCH (1 << 2)
  2690. +#define SMB_CSTS_BB (1 << 1)
  2691. +#define SMB_CSTS_BUSY (1 << 0)
  2692. +#define SMB_CTRL1 0x03
  2693. +#define SMB_CTRL1_STASTRE (1 << 7)
  2694. +#define SMB_CTRL1_NMINTE (1 << 6)
  2695. +#define SMB_CTRL1_GCMEN (1 << 5)
  2696. +#define SMB_CTRL1_ACK (1 << 4)
  2697. +#define SMB_CTRL1_RSVD (1 << 3)
  2698. +#define SMB_CTRL1_INTEN (1 << 2)
  2699. +#define SMB_CTRL1_STOP (1 << 1)
  2700. +#define SMB_CTRL1_START (1 << 0)
  2701. +#define SMB_ADDR 0x04
  2702. +#define SMB_ADDR_SAEN (1 << 7)
  2703. +#define SMB_CONTROLLER_ADDR (0xef << 0)
  2704. +#define SMB_CTRL2 0x05
  2705. +#define SMB_FREQ (0x20 << 1)
  2706. +#define SMB_ENABLE (0x01 << 0)
  2707. +#define SMB_CTRL3 0x06
  2708. #endif /* _CS5536_H */
  2709. 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
  2710. --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-05-16 23:17:36.000000000 +0200
  2711. +++ linux-loongson/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h 2010-05-27 18:12:28.712212405 +0200
  2712. @@ -32,4 +32,9 @@
  2713. #define MFGPT0_CNT (MFGPT_BASE + 4)
  2714. #define MFGPT0_SETUP (MFGPT_BASE + 6)
  2715. +#define MFGPT2_CMP1 (MFGPT_BASE + 0x10)
  2716. +#define MFGPT2_CMP2 (MFGPT_BASE + 0x12)
  2717. +#define MFGPT2_CNT (MFGPT_BASE + 0x14)
  2718. +#define MFGPT2_SETUP (MFGPT_BASE + 0x16)
  2719. +
  2720. #endif /*!_CS5536_MFGPT_H */
  2721. 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
  2722. --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
  2723. +++ linux-loongson/arch/mips/include/asm/mach-loongson/ec_kb3310b.h 2010-05-27 18:12:28.712212405 +0200
  2724. @@ -0,0 +1,191 @@
  2725. +/*
  2726. + * KB3310B Embedded Controller
  2727. + *
  2728. + * Copyright (C) 2008 Lemote Inc.
  2729. + * Author: liujl <liujl@lemote.com>, 2008-03-14
  2730. + * Copyright (C) 2009 Lemote Inc.
  2731. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  2732. + *
  2733. + * This program is free software; you can redistribute it and/or modify
  2734. + * it under the terms of the GNU General Public License as published by
  2735. + * the Free Software Foundation; either version 2 of the License, or
  2736. + * (at your option) any later version.
  2737. + */
  2738. +
  2739. +#ifndef _EC_KB3310B_H
  2740. +#define _EC_KB3310B_H
  2741. +
  2742. +extern unsigned char ec_read(unsigned short addr);
  2743. +extern void ec_write(unsigned short addr, unsigned char val);
  2744. +extern int ec_query_seq(unsigned char cmd);
  2745. +extern int ec_query_event_num(void);
  2746. +extern int ec_get_event_num(void);
  2747. +
  2748. +typedef int (*sci_handler) (int status);
  2749. +extern sci_handler yeeloong_report_lid_status;
  2750. +
  2751. +#define SCI_IRQ_NUM 0x0A
  2752. +
  2753. +/*
  2754. + * The following registers are determined by the EC index configuration.
  2755. + * 1, fill the PORT_HIGH as EC register high part.
  2756. + * 2, fill the PORT_LOW as EC register low part.
  2757. + * 3, fill the PORT_DATA as EC register write data or get the data from it.
  2758. + */
  2759. +#define EC_IO_PORT_HIGH 0x0381
  2760. +#define EC_IO_PORT_LOW 0x0382
  2761. +#define EC_IO_PORT_DATA 0x0383
  2762. +
  2763. +/*
  2764. + * EC delay time is 500us for register and status access
  2765. + */
  2766. +#define EC_REG_DELAY 500 /* unit : us */
  2767. +#define EC_CMD_TIMEOUT 0x1000
  2768. +
  2769. +/*
  2770. + * EC access port for SCI communication
  2771. + */
  2772. +#define EC_CMD_PORT 0x66
  2773. +#define EC_STS_PORT 0x66
  2774. +#define EC_DAT_PORT 0x62
  2775. +#define CMD_INIT_IDLE_MODE 0xdd
  2776. +#define CMD_EXIT_IDLE_MODE 0xdf
  2777. +#define CMD_INIT_RESET_MODE 0xd8
  2778. +#define CMD_REBOOT_SYSTEM 0x8c
  2779. +#define CMD_GET_EVENT_NUM 0x84
  2780. +#define CMD_PROGRAM_PIECE 0xda
  2781. +
  2782. +/* Temperature & Fan registers */
  2783. +#define REG_TEMPERATURE_VALUE 0xF458
  2784. +#define REG_FAN_AUTO_MAN_SWITCH 0xF459
  2785. +#define BIT_FAN_AUTO 0
  2786. +#define BIT_FAN_MANUAL 1
  2787. +#define REG_FAN_CONTROL 0xF4D2
  2788. +#define BIT_FAN_CONTROL_ON (1 << 0)
  2789. +#define BIT_FAN_CONTROL_OFF (0 << 0)
  2790. +#define REG_FAN_STATUS 0xF4DA
  2791. +#define BIT_FAN_STATUS_ON (1 << 0)
  2792. +#define BIT_FAN_STATUS_OFF (0 << 0)
  2793. +#define REG_FAN_SPEED_HIGH 0xFE22
  2794. +#define REG_FAN_SPEED_LOW 0xFE23
  2795. +#define REG_FAN_SPEED_LEVEL 0xF4CC
  2796. +/* Fan speed divider */
  2797. +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
  2798. +
  2799. +/* Battery registers */
  2800. +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
  2801. +#define REG_BAT_DESIGN_CAP_LOW 0xF77E
  2802. +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
  2803. +#define REG_BAT_FULLCHG_CAP_LOW 0xF781
  2804. +#define REG_BAT_DESIGN_VOL_HIGH 0xF782
  2805. +#define REG_BAT_DESIGN_VOL_LOW 0xF783
  2806. +#define REG_BAT_CURRENT_HIGH 0xF784
  2807. +#define REG_BAT_CURRENT_LOW 0xF785
  2808. +#define REG_BAT_VOLTAGE_HIGH 0xF786
  2809. +#define REG_BAT_VOLTAGE_LOW 0xF787
  2810. +#define REG_BAT_TEMPERATURE_HIGH 0xF788
  2811. +#define REG_BAT_TEMPERATURE_LOW 0xF789
  2812. +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
  2813. +#define REG_BAT_RELATIVE_CAP_LOW 0xF493
  2814. +#define REG_BAT_VENDOR 0xF4C4
  2815. +#define FLAG_BAT_VENDOR_SANYO 0x01
  2816. +#define FLAG_BAT_VENDOR_SIMPLO 0x02
  2817. +#define REG_BAT_CELL_COUNT 0xF4C6
  2818. +#define FLAG_BAT_CELL_3S1P 0x03
  2819. +#define FLAG_BAT_CELL_3S2P 0x06
  2820. +#define REG_BAT_CHARGE 0xF4A2
  2821. +#define FLAG_BAT_CHARGE_DISCHARGE 0x01
  2822. +#define FLAG_BAT_CHARGE_CHARGE 0x02
  2823. +#define FLAG_BAT_CHARGE_ACPOWER 0x00
  2824. +#define REG_BAT_STATUS 0xF4B0
  2825. +#define BIT_BAT_STATUS_LOW (1 << 5)
  2826. +#define BIT_BAT_STATUS_DESTROY (1 << 2)
  2827. +#define BIT_BAT_STATUS_FULL (1 << 1)
  2828. +#define BIT_BAT_STATUS_IN (1 << 0)
  2829. +#define REG_BAT_CHARGE_STATUS 0xF4B1
  2830. +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
  2831. +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
  2832. +#define REG_BAT_STATE 0xF482
  2833. +#define BIT_BAT_STATE_CHARGING (1 << 1)
  2834. +#define BIT_BAT_STATE_DISCHARGING (1 << 0)
  2835. +#define REG_BAT_POWER 0xF440
  2836. +#define BIT_BAT_POWER_S3 (1 << 2)
  2837. +#define BIT_BAT_POWER_ON (1 << 1)
  2838. +#define BIT_BAT_POWER_ACIN (1 << 0)
  2839. +
  2840. +/* Audio: rd/wr */
  2841. +#define REG_AUDIO_VOLUME 0xF46C
  2842. +#define REG_AUDIO_MUTE 0xF4E7
  2843. +#define REG_AUDIO_BEEP 0xF4D0
  2844. +/* USB port power or not: rd/wr */
  2845. +#define REG_USB0_FLAG 0xF461
  2846. +#define REG_USB1_FLAG 0xF462
  2847. +#define REG_USB2_FLAG 0xF463
  2848. +#define BIT_USB_FLAG_ON 1
  2849. +#define BIT_USB_FLAG_OFF 0
  2850. +/* LID */
  2851. +#define REG_LID_DETECT 0xF4BD
  2852. +#define BIT_LID_DETECT_ON 1
  2853. +#define BIT_LID_DETECT_OFF 0
  2854. +/* CRT */
  2855. +#define REG_CRT_DETECT 0xF4AD
  2856. +#define BIT_CRT_DETECT_PLUG 1
  2857. +#define BIT_CRT_DETECT_UNPLUG 0
  2858. +/* LCD backlight brightness adjust: 9 levels */
  2859. +#define REG_DISPLAY_BRIGHTNESS 0xF4F5
  2860. +/* Black screen Status */
  2861. +#define BIT_DISPLAY_LCD_ON 1
  2862. +#define BIT_DISPLAY_LCD_OFF 0
  2863. +/* LCD backlight control: off/restore */
  2864. +#define REG_BACKLIGHT_CTRL 0xF7BD
  2865. +#define BIT_BACKLIGHT_ON 1
  2866. +#define BIT_BACKLIGHT_OFF 0
  2867. +/* Reset the machine auto-clear: rd/wr */
  2868. +#define REG_RESET 0xF4EC
  2869. +#define BIT_RESET_ON 1
  2870. +/* Light the led: rd/wr */
  2871. +#define REG_LED 0xF4C8
  2872. +#define BIT_LED_RED_POWER (1 << 0)
  2873. +#define BIT_LED_ORANGE_POWER (1 << 1)
  2874. +#define BIT_LED_GREEN_CHARGE (1 << 2)
  2875. +#define BIT_LED_RED_CHARGE (1 << 3)
  2876. +#define BIT_LED_NUMLOCK (1 << 4)
  2877. +/* Test led mode, all led on/off */
  2878. +#define REG_LED_TEST 0xF4C2
  2879. +#define BIT_LED_TEST_IN 1
  2880. +#define BIT_LED_TEST_OUT 0
  2881. +/* Camera on/off */
  2882. +#define REG_CAMERA_STATUS 0xF46A
  2883. +#define BIT_CAMERA_STATUS_ON 1
  2884. +#define BIT_CAMERA_STATUS_OFF 0
  2885. +#define REG_CAMERA_CONTROL 0xF7B7
  2886. +#define BIT_CAMERA_CONTROL_OFF 0
  2887. +#define BIT_CAMERA_CONTROL_ON 1
  2888. +/* Wlan Status */
  2889. +#define REG_WLAN 0xF4FA
  2890. +#define BIT_WLAN_ON 1
  2891. +#define BIT_WLAN_OFF 0
  2892. +#define REG_DISPLAY_LCD 0xF79F
  2893. +
  2894. +/* SCI Event Number from EC */
  2895. +enum {
  2896. + EVENT_LID = 0x23, /* Turn on/off LID */
  2897. + EVENT_SWITCHVIDEOMODE, /* Fn+F3 for display switch */
  2898. + EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
  2899. + EVENT_OVERTEMP, /* Over-temperature happened */
  2900. + EVENT_CRT_DETECT, /* CRT is connected */
  2901. + EVENT_CAMERA, /* Camera on/off */
  2902. + EVENT_USB_OC2, /* USB2 Over Current occurred */
  2903. + EVENT_USB_OC0, /* USB0 Over Current occurred */
  2904. + EVENT_DISPLAYTOGGLE, /* Fn+F2, Turn on/off backlight */
  2905. + EVENT_AUDIO_MUTE, /* Fn+F4, Mute on/off */
  2906. + EVENT_DISPLAY_BRIGHTNESS,/* Fn+^/V, LCD backlight brightness adjust */
  2907. + EVENT_AC_BAT, /* AC & Battery relative issue */
  2908. + EVENT_AUDIO_VOLUME, /* Fn+<|>, Volume adjust */
  2909. + EVENT_WLAN, /* Wlan on/off */
  2910. +};
  2911. +
  2912. +#define EVENT_START EVENT_LID
  2913. +#define EVENT_END EVENT_WLAN
  2914. +
  2915. +#endif /* !_EC_KB3310B_H */
  2916. 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
  2917. --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/gpio.h 1970-01-01 01:00:00.000000000 +0100
  2918. +++ linux-loongson/arch/mips/include/asm/mach-loongson/gpio.h 2010-05-27 18:12:28.712212405 +0200
  2919. @@ -0,0 +1,35 @@
  2920. +/*
  2921. + * STLS2F GPIO Support
  2922. + *
  2923. + * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
  2924. + * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
  2925. + *
  2926. + * This program is free software; you can redistribute it and/or modify
  2927. + * it under the terms of the GNU General Public License as published by
  2928. + * the Free Software Foundation; either version 2 of the License, or
  2929. + * (at your option) any later version.
  2930. + */
  2931. +
  2932. +#ifndef __STLS2F_GPIO_H
  2933. +#define __STLS2F_GPIO_H
  2934. +
  2935. +#include <asm-generic/gpio.h>
  2936. +
  2937. +extern void gpio_set_value(unsigned gpio, int value);
  2938. +extern int gpio_get_value(unsigned gpio);
  2939. +extern int gpio_cansleep(unsigned gpio);
  2940. +
  2941. +/* The chip can do interrupt
  2942. + * but it has not been tested and doc not clear
  2943. + */
  2944. +static inline int gpio_to_irq(int gpio)
  2945. +{
  2946. + return -EINVAL;
  2947. +}
  2948. +
  2949. +static inline int irq_to_gpio(int gpio)
  2950. +{
  2951. + return -EINVAL;
  2952. +}
  2953. +
  2954. +#endif /* __STLS2F_GPIO_H */
  2955. 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
  2956. --- linux-2.6.34.orig/arch/mips/include/asm/mach-loongson/loongson.h 2010-05-16 23:17:36.000000000 +0200
  2957. +++ linux-loongson/arch/mips/include/asm/mach-loongson/loongson.h 2010-05-27 18:12:28.712212405 +0200
  2958. @@ -42,6 +42,12 @@
  2959. #endif
  2960. }
  2961. +/*
  2962. + * Copy kernel command line from arcs_cmdline
  2963. + */
  2964. +#include <asm/setup.h>
  2965. +extern char loongson_cmdline[COMMAND_LINE_SIZE];
  2966. +
  2967. /* irq operation functions */
  2968. extern void bonito_irqdispatch(void);
  2969. extern void __init bonito_irq_init(void);
  2970. diff -Nur linux-2.6.34.orig/arch/mips/Kconfig linux-loongson/arch/mips/Kconfig
  2971. --- linux-2.6.34.orig/arch/mips/Kconfig 2010-05-16 23:17:36.000000000 +0200
  2972. +++ linux-loongson/arch/mips/Kconfig 2010-05-27 18:12:28.582214052 +0200
  2973. @@ -180,7 +180,7 @@
  2974. config MACH_LOONGSON
  2975. bool "Loongson family of machines"
  2976. - select SYS_SUPPORTS_ZBOOT
  2977. + select SYS_SUPPORTS_ZBOOT_UART16550
  2978. help
  2979. This enables the support of Loongson family of machines.
  2980. @@ -1075,6 +1075,8 @@
  2981. bool "Loongson 2F"
  2982. depends on SYS_HAS_CPU_LOONGSON2F
  2983. select CPU_LOONGSON2
  2984. + select GENERIC_GPIO
  2985. + select ARCH_REQUIRE_GPIOLIB
  2986. help
  2987. The Loongson 2F processor implements the MIPS III instruction set
  2988. with many extensions.
  2989. @@ -1965,6 +1967,18 @@
  2990. source "kernel/time/Kconfig"
  2991. #
  2992. +# High Resolution sched_clock() Configuration
  2993. +#
  2994. +
  2995. +config CPU_HAS_FIXED_C0_COUNT
  2996. + bool
  2997. +
  2998. +config CPU_SUPPORTS_HR_SCHED_CLOCK
  2999. + bool
  3000. + depends on CPU_HAS_FIXED_C0_COUNT || !CPU_FREQ
  3001. + default y
  3002. +
  3003. +#
  3004. # Timer Interrupt Frequency Configuration
  3005. #
  3006. diff -Nur linux-2.6.34.orig/arch/mips/kernel/csrc-r4k.c linux-loongson/arch/mips/kernel/csrc-r4k.c
  3007. --- linux-2.6.34.orig/arch/mips/kernel/csrc-r4k.c 2010-05-16 23:17:36.000000000 +0200
  3008. +++ linux-loongson/arch/mips/kernel/csrc-r4k.c 2010-05-27 18:12:28.882214141 +0200
  3009. @@ -6,10 +6,66 @@
  3010. * Copyright (C) 2007 by Ralf Baechle
  3011. */
  3012. #include <linux/clocksource.h>
  3013. +#include <linux/cnt32_to_63.h>
  3014. #include <linux/init.h>
  3015. +#include <linux/timer.h>
  3016. #include <asm/time.h>
  3017. +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
  3018. +/*
  3019. + * MIPS sched_clock implementation.
  3020. + *
  3021. + * Because the hardware timer period is quite short and because cnt32_to_63()
  3022. + * needs to be called at least once per half period to work properly, a kernel
  3023. + * timer is set up to ensure this requirement is always met.
  3024. + *
  3025. + * Please refer to include/linux/cnt32_to_63.h and arch/arm/plat-orion/time.c
  3026. + */
  3027. +#define CLOCK2NS_SCALE_FACTOR 8
  3028. +
  3029. +static unsigned long clock2ns_scale __read_mostly;
  3030. +
  3031. +unsigned long long notrace sched_clock(void)
  3032. +{
  3033. + unsigned long long v = cnt32_to_63(read_c0_count());
  3034. + return (v * clock2ns_scale) >> CLOCK2NS_SCALE_FACTOR;
  3035. +}
  3036. +
  3037. +static struct timer_list cnt32_to_63_keepwarm_timer;
  3038. +
  3039. +static void cnt32_to_63_keepwarm(unsigned long data)
  3040. +{
  3041. + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
  3042. + sched_clock();
  3043. +}
  3044. +#endif
  3045. +
  3046. +static inline void setup_hres_sched_clock(unsigned long clock)
  3047. +{
  3048. +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK
  3049. + unsigned long long v;
  3050. + unsigned long data;
  3051. +
  3052. + v = NSEC_PER_SEC;
  3053. + v <<= CLOCK2NS_SCALE_FACTOR;
  3054. + v += clock/2;
  3055. + do_div(v, clock);
  3056. + /*
  3057. + * We want an even value to automatically clear the top bit
  3058. + * returned by cnt32_to_63() without an additional run time
  3059. + * instruction. So if the LSB is 1 then round it up.
  3060. + */
  3061. + if (v & 1)
  3062. + v++;
  3063. + clock2ns_scale = v;
  3064. +
  3065. + data = 0x80000000UL / clock * HZ;
  3066. + setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
  3067. + mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
  3068. +#endif
  3069. +}
  3070. +
  3071. static cycle_t c0_hpt_read(struct clocksource *cs)
  3072. {
  3073. return read_c0_count();
  3074. @@ -27,6 +83,8 @@
  3075. if (!cpu_has_counter || !mips_hpt_frequency)
  3076. return -ENXIO;
  3077. + setup_hres_sched_clock(mips_hpt_frequency);
  3078. +
  3079. /* Calculate a somewhat reasonable rating value */
  3080. clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
  3081. diff -Nur linux-2.6.34.orig/arch/mips/kernel/ftrace.c linux-loongson/arch/mips/kernel/ftrace.c
  3082. --- linux-2.6.34.orig/arch/mips/kernel/ftrace.c 2010-05-16 23:17:36.000000000 +0200
  3083. +++ linux-loongson/arch/mips/kernel/ftrace.c 2010-05-27 18:12:28.882214141 +0200
  3084. @@ -2,7 +2,7 @@
  3085. * Code for replacing ftrace calls with jumps.
  3086. *
  3087. * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
  3088. - * Copyright (C) 2009 DSLab, Lanzhou University, China
  3089. + * Copyright (C) 2009, 2010 DSLab, Lanzhou University, China
  3090. * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  3091. *
  3092. * Thanks goes to Steven Rostedt for writing the original x86 version.
  3093. @@ -15,15 +15,51 @@
  3094. #include <asm/cacheflush.h>
  3095. #include <asm/asm.h>
  3096. #include <asm/asm-offsets.h>
  3097. +#include <asm/uasm.h>
  3098. +
  3099. +#define INSN_S_R_SP 0xafb00000 /* s{d,w} R, offset(sp) */
  3100. #ifdef CONFIG_DYNAMIC_FTRACE
  3101. -#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */
  3102. -#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */
  3103. -#define jump_insn_encode(op_code, addr) \
  3104. - ((unsigned int)((op_code) | (((addr) >> 2) & ADDR_MASK)))
  3105. +/* Before linking, the following instructions are fixed. */
  3106. +#ifdef CONFIG_CPU_LOONGSON2F
  3107. +#define INSN_NOP 0x00200825 /* or at, at, zero */
  3108. +#else
  3109. +#define INSN_NOP 0x00000000 /* nop */
  3110. +#endif
  3111. +#define INSN_B_1F_16 0x10000004 /* b 1f; offset = (16 >> 2) */
  3112. +#define INSN_B_1F_20 0x10000005 /* b 1f; offset = (20 >> 2) */
  3113. +
  3114. +/* After linking, the following instructions are fixed. */
  3115. +static unsigned int insn_jal_ftrace_caller __read_mostly;
  3116. +static unsigned int insn_lui_v1_hi16_mcount __read_mostly;
  3117. +static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly;
  3118. +
  3119. +/* The following instructions are encoded in the run-time */
  3120. +/* insn: jal func; op_code|addr : 31...26|25 ....0 */
  3121. +#define INSN_JAL(addr) \
  3122. + ((unsigned int)(0x0c000000 | (((addr) >> 2) & 0x03ffffff)))
  3123. -static unsigned int ftrace_nop = 0x00000000;
  3124. +static inline void ftrace_dyn_arch_init_insns(void)
  3125. +{
  3126. + u32 *buf;
  3127. + unsigned int v1;
  3128. +
  3129. + /* lui v1, hi16_mcount */
  3130. + v1 = 3;
  3131. + buf = (u32 *)&insn_lui_v1_hi16_mcount;
  3132. + UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR);
  3133. +
  3134. + /* jal (ftrace_caller + 8), jump over the first two instruction */
  3135. + buf = (u32 *)&insn_jal_ftrace_caller;
  3136. + uasm_i_jal(&buf, (FTRACE_ADDR + 8));
  3137. +
  3138. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  3139. + /* j ftrace_graph_caller */
  3140. + buf = (u32 *)&insn_j_ftrace_graph_caller;
  3141. + uasm_i_j(&buf, (unsigned long)ftrace_graph_caller);
  3142. +#endif
  3143. +}
  3144. static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
  3145. {
  3146. @@ -31,7 +67,6 @@
  3147. /* *(unsigned int *)ip = new_code; */
  3148. safe_store_code(new_code, ip, faulted);
  3149. -
  3150. if (unlikely(faulted))
  3151. return -EFAULT;
  3152. @@ -40,84 +75,82 @@
  3153. return 0;
  3154. }
  3155. -static int lui_v1;
  3156. -static int jal_mcount;
  3157. -
  3158. int ftrace_make_nop(struct module *mod,
  3159. struct dyn_ftrace *rec, unsigned long addr)
  3160. {
  3161. unsigned int new;
  3162. - int faulted;
  3163. unsigned long ip = rec->ip;
  3164. - /* We have compiled module with -mlong-calls, but compiled the kernel
  3165. - * without it, we need to cope with them respectively. */
  3166. - if (ip & 0x40000000) {
  3167. - /* record it for ftrace_make_call */
  3168. - if (lui_v1 == 0) {
  3169. - /* lui_v1 = *(unsigned int *)ip; */
  3170. - safe_load_code(lui_v1, ip, faulted);
  3171. -
  3172. - if (unlikely(faulted))
  3173. - return -EFAULT;
  3174. - }
  3175. -
  3176. - /* lui v1, hi_16bit_of_mcount --> b 1f (0x10000004)
  3177. - * addiu v1, v1, low_16bit_of_mcount
  3178. - * move at, ra
  3179. - * jalr v1
  3180. - * nop
  3181. - * 1f: (ip + 12)
  3182. - */
  3183. - new = 0x10000004;
  3184. - } else {
  3185. - /* record/calculate it for ftrace_make_call */
  3186. - if (jal_mcount == 0) {
  3187. - /* We can record it directly like this:
  3188. - * jal_mcount = *(unsigned int *)ip;
  3189. - * Herein, jump over the first two nop instructions */
  3190. - jal_mcount = jump_insn_encode(JAL, (MCOUNT_ADDR + 8));
  3191. - }
  3192. + /*
  3193. + * We have compiled modules with -mlong-calls, but compiled kernel
  3194. + * without it, therefore, need to cope with them respectively.
  3195. + *
  3196. + * For module:
  3197. + *
  3198. + * lui v1, hi16_mcount --> b 1f
  3199. + * addiu v1, v1, lo16_mcount
  3200. + * move at, ra
  3201. + * jalr v1
  3202. + * nop
  3203. + * 1f: (ip + 16)
  3204. + * For kernel:
  3205. + *
  3206. + * move at, ra
  3207. + * jal _mcount --> nop
  3208. + *
  3209. + * And with the -mmcount-ra-address option, the offset may be 20 for
  3210. + * leaf fuction and 24 for non-leaf function.
  3211. + */
  3212. - /* move at, ra
  3213. - * jalr v1 --> nop
  3214. - */
  3215. - new = ftrace_nop;
  3216. + if (!in_module(ip))
  3217. + new = INSN_NOP;
  3218. + else {
  3219. +#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
  3220. + new = INSN_B_1F_20;
  3221. +#else
  3222. + new = INSN_B_1F_16;
  3223. +#endif
  3224. }
  3225. +
  3226. return ftrace_modify_code(ip, new);
  3227. }
  3228. -static int modified; /* initialized as 0 by default */
  3229. -
  3230. int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  3231. {
  3232. unsigned int new;
  3233. unsigned long ip = rec->ip;
  3234. - /* We just need to remove the "b ftrace_stub" at the fist time! */
  3235. - if (modified == 0) {
  3236. - modified = 1;
  3237. - ftrace_modify_code(addr, ftrace_nop);
  3238. - }
  3239. - /* ip, module: 0xc0000000, kernel: 0x80000000 */
  3240. - new = (ip & 0x40000000) ? lui_v1 : jal_mcount;
  3241. + new = in_module(ip) ? insn_lui_v1_hi16_mcount : insn_jal_ftrace_caller;
  3242. return ftrace_modify_code(ip, new);
  3243. }
  3244. -#define FTRACE_CALL_IP ((unsigned long)(&ftrace_call))
  3245. -
  3246. int ftrace_update_ftrace_func(ftrace_func_t func)
  3247. {
  3248. unsigned int new;
  3249. - new = jump_insn_encode(JAL, (unsigned long)func);
  3250. + new = INSN_JAL((unsigned long)func);
  3251. - return ftrace_modify_code(FTRACE_CALL_IP, new);
  3252. + return ftrace_modify_code((unsigned long)(&ftrace_call), new);
  3253. }
  3254. int __init ftrace_dyn_arch_init(void *data)
  3255. {
  3256. + ftrace_dyn_arch_init_insns();
  3257. +
  3258. + /*
  3259. + * We are safe to remove the "b ftrace_stub" for the current
  3260. + * ftrace_caller() is almost empty (only the stack operations), and
  3261. + * most importantly, the calling to mcount will be disabled later in
  3262. + * ftrace_init(), then there is no 'big' overhead. And in the future,
  3263. + * we are hoping the function_trace_stop is initialized as 1 then we
  3264. + * can eventually remove that 'useless' "b ftrace_stub" and the
  3265. + * following nop. Currently, although we can call ftrace_stop() to set
  3266. + * function_trace_stop as 1, but it will change the behavior of the
  3267. + * Function Tracer.
  3268. + */
  3269. + ftrace_modify_code(MCOUNT_ADDR, INSN_NOP);
  3270. +
  3271. /* The return code is retured via data */
  3272. *(unsigned long *)data = 0;
  3273. @@ -128,30 +161,24 @@
  3274. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  3275. #ifdef CONFIG_DYNAMIC_FTRACE
  3276. -
  3277. extern void ftrace_graph_call(void);
  3278. -#define JMP 0x08000000 /* jump to target directly */
  3279. -#define CALL_FTRACE_GRAPH_CALLER \
  3280. - jump_insn_encode(JMP, (unsigned long)(&ftrace_graph_caller))
  3281. #define FTRACE_GRAPH_CALL_IP ((unsigned long)(&ftrace_graph_call))
  3282. int ftrace_enable_ftrace_graph_caller(void)
  3283. {
  3284. return ftrace_modify_code(FTRACE_GRAPH_CALL_IP,
  3285. - CALL_FTRACE_GRAPH_CALLER);
  3286. + insn_j_ftrace_graph_caller);
  3287. }
  3288. int ftrace_disable_ftrace_graph_caller(void)
  3289. {
  3290. - return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, ftrace_nop);
  3291. + return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, INSN_NOP);
  3292. }
  3293. -
  3294. #endif /* !CONFIG_DYNAMIC_FTRACE */
  3295. #ifndef KBUILD_MCOUNT_RA_ADDRESS
  3296. -#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */
  3297. -#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */
  3298. -#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
  3299. +#define INSN_S_RA_SP 0xafbf0000 /* s{d,w} ra, offset(sp) */
  3300. +#define STACK_OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
  3301. unsigned long ftrace_get_parent_addr(unsigned long self_addr,
  3302. unsigned long parent,
  3303. @@ -162,35 +189,35 @@
  3304. unsigned int code;
  3305. int faulted;
  3306. - /* in module or kernel? */
  3307. - if (self_addr & 0x40000000) {
  3308. - /* module: move to the instruction "lui v1, HI_16BIT_OF_MCOUNT" */
  3309. - ip = self_addr - 20;
  3310. - } else {
  3311. - /* kernel: move to the instruction "move ra, at" */
  3312. - ip = self_addr - 12;
  3313. - }
  3314. + /*
  3315. + * For module, move the ip from calling site of mcount to the
  3316. + * instruction "lui v1, hi_16bit_of_mcount"(offset is 20), but for
  3317. + * kernel, move to the instruction "move ra, at"(offset is 12)
  3318. + */
  3319. + ip = self_addr - (in_module(self_addr) ? 20 : 12);
  3320. - /* search the text until finding the non-store instruction or "s{d,w}
  3321. - * ra, offset(sp)" instruction */
  3322. + /*
  3323. + * search the text until finding the non-store instruction or "s{d,w}
  3324. + * ra, offset(sp)" instruction
  3325. + */
  3326. do {
  3327. ip -= 4;
  3328. /* get the code at "ip": code = *(unsigned int *)ip; */
  3329. safe_load_code(code, ip, faulted);
  3330. -
  3331. if (unlikely(faulted))
  3332. return 0;
  3333. - /* If we hit the non-store instruction before finding where the
  3334. + /*
  3335. + * If we hit the non-store instruction before finding where the
  3336. * ra is stored, then this is a leaf function and it does not
  3337. - * store the ra on the stack. */
  3338. - if ((code & S_R_SP) != S_R_SP)
  3339. + * store the ra on the stack.
  3340. + */
  3341. + if ((code & INSN_S_R_SP) != INSN_S_R_SP)
  3342. return parent_addr;
  3343. + } while (((code & INSN_S_RA_SP) != INSN_S_RA_SP));
  3344. - } while (((code & S_RA_SP) != S_RA_SP));
  3345. -
  3346. - sp = fp + (code & OFFSET_MASK);
  3347. + sp = fp + (code & STACK_OFFSET_MASK);
  3348. /* ra = *(unsigned long *)sp; */
  3349. safe_load_stack(ra, sp, faulted);
  3350. @@ -201,8 +228,7 @@
  3351. return sp;
  3352. return 0;
  3353. }
  3354. -
  3355. -#endif
  3356. +#endif /* !KBUILD_MCOUNT_RA_ADDRESS */
  3357. /*
  3358. * Hook the return address and push it in the stack of return addrs
  3359. @@ -211,16 +237,17 @@
  3360. void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
  3361. unsigned long fp)
  3362. {
  3363. + int faulted;
  3364. unsigned long old;
  3365. struct ftrace_graph_ent trace;
  3366. unsigned long return_hooker = (unsigned long)
  3367. &return_to_handler;
  3368. - int faulted;
  3369. if (unlikely(atomic_read(&current->tracing_graph_pause)))
  3370. return;
  3371. - /* "parent" is the stack address saved the return address of the caller
  3372. + /*
  3373. + * "parent" is the stack address saved the return address of the caller
  3374. * of _mcount.
  3375. *
  3376. * if the gcc < 4.5, a leaf function does not save the return address
  3377. @@ -241,12 +268,14 @@
  3378. if (unlikely(faulted))
  3379. goto out;
  3380. #ifndef KBUILD_MCOUNT_RA_ADDRESS
  3381. - parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old,
  3382. - (unsigned long)parent,
  3383. - fp);
  3384. - /* If fails when getting the stack address of the non-leaf function's
  3385. - * ra, stop function graph tracer and return */
  3386. - if (parent == 0)
  3387. + parent = (unsigned long *)ftrace_get_parent_addr(
  3388. + self_addr, old, (unsigned long)parent, fp);
  3389. +
  3390. + /*
  3391. + * If fails on getting the stack address of the non-leaf function's ra,
  3392. + * stop function graph tracer and return
  3393. + */
  3394. + if (unlikely(parent == 0))
  3395. goto out;
  3396. #endif
  3397. /* *parent = return_hooker; */
  3398. diff -Nur linux-2.6.34.orig/arch/mips/kernel/mcount.S linux-loongson/arch/mips/kernel/mcount.S
  3399. --- linux-2.6.34.orig/arch/mips/kernel/mcount.S 2010-05-16 23:17:36.000000000 +0200
  3400. +++ linux-loongson/arch/mips/kernel/mcount.S 2010-05-27 18:12:28.882214141 +0200
  3401. @@ -6,6 +6,7 @@
  3402. * more details.
  3403. *
  3404. * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
  3405. + * Copyright (C) 2010 DSLab, Lanzhou University, China
  3406. * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  3407. */
  3408. @@ -45,8 +46,6 @@
  3409. PTR_L a5, PT_R9(sp)
  3410. PTR_L a6, PT_R10(sp)
  3411. PTR_L a7, PT_R11(sp)
  3412. -#endif
  3413. -#ifdef CONFIG_64BIT
  3414. PTR_ADDIU sp, PT_SIZE
  3415. #else
  3416. PTR_ADDIU sp, (PT_SIZE + 8)
  3417. @@ -71,14 +70,14 @@
  3418. MCOUNT_SAVE_REGS
  3419. #ifdef KBUILD_MCOUNT_RA_ADDRESS
  3420. - PTR_S t0, PT_R12(sp) /* t0 saved the location of the return address(at) by -mmcount-ra-address */
  3421. + PTR_S $12, PT_R12(sp) /* save location of parent's return address */
  3422. #endif
  3423. - move a0, ra /* arg1: next ip, selfaddr */
  3424. + move a0, ra /* arg1: self return address */
  3425. .globl ftrace_call
  3426. ftrace_call:
  3427. nop /* a placeholder for the call to a real tracing function */
  3428. - move a1, AT /* arg2: the caller's next ip, parent */
  3429. + move a1, AT /* arg2: parent's return address */
  3430. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  3431. .globl ftrace_graph_call
  3432. @@ -119,9 +118,9 @@
  3433. static_trace:
  3434. MCOUNT_SAVE_REGS
  3435. - move a0, ra /* arg1: next ip, selfaddr */
  3436. + move a0, ra /* arg1: self return address */
  3437. jalr t2 /* (1) call *ftrace_trace_function */
  3438. - move a1, AT /* arg2: the caller's next ip, parent */
  3439. + move a1, AT /* arg2: parent's return address */
  3440. MCOUNT_RESTORE_REGS
  3441. .globl ftrace_stub
  3442. @@ -134,28 +133,36 @@
  3443. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  3444. NESTED(ftrace_graph_caller, PT_SIZE, ra)
  3445. -#ifdef CONFIG_DYNAMIC_FTRACE
  3446. - PTR_L a1, PT_R31(sp) /* load the original ra from the stack */
  3447. -#ifdef KBUILD_MCOUNT_RA_ADDRESS
  3448. - PTR_L t0, PT_R12(sp) /* load the original t0 from the stack */
  3449. -#endif
  3450. -#else
  3451. +#ifndef CONFIG_DYNAMIC_FTRACE
  3452. MCOUNT_SAVE_REGS
  3453. - move a1, ra /* arg2: next ip, selfaddr */
  3454. #endif
  3455. + /* arg1: Get the location of the parent's return address */
  3456. #ifdef KBUILD_MCOUNT_RA_ADDRESS
  3457. - bnez t0, 1f /* non-leaf func: t0 saved the location of the return address */
  3458. +#ifdef CONFIG_DYNAMIC_FTRACE
  3459. + PTR_L a0, PT_R12(sp)
  3460. +#else
  3461. + move a0, $12
  3462. +#endif
  3463. + bnez a0, 1f /* arg1: non-leaf func: stored in $12 */
  3464. nop
  3465. - PTR_LA t0, PT_R1(sp) /* leaf func: get the location of at(old ra) from our own stack */
  3466. -1: move a0, t0 /* arg1: the location of the return address */
  3467. +#endif
  3468. + PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */
  3469. +
  3470. +1:
  3471. + /* arg2: Get self return address */
  3472. +#ifdef CONFIG_DYNAMIC_FTRACE
  3473. + PTR_L a1, PT_R31(sp)
  3474. #else
  3475. - PTR_LA a0, PT_R1(sp) /* arg1: &AT -> a0 */
  3476. + move a1, ra
  3477. #endif
  3478. +
  3479. jal prepare_ftrace_return
  3480. +
  3481. + /* arg3: Get frame pointer of current stack */
  3482. #ifdef CONFIG_FRAME_POINTER
  3483. - move a2, fp /* arg3: frame pointer */
  3484. -#else
  3485. + move a2, fp
  3486. +#else /* ! CONFIG_FRAME_POINTER */
  3487. #ifdef CONFIG_64BIT
  3488. PTR_LA a2, PT_SIZE(sp)
  3489. #else
  3490. diff -Nur linux-2.6.34.orig/arch/mips/kernel/time.c linux-loongson/arch/mips/kernel/time.c
  3491. --- linux-2.6.34.orig/arch/mips/kernel/time.c 2010-05-16 23:17:36.000000000 +0200
  3492. +++ linux-loongson/arch/mips/kernel/time.c 2010-05-27 18:12:28.892213481 +0200
  3493. @@ -119,6 +119,11 @@
  3494. void __init time_init(void)
  3495. {
  3496. +#ifdef CONFIG_HR_SCHED_CLOCK
  3497. + if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
  3498. + write_c0_count(0);
  3499. +#endif
  3500. +
  3501. plat_time_init();
  3502. if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
  3503. diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/cmdline.c linux-loongson/arch/mips/loongson/common/cmdline.c
  3504. --- linux-2.6.34.orig/arch/mips/loongson/common/cmdline.c 2010-05-16 23:17:36.000000000 +0200
  3505. +++ linux-loongson/arch/mips/loongson/common/cmdline.c 2010-05-27 18:12:28.902214422 +0200
  3506. @@ -17,10 +17,15 @@
  3507. * Free Software Foundation; either version 2 of the License, or (at your
  3508. * option) any later version.
  3509. */
  3510. +#include <linux/module.h>
  3511. #include <asm/bootinfo.h>
  3512. #include <loongson.h>
  3513. +/* the kernel command line copied from arcs_cmdline */
  3514. +char loongson_cmdline[COMMAND_LINE_SIZE];
  3515. +EXPORT_SYMBOL(loongson_cmdline);
  3516. +
  3517. void __init prom_init_cmdline(void)
  3518. {
  3519. int prom_argc;
  3520. @@ -50,4 +55,26 @@
  3521. strcat(arcs_cmdline, " root=/dev/hda1");
  3522. prom_init_machtype();
  3523. +
  3524. + /* append machine specific command line */
  3525. + switch (mips_machtype) {
  3526. + case MACH_LEMOTE_LL2F:
  3527. + if ((strstr(arcs_cmdline, "video=")) == NULL)
  3528. + strcat(arcs_cmdline, " video=sisfb:1360x768-16@60");
  3529. + break;
  3530. + case MACH_LEMOTE_FL2F:
  3531. + if ((strstr(arcs_cmdline, "ide_core.ignore_cable=")) == NULL)
  3532. + strcat(arcs_cmdline, " ide_core.ignore_cable=0");
  3533. + break;
  3534. + case MACH_LEMOTE_ML2F7:
  3535. + /* Mengloong-2F has a 800x480 screen */
  3536. + if ((strstr(arcs_cmdline, "vga=")) == NULL)
  3537. + strcat(arcs_cmdline, " vga=0x313");
  3538. + break;
  3539. + default:
  3540. + break;
  3541. + }
  3542. +
  3543. + /* copy arcs_cmdline into loongson_cmdline */
  3544. + strncpy(loongson_cmdline, arcs_cmdline, COMMAND_LINE_SIZE);
  3545. }
  3546. 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
  3547. --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-05-16 23:17:36.000000000 +0200
  3548. +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_acc.c 2010-05-27 18:12:28.902214422 +0200
  3549. @@ -18,7 +18,7 @@
  3550. void pci_acc_write_reg(int reg, u32 value)
  3551. {
  3552. - u32 hi = 0, lo = value;
  3553. + u32 hi, lo;
  3554. switch (reg) {
  3555. case PCI_COMMAND:
  3556. @@ -66,75 +66,73 @@
  3557. u32 pci_acc_read_reg(int reg)
  3558. {
  3559. u32 hi, lo;
  3560. - u32 conf_data = 0;
  3561. + u32 cfg = 0;
  3562. switch (reg) {
  3563. case PCI_VENDOR_ID:
  3564. - conf_data =
  3565. - CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);
  3566. + cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID,
  3567. + CS5536_VENDOR_ID);
  3568. break;
  3569. case PCI_COMMAND:
  3570. _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
  3571. if (((lo & 0xfff00000) || (hi & 0x000000ff))
  3572. && ((hi & 0xf0000000) == 0xa0000000))
  3573. - conf_data |= PCI_COMMAND_IO;
  3574. + cfg |= PCI_COMMAND_IO;
  3575. _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
  3576. if ((lo & 0x300) == 0x300)
  3577. - conf_data |= PCI_COMMAND_MASTER;
  3578. + cfg |= PCI_COMMAND_MASTER;
  3579. break;
  3580. case PCI_STATUS:
  3581. - conf_data |= PCI_STATUS_66MHZ;
  3582. - conf_data |= PCI_STATUS_FAST_BACK;
  3583. + cfg |= PCI_STATUS_66MHZ;
  3584. + cfg |= PCI_STATUS_FAST_BACK;
  3585. _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  3586. if (lo & SB_PARE_ERR_FLAG)
  3587. - conf_data |= PCI_STATUS_PARITY;
  3588. - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
  3589. + cfg |= PCI_STATUS_PARITY;
  3590. + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
  3591. break;
  3592. case PCI_CLASS_REVISION:
  3593. _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
  3594. - conf_data = lo & 0x000000ff;
  3595. - conf_data |= (CS5536_ACC_CLASS_CODE << 8);
  3596. + cfg = lo & 0x000000ff;
  3597. + cfg |= (CS5536_ACC_CLASS_CODE << 8);
  3598. break;
  3599. case PCI_CACHE_LINE_SIZE:
  3600. - conf_data =
  3601. - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
  3602. - PCI_NORMAL_LATENCY_TIMER);
  3603. + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
  3604. + PCI_NORMAL_LATENCY_TIMER);
  3605. break;
  3606. case PCI_BAR0_REG:
  3607. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  3608. if (lo & SOFT_BAR_ACC_FLAG) {
  3609. - conf_data = CS5536_ACC_RANGE |
  3610. + cfg = CS5536_ACC_RANGE |
  3611. PCI_BASE_ADDRESS_SPACE_IO;
  3612. lo &= ~SOFT_BAR_ACC_FLAG;
  3613. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  3614. } else {
  3615. _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
  3616. - conf_data = (hi & 0x000000ff) << 12;
  3617. - conf_data |= (lo & 0xfff00000) >> 20;
  3618. - conf_data |= 0x01;
  3619. - conf_data &= ~0x02;
  3620. + cfg = (hi & 0x000000ff) << 12;
  3621. + cfg |= (lo & 0xfff00000) >> 20;
  3622. + cfg |= 0x01;
  3623. + cfg &= ~0x02;
  3624. }
  3625. break;
  3626. case PCI_CARDBUS_CIS:
  3627. - conf_data = PCI_CARDBUS_CIS_POINTER;
  3628. + cfg = PCI_CARDBUS_CIS_POINTER;
  3629. break;
  3630. case PCI_SUBSYSTEM_VENDOR_ID:
  3631. - conf_data =
  3632. - CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);
  3633. + cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID,
  3634. + CS5536_SUB_VENDOR_ID);
  3635. break;
  3636. case PCI_ROM_ADDRESS:
  3637. - conf_data = PCI_EXPANSION_ROM_BAR;
  3638. + cfg = PCI_EXPANSION_ROM_BAR;
  3639. break;
  3640. case PCI_CAPABILITY_LIST:
  3641. - conf_data = PCI_CAPLIST_USB_POINTER;
  3642. + cfg = PCI_CAPLIST_USB_POINTER;
  3643. break;
  3644. case PCI_INTERRUPT_LINE:
  3645. - conf_data =
  3646. - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
  3647. + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
  3648. break;
  3649. default:
  3650. break;
  3651. }
  3652. - return conf_data;
  3653. + return cfg;
  3654. }
  3655. 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
  3656. --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-05-16 23:17:36.000000000 +0200
  3657. +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ehci.c 2010-05-27 18:12:28.902214422 +0200
  3658. @@ -18,7 +18,7 @@
  3659. void pci_ehci_write_reg(int reg, u32 value)
  3660. {
  3661. - u32 hi = 0, lo = value;
  3662. + u32 hi, lo;
  3663. switch (reg) {
  3664. case PCI_COMMAND:
  3665. @@ -49,6 +49,8 @@
  3666. lo |= SOFT_BAR_EHCI_FLAG;
  3667. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  3668. } else if ((value & 0x01) == 0x00) {
  3669. + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
  3670. + lo = value;
  3671. _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
  3672. value &= 0xfffffff0;
  3673. @@ -76,83 +78,81 @@
  3674. u32 pci_ehci_read_reg(int reg)
  3675. {
  3676. - u32 conf_data = 0;
  3677. + u32 cfg = 0;
  3678. u32 hi, lo;
  3679. switch (reg) {
  3680. case PCI_VENDOR_ID:
  3681. - conf_data =
  3682. - CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
  3683. + cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID,
  3684. + CS5536_VENDOR_ID);
  3685. break;
  3686. case PCI_COMMAND:
  3687. _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
  3688. if (hi & PCI_COMMAND_MASTER)
  3689. - conf_data |= PCI_COMMAND_MASTER;
  3690. + cfg |= PCI_COMMAND_MASTER;
  3691. if (hi & PCI_COMMAND_MEMORY)
  3692. - conf_data |= PCI_COMMAND_MEMORY;
  3693. + cfg |= PCI_COMMAND_MEMORY;
  3694. break;
  3695. case PCI_STATUS:
  3696. - conf_data |= PCI_STATUS_66MHZ;
  3697. - conf_data |= PCI_STATUS_FAST_BACK;
  3698. + cfg |= PCI_STATUS_66MHZ;
  3699. + cfg |= PCI_STATUS_FAST_BACK;
  3700. _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  3701. if (lo & SB_PARE_ERR_FLAG)
  3702. - conf_data |= PCI_STATUS_PARITY;
  3703. - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
  3704. + cfg |= PCI_STATUS_PARITY;
  3705. + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
  3706. break;
  3707. case PCI_CLASS_REVISION:
  3708. _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
  3709. - conf_data = lo & 0x000000ff;
  3710. - conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
  3711. + cfg = lo & 0x000000ff;
  3712. + cfg |= (CS5536_EHCI_CLASS_CODE << 8);
  3713. break;
  3714. case PCI_CACHE_LINE_SIZE:
  3715. - conf_data =
  3716. - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
  3717. - PCI_NORMAL_LATENCY_TIMER);
  3718. + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
  3719. + PCI_NORMAL_LATENCY_TIMER);
  3720. break;
  3721. case PCI_BAR0_REG:
  3722. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  3723. if (lo & SOFT_BAR_EHCI_FLAG) {
  3724. - conf_data = CS5536_EHCI_RANGE |
  3725. + cfg = CS5536_EHCI_RANGE |
  3726. PCI_BASE_ADDRESS_SPACE_MEMORY;
  3727. lo &= ~SOFT_BAR_EHCI_FLAG;
  3728. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  3729. } else {
  3730. _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
  3731. - conf_data = lo & 0xfffff000;
  3732. + cfg = lo & 0xfffff000;
  3733. }
  3734. break;
  3735. case PCI_CARDBUS_CIS:
  3736. - conf_data = PCI_CARDBUS_CIS_POINTER;
  3737. + cfg = PCI_CARDBUS_CIS_POINTER;
  3738. break;
  3739. case PCI_SUBSYSTEM_VENDOR_ID:
  3740. - conf_data =
  3741. - CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
  3742. + cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID,
  3743. + CS5536_SUB_VENDOR_ID);
  3744. break;
  3745. case PCI_ROM_ADDRESS:
  3746. - conf_data = PCI_EXPANSION_ROM_BAR;
  3747. + cfg = PCI_EXPANSION_ROM_BAR;
  3748. break;
  3749. case PCI_CAPABILITY_LIST:
  3750. - conf_data = PCI_CAPLIST_USB_POINTER;
  3751. + cfg = PCI_CAPLIST_USB_POINTER;
  3752. break;
  3753. case PCI_INTERRUPT_LINE:
  3754. - conf_data =
  3755. - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
  3756. + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
  3757. break;
  3758. case PCI_EHCI_LEGSMIEN_REG:
  3759. _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
  3760. - conf_data = (hi & 0x003f0000) >> 16;
  3761. + cfg = (hi & 0x003f0000) >> 16;
  3762. break;
  3763. case PCI_EHCI_LEGSMISTS_REG:
  3764. _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
  3765. - conf_data = (hi & 0x3f000000) >> 24;
  3766. + cfg = (hi & 0x3f000000) >> 24;
  3767. break;
  3768. case PCI_EHCI_FLADJ_REG:
  3769. _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
  3770. - conf_data = hi & 0x00003f00;
  3771. + cfg = hi & 0x00003f00;
  3772. break;
  3773. default:
  3774. break;
  3775. }
  3776. - return conf_data;
  3777. + return cfg;
  3778. }
  3779. 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
  3780. --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-05-16 23:17:36.000000000 +0200
  3781. +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ide.c 2010-05-27 18:12:28.902214422 +0200
  3782. @@ -18,7 +18,7 @@
  3783. void pci_ide_write_reg(int reg, u32 value)
  3784. {
  3785. - u32 hi = 0, lo = value;
  3786. + u32 hi, lo;
  3787. switch (reg) {
  3788. case PCI_COMMAND:
  3789. @@ -51,6 +51,7 @@
  3790. lo |= SOFT_BAR_IDE_FLAG;
  3791. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  3792. } else if (value & 0x01) {
  3793. + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
  3794. lo = (value & 0xfffffff0) | 0x1;
  3795. _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
  3796. @@ -65,21 +66,22 @@
  3797. _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
  3798. lo |= 0x01;
  3799. _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
  3800. - } else
  3801. + } else {
  3802. + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
  3803. + lo = value;
  3804. _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
  3805. + }
  3806. break;
  3807. - case PCI_IDE_DTC_REG:
  3808. - _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
  3809. - break;
  3810. - case PCI_IDE_CAST_REG:
  3811. - _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
  3812. - break;
  3813. - case PCI_IDE_ETC_REG:
  3814. - _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
  3815. - break;
  3816. - case PCI_IDE_PM_REG:
  3817. - _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
  3818. - break;
  3819. +#define SET_PCI_IDE_REG(r) \
  3820. + case PCI_IDE_##r##_REG: \
  3821. + _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &lo); \
  3822. + lo = value; \
  3823. + _wrmsr(IDE_MSR_REG(IDE_##r), hi, lo); \
  3824. + break;
  3825. + SET_PCI_IDE_REG(DTC)
  3826. + SET_PCI_IDE_REG(CAST)
  3827. + SET_PCI_IDE_REG(ETC)
  3828. + SET_PCI_IDE_REG(PM)
  3829. default:
  3830. break;
  3831. }
  3832. @@ -87,93 +89,82 @@
  3833. u32 pci_ide_read_reg(int reg)
  3834. {
  3835. - u32 conf_data = 0;
  3836. + u32 cfg = 0;
  3837. u32 hi, lo;
  3838. switch (reg) {
  3839. case PCI_VENDOR_ID:
  3840. - conf_data =
  3841. - CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
  3842. + cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID,
  3843. + CS5536_VENDOR_ID);
  3844. break;
  3845. case PCI_COMMAND:
  3846. _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
  3847. if (lo & 0xfffffff0)
  3848. - conf_data |= PCI_COMMAND_IO;
  3849. + cfg |= PCI_COMMAND_IO;
  3850. _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
  3851. if ((lo & 0x30) == 0x30)
  3852. - conf_data |= PCI_COMMAND_MASTER;
  3853. + cfg |= PCI_COMMAND_MASTER;
  3854. break;
  3855. case PCI_STATUS:
  3856. - conf_data |= PCI_STATUS_66MHZ;
  3857. - conf_data |= PCI_STATUS_FAST_BACK;
  3858. + cfg |= PCI_STATUS_66MHZ;
  3859. + cfg |= PCI_STATUS_FAST_BACK;
  3860. _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  3861. if (lo & SB_PARE_ERR_FLAG)
  3862. - conf_data |= PCI_STATUS_PARITY;
  3863. - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
  3864. + cfg |= PCI_STATUS_PARITY;
  3865. + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
  3866. break;
  3867. case PCI_CLASS_REVISION:
  3868. _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
  3869. - conf_data = lo & 0x000000ff;
  3870. - conf_data |= (CS5536_IDE_CLASS_CODE << 8);
  3871. + cfg = lo & 0x000000ff;
  3872. + cfg |= (CS5536_IDE_CLASS_CODE << 8);
  3873. break;
  3874. case PCI_CACHE_LINE_SIZE:
  3875. _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
  3876. hi &= 0x000000f8;
  3877. - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
  3878. + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
  3879. break;
  3880. case PCI_BAR4_REG:
  3881. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  3882. if (lo & SOFT_BAR_IDE_FLAG) {
  3883. - conf_data = CS5536_IDE_RANGE |
  3884. + cfg = CS5536_IDE_RANGE |
  3885. PCI_BASE_ADDRESS_SPACE_IO;
  3886. lo &= ~SOFT_BAR_IDE_FLAG;
  3887. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  3888. } else {
  3889. _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
  3890. - conf_data = lo & 0xfffffff0;
  3891. - conf_data |= 0x01;
  3892. - conf_data &= ~0x02;
  3893. + cfg = lo & 0xfffffff0;
  3894. + cfg |= 0x01;
  3895. + cfg &= ~0x02;
  3896. }
  3897. break;
  3898. case PCI_CARDBUS_CIS:
  3899. - conf_data = PCI_CARDBUS_CIS_POINTER;
  3900. + cfg = PCI_CARDBUS_CIS_POINTER;
  3901. break;
  3902. case PCI_SUBSYSTEM_VENDOR_ID:
  3903. - conf_data =
  3904. - CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
  3905. + cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID,
  3906. + CS5536_SUB_VENDOR_ID);
  3907. break;
  3908. case PCI_ROM_ADDRESS:
  3909. - conf_data = PCI_EXPANSION_ROM_BAR;
  3910. + cfg = PCI_EXPANSION_ROM_BAR;
  3911. break;
  3912. case PCI_CAPABILITY_LIST:
  3913. - conf_data = PCI_CAPLIST_POINTER;
  3914. + cfg = PCI_CAPLIST_POINTER;
  3915. break;
  3916. case PCI_INTERRUPT_LINE:
  3917. - conf_data =
  3918. - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
  3919. - break;
  3920. - case PCI_IDE_CFG_REG:
  3921. - _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
  3922. - conf_data = lo;
  3923. - break;
  3924. - case PCI_IDE_DTC_REG:
  3925. - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
  3926. - conf_data = lo;
  3927. - break;
  3928. - case PCI_IDE_CAST_REG:
  3929. - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
  3930. - conf_data = lo;
  3931. - break;
  3932. - case PCI_IDE_ETC_REG:
  3933. - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
  3934. - conf_data = lo;
  3935. - case PCI_IDE_PM_REG:
  3936. - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
  3937. - conf_data = lo;
  3938. + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
  3939. break;
  3940. +#define GET_PCI_IDE_REG(r) \
  3941. + case PCI_IDE_##r##_REG: \
  3942. + _rdmsr(IDE_MSR_REG(IDE_##r), &hi, &cfg); \
  3943. + break;
  3944. + GET_PCI_IDE_REG(CFG)
  3945. + GET_PCI_IDE_REG(DTC)
  3946. + GET_PCI_IDE_REG(CAST)
  3947. + GET_PCI_IDE_REG(ETC)
  3948. + GET_PCI_IDE_REG(PM)
  3949. default:
  3950. break;
  3951. }
  3952. - return conf_data;
  3953. + return cfg;
  3954. }
  3955. 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
  3956. --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-05-16 23:17:36.000000000 +0200
  3957. +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_isa.c 2010-05-27 18:12:28.902214422 +0200
  3958. @@ -61,7 +61,7 @@
  3959. for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
  3960. _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
  3961. hi |= 0x01;
  3962. - _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
  3963. + _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
  3964. }
  3965. }
  3966. @@ -76,7 +76,7 @@
  3967. for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
  3968. _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
  3969. hi &= ~0x01;
  3970. - _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo);
  3971. + _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
  3972. }
  3973. }
  3974. @@ -86,7 +86,7 @@
  3975. void pci_isa_write_bar(int n, u32 value)
  3976. {
  3977. - u32 hi = 0, lo = value;
  3978. + u32 hi, lo;
  3979. if (value == PCI_BAR_RANGE_MASK) {
  3980. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  3981. @@ -95,7 +95,7 @@
  3982. } else if (value & 0x01) {
  3983. /* NATIVE reg */
  3984. hi = 0x0000f001;
  3985. - lo &= bar_space_range[n];
  3986. + lo = value & bar_space_range[n];
  3987. _wrmsr(divil_msr_reg[n], hi, lo);
  3988. /* RCONFx is 4bytes in units for I/O space */
  3989. @@ -112,21 +112,21 @@
  3990. u32 pci_isa_read_bar(int n)
  3991. {
  3992. - u32 conf_data = 0;
  3993. + u32 cfg = 0;
  3994. u32 hi, lo;
  3995. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  3996. if (lo & soft_bar_flag[n]) {
  3997. - conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
  3998. + cfg = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
  3999. lo &= ~soft_bar_flag[n];
  4000. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  4001. } else {
  4002. _rdmsr(divil_msr_reg[n], &hi, &lo);
  4003. - conf_data = lo & bar_space_range[n];
  4004. - conf_data |= 0x01;
  4005. - conf_data &= ~0x02;
  4006. + cfg = lo & bar_space_range[n];
  4007. + cfg |= 0x01;
  4008. + cfg &= ~0x02;
  4009. }
  4010. - return conf_data;
  4011. + return cfg;
  4012. }
  4013. /*
  4014. @@ -136,7 +136,7 @@
  4015. */
  4016. void pci_isa_write_reg(int reg, u32 value)
  4017. {
  4018. - u32 hi = 0, lo = value;
  4019. + u32 hi, lo;
  4020. u32 temp;
  4021. switch (reg) {
  4022. @@ -230,45 +230,45 @@
  4023. */
  4024. u32 pci_isa_read_reg(int reg)
  4025. {
  4026. - u32 conf_data = 0;
  4027. + u32 cfg = 0;
  4028. u32 hi, lo;
  4029. switch (reg) {
  4030. case PCI_VENDOR_ID:
  4031. - conf_data =
  4032. - CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID);
  4033. + cfg = CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID,
  4034. + CS5536_VENDOR_ID);
  4035. break;
  4036. case PCI_COMMAND:
  4037. /* we just check the first LBAR for the IO enable bit, */
  4038. /* maybe we should changed later. */
  4039. _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
  4040. if (hi & 0x01)
  4041. - conf_data |= PCI_COMMAND_IO;
  4042. + cfg |= PCI_COMMAND_IO;
  4043. break;
  4044. case PCI_STATUS:
  4045. - conf_data |= PCI_STATUS_66MHZ;
  4046. - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
  4047. - conf_data |= PCI_STATUS_FAST_BACK;
  4048. + cfg |= PCI_STATUS_66MHZ;
  4049. + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
  4050. + cfg |= PCI_STATUS_FAST_BACK;
  4051. _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  4052. if (lo & SB_TAS_ERR_FLAG)
  4053. - conf_data |= PCI_STATUS_SIG_TARGET_ABORT;
  4054. + cfg |= PCI_STATUS_SIG_TARGET_ABORT;
  4055. if (lo & SB_TAR_ERR_FLAG)
  4056. - conf_data |= PCI_STATUS_REC_TARGET_ABORT;
  4057. + cfg |= PCI_STATUS_REC_TARGET_ABORT;
  4058. if (lo & SB_MAR_ERR_FLAG)
  4059. - conf_data |= PCI_STATUS_REC_MASTER_ABORT;
  4060. + cfg |= PCI_STATUS_REC_MASTER_ABORT;
  4061. if (lo & SB_PARE_ERR_FLAG)
  4062. - conf_data |= PCI_STATUS_DETECTED_PARITY;
  4063. + cfg |= PCI_STATUS_DETECTED_PARITY;
  4064. break;
  4065. case PCI_CLASS_REVISION:
  4066. _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
  4067. - conf_data = lo & 0x000000ff;
  4068. - conf_data |= (CS5536_ISA_CLASS_CODE << 8);
  4069. + cfg = lo & 0x000000ff;
  4070. + cfg |= (CS5536_ISA_CLASS_CODE << 8);
  4071. break;
  4072. case PCI_CACHE_LINE_SIZE:
  4073. _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
  4074. hi &= 0x000000f8;
  4075. - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
  4076. + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
  4077. break;
  4078. /*
  4079. * we only use the LBAR of DIVIL, no RCONF used.
  4080. @@ -292,25 +292,25 @@
  4081. return pci_isa_read_bar(5);
  4082. break;
  4083. case PCI_CARDBUS_CIS:
  4084. - conf_data = PCI_CARDBUS_CIS_POINTER;
  4085. + cfg = PCI_CARDBUS_CIS_POINTER;
  4086. break;
  4087. case PCI_SUBSYSTEM_VENDOR_ID:
  4088. - conf_data =
  4089. - CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID);
  4090. + cfg = CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID,
  4091. + CS5536_SUB_VENDOR_ID);
  4092. break;
  4093. case PCI_ROM_ADDRESS:
  4094. - conf_data = PCI_EXPANSION_ROM_BAR;
  4095. + cfg = PCI_EXPANSION_ROM_BAR;
  4096. break;
  4097. case PCI_CAPABILITY_LIST:
  4098. - conf_data = PCI_CAPLIST_POINTER;
  4099. + cfg = PCI_CAPLIST_POINTER;
  4100. break;
  4101. case PCI_INTERRUPT_LINE:
  4102. /* no interrupt used here */
  4103. - conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
  4104. + cfg = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
  4105. break;
  4106. default:
  4107. break;
  4108. }
  4109. - return conf_data;
  4110. + return cfg;
  4111. }
  4112. 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
  4113. --- linux-2.6.34.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-05-16 23:17:36.000000000 +0200
  4114. +++ linux-loongson/arch/mips/loongson/common/cs5536/cs5536_ohci.c 2010-05-27 18:12:28.902214422 +0200
  4115. @@ -18,7 +18,7 @@
  4116. void pci_ohci_write_reg(int reg, u32 value)
  4117. {
  4118. - u32 hi = 0, lo = value;
  4119. + u32 hi, lo;
  4120. switch (reg) {
  4121. case PCI_COMMAND:
  4122. @@ -49,6 +49,8 @@
  4123. lo |= SOFT_BAR_OHCI_FLAG;
  4124. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  4125. } else if ((value & 0x01) == 0x00) {
  4126. + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
  4127. + lo = value;
  4128. _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
  4129. value &= 0xfffffff0;
  4130. @@ -71,77 +73,75 @@
  4131. u32 pci_ohci_read_reg(int reg)
  4132. {
  4133. - u32 conf_data = 0;
  4134. + u32 cfg = 0;
  4135. u32 hi, lo;
  4136. switch (reg) {
  4137. case PCI_VENDOR_ID:
  4138. - conf_data =
  4139. - CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
  4140. + cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID,
  4141. + CS5536_VENDOR_ID);
  4142. break;
  4143. case PCI_COMMAND:
  4144. _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
  4145. if (hi & PCI_COMMAND_MASTER)
  4146. - conf_data |= PCI_COMMAND_MASTER;
  4147. + cfg |= PCI_COMMAND_MASTER;
  4148. if (hi & PCI_COMMAND_MEMORY)
  4149. - conf_data |= PCI_COMMAND_MEMORY;
  4150. + cfg |= PCI_COMMAND_MEMORY;
  4151. break;
  4152. case PCI_STATUS:
  4153. - conf_data |= PCI_STATUS_66MHZ;
  4154. - conf_data |= PCI_STATUS_FAST_BACK;
  4155. + cfg |= PCI_STATUS_66MHZ;
  4156. + cfg |= PCI_STATUS_FAST_BACK;
  4157. _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  4158. if (lo & SB_PARE_ERR_FLAG)
  4159. - conf_data |= PCI_STATUS_PARITY;
  4160. - conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
  4161. + cfg |= PCI_STATUS_PARITY;
  4162. + cfg |= PCI_STATUS_DEVSEL_MEDIUM;
  4163. break;
  4164. case PCI_CLASS_REVISION:
  4165. _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
  4166. - conf_data = lo & 0x000000ff;
  4167. - conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
  4168. + cfg = lo & 0x000000ff;
  4169. + cfg |= (CS5536_OHCI_CLASS_CODE << 8);
  4170. break;
  4171. case PCI_CACHE_LINE_SIZE:
  4172. - conf_data =
  4173. - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
  4174. - PCI_NORMAL_LATENCY_TIMER);
  4175. + cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
  4176. + PCI_NORMAL_LATENCY_TIMER);
  4177. break;
  4178. case PCI_BAR0_REG:
  4179. _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  4180. if (lo & SOFT_BAR_OHCI_FLAG) {
  4181. - conf_data = CS5536_OHCI_RANGE |
  4182. + cfg = CS5536_OHCI_RANGE |
  4183. PCI_BASE_ADDRESS_SPACE_MEMORY;
  4184. lo &= ~SOFT_BAR_OHCI_FLAG;
  4185. _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  4186. } else {
  4187. _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
  4188. - conf_data = lo & 0xffffff00;
  4189. - conf_data &= ~0x0000000f; /* 32bit mem */
  4190. + cfg = lo & 0xffffff00;
  4191. + cfg &= ~0x0000000f; /* 32bit mem */
  4192. }
  4193. break;
  4194. case PCI_CARDBUS_CIS:
  4195. - conf_data = PCI_CARDBUS_CIS_POINTER;
  4196. + cfg = PCI_CARDBUS_CIS_POINTER;
  4197. break;
  4198. case PCI_SUBSYSTEM_VENDOR_ID:
  4199. - conf_data =
  4200. - CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
  4201. + cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID,
  4202. + CS5536_SUB_VENDOR_ID);
  4203. break;
  4204. case PCI_ROM_ADDRESS:
  4205. - conf_data = PCI_EXPANSION_ROM_BAR;
  4206. + cfg = PCI_EXPANSION_ROM_BAR;
  4207. break;
  4208. case PCI_CAPABILITY_LIST:
  4209. - conf_data = PCI_CAPLIST_USB_POINTER;
  4210. + cfg = PCI_CAPLIST_USB_POINTER;
  4211. break;
  4212. case PCI_INTERRUPT_LINE:
  4213. - conf_data =
  4214. - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
  4215. + cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
  4216. break;
  4217. case PCI_OHCI_INT_REG:
  4218. _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
  4219. if ((lo & 0x00000f00) == CS5536_USB_INTR)
  4220. - conf_data = 1;
  4221. + cfg = 1;
  4222. break;
  4223. default:
  4224. break;
  4225. }
  4226. - return conf_data;
  4227. + return cfg;
  4228. }
  4229. diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/gpio.c linux-loongson/arch/mips/loongson/common/gpio.c
  4230. --- linux-2.6.34.orig/arch/mips/loongson/common/gpio.c 1970-01-01 01:00:00.000000000 +0100
  4231. +++ linux-loongson/arch/mips/loongson/common/gpio.c 2010-05-27 18:12:28.902214422 +0200
  4232. @@ -0,0 +1,139 @@
  4233. +/*
  4234. + * STLS2F GPIO Support
  4235. + *
  4236. + * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
  4237. + * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
  4238. + *
  4239. + * This program is free software; you can redistribute it and/or modify
  4240. + * it under the terms of the GNU General Public License as published by
  4241. + * the Free Software Foundation; either version 2 of the License, or
  4242. + * (at your option) any later version.
  4243. + */
  4244. +
  4245. +#include <linux/kernel.h>
  4246. +#include <linux/init.h>
  4247. +#include <linux/module.h>
  4248. +#include <linux/spinlock.h>
  4249. +#include <linux/err.h>
  4250. +#include <asm/types.h>
  4251. +#include <loongson.h>
  4252. +#include <linux/gpio.h>
  4253. +
  4254. +#define STLS2F_N_GPIO 4
  4255. +#define STLS2F_GPIO_IN_OFFSET 16
  4256. +
  4257. +static DEFINE_SPINLOCK(gpio_lock);
  4258. +
  4259. +int gpio_get_value(unsigned gpio)
  4260. +{
  4261. + u32 val;
  4262. + u32 mask;
  4263. +
  4264. + if (gpio >= STLS2F_N_GPIO)
  4265. + return __gpio_get_value(gpio);
  4266. +
  4267. + mask = 1 << (gpio + STLS2F_GPIO_IN_OFFSET);
  4268. + spin_lock(&gpio_lock);
  4269. + val = LOONGSON_GPIODATA;
  4270. + spin_unlock(&gpio_lock);
  4271. +
  4272. + return ((val & mask) != 0);
  4273. +}
  4274. +EXPORT_SYMBOL(gpio_get_value);
  4275. +
  4276. +void gpio_set_value(unsigned gpio, int state)
  4277. +{
  4278. + u32 val;
  4279. + u32 mask;
  4280. +
  4281. + if (gpio >= STLS2F_N_GPIO) {
  4282. + __gpio_set_value(gpio, state);
  4283. + return ;
  4284. + }
  4285. +
  4286. + mask = 1 << gpio;
  4287. +
  4288. + spin_lock(&gpio_lock);
  4289. + val = LOONGSON_GPIODATA;
  4290. + if (state)
  4291. + val |= mask;
  4292. + else
  4293. + val &= (~mask);
  4294. + LOONGSON_GPIODATA = val;
  4295. + spin_unlock(&gpio_lock);
  4296. +}
  4297. +EXPORT_SYMBOL(gpio_set_value);
  4298. +
  4299. +int gpio_cansleep(unsigned gpio)
  4300. +{
  4301. + if (gpio < STLS2F_N_GPIO)
  4302. + return 0;
  4303. + else
  4304. + return __gpio_cansleep(gpio);
  4305. +}
  4306. +EXPORT_SYMBOL(gpio_cansleep);
  4307. +
  4308. +static int ls2f_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
  4309. +{
  4310. + u32 temp;
  4311. + u32 mask;
  4312. +
  4313. + if (gpio >= STLS2F_N_GPIO)
  4314. + return -EINVAL;
  4315. +
  4316. + spin_lock(&gpio_lock);
  4317. + mask = 1 << gpio;
  4318. + temp = LOONGSON_GPIOIE;
  4319. + temp |= mask;
  4320. + LOONGSON_GPIOIE = temp;
  4321. + spin_unlock(&gpio_lock);
  4322. +
  4323. + return 0;
  4324. +}
  4325. +
  4326. +static int ls2f_gpio_direction_output(struct gpio_chip *chip,
  4327. + unsigned gpio, int level)
  4328. +{
  4329. + u32 temp;
  4330. + u32 mask;
  4331. +
  4332. + if (gpio >= STLS2F_N_GPIO)
  4333. + return -EINVAL;
  4334. +
  4335. + gpio_set_value(gpio, level);
  4336. + spin_lock(&gpio_lock);
  4337. + mask = 1 << gpio;
  4338. + temp = LOONGSON_GPIOIE;
  4339. + temp &= (~mask);
  4340. + LOONGSON_GPIOIE = temp;
  4341. + spin_unlock(&gpio_lock);
  4342. +
  4343. + return 0;
  4344. +}
  4345. +
  4346. +static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
  4347. +{
  4348. + return gpio_get_value(gpio);
  4349. +}
  4350. +
  4351. +static void ls2f_gpio_set_value(struct gpio_chip *chip,
  4352. + unsigned gpio, int value)
  4353. +{
  4354. + gpio_set_value(gpio, value);
  4355. +}
  4356. +
  4357. +static struct gpio_chip ls2f_chip = {
  4358. + .label = "ls2f",
  4359. + .direction_input = ls2f_gpio_direction_input,
  4360. + .get = ls2f_gpio_get_value,
  4361. + .direction_output = ls2f_gpio_direction_output,
  4362. + .set = ls2f_gpio_set_value,
  4363. + .base = 0,
  4364. + .ngpio = STLS2F_N_GPIO,
  4365. +};
  4366. +
  4367. +static int __init ls2f_gpio_setup(void)
  4368. +{
  4369. + return gpiochip_add(&ls2f_chip);
  4370. +}
  4371. +arch_initcall(ls2f_gpio_setup);
  4372. diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/Makefile linux-loongson/arch/mips/loongson/common/Makefile
  4373. --- linux-2.6.34.orig/arch/mips/loongson/common/Makefile 2010-05-16 23:17:36.000000000 +0200
  4374. +++ linux-loongson/arch/mips/loongson/common/Makefile 2010-05-27 18:12:28.902214422 +0200
  4375. @@ -4,6 +4,7 @@
  4376. obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
  4377. pci.o bonito-irq.o mem.o machtype.o platform.o
  4378. +obj-$(CONFIG_GENERIC_GPIO) += gpio.o
  4379. #
  4380. # Serial port support
  4381. @@ -23,3 +24,9 @@
  4382. #
  4383. obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
  4384. +
  4385. +# Enable RTC Class support
  4386. +#
  4387. +# please enable CONFIG_RTC_DRV_CMOS
  4388. +#
  4389. +obj-$(CONFIG_RTC_DRV_CMOS) += rtc.o
  4390. diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/mtd.c linux-loongson/arch/mips/loongson/common/mtd.c
  4391. --- linux-2.6.34.orig/arch/mips/loongson/common/mtd.c 1970-01-01 01:00:00.000000000 +0100
  4392. +++ linux-loongson/arch/mips/loongson/common/mtd.c 2010-05-27 18:12:28.902214422 +0200
  4393. @@ -0,0 +1,91 @@
  4394. +/*
  4395. + * Driver for flushing/dumping ROM of PMON on loongson family machines
  4396. + *
  4397. + * Copyright (C) 2008-2009 Lemote Inc.
  4398. + * Author: Yan Hua <yanh@lemote.com>
  4399. + *
  4400. + * This program is free software; you can redistribute it and/or modify it
  4401. + * under the terms of the GNU General Public License as published by the
  4402. + * Free Software Foundation; either version 2 of the License, or (at your
  4403. + * option) any later version.
  4404. + */
  4405. +
  4406. +#include <linux/module.h>
  4407. +#include <linux/types.h>
  4408. +#include <linux/kernel.h>
  4409. +#include <linux/init.h>
  4410. +#include <linux/mtd/mtd.h>
  4411. +#include <linux/mtd/map.h>
  4412. +#include <linux/mtd/partitions.h>
  4413. +
  4414. +#include <asm/io.h>
  4415. +
  4416. +#include <loongson.h>
  4417. +
  4418. +#define FLASH_PHYS_ADDR LOONGSON_BOOT_BASE
  4419. +#define FLASH_SIZE 0x080000
  4420. +
  4421. +#define FLASH_PARTITION0_ADDR 0x00000000
  4422. +#define FLASH_PARTITION0_SIZE 0x00080000
  4423. +
  4424. +struct map_info flash_map = {
  4425. + .name = "flash device",
  4426. + .size = FLASH_SIZE,
  4427. + .bankwidth = 1,
  4428. +};
  4429. +
  4430. +struct mtd_partition flash_parts[] = {
  4431. + {
  4432. + .name = "Bootloader",
  4433. + .offset = FLASH_PARTITION0_ADDR,
  4434. + .size = FLASH_PARTITION0_SIZE},
  4435. +};
  4436. +
  4437. +#define PARTITION_COUNT ARRAY_SIZE(flash_parts)
  4438. +
  4439. +static struct mtd_info *mymtd;
  4440. +
  4441. +int __init init_flash(void)
  4442. +{
  4443. + printk(KERN_NOTICE "flash device: %x at %x\n",
  4444. + FLASH_SIZE, FLASH_PHYS_ADDR);
  4445. +
  4446. + flash_map.phys = FLASH_PHYS_ADDR;
  4447. + flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE);
  4448. +
  4449. + if (!flash_map.virt) {
  4450. + printk(KERN_NOTICE "Failed to ioremap\n");
  4451. + return -EIO;
  4452. + }
  4453. +
  4454. + simple_map_init(&flash_map);
  4455. +
  4456. + mymtd = do_map_probe("cfi_probe", &flash_map);
  4457. + if (mymtd) {
  4458. + add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT);
  4459. + printk(KERN_NOTICE "pmon flash device initialized\n");
  4460. + return 0;
  4461. + }
  4462. +
  4463. + iounmap((void *)flash_map.virt);
  4464. + return -ENXIO;
  4465. +}
  4466. +
  4467. +static void __exit cleanup_flash(void)
  4468. +{
  4469. + if (mymtd) {
  4470. + del_mtd_partitions(mymtd);
  4471. + map_destroy(mymtd);
  4472. + }
  4473. + if (flash_map.virt) {
  4474. + iounmap((void *)flash_map.virt);
  4475. + flash_map.virt = 0;
  4476. + }
  4477. +}
  4478. +
  4479. +module_init(init_flash);
  4480. +module_exit(cleanup_flash);
  4481. +
  4482. +MODULE_LICENSE("GPL");
  4483. +MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
  4484. +MODULE_DESCRIPTION("MTD driver for pmon flushing/dumping");
  4485. diff -Nur linux-2.6.34.orig/arch/mips/loongson/common/rtc.c linux-loongson/arch/mips/loongson/common/rtc.c
  4486. --- linux-2.6.34.orig/arch/mips/loongson/common/rtc.c 1970-01-01 01:00:00.000000000 +0100
  4487. +++ linux-loongson/arch/mips/loongson/common/rtc.c 2010-05-27 18:12:28.902214422 +0200
  4488. @@ -0,0 +1,43 @@
  4489. +/*
  4490. + * Registration of Loongson RTC platform device.
  4491. + *
  4492. + * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  4493. + * Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
  4494. + *
  4495. + * This program is free software; you can redistribute it and/or modify
  4496. + * it under the terms of the GNU General Public License as published by
  4497. + * the Free Software Foundation; either version 2 of the License, or
  4498. + * (at your option) any later version.
  4499. + */
  4500. +
  4501. +#include <linux/init.h>
  4502. +#include <linux/ioport.h>
  4503. +#include <linux/mc146818rtc.h>
  4504. +#include <linux/platform_device.h>
  4505. +
  4506. +static struct resource rtc_cmos_resource[] = {
  4507. + {
  4508. + .start = RTC_PORT(0),
  4509. + .end = RTC_PORT(1),
  4510. + .flags = IORESOURCE_IO,
  4511. + },
  4512. + {
  4513. + .start = RTC_IRQ,
  4514. + .end = RTC_IRQ,
  4515. + .flags = IORESOURCE_IRQ,
  4516. + },
  4517. +};
  4518. +
  4519. +static struct platform_device rtc_cmos_device = {
  4520. + .name = "rtc_cmos",
  4521. + .id = -1,
  4522. + .num_resources = ARRAY_SIZE(rtc_cmos_resource),
  4523. + .resource = rtc_cmos_resource
  4524. +};
  4525. +
  4526. +static __init int rtc_cmos_init(void)
  4527. +{
  4528. + return platform_device_register(&rtc_cmos_device);
  4529. +}
  4530. +
  4531. +device_initcall(rtc_cmos_init);
  4532. 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
  4533. --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-05-16 23:17:36.000000000 +0200
  4534. +++ linux-loongson/arch/mips/loongson/lemote-2f/ec_kb3310b.c 2010-05-27 18:12:28.902214422 +0200
  4535. @@ -14,7 +14,7 @@
  4536. #include <linux/spinlock.h>
  4537. #include <linux/delay.h>
  4538. -#include "ec_kb3310b.h"
  4539. +#include <ec_kb3310b.h>
  4540. static DEFINE_SPINLOCK(index_access_lock);
  4541. static DEFINE_SPINLOCK(port_access_lock);
  4542. @@ -78,12 +78,9 @@
  4543. spin_unlock_irqrestore(&port_access_lock, flags);
  4544. if (timeout <= 0) {
  4545. - printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
  4546. + pr_err("%s: deadable error : timeout...\n", __func__);
  4547. ret = -EINVAL;
  4548. - } else
  4549. - printk(KERN_INFO
  4550. - "(%x/%d)ec issued command %d status : 0x%x\n",
  4551. - timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
  4552. + }
  4553. return ret;
  4554. }
  4555. @@ -118,8 +115,7 @@
  4556. udelay(EC_REG_DELAY);
  4557. }
  4558. if (timeout <= 0) {
  4559. - pr_info("%s: get event number timeout.\n", __func__);
  4560. -
  4561. + pr_err("%s: get event number timeout.\n", __func__);
  4562. return -EINVAL;
  4563. }
  4564. value = inb(EC_DAT_PORT);
  4565. 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
  4566. --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h 2010-05-16 23:17:36.000000000 +0200
  4567. +++ linux-loongson/arch/mips/loongson/lemote-2f/ec_kb3310b.h 1970-01-01 01:00:00.000000000 +0100
  4568. @@ -1,188 +0,0 @@
  4569. -/*
  4570. - * KB3310B Embedded Controller
  4571. - *
  4572. - * Copyright (C) 2008 Lemote Inc.
  4573. - * Author: liujl <liujl@lemote.com>, 2008-03-14
  4574. - *
  4575. - * This program is free software; you can redistribute it and/or modify
  4576. - * it under the terms of the GNU General Public License as published by
  4577. - * the Free Software Foundation; either version 2 of the License, or
  4578. - * (at your option) any later version.
  4579. - */
  4580. -
  4581. -#ifndef _EC_KB3310B_H
  4582. -#define _EC_KB3310B_H
  4583. -
  4584. -extern unsigned char ec_read(unsigned short addr);
  4585. -extern void ec_write(unsigned short addr, unsigned char val);
  4586. -extern int ec_query_seq(unsigned char cmd);
  4587. -extern int ec_query_event_num(void);
  4588. -extern int ec_get_event_num(void);
  4589. -
  4590. -typedef int (*sci_handler) (int status);
  4591. -extern sci_handler yeeloong_report_lid_status;
  4592. -
  4593. -#define SCI_IRQ_NUM 0x0A
  4594. -
  4595. -/*
  4596. - * The following registers are determined by the EC index configuration.
  4597. - * 1, fill the PORT_HIGH as EC register high part.
  4598. - * 2, fill the PORT_LOW as EC register low part.
  4599. - * 3, fill the PORT_DATA as EC register write data or get the data from it.
  4600. - */
  4601. -#define EC_IO_PORT_HIGH 0x0381
  4602. -#define EC_IO_PORT_LOW 0x0382
  4603. -#define EC_IO_PORT_DATA 0x0383
  4604. -
  4605. -/*
  4606. - * EC delay time is 500us for register and status access
  4607. - */
  4608. -#define EC_REG_DELAY 500 /* unit : us */
  4609. -#define EC_CMD_TIMEOUT 0x1000
  4610. -
  4611. -/*
  4612. - * EC access port for SCI communication
  4613. - */
  4614. -#define EC_CMD_PORT 0x66
  4615. -#define EC_STS_PORT 0x66
  4616. -#define EC_DAT_PORT 0x62
  4617. -#define CMD_INIT_IDLE_MODE 0xdd
  4618. -#define CMD_EXIT_IDLE_MODE 0xdf
  4619. -#define CMD_INIT_RESET_MODE 0xd8
  4620. -#define CMD_REBOOT_SYSTEM 0x8c
  4621. -#define CMD_GET_EVENT_NUM 0x84
  4622. -#define CMD_PROGRAM_PIECE 0xda
  4623. -
  4624. -/* temperature & fan registers */
  4625. -#define REG_TEMPERATURE_VALUE 0xF458
  4626. -#define REG_FAN_AUTO_MAN_SWITCH 0xF459
  4627. -#define BIT_FAN_AUTO 0
  4628. -#define BIT_FAN_MANUAL 1
  4629. -#define REG_FAN_CONTROL 0xF4D2
  4630. -#define BIT_FAN_CONTROL_ON (1 << 0)
  4631. -#define BIT_FAN_CONTROL_OFF (0 << 0)
  4632. -#define REG_FAN_STATUS 0xF4DA
  4633. -#define BIT_FAN_STATUS_ON (1 << 0)
  4634. -#define BIT_FAN_STATUS_OFF (0 << 0)
  4635. -#define REG_FAN_SPEED_HIGH 0xFE22
  4636. -#define REG_FAN_SPEED_LOW 0xFE23
  4637. -#define REG_FAN_SPEED_LEVEL 0xF4CC
  4638. -/* fan speed divider */
  4639. -#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
  4640. -
  4641. -/* battery registers */
  4642. -#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
  4643. -#define REG_BAT_DESIGN_CAP_LOW 0xF77E
  4644. -#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
  4645. -#define REG_BAT_FULLCHG_CAP_LOW 0xF781
  4646. -#define REG_BAT_DESIGN_VOL_HIGH 0xF782
  4647. -#define REG_BAT_DESIGN_VOL_LOW 0xF783
  4648. -#define REG_BAT_CURRENT_HIGH 0xF784
  4649. -#define REG_BAT_CURRENT_LOW 0xF785
  4650. -#define REG_BAT_VOLTAGE_HIGH 0xF786
  4651. -#define REG_BAT_VOLTAGE_LOW 0xF787
  4652. -#define REG_BAT_TEMPERATURE_HIGH 0xF788
  4653. -#define REG_BAT_TEMPERATURE_LOW 0xF789
  4654. -#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
  4655. -#define REG_BAT_RELATIVE_CAP_LOW 0xF493
  4656. -#define REG_BAT_VENDOR 0xF4C4
  4657. -#define FLAG_BAT_VENDOR_SANYO 0x01
  4658. -#define FLAG_BAT_VENDOR_SIMPLO 0x02
  4659. -#define REG_BAT_CELL_COUNT 0xF4C6
  4660. -#define FLAG_BAT_CELL_3S1P 0x03
  4661. -#define FLAG_BAT_CELL_3S2P 0x06
  4662. -#define REG_BAT_CHARGE 0xF4A2
  4663. -#define FLAG_BAT_CHARGE_DISCHARGE 0x01
  4664. -#define FLAG_BAT_CHARGE_CHARGE 0x02
  4665. -#define FLAG_BAT_CHARGE_ACPOWER 0x00
  4666. -#define REG_BAT_STATUS 0xF4B0
  4667. -#define BIT_BAT_STATUS_LOW (1 << 5)
  4668. -#define BIT_BAT_STATUS_DESTROY (1 << 2)
  4669. -#define BIT_BAT_STATUS_FULL (1 << 1)
  4670. -#define BIT_BAT_STATUS_IN (1 << 0)
  4671. -#define REG_BAT_CHARGE_STATUS 0xF4B1
  4672. -#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
  4673. -#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
  4674. -#define REG_BAT_STATE 0xF482
  4675. -#define BIT_BAT_STATE_CHARGING (1 << 1)
  4676. -#define BIT_BAT_STATE_DISCHARGING (1 << 0)
  4677. -#define REG_BAT_POWER 0xF440
  4678. -#define BIT_BAT_POWER_S3 (1 << 2)
  4679. -#define BIT_BAT_POWER_ON (1 << 1)
  4680. -#define BIT_BAT_POWER_ACIN (1 << 0)
  4681. -
  4682. -/* other registers */
  4683. -/* Audio: rd/wr */
  4684. -#define REG_AUDIO_VOLUME 0xF46C
  4685. -#define REG_AUDIO_MUTE 0xF4E7
  4686. -#define REG_AUDIO_BEEP 0xF4D0
  4687. -/* USB port power or not: rd/wr */
  4688. -#define REG_USB0_FLAG 0xF461
  4689. -#define REG_USB1_FLAG 0xF462
  4690. -#define REG_USB2_FLAG 0xF463
  4691. -#define BIT_USB_FLAG_ON 1
  4692. -#define BIT_USB_FLAG_OFF 0
  4693. -/* LID */
  4694. -#define REG_LID_DETECT 0xF4BD
  4695. -#define BIT_LID_DETECT_ON 1
  4696. -#define BIT_LID_DETECT_OFF 0
  4697. -/* CRT */
  4698. -#define REG_CRT_DETECT 0xF4AD
  4699. -#define BIT_CRT_DETECT_PLUG 1
  4700. -#define BIT_CRT_DETECT_UNPLUG 0
  4701. -/* LCD backlight brightness adjust: 9 levels */
  4702. -#define REG_DISPLAY_BRIGHTNESS 0xF4F5
  4703. -/* Black screen Status */
  4704. -#define BIT_DISPLAY_LCD_ON 1
  4705. -#define BIT_DISPLAY_LCD_OFF 0
  4706. -/* LCD backlight control: off/restore */
  4707. -#define REG_BACKLIGHT_CTRL 0xF7BD
  4708. -#define BIT_BACKLIGHT_ON 1
  4709. -#define BIT_BACKLIGHT_OFF 0
  4710. -/* Reset the machine auto-clear: rd/wr */
  4711. -#define REG_RESET 0xF4EC
  4712. -#define BIT_RESET_ON 1
  4713. -/* Light the led: rd/wr */
  4714. -#define REG_LED 0xF4C8
  4715. -#define BIT_LED_RED_POWER (1 << 0)
  4716. -#define BIT_LED_ORANGE_POWER (1 << 1)
  4717. -#define BIT_LED_GREEN_CHARGE (1 << 2)
  4718. -#define BIT_LED_RED_CHARGE (1 << 3)
  4719. -#define BIT_LED_NUMLOCK (1 << 4)
  4720. -/* Test led mode, all led on/off */
  4721. -#define REG_LED_TEST 0xF4C2
  4722. -#define BIT_LED_TEST_IN 1
  4723. -#define BIT_LED_TEST_OUT 0
  4724. -/* Camera on/off */
  4725. -#define REG_CAMERA_STATUS 0xF46A
  4726. -#define BIT_CAMERA_STATUS_ON 1
  4727. -#define BIT_CAMERA_STATUS_OFF 0
  4728. -#define REG_CAMERA_CONTROL 0xF7B7
  4729. -#define BIT_CAMERA_CONTROL_OFF 0
  4730. -#define BIT_CAMERA_CONTROL_ON 1
  4731. -/* Wlan Status */
  4732. -#define REG_WLAN 0xF4FA
  4733. -#define BIT_WLAN_ON 1
  4734. -#define BIT_WLAN_OFF 0
  4735. -#define REG_DISPLAY_LCD 0xF79F
  4736. -
  4737. -/* SCI Event Number from EC */
  4738. -enum {
  4739. - EVENT_LID = 0x23, /* LID open/close */
  4740. - EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
  4741. - EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
  4742. - EVENT_OVERTEMP, /* Over-temperature happened */
  4743. - EVENT_CRT_DETECT, /* CRT is connected */
  4744. - EVENT_CAMERA, /* Camera on/off */
  4745. - EVENT_USB_OC2, /* USB2 Over Current occurred */
  4746. - EVENT_USB_OC0, /* USB0 Over Current occurred */
  4747. - EVENT_BLACK_SCREEN, /* Turn on/off backlight */
  4748. - EVENT_AUDIO_MUTE, /* Mute on/off */
  4749. - EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
  4750. - EVENT_AC_BAT, /* AC & Battery relative issue */
  4751. - EVENT_AUDIO_VOLUME, /* Volume adjust */
  4752. - EVENT_WLAN, /* Wlan on/off */
  4753. - EVENT_END
  4754. -};
  4755. -
  4756. -#endif /* !_EC_KB3310B_H */
  4757. diff -Nur linux-2.6.34.orig/arch/mips/loongson/lemote-2f/Makefile linux-loongson/arch/mips/loongson/lemote-2f/Makefile
  4758. --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/Makefile 2010-05-16 23:17:36.000000000 +0200
  4759. +++ linux-loongson/arch/mips/loongson/lemote-2f/Makefile 2010-05-27 18:12:28.902214422 +0200
  4760. @@ -2,7 +2,7 @@
  4761. # Makefile for lemote loongson2f family machines
  4762. #
  4763. -obj-y += machtype.o irq.o reset.o ec_kb3310b.o
  4764. +obj-y += machtype.o irq.o reset.o ec_kb3310b.o platform.o
  4765. #
  4766. # Suspend Support
  4767. diff -Nur linux-2.6.34.orig/arch/mips/loongson/lemote-2f/platform.c linux-loongson/arch/mips/loongson/lemote-2f/platform.c
  4768. --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/platform.c 1970-01-01 01:00:00.000000000 +0100
  4769. +++ linux-loongson/arch/mips/loongson/lemote-2f/platform.c 2010-05-27 18:12:28.902214422 +0200
  4770. @@ -0,0 +1,48 @@
  4771. +/*
  4772. + * Copyright (C) 2009 Lemote Inc.
  4773. + * Author: Wu Zhangjin, wuzhangjin@gmail.com
  4774. + *
  4775. + * This program is free software; you can redistribute it and/or modify it
  4776. + * under the terms of the GNU General Public License as published by the
  4777. + * Free Software Foundation; either version 2 of the License, or (at your
  4778. + * option) any later version.
  4779. + */
  4780. +
  4781. +#include <linux/err.h>
  4782. +#include <linux/platform_device.h>
  4783. +
  4784. +#include <asm/bootinfo.h>
  4785. +
  4786. +static struct platform_device yeeloong_pdev = {
  4787. + .name = "yeeloong_laptop",
  4788. + .id = -1,
  4789. +};
  4790. +
  4791. +static struct platform_device lynloong_pdev = {
  4792. + .name = "lynloong_pc",
  4793. + .id = -1,
  4794. +};
  4795. +
  4796. +static int __init lemote2f_platform_init(void)
  4797. +{
  4798. + struct platform_device *pdev = NULL;
  4799. +
  4800. + switch (mips_machtype) {
  4801. + case MACH_LEMOTE_YL2F89:
  4802. + pdev = &yeeloong_pdev;
  4803. + break;
  4804. + case MACH_LEMOTE_LL2F:
  4805. + pdev = &lynloong_pdev;
  4806. + break;
  4807. + default:
  4808. + break;
  4809. +
  4810. + }
  4811. +
  4812. + if (pdev != NULL)
  4813. + return platform_device_register(pdev);
  4814. +
  4815. + return -ENODEV;
  4816. +}
  4817. +
  4818. +arch_initcall(lemote2f_platform_init);
  4819. diff -Nur linux-2.6.34.orig/arch/mips/loongson/lemote-2f/pm.c linux-loongson/arch/mips/loongson/lemote-2f/pm.c
  4820. --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/pm.c 2010-05-16 23:17:36.000000000 +0200
  4821. +++ linux-loongson/arch/mips/loongson/lemote-2f/pm.c 2010-05-27 18:12:28.902214422 +0200
  4822. @@ -23,7 +23,7 @@
  4823. #include <loongson.h>
  4824. #include <cs5536/cs5536_mfgpt.h>
  4825. -#include "ec_kb3310b.h"
  4826. +#include <ec_kb3310b.h>
  4827. #define I8042_KBD_IRQ 1
  4828. #define I8042_CTR_KBDINT 0x01
  4829. @@ -100,7 +100,7 @@
  4830. if (irq < 0)
  4831. return 0;
  4832. - printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
  4833. + pr_info("%s: irq = %d\n", __func__, irq);
  4834. if (irq == I8042_KBD_IRQ)
  4835. return 1;
  4836. diff -Nur linux-2.6.34.orig/arch/mips/loongson/lemote-2f/reset.c linux-loongson/arch/mips/loongson/lemote-2f/reset.c
  4837. --- linux-2.6.34.orig/arch/mips/loongson/lemote-2f/reset.c 2010-05-16 23:17:36.000000000 +0200
  4838. +++ linux-loongson/arch/mips/loongson/lemote-2f/reset.c 2010-05-27 18:12:28.902214422 +0200
  4839. @@ -20,7 +20,7 @@
  4840. #include <loongson.h>
  4841. #include <cs5536/cs5536.h>
  4842. -#include "ec_kb3310b.h"
  4843. +#include <ec_kb3310b.h>
  4844. static void reset_cpu(void)
  4845. {
  4846. diff -Nur linux-2.6.34.orig/arch/mips/mm/dma-default.c linux-loongson/arch/mips/mm/dma-default.c
  4847. --- linux-2.6.34.orig/arch/mips/mm/dma-default.c 2010-05-16 23:17:36.000000000 +0200
  4848. +++ linux-loongson/arch/mips/mm/dma-default.c 2010-05-27 18:12:28.932213915 +0200
  4849. @@ -375,3 +375,16 @@
  4850. }
  4851. EXPORT_SYMBOL(dma_cache_sync);
  4852. +
  4853. +int __weak dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
  4854. + void *cpu_addr, dma_addr_t handle, size_t size)
  4855. +{
  4856. + struct page *pg;
  4857. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  4858. + cpu_addr = (void *)dma_addr_to_virt(dev, handle);
  4859. + pg = virt_to_page(cpu_addr);
  4860. + return remap_pfn_range(vma, vma->vm_start,
  4861. + page_to_pfn(pg) + vma->vm_pgoff,
  4862. + size, vma->vm_page_prot);
  4863. +}
  4864. +EXPORT_SYMBOL(dma_mmap_coherent);
  4865. diff -Nur linux-2.6.34.orig/arch/mips/oprofile/op_model_loongson2.c linux-loongson/arch/mips/oprofile/op_model_loongson2.c
  4866. --- linux-2.6.34.orig/arch/mips/oprofile/op_model_loongson2.c 2010-05-16 23:17:36.000000000 +0200
  4867. +++ linux-loongson/arch/mips/oprofile/op_model_loongson2.c 2010-05-27 18:12:28.962214357 +0200
  4868. @@ -8,7 +8,6 @@
  4869. * This file is subject to the terms and conditions of the GNU General Public
  4870. * License. See the file "COPYING" in the main directory of this archive
  4871. * for more details.
  4872. - *
  4873. */
  4874. #include <linux/init.h>
  4875. #include <linux/oprofile.h>
  4876. @@ -17,24 +16,18 @@
  4877. #include <loongson.h> /* LOONGSON2_PERFCNT_IRQ */
  4878. #include "op_impl.h"
  4879. -/*
  4880. - * a patch should be sent to oprofile with the loongson-specific support.
  4881. - * otherwise, the oprofile tool will not recognize this and complain about
  4882. - * "cpu_type 'unset' is not valid".
  4883. - */
  4884. #define LOONGSON2_CPU_TYPE "mips/loongson2"
  4885. -#define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5)
  4886. -#define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9)
  4887. -
  4888. -#define LOONGSON2_PERFCNT_EXL (1UL << 0)
  4889. -#define LOONGSON2_PERFCNT_KERNEL (1UL << 1)
  4890. -#define LOONGSON2_PERFCNT_SUPERVISOR (1UL << 2)
  4891. -#define LOONGSON2_PERFCNT_USER (1UL << 3)
  4892. -#define LOONGSON2_PERFCNT_INT_EN (1UL << 4)
  4893. #define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31)
  4894. -/* Loongson2 performance counter register */
  4895. +#define LOONGSON2_PERFCTRL_EXL (1UL << 0)
  4896. +#define LOONGSON2_PERFCTRL_KERNEL (1UL << 1)
  4897. +#define LOONGSON2_PERFCTRL_SUPERVISOR (1UL << 2)
  4898. +#define LOONGSON2_PERFCTRL_USER (1UL << 3)
  4899. +#define LOONGSON2_PERFCTRL_ENABLE (1UL << 4)
  4900. +#define LOONGSON2_PERFCTRL_EVENT(idx, event) \
  4901. + (((event) & 0x0f) << ((idx) ? 9 : 5))
  4902. +
  4903. #define read_c0_perfctrl() __read_64bit_c0_register($24, 0)
  4904. #define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val)
  4905. #define read_c0_perfcnt() __read_64bit_c0_register($25, 0)
  4906. @@ -49,7 +42,12 @@
  4907. static char *oprofid = "LoongsonPerf";
  4908. static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
  4909. -/* Compute all of the registers in preparation for enabling profiling. */
  4910. +
  4911. +static void reset_counters(void *arg)
  4912. +{
  4913. + write_c0_perfctrl(0);
  4914. + write_c0_perfcnt(0);
  4915. +}
  4916. static void loongson2_reg_setup(struct op_counter_config *cfg)
  4917. {
  4918. @@ -57,41 +55,38 @@
  4919. reg.reset_counter1 = 0;
  4920. reg.reset_counter2 = 0;
  4921. - /* Compute the performance counter ctrl word. */
  4922. - /* For now count kernel and user mode */
  4923. +
  4924. + /*
  4925. + * Compute the performance counter ctrl word.
  4926. + * For now, count kernel and user mode.
  4927. + */
  4928. if (cfg[0].enabled) {
  4929. - ctrl |= LOONGSON2_COUNTER1_EVENT(cfg[0].event);
  4930. + ctrl |= LOONGSON2_PERFCTRL_EVENT(0, cfg[0].event);
  4931. reg.reset_counter1 = 0x80000000ULL - cfg[0].count;
  4932. }
  4933. if (cfg[1].enabled) {
  4934. - ctrl |= LOONGSON2_COUNTER2_EVENT(cfg[1].event);
  4935. - reg.reset_counter2 = (0x80000000ULL - cfg[1].count);
  4936. + ctrl |= LOONGSON2_PERFCTRL_EVENT(1, cfg[1].event);
  4937. + reg.reset_counter2 = 0x80000000ULL - cfg[1].count;
  4938. }
  4939. if (cfg[0].enabled || cfg[1].enabled) {
  4940. - ctrl |= LOONGSON2_PERFCNT_EXL | LOONGSON2_PERFCNT_INT_EN;
  4941. + ctrl |= LOONGSON2_PERFCTRL_EXL | LOONGSON2_PERFCTRL_ENABLE;
  4942. if (cfg[0].kernel || cfg[1].kernel)
  4943. - ctrl |= LOONGSON2_PERFCNT_KERNEL;
  4944. + ctrl |= LOONGSON2_PERFCTRL_KERNEL;
  4945. if (cfg[0].user || cfg[1].user)
  4946. - ctrl |= LOONGSON2_PERFCNT_USER;
  4947. + ctrl |= LOONGSON2_PERFCTRL_USER;
  4948. }
  4949. reg.ctrl = ctrl;
  4950. reg.cnt1_enabled = cfg[0].enabled;
  4951. reg.cnt2_enabled = cfg[1].enabled;
  4952. -
  4953. }
  4954. -/* Program all of the registers in preparation for enabling profiling. */
  4955. -
  4956. static void loongson2_cpu_setup(void *args)
  4957. {
  4958. - uint64_t perfcount;
  4959. -
  4960. - perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1;
  4961. - write_c0_perfcnt(perfcount);
  4962. + write_c0_perfcnt((reg.reset_counter2 << 32) | reg.reset_counter1);
  4963. }
  4964. static void loongson2_cpu_start(void *args)
  4965. @@ -114,15 +109,8 @@
  4966. struct pt_regs *regs = get_irq_regs();
  4967. int enabled;
  4968. - /*
  4969. - * LOONGSON2 defines two 32-bit performance counters.
  4970. - * To avoid a race updating the registers we need to stop the counters
  4971. - * while we're messing with
  4972. - * them ...
  4973. - */
  4974. -
  4975. /* Check whether the irq belongs to me */
  4976. - enabled = read_c0_perfctrl() & LOONGSON2_PERFCNT_INT_EN;
  4977. + enabled = read_c0_perfctrl() & LOONGSON2_PERFCTRL_ENABLE;
  4978. if (!enabled)
  4979. return IRQ_NONE;
  4980. enabled = reg.cnt1_enabled | reg.cnt2_enabled;
  4981. @@ -157,7 +145,7 @@
  4982. static void loongson2_exit(void)
  4983. {
  4984. - write_c0_perfctrl(0);
  4985. + reset_counters(NULL);
  4986. free_irq(LOONGSON2_PERFCNT_IRQ, oprofid);
  4987. }
  4988. diff -Nur linux-2.6.34.orig/drivers/ide/ide-iops.c linux-loongson/drivers/ide/ide-iops.c
  4989. --- linux-2.6.34.orig/drivers/ide/ide-iops.c 2010-05-16 23:17:36.000000000 +0200
  4990. +++ linux-loongson/drivers/ide/ide-iops.c 2010-05-27 18:12:36.363472774 +0200
  4991. @@ -27,6 +27,8 @@
  4992. #include <asm/uaccess.h>
  4993. #include <asm/io.h>
  4994. +#include <asm/bootinfo.h>
  4995. +
  4996. void SELECT_MASK(ide_drive_t *drive, int mask)
  4997. {
  4998. const struct ide_port_ops *port_ops = drive->hwif->port_ops;
  4999. @@ -300,6 +302,9 @@
  5000. {
  5001. const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
  5002. + if (mips_machtype != MACH_LEMOTE_YL2F89)
  5003. + return;
  5004. +
  5005. for (list = nien_quirk_list; *list != NULL; list++)
  5006. if (strstr(m, *list) != NULL) {
  5007. drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
  5008. diff -Nur linux-2.6.34.orig/drivers/net/Kconfig linux-loongson/drivers/net/Kconfig
  5009. --- linux-2.6.34.orig/drivers/net/Kconfig 2010-05-16 23:17:36.000000000 +0200
  5010. +++ linux-loongson/drivers/net/Kconfig 2010-05-27 18:15:36.182214625 +0200
  5011. @@ -2432,6 +2432,13 @@
  5012. Some boards that use the Discovery chipset are the Momenco
  5013. Ocelot C and Jaguar ATX and Pegasos II.
  5014. +config TITAN_GE
  5015. + bool "PMC-Sierra TITAN Gigabit Ethernet Support"
  5016. + depends on PMC_YOSEMITE
  5017. + help
  5018. + This enables support for the the integrated ethernet of
  5019. + PMC-Sierra's Titan SoC.
  5020. +
  5021. config XILINX_LL_TEMAC
  5022. tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
  5023. select PHYLIB
  5024. diff -Nur linux-2.6.34.orig/drivers/net/Makefile linux-loongson/drivers/net/Makefile
  5025. --- linux-2.6.34.orig/drivers/net/Makefile 2010-05-16 23:17:36.000000000 +0200
  5026. +++ linux-loongson/drivers/net/Makefile 2010-05-27 18:15:36.182214625 +0200
  5027. @@ -154,6 +154,8 @@
  5028. obj-$(CONFIG_QLCNIC) += qlcnic/
  5029. obj-$(CONFIG_QLGE) += qlge/
  5030. +obj-$(CONFIG_TITAN_GE) += titan_mdio.o titan_ge.o
  5031. +
  5032. obj-$(CONFIG_PPP) += ppp_generic.o
  5033. obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
  5034. obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
  5035. diff -Nur linux-2.6.34.orig/drivers/net/titan_ge.c linux-loongson/drivers/net/titan_ge.c
  5036. --- linux-2.6.34.orig/drivers/net/titan_ge.c 1970-01-01 01:00:00.000000000 +0100
  5037. +++ linux-loongson/drivers/net/titan_ge.c 2010-05-27 18:12:39.084716399 +0200
  5038. @@ -0,0 +1,2069 @@
  5039. +/*
  5040. + * drivers/net/titan_ge.c - Driver for Titan ethernet ports
  5041. + *
  5042. + * Copyright (C) 2003 PMC-Sierra Inc.
  5043. + * Author : Manish Lachwani (lachwani@pmc-sierra.com)
  5044. + *
  5045. + * This program is free software; you can redistribute it and/or
  5046. + * modify it under the terms of the GNU General Public License
  5047. + * as published by the Free Software Foundation; either version 2
  5048. + * of the License, or (at your option) any later version.
  5049. + *
  5050. + * This program is distributed in the hope that it will be useful,
  5051. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  5052. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5053. + * GNU General Public License for more details.
  5054. + *
  5055. + * You should have received a copy of the GNU General Public License
  5056. + * along with this program; if not, write to the Free Software
  5057. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  5058. + */
  5059. +
  5060. +/*
  5061. + * The MAC unit of the Titan consists of the following:
  5062. + *
  5063. + * -> XDMA Engine to move data to from the memory to the MAC packet FIFO
  5064. + * -> FIFO is where the incoming and outgoing data is placed
  5065. + * -> TRTG is the unit that pulls the data from the FIFO for Tx and pushes
  5066. + * the data into the FIFO for Rx
  5067. + * -> TMAC is the outgoing MAC interface and RMAC is the incoming.
  5068. + * -> AFX is the address filtering block
  5069. + * -> GMII block to communicate with the PHY
  5070. + *
  5071. + * Rx will look like the following:
  5072. + * GMII --> RMAC --> AFX --> TRTG --> Rx FIFO --> XDMA --> CPU memory
  5073. + *
  5074. + * Tx will look like the following:
  5075. + * CPU memory --> XDMA --> Tx FIFO --> TRTG --> TMAC --> GMII
  5076. + *
  5077. + * The Titan driver has support for the following performance features:
  5078. + * -> Rx side checksumming
  5079. + * -> Jumbo Frames
  5080. + * -> Interrupt Coalscing
  5081. + * -> Rx NAPI
  5082. + * -> SKB Recycling
  5083. + * -> Transmit/Receive descriptors in SRAM
  5084. + * -> Fast routing for IP forwarding
  5085. + */
  5086. +
  5087. +#include <linux/dma-mapping.h>
  5088. +#include <linux/module.h>
  5089. +#include <linux/kernel.h>
  5090. +#include <linux/sched.h>
  5091. +#include <linux/ioport.h>
  5092. +#include <linux/interrupt.h>
  5093. +#include <linux/slab.h>
  5094. +#include <linux/string.h>
  5095. +#include <linux/errno.h>
  5096. +#include <linux/ip.h>
  5097. +#include <linux/init.h>
  5098. +#include <linux/in.h>
  5099. +#include <linux/platform_device.h>
  5100. +#include <linux/netdevice.h>
  5101. +#include <linux/etherdevice.h>
  5102. +#include <linux/skbuff.h>
  5103. +#include <linux/mii.h>
  5104. +#include <linux/delay.h>
  5105. +#include <linux/skbuff.h>
  5106. +#include <linux/prefetch.h>
  5107. +
  5108. +/* For MII specifc registers, titan_mdio.h should be included */
  5109. +#include <net/ip.h>
  5110. +
  5111. +#include <asm/bitops.h>
  5112. +#include <asm/io.h>
  5113. +#include <asm/types.h>
  5114. +#include <asm/pgtable.h>
  5115. +#include <asm/system.h>
  5116. +#include <asm/titan_dep.h>
  5117. +
  5118. +#include "titan_ge.h"
  5119. +#include "titan_mdio.h"
  5120. +
  5121. +/* Static Function Declarations */
  5122. +static int titan_ge_eth_open(struct net_device *);
  5123. +static void titan_ge_eth_stop(struct net_device *);
  5124. +static struct net_device_stats *titan_ge_get_stats(struct net_device *);
  5125. +static int titan_ge_init_rx_desc_ring(titan_ge_port_info *, int, int,
  5126. + unsigned long, unsigned long,
  5127. + unsigned long);
  5128. +static int titan_ge_init_tx_desc_ring(titan_ge_port_info *, int,
  5129. + unsigned long, unsigned long);
  5130. +
  5131. +static int titan_ge_open(struct net_device *);
  5132. +static int titan_ge_start_xmit(struct sk_buff *, struct net_device *);
  5133. +static int titan_ge_stop(struct net_device *);
  5134. +
  5135. +static unsigned long titan_ge_tx_coal(unsigned long, int);
  5136. +
  5137. +static void titan_ge_port_reset(unsigned int);
  5138. +static int titan_ge_free_tx_queue(titan_ge_port_info *);
  5139. +static int titan_ge_rx_task(struct net_device *, titan_ge_port_info *);
  5140. +static int titan_ge_port_start(struct net_device *, titan_ge_port_info *);
  5141. +
  5142. +static int titan_ge_return_tx_desc(titan_ge_port_info *, int);
  5143. +
  5144. +/*
  5145. + * Some configuration for the FIFO and the XDMA channel needs
  5146. + * to be done only once for all the ports. This flag controls
  5147. + * that
  5148. + */
  5149. +static unsigned long config_done;
  5150. +
  5151. +/*
  5152. + * One time out of memory flag
  5153. + */
  5154. +static unsigned int oom_flag;
  5155. +
  5156. +static int titan_ge_poll(struct net_device *netdev, int *budget);
  5157. +
  5158. +static int titan_ge_receive_queue(struct net_device *, unsigned int);
  5159. +
  5160. +static struct platform_device *titan_ge_device[3];
  5161. +
  5162. +/* MAC Address */
  5163. +extern unsigned char titan_ge_mac_addr_base[6];
  5164. +
  5165. +unsigned long titan_ge_base;
  5166. +static unsigned long titan_ge_sram;
  5167. +
  5168. +static char titan_string[] = "titan";
  5169. +
  5170. +/*
  5171. + * The Titan GE has two alignment requirements:
  5172. + * -> skb->data to be cacheline aligned (32 byte)
  5173. + * -> IP header alignment to 16 bytes
  5174. + *
  5175. + * The latter is not implemented. So, that results in an extra copy on
  5176. + * the Rx. This is a big performance hog. For the former case, the
  5177. + * dev_alloc_skb() has been replaced with titan_ge_alloc_skb(). The size
  5178. + * requested is calculated:
  5179. + *
  5180. + * Ethernet Frame Size : 1518
  5181. + * Ethernet Header : 14
  5182. + * Future Titan change for IP header alignment : 2
  5183. + *
  5184. + * Hence, we allocate (1518 + 14 + 2+ 64) = 1580 bytes. For IP header
  5185. + * alignment, we use skb_reserve().
  5186. + */
  5187. +
  5188. +#define ALIGNED_RX_SKB_ADDR(addr) \
  5189. + ((((unsigned long)(addr) + (64UL - 1UL)) \
  5190. + & ~(64UL - 1UL)) - (unsigned long)(addr))
  5191. +
  5192. +#define titan_ge_alloc_skb(__length, __gfp_flags) \
  5193. +({ struct sk_buff *__skb; \
  5194. + __skb = alloc_skb((__length) + 64, (__gfp_flags)); \
  5195. + if(__skb) { \
  5196. + int __offset = (int) ALIGNED_RX_SKB_ADDR(__skb->data); \
  5197. + if(__offset) \
  5198. + skb_reserve(__skb, __offset); \
  5199. + } \
  5200. + __skb; \
  5201. +})
  5202. +
  5203. +/*
  5204. + * Configure the GMII block of the Titan based on what the PHY tells us
  5205. + */
  5206. +static void titan_ge_gmii_config(int port_num)
  5207. +{
  5208. + unsigned int reg_data = 0, phy_reg;
  5209. + int err;
  5210. +
  5211. + err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
  5212. +
  5213. + if (err == TITAN_GE_MDIO_ERROR) {
  5214. + printk(KERN_ERR
  5215. + "Could not read PHY control register 0x11 \n");
  5216. + printk(KERN_ERR
  5217. + "Setting speed to 1000 Mbps and Duplex to Full \n");
  5218. +
  5219. + return;
  5220. + }
  5221. +
  5222. + err = titan_ge_mdio_write(port_num, TITAN_GE_MDIO_PHY_IE, 0);
  5223. +
  5224. + if (phy_reg & 0x8000) {
  5225. + if (phy_reg & 0x2000) {
  5226. + /* Full Duplex and 1000 Mbps */
  5227. + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
  5228. + (port_num << 12)), 0x201);
  5229. + } else {
  5230. + /* Half Duplex and 1000 Mbps */
  5231. + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
  5232. + (port_num << 12)), 0x2201);
  5233. + }
  5234. + }
  5235. + if (phy_reg & 0x4000) {
  5236. + if (phy_reg & 0x2000) {
  5237. + /* Full Duplex and 100 Mbps */
  5238. + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
  5239. + (port_num << 12)), 0x100);
  5240. + } else {
  5241. + /* Half Duplex and 100 Mbps */
  5242. + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
  5243. + (port_num << 12)), 0x2100);
  5244. + }
  5245. + }
  5246. + reg_data = TITAN_GE_READ(TITAN_GE_GMII_CONFIG_GENERAL +
  5247. + (port_num << 12));
  5248. + reg_data |= 0x3;
  5249. + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_GENERAL +
  5250. + (port_num << 12)), reg_data);
  5251. +}
  5252. +
  5253. +/*
  5254. + * Enable the TMAC if it is not
  5255. + */
  5256. +static void titan_ge_enable_tx(unsigned int port_num)
  5257. +{
  5258. + unsigned long reg_data;
  5259. +
  5260. + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
  5261. + if (!(reg_data & 0x8000)) {
  5262. + printk("TMAC disabled for port %d!! \n", port_num);
  5263. +
  5264. + reg_data |= 0x0001; /* Enable TMAC */
  5265. + reg_data |= 0x4000; /* CRC Check Enable */
  5266. + reg_data |= 0x2000; /* Padding enable */
  5267. + reg_data |= 0x0800; /* CRC Add enable */
  5268. + reg_data |= 0x0080; /* PAUSE frame */
  5269. +
  5270. + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
  5271. + (port_num << 12)), reg_data);
  5272. + }
  5273. +}
  5274. +
  5275. +/*
  5276. + * Tx Timeout function
  5277. + */
  5278. +static void titan_ge_tx_timeout(struct net_device *netdev)
  5279. +{
  5280. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  5281. +
  5282. + printk(KERN_INFO "%s: TX timeout ", netdev->name);
  5283. + printk(KERN_INFO "Resetting card \n");
  5284. +
  5285. + /* Do the reset outside of interrupt context */
  5286. + schedule_work(&titan_ge_eth->tx_timeout_task);
  5287. +}
  5288. +
  5289. +/*
  5290. + * Update the AFX tables for UC and MC for slice 0 only
  5291. + */
  5292. +static void titan_ge_update_afx(titan_ge_port_info * titan_ge_eth)
  5293. +{
  5294. + int port = titan_ge_eth->port_num;
  5295. + unsigned int i;
  5296. + volatile unsigned long reg_data = 0;
  5297. + u8 p_addr[6];
  5298. +
  5299. + memcpy(p_addr, titan_ge_eth->port_mac_addr, 6);
  5300. +
  5301. + /* Set the MAC address here for TMAC and RMAC */
  5302. + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port << 12)),
  5303. + ((p_addr[5] << 8) | p_addr[4]));
  5304. + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port << 12)),
  5305. + ((p_addr[3] << 8) | p_addr[2]));
  5306. + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port << 12)),
  5307. + ((p_addr[1] << 8) | p_addr[0]));
  5308. +
  5309. + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port << 12)),
  5310. + ((p_addr[5] << 8) | p_addr[4]));
  5311. + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port << 12)),
  5312. + ((p_addr[3] << 8) | p_addr[2]));
  5313. + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port << 12)),
  5314. + ((p_addr[1] << 8) | p_addr[0]));
  5315. +
  5316. + TITAN_GE_WRITE((0x112c | (port << 12)), 0x1);
  5317. + /* Configure the eight address filters */
  5318. + for (i = 0; i < 8; i++) {
  5319. + /* Select each of the eight filters */
  5320. + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 +
  5321. + (port << 12)), i);
  5322. +
  5323. + /* Configure the match */
  5324. + reg_data = 0x9; /* Forward Enable Bit */
  5325. + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 +
  5326. + (port << 12)), reg_data);
  5327. +
  5328. + /* Finally, AFX Exact Match Address Registers */
  5329. + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_LOW + (port << 12)),
  5330. + ((p_addr[1] << 8) | p_addr[0]));
  5331. + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_MID + (port << 12)),
  5332. + ((p_addr[3] << 8) | p_addr[2]));
  5333. + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_HIGH + (port << 12)),
  5334. + ((p_addr[5] << 8) | p_addr[4]));
  5335. +
  5336. + /* VLAN id set to 0 */
  5337. + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_VID +
  5338. + (port << 12)), 0);
  5339. + }
  5340. +}
  5341. +
  5342. +/*
  5343. + * Actual Routine to reset the adapter when the timeout occurred
  5344. + */
  5345. +static void titan_ge_tx_timeout_task(struct net_device *netdev)
  5346. +{
  5347. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  5348. + int port = titan_ge_eth->port_num;
  5349. +
  5350. + printk("Titan GE: Transmit timed out. Resetting ... \n");
  5351. +
  5352. + /* Dump debug info */
  5353. + printk(KERN_ERR "TRTG cause : %x \n",
  5354. + TITAN_GE_READ(0x100c + (port << 12)));
  5355. +
  5356. + /* Fix this for the other ports */
  5357. + printk(KERN_ERR "FIFO cause : %x \n", TITAN_GE_READ(0x482c));
  5358. + printk(KERN_ERR "IE cause : %x \n", TITAN_GE_READ(0x0040));
  5359. + printk(KERN_ERR "XDMA GDI ERROR : %x \n",
  5360. + TITAN_GE_READ(0x5008 + (port << 8)));
  5361. + printk(KERN_ERR "CHANNEL ERROR: %x \n",
  5362. + TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT
  5363. + + (port << 8)));
  5364. +
  5365. + netif_device_detach(netdev);
  5366. + titan_ge_port_reset(titan_ge_eth->port_num);
  5367. + titan_ge_port_start(netdev, titan_ge_eth);
  5368. + netif_device_attach(netdev);
  5369. +}
  5370. +
  5371. +/*
  5372. + * Change the MTU of the Ethernet Device
  5373. + */
  5374. +static int titan_ge_change_mtu(struct net_device *netdev, int new_mtu)
  5375. +{
  5376. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  5377. + unsigned long flags;
  5378. +
  5379. + if ((new_mtu > 9500) || (new_mtu < 64))
  5380. + return -EINVAL;
  5381. +
  5382. + spin_lock_irqsave(&titan_ge_eth->lock, flags);
  5383. +
  5384. + netdev->mtu = new_mtu;
  5385. +
  5386. + /* Now we have to reopen the interface so that SKBs with the new
  5387. + * size will be allocated */
  5388. +
  5389. + if (netif_running(netdev)) {
  5390. + titan_ge_eth_stop(netdev);
  5391. +
  5392. + if (titan_ge_eth_open(netdev) != TITAN_OK) {
  5393. + printk(KERN_ERR
  5394. + "%s: Fatal error on opening device\n",
  5395. + netdev->name);
  5396. + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
  5397. + return -1;
  5398. + }
  5399. + }
  5400. +
  5401. + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
  5402. + return 0;
  5403. +}
  5404. +
  5405. +/*
  5406. + * Titan Gbe Interrupt Handler. All the three ports send interrupt to one line
  5407. + * only. Once an interrupt is triggered, figure out the port and then check
  5408. + * the channel.
  5409. + */
  5410. +static irqreturn_t titan_ge_int_handler(int irq, void *dev_id)
  5411. +{
  5412. + struct net_device *netdev = (struct net_device *) dev_id;
  5413. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  5414. + unsigned int port_num = titan_ge_eth->port_num;
  5415. + unsigned int reg_data;
  5416. + unsigned int eth_int_cause_error = 0, is;
  5417. + unsigned long eth_int_cause1;
  5418. + int err = 0;
  5419. +#ifdef CONFIG_SMP
  5420. + unsigned long eth_int_cause2;
  5421. +#endif
  5422. +
  5423. + /* Ack the CPU interrupt */
  5424. + switch (port_num) {
  5425. + case 0:
  5426. + is = OCD_READ(RM9000x2_OCD_INTP0STATUS1);
  5427. + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR1, is);
  5428. +
  5429. +#ifdef CONFIG_SMP
  5430. + is = OCD_READ(RM9000x2_OCD_INTP1STATUS1);
  5431. + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR1, is);
  5432. +#endif
  5433. + break;
  5434. +
  5435. + case 1:
  5436. + is = OCD_READ(RM9000x2_OCD_INTP0STATUS0);
  5437. + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR0, is);
  5438. +
  5439. +#ifdef CONFIG_SMP
  5440. + is = OCD_READ(RM9000x2_OCD_INTP1STATUS0);
  5441. + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR0, is);
  5442. +#endif
  5443. + break;
  5444. +
  5445. + case 2:
  5446. + is = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
  5447. + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR4, is);
  5448. +
  5449. +#ifdef CONFIG_SMP
  5450. + is = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
  5451. + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR4, is);
  5452. +#endif
  5453. + }
  5454. +
  5455. + eth_int_cause1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
  5456. +#ifdef CONFIG_SMP
  5457. + eth_int_cause2 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_B);
  5458. +#endif
  5459. +
  5460. + /* Spurious interrupt */
  5461. +#ifdef CONFIG_SMP
  5462. + if ( (eth_int_cause1 == 0) && (eth_int_cause2 == 0)) {
  5463. +#else
  5464. + if (eth_int_cause1 == 0) {
  5465. +#endif
  5466. + eth_int_cause_error = TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT +
  5467. + (port_num << 8));
  5468. +
  5469. + if (eth_int_cause_error == 0)
  5470. + return IRQ_NONE;
  5471. + }
  5472. +
  5473. + /* Handle Tx first. No need to ack interrupts */
  5474. +#ifdef CONFIG_SMP
  5475. + if ( (eth_int_cause1 & 0x20202) ||
  5476. + (eth_int_cause2 & 0x20202) )
  5477. +#else
  5478. + if (eth_int_cause1 & 0x20202)
  5479. +#endif
  5480. + titan_ge_free_tx_queue(titan_ge_eth);
  5481. +
  5482. + /* Handle the Rx next */
  5483. +#ifdef CONFIG_SMP
  5484. + if ( (eth_int_cause1 & 0x10101) ||
  5485. + (eth_int_cause2 & 0x10101)) {
  5486. +#else
  5487. + if (eth_int_cause1 & 0x10101) {
  5488. +#endif
  5489. + if (netif_rx_schedule_prep(netdev)) {
  5490. + unsigned int ack;
  5491. +
  5492. + ack = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
  5493. + /* Disable Tx and Rx both */
  5494. + if (port_num == 0)
  5495. + ack &= ~(0x3);
  5496. + if (port_num == 1)
  5497. + ack &= ~(0x300);
  5498. +
  5499. + if (port_num == 2)
  5500. + ack &= ~(0x30000);
  5501. +
  5502. + /* Interrupts have been disabled */
  5503. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, ack);
  5504. +
  5505. + __netif_rx_schedule(netdev);
  5506. + }
  5507. + }
  5508. +
  5509. + /* Handle error interrupts */
  5510. + if (eth_int_cause_error && (eth_int_cause_error != 0x2)) {
  5511. + printk(KERN_ERR
  5512. + "XDMA Channel Error : %x on port %d\n",
  5513. + eth_int_cause_error, port_num);
  5514. +
  5515. + printk(KERN_ERR
  5516. + "XDMA GDI Hardware error : %x on port %d\n",
  5517. + TITAN_GE_READ(0x5008 + (port_num << 8)), port_num);
  5518. +
  5519. + printk(KERN_ERR
  5520. + "XDMA currently has %d Rx descriptors \n",
  5521. + TITAN_GE_READ(0x5048 + (port_num << 8)));
  5522. +
  5523. + printk(KERN_ERR
  5524. + "XDMA currently has prefetcted %d Rx descriptors \n",
  5525. + TITAN_GE_READ(0x505c + (port_num << 8)));
  5526. +
  5527. + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT +
  5528. + (port_num << 8)), eth_int_cause_error);
  5529. + }
  5530. +
  5531. + /*
  5532. + * PHY interrupt to inform abt the changes. Reading the
  5533. + * PHY Status register will clear the interrupt
  5534. + */
  5535. + if ((!(eth_int_cause1 & 0x30303)) &&
  5536. + (eth_int_cause_error == 0)) {
  5537. + err =
  5538. + titan_ge_mdio_read(port_num,
  5539. + TITAN_GE_MDIO_PHY_IS, &reg_data);
  5540. +
  5541. + if (reg_data & 0x0400) {
  5542. + /* Link status change */
  5543. + titan_ge_mdio_read(port_num,
  5544. + TITAN_GE_MDIO_PHY_STATUS, &reg_data);
  5545. + if (!(reg_data & 0x0400)) {
  5546. + /* Link is down */
  5547. + netif_carrier_off(netdev);
  5548. + netif_stop_queue(netdev);
  5549. + } else {
  5550. + /* Link is up */
  5551. + netif_carrier_on(netdev);
  5552. + netif_wake_queue(netdev);
  5553. +
  5554. + /* Enable the queue */
  5555. + titan_ge_enable_tx(port_num);
  5556. + }
  5557. + }
  5558. + }
  5559. +
  5560. + return IRQ_HANDLED;
  5561. +}
  5562. +
  5563. +/*
  5564. + * Multicast and Promiscuous mode set. The
  5565. + * set_multi entry point is called whenever the
  5566. + * multicast address list or the network interface
  5567. + * flags are updated.
  5568. + */
  5569. +static void titan_ge_set_multi(struct net_device *netdev)
  5570. +{
  5571. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  5572. + unsigned int port_num = titan_ge_eth->port_num;
  5573. + unsigned long reg_data;
  5574. +
  5575. + reg_data = TITAN_GE_READ(TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
  5576. + (port_num << 12));
  5577. +
  5578. + if (netdev->flags & IFF_PROMISC) {
  5579. + reg_data |= 0x2;
  5580. + }
  5581. + else if (netdev->flags & IFF_ALLMULTI) {
  5582. + reg_data |= 0x01;
  5583. + reg_data |= 0x400; /* Use the 64-bit Multicast Hash bin */
  5584. + }
  5585. + else {
  5586. + reg_data = 0x2;
  5587. + }
  5588. +
  5589. + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
  5590. + (port_num << 12)), reg_data);
  5591. + if (reg_data & 0x01) {
  5592. + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_LOW +
  5593. + (port_num << 12)), 0xffff);
  5594. + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDLOW +
  5595. + (port_num << 12)), 0xffff);
  5596. + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDHI +
  5597. + (port_num << 12)), 0xffff);
  5598. + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_HI +
  5599. + (port_num << 12)), 0xffff);
  5600. + }
  5601. +}
  5602. +
  5603. +/*
  5604. + * Open the network device
  5605. + */
  5606. +static int titan_ge_open(struct net_device *netdev)
  5607. +{
  5608. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  5609. + unsigned int port_num = titan_ge_eth->port_num;
  5610. + unsigned int irq = TITAN_ETH_PORT_IRQ - port_num;
  5611. + int retval;
  5612. +
  5613. + retval = request_irq(irq, titan_ge_int_handler,
  5614. + SA_INTERRUPT | SA_SAMPLE_RANDOM , netdev->name, netdev);
  5615. +
  5616. + if (retval != 0) {
  5617. + printk(KERN_ERR "Cannot assign IRQ number to TITAN GE \n");
  5618. + return -1;
  5619. + }
  5620. +
  5621. + netdev->irq = irq;
  5622. + printk(KERN_INFO "Assigned IRQ %d to port %d\n", irq, port_num);
  5623. +
  5624. + spin_lock_irq(&(titan_ge_eth->lock));
  5625. +
  5626. + if (titan_ge_eth_open(netdev) != TITAN_OK) {
  5627. + spin_unlock_irq(&(titan_ge_eth->lock));
  5628. + printk("%s: Error opening interface \n", netdev->name);
  5629. + free_irq(netdev->irq, netdev);
  5630. + return -EBUSY;
  5631. + }
  5632. +
  5633. + spin_unlock_irq(&(titan_ge_eth->lock));
  5634. +
  5635. + return 0;
  5636. +}
  5637. +
  5638. +/*
  5639. + * Allocate the SKBs for the Rx ring. Also used
  5640. + * for refilling the queue
  5641. + */
  5642. +static int titan_ge_rx_task(struct net_device *netdev,
  5643. + titan_ge_port_info *titan_ge_port)
  5644. +{
  5645. + struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
  5646. + volatile titan_ge_rx_desc *rx_desc;
  5647. + struct sk_buff *skb;
  5648. + int rx_used_desc;
  5649. + int count = 0;
  5650. +
  5651. + while (titan_ge_port->rx_ring_skbs < titan_ge_port->rx_ring_size) {
  5652. +
  5653. + /* First try to get the skb from the recycler */
  5654. +#ifdef TITAN_GE_JUMBO_FRAMES
  5655. + skb = titan_ge_alloc_skb(TITAN_GE_JUMBO_BUFSIZE, GFP_ATOMIC);
  5656. +#else
  5657. + skb = titan_ge_alloc_skb(TITAN_GE_STD_BUFSIZE, GFP_ATOMIC);
  5658. +#endif
  5659. + if (unlikely(!skb)) {
  5660. + /* OOM, set the flag */
  5661. + printk("OOM \n");
  5662. + oom_flag = 1;
  5663. + break;
  5664. + }
  5665. + count++;
  5666. + skb->dev = netdev;
  5667. +
  5668. + titan_ge_port->rx_ring_skbs++;
  5669. +
  5670. + rx_used_desc = titan_ge_port->rx_used_desc_q;
  5671. + rx_desc = &(titan_ge_port->rx_desc_area[rx_used_desc]);
  5672. +
  5673. +#ifdef TITAN_GE_JUMBO_FRAMES
  5674. + rx_desc->buffer_addr = dma_map_single(device, skb->data,
  5675. + TITAN_GE_JUMBO_BUFSIZE - 2, DMA_FROM_DEVICE);
  5676. +#else
  5677. + rx_desc->buffer_addr = dma_map_single(device, skb->data,
  5678. + TITAN_GE_STD_BUFSIZE - 2, DMA_FROM_DEVICE);
  5679. +#endif
  5680. +
  5681. + titan_ge_port->rx_skb[rx_used_desc] = skb;
  5682. + rx_desc->cmd_sts = TITAN_GE_RX_BUFFER_OWNED;
  5683. +
  5684. + titan_ge_port->rx_used_desc_q =
  5685. + (rx_used_desc + 1) % TITAN_GE_RX_QUEUE;
  5686. + }
  5687. +
  5688. + return count;
  5689. +}
  5690. +
  5691. +/*
  5692. + * Actual init of the Tital GE port. There is one register for
  5693. + * the channel configuration
  5694. + */
  5695. +static void titan_port_init(struct net_device *netdev,
  5696. + titan_ge_port_info * titan_ge_eth)
  5697. +{
  5698. + unsigned long reg_data;
  5699. +
  5700. + titan_ge_port_reset(titan_ge_eth->port_num);
  5701. +
  5702. + /* First reset the TMAC */
  5703. + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
  5704. + reg_data |= 0x80000000;
  5705. + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
  5706. +
  5707. + udelay(30);
  5708. +
  5709. + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
  5710. + reg_data &= ~(0xc0000000);
  5711. + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
  5712. +
  5713. + /* Now reset the RMAC */
  5714. + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
  5715. + reg_data |= 0x00080000;
  5716. + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
  5717. +
  5718. + udelay(30);
  5719. +
  5720. + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
  5721. + reg_data &= ~(0x000c0000);
  5722. + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
  5723. +}
  5724. +
  5725. +/*
  5726. + * Start the port. All the hardware specific configuration
  5727. + * for the XDMA, Tx FIFO, Rx FIFO, TMAC, RMAC, TRTG and AFX
  5728. + * go here
  5729. + */
  5730. +static int titan_ge_port_start(struct net_device *netdev,
  5731. + titan_ge_port_info * titan_port)
  5732. +{
  5733. + volatile unsigned long reg_data, reg_data1;
  5734. + int port_num = titan_port->port_num;
  5735. + int count = 0;
  5736. + unsigned long reg_data_1;
  5737. +
  5738. + if (config_done == 0) {
  5739. + reg_data = TITAN_GE_READ(0x0004);
  5740. + reg_data |= 0x100;
  5741. + TITAN_GE_WRITE(0x0004, reg_data);
  5742. +
  5743. + reg_data &= ~(0x100);
  5744. + TITAN_GE_WRITE(0x0004, reg_data);
  5745. +
  5746. + /* Turn on GMII/MII mode and turn off TBI mode */
  5747. + reg_data = TITAN_GE_READ(TITAN_GE_TSB_CTRL_1);
  5748. + reg_data |= 0x00000700;
  5749. + reg_data &= ~(0x00800000); /* Fencing */
  5750. +
  5751. + TITAN_GE_WRITE(0x000c, 0x00001100);
  5752. +
  5753. + TITAN_GE_WRITE(TITAN_GE_TSB_CTRL_1, reg_data);
  5754. +
  5755. + /* Set the CPU Resource Limit register */
  5756. + TITAN_GE_WRITE(0x00f8, 0x8);
  5757. +
  5758. + /* Be conservative when using the BIU buffers */
  5759. + TITAN_GE_WRITE(0x0068, 0x4);
  5760. + }
  5761. +
  5762. + titan_port->tx_threshold = 0;
  5763. + titan_port->rx_threshold = 0;
  5764. +
  5765. + /* We need to write the descriptors for Tx and Rx */
  5766. + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_TX_DESC + (port_num << 8)),
  5767. + (unsigned long) titan_port->tx_dma);
  5768. + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_RX_DESC + (port_num << 8)),
  5769. + (unsigned long) titan_port->rx_dma);
  5770. +
  5771. + if (config_done == 0) {
  5772. + /* Step 1: XDMA config */
  5773. + reg_data = TITAN_GE_READ(TITAN_GE_XDMA_CONFIG);
  5774. + reg_data &= ~(0x80000000); /* clear reset */
  5775. + reg_data |= 0x1 << 29; /* sparse tx descriptor spacing */
  5776. + reg_data |= 0x1 << 28; /* sparse rx descriptor spacing */
  5777. + reg_data |= (0x1 << 23) | (0x1 << 24); /* Descriptor Coherency */
  5778. + reg_data |= (0x1 << 21) | (0x1 << 22); /* Data Coherency */
  5779. + TITAN_GE_WRITE(TITAN_GE_XDMA_CONFIG, reg_data);
  5780. + }
  5781. +
  5782. + /* IR register for the XDMA */
  5783. + reg_data = TITAN_GE_READ(TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8));
  5784. + reg_data |= 0x80068000; /* No Rx_OOD */
  5785. + TITAN_GE_WRITE((TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8)), reg_data);
  5786. +
  5787. + /* Start the Tx and Rx XDMA controller */
  5788. + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG + (port_num << 8));
  5789. + reg_data &= 0x4fffffff; /* Clear tx reset */
  5790. + reg_data &= 0xfff4ffff; /* Clear rx reset */
  5791. +
  5792. +#ifdef TITAN_GE_JUMBO_FRAMES
  5793. + reg_data |= 0xa0 | 0x30030000;
  5794. +#else
  5795. + reg_data |= 0x40 | 0x20030000;
  5796. +#endif
  5797. +
  5798. +#ifndef CONFIG_SMP
  5799. + reg_data &= ~(0x10);
  5800. + reg_data |= 0x0f; /* All of the packet */
  5801. +#endif
  5802. +
  5803. + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG + (port_num << 8)), reg_data);
  5804. +
  5805. + /* Rx desc count */
  5806. + count = titan_ge_rx_task(netdev, titan_port);
  5807. + TITAN_GE_WRITE((0x5048 + (port_num << 8)), count);
  5808. + count = TITAN_GE_READ(0x5048 + (port_num << 8));
  5809. +
  5810. + udelay(30);
  5811. +
  5812. + /*
  5813. + * Step 2: Configure the SDQPF, i.e. FIFO
  5814. + */
  5815. + if (config_done == 0) {
  5816. + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
  5817. + reg_data = 0x1;
  5818. + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
  5819. + reg_data &= ~(0x1);
  5820. + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
  5821. + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
  5822. + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
  5823. +
  5824. + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
  5825. + reg_data = 0x1;
  5826. + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
  5827. + reg_data &= ~(0x1);
  5828. + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
  5829. + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
  5830. + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
  5831. + }
  5832. + /*
  5833. + * Enable RX FIFO 0, 4 and 8
  5834. + */
  5835. + if (port_num == 0) {
  5836. + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_0);
  5837. +
  5838. + reg_data |= 0x100000;
  5839. + reg_data |= (0xff << 10);
  5840. +
  5841. + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
  5842. + /*
  5843. + * BAV2,BAV and DAV settings for the Rx FIFO
  5844. + */
  5845. + reg_data1 = TITAN_GE_READ(0x4844);
  5846. + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
  5847. + TITAN_GE_WRITE(0x4844, reg_data1);
  5848. +
  5849. + reg_data &= ~(0x00100000);
  5850. + reg_data |= 0x200000;
  5851. +
  5852. + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
  5853. +
  5854. + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_0);
  5855. + reg_data |= 0x100000;
  5856. +
  5857. + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
  5858. +
  5859. + reg_data |= (0xff << 10);
  5860. +
  5861. + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
  5862. +
  5863. + /*
  5864. + * BAV2, BAV and DAV settings for the Tx FIFO
  5865. + */
  5866. + reg_data1 = TITAN_GE_READ(0x4944);
  5867. + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
  5868. +
  5869. + TITAN_GE_WRITE(0x4944, reg_data1);
  5870. +
  5871. + reg_data &= ~(0x00100000);
  5872. + reg_data |= 0x200000;
  5873. +
  5874. + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
  5875. +
  5876. + }
  5877. +
  5878. + if (port_num == 1) {
  5879. + reg_data = TITAN_GE_READ(0x4870);
  5880. +
  5881. + reg_data |= 0x100000;
  5882. + reg_data |= (0xff << 10) | (0xff + 1);
  5883. +
  5884. + TITAN_GE_WRITE(0x4870, reg_data);
  5885. + /*
  5886. + * BAV2,BAV and DAV settings for the Rx FIFO
  5887. + */
  5888. + reg_data1 = TITAN_GE_READ(0x4874);
  5889. + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
  5890. + TITAN_GE_WRITE(0x4874, reg_data1);
  5891. +
  5892. + reg_data &= ~(0x00100000);
  5893. + reg_data |= 0x200000;
  5894. +
  5895. + TITAN_GE_WRITE(0x4870, reg_data);
  5896. +
  5897. + reg_data = TITAN_GE_READ(0x494c);
  5898. + reg_data |= 0x100000;
  5899. +
  5900. + TITAN_GE_WRITE(0x494c, reg_data);
  5901. + reg_data |= (0xff << 10) | (0xff + 1);
  5902. + TITAN_GE_WRITE(0x494c, reg_data);
  5903. +
  5904. + /*
  5905. + * BAV2, BAV and DAV settings for the Tx FIFO
  5906. + */
  5907. + reg_data1 = TITAN_GE_READ(0x4950);
  5908. + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
  5909. +
  5910. + TITAN_GE_WRITE(0x4950, reg_data1);
  5911. +
  5912. + reg_data &= ~(0x00100000);
  5913. + reg_data |= 0x200000;
  5914. +
  5915. + TITAN_GE_WRITE(0x494c, reg_data);
  5916. + }
  5917. +
  5918. + /*
  5919. + * Titan 1.2 revision does support port #2
  5920. + */
  5921. + if (port_num == 2) {
  5922. + /*
  5923. + * Put the descriptors in the SRAM
  5924. + */
  5925. + reg_data = TITAN_GE_READ(0x48a0);
  5926. +
  5927. + reg_data |= 0x100000;
  5928. + reg_data |= (0xff << 10) | (2*(0xff + 1));
  5929. +
  5930. + TITAN_GE_WRITE(0x48a0, reg_data);
  5931. + /*
  5932. + * BAV2,BAV and DAV settings for the Rx FIFO
  5933. + */
  5934. + reg_data1 = TITAN_GE_READ(0x48a4);
  5935. + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
  5936. + TITAN_GE_WRITE(0x48a4, reg_data1);
  5937. +
  5938. + reg_data &= ~(0x00100000);
  5939. + reg_data |= 0x200000;
  5940. +
  5941. + TITAN_GE_WRITE(0x48a0, reg_data);
  5942. +
  5943. + reg_data = TITAN_GE_READ(0x4958);
  5944. + reg_data |= 0x100000;
  5945. +
  5946. + TITAN_GE_WRITE(0x4958, reg_data);
  5947. + reg_data |= (0xff << 10) | (2*(0xff + 1));
  5948. + TITAN_GE_WRITE(0x4958, reg_data);
  5949. +
  5950. + /*
  5951. + * BAV2, BAV and DAV settings for the Tx FIFO
  5952. + */
  5953. + reg_data1 = TITAN_GE_READ(0x495c);
  5954. + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
  5955. +
  5956. + TITAN_GE_WRITE(0x495c, reg_data1);
  5957. +
  5958. + reg_data &= ~(0x00100000);
  5959. + reg_data |= 0x200000;
  5960. +
  5961. + TITAN_GE_WRITE(0x4958, reg_data);
  5962. + }
  5963. +
  5964. + if (port_num == 2) {
  5965. + reg_data = TITAN_GE_READ(0x48a0);
  5966. +
  5967. + reg_data |= 0x100000;
  5968. + reg_data |= (0xff << 10) | (2*(0xff + 1));
  5969. +
  5970. + TITAN_GE_WRITE(0x48a0, reg_data);
  5971. + /*
  5972. + * BAV2,BAV and DAV settings for the Rx FIFO
  5973. + */
  5974. + reg_data1 = TITAN_GE_READ(0x48a4);
  5975. + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
  5976. + TITAN_GE_WRITE(0x48a4, reg_data1);
  5977. +
  5978. + reg_data &= ~(0x00100000);
  5979. + reg_data |= 0x200000;
  5980. +
  5981. + TITAN_GE_WRITE(0x48a0, reg_data);
  5982. +
  5983. + reg_data = TITAN_GE_READ(0x4958);
  5984. + reg_data |= 0x100000;
  5985. +
  5986. + TITAN_GE_WRITE(0x4958, reg_data);
  5987. + reg_data |= (0xff << 10) | (2*(0xff + 1));
  5988. + TITAN_GE_WRITE(0x4958, reg_data);
  5989. +
  5990. + /*
  5991. + * BAV2, BAV and DAV settings for the Tx FIFO
  5992. + */
  5993. + reg_data1 = TITAN_GE_READ(0x495c);
  5994. + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
  5995. +
  5996. + TITAN_GE_WRITE(0x495c, reg_data1);
  5997. +
  5998. + reg_data &= ~(0x00100000);
  5999. + reg_data |= 0x200000;
  6000. +
  6001. + TITAN_GE_WRITE(0x4958, reg_data);
  6002. + }
  6003. +
  6004. + /*
  6005. + * Step 3: TRTG block enable
  6006. + */
  6007. + reg_data = TITAN_GE_READ(TITAN_GE_TRTG_CONFIG + (port_num << 12));
  6008. +
  6009. + /*
  6010. + * This is the 1.2 revision of the chip. It has fix for the
  6011. + * IP header alignment. Now, the IP header begins at an
  6012. + * aligned address and this wont need an extra copy in the
  6013. + * driver. This performance drawback existed in the previous
  6014. + * versions of the silicon
  6015. + */
  6016. + reg_data_1 = TITAN_GE_READ(0x103c + (port_num << 12));
  6017. + reg_data_1 |= 0x40000000;
  6018. + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
  6019. +
  6020. + reg_data_1 |= 0x04000000;
  6021. + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
  6022. +
  6023. + mdelay(5);
  6024. +
  6025. + reg_data_1 &= ~(0x04000000);
  6026. + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
  6027. +
  6028. + mdelay(5);
  6029. +
  6030. + reg_data |= 0x0001;
  6031. + TITAN_GE_WRITE((TITAN_GE_TRTG_CONFIG + (port_num << 12)), reg_data);
  6032. +
  6033. + /*
  6034. + * Step 4: Start the Tx activity
  6035. + */
  6036. + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_2 + (port_num << 12)), 0xe197);
  6037. +#ifdef TITAN_GE_JUMBO_FRAMES
  6038. + TITAN_GE_WRITE((0x1258 + (port_num << 12)), 0x4000);
  6039. +#endif
  6040. + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
  6041. + reg_data |= 0x0001; /* Enable TMAC */
  6042. + reg_data |= 0x6c70; /* PAUSE also set */
  6043. +
  6044. + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + (port_num << 12)), reg_data);
  6045. +
  6046. + udelay(30);
  6047. +
  6048. + /* Destination Address drop bit */
  6049. + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_2 + (port_num << 12));
  6050. + reg_data |= 0x218; /* DA_DROP bit and pause */
  6051. + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_2 + (port_num << 12)), reg_data);
  6052. +
  6053. + TITAN_GE_WRITE((0x1218 + (port_num << 12)), 0x3);
  6054. +
  6055. +#ifdef TITAN_GE_JUMBO_FRAMES
  6056. + TITAN_GE_WRITE((0x1208 + (port_num << 12)), 0x4000);
  6057. +#endif
  6058. + /* Start the Rx activity */
  6059. + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
  6060. + reg_data |= 0x0001; /* RMAC Enable */
  6061. + reg_data |= 0x0010; /* CRC Check enable */
  6062. + reg_data |= 0x0040; /* Min Frame check enable */
  6063. + reg_data |= 0x4400; /* Max Frame check enable */
  6064. +
  6065. + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
  6066. +
  6067. + udelay(30);
  6068. +
  6069. + /*
  6070. + * Enable the Interrupts for Tx and Rx
  6071. + */
  6072. + reg_data1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
  6073. +
  6074. + if (port_num == 0) {
  6075. + reg_data1 |= 0x3;
  6076. +#ifdef CONFIG_SMP
  6077. + TITAN_GE_WRITE(0x0038, 0x003);
  6078. +#else
  6079. + TITAN_GE_WRITE(0x0038, 0x303);
  6080. +#endif
  6081. + }
  6082. +
  6083. + if (port_num == 1) {
  6084. + reg_data1 |= 0x300;
  6085. + }
  6086. +
  6087. + if (port_num == 2)
  6088. + reg_data1 |= 0x30000;
  6089. +
  6090. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data1);
  6091. + TITAN_GE_WRITE(0x003c, 0x300);
  6092. +
  6093. + if (config_done == 0) {
  6094. + TITAN_GE_WRITE(0x0024, 0x04000024); /* IRQ vector */
  6095. + TITAN_GE_WRITE(0x0020, 0x000fb000); /* INTMSG base */
  6096. + }
  6097. +
  6098. + /* Priority */
  6099. + reg_data = TITAN_GE_READ(0x1038 + (port_num << 12));
  6100. + reg_data &= ~(0x00f00000);
  6101. + TITAN_GE_WRITE((0x1038 + (port_num << 12)), reg_data);
  6102. +
  6103. + /* Step 5: GMII config */
  6104. + titan_ge_gmii_config(port_num);
  6105. +
  6106. + if (config_done == 0) {
  6107. + TITAN_GE_WRITE(0x1a80, 0);
  6108. + config_done = 1;
  6109. + }
  6110. +
  6111. + return TITAN_OK;
  6112. +}
  6113. +
  6114. +/*
  6115. + * Function to queue the packet for the Ethernet device
  6116. + */
  6117. +static void titan_ge_tx_queue(titan_ge_port_info * titan_ge_eth,
  6118. + struct sk_buff * skb)
  6119. +{
  6120. + struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev;
  6121. + unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q;
  6122. + volatile titan_ge_tx_desc *tx_curr;
  6123. + int port_num = titan_ge_eth->port_num;
  6124. +
  6125. + tx_curr = &(titan_ge_eth->tx_desc_area[curr_desc]);
  6126. + tx_curr->buffer_addr =
  6127. + dma_map_single(device, skb->data, skb_headlen(skb),
  6128. + DMA_TO_DEVICE);
  6129. +
  6130. + titan_ge_eth->tx_skb[curr_desc] = (struct sk_buff *) skb;
  6131. + tx_curr->buffer_len = skb_headlen(skb);
  6132. +
  6133. + /* Last descriptor enables interrupt and changes ownership */
  6134. + tx_curr->cmd_sts = 0x1 | (1 << 15) | (1 << 5);
  6135. +
  6136. + /* Kick the XDMA to start the transfer from memory to the FIFO */
  6137. + TITAN_GE_WRITE((0x5044 + (port_num << 8)), 0x1);
  6138. +
  6139. + /* Current descriptor updated */
  6140. + titan_ge_eth->tx_curr_desc_q = (curr_desc + 1) % TITAN_GE_TX_QUEUE;
  6141. +
  6142. + /* Prefetch the next descriptor */
  6143. + prefetch((const void *)
  6144. + &titan_ge_eth->tx_desc_area[titan_ge_eth->tx_curr_desc_q]);
  6145. +}
  6146. +
  6147. +/*
  6148. + * Actually does the open of the Ethernet device
  6149. + */
  6150. +static int titan_ge_eth_open(struct net_device *netdev)
  6151. +{
  6152. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6153. + unsigned int port_num = titan_ge_eth->port_num;
  6154. + struct device *device = &titan_ge_device[port_num]->dev;
  6155. + unsigned long reg_data;
  6156. + unsigned int phy_reg;
  6157. + int err = 0;
  6158. +
  6159. + /* Stop the Rx activity */
  6160. + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
  6161. + reg_data &= ~(0x00000001);
  6162. + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
  6163. +
  6164. + /* Clear the port interrupts */
  6165. + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT + (port_num << 8)), 0x0);
  6166. +
  6167. + if (config_done == 0) {
  6168. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0);
  6169. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_B, 0);
  6170. + }
  6171. +
  6172. + /* Set the MAC Address */
  6173. + memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
  6174. +
  6175. + if (config_done == 0)
  6176. + titan_port_init(netdev, titan_ge_eth);
  6177. +
  6178. + titan_ge_update_afx(titan_ge_eth);
  6179. +
  6180. + /* Allocate the Tx ring now */
  6181. + titan_ge_eth->tx_ring_skbs = 0;
  6182. + titan_ge_eth->tx_ring_size = TITAN_GE_TX_QUEUE;
  6183. +
  6184. + /* Allocate space in the SRAM for the descriptors */
  6185. + titan_ge_eth->tx_desc_area = (titan_ge_tx_desc *)
  6186. + (titan_ge_sram + TITAN_TX_RING_BYTES * port_num);
  6187. + titan_ge_eth->tx_dma = TITAN_SRAM_BASE + TITAN_TX_RING_BYTES * port_num;
  6188. +
  6189. + if (!titan_ge_eth->tx_desc_area) {
  6190. + printk(KERN_ERR
  6191. + "%s: Cannot allocate Tx Ring (size %d bytes) for port %d\n",
  6192. + netdev->name, TITAN_TX_RING_BYTES, port_num);
  6193. + return -ENOMEM;
  6194. + }
  6195. +
  6196. + memset(titan_ge_eth->tx_desc_area, 0, titan_ge_eth->tx_desc_area_size);
  6197. +
  6198. + /* Now initialize the Tx descriptor ring */
  6199. + titan_ge_init_tx_desc_ring(titan_ge_eth,
  6200. + titan_ge_eth->tx_ring_size,
  6201. + (unsigned long) titan_ge_eth->tx_desc_area,
  6202. + (unsigned long) titan_ge_eth->tx_dma);
  6203. +
  6204. + /* Allocate the Rx ring now */
  6205. + titan_ge_eth->rx_ring_size = TITAN_GE_RX_QUEUE;
  6206. + titan_ge_eth->rx_ring_skbs = 0;
  6207. +
  6208. + titan_ge_eth->rx_desc_area =
  6209. + (titan_ge_rx_desc *)(titan_ge_sram + 0x1000 + TITAN_RX_RING_BYTES * port_num);
  6210. +
  6211. + titan_ge_eth->rx_dma = TITAN_SRAM_BASE + 0x1000 + TITAN_RX_RING_BYTES * port_num;
  6212. +
  6213. + if (!titan_ge_eth->rx_desc_area) {
  6214. + printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n",
  6215. + netdev->name, TITAN_RX_RING_BYTES);
  6216. +
  6217. + printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
  6218. + netdev->name);
  6219. +
  6220. + dma_free_coherent(device, titan_ge_eth->tx_desc_area_size,
  6221. + (void *) titan_ge_eth->tx_desc_area,
  6222. + titan_ge_eth->tx_dma);
  6223. +
  6224. + return -ENOMEM;
  6225. + }
  6226. +
  6227. + memset(titan_ge_eth->rx_desc_area, 0, titan_ge_eth->rx_desc_area_size);
  6228. +
  6229. + /* Now initialize the Rx ring */
  6230. +#ifdef TITAN_GE_JUMBO_FRAMES
  6231. + if ((titan_ge_init_rx_desc_ring
  6232. + (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_JUMBO_BUFSIZE,
  6233. + (unsigned long) titan_ge_eth->rx_desc_area, 0,
  6234. + (unsigned long) titan_ge_eth->rx_dma)) == 0)
  6235. +#else
  6236. + if ((titan_ge_init_rx_desc_ring
  6237. + (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_STD_BUFSIZE,
  6238. + (unsigned long) titan_ge_eth->rx_desc_area, 0,
  6239. + (unsigned long) titan_ge_eth->rx_dma)) == 0)
  6240. +#endif
  6241. + panic("%s: Error initializing RX Ring\n", netdev->name);
  6242. +
  6243. + /* Fill the Rx ring with the SKBs */
  6244. + titan_ge_port_start(netdev, titan_ge_eth);
  6245. +
  6246. + /*
  6247. + * Check if Interrupt Coalscing needs to be turned on. The
  6248. + * values specified in the register is multiplied by
  6249. + * (8 x 64 nanoseconds) to determine when an interrupt should
  6250. + * be sent to the CPU.
  6251. + */
  6252. +
  6253. + if (TITAN_GE_TX_COAL) {
  6254. + titan_ge_eth->tx_int_coal =
  6255. + titan_ge_tx_coal(TITAN_GE_TX_COAL, port_num);
  6256. + }
  6257. +
  6258. + err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
  6259. + if (err == TITAN_GE_MDIO_ERROR) {
  6260. + printk(KERN_ERR
  6261. + "Could not read PHY control register 0x11 \n");
  6262. + return TITAN_ERROR;
  6263. + }
  6264. + if (!(phy_reg & 0x0400)) {
  6265. + netif_carrier_off(netdev);
  6266. + netif_stop_queue(netdev);
  6267. + return TITAN_ERROR;
  6268. + } else {
  6269. + netif_carrier_on(netdev);
  6270. + netif_start_queue(netdev);
  6271. + }
  6272. +
  6273. + return TITAN_OK;
  6274. +}
  6275. +
  6276. +/*
  6277. + * Queue the packet for Tx. Currently no support for zero copy,
  6278. + * checksum offload and Scatter Gather. The chip does support
  6279. + * Scatter Gather only. But, that wont help here since zero copy
  6280. + * requires support for Tx checksumming also.
  6281. + */
  6282. +int titan_ge_start_xmit(struct sk_buff *skb, struct net_device *netdev)
  6283. +{
  6284. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6285. + unsigned long flags;
  6286. + struct net_device_stats *stats;
  6287. +//printk("titan_ge_start_xmit\n");
  6288. +
  6289. + stats = &titan_ge_eth->stats;
  6290. + spin_lock_irqsave(&titan_ge_eth->lock, flags);
  6291. +
  6292. + if ((TITAN_GE_TX_QUEUE - titan_ge_eth->tx_ring_skbs) <=
  6293. + (skb_shinfo(skb)->nr_frags + 1)) {
  6294. + netif_stop_queue(netdev);
  6295. + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
  6296. + printk(KERN_ERR "Tx OOD \n");
  6297. + return 1;
  6298. + }
  6299. +
  6300. + titan_ge_tx_queue(titan_ge_eth, skb);
  6301. + titan_ge_eth->tx_ring_skbs++;
  6302. +
  6303. + if (TITAN_GE_TX_QUEUE <= (titan_ge_eth->tx_ring_skbs + 4)) {
  6304. + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
  6305. + titan_ge_free_tx_queue(titan_ge_eth);
  6306. + spin_lock_irqsave(&titan_ge_eth->lock, flags);
  6307. + }
  6308. +
  6309. + stats->tx_bytes += skb->len;
  6310. + stats->tx_packets++;
  6311. +
  6312. + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
  6313. +
  6314. + netdev->trans_start = jiffies;
  6315. +
  6316. + return 0;
  6317. +}
  6318. +
  6319. +/*
  6320. + * Actually does the Rx. Rx side checksumming supported.
  6321. + */
  6322. +static int titan_ge_rx(struct net_device *netdev, int port_num,
  6323. + titan_ge_port_info * titan_ge_port,
  6324. + titan_ge_packet * packet)
  6325. +{
  6326. + int rx_curr_desc, rx_used_desc;
  6327. + volatile titan_ge_rx_desc *rx_desc;
  6328. +
  6329. + rx_curr_desc = titan_ge_port->rx_curr_desc_q;
  6330. + rx_used_desc = titan_ge_port->rx_used_desc_q;
  6331. +
  6332. + if (((rx_curr_desc + 1) % TITAN_GE_RX_QUEUE) == rx_used_desc)
  6333. + return TITAN_ERROR;
  6334. +
  6335. + rx_desc = &(titan_ge_port->rx_desc_area[rx_curr_desc]);
  6336. +
  6337. + if (rx_desc->cmd_sts & TITAN_GE_RX_BUFFER_OWNED)
  6338. + return TITAN_ERROR;
  6339. +
  6340. + packet->skb = titan_ge_port->rx_skb[rx_curr_desc];
  6341. + packet->len = (rx_desc->cmd_sts & 0x7fff);
  6342. +
  6343. + /*
  6344. + * At this point, we dont know if the checksumming
  6345. + * actually helps relieve CPU. So, keep it for
  6346. + * port 0 only
  6347. + */
  6348. + packet->checksum = ntohs((rx_desc->buffer & 0xffff0000) >> 16);
  6349. + packet->cmd_sts = rx_desc->cmd_sts;
  6350. +
  6351. + titan_ge_port->rx_curr_desc_q = (rx_curr_desc + 1) % TITAN_GE_RX_QUEUE;
  6352. +
  6353. + /* Prefetch the next descriptor */
  6354. + prefetch((const void *)
  6355. + &titan_ge_port->rx_desc_area[titan_ge_port->rx_curr_desc_q + 1]);
  6356. +
  6357. + return TITAN_OK;
  6358. +}
  6359. +
  6360. +/*
  6361. + * Free the Tx queue of the used SKBs
  6362. + */
  6363. +static int titan_ge_free_tx_queue(titan_ge_port_info *titan_ge_eth)
  6364. +{
  6365. + unsigned long flags;
  6366. +
  6367. + /* Take the lock */
  6368. + spin_lock_irqsave(&(titan_ge_eth->lock), flags);
  6369. +
  6370. + while (titan_ge_return_tx_desc(titan_ge_eth, titan_ge_eth->port_num) == 0)
  6371. + if (titan_ge_eth->tx_ring_skbs != 1)
  6372. + titan_ge_eth->tx_ring_skbs--;
  6373. +
  6374. + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
  6375. +
  6376. + return TITAN_OK;
  6377. +}
  6378. +
  6379. +/*
  6380. + * Threshold beyond which we do the cleaning of
  6381. + * Tx queue and new allocation for the Rx
  6382. + * queue
  6383. + */
  6384. +#define TX_THRESHOLD 4
  6385. +#define RX_THRESHOLD 10
  6386. +
  6387. +/*
  6388. + * Receive the packets and send it to the kernel.
  6389. + */
  6390. +static int titan_ge_receive_queue(struct net_device *netdev, unsigned int max)
  6391. +{
  6392. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6393. + unsigned int port_num = titan_ge_eth->port_num;
  6394. + titan_ge_packet packet;
  6395. + struct net_device_stats *stats;
  6396. + struct sk_buff *skb;
  6397. + unsigned long received_packets = 0;
  6398. + unsigned int ack;
  6399. +
  6400. + stats = &titan_ge_eth->stats;
  6401. +
  6402. + while ((--max)
  6403. + && (titan_ge_rx(netdev, port_num, titan_ge_eth, &packet) == TITAN_OK)) {
  6404. + skb = (struct sk_buff *) packet.skb;
  6405. +
  6406. + titan_ge_eth->rx_ring_skbs--;
  6407. +
  6408. + if (--titan_ge_eth->rx_work_limit < 0)
  6409. + break;
  6410. + received_packets++;
  6411. +
  6412. + stats->rx_packets++;
  6413. + stats->rx_bytes += packet.len;
  6414. +
  6415. + if ((packet.cmd_sts & TITAN_GE_RX_PERR) ||
  6416. + (packet.cmd_sts & TITAN_GE_RX_OVERFLOW_ERROR) ||
  6417. + (packet.cmd_sts & TITAN_GE_RX_TRUNC) ||
  6418. + (packet.cmd_sts & TITAN_GE_RX_CRC_ERROR)) {
  6419. + stats->rx_dropped++;
  6420. + dev_kfree_skb_any(skb);
  6421. +
  6422. + continue;
  6423. + }
  6424. + /*
  6425. + * Either support fast path or slow path. Decision
  6426. + * making can really slow down the performance. The
  6427. + * idea is to cut down the number of checks and improve
  6428. + * the fastpath.
  6429. + */
  6430. +
  6431. + skb_put(skb, packet.len - 2);
  6432. +
  6433. + /*
  6434. + * Increment data pointer by two since thats where
  6435. + * the MAC starts
  6436. + */
  6437. + skb_reserve(skb, 2);
  6438. + skb->protocol = eth_type_trans(skb, netdev);
  6439. + netif_receive_skb(skb);
  6440. +
  6441. + if (titan_ge_eth->rx_threshold > RX_THRESHOLD) {
  6442. + ack = titan_ge_rx_task(netdev, titan_ge_eth);
  6443. + TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
  6444. + titan_ge_eth->rx_threshold = 0;
  6445. + } else
  6446. + titan_ge_eth->rx_threshold++;
  6447. +
  6448. + if (titan_ge_eth->tx_threshold > TX_THRESHOLD) {
  6449. + titan_ge_eth->tx_threshold = 0;
  6450. + titan_ge_free_tx_queue(titan_ge_eth);
  6451. + }
  6452. + else
  6453. + titan_ge_eth->tx_threshold++;
  6454. +
  6455. + }
  6456. + return received_packets;
  6457. +}
  6458. +
  6459. +
  6460. +/*
  6461. + * Enable the Rx side interrupts
  6462. + */
  6463. +static void titan_ge_enable_int(unsigned int port_num,
  6464. + titan_ge_port_info *titan_ge_eth,
  6465. + struct net_device *netdev)
  6466. +{
  6467. + unsigned long reg_data = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
  6468. +
  6469. + if (port_num == 0)
  6470. + reg_data |= 0x3;
  6471. + if (port_num == 1)
  6472. + reg_data |= 0x300;
  6473. + if (port_num == 2)
  6474. + reg_data |= 0x30000;
  6475. +
  6476. + /* Re-enable interrupts */
  6477. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data);
  6478. +}
  6479. +
  6480. +/*
  6481. + * Main function to handle the polling for Rx side NAPI.
  6482. + * Receive interrupts have been disabled at this point.
  6483. + * The poll schedules the transmit followed by receive.
  6484. + */
  6485. +static int titan_ge_poll(struct net_device *netdev, int *budget)
  6486. +{
  6487. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6488. + int port_num = titan_ge_eth->port_num;
  6489. + int work_done = 0;
  6490. + unsigned long flags, status;
  6491. +
  6492. + titan_ge_eth->rx_work_limit = *budget;
  6493. + if (titan_ge_eth->rx_work_limit > netdev->quota)
  6494. + titan_ge_eth->rx_work_limit = netdev->quota;
  6495. +
  6496. + do {
  6497. + /* Do the transmit cleaning work here */
  6498. + titan_ge_free_tx_queue(titan_ge_eth);
  6499. +
  6500. + /* Ack the Rx interrupts */
  6501. + if (port_num == 0)
  6502. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x3);
  6503. + if (port_num == 1)
  6504. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x300);
  6505. + if (port_num == 2)
  6506. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x30000);
  6507. +
  6508. + work_done += titan_ge_receive_queue(netdev, 0);
  6509. +
  6510. + /* Out of quota and there is work to be done */
  6511. + if (titan_ge_eth->rx_work_limit < 0)
  6512. + goto not_done;
  6513. +
  6514. + /* Receive alloc_skb could lead to OOM */
  6515. + if (oom_flag == 1) {
  6516. + oom_flag = 0;
  6517. + goto oom;
  6518. + }
  6519. +
  6520. + status = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
  6521. + } while (status & 0x30300);
  6522. +
  6523. + /* If we are here, then no more interrupts to process */
  6524. + goto done;
  6525. +
  6526. +not_done:
  6527. + *budget -= work_done;
  6528. + netdev->quota -= work_done;
  6529. + return 1;
  6530. +
  6531. +oom:
  6532. + printk(KERN_ERR "OOM \n");
  6533. + netif_rx_complete(netdev);
  6534. + return 0;
  6535. +
  6536. +done:
  6537. + /*
  6538. + * No more packets on the poll list. Turn the interrupts
  6539. + * back on and we should be able to catch the new
  6540. + * packets in the interrupt handler
  6541. + */
  6542. + if (!work_done)
  6543. + work_done = 1;
  6544. +
  6545. + *budget -= work_done;
  6546. + netdev->quota -= work_done;
  6547. +
  6548. + spin_lock_irqsave(&titan_ge_eth->lock, flags);
  6549. +
  6550. + /* Remove us from the poll list */
  6551. + netif_rx_complete(netdev);
  6552. +
  6553. + /* Re-enable interrupts */
  6554. + titan_ge_enable_int(port_num, titan_ge_eth, netdev);
  6555. +
  6556. + spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
  6557. +
  6558. + return 0;
  6559. +}
  6560. +
  6561. +/*
  6562. + * Close the network device
  6563. + */
  6564. +int titan_ge_stop(struct net_device *netdev)
  6565. +{
  6566. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6567. +
  6568. + spin_lock_irq(&(titan_ge_eth->lock));
  6569. + titan_ge_eth_stop(netdev);
  6570. + free_irq(netdev->irq, netdev);
  6571. + spin_unlock_irq(&titan_ge_eth->lock);
  6572. +
  6573. + return TITAN_OK;
  6574. +}
  6575. +
  6576. +/*
  6577. + * Free the Tx ring
  6578. + */
  6579. +static void titan_ge_free_tx_rings(struct net_device *netdev)
  6580. +{
  6581. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6582. + unsigned int port_num = titan_ge_eth->port_num;
  6583. + unsigned int curr;
  6584. + unsigned long reg_data;
  6585. +
  6586. + /* Stop the Tx DMA */
  6587. + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
  6588. + (port_num << 8));
  6589. + reg_data |= 0xc0000000;
  6590. + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
  6591. + (port_num << 8)), reg_data);
  6592. +
  6593. + /* Disable the TMAC */
  6594. + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
  6595. + (port_num << 12));
  6596. + reg_data &= ~(0x00000001);
  6597. + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
  6598. + (port_num << 12)), reg_data);
  6599. +
  6600. + for (curr = 0;
  6601. + (titan_ge_eth->tx_ring_skbs) && (curr < TITAN_GE_TX_QUEUE);
  6602. + curr++) {
  6603. + if (titan_ge_eth->tx_skb[curr]) {
  6604. + dev_kfree_skb(titan_ge_eth->tx_skb[curr]);
  6605. + titan_ge_eth->tx_ring_skbs--;
  6606. + }
  6607. + }
  6608. +
  6609. + if (titan_ge_eth->tx_ring_skbs != 0)
  6610. + printk
  6611. + ("%s: Error on Tx descriptor free - could not free %d"
  6612. + " descriptors\n", netdev->name,
  6613. + titan_ge_eth->tx_ring_skbs);
  6614. +
  6615. +#ifndef TITAN_RX_RING_IN_SRAM
  6616. + dma_free_coherent(&titan_ge_device[port_num]->dev,
  6617. + titan_ge_eth->tx_desc_area_size,
  6618. + (void *) titan_ge_eth->tx_desc_area,
  6619. + titan_ge_eth->tx_dma);
  6620. +#endif
  6621. +}
  6622. +
  6623. +/*
  6624. + * Free the Rx ring
  6625. + */
  6626. +static void titan_ge_free_rx_rings(struct net_device *netdev)
  6627. +{
  6628. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6629. + unsigned int port_num = titan_ge_eth->port_num;
  6630. + unsigned int curr;
  6631. + unsigned long reg_data;
  6632. +
  6633. + /* Stop the Rx DMA */
  6634. + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
  6635. + (port_num << 8));
  6636. + reg_data |= 0x000c0000;
  6637. + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
  6638. + (port_num << 8)), reg_data);
  6639. +
  6640. + /* Disable the RMAC */
  6641. + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
  6642. + (port_num << 12));
  6643. + reg_data &= ~(0x00000001);
  6644. + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
  6645. + (port_num << 12)), reg_data);
  6646. +
  6647. + for (curr = 0;
  6648. + titan_ge_eth->rx_ring_skbs && (curr < TITAN_GE_RX_QUEUE);
  6649. + curr++) {
  6650. + if (titan_ge_eth->rx_skb[curr]) {
  6651. + dev_kfree_skb(titan_ge_eth->rx_skb[curr]);
  6652. + titan_ge_eth->rx_ring_skbs--;
  6653. + }
  6654. + }
  6655. +
  6656. + if (titan_ge_eth->rx_ring_skbs != 0)
  6657. + printk(KERN_ERR
  6658. + "%s: Error in freeing Rx Ring. %d skb's still"
  6659. + " stuck in RX Ring - ignoring them\n", netdev->name,
  6660. + titan_ge_eth->rx_ring_skbs);
  6661. +
  6662. +#ifndef TITAN_RX_RING_IN_SRAM
  6663. + dma_free_coherent(&titan_ge_device[port_num]->dev,
  6664. + titan_ge_eth->rx_desc_area_size,
  6665. + (void *) titan_ge_eth->rx_desc_area,
  6666. + titan_ge_eth->rx_dma);
  6667. +#endif
  6668. +}
  6669. +
  6670. +/*
  6671. + * Actually does the stop of the Ethernet device
  6672. + */
  6673. +static void titan_ge_eth_stop(struct net_device *netdev)
  6674. +{
  6675. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6676. +
  6677. + netif_stop_queue(netdev);
  6678. +
  6679. + titan_ge_port_reset(titan_ge_eth->port_num);
  6680. +
  6681. + titan_ge_free_tx_rings(netdev);
  6682. + titan_ge_free_rx_rings(netdev);
  6683. +
  6684. + /* Disable the Tx and Rx Interrupts for all channels */
  6685. + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, 0x0);
  6686. +}
  6687. +
  6688. +/*
  6689. + * Update the MAC address. Note that we have to write the
  6690. + * address in three station registers, 16 bits each. And this
  6691. + * has to be done for TMAC and RMAC
  6692. + */
  6693. +static void titan_ge_update_mac_address(struct net_device *netdev)
  6694. +{
  6695. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6696. + unsigned int port_num = titan_ge_eth->port_num;
  6697. + u8 p_addr[6];
  6698. +
  6699. + memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
  6700. + memcpy(p_addr, netdev->dev_addr, 6);
  6701. +
  6702. + /* Update the Address Filtering Match tables */
  6703. + titan_ge_update_afx(titan_ge_eth);
  6704. +
  6705. + printk("Station MAC : %d %d %d %d %d %d \n",
  6706. + p_addr[5], p_addr[4], p_addr[3],
  6707. + p_addr[2], p_addr[1], p_addr[0]);
  6708. +
  6709. + /* Set the MAC address here for TMAC and RMAC */
  6710. + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port_num << 12)),
  6711. + ((p_addr[5] << 8) | p_addr[4]));
  6712. + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port_num << 12)),
  6713. + ((p_addr[3] << 8) | p_addr[2]));
  6714. + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port_num << 12)),
  6715. + ((p_addr[1] << 8) | p_addr[0]));
  6716. +
  6717. + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port_num << 12)),
  6718. + ((p_addr[5] << 8) | p_addr[4]));
  6719. + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port_num << 12)),
  6720. + ((p_addr[3] << 8) | p_addr[2]));
  6721. + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port_num << 12)),
  6722. + ((p_addr[1] << 8) | p_addr[0]));
  6723. +}
  6724. +
  6725. +/*
  6726. + * Set the MAC address of the Ethernet device
  6727. + */
  6728. +static int titan_ge_set_mac_address(struct net_device *dev, void *addr)
  6729. +{
  6730. + titan_ge_port_info *tp = netdev_priv(dev);
  6731. + struct sockaddr *sa = addr;
  6732. +
  6733. + memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
  6734. +
  6735. + spin_lock_irq(&tp->lock);
  6736. + titan_ge_update_mac_address(dev);
  6737. + spin_unlock_irq(&tp->lock);
  6738. +
  6739. + return 0;
  6740. +}
  6741. +
  6742. +/*
  6743. + * Get the Ethernet device stats
  6744. + */
  6745. +static struct net_device_stats *titan_ge_get_stats(struct net_device *netdev)
  6746. +{
  6747. + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
  6748. +
  6749. + return &titan_ge_eth->stats;
  6750. +}
  6751. +
  6752. +/*
  6753. + * Initialize the Rx descriptor ring for the Titan Ge
  6754. + */
  6755. +static int titan_ge_init_rx_desc_ring(titan_ge_port_info * titan_eth_port,
  6756. + int rx_desc_num,
  6757. + int rx_buff_size,
  6758. + unsigned long rx_desc_base_addr,
  6759. + unsigned long rx_buff_base_addr,
  6760. + unsigned long rx_dma)
  6761. +{
  6762. + volatile titan_ge_rx_desc *rx_desc;
  6763. + unsigned long buffer_addr;
  6764. + int index;
  6765. + unsigned long titan_ge_rx_desc_bus = rx_dma;
  6766. +
  6767. + buffer_addr = rx_buff_base_addr;
  6768. + rx_desc = (titan_ge_rx_desc *) rx_desc_base_addr;
  6769. +
  6770. + /* Check alignment */
  6771. + if (rx_buff_base_addr & 0xF)
  6772. + return 0;
  6773. +
  6774. + /* Check Rx buffer size */
  6775. + if ((rx_buff_size < 8) || (rx_buff_size > TITAN_GE_MAX_RX_BUFFER))
  6776. + return 0;
  6777. +
  6778. + /* 64-bit alignment
  6779. + if ((rx_buff_base_addr + rx_buff_size) & 0x7)
  6780. + return 0; */
  6781. +
  6782. + /* Initialize the Rx desc ring */
  6783. + for (index = 0; index < rx_desc_num; index++) {
  6784. + titan_ge_rx_desc_bus += sizeof(titan_ge_rx_desc);
  6785. + rx_desc[index].cmd_sts = 0;
  6786. + rx_desc[index].buffer_addr = buffer_addr;
  6787. + titan_eth_port->rx_skb[index] = NULL;
  6788. + buffer_addr += rx_buff_size;
  6789. + }
  6790. +
  6791. + titan_eth_port->rx_curr_desc_q = 0;
  6792. + titan_eth_port->rx_used_desc_q = 0;
  6793. +
  6794. + titan_eth_port->rx_desc_area = (titan_ge_rx_desc *) rx_desc_base_addr;
  6795. + titan_eth_port->rx_desc_area_size =
  6796. + rx_desc_num * sizeof(titan_ge_rx_desc);
  6797. +
  6798. + titan_eth_port->rx_dma = rx_dma;
  6799. +
  6800. + return TITAN_OK;
  6801. +}
  6802. +
  6803. +/*
  6804. + * Initialize the Tx descriptor ring. Descriptors in the SRAM
  6805. + */
  6806. +static int titan_ge_init_tx_desc_ring(titan_ge_port_info * titan_ge_port,
  6807. + int tx_desc_num,
  6808. + unsigned long tx_desc_base_addr,
  6809. + unsigned long tx_dma)
  6810. +{
  6811. + titan_ge_tx_desc *tx_desc;
  6812. + int index;
  6813. + unsigned long titan_ge_tx_desc_bus = tx_dma;
  6814. +
  6815. + if (tx_desc_base_addr & 0xF)
  6816. + return 0;
  6817. +
  6818. + tx_desc = (titan_ge_tx_desc *) tx_desc_base_addr;
  6819. +
  6820. + for (index = 0; index < tx_desc_num; index++) {
  6821. + titan_ge_port->tx_dma_array[index] =
  6822. + (dma_addr_t) titan_ge_tx_desc_bus;
  6823. + titan_ge_tx_desc_bus += sizeof(titan_ge_tx_desc);
  6824. + tx_desc[index].cmd_sts = 0x0000;
  6825. + tx_desc[index].buffer_len = 0;
  6826. + tx_desc[index].buffer_addr = 0x00000000;
  6827. + titan_ge_port->tx_skb[index] = NULL;
  6828. + }
  6829. +
  6830. + titan_ge_port->tx_curr_desc_q = 0;
  6831. + titan_ge_port->tx_used_desc_q = 0;
  6832. +
  6833. + titan_ge_port->tx_desc_area = (titan_ge_tx_desc *) tx_desc_base_addr;
  6834. + titan_ge_port->tx_desc_area_size =
  6835. + tx_desc_num * sizeof(titan_ge_tx_desc);
  6836. +
  6837. + titan_ge_port->tx_dma = tx_dma;
  6838. + return TITAN_OK;
  6839. +}
  6840. +
  6841. +/*
  6842. + * Initialize the device as an Ethernet device
  6843. + */
  6844. +static int __init titan_ge_probe(struct device *device)
  6845. +{
  6846. + titan_ge_port_info *titan_ge_eth;
  6847. + struct net_device *netdev;
  6848. + int port = to_platform_device(device)->id;
  6849. + int err;
  6850. +
  6851. + netdev = alloc_etherdev(sizeof(titan_ge_port_info));
  6852. + if (!netdev) {
  6853. + err = -ENODEV;
  6854. + goto out;
  6855. + }
  6856. +
  6857. + netdev->open = titan_ge_open;
  6858. + netdev->stop = titan_ge_stop;
  6859. + netdev->hard_start_xmit = titan_ge_start_xmit;
  6860. + netdev->get_stats = titan_ge_get_stats;
  6861. + netdev->set_multicast_list = titan_ge_set_multi;
  6862. + netdev->set_mac_address = titan_ge_set_mac_address;
  6863. +
  6864. + /* Tx timeout */
  6865. + netdev->tx_timeout = titan_ge_tx_timeout;
  6866. + netdev->watchdog_timeo = 2 * HZ;
  6867. +
  6868. + /* Set these to very high values */
  6869. + netdev->poll = titan_ge_poll;
  6870. + netdev->weight = 64;
  6871. +
  6872. + netdev->tx_queue_len = TITAN_GE_TX_QUEUE;
  6873. + netif_carrier_off(netdev);
  6874. + netdev->base_addr = 0;
  6875. +
  6876. + netdev->change_mtu = titan_ge_change_mtu;
  6877. +
  6878. + titan_ge_eth = netdev_priv(netdev);
  6879. + /* Allocation of memory for the driver structures */
  6880. +
  6881. + titan_ge_eth->port_num = port;
  6882. +
  6883. + /* Configure the Tx timeout handler */
  6884. + INIT_WORK(&titan_ge_eth->tx_timeout_task,
  6885. + (void (*)(void *)) titan_ge_tx_timeout_task, netdev);
  6886. +
  6887. + spin_lock_init(&titan_ge_eth->lock);
  6888. +
  6889. + /* set MAC addresses */
  6890. + memcpy(netdev->dev_addr, titan_ge_mac_addr_base, 6);
  6891. + netdev->dev_addr[5] += port;
  6892. +
  6893. + err = register_netdev(netdev);
  6894. +
  6895. + if (err)
  6896. + goto out_free_netdev;
  6897. +
  6898. + printk(KERN_NOTICE
  6899. + "%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
  6900. + netdev->name, port, netdev->dev_addr[0],
  6901. + netdev->dev_addr[1], netdev->dev_addr[2],
  6902. + netdev->dev_addr[3], netdev->dev_addr[4],
  6903. + netdev->dev_addr[5]);
  6904. +
  6905. + printk(KERN_NOTICE "Rx NAPI supported, Tx Coalescing ON \n");
  6906. +
  6907. + return 0;
  6908. +
  6909. +out_free_netdev:
  6910. + kfree(netdev);
  6911. +
  6912. +out:
  6913. + return err;
  6914. +}
  6915. +
  6916. +static void __devexit titan_device_remove(struct device *device)
  6917. +{
  6918. +}
  6919. +
  6920. +/*
  6921. + * Reset the Ethernet port
  6922. + */
  6923. +static void titan_ge_port_reset(unsigned int port_num)
  6924. +{
  6925. + unsigned int reg_data;
  6926. +
  6927. + /* Stop the Tx port activity */
  6928. + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
  6929. + (port_num << 12));
  6930. + reg_data &= ~(0x0001);
  6931. + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
  6932. + (port_num << 12)), reg_data);
  6933. +
  6934. + /* Stop the Rx port activity */
  6935. + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
  6936. + (port_num << 12));
  6937. + reg_data &= ~(0x0001);
  6938. + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
  6939. + (port_num << 12)), reg_data);
  6940. +
  6941. + return;
  6942. +}
  6943. +
  6944. +/*
  6945. + * Return the Tx desc after use by the XDMA
  6946. + */
  6947. +static int titan_ge_return_tx_desc(titan_ge_port_info * titan_ge_eth, int port)
  6948. +{
  6949. + int tx_desc_used;
  6950. + struct sk_buff *skb;
  6951. +
  6952. + tx_desc_used = titan_ge_eth->tx_used_desc_q;
  6953. +
  6954. + /* return right away */
  6955. + if (tx_desc_used == titan_ge_eth->tx_curr_desc_q)
  6956. + return TITAN_ERROR;
  6957. +
  6958. + /* Now the critical stuff */
  6959. + skb = titan_ge_eth->tx_skb[tx_desc_used];
  6960. +
  6961. + dev_kfree_skb_any(skb);
  6962. +
  6963. + titan_ge_eth->tx_skb[tx_desc_used] = NULL;
  6964. + titan_ge_eth->tx_used_desc_q =
  6965. + (tx_desc_used + 1) % TITAN_GE_TX_QUEUE;
  6966. +
  6967. + return 0;
  6968. +}
  6969. +
  6970. +/*
  6971. + * Coalescing for the Tx path
  6972. + */
  6973. +static unsigned long titan_ge_tx_coal(unsigned long delay, int port)
  6974. +{
  6975. + unsigned long rx_delay;
  6976. +
  6977. + rx_delay = TITAN_GE_READ(TITAN_GE_INT_COALESCING);
  6978. + delay = (delay << 16) | rx_delay;
  6979. +
  6980. + TITAN_GE_WRITE(TITAN_GE_INT_COALESCING, delay);
  6981. + TITAN_GE_WRITE(0x5038, delay);
  6982. +
  6983. + return delay;
  6984. +}
  6985. +
  6986. +static struct device_driver titan_soc_driver = {
  6987. + .name = titan_string,
  6988. + .bus = &platform_bus_type,
  6989. + .probe = titan_ge_probe,
  6990. + .remove = __devexit_p(titan_device_remove),
  6991. +};
  6992. +
  6993. +static void titan_platform_release (struct device *device)
  6994. +{
  6995. + struct platform_device *pldev;
  6996. +
  6997. + /* free device */
  6998. + pldev = to_platform_device (device);
  6999. + kfree (pldev);
  7000. +}
  7001. +
  7002. +/*
  7003. + * Register the Titan GE with the kernel
  7004. + */
  7005. +static int __init titan_ge_init_module(void)
  7006. +{
  7007. + struct platform_device *pldev;
  7008. + unsigned int version, device;
  7009. + int i;
  7010. +
  7011. + printk(KERN_NOTICE
  7012. + "PMC-Sierra TITAN 10/100/1000 Ethernet Driver \n");
  7013. +
  7014. + titan_ge_base = (unsigned long) ioremap(TITAN_GE_BASE, TITAN_GE_SIZE);
  7015. + if (!titan_ge_base) {
  7016. + printk("Mapping Titan GE failed\n");
  7017. + goto out;
  7018. + }
  7019. +
  7020. + device = TITAN_GE_READ(TITAN_GE_DEVICE_ID);
  7021. + version = (device & 0x000f0000) >> 16;
  7022. + device &= 0x0000ffff;
  7023. +
  7024. + printk(KERN_NOTICE "Device Id : %x, Version : %x \n", device, version);
  7025. +
  7026. +#ifdef TITAN_RX_RING_IN_SRAM
  7027. + titan_ge_sram = (unsigned long) ioremap(TITAN_SRAM_BASE,
  7028. + TITAN_SRAM_SIZE);
  7029. + if (!titan_ge_sram) {
  7030. + printk("Mapping Titan SRAM failed\n");
  7031. + goto out_unmap_ge;
  7032. + }
  7033. +#endif
  7034. +
  7035. + if (driver_register(&titan_soc_driver)) {
  7036. + printk(KERN_ERR "Driver registration failed\n");
  7037. + goto out_unmap_sram;
  7038. + }
  7039. +
  7040. + for (i = 0; i < 3; i++) {
  7041. + titan_ge_device[i] = NULL;
  7042. +
  7043. + if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
  7044. + continue;
  7045. +
  7046. + memset (pldev, 0, sizeof (*pldev));
  7047. + pldev->name = titan_string;
  7048. + pldev->id = i;
  7049. + pldev->dev.release = titan_platform_release;
  7050. + titan_ge_device[i] = pldev;
  7051. +
  7052. + if (platform_device_register (pldev)) {
  7053. + kfree (pldev);
  7054. + titan_ge_device[i] = NULL;
  7055. + continue;
  7056. + }
  7057. +
  7058. + if (!pldev->dev.driver) {
  7059. + /*
  7060. + * The driver was not bound to this device, there was
  7061. + * no hardware at this address. Unregister it, as the
  7062. + * release fuction will take care of freeing the
  7063. + * allocated structure
  7064. + */
  7065. + titan_ge_device[i] = NULL;
  7066. + platform_device_unregister (pldev);
  7067. + }
  7068. + }
  7069. +
  7070. + return 0;
  7071. +
  7072. +out_unmap_sram:
  7073. + iounmap((void *)titan_ge_sram);
  7074. +
  7075. +out_unmap_ge:
  7076. + iounmap((void *)titan_ge_base);
  7077. +
  7078. +out:
  7079. + return -ENOMEM;
  7080. +}
  7081. +
  7082. +/*
  7083. + * Unregister the Titan GE from the kernel
  7084. + */
  7085. +static void __exit titan_ge_cleanup_module(void)
  7086. +{
  7087. + int i;
  7088. +
  7089. + driver_unregister(&titan_soc_driver);
  7090. +
  7091. + for (i = 0; i < 3; i++) {
  7092. + if (titan_ge_device[i]) {
  7093. + platform_device_unregister (titan_ge_device[i]);
  7094. + titan_ge_device[i] = NULL;
  7095. + }
  7096. + }
  7097. +
  7098. + iounmap((void *)titan_ge_sram);
  7099. + iounmap((void *)titan_ge_base);
  7100. +}
  7101. +
  7102. +MODULE_AUTHOR("Manish Lachwani <lachwani@pmc-sierra.com>");
  7103. +MODULE_DESCRIPTION("Titan GE Ethernet driver");
  7104. +MODULE_LICENSE("GPL");
  7105. +
  7106. +module_init(titan_ge_init_module);
  7107. +module_exit(titan_ge_cleanup_module);
  7108. diff -Nur linux-2.6.34.orig/drivers/net/titan_ge.h linux-loongson/drivers/net/titan_ge.h
  7109. --- linux-2.6.34.orig/drivers/net/titan_ge.h 1970-01-01 01:00:00.000000000 +0100
  7110. +++ linux-loongson/drivers/net/titan_ge.h 2010-05-27 18:12:39.084716399 +0200
  7111. @@ -0,0 +1,415 @@
  7112. +#ifndef _TITAN_GE_H_
  7113. +#define _TITAN_GE_H_
  7114. +
  7115. +#include <linux/module.h>
  7116. +#include <linux/kernel.h>
  7117. +#include <linux/spinlock.h>
  7118. +#include <asm/byteorder.h>
  7119. +
  7120. +/*
  7121. + * These functions should be later moved to a more generic location since there
  7122. + * will be others accessing it also
  7123. + */
  7124. +
  7125. +/*
  7126. + * This is the way it works: LKB5 Base is at 0x0128. TITAN_BASE is defined in
  7127. + * include/asm/titan_dep.h. TITAN_GE_BASE is the value in the TITAN_GE_LKB5
  7128. + * register.
  7129. + */
  7130. +
  7131. +#define TITAN_GE_BASE 0xfe000000UL
  7132. +#define TITAN_GE_SIZE 0x10000UL
  7133. +
  7134. +extern unsigned long titan_ge_base;
  7135. +
  7136. +#define TITAN_GE_WRITE(offset, data) \
  7137. + *(volatile u32 *)(titan_ge_base + (offset)) = (data)
  7138. +
  7139. +#define TITAN_GE_READ(offset) *(volatile u32 *)(titan_ge_base + (offset))
  7140. +
  7141. +#ifndef msec_delay
  7142. +#define msec_delay(x) do { if(in_interrupt()) { \
  7143. + /* Don't mdelay in interrupt context! */ \
  7144. + BUG(); \
  7145. + } else { \
  7146. + set_current_state(TASK_UNINTERRUPTIBLE); \
  7147. + schedule_timeout((x * HZ)/1000); \
  7148. + } } while(0)
  7149. +#endif
  7150. +
  7151. +#define TITAN_GE_PORT_0
  7152. +
  7153. +#define TITAN_SRAM_BASE ((OCD_READ(RM9000x2_OCD_LKB13) & ~1) << 4)
  7154. +#define TITAN_SRAM_SIZE 0x2000UL
  7155. +
  7156. +/*
  7157. + * We may need these constants
  7158. + */
  7159. +#define TITAN_BIT0 0x00000001
  7160. +#define TITAN_BIT1 0x00000002
  7161. +#define TITAN_BIT2 0x00000004
  7162. +#define TITAN_BIT3 0x00000008
  7163. +#define TITAN_BIT4 0x00000010
  7164. +#define TITAN_BIT5 0x00000020
  7165. +#define TITAN_BIT6 0x00000040
  7166. +#define TITAN_BIT7 0x00000080
  7167. +#define TITAN_BIT8 0x00000100
  7168. +#define TITAN_BIT9 0x00000200
  7169. +#define TITAN_BIT10 0x00000400
  7170. +#define TITAN_BIT11 0x00000800
  7171. +#define TITAN_BIT12 0x00001000
  7172. +#define TITAN_BIT13 0x00002000
  7173. +#define TITAN_BIT14 0x00004000
  7174. +#define TITAN_BIT15 0x00008000
  7175. +#define TITAN_BIT16 0x00010000
  7176. +#define TITAN_BIT17 0x00020000
  7177. +#define TITAN_BIT18 0x00040000
  7178. +#define TITAN_BIT19 0x00080000
  7179. +#define TITAN_BIT20 0x00100000
  7180. +#define TITAN_BIT21 0x00200000
  7181. +#define TITAN_BIT22 0x00400000
  7182. +#define TITAN_BIT23 0x00800000
  7183. +#define TITAN_BIT24 0x01000000
  7184. +#define TITAN_BIT25 0x02000000
  7185. +#define TITAN_BIT26 0x04000000
  7186. +#define TITAN_BIT27 0x08000000
  7187. +#define TITAN_BIT28 0x10000000
  7188. +#define TITAN_BIT29 0x20000000
  7189. +#define TITAN_BIT30 0x40000000
  7190. +#define TITAN_BIT31 0x80000000
  7191. +
  7192. +/* Flow Control */
  7193. +#define TITAN_GE_FC_NONE 0x0
  7194. +#define TITAN_GE_FC_FULL 0x1
  7195. +#define TITAN_GE_FC_TX_PAUSE 0x2
  7196. +#define TITAN_GE_FC_RX_PAUSE 0x3
  7197. +
  7198. +/* Duplex Settings */
  7199. +#define TITAN_GE_FULL_DUPLEX 0x1
  7200. +#define TITAN_GE_HALF_DUPLEX 0x2
  7201. +
  7202. +/* Speed settings */
  7203. +#define TITAN_GE_SPEED_1000 0x1
  7204. +#define TITAN_GE_SPEED_100 0x2
  7205. +#define TITAN_GE_SPEED_10 0x3
  7206. +
  7207. +/* Debugging info only */
  7208. +#undef TITAN_DEBUG
  7209. +
  7210. +/* Keep the rings in the Titan's SSRAM */
  7211. +#define TITAN_RX_RING_IN_SRAM
  7212. +
  7213. +#ifdef CONFIG_64BIT
  7214. +#define TITAN_GE_IE_MASK 0xfffffffffb001b64
  7215. +#define TITAN_GE_IE_STATUS 0xfffffffffb001b60
  7216. +#else
  7217. +#define TITAN_GE_IE_MASK 0xfb001b64
  7218. +#define TITAN_GE_IE_STATUS 0xfb001b60
  7219. +#endif
  7220. +
  7221. +/* Support for Jumbo Frames */
  7222. +#undef TITAN_GE_JUMBO_FRAMES
  7223. +
  7224. +/* Rx buffer size */
  7225. +#ifdef TITAN_GE_JUMBO_FRAMES
  7226. +#define TITAN_GE_JUMBO_BUFSIZE 9080
  7227. +#else
  7228. +#define TITAN_GE_STD_BUFSIZE 1580
  7229. +#endif
  7230. +
  7231. +/*
  7232. + * Tx and Rx Interrupt Coalescing parameter. These values are
  7233. + * for 1 Ghz processor. Rx coalescing can be taken care of
  7234. + * by NAPI. NAPI is adaptive and hence useful. Tx coalescing
  7235. + * is not adaptive. Hence, these values need to be adjusted
  7236. + * based on load, CPU speed etc.
  7237. + */
  7238. +#define TITAN_GE_RX_COAL 150
  7239. +#define TITAN_GE_TX_COAL 300
  7240. +
  7241. +#if defined(__BIG_ENDIAN)
  7242. +
  7243. +/* Define the Rx descriptor */
  7244. +typedef struct eth_rx_desc {
  7245. + u32 reserved; /* Unused */
  7246. + u32 buffer_addr; /* CPU buffer address */
  7247. + u32 cmd_sts; /* Command and Status */
  7248. + u32 buffer; /* XDMA buffer address */
  7249. +} titan_ge_rx_desc;
  7250. +
  7251. +/* Define the Tx descriptor */
  7252. +typedef struct eth_tx_desc {
  7253. + u16 cmd_sts; /* Command, Status and Buffer count */
  7254. + u16 buffer_len; /* Length of the buffer */
  7255. + u32 buffer_addr; /* Physical address of the buffer */
  7256. +} titan_ge_tx_desc;
  7257. +
  7258. +#elif defined(__LITTLE_ENDIAN)
  7259. +
  7260. +/* Define the Rx descriptor */
  7261. +typedef struct eth_rx_desc {
  7262. + u32 buffer_addr; /* CPU buffer address */
  7263. + u32 reserved; /* Unused */
  7264. + u32 buffer; /* XDMA buffer address */
  7265. + u32 cmd_sts; /* Command and Status */
  7266. +} titan_ge_rx_desc;
  7267. +
  7268. +/* Define the Tx descriptor */
  7269. +typedef struct eth_tx_desc {
  7270. + u32 buffer_addr; /* Physical address of the buffer */
  7271. + u16 buffer_len; /* Length of the buffer */
  7272. + u16 cmd_sts; /* Command, Status and Buffer count */
  7273. +} titan_ge_tx_desc;
  7274. +#endif
  7275. +
  7276. +/* Default Tx Queue Size */
  7277. +#define TITAN_GE_TX_QUEUE 128
  7278. +#define TITAN_TX_RING_BYTES (TITAN_GE_TX_QUEUE * sizeof(struct eth_tx_desc))
  7279. +
  7280. +/* Default Rx Queue Size */
  7281. +#define TITAN_GE_RX_QUEUE 64
  7282. +#define TITAN_RX_RING_BYTES (TITAN_GE_RX_QUEUE * sizeof(struct eth_rx_desc))
  7283. +
  7284. +/* Packet Structure */
  7285. +typedef struct _pkt_info {
  7286. + unsigned int len;
  7287. + unsigned int cmd_sts;
  7288. + unsigned int buffer;
  7289. + struct sk_buff *skb;
  7290. + unsigned int checksum;
  7291. +} titan_ge_packet;
  7292. +
  7293. +
  7294. +#define PHYS_CNT 3
  7295. +
  7296. +/* Titan Port specific data structure */
  7297. +typedef struct _eth_port_ctrl {
  7298. + unsigned int port_num;
  7299. + u8 port_mac_addr[6];
  7300. +
  7301. + /* Rx descriptor pointers */
  7302. + int rx_curr_desc_q, rx_used_desc_q;
  7303. +
  7304. + /* Tx descriptor pointers */
  7305. + int tx_curr_desc_q, tx_used_desc_q;
  7306. +
  7307. + /* Rx descriptor area */
  7308. + volatile titan_ge_rx_desc *rx_desc_area;
  7309. + unsigned int rx_desc_area_size;
  7310. + struct sk_buff* rx_skb[TITAN_GE_RX_QUEUE];
  7311. +
  7312. + /* Tx Descriptor area */
  7313. + volatile titan_ge_tx_desc *tx_desc_area;
  7314. + unsigned int tx_desc_area_size;
  7315. + struct sk_buff* tx_skb[TITAN_GE_TX_QUEUE];
  7316. +
  7317. + /* Timeout task */
  7318. + struct work_struct tx_timeout_task;
  7319. +
  7320. + /* DMA structures and handles */
  7321. + dma_addr_t tx_dma;
  7322. + dma_addr_t rx_dma;
  7323. + dma_addr_t tx_dma_array[TITAN_GE_TX_QUEUE];
  7324. +
  7325. + /* Device lock */
  7326. + spinlock_t lock;
  7327. +
  7328. + unsigned int tx_ring_skbs;
  7329. + unsigned int rx_ring_size;
  7330. + unsigned int tx_ring_size;
  7331. + unsigned int rx_ring_skbs;
  7332. +
  7333. + struct net_device_stats stats;
  7334. +
  7335. + /* Tx and Rx coalescing */
  7336. + unsigned long rx_int_coal;
  7337. + unsigned long tx_int_coal;
  7338. +
  7339. + /* Threshold for replenishing the Rx and Tx rings */
  7340. + unsigned int tx_threshold;
  7341. + unsigned int rx_threshold;
  7342. +
  7343. + /* NAPI work limit */
  7344. + unsigned int rx_work_limit;
  7345. +} titan_ge_port_info;
  7346. +
  7347. +/* Titan specific constants */
  7348. +#define TITAN_ETH_PORT_IRQ 3
  7349. +
  7350. +/* Max Rx buffer */
  7351. +#define TITAN_GE_MAX_RX_BUFFER 65536
  7352. +
  7353. +/* Tx and Rx Error */
  7354. +#define TITAN_GE_ERROR
  7355. +
  7356. +/* Rx Descriptor Command and Status */
  7357. +
  7358. +#define TITAN_GE_RX_CRC_ERROR TITAN_BIT27 /* crc error */
  7359. +#define TITAN_GE_RX_OVERFLOW_ERROR TITAN_BIT15 /* overflow */
  7360. +#define TITAN_GE_RX_BUFFER_OWNED TITAN_BIT21 /* buffer ownership */
  7361. +#define TITAN_GE_RX_STP TITAN_BIT31 /* start of packet */
  7362. +#define TITAN_GE_RX_BAM TITAN_BIT30 /* broadcast address match */
  7363. +#define TITAN_GE_RX_PAM TITAN_BIT28 /* physical address match */
  7364. +#define TITAN_GE_RX_LAFM TITAN_BIT29 /* logical address filter match */
  7365. +#define TITAN_GE_RX_VLAN TITAN_BIT26 /* virtual lans */
  7366. +#define TITAN_GE_RX_PERR TITAN_BIT19 /* packet error */
  7367. +#define TITAN_GE_RX_TRUNC TITAN_BIT20 /* packet size greater than 32 buffers */
  7368. +
  7369. +/* Tx Descriptor Command */
  7370. +#define TITAN_GE_TX_BUFFER_OWNED TITAN_BIT5 /* buffer ownership */
  7371. +#define TITAN_GE_TX_ENABLE_INTERRUPT TITAN_BIT15 /* Interrupt Enable */
  7372. +
  7373. +/* Return Status */
  7374. +#define TITAN_OK 0x1 /* Good Status */
  7375. +#define TITAN_ERROR 0x2 /* Error Status */
  7376. +
  7377. +/* MIB specific register offset */
  7378. +#define TITAN_GE_MSTATX_STATS_BASE_LOW 0x0800 /* MSTATX COUNTL[15:0] */
  7379. +#define TITAN_GE_MSTATX_STATS_BASE_MID 0x0804 /* MSTATX COUNTM[15:0] */
  7380. +#define TITAN_GE_MSTATX_STATS_BASE_HI 0x0808 /* MSTATX COUNTH[7:0] */
  7381. +#define TITAN_GE_MSTATX_CONTROL 0x0828 /* MSTATX Control */
  7382. +#define TITAN_GE_MSTATX_VARIABLE_SELECT 0x082C /* MSTATX Variable Select */
  7383. +
  7384. +/* MIB counter offsets, add to the TITAN_GE_MSTATX_STATS_BASE_XXX */
  7385. +#define TITAN_GE_MSTATX_RXFRAMESOK 0x0040
  7386. +#define TITAN_GE_MSTATX_RXOCTETSOK 0x0050
  7387. +#define TITAN_GE_MSTATX_RXFRAMES 0x0060
  7388. +#define TITAN_GE_MSTATX_RXOCTETS 0x0070
  7389. +#define TITAN_GE_MSTATX_RXUNICASTFRAMESOK 0x0080
  7390. +#define TITAN_GE_MSTATX_RXBROADCASTFRAMESOK 0x0090
  7391. +#define TITAN_GE_MSTATX_RXMULTICASTFRAMESOK 0x00A0
  7392. +#define TITAN_GE_MSTATX_RXTAGGEDFRAMESOK 0x00B0
  7393. +#define TITAN_GE_MSTATX_RXMACPAUSECONTROLFRAMESOK 0x00C0
  7394. +#define TITAN_GE_MSTATX_RXMACCONTROLFRAMESOK 0x00D0
  7395. +#define TITAN_GE_MSTATX_RXFCSERROR 0x00E0
  7396. +#define TITAN_GE_MSTATX_RXALIGNMENTERROR 0x00F0
  7397. +#define TITAN_GE_MSTATX_RXSYMBOLERROR 0x0100
  7398. +#define TITAN_GE_MSTATX_RXLAYER1ERROR 0x0110
  7399. +#define TITAN_GE_MSTATX_RXINRANGELENGTHERROR 0x0120
  7400. +#define TITAN_GE_MSTATX_RXLONGLENGTHERROR 0x0130
  7401. +#define TITAN_GE_MSTATX_RXLONGLENGTHCRCERROR 0x0140
  7402. +#define TITAN_GE_MSTATX_RXSHORTLENGTHERROR 0x0150
  7403. +#define TITAN_GE_MSTATX_RXSHORTLLENGTHCRCERROR 0x0160
  7404. +#define TITAN_GE_MSTATX_RXFRAMES64OCTETS 0x0170
  7405. +#define TITAN_GE_MSTATX_RXFRAMES65TO127OCTETS 0x0180
  7406. +#define TITAN_GE_MSTATX_RXFRAMES128TO255OCTETS 0x0190
  7407. +#define TITAN_GE_MSTATX_RXFRAMES256TO511OCTETS 0x01A0
  7408. +#define TITAN_GE_MSTATX_RXFRAMES512TO1023OCTETS 0x01B0
  7409. +#define TITAN_GE_MSTATX_RXFRAMES1024TO1518OCTETS 0x01C0
  7410. +#define TITAN_GE_MSTATX_RXFRAMES1519TOMAXSIZE 0x01D0
  7411. +#define TITAN_GE_MSTATX_RXSTATIONADDRESSFILTERED 0x01E0
  7412. +#define TITAN_GE_MSTATX_RXVARIABLE 0x01F0
  7413. +#define TITAN_GE_MSTATX_GENERICADDRESSFILTERED 0x0200
  7414. +#define TITAN_GE_MSTATX_UNICASTFILTERED 0x0210
  7415. +#define TITAN_GE_MSTATX_MULTICASTFILTERED 0x0220
  7416. +#define TITAN_GE_MSTATX_BROADCASTFILTERED 0x0230
  7417. +#define TITAN_GE_MSTATX_HASHFILTERED 0x0240
  7418. +#define TITAN_GE_MSTATX_TXFRAMESOK 0x0250
  7419. +#define TITAN_GE_MSTATX_TXOCTETSOK 0x0260
  7420. +#define TITAN_GE_MSTATX_TXOCTETS 0x0270
  7421. +#define TITAN_GE_MSTATX_TXTAGGEDFRAMESOK 0x0280
  7422. +#define TITAN_GE_MSTATX_TXMACPAUSECONTROLFRAMESOK 0x0290
  7423. +#define TITAN_GE_MSTATX_TXFCSERROR 0x02A0
  7424. +#define TITAN_GE_MSTATX_TXSHORTLENGTHERROR 0x02B0
  7425. +#define TITAN_GE_MSTATX_TXLONGLENGTHERROR 0x02C0
  7426. +#define TITAN_GE_MSTATX_TXSYSTEMERROR 0x02D0
  7427. +#define TITAN_GE_MSTATX_TXMACERROR 0x02E0
  7428. +#define TITAN_GE_MSTATX_TXCARRIERSENSEERROR 0x02F0
  7429. +#define TITAN_GE_MSTATX_TXSQETESTERROR 0x0300
  7430. +#define TITAN_GE_MSTATX_TXUNICASTFRAMESOK 0x0310
  7431. +#define TITAN_GE_MSTATX_TXBROADCASTFRAMESOK 0x0320
  7432. +#define TITAN_GE_MSTATX_TXMULTICASTFRAMESOK 0x0330
  7433. +#define TITAN_GE_MSTATX_TXUNICASTFRAMESATTEMPTED 0x0340
  7434. +#define TITAN_GE_MSTATX_TXBROADCASTFRAMESATTEMPTED 0x0350
  7435. +#define TITAN_GE_MSTATX_TXMULTICASTFRAMESATTEMPTED 0x0360
  7436. +#define TITAN_GE_MSTATX_TXFRAMES64OCTETS 0x0370
  7437. +#define TITAN_GE_MSTATX_TXFRAMES65TO127OCTETS 0x0380
  7438. +#define TITAN_GE_MSTATX_TXFRAMES128TO255OCTETS 0x0390
  7439. +#define TITAN_GE_MSTATX_TXFRAMES256TO511OCTETS 0x03A0
  7440. +#define TITAN_GE_MSTATX_TXFRAMES512TO1023OCTETS 0x03B0
  7441. +#define TITAN_GE_MSTATX_TXFRAMES1024TO1518OCTETS 0x03C0
  7442. +#define TITAN_GE_MSTATX_TXFRAMES1519TOMAXSIZE 0x03D0
  7443. +#define TITAN_GE_MSTATX_TXVARIABLE 0x03E0
  7444. +#define TITAN_GE_MSTATX_RXSYSTEMERROR 0x03F0
  7445. +#define TITAN_GE_MSTATX_SINGLECOLLISION 0x0400
  7446. +#define TITAN_GE_MSTATX_MULTIPLECOLLISION 0x0410
  7447. +#define TITAN_GE_MSTATX_DEFERREDXMISSIONS 0x0420
  7448. +#define TITAN_GE_MSTATX_LATECOLLISIONS 0x0430
  7449. +#define TITAN_GE_MSTATX_ABORTEDDUETOXSCOLLS 0x0440
  7450. +
  7451. +/* Interrupt specific defines */
  7452. +#define TITAN_GE_DEVICE_ID 0x0000 /* Device ID */
  7453. +#define TITAN_GE_RESET 0x0004 /* Reset reg */
  7454. +#define TITAN_GE_TSB_CTRL_0 0x000C /* TSB Control reg 0 */
  7455. +#define TITAN_GE_TSB_CTRL_1 0x0010 /* TSB Control reg 1 */
  7456. +#define TITAN_GE_INTR_GRP0_STATUS 0x0040 /* General Interrupt Group 0 Status */
  7457. +#define TITAN_GE_INTR_XDMA_CORE_A 0x0048 /* XDMA Channel Interrupt Status, Core A*/
  7458. +#define TITAN_GE_INTR_XDMA_CORE_B 0x004C /* XDMA Channel Interrupt Status, Core B*/
  7459. +#define TITAN_GE_INTR_XDMA_IE 0x0058 /* XDMA Channel Interrupt Enable */
  7460. +#define TITAN_GE_SDQPF_ECC_INTR 0x480C /* SDQPF ECC Interrupt Status */
  7461. +#define TITAN_GE_SDQPF_RXFIFO_CTL 0x4828 /* SDQPF RxFifo Control and Interrupt Enb*/
  7462. +#define TITAN_GE_SDQPF_RXFIFO_INTR 0x482C /* SDQPF RxFifo Interrupt Status */
  7463. +#define TITAN_GE_SDQPF_TXFIFO_CTL 0x4928 /* SDQPF TxFifo Control and Interrupt Enb*/
  7464. +#define TITAN_GE_SDQPF_TXFIFO_INTR 0x492C /* SDQPF TxFifo Interrupt Status */
  7465. +#define TITAN_GE_SDQPF_RXFIFO_0 0x4840 /* SDQPF RxFIFO Enable */
  7466. +#define TITAN_GE_SDQPF_TXFIFO_0 0x4940 /* SDQPF TxFIFO Enable */
  7467. +#define TITAN_GE_XDMA_CONFIG 0x5000 /* XDMA Global Configuration */
  7468. +#define TITAN_GE_XDMA_INTR_SUMMARY 0x5010 /* XDMA Interrupt Summary */
  7469. +#define TITAN_GE_XDMA_BUFADDRPRE 0x5018 /* XDMA Buffer Address Prefix */
  7470. +#define TITAN_GE_XDMA_DESCADDRPRE 0x501C /* XDMA Descriptor Address Prefix */
  7471. +#define TITAN_GE_XDMA_PORTWEIGHT 0x502C /* XDMA Port Weight Configuration */
  7472. +
  7473. +/* Rx MAC defines */
  7474. +#define TITAN_GE_RMAC_CONFIG_1 0x1200 /* RMAC Configuration 1 */
  7475. +#define TITAN_GE_RMAC_CONFIG_2 0x1204 /* RMAC Configuration 2 */
  7476. +#define TITAN_GE_RMAC_MAX_FRAME_LEN 0x1208 /* RMAC Max Frame Length */
  7477. +#define TITAN_GE_RMAC_STATION_HI 0x120C /* Rx Station Address High */
  7478. +#define TITAN_GE_RMAC_STATION_MID 0x1210 /* Rx Station Address Middle */
  7479. +#define TITAN_GE_RMAC_STATION_LOW 0x1214 /* Rx Station Address Low */
  7480. +#define TITAN_GE_RMAC_LINK_CONFIG 0x1218 /* RMAC Link Configuration */
  7481. +
  7482. +/* Tx MAC defines */
  7483. +#define TITAN_GE_TMAC_CONFIG_1 0x1240 /* TMAC Configuration 1 */
  7484. +#define TITAN_GE_TMAC_CONFIG_2 0x1244 /* TMAC Configuration 2 */
  7485. +#define TITAN_GE_TMAC_IPG 0x1248 /* TMAC Inter-Packet Gap */
  7486. +#define TITAN_GE_TMAC_STATION_HI 0x124C /* Tx Station Address High */
  7487. +#define TITAN_GE_TMAC_STATION_MID 0x1250 /* Tx Station Address Middle */
  7488. +#define TITAN_GE_TMAC_STATION_LOW 0x1254 /* Tx Station Address Low */
  7489. +#define TITAN_GE_TMAC_MAX_FRAME_LEN 0x1258 /* TMAC Max Frame Length */
  7490. +#define TITAN_GE_TMAC_MIN_FRAME_LEN 0x125C /* TMAC Min Frame Length */
  7491. +#define TITAN_GE_TMAC_PAUSE_FRAME_TIME 0x1260 /* TMAC Pause Frame Time */
  7492. +#define TITAN_GE_TMAC_PAUSE_FRAME_INTERVAL 0x1264 /* TMAC Pause Frame Interval */
  7493. +
  7494. +/* GMII register */
  7495. +#define TITAN_GE_GMII_INTERRUPT_STATUS 0x1348 /* GMII Interrupt Status */
  7496. +#define TITAN_GE_GMII_CONFIG_GENERAL 0x134C /* GMII Configuration General */
  7497. +#define TITAN_GE_GMII_CONFIG_MODE 0x1350 /* GMII Configuration Mode */
  7498. +
  7499. +/* Tx and Rx XDMA defines */
  7500. +#define TITAN_GE_INT_COALESCING 0x5030 /* Interrupt Coalescing */
  7501. +#define TITAN_GE_CHANNEL0_CONFIG 0x5040 /* Channel 0 XDMA config */
  7502. +#define TITAN_GE_CHANNEL0_INTERRUPT 0x504c /* Channel 0 Interrupt Status */
  7503. +#define TITAN_GE_GDI_INTERRUPT_ENABLE 0x5050 /* IE for the GDI Errors */
  7504. +#define TITAN_GE_CHANNEL0_PACKET 0x5060 /* Channel 0 Packet count */
  7505. +#define TITAN_GE_CHANNEL0_BYTE 0x5064 /* Channel 0 Byte count */
  7506. +#define TITAN_GE_CHANNEL0_TX_DESC 0x5054 /* Channel 0 Tx first desc */
  7507. +#define TITAN_GE_CHANNEL0_RX_DESC 0x5058 /* Channel 0 Rx first desc */
  7508. +
  7509. +/* AFX (Address Filter Exact) register offsets for Slice 0 */
  7510. +#define TITAN_GE_AFX_EXACT_MATCH_LOW 0x1100 /* AFX Exact Match Address Low*/
  7511. +#define TITAN_GE_AFX_EXACT_MATCH_MID 0x1104 /* AFX Exact Match Address Mid*/
  7512. +#define TITAN_GE_AFX_EXACT_MATCH_HIGH 0x1108 /* AFX Exact Match Address Hi */
  7513. +#define TITAN_GE_AFX_EXACT_MATCH_VID 0x110C /* AFX Exact Match VID */
  7514. +#define TITAN_GE_AFX_MULTICAST_HASH_LOW 0x1110 /* AFX Multicast HASH Low */
  7515. +#define TITAN_GE_AFX_MULTICAST_HASH_MIDLOW 0x1114 /* AFX Multicast HASH MidLow */
  7516. +#define TITAN_GE_AFX_MULTICAST_HASH_MIDHI 0x1118 /* AFX Multicast HASH MidHi */
  7517. +#define TITAN_GE_AFX_MULTICAST_HASH_HI 0x111C /* AFX Multicast HASH Hi */
  7518. +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 0x1120 /* AFX Address Filter Ctrl 0 */
  7519. +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 0x1124 /* AFX Address Filter Ctrl 1 */
  7520. +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 0x1128 /* AFX Address Filter Ctrl 2 */
  7521. +
  7522. +/* Traffic Groomer block */
  7523. +#define TITAN_GE_TRTG_CONFIG 0x1000 /* TRTG Config */
  7524. +
  7525. +#endif /* _TITAN_GE_H_ */
  7526. +
  7527. diff -Nur linux-2.6.34.orig/drivers/net/titan_mdio.c linux-loongson/drivers/net/titan_mdio.c
  7528. --- linux-2.6.34.orig/drivers/net/titan_mdio.c 1970-01-01 01:00:00.000000000 +0100
  7529. +++ linux-loongson/drivers/net/titan_mdio.c 2010-05-27 18:12:39.084716399 +0200
  7530. @@ -0,0 +1,217 @@
  7531. +/*
  7532. + * drivers/net/titan_mdio.c - Driver for Titan ethernet ports
  7533. + *
  7534. + * Copyright (C) 2003 PMC-Sierra Inc.
  7535. + * Author : Manish Lachwani (lachwani@pmc-sierra.com)
  7536. + *
  7537. + * This program is free software; you can redistribute it and/or
  7538. + * modify it under the terms of the GNU General Public License
  7539. + * as published by the Free Software Foundation; either version 2
  7540. + * of the License, or (at your option) any later version.
  7541. + *
  7542. + * This program is distributed in the hope that it will be useful,
  7543. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7544. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  7545. + * GNU General Public License for more details.
  7546. + *
  7547. + * You should have received a copy of the GNU General Public License
  7548. + * along with this program; if not, write to the Free Software
  7549. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  7550. + *
  7551. + * Management Data IO (MDIO) driver for the Titan GMII. Interacts with the Marvel PHY
  7552. + * on the Titan. No support for the TBI as yet.
  7553. + *
  7554. + */
  7555. +
  7556. +#include "titan_mdio.h"
  7557. +
  7558. +#define MDIO_DEBUG
  7559. +
  7560. +/*
  7561. + * Local constants
  7562. + */
  7563. +#define MAX_CLKA 1023
  7564. +#define MAX_PHY_DEV 31
  7565. +#define MAX_PHY_REG 31
  7566. +#define WRITEADDRS_OPCODE 0x0
  7567. +#define READ_OPCODE 0x2
  7568. +#define WRITE_OPCODE 0x1
  7569. +#define MAX_MDIO_POLL 100
  7570. +
  7571. +/*
  7572. + * Titan MDIO and SCMB registers
  7573. + */
  7574. +#define TITAN_GE_SCMB_CONTROL 0x01c0 /* SCMB Control */
  7575. +#define TITAN_GE_SCMB_CLKA 0x01c4 /* SCMB Clock A */
  7576. +#define TITAN_GE_MDIO_COMMAND 0x01d0 /* MDIO Command */
  7577. +#define TITAN_GE_MDIO_DEVICE_PORT_ADDRESS 0x01d4 /* MDIO Device and Port addrs */
  7578. +#define TITAN_GE_MDIO_DATA 0x01d8 /* MDIO Data */
  7579. +#define TITAN_GE_MDIO_INTERRUPTS 0x01dC /* MDIO Interrupts */
  7580. +
  7581. +/*
  7582. + * Function to poll the MDIO
  7583. + */
  7584. +static int titan_ge_mdio_poll(void)
  7585. +{
  7586. + int i, val;
  7587. +
  7588. + for (i = 0; i < MAX_MDIO_POLL; i++) {
  7589. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
  7590. +
  7591. + if (!(val & 0x8000))
  7592. + return TITAN_GE_MDIO_GOOD;
  7593. + }
  7594. +
  7595. + return TITAN_GE_MDIO_ERROR;
  7596. +}
  7597. +
  7598. +
  7599. +/*
  7600. + * Initialize and configure the MDIO
  7601. + */
  7602. +int titan_ge_mdio_setup(titan_ge_mdio_config *titan_mdio)
  7603. +{
  7604. + unsigned long val;
  7605. +
  7606. + /* Reset the SCMB and program into MDIO mode*/
  7607. + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x9000);
  7608. + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x1000);
  7609. +
  7610. + /* CLK A */
  7611. + val = TITAN_GE_MDIO_READ(TITAN_GE_SCMB_CLKA);
  7612. + val = ( (val & ~(0x03ff)) | (titan_mdio->clka & 0x03ff));
  7613. + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CLKA, val);
  7614. +
  7615. + /* Preamble Suppresion */
  7616. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
  7617. + val = ( (val & ~(0x0001)) | (titan_mdio->mdio_spre & 0x0001));
  7618. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
  7619. +
  7620. + /* MDIO mode */
  7621. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
  7622. + val = ( (val & ~(0x4000)) | (titan_mdio->mdio_mode & 0x4000));
  7623. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
  7624. +
  7625. + return TITAN_GE_MDIO_GOOD;
  7626. +}
  7627. +
  7628. +/*
  7629. + * Set the PHY address in indirect mode
  7630. + */
  7631. +int titan_ge_mdio_inaddrs(int dev_addr, int reg_addr)
  7632. +{
  7633. + volatile unsigned long val;
  7634. +
  7635. + /* Setup the PHY device */
  7636. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
  7637. + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
  7638. + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
  7639. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
  7640. +
  7641. + /* Write the new address */
  7642. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
  7643. + val = ( (val & ~(0x0300)) | ( (WRITEADDRS_OPCODE << 8) & 0x0300));
  7644. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
  7645. +
  7646. + return TITAN_GE_MDIO_GOOD;
  7647. +}
  7648. +
  7649. +/*
  7650. + * Read the MDIO register. This is what the individual parametes mean:
  7651. + *
  7652. + * dev_addr : PHY ID
  7653. + * reg_addr : register offset
  7654. + *
  7655. + * See the spec for the Titan MAC. We operate in the Direct Mode.
  7656. + */
  7657. +
  7658. +#define MAX_RETRIES 2
  7659. +
  7660. +int titan_ge_mdio_read(int dev_addr, int reg_addr, unsigned int *pdata)
  7661. +{
  7662. + volatile unsigned long val;
  7663. + int retries = 0;
  7664. +
  7665. + /* Setup the PHY device */
  7666. +
  7667. +again:
  7668. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
  7669. + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
  7670. + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
  7671. + val |= 0x4000;
  7672. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
  7673. +
  7674. + udelay(30);
  7675. +
  7676. + /* Issue the read command */
  7677. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
  7678. + val = ( (val & ~(0x0300)) | ( (READ_OPCODE << 8) & 0x0300));
  7679. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
  7680. +
  7681. + udelay(30);
  7682. +
  7683. + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
  7684. + return TITAN_GE_MDIO_ERROR;
  7685. +
  7686. + *pdata = (unsigned int)TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DATA);
  7687. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
  7688. +
  7689. + udelay(30);
  7690. +
  7691. + if (val & 0x2) {
  7692. + if (retries == MAX_RETRIES)
  7693. + return TITAN_GE_MDIO_ERROR;
  7694. + else {
  7695. + retries++;
  7696. + goto again;
  7697. + }
  7698. + }
  7699. +
  7700. + return TITAN_GE_MDIO_GOOD;
  7701. +}
  7702. +
  7703. +/*
  7704. + * Write to the MDIO register
  7705. + *
  7706. + * dev_addr : PHY ID
  7707. + * reg_addr : register that needs to be written to
  7708. + *
  7709. + */
  7710. +int titan_ge_mdio_write(int dev_addr, int reg_addr, unsigned int data)
  7711. +{
  7712. + volatile unsigned long val;
  7713. +
  7714. + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
  7715. + return TITAN_GE_MDIO_ERROR;
  7716. +
  7717. + /* Setup the PHY device */
  7718. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
  7719. + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
  7720. + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
  7721. + val |= 0x4000;
  7722. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
  7723. +
  7724. + udelay(30);
  7725. +
  7726. + /* Setup the data to write */
  7727. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DATA, data);
  7728. +
  7729. + udelay(30);
  7730. +
  7731. + /* Issue the write command */
  7732. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
  7733. + val = ( (val & ~(0x0300)) | ( (WRITE_OPCODE << 8) & 0x0300));
  7734. + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
  7735. +
  7736. + udelay(30);
  7737. +
  7738. + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
  7739. + return TITAN_GE_MDIO_ERROR;
  7740. +
  7741. + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
  7742. + if (val & 0x2)
  7743. + return TITAN_GE_MDIO_ERROR;
  7744. +
  7745. + return TITAN_GE_MDIO_GOOD;
  7746. +}
  7747. +
  7748. diff -Nur linux-2.6.34.orig/drivers/net/titan_mdio.h linux-loongson/drivers/net/titan_mdio.h
  7749. --- linux-2.6.34.orig/drivers/net/titan_mdio.h 1970-01-01 01:00:00.000000000 +0100
  7750. +++ linux-loongson/drivers/net/titan_mdio.h 2010-05-27 18:12:39.084716399 +0200
  7751. @@ -0,0 +1,56 @@
  7752. +/*
  7753. + * MDIO used to interact with the PHY when using GMII/MII
  7754. + */
  7755. +#ifndef _TITAN_MDIO_H
  7756. +#define _TITAN_MDIO_H
  7757. +
  7758. +#include <linux/netdevice.h>
  7759. +#include <linux/workqueue.h>
  7760. +#include <linux/delay.h>
  7761. +#include "titan_ge.h"
  7762. +
  7763. +
  7764. +#define TITAN_GE_MDIO_ERROR (-9000)
  7765. +#define TITAN_GE_MDIO_GOOD 0
  7766. +
  7767. +#define TITAN_GE_MDIO_BASE titan_ge_base
  7768. +
  7769. +#define TITAN_GE_MDIO_READ(offset) \
  7770. + *(volatile u32 *)(titan_ge_base + (offset))
  7771. +
  7772. +#define TITAN_GE_MDIO_WRITE(offset, data) \
  7773. + *(volatile u32 *)(titan_ge_base + (offset)) = (data)
  7774. +
  7775. +
  7776. +/* GMII specific registers */
  7777. +#define TITAN_GE_MARVEL_PHY_ID 0x00
  7778. +#define TITAN_PHY_AUTONEG_ADV 0x04
  7779. +#define TITAN_PHY_LP_ABILITY 0x05
  7780. +#define TITAN_GE_MDIO_MII_CTRL 0x09
  7781. +#define TITAN_GE_MDIO_MII_EXTENDED 0x0f
  7782. +#define TITAN_GE_MDIO_PHY_CTRL 0x10
  7783. +#define TITAN_GE_MDIO_PHY_STATUS 0x11
  7784. +#define TITAN_GE_MDIO_PHY_IE 0x12
  7785. +#define TITAN_GE_MDIO_PHY_IS 0x13
  7786. +#define TITAN_GE_MDIO_PHY_LED 0x18
  7787. +#define TITAN_GE_MDIO_PHY_LED_OVER 0x19
  7788. +#define PHY_ANEG_TIME_WAIT 45 /* 45 seconds wait time */
  7789. +
  7790. +/*
  7791. + * MDIO Config Structure
  7792. + */
  7793. +typedef struct {
  7794. + unsigned int clka;
  7795. + int mdio_spre;
  7796. + int mdio_mode;
  7797. +} titan_ge_mdio_config;
  7798. +
  7799. +/*
  7800. + * Function Prototypes
  7801. + */
  7802. +int titan_ge_mdio_setup(titan_ge_mdio_config *);
  7803. +int titan_ge_mdio_inaddrs(int, int);
  7804. +int titan_ge_mdio_read(int, int, unsigned int *);
  7805. +int titan_ge_mdio_write(int, int, unsigned int);
  7806. +
  7807. +#endif /* _TITAN_MDIO_H */
  7808. diff -Nur linux-2.6.34.orig/drivers/net/wireless/Kconfig linux-loongson/drivers/net/wireless/Kconfig
  7809. --- linux-2.6.34.orig/drivers/net/wireless/Kconfig 2010-05-16 23:17:36.000000000 +0200
  7810. +++ linux-loongson/drivers/net/wireless/Kconfig 2010-05-27 18:15:37.400979385 +0200
  7811. @@ -268,7 +268,7 @@
  7812. config RTL8187
  7813. tristate "Realtek 8187 and 8187B USB support"
  7814. - depends on MAC80211 && USB
  7815. + depends on MAC80211 && USB && !LEMOTE_MACH2F
  7816. select EEPROM_93CX6
  7817. ---help---
  7818. This is a driver for RTL8187 and RTL8187B based cards.
  7819. @@ -295,6 +295,19 @@
  7820. depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
  7821. default y
  7822. +config RTL8187B
  7823. + tristate "Realtek 8187B wifi support for yeeloong2f laptop"
  7824. + depends on MAC80211 && USB && LEMOTE_MACH2F
  7825. + depends on RFKILL || !RFKILL
  7826. + select CRYPTO
  7827. + select WIRELESS_EXT
  7828. + select WEXT_PRIV
  7829. + ---help---
  7830. + This is a driver for RTL8187B based cards, this driver is especially
  7831. + for yeeloon2f laptop.
  7832. +
  7833. + Thanks to Realtek for their support!
  7834. +
  7835. config ADM8211
  7836. tristate "ADMtek ADM8211 support"
  7837. depends on MAC80211 && PCI && EXPERIMENTAL
  7838. diff -Nur linux-2.6.34.orig/drivers/net/wireless/Makefile linux-loongson/drivers/net/wireless/Makefile
  7839. --- linux-2.6.34.orig/drivers/net/wireless/Makefile 2010-05-16 23:17:36.000000000 +0200
  7840. +++ linux-loongson/drivers/net/wireless/Makefile 2010-05-27 18:12:39.124712905 +0200
  7841. @@ -24,6 +24,7 @@
  7842. obj-$(CONFIG_ZD1211RW) += zd1211rw/
  7843. obj-$(CONFIG_RTL8180) += rtl818x/
  7844. obj-$(CONFIG_RTL8187) += rtl818x/
  7845. +obj-$(CONFIG_RTL8187B) += rtl8187b/
  7846. # 16-bit wireless PCMCIA client drivers
  7847. obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
  7848. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/dot11d.h linux-loongson/drivers/net/wireless/rtl8187b/dot11d.h
  7849. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/dot11d.h 1970-01-01 01:00:00.000000000 +0100
  7850. +++ linux-loongson/drivers/net/wireless/rtl8187b/dot11d.h 2010-05-27 18:12:39.532222207 +0200
  7851. @@ -0,0 +1,102 @@
  7852. +#ifndef __INC_DOT11D_H
  7853. +#define __INC_DOT11D_H
  7854. +
  7855. +#include "ieee80211/ieee80211.h"
  7856. +
  7857. +//#define ENABLE_DOT11D
  7858. +
  7859. +//#define DOT11D_MAX_CHNL_NUM 83
  7860. +
  7861. +typedef struct _CHNL_TXPOWER_TRIPLE {
  7862. + u8 FirstChnl;
  7863. + u8 NumChnls;
  7864. + u8 MaxTxPowerInDbm;
  7865. +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
  7866. +
  7867. +typedef enum _DOT11D_STATE {
  7868. + DOT11D_STATE_NONE = 0,
  7869. + DOT11D_STATE_LEARNED,
  7870. + DOT11D_STATE_DONE,
  7871. +}DOT11D_STATE;
  7872. +
  7873. +typedef struct _RT_DOT11D_INFO {
  7874. + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
  7875. +
  7876. + bool bEnabled; // dot11MultiDomainCapabilityEnabled
  7877. +
  7878. + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
  7879. + u8 CountryIeBuf[MAX_IE_LEN];
  7880. + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
  7881. + u8 CountryIeWatchdog;
  7882. +
  7883. + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
  7884. + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
  7885. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
  7886. + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
  7887. +
  7888. + DOT11D_STATE State;
  7889. +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
  7890. +#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 )
  7891. +#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])
  7892. +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
  7893. +
  7894. +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
  7895. +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
  7896. +
  7897. +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  7898. +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  7899. +
  7900. +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
  7901. + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
  7902. + FALSE : \
  7903. + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
  7904. +
  7905. +#define CIE_WATCHDOG_TH 1
  7906. +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
  7907. +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
  7908. +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
  7909. +
  7910. +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
  7911. +
  7912. +
  7913. +void
  7914. +Dot11d_Init(
  7915. + struct ieee80211_device *dev
  7916. + );
  7917. +
  7918. +void
  7919. +Dot11d_Reset(
  7920. + struct ieee80211_device *dev
  7921. + );
  7922. +
  7923. +void
  7924. +Dot11d_UpdateCountryIe(
  7925. + struct ieee80211_device *dev,
  7926. + u8 * pTaddr,
  7927. + u16 CoutryIeLen,
  7928. + u8 * pCoutryIe
  7929. + );
  7930. +
  7931. +u8
  7932. +DOT11D_GetMaxTxPwrInDbm(
  7933. + struct ieee80211_device *dev,
  7934. + u8 Channel
  7935. + );
  7936. +
  7937. +void
  7938. +DOT11D_ScanComplete(
  7939. + struct ieee80211_device * dev
  7940. + );
  7941. +
  7942. +int IsLegalChannel(
  7943. + struct ieee80211_device * dev,
  7944. + u8 channel
  7945. +);
  7946. +
  7947. +int ToLegalChannel(
  7948. + struct ieee80211_device * dev,
  7949. + u8 channel
  7950. +);
  7951. +
  7952. +void dump_chnl_map(u8 * channel_map);
  7953. +#endif // #ifndef __INC_DOT11D_H
  7954. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/arc4.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/arc4.c
  7955. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 1970-01-01 01:00:00.000000000 +0100
  7956. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/arc4.c 2010-05-27 18:12:39.532222207 +0200
  7957. @@ -0,0 +1,103 @@
  7958. +/*
  7959. + * Cryptographic API
  7960. + *
  7961. + * ARC4 Cipher Algorithm
  7962. + *
  7963. + * Jon Oberheide <jon@oberheide.org>
  7964. + *
  7965. + * This program is free software; you can redistribute it and/or modify
  7966. + * it under the terms of the GNU General Public License as published by
  7967. + * the Free Software Foundation; either version 2 of the License, or
  7968. + * (at your option) any later version.
  7969. + *
  7970. + */
  7971. +#include <linux/module.h>
  7972. +#include <linux/init.h>
  7973. +#include "rtl_crypto.h"
  7974. +
  7975. +#define ARC4_MIN_KEY_SIZE 1
  7976. +#define ARC4_MAX_KEY_SIZE 256
  7977. +#define ARC4_BLOCK_SIZE 1
  7978. +
  7979. +struct arc4_ctx {
  7980. + u8 S[256];
  7981. + u8 x, y;
  7982. +};
  7983. +
  7984. +static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
  7985. +{
  7986. + struct arc4_ctx *ctx = ctx_arg;
  7987. + int i, j = 0, k = 0;
  7988. +
  7989. + ctx->x = 1;
  7990. + ctx->y = 0;
  7991. +
  7992. + for(i = 0; i < 256; i++)
  7993. + ctx->S[i] = i;
  7994. +
  7995. + for(i = 0; i < 256; i++)
  7996. + {
  7997. + u8 a = ctx->S[i];
  7998. + j = (j + in_key[k] + a) & 0xff;
  7999. + ctx->S[i] = ctx->S[j];
  8000. + ctx->S[j] = a;
  8001. + if(++k >= key_len)
  8002. + k = 0;
  8003. + }
  8004. +
  8005. + return 0;
  8006. +}
  8007. +
  8008. +static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
  8009. +{
  8010. + struct arc4_ctx *ctx = ctx_arg;
  8011. +
  8012. + u8 *const S = ctx->S;
  8013. + u8 x = ctx->x;
  8014. + u8 y = ctx->y;
  8015. + u8 a, b;
  8016. +
  8017. + a = S[x];
  8018. + y = (y + a) & 0xff;
  8019. + b = S[y];
  8020. + S[x] = b;
  8021. + S[y] = a;
  8022. + x = (x + 1) & 0xff;
  8023. + *out++ = *in ^ S[(a + b) & 0xff];
  8024. +
  8025. + ctx->x = x;
  8026. + ctx->y = y;
  8027. +}
  8028. +
  8029. +static struct crypto_alg arc4_alg = {
  8030. + .cra_name = "arc4",
  8031. + .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  8032. + .cra_blocksize = ARC4_BLOCK_SIZE,
  8033. + .cra_ctxsize = sizeof(struct arc4_ctx),
  8034. + .cra_module = THIS_MODULE,
  8035. + .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list),
  8036. + .cra_u = { .cipher = {
  8037. + .cia_min_keysize = ARC4_MIN_KEY_SIZE,
  8038. + .cia_max_keysize = ARC4_MAX_KEY_SIZE,
  8039. + .cia_setkey = arc4_set_key,
  8040. + .cia_encrypt = arc4_crypt,
  8041. + .cia_decrypt = arc4_crypt } }
  8042. +};
  8043. +
  8044. +static int __init arc4_init(void)
  8045. +{
  8046. + return crypto_register_alg(&arc4_alg);
  8047. +}
  8048. +
  8049. +
  8050. +static void __exit arc4_exit(void)
  8051. +{
  8052. + crypto_unregister_alg(&arc4_alg);
  8053. +}
  8054. +
  8055. +module_init(arc4_init);
  8056. +module_exit(arc4_exit);
  8057. +
  8058. +MODULE_LICENSE("GPL");
  8059. +MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
  8060. +MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
  8061. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c
  8062. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 1970-01-01 01:00:00.000000000 +0100
  8063. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.c 2010-05-27 18:12:39.532222207 +0200
  8064. @@ -0,0 +1,244 @@
  8065. +#ifdef ENABLE_DOT11D
  8066. +//-----------------------------------------------------------------------------
  8067. +// File:
  8068. +// Dot11d.c
  8069. +//
  8070. +// Description:
  8071. +// Implement 802.11d.
  8072. +//
  8073. +//-----------------------------------------------------------------------------
  8074. +
  8075. +#include "dot11d.h"
  8076. +
  8077. +void
  8078. +Dot11d_Init(struct ieee80211_device *ieee)
  8079. +{
  8080. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
  8081. +
  8082. + pDot11dInfo->bEnabled = 0;
  8083. +
  8084. + pDot11dInfo->State = DOT11D_STATE_NONE;
  8085. + pDot11dInfo->CountryIeLen = 0;
  8086. + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
  8087. + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
  8088. + RESET_CIE_WATCHDOG(ieee);
  8089. +
  8090. + //printk("Dot11d_Init()\n");
  8091. +}
  8092. +
  8093. +//
  8094. +// Description:
  8095. +// Reset to the state as we are just entering a regulatory domain.
  8096. +//
  8097. +void
  8098. +Dot11d_Reset(struct ieee80211_device *ieee)
  8099. +{
  8100. + u32 i;
  8101. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
  8102. +
  8103. + // Clear old channel map
  8104. + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
  8105. + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
  8106. + // Set new channel map
  8107. + for (i=1; i<=11; i++) {
  8108. + (pDot11dInfo->channel_map)[i] = 1;
  8109. + }
  8110. + for (i=12; i<=14; i++) {
  8111. + (pDot11dInfo->channel_map)[i] = 2;
  8112. + }
  8113. +
  8114. + pDot11dInfo->State = DOT11D_STATE_NONE;
  8115. + pDot11dInfo->CountryIeLen = 0;
  8116. + RESET_CIE_WATCHDOG(ieee);
  8117. +
  8118. + //printk("Dot11d_Reset()\n");
  8119. +}
  8120. +
  8121. +//
  8122. +// Description:
  8123. +// Update country IE from Beacon or Probe Resopnse
  8124. +// and configure PHY for operation in the regulatory domain.
  8125. +//
  8126. +// TODO:
  8127. +// Configure Tx power.
  8128. +//
  8129. +// Assumption:
  8130. +// 1. IS_DOT11D_ENABLE() is TRUE.
  8131. +// 2. Input IE is an valid one.
  8132. +//
  8133. +void
  8134. +Dot11d_UpdateCountryIe(
  8135. + struct ieee80211_device *dev,
  8136. + u8 * pTaddr,
  8137. + u16 CoutryIeLen,
  8138. + u8 * pCoutryIe
  8139. + )
  8140. +{
  8141. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  8142. + u8 i, j, NumTriples, MaxChnlNum;
  8143. + PCHNL_TXPOWER_TRIPLE pTriple;
  8144. +
  8145. + if((CoutryIeLen - 3)%3 != 0)
  8146. + {
  8147. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
  8148. + Dot11d_Reset(dev);
  8149. + return;
  8150. + }
  8151. +
  8152. + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
  8153. + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
  8154. + MaxChnlNum = 0;
  8155. + NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
  8156. + pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
  8157. + for(i = 0; i < NumTriples; i++)
  8158. + {
  8159. + if(MaxChnlNum >= pTriple->FirstChnl)
  8160. + { // It is not in a monotonically increasing order, so stop processing.
  8161. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
  8162. + Dot11d_Reset(dev);
  8163. + return;
  8164. + }
  8165. + if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
  8166. + { // It is not a valid set of channel id, so stop processing.
  8167. + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
  8168. + Dot11d_Reset(dev);
  8169. + return;
  8170. + }
  8171. +
  8172. + for(j = 0 ; j < pTriple->NumChnls; j++)
  8173. + {
  8174. + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
  8175. + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
  8176. + MaxChnlNum = pTriple->FirstChnl + j;
  8177. + }
  8178. +
  8179. + pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
  8180. + }
  8181. +#if 1
  8182. + //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
  8183. + printk("Channel List:");
  8184. + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
  8185. + if(pDot11dInfo->channel_map[i] > 0)
  8186. + printk(" %d", i);
  8187. + printk("\n");
  8188. +#endif
  8189. +
  8190. + UPDATE_CIE_SRC(dev, pTaddr);
  8191. +
  8192. + pDot11dInfo->CountryIeLen = CoutryIeLen;
  8193. + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
  8194. + pDot11dInfo->State = DOT11D_STATE_LEARNED;
  8195. +}
  8196. +
  8197. +void dump_chnl_map(u8 * channel_map)
  8198. +{
  8199. + int i;
  8200. + printk("Channel List:");
  8201. + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
  8202. + if(channel_map[i] > 0)
  8203. + printk(" %d(%d)", i, channel_map[i]);
  8204. + printk("\n");
  8205. +}
  8206. +
  8207. +u8
  8208. +DOT11D_GetMaxTxPwrInDbm(
  8209. + struct ieee80211_device *dev,
  8210. + u8 Channel
  8211. + )
  8212. +{
  8213. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  8214. + u8 MaxTxPwrInDbm = 255;
  8215. +
  8216. + if(MAX_CHANNEL_NUMBER < Channel)
  8217. + {
  8218. + printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
  8219. + return MaxTxPwrInDbm;
  8220. + }
  8221. + if(pDot11dInfo->channel_map[Channel])
  8222. + {
  8223. + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
  8224. + }
  8225. +
  8226. + return MaxTxPwrInDbm;
  8227. +}
  8228. +
  8229. +
  8230. +void
  8231. +DOT11D_ScanComplete(
  8232. + struct ieee80211_device * dev
  8233. + )
  8234. +{
  8235. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  8236. +
  8237. + switch(pDot11dInfo->State)
  8238. + {
  8239. + case DOT11D_STATE_LEARNED:
  8240. + pDot11dInfo->State = DOT11D_STATE_DONE;
  8241. + break;
  8242. +
  8243. + case DOT11D_STATE_DONE:
  8244. + if( GET_CIE_WATCHDOG(dev) == 0 )
  8245. + { // Reset country IE if previous one is gone.
  8246. + Dot11d_Reset(dev);
  8247. + }
  8248. + break;
  8249. + case DOT11D_STATE_NONE:
  8250. + break;
  8251. + }
  8252. +}
  8253. +
  8254. +int IsLegalChannel(
  8255. + struct ieee80211_device * dev,
  8256. + u8 channel
  8257. +)
  8258. +{
  8259. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  8260. +
  8261. + if(MAX_CHANNEL_NUMBER < channel)
  8262. + {
  8263. + printk("IsLegalChannel(): Invalid Channel\n");
  8264. + return 0;
  8265. + }
  8266. + if(pDot11dInfo->channel_map[channel] > 0)
  8267. + return 1;
  8268. + return 0;
  8269. +}
  8270. +
  8271. +int ToLegalChannel(
  8272. + struct ieee80211_device * dev,
  8273. + u8 channel
  8274. +)
  8275. +{
  8276. + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
  8277. + u8 default_chn = 0;
  8278. + u32 i = 0;
  8279. +
  8280. + for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
  8281. + {
  8282. + if(pDot11dInfo->channel_map[i] > 0)
  8283. + {
  8284. + default_chn = i;
  8285. + break;
  8286. + }
  8287. + }
  8288. +
  8289. + if(MAX_CHANNEL_NUMBER < channel)
  8290. + {
  8291. + printk("IsLegalChannel(): Invalid Channel\n");
  8292. + return default_chn;
  8293. + }
  8294. +
  8295. + if(pDot11dInfo->channel_map[channel] > 0)
  8296. + return channel;
  8297. +
  8298. + return default_chn;
  8299. +}
  8300. +
  8301. +EXPORT_SYMBOL(Dot11d_Init);
  8302. +EXPORT_SYMBOL(Dot11d_Reset);
  8303. +EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
  8304. +EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
  8305. +EXPORT_SYMBOL(DOT11D_ScanComplete);
  8306. +EXPORT_SYMBOL(IsLegalChannel);
  8307. +EXPORT_SYMBOL(ToLegalChannel);
  8308. +#endif
  8309. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h
  8310. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 1970-01-01 01:00:00.000000000 +0100
  8311. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/dot11d.h 2010-05-27 18:12:39.532222207 +0200
  8312. @@ -0,0 +1,102 @@
  8313. +#ifndef __INC_DOT11D_H
  8314. +#define __INC_DOT11D_H
  8315. +
  8316. +#include "ieee80211.h"
  8317. +
  8318. +//#define ENABLE_DOT11D
  8319. +
  8320. +//#define DOT11D_MAX_CHNL_NUM 83
  8321. +
  8322. +typedef struct _CHNL_TXPOWER_TRIPLE {
  8323. + u8 FirstChnl;
  8324. + u8 NumChnls;
  8325. + u8 MaxTxPowerInDbm;
  8326. +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
  8327. +
  8328. +typedef enum _DOT11D_STATE {
  8329. + DOT11D_STATE_NONE = 0,
  8330. + DOT11D_STATE_LEARNED,
  8331. + DOT11D_STATE_DONE,
  8332. +}DOT11D_STATE;
  8333. +
  8334. +typedef struct _RT_DOT11D_INFO {
  8335. + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
  8336. +
  8337. + bool bEnabled; // dot11MultiDomainCapabilityEnabled
  8338. +
  8339. + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
  8340. + u8 CountryIeBuf[MAX_IE_LEN];
  8341. + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
  8342. + u8 CountryIeWatchdog;
  8343. +
  8344. + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
  8345. + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
  8346. + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
  8347. + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
  8348. +
  8349. + DOT11D_STATE State;
  8350. +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
  8351. +#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 )
  8352. +#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])
  8353. +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
  8354. +
  8355. +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
  8356. +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
  8357. +
  8358. +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  8359. +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
  8360. +
  8361. +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
  8362. + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
  8363. + FALSE : \
  8364. + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
  8365. +
  8366. +#define CIE_WATCHDOG_TH 1
  8367. +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
  8368. +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
  8369. +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
  8370. +
  8371. +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
  8372. +
  8373. +
  8374. +void
  8375. +Dot11d_Init(
  8376. + struct ieee80211_device *dev
  8377. + );
  8378. +
  8379. +void
  8380. +Dot11d_Reset(
  8381. + struct ieee80211_device *dev
  8382. + );
  8383. +
  8384. +void
  8385. +Dot11d_UpdateCountryIe(
  8386. + struct ieee80211_device *dev,
  8387. + u8 * pTaddr,
  8388. + u16 CoutryIeLen,
  8389. + u8 * pCoutryIe
  8390. + );
  8391. +
  8392. +u8
  8393. +DOT11D_GetMaxTxPwrInDbm(
  8394. + struct ieee80211_device *dev,
  8395. + u8 Channel
  8396. + );
  8397. +
  8398. +void
  8399. +DOT11D_ScanComplete(
  8400. + struct ieee80211_device * dev
  8401. + );
  8402. +
  8403. +int IsLegalChannel(
  8404. + struct ieee80211_device * dev,
  8405. + u8 channel
  8406. +);
  8407. +
  8408. +int ToLegalChannel(
  8409. + struct ieee80211_device * dev,
  8410. + u8 channel
  8411. +);
  8412. +
  8413. +void dump_chnl_map(u8 * channel_map);
  8414. +#endif // #ifndef __INC_DOT11D_H
  8415. 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
  8416. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 1970-01-01 01:00:00.000000000 +0100
  8417. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.c 2010-05-27 18:12:39.532222207 +0200
  8418. @@ -0,0 +1,275 @@
  8419. +/*
  8420. + * Host AP crypto routines
  8421. + *
  8422. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  8423. + * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
  8424. + *
  8425. + * This program is free software; you can redistribute it and/or modify
  8426. + * it under the terms of the GNU General Public License version 2 as
  8427. + * published by the Free Software Foundation. See README and COPYING for
  8428. + * more details.
  8429. + *
  8430. + */
  8431. +
  8432. +//#include <linux/config.h>
  8433. +#include <linux/version.h>
  8434. +#include <linux/module.h>
  8435. +#include <linux/init.h>
  8436. +#include <linux/slab.h>
  8437. +#include <asm/string.h>
  8438. +#include <asm/errno.h>
  8439. +
  8440. +#include "ieee80211.h"
  8441. +
  8442. +MODULE_AUTHOR("Jouni Malinen");
  8443. +MODULE_DESCRIPTION("HostAP crypto");
  8444. +MODULE_LICENSE("GPL");
  8445. +
  8446. +struct ieee80211_crypto_alg {
  8447. + struct list_head list;
  8448. + struct ieee80211_crypto_ops *ops;
  8449. +};
  8450. +
  8451. +
  8452. +struct ieee80211_crypto {
  8453. + struct list_head algs;
  8454. + spinlock_t lock;
  8455. +};
  8456. +
  8457. +static struct ieee80211_crypto *hcrypt;
  8458. +
  8459. +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
  8460. + int force)
  8461. +{
  8462. + struct list_head *ptr, *n;
  8463. + struct ieee80211_crypt_data *entry;
  8464. +
  8465. + for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
  8466. + ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
  8467. + entry = list_entry(ptr, struct ieee80211_crypt_data, list);
  8468. +
  8469. + if (atomic_read(&entry->refcnt) != 0 && !force)
  8470. + continue;
  8471. +
  8472. + list_del(ptr);
  8473. +
  8474. + if (entry->ops) {
  8475. + entry->ops->deinit(entry->priv);
  8476. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  8477. + module_put(entry->ops->owner);
  8478. +#else
  8479. + __MOD_DEC_USE_COUNT(entry->ops->owner);
  8480. +#endif
  8481. + }
  8482. + kfree(entry);
  8483. + }
  8484. +}
  8485. +
  8486. +void ieee80211_crypt_deinit_handler(unsigned long data)
  8487. +{
  8488. + struct ieee80211_device *ieee = (struct ieee80211_device *)data;
  8489. + unsigned long flags;
  8490. +
  8491. + spin_lock_irqsave(&ieee->lock, flags);
  8492. + ieee80211_crypt_deinit_entries(ieee, 0);
  8493. + if (!list_empty(&ieee->crypt_deinit_list)) {
  8494. + printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
  8495. + "deletion list\n", ieee->dev->name);
  8496. + ieee->crypt_deinit_timer.expires = jiffies + HZ;
  8497. + add_timer(&ieee->crypt_deinit_timer);
  8498. + }
  8499. + spin_unlock_irqrestore(&ieee->lock, flags);
  8500. +
  8501. +}
  8502. +
  8503. +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
  8504. + struct ieee80211_crypt_data **crypt)
  8505. +{
  8506. + struct ieee80211_crypt_data *tmp;
  8507. + unsigned long flags;
  8508. +
  8509. + if (*crypt == NULL)
  8510. + return;
  8511. +
  8512. + tmp = *crypt;
  8513. + *crypt = NULL;
  8514. +
  8515. + /* must not run ops->deinit() while there may be pending encrypt or
  8516. + * decrypt operations. Use a list of delayed deinits to avoid needing
  8517. + * locking. */
  8518. +
  8519. + spin_lock_irqsave(&ieee->lock, flags);
  8520. + list_add(&tmp->list, &ieee->crypt_deinit_list);
  8521. + if (!timer_pending(&ieee->crypt_deinit_timer)) {
  8522. + ieee->crypt_deinit_timer.expires = jiffies + HZ;
  8523. + add_timer(&ieee->crypt_deinit_timer);
  8524. + }
  8525. + spin_unlock_irqrestore(&ieee->lock, flags);
  8526. +}
  8527. +
  8528. +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
  8529. +{
  8530. + unsigned long flags;
  8531. + struct ieee80211_crypto_alg *alg;
  8532. +
  8533. + if (hcrypt == NULL)
  8534. + return -1;
  8535. +
  8536. + alg = kmalloc(sizeof(*alg), GFP_KERNEL);
  8537. + if (alg == NULL)
  8538. + return -ENOMEM;
  8539. +
  8540. + memset(alg, 0, sizeof(*alg));
  8541. + alg->ops = ops;
  8542. +
  8543. + spin_lock_irqsave(&hcrypt->lock, flags);
  8544. + list_add(&alg->list, &hcrypt->algs);
  8545. + spin_unlock_irqrestore(&hcrypt->lock, flags);
  8546. +
  8547. + printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
  8548. + ops->name);
  8549. +
  8550. + return 0;
  8551. +}
  8552. +
  8553. +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
  8554. +{
  8555. + unsigned long flags;
  8556. + struct list_head *ptr;
  8557. + struct ieee80211_crypto_alg *del_alg = NULL;
  8558. +
  8559. + if (hcrypt == NULL)
  8560. + return -1;
  8561. +
  8562. + spin_lock_irqsave(&hcrypt->lock, flags);
  8563. + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
  8564. + struct ieee80211_crypto_alg *alg =
  8565. + (struct ieee80211_crypto_alg *) ptr;
  8566. + if (alg->ops == ops) {
  8567. + list_del(&alg->list);
  8568. + del_alg = alg;
  8569. + break;
  8570. + }
  8571. + }
  8572. + spin_unlock_irqrestore(&hcrypt->lock, flags);
  8573. +
  8574. + if (del_alg) {
  8575. + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
  8576. + "'%s'\n", ops->name);
  8577. + kfree(del_alg);
  8578. + }
  8579. +
  8580. + return del_alg ? 0 : -1;
  8581. +}
  8582. +
  8583. +
  8584. +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
  8585. +{
  8586. + unsigned long flags;
  8587. + struct list_head *ptr;
  8588. + struct ieee80211_crypto_alg *found_alg = NULL;
  8589. +
  8590. + if (hcrypt == NULL)
  8591. + return NULL;
  8592. +
  8593. + spin_lock_irqsave(&hcrypt->lock, flags);
  8594. + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
  8595. + struct ieee80211_crypto_alg *alg =
  8596. + (struct ieee80211_crypto_alg *) ptr;
  8597. + if (strcmp(alg->ops->name, name) == 0) {
  8598. + found_alg = alg;
  8599. + break;
  8600. + }
  8601. + }
  8602. + spin_unlock_irqrestore(&hcrypt->lock, flags);
  8603. +
  8604. + if (found_alg)
  8605. + return found_alg->ops;
  8606. + else
  8607. + return NULL;
  8608. +}
  8609. +
  8610. +
  8611. +static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
  8612. +static void ieee80211_crypt_null_deinit(void *priv) {}
  8613. +
  8614. +static struct ieee80211_crypto_ops ieee80211_crypt_null = {
  8615. + .name = "NULL",
  8616. + .init = ieee80211_crypt_null_init,
  8617. + .deinit = ieee80211_crypt_null_deinit,
  8618. + .encrypt_mpdu = NULL,
  8619. + .decrypt_mpdu = NULL,
  8620. + .encrypt_msdu = NULL,
  8621. + .decrypt_msdu = NULL,
  8622. + .set_key = NULL,
  8623. + .get_key = NULL,
  8624. + .extra_prefix_len = 0,
  8625. + .extra_postfix_len = 0,
  8626. + .owner = THIS_MODULE,
  8627. +};
  8628. +
  8629. +
  8630. +int __init ieee80211_crypto_init(void)
  8631. +{
  8632. + int ret = -ENOMEM;
  8633. +
  8634. + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
  8635. + if (!hcrypt)
  8636. + goto out;
  8637. +
  8638. + memset(hcrypt, 0, sizeof(*hcrypt));
  8639. + INIT_LIST_HEAD(&hcrypt->algs);
  8640. + spin_lock_init(&hcrypt->lock);
  8641. +
  8642. + ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
  8643. + if (ret < 0) {
  8644. + kfree(hcrypt);
  8645. + hcrypt = NULL;
  8646. + }
  8647. +out:
  8648. + return ret;
  8649. +}
  8650. +
  8651. +
  8652. +void __exit ieee80211_crypto_deinit(void)
  8653. +{
  8654. + struct list_head *ptr, *n;
  8655. +
  8656. + if (hcrypt == NULL)
  8657. + return;
  8658. +
  8659. + for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
  8660. + ptr = n, n = ptr->next) {
  8661. + struct ieee80211_crypto_alg *alg =
  8662. + (struct ieee80211_crypto_alg *) ptr;
  8663. + list_del(ptr);
  8664. + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
  8665. + "'%s' (deinit)\n", alg->ops->name);
  8666. + kfree(alg);
  8667. + }
  8668. +
  8669. + kfree(hcrypt);
  8670. +}
  8671. +
  8672. +#if 0
  8673. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  8674. +EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
  8675. +EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
  8676. +EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
  8677. +
  8678. +EXPORT_SYMBOL(ieee80211_register_crypto_ops);
  8679. +EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
  8680. +EXPORT_SYMBOL(ieee80211_get_crypto_ops);
  8681. +#else
  8682. +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries);
  8683. +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler);
  8684. +EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit);
  8685. +
  8686. +EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops);
  8687. +EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops);
  8688. +EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops);
  8689. +#endif
  8690. +
  8691. +module_init(ieee80211_crypto_init);
  8692. +module_exit(ieee80211_crypto_deinit);
  8693. +#endif
  8694. 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
  8695. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 1970-01-01 01:00:00.000000000 +0100
  8696. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_ccmp.c 2010-05-27 18:12:39.532222207 +0200
  8697. @@ -0,0 +1,524 @@
  8698. +/*
  8699. + * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
  8700. + *
  8701. + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
  8702. + *
  8703. + * This program is free software; you can redistribute it and/or modify
  8704. + * it under the terms of the GNU General Public License version 2 as
  8705. + * published by the Free Software Foundation. See README and COPYING for
  8706. + * more details.
  8707. + */
  8708. +
  8709. +//#include <linux/config.h>
  8710. +#include <linux/version.h>
  8711. +#include <linux/module.h>
  8712. +#include <linux/init.h>
  8713. +#include <linux/slab.h>
  8714. +#include <linux/random.h>
  8715. +#include <linux/skbuff.h>
  8716. +#include <linux/netdevice.h>
  8717. +#include <linux/if_ether.h>
  8718. +#include <linux/if_arp.h>
  8719. +#include <asm/string.h>
  8720. +#include <linux/wireless.h>
  8721. +
  8722. +#include "ieee80211.h"
  8723. +
  8724. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  8725. +#include "rtl_crypto.h"
  8726. +#else
  8727. +#include <linux/crypto.h>
  8728. +#endif
  8729. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  8730. + #include <asm/scatterlist.h>
  8731. +#else
  8732. + #include <linux/scatterlist.h>
  8733. +#endif
  8734. +
  8735. +//#include <asm/scatterlist.h>
  8736. +
  8737. +MODULE_AUTHOR("Jouni Malinen");
  8738. +MODULE_DESCRIPTION("Host AP crypt: CCMP");
  8739. +MODULE_LICENSE("GPL");
  8740. +
  8741. +#define AES_BLOCK_LEN 16
  8742. +#define CCMP_HDR_LEN 8
  8743. +#define CCMP_MIC_LEN 8
  8744. +#define CCMP_TK_LEN 16
  8745. +#define CCMP_PN_LEN 6
  8746. +
  8747. +struct ieee80211_ccmp_data {
  8748. + u8 key[CCMP_TK_LEN];
  8749. + int key_set;
  8750. +
  8751. + u8 tx_pn[CCMP_PN_LEN];
  8752. + u8 rx_pn[CCMP_PN_LEN];
  8753. +
  8754. + u32 dot11RSNAStatsCCMPFormatErrors;
  8755. + u32 dot11RSNAStatsCCMPReplays;
  8756. + u32 dot11RSNAStatsCCMPDecryptErrors;
  8757. +
  8758. + int key_idx;
  8759. +
  8760. + struct crypto_tfm *tfm;
  8761. +
  8762. + /* scratch buffers for virt_to_page() (crypto API) */
  8763. + u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
  8764. + tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
  8765. + u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
  8766. +};
  8767. +
  8768. +void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
  8769. + const u8 pt[16], u8 ct[16])
  8770. +{
  8771. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  8772. + struct scatterlist src, dst;
  8773. +
  8774. + src.page = virt_to_page(pt);
  8775. + src.offset = offset_in_page(pt);
  8776. + src.length = AES_BLOCK_LEN;
  8777. +
  8778. + dst.page = virt_to_page(ct);
  8779. + dst.offset = offset_in_page(ct);
  8780. + dst.length = AES_BLOCK_LEN;
  8781. +
  8782. + crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
  8783. + #else
  8784. + crypto_cipher_encrypt_one((void*)tfm, ct, pt);
  8785. + #endif
  8786. +}
  8787. +
  8788. +static void * ieee80211_ccmp_init(int key_idx)
  8789. +{
  8790. + struct ieee80211_ccmp_data *priv;
  8791. +
  8792. + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
  8793. + if (priv == NULL)
  8794. + goto fail;
  8795. + memset(priv, 0, sizeof(*priv));
  8796. + priv->key_idx = key_idx;
  8797. +
  8798. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  8799. + priv->tfm = crypto_alloc_tfm("aes", 0);
  8800. + if (priv->tfm == NULL) {
  8801. + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
  8802. + "crypto API aes\n");
  8803. + goto fail;
  8804. + }
  8805. + #else
  8806. + priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
  8807. + if (IS_ERR(priv->tfm)) {
  8808. + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
  8809. + "crypto API aes\n");
  8810. + priv->tfm = NULL;
  8811. + goto fail;
  8812. + }
  8813. + #endif
  8814. + return priv;
  8815. +
  8816. +fail:
  8817. + if (priv) {
  8818. + if (priv->tfm)
  8819. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  8820. + crypto_free_tfm(priv->tfm);
  8821. + #else
  8822. + crypto_free_cipher((void*)priv->tfm);
  8823. + #endif
  8824. + kfree(priv);
  8825. + }
  8826. +
  8827. + return NULL;
  8828. +}
  8829. +
  8830. +
  8831. +static void ieee80211_ccmp_deinit(void *priv)
  8832. +{
  8833. + struct ieee80211_ccmp_data *_priv = priv;
  8834. + if (_priv && _priv->tfm)
  8835. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  8836. + crypto_free_tfm(_priv->tfm);
  8837. + #else
  8838. + crypto_free_cipher((void*)_priv->tfm);
  8839. + #endif
  8840. + kfree(priv);
  8841. +}
  8842. +
  8843. +
  8844. +static inline void xor_block(u8 *b, u8 *a, size_t len)
  8845. +{
  8846. + int i;
  8847. + for (i = 0; i < len; i++)
  8848. + b[i] ^= a[i];
  8849. +}
  8850. +
  8851. +#ifndef JOHN_CCMP
  8852. +static void ccmp_init_blocks(struct crypto_tfm *tfm,
  8853. + struct ieee80211_hdr *hdr,
  8854. + u8 *pn, size_t dlen, u8 *b0, u8 *auth,
  8855. + u8 *s0)
  8856. +{
  8857. + u8 *pos, qc = 0;
  8858. + size_t aad_len;
  8859. + u16 fc;
  8860. + int a4_included, qc_included;
  8861. + u8 aad[2 * AES_BLOCK_LEN];
  8862. +
  8863. + fc = le16_to_cpu(hdr->frame_ctl);
  8864. + a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  8865. + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
  8866. + /*
  8867. + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
  8868. + (WLAN_FC_GET_STYPE(fc) & 0x08));
  8869. + */
  8870. + // fixed by David :2006.9.6
  8871. + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
  8872. + (WLAN_FC_GET_STYPE(fc) & 0x80));
  8873. + aad_len = 22;
  8874. + if (a4_included)
  8875. + aad_len += 6;
  8876. + if (qc_included) {
  8877. + pos = (u8 *) &hdr->addr4;
  8878. + if (a4_included)
  8879. + pos += 6;
  8880. + qc = *pos & 0x0f;
  8881. + aad_len += 2;
  8882. + }
  8883. + /* CCM Initial Block:
  8884. + * Flag (Include authentication header, M=3 (8-octet MIC),
  8885. + * L=1 (2-octet Dlen))
  8886. + * Nonce: 0x00 | A2 | PN
  8887. + * Dlen */
  8888. + b0[0] = 0x59;
  8889. + b0[1] = qc;
  8890. + memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
  8891. + memcpy(b0 + 8, pn, CCMP_PN_LEN);
  8892. + b0[14] = (dlen >> 8) & 0xff;
  8893. + b0[15] = dlen & 0xff;
  8894. +
  8895. + /* AAD:
  8896. + * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
  8897. + * A1 | A2 | A3
  8898. + * SC with bits 4..15 (seq#) masked to zero
  8899. + * A4 (if present)
  8900. + * QC (if present)
  8901. + */
  8902. + pos = (u8 *) hdr;
  8903. + aad[0] = 0; /* aad_len >> 8 */
  8904. + aad[1] = aad_len & 0xff;
  8905. + aad[2] = pos[0] & 0x8f;
  8906. + aad[3] = pos[1] & 0xc7;
  8907. + memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
  8908. + pos = (u8 *) &hdr->seq_ctl;
  8909. + aad[22] = pos[0] & 0x0f;
  8910. + aad[23] = 0; /* all bits masked */
  8911. + memset(aad + 24, 0, 8);
  8912. + if (a4_included)
  8913. + memcpy(aad + 24, hdr->addr4, ETH_ALEN);
  8914. + if (qc_included) {
  8915. + aad[a4_included ? 30 : 24] = qc;
  8916. + /* rest of QC masked */
  8917. + }
  8918. +
  8919. + /* Start with the first block and AAD */
  8920. + ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
  8921. + xor_block(auth, aad, AES_BLOCK_LEN);
  8922. + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
  8923. + xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
  8924. + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
  8925. + b0[0] &= 0x07;
  8926. + b0[14] = b0[15] = 0;
  8927. + ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
  8928. +}
  8929. +#endif
  8930. +
  8931. +static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
  8932. +{
  8933. + struct ieee80211_ccmp_data *key = priv;
  8934. + int data_len, i;
  8935. + u8 *pos;
  8936. + struct ieee80211_hdr *hdr;
  8937. +#ifndef JOHN_CCMP
  8938. + int blocks, last, len;
  8939. + u8 *mic;
  8940. + u8 *b0 = key->tx_b0;
  8941. + u8 *b = key->tx_b;
  8942. + u8 *e = key->tx_e;
  8943. + u8 *s0 = key->tx_s0;
  8944. +#endif
  8945. + if (skb_headroom(skb) < CCMP_HDR_LEN ||
  8946. + skb_tailroom(skb) < CCMP_MIC_LEN ||
  8947. + skb->len < hdr_len)
  8948. + return -1;
  8949. +
  8950. + data_len = skb->len - hdr_len;
  8951. + pos = skb_push(skb, CCMP_HDR_LEN);
  8952. + memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
  8953. + pos += hdr_len;
  8954. +// mic = skb_put(skb, CCMP_MIC_LEN);
  8955. +
  8956. + i = CCMP_PN_LEN - 1;
  8957. + while (i >= 0) {
  8958. + key->tx_pn[i]++;
  8959. + if (key->tx_pn[i] != 0)
  8960. + break;
  8961. + i--;
  8962. + }
  8963. +
  8964. + *pos++ = key->tx_pn[5];
  8965. + *pos++ = key->tx_pn[4];
  8966. + *pos++ = 0;
  8967. + *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
  8968. + *pos++ = key->tx_pn[3];
  8969. + *pos++ = key->tx_pn[2];
  8970. + *pos++ = key->tx_pn[1];
  8971. + *pos++ = key->tx_pn[0];
  8972. +
  8973. + hdr = (struct ieee80211_hdr *) skb->data;
  8974. +#ifndef JOHN_CCMP
  8975. + //mic is moved to here by john
  8976. + mic = skb_put(skb, CCMP_MIC_LEN);
  8977. +
  8978. + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
  8979. +
  8980. + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
  8981. + last = data_len % AES_BLOCK_LEN;
  8982. +
  8983. + for (i = 1; i <= blocks; i++) {
  8984. + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
  8985. + /* Authentication */
  8986. + xor_block(b, pos, len);
  8987. + ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
  8988. + /* Encryption, with counter */
  8989. + b0[14] = (i >> 8) & 0xff;
  8990. + b0[15] = i & 0xff;
  8991. + ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
  8992. + xor_block(pos, e, len);
  8993. + pos += len;
  8994. + }
  8995. +
  8996. + for (i = 0; i < CCMP_MIC_LEN; i++)
  8997. + mic[i] = b[i] ^ s0[i];
  8998. +#endif
  8999. + return 0;
  9000. +}
  9001. +
  9002. +
  9003. +static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
  9004. +{
  9005. + struct ieee80211_ccmp_data *key = priv;
  9006. + u8 keyidx, *pos;
  9007. + struct ieee80211_hdr *hdr;
  9008. + u8 pn[6];
  9009. +#ifndef JOHN_CCMP
  9010. + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
  9011. + u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
  9012. + u8 *b0 = key->rx_b0;
  9013. + u8 *b = key->rx_b;
  9014. + u8 *a = key->rx_a;
  9015. + int i, blocks, last, len;
  9016. +#endif
  9017. + if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
  9018. + key->dot11RSNAStatsCCMPFormatErrors++;
  9019. + return -1;
  9020. + }
  9021. +
  9022. + hdr = (struct ieee80211_hdr *) skb->data;
  9023. + pos = skb->data + hdr_len;
  9024. + keyidx = pos[3];
  9025. + if (!(keyidx & (1 << 5))) {
  9026. + if (net_ratelimit()) {
  9027. + printk(KERN_DEBUG "CCMP: received packet without ExtIV"
  9028. + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
  9029. + }
  9030. + key->dot11RSNAStatsCCMPFormatErrors++;
  9031. + return -2;
  9032. + }
  9033. + keyidx >>= 6;
  9034. + if (key->key_idx != keyidx) {
  9035. + printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
  9036. + "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
  9037. + return -6;
  9038. + }
  9039. + if (!key->key_set) {
  9040. + if (net_ratelimit()) {
  9041. + printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
  9042. + " with keyid=%d that does not have a configured"
  9043. + " key\n", MAC_ARG(hdr->addr2), keyidx);
  9044. + }
  9045. + return -3;
  9046. + }
  9047. +
  9048. + pn[0] = pos[7];
  9049. + pn[1] = pos[6];
  9050. + pn[2] = pos[5];
  9051. + pn[3] = pos[4];
  9052. + pn[4] = pos[1];
  9053. + pn[5] = pos[0];
  9054. + pos += 8;
  9055. +#if 0
  9056. + if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
  9057. + if (net_ratelimit()) {
  9058. + printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
  9059. + " previous PN %02x%02x%02x%02x%02x%02x "
  9060. + "received PN %02x%02x%02x%02x%02x%02x\n",
  9061. + MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
  9062. + MAC_ARG(pn));
  9063. + }
  9064. + key->dot11RSNAStatsCCMPReplays++;
  9065. + return -4;
  9066. + }
  9067. +#endif
  9068. +#ifndef JOHN_CCMP
  9069. + ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
  9070. + xor_block(mic, b, CCMP_MIC_LEN);
  9071. +
  9072. + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
  9073. + last = data_len % AES_BLOCK_LEN;
  9074. +
  9075. + for (i = 1; i <= blocks; i++) {
  9076. + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
  9077. + /* Decrypt, with counter */
  9078. + b0[14] = (i >> 8) & 0xff;
  9079. + b0[15] = i & 0xff;
  9080. + ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
  9081. + xor_block(pos, b, len);
  9082. + /* Authentication */
  9083. + xor_block(a, pos, len);
  9084. + ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
  9085. + pos += len;
  9086. + }
  9087. +
  9088. + if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
  9089. + if (net_ratelimit()) {
  9090. + printk(KERN_DEBUG "CCMP: decrypt failed: STA="
  9091. + MAC_FMT "\n", MAC_ARG(hdr->addr2));
  9092. + }
  9093. + key->dot11RSNAStatsCCMPDecryptErrors++;
  9094. + return -5;
  9095. + }
  9096. +
  9097. + memcpy(key->rx_pn, pn, CCMP_PN_LEN);
  9098. +
  9099. +#endif
  9100. + /* Remove hdr and MIC */
  9101. + memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
  9102. + skb_pull(skb, CCMP_HDR_LEN);
  9103. + skb_trim(skb, skb->len - CCMP_MIC_LEN);
  9104. +
  9105. + return keyidx;
  9106. +}
  9107. +
  9108. +
  9109. +static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
  9110. +{
  9111. + struct ieee80211_ccmp_data *data = priv;
  9112. + int keyidx;
  9113. + struct crypto_tfm *tfm = data->tfm;
  9114. +
  9115. + keyidx = data->key_idx;
  9116. + memset(data, 0, sizeof(*data));
  9117. + data->key_idx = keyidx;
  9118. + data->tfm = tfm;
  9119. + if (len == CCMP_TK_LEN) {
  9120. + memcpy(data->key, key, CCMP_TK_LEN);
  9121. + data->key_set = 1;
  9122. + if (seq) {
  9123. + data->rx_pn[0] = seq[5];
  9124. + data->rx_pn[1] = seq[4];
  9125. + data->rx_pn[2] = seq[3];
  9126. + data->rx_pn[3] = seq[2];
  9127. + data->rx_pn[4] = seq[1];
  9128. + data->rx_pn[5] = seq[0];
  9129. + }
  9130. + crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN);
  9131. + } else if (len == 0)
  9132. + data->key_set = 0;
  9133. + else
  9134. + return -1;
  9135. +
  9136. + return 0;
  9137. +}
  9138. +
  9139. +
  9140. +static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
  9141. +{
  9142. + struct ieee80211_ccmp_data *data = priv;
  9143. +
  9144. + if (len < CCMP_TK_LEN)
  9145. + return -1;
  9146. +
  9147. + if (!data->key_set)
  9148. + return 0;
  9149. + memcpy(key, data->key, CCMP_TK_LEN);
  9150. +
  9151. + if (seq) {
  9152. + seq[0] = data->tx_pn[5];
  9153. + seq[1] = data->tx_pn[4];
  9154. + seq[2] = data->tx_pn[3];
  9155. + seq[3] = data->tx_pn[2];
  9156. + seq[4] = data->tx_pn[1];
  9157. + seq[5] = data->tx_pn[0];
  9158. + }
  9159. +
  9160. + return CCMP_TK_LEN;
  9161. +}
  9162. +
  9163. +
  9164. +static char * ieee80211_ccmp_print_stats(char *p, void *priv)
  9165. +{
  9166. + struct ieee80211_ccmp_data *ccmp = priv;
  9167. + p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
  9168. + "tx_pn=%02x%02x%02x%02x%02x%02x "
  9169. + "rx_pn=%02x%02x%02x%02x%02x%02x "
  9170. + "format_errors=%d replays=%d decrypt_errors=%d\n",
  9171. + ccmp->key_idx, ccmp->key_set,
  9172. + MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
  9173. + ccmp->dot11RSNAStatsCCMPFormatErrors,
  9174. + ccmp->dot11RSNAStatsCCMPReplays,
  9175. + ccmp->dot11RSNAStatsCCMPDecryptErrors);
  9176. +
  9177. + return p;
  9178. +}
  9179. +
  9180. +void ieee80211_ccmp_null(void)
  9181. +{
  9182. + // printk("============>%s()\n", __FUNCTION__);
  9183. + return;
  9184. +}
  9185. +static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
  9186. + .name = "CCMP",
  9187. + .init = ieee80211_ccmp_init,
  9188. + .deinit = ieee80211_ccmp_deinit,
  9189. + .encrypt_mpdu = ieee80211_ccmp_encrypt,
  9190. + .decrypt_mpdu = ieee80211_ccmp_decrypt,
  9191. + .encrypt_msdu = NULL,
  9192. + .decrypt_msdu = NULL,
  9193. + .set_key = ieee80211_ccmp_set_key,
  9194. + .get_key = ieee80211_ccmp_get_key,
  9195. + .print_stats = ieee80211_ccmp_print_stats,
  9196. + .extra_prefix_len = CCMP_HDR_LEN,
  9197. + .extra_postfix_len = CCMP_MIC_LEN,
  9198. + .owner = THIS_MODULE,
  9199. +};
  9200. +
  9201. +
  9202. +int __init ieee80211_crypto_ccmp_init(void)
  9203. +{
  9204. + return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
  9205. +}
  9206. +
  9207. +
  9208. +void __exit ieee80211_crypto_ccmp_exit(void)
  9209. +{
  9210. + ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
  9211. +}
  9212. +#if 0
  9213. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  9214. +EXPORT_SYMBOL(ieee80211_ccmp_null);
  9215. +#else
  9216. +EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
  9217. +#endif
  9218. +
  9219. +module_init(ieee80211_crypto_ccmp_init);
  9220. +module_exit(ieee80211_crypto_ccmp_exit);
  9221. +#endif
  9222. 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
  9223. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 1970-01-01 01:00:00.000000000 +0100
  9224. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt.h 2010-05-27 18:12:39.532222207 +0200
  9225. @@ -0,0 +1,91 @@
  9226. +/*
  9227. + * Original code based on Host AP (software wireless LAN access point) driver
  9228. + * for Intersil Prism2/2.5/3.
  9229. + *
  9230. + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  9231. + * <jkmaline@cc.hut.fi>
  9232. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  9233. + *
  9234. + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
  9235. + * <jketreno@linux.intel.com>
  9236. + *
  9237. + * Copyright (c) 2004, Intel Corporation
  9238. + *
  9239. + * This program is free software; you can redistribute it and/or modify
  9240. + * it under the terms of the GNU General Public License version 2 as
  9241. + * published by the Free Software Foundation. See README and COPYING for
  9242. + * more details.
  9243. + */
  9244. +
  9245. +/*
  9246. + * This file defines the interface to the ieee80211 crypto module.
  9247. + */
  9248. +#ifndef IEEE80211_CRYPT_H
  9249. +#define IEEE80211_CRYPT_H
  9250. +
  9251. +#include <linux/skbuff.h>
  9252. +
  9253. +struct ieee80211_crypto_ops {
  9254. + const char *name;
  9255. +
  9256. + /* init new crypto context (e.g., allocate private data space,
  9257. + * select IV, etc.); returns NULL on failure or pointer to allocated
  9258. + * private data on success */
  9259. + void * (*init)(int keyidx);
  9260. +
  9261. + /* deinitialize crypto context and free allocated private data */
  9262. + void (*deinit)(void *priv);
  9263. +
  9264. + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
  9265. + * value from decrypt_mpdu is passed as the keyidx value for
  9266. + * decrypt_msdu. skb must have enough head and tail room for the
  9267. + * encryption; if not, error will be returned; these functions are
  9268. + * called for all MPDUs (i.e., fragments).
  9269. + */
  9270. + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
  9271. + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
  9272. +
  9273. + /* These functions are called for full MSDUs, i.e. full frames.
  9274. + * These can be NULL if full MSDU operations are not needed. */
  9275. + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
  9276. + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
  9277. + void *priv);
  9278. +
  9279. + int (*set_key)(void *key, int len, u8 *seq, void *priv);
  9280. + int (*get_key)(void *key, int len, u8 *seq, void *priv);
  9281. +
  9282. + /* procfs handler for printing out key information and possible
  9283. + * statistics */
  9284. + char * (*print_stats)(char *p, void *priv);
  9285. +
  9286. + /* maximum number of bytes added by encryption; encrypt buf is
  9287. + * allocated with extra_prefix_len bytes, copy of in_buf, and
  9288. + * extra_postfix_len; encrypt need not use all this space, but
  9289. + * the result must start at the beginning of the buffer and correct
  9290. + * length must be returned */
  9291. + int extra_prefix_len, extra_postfix_len;
  9292. +
  9293. + struct module *owner;
  9294. +};
  9295. +
  9296. +struct ieee80211_crypt_data {
  9297. + struct list_head list; /* delayed deletion list */
  9298. + struct ieee80211_crypto_ops *ops;
  9299. + void *priv;
  9300. + atomic_t refcnt;
  9301. +};
  9302. +
  9303. +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
  9304. +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
  9305. +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
  9306. +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
  9307. +void ieee80211_crypt_deinit_handler(unsigned long);
  9308. +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
  9309. + struct ieee80211_crypt_data **crypt);
  9310. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  9311. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  9312. +#define crypto_alloc_tfm crypto_alloc_tfm_rtl
  9313. +#define crypto_free_tfm crypto_free_tfm_rtl
  9314. +#endif
  9315. +
  9316. +#endif
  9317. 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
  9318. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 1970-01-01 01:00:00.000000000 +0100
  9319. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_tkip.c 2010-05-27 18:12:39.532222207 +0200
  9320. @@ -0,0 +1,996 @@
  9321. +/*
  9322. + * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
  9323. + *
  9324. + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
  9325. + *
  9326. + * This program is free software; you can redistribute it and/or modify
  9327. + * it under the terms of the GNU General Public License version 2 as
  9328. + * published by the Free Software Foundation. See README and COPYING for
  9329. + * more details.
  9330. + */
  9331. +
  9332. +//#include <linux/config.h>
  9333. +#include <linux/version.h>
  9334. +#include <linux/module.h>
  9335. +#include <linux/init.h>
  9336. +#include <linux/slab.h>
  9337. +#include <linux/random.h>
  9338. +#include <linux/skbuff.h>
  9339. +#include <linux/netdevice.h>
  9340. +#include <linux/if_ether.h>
  9341. +#include <linux/if_arp.h>
  9342. +#include <asm/string.h>
  9343. +
  9344. +#include "ieee80211.h"
  9345. +
  9346. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  9347. +#include "rtl_crypto.h"
  9348. +#else
  9349. +#include <linux/crypto.h>
  9350. +#endif
  9351. +//#include <asm/scatterlist.h>
  9352. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  9353. + #include <asm/scatterlist.h>
  9354. +#else
  9355. + #include <linux/scatterlist.h>
  9356. +#endif
  9357. +
  9358. +#include <linux/crc32.h>
  9359. +
  9360. +MODULE_AUTHOR("Jouni Malinen");
  9361. +MODULE_DESCRIPTION("Host AP crypt: TKIP");
  9362. +MODULE_LICENSE("GPL");
  9363. +
  9364. +struct ieee80211_tkip_data {
  9365. +#define TKIP_KEY_LEN 32
  9366. + u8 key[TKIP_KEY_LEN];
  9367. + int key_set;
  9368. +
  9369. + u32 tx_iv32;
  9370. + u16 tx_iv16;
  9371. + u16 tx_ttak[5];
  9372. + int tx_phase1_done;
  9373. +
  9374. + u32 rx_iv32;
  9375. + u16 rx_iv16;
  9376. + u16 rx_ttak[5];
  9377. + int rx_phase1_done;
  9378. + u32 rx_iv32_new;
  9379. + u16 rx_iv16_new;
  9380. +
  9381. + u32 dot11RSNAStatsTKIPReplays;
  9382. + u32 dot11RSNAStatsTKIPICVErrors;
  9383. + u32 dot11RSNAStatsTKIPLocalMICFailures;
  9384. +
  9385. + int key_idx;
  9386. +
  9387. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  9388. + struct crypto_blkcipher *rx_tfm_arc4;
  9389. + struct crypto_hash *rx_tfm_michael;
  9390. + struct crypto_blkcipher *tx_tfm_arc4;
  9391. + struct crypto_hash *tx_tfm_michael;
  9392. + #endif
  9393. +
  9394. + struct crypto_tfm *tfm_arc4;
  9395. + struct crypto_tfm *tfm_michael;
  9396. +
  9397. + /* scratch buffers for virt_to_page() (crypto API) */
  9398. + u8 rx_hdr[16], tx_hdr[16];
  9399. +};
  9400. +
  9401. +static void * ieee80211_tkip_init(int key_idx)
  9402. +{
  9403. + struct ieee80211_tkip_data *priv;
  9404. +
  9405. + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
  9406. + if (priv == NULL)
  9407. + goto fail;
  9408. + memset(priv, 0, sizeof(*priv));
  9409. + priv->key_idx = key_idx;
  9410. +
  9411. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  9412. + priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
  9413. + if (priv->tfm_arc4 == NULL) {
  9414. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  9415. + "crypto API arc4\n");
  9416. + goto fail;
  9417. + }
  9418. +
  9419. + priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
  9420. + if (priv->tfm_michael == NULL) {
  9421. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  9422. + "crypto API michael_mic\n");
  9423. + goto fail;
  9424. + }
  9425. +
  9426. + #else
  9427. + priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
  9428. + CRYPTO_ALG_ASYNC);
  9429. + if (IS_ERR(priv->tx_tfm_arc4)) {
  9430. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  9431. + "crypto API arc4\n");
  9432. + priv->tx_tfm_arc4 = NULL;
  9433. + goto fail;
  9434. + }
  9435. +
  9436. + priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
  9437. + CRYPTO_ALG_ASYNC);
  9438. + if (IS_ERR(priv->tx_tfm_michael)) {
  9439. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  9440. + "crypto API michael_mic\n");
  9441. + priv->tx_tfm_michael = NULL;
  9442. + goto fail;
  9443. + }
  9444. +
  9445. + priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
  9446. + CRYPTO_ALG_ASYNC);
  9447. + if (IS_ERR(priv->rx_tfm_arc4)) {
  9448. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  9449. + "crypto API arc4\n");
  9450. + priv->rx_tfm_arc4 = NULL;
  9451. + goto fail;
  9452. + }
  9453. +
  9454. + priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
  9455. + CRYPTO_ALG_ASYNC);
  9456. + if (IS_ERR(priv->rx_tfm_michael)) {
  9457. + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
  9458. + "crypto API michael_mic\n");
  9459. + priv->rx_tfm_michael = NULL;
  9460. + goto fail;
  9461. + }
  9462. + #endif
  9463. + return priv;
  9464. +
  9465. +fail:
  9466. + if (priv) {
  9467. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  9468. + if (priv->tfm_michael)
  9469. + crypto_free_tfm(priv->tfm_michael);
  9470. + if (priv->tfm_arc4)
  9471. + crypto_free_tfm(priv->tfm_arc4);
  9472. + #else
  9473. + if (priv->tx_tfm_michael)
  9474. + crypto_free_hash(priv->tx_tfm_michael);
  9475. + if (priv->tx_tfm_arc4)
  9476. + crypto_free_blkcipher(priv->tx_tfm_arc4);
  9477. + if (priv->rx_tfm_michael)
  9478. + crypto_free_hash(priv->rx_tfm_michael);
  9479. + if (priv->rx_tfm_arc4)
  9480. + crypto_free_blkcipher(priv->rx_tfm_arc4);
  9481. + #endif
  9482. + kfree(priv);
  9483. + }
  9484. +
  9485. + return NULL;
  9486. +}
  9487. +
  9488. +
  9489. +static void ieee80211_tkip_deinit(void *priv)
  9490. +{
  9491. + struct ieee80211_tkip_data *_priv = priv;
  9492. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  9493. + if (_priv && _priv->tfm_michael)
  9494. + crypto_free_tfm(_priv->tfm_michael);
  9495. + if (_priv && _priv->tfm_arc4)
  9496. + crypto_free_tfm(_priv->tfm_arc4);
  9497. + #else
  9498. + if (_priv) {
  9499. + if (_priv->tx_tfm_michael)
  9500. + crypto_free_hash(_priv->tx_tfm_michael);
  9501. + if (_priv->tx_tfm_arc4)
  9502. + crypto_free_blkcipher(_priv->tx_tfm_arc4);
  9503. + if (_priv->rx_tfm_michael)
  9504. + crypto_free_hash(_priv->rx_tfm_michael);
  9505. + if (_priv->rx_tfm_arc4)
  9506. + crypto_free_blkcipher(_priv->rx_tfm_arc4);
  9507. + }
  9508. + #endif
  9509. + kfree(priv);
  9510. +}
  9511. +
  9512. +
  9513. +static inline u16 RotR1(u16 val)
  9514. +{
  9515. + return (val >> 1) | (val << 15);
  9516. +}
  9517. +
  9518. +
  9519. +static inline u8 Lo8(u16 val)
  9520. +{
  9521. + return val & 0xff;
  9522. +}
  9523. +
  9524. +
  9525. +static inline u8 Hi8(u16 val)
  9526. +{
  9527. + return val >> 8;
  9528. +}
  9529. +
  9530. +
  9531. +static inline u16 Lo16(u32 val)
  9532. +{
  9533. + return val & 0xffff;
  9534. +}
  9535. +
  9536. +
  9537. +static inline u16 Hi16(u32 val)
  9538. +{
  9539. + return val >> 16;
  9540. +}
  9541. +
  9542. +
  9543. +static inline u16 Mk16(u8 hi, u8 lo)
  9544. +{
  9545. + return lo | (((u16) hi) << 8);
  9546. +}
  9547. +
  9548. +
  9549. +static inline u16 Mk16_le(u16 *v)
  9550. +{
  9551. + return le16_to_cpu(*v);
  9552. +}
  9553. +
  9554. +
  9555. +static const u16 Sbox[256] =
  9556. +{
  9557. + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
  9558. + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
  9559. + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
  9560. + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
  9561. + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
  9562. + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
  9563. + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
  9564. + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
  9565. + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
  9566. + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
  9567. + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
  9568. + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
  9569. + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
  9570. + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
  9571. + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
  9572. + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
  9573. + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
  9574. + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
  9575. + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
  9576. + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
  9577. + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
  9578. + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
  9579. + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
  9580. + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
  9581. + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
  9582. + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
  9583. + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
  9584. + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
  9585. + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
  9586. + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
  9587. + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
  9588. + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
  9589. +};
  9590. +
  9591. +
  9592. +static inline u16 _S_(u16 v)
  9593. +{
  9594. + u16 t = Sbox[Hi8(v)];
  9595. + return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
  9596. +}
  9597. +
  9598. +#ifndef JOHN_TKIP
  9599. +#define PHASE1_LOOP_COUNT 8
  9600. +
  9601. +static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
  9602. +{
  9603. + int i, j;
  9604. +
  9605. + /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
  9606. + TTAK[0] = Lo16(IV32);
  9607. + TTAK[1] = Hi16(IV32);
  9608. + TTAK[2] = Mk16(TA[1], TA[0]);
  9609. + TTAK[3] = Mk16(TA[3], TA[2]);
  9610. + TTAK[4] = Mk16(TA[5], TA[4]);
  9611. +
  9612. + for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
  9613. + j = 2 * (i & 1);
  9614. + TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
  9615. + TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
  9616. + TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
  9617. + TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
  9618. + TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
  9619. + }
  9620. +}
  9621. +
  9622. +
  9623. +static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
  9624. + u16 IV16)
  9625. +{
  9626. + /* Make temporary area overlap WEP seed so that the final copy can be
  9627. + * avoided on little endian hosts. */
  9628. + u16 *PPK = (u16 *) &WEPSeed[4];
  9629. +
  9630. + /* Step 1 - make copy of TTAK and bring in TSC */
  9631. + PPK[0] = TTAK[0];
  9632. + PPK[1] = TTAK[1];
  9633. + PPK[2] = TTAK[2];
  9634. + PPK[3] = TTAK[3];
  9635. + PPK[4] = TTAK[4];
  9636. + PPK[5] = TTAK[4] + IV16;
  9637. +
  9638. + /* Step 2 - 96-bit bijective mixing using S-box */
  9639. + PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
  9640. + PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
  9641. + PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
  9642. + PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
  9643. + PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
  9644. + PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
  9645. +
  9646. + PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
  9647. + PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
  9648. + PPK[2] += RotR1(PPK[1]);
  9649. + PPK[3] += RotR1(PPK[2]);
  9650. + PPK[4] += RotR1(PPK[3]);
  9651. + PPK[5] += RotR1(PPK[4]);
  9652. +
  9653. + /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
  9654. + * WEPSeed[0..2] is transmitted as WEP IV */
  9655. + WEPSeed[0] = Hi8(IV16);
  9656. + WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
  9657. + WEPSeed[2] = Lo8(IV16);
  9658. + WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
  9659. +
  9660. +#ifdef __BIG_ENDIAN
  9661. + {
  9662. + int i;
  9663. + for (i = 0; i < 6; i++)
  9664. + PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
  9665. + }
  9666. +#endif
  9667. +}
  9668. +#endif
  9669. +static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
  9670. +{
  9671. + struct ieee80211_tkip_data *tkey = priv;
  9672. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  9673. + struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
  9674. + #endif
  9675. + int len;
  9676. + u8 *pos;
  9677. + struct ieee80211_hdr *hdr;
  9678. +#ifndef JOHN_TKIP
  9679. + u8 rc4key[16],*icv;
  9680. + u32 crc;
  9681. + struct scatterlist sg;
  9682. +#endif
  9683. + #if(LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,21))
  9684. + int ret;
  9685. + #endif
  9686. +
  9687. + if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
  9688. + skb->len < hdr_len)
  9689. + return -1;
  9690. +
  9691. + hdr = (struct ieee80211_hdr *) skb->data;
  9692. +#if 0
  9693. +printk("@@ tkey\n");
  9694. +printk("%x|", ((u32*)tkey->key)[0]);
  9695. +printk("%x|", ((u32*)tkey->key)[1]);
  9696. +printk("%x|", ((u32*)tkey->key)[2]);
  9697. +printk("%x|", ((u32*)tkey->key)[3]);
  9698. +printk("%x|", ((u32*)tkey->key)[4]);
  9699. +printk("%x|", ((u32*)tkey->key)[5]);
  9700. +printk("%x|", ((u32*)tkey->key)[6]);
  9701. +printk("%x\n", ((u32*)tkey->key)[7]);
  9702. +#endif
  9703. +
  9704. +#ifndef JOHN_TKIP
  9705. + if (!tkey->tx_phase1_done) {
  9706. + tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
  9707. + tkey->tx_iv32);
  9708. + tkey->tx_phase1_done = 1;
  9709. + }
  9710. + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
  9711. +
  9712. +#else
  9713. + tkey->tx_phase1_done = 1;
  9714. +#endif /*JOHN_TKIP*/
  9715. +
  9716. + len = skb->len - hdr_len;
  9717. + pos = skb_push(skb, 8);
  9718. + memmove(pos, pos + 8, hdr_len);
  9719. + pos += hdr_len;
  9720. +
  9721. +#ifdef JOHN_TKIP
  9722. + *pos++ = Hi8(tkey->tx_iv16);
  9723. + *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
  9724. + *pos++ = Lo8(tkey->tx_iv16);
  9725. +#else
  9726. + *pos++ = rc4key[0];
  9727. + *pos++ = rc4key[1];
  9728. + *pos++ = rc4key[2];
  9729. +#endif
  9730. + *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
  9731. + *pos++ = tkey->tx_iv32 & 0xff;
  9732. + *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
  9733. + *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
  9734. + *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
  9735. +#ifndef JOHN_TKIP
  9736. + icv = skb_put(skb, 4);
  9737. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  9738. + crc = ~crc32_le(~0, pos, len);
  9739. +#else
  9740. + crc = ~ether_crc_le(len, pos);
  9741. +#endif
  9742. + icv[0] = crc;
  9743. + icv[1] = crc >> 8;
  9744. + icv[2] = crc >> 16;
  9745. + icv[3] = crc >> 24;
  9746. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  9747. + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
  9748. + sg.page = virt_to_page(pos);
  9749. + sg.offset = offset_in_page(pos);
  9750. + sg.length = len + 4;
  9751. + crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
  9752. + #else
  9753. + crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
  9754. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  9755. + sg.page = virt_to_page(pos);
  9756. + sg.offset = offset_in_page(pos);
  9757. + sg.length = len + 4;
  9758. + #else
  9759. + sg_init_one(&sg, pos, len + 4);
  9760. + #endif
  9761. + ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
  9762. + #endif
  9763. +#endif
  9764. + tkey->tx_iv16++;
  9765. + if (tkey->tx_iv16 == 0) {
  9766. + tkey->tx_phase1_done = 0;
  9767. + tkey->tx_iv32++;
  9768. + }
  9769. +#ifndef JOHN_TKIP
  9770. + #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
  9771. + return 0;
  9772. + #else
  9773. + return ret;
  9774. + #endif
  9775. +#else
  9776. + return 0;
  9777. +#endif
  9778. +}
  9779. +
  9780. +static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
  9781. +{
  9782. + struct ieee80211_tkip_data *tkey = priv;
  9783. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  9784. + struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
  9785. + #endif
  9786. + u8 keyidx, *pos;
  9787. + u32 iv32;
  9788. + u16 iv16;
  9789. + struct ieee80211_hdr *hdr;
  9790. +#ifndef JOHN_TKIP
  9791. + u8 icv[4];
  9792. + u32 crc;
  9793. + struct scatterlist sg;
  9794. + u8 rc4key[16];
  9795. + int plen;
  9796. +#endif
  9797. + if (skb->len < hdr_len + 8 + 4)
  9798. + return -1;
  9799. +
  9800. + hdr = (struct ieee80211_hdr *) skb->data;
  9801. + pos = skb->data + hdr_len;
  9802. + keyidx = pos[3];
  9803. + if (!(keyidx & (1 << 5))) {
  9804. + if (net_ratelimit()) {
  9805. + printk(KERN_DEBUG "TKIP: received packet without ExtIV"
  9806. + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
  9807. + }
  9808. + return -2;
  9809. + }
  9810. + keyidx >>= 6;
  9811. + if (tkey->key_idx != keyidx) {
  9812. + printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
  9813. + "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
  9814. + return -6;
  9815. + }
  9816. + if (!tkey->key_set) {
  9817. + if (net_ratelimit()) {
  9818. + printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
  9819. + " with keyid=%d that does not have a configured"
  9820. + " key\n", MAC_ARG(hdr->addr2), keyidx);
  9821. + }
  9822. + return -3;
  9823. + }
  9824. + iv16 = (pos[0] << 8) | pos[2];
  9825. + iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
  9826. + pos += 8;
  9827. +#ifndef JOHN_TKIP
  9828. +#if 0
  9829. + if (iv32 < tkey->rx_iv32 ||
  9830. + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
  9831. + if (net_ratelimit()) {
  9832. + printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
  9833. + " previous TSC %08x%04x received TSC "
  9834. + "%08x%04x\n", MAC_ARG(hdr->addr2),
  9835. + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
  9836. + }
  9837. + tkey->dot11RSNAStatsTKIPReplays++;
  9838. + return -4;
  9839. + }
  9840. +#endif
  9841. + if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
  9842. + tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
  9843. + tkey->rx_phase1_done = 1;
  9844. + }
  9845. + tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
  9846. +
  9847. + plen = skb->len - hdr_len - 12;
  9848. + #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))
  9849. + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
  9850. + sg.page = virt_to_page(pos);
  9851. + sg.offset = offset_in_page(pos);
  9852. + sg.length = plen + 4;
  9853. + crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
  9854. + #else
  9855. + crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
  9856. + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
  9857. + sg.page = virt_to_page(pos);
  9858. + sg.offset = offset_in_page(pos);
  9859. + sg.length = plen + 4;
  9860. + #else
  9861. + sg_init_one(&sg, pos, plen + 4);
  9862. + #endif
  9863. + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
  9864. + if (net_ratelimit()) {
  9865. + printk(KERN_DEBUG ": TKIP: failed to decrypt "
  9866. + "received packet from " MAC_FMT "\n",
  9867. + MAC_ARG(hdr->addr2));
  9868. + }
  9869. + return -7;
  9870. + }
  9871. + #endif
  9872. +
  9873. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  9874. + crc = ~crc32_le(~0, pos, plen);
  9875. +#else
  9876. + crc = ~ether_crc_le(plen, pos);
  9877. +#endif
  9878. + icv[0] = crc;
  9879. + icv[1] = crc >> 8;
  9880. + icv[2] = crc >> 16;
  9881. + icv[3] = crc >> 24;
  9882. + if (memcmp(icv, pos + plen, 4) != 0) {
  9883. + if (iv32 != tkey->rx_iv32) {
  9884. + /* Previously cached Phase1 result was already lost, so
  9885. + * it needs to be recalculated for the next packet. */
  9886. + tkey->rx_phase1_done = 0;
  9887. + }
  9888. + if (net_ratelimit()) {
  9889. + printk(KERN_DEBUG "TKIP: ICV error detected: STA="
  9890. + MAC_FMT "\n", MAC_ARG(hdr->addr2));
  9891. + }
  9892. + tkey->dot11RSNAStatsTKIPICVErrors++;
  9893. + return -5;
  9894. + }
  9895. +
  9896. +#endif /* JOHN_TKIP */
  9897. +
  9898. + /* Update real counters only after Michael MIC verification has
  9899. + * completed */
  9900. + tkey->rx_iv32_new = iv32;
  9901. + tkey->rx_iv16_new = iv16;
  9902. +
  9903. + /* Remove IV and ICV */
  9904. + memmove(skb->data + 8, skb->data, hdr_len);
  9905. + skb_pull(skb, 8);
  9906. + skb_trim(skb, skb->len - 4);
  9907. +
  9908. +//john's test
  9909. +#ifdef JOHN_DUMP
  9910. +if( ((u16*)skb->data)[0] & 0x4000){
  9911. + printk("@@ rx decrypted skb->data");
  9912. + int i;
  9913. + for(i=0;i<skb->len;i++){
  9914. + if( (i%24)==0 ) printk("\n");
  9915. + printk("%2x ", ((u8*)skb->data)[i]);
  9916. + }
  9917. + printk("\n");
  9918. +}
  9919. +#endif /*JOHN_DUMP*/
  9920. + return keyidx;
  9921. +}
  9922. +
  9923. +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  9924. +static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
  9925. + u8 *data, size_t data_len, u8 *mic)
  9926. +{
  9927. + struct scatterlist sg[2];
  9928. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  9929. + struct hash_desc desc;
  9930. + int ret=0;
  9931. +#endif
  9932. + if (tkey->tfm_michael == NULL) {
  9933. + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
  9934. + return -1;
  9935. + }
  9936. + sg[0].page = virt_to_page(hdr);
  9937. + sg[0].offset = offset_in_page(hdr);
  9938. + sg[0].length = 16;
  9939. +
  9940. + sg[1].page = virt_to_page(data);
  9941. + sg[1].offset = offset_in_page(data);
  9942. + sg[1].length = data_len;
  9943. +
  9944. + //crypto_digest_init(tkey->tfm_michael);
  9945. + //crypto_digest_setkey(tkey->tfm_michael, key, 8);
  9946. + //crypto_digest_update(tkey->tfm_michael, sg, 2);
  9947. + //crypto_digest_final(tkey->tfm_michael, mic);
  9948. +
  9949. + //return 0;
  9950. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  9951. + crypto_digest_init(tkey->tfm_michael);
  9952. + crypto_digest_setkey(tkey->tfm_michael, key, 8);
  9953. + crypto_digest_update(tkey->tfm_michael, sg, 2);
  9954. + crypto_digest_final(tkey->tfm_michael, mic);
  9955. +
  9956. + return 0;
  9957. +#else
  9958. +if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
  9959. + return -1;
  9960. +
  9961. +// return 0;
  9962. + desc.tfm = tkey->tfm_michael;
  9963. + desc.flags = 0;
  9964. + ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
  9965. + return ret;
  9966. +#endif
  9967. +}
  9968. +#else
  9969. +static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
  9970. + u8 * data, size_t data_len, u8 * mic)
  9971. +{
  9972. + struct hash_desc desc;
  9973. + struct scatterlist sg[2];
  9974. +
  9975. + if (tfm_michael == NULL) {
  9976. + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
  9977. + return -1;
  9978. + }
  9979. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  9980. + sg[0].page = virt_to_page(hdr);
  9981. + sg[0].offset = offset_in_page(hdr);
  9982. + sg[0].length = 16;
  9983. +
  9984. + sg[1].page = virt_to_page(data);
  9985. + sg[1].offset = offset_in_page(data);
  9986. + sg[1].length = data_len;
  9987. +#else
  9988. + sg_init_table(sg, 2);
  9989. + sg_set_buf(&sg[0], hdr, 16);
  9990. + sg_set_buf(&sg[1], data, data_len);
  9991. +#endif
  9992. + if (crypto_hash_setkey(tfm_michael, key, 8))
  9993. + return -1;
  9994. +
  9995. + desc.tfm = tfm_michael;
  9996. + desc.flags = 0;
  9997. + return crypto_hash_digest(&desc, sg, data_len + 16, mic);
  9998. +}
  9999. +#endif
  10000. +
  10001. +
  10002. +
  10003. +static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
  10004. +{
  10005. + struct ieee80211_hdr *hdr11;
  10006. +
  10007. + hdr11 = (struct ieee80211_hdr *) skb->data;
  10008. + switch (le16_to_cpu(hdr11->frame_ctl) &
  10009. + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
  10010. + case IEEE80211_FCTL_TODS:
  10011. + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
  10012. + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
  10013. + break;
  10014. + case IEEE80211_FCTL_FROMDS:
  10015. + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
  10016. + memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
  10017. + break;
  10018. + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
  10019. + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
  10020. + memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
  10021. + break;
  10022. + case 0:
  10023. + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
  10024. + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
  10025. + break;
  10026. + }
  10027. +
  10028. + hdr[12] = 0; /* priority */
  10029. +
  10030. + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
  10031. +}
  10032. +
  10033. +
  10034. +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
  10035. +{
  10036. + struct ieee80211_tkip_data *tkey = priv;
  10037. + u8 *pos;
  10038. + struct ieee80211_hdr *hdr;
  10039. +
  10040. + hdr = (struct ieee80211_hdr *) skb->data;
  10041. +
  10042. + if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
  10043. + printk(KERN_DEBUG "Invalid packet for Michael MIC add "
  10044. + "(tailroom=%d hdr_len=%d skb->len=%d)\n",
  10045. + skb_tailroom(skb), hdr_len, skb->len);
  10046. + return -1;
  10047. + }
  10048. +
  10049. + michael_mic_hdr(skb, tkey->tx_hdr);
  10050. +
  10051. + // { david, 2006.9.1
  10052. + // fix the wpa process with wmm enabled.
  10053. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
  10054. + tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
  10055. + }
  10056. + // }
  10057. + pos = skb_put(skb, 8);
  10058. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10059. + if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
  10060. + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
  10061. + #else
  10062. + if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
  10063. + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
  10064. + #endif
  10065. + return -1;
  10066. +
  10067. + return 0;
  10068. +}
  10069. +
  10070. +
  10071. +#if WIRELESS_EXT >= 18
  10072. +static void ieee80211_michael_mic_failure(struct net_device *dev,
  10073. + struct ieee80211_hdr *hdr,
  10074. + int keyidx)
  10075. +{
  10076. + union iwreq_data wrqu;
  10077. + struct iw_michaelmicfailure ev;
  10078. +
  10079. + /* TODO: needed parameters: count, keyid, key type, TSC */
  10080. + memset(&ev, 0, sizeof(ev));
  10081. + ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
  10082. + if (hdr->addr1[0] & 0x01)
  10083. + ev.flags |= IW_MICFAILURE_GROUP;
  10084. + else
  10085. + ev.flags |= IW_MICFAILURE_PAIRWISE;
  10086. + ev.src_addr.sa_family = ARPHRD_ETHER;
  10087. + memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
  10088. + memset(&wrqu, 0, sizeof(wrqu));
  10089. + wrqu.data.length = sizeof(ev);
  10090. + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
  10091. +}
  10092. +#elif WIRELESS_EXT >= 15
  10093. +static void ieee80211_michael_mic_failure(struct net_device *dev,
  10094. + struct ieee80211_hdr *hdr,
  10095. + int keyidx)
  10096. +{
  10097. + union iwreq_data wrqu;
  10098. + char buf[128];
  10099. +
  10100. + /* TODO: needed parameters: count, keyid, key type, TSC */
  10101. + sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
  10102. + MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
  10103. + MAC_ARG(hdr->addr2));
  10104. + memset(&wrqu, 0, sizeof(wrqu));
  10105. + wrqu.data.length = strlen(buf);
  10106. + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
  10107. +}
  10108. +#else /* WIRELESS_EXT >= 15 */
  10109. +static inline void ieee80211_michael_mic_failure(struct net_device *dev,
  10110. + struct ieee80211_hdr *hdr,
  10111. + int keyidx)
  10112. +{
  10113. +}
  10114. +#endif /* WIRELESS_EXT >= 15 */
  10115. +
  10116. +
  10117. +static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
  10118. + int hdr_len, void *priv)
  10119. +{
  10120. + struct ieee80211_tkip_data *tkey = priv;
  10121. + u8 mic[8];
  10122. + struct ieee80211_hdr *hdr;
  10123. +
  10124. + hdr = (struct ieee80211_hdr *) skb->data;
  10125. +
  10126. + if (!tkey->key_set)
  10127. + return -1;
  10128. +
  10129. + michael_mic_hdr(skb, tkey->rx_hdr);
  10130. + // { david, 2006.9.1
  10131. + // fix the wpa process with wmm enabled.
  10132. + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
  10133. + tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
  10134. + }
  10135. + // }
  10136. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10137. + if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
  10138. + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
  10139. + #else
  10140. + if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
  10141. + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
  10142. + #endif
  10143. + return -1;
  10144. + if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
  10145. + struct ieee80211_hdr *hdr;
  10146. + hdr = (struct ieee80211_hdr *) skb->data;
  10147. + printk(KERN_DEBUG "%s: Michael MIC verification failed for "
  10148. + "MSDU from " MAC_FMT " keyidx=%d\n",
  10149. + skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
  10150. + keyidx);
  10151. + if (skb->dev)
  10152. + ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
  10153. + tkey->dot11RSNAStatsTKIPLocalMICFailures++;
  10154. + return -1;
  10155. + }
  10156. +
  10157. + /* Update TSC counters for RX now that the packet verification has
  10158. + * completed. */
  10159. + tkey->rx_iv32 = tkey->rx_iv32_new;
  10160. + tkey->rx_iv16 = tkey->rx_iv16_new;
  10161. +
  10162. + skb_trim(skb, skb->len - 8);
  10163. +
  10164. + return 0;
  10165. +}
  10166. +
  10167. +
  10168. +static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
  10169. +{
  10170. + struct ieee80211_tkip_data *tkey = priv;
  10171. + int keyidx;
  10172. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10173. + struct crypto_tfm *tfm = tkey->tfm_michael;
  10174. + struct crypto_tfm *tfm2 = tkey->tfm_arc4;
  10175. + #else
  10176. + struct crypto_hash *tfm = tkey->tx_tfm_michael;
  10177. + struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
  10178. + struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
  10179. + struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
  10180. + #endif
  10181. +
  10182. + keyidx = tkey->key_idx;
  10183. + memset(tkey, 0, sizeof(*tkey));
  10184. + tkey->key_idx = keyidx;
  10185. +
  10186. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10187. + tkey->tfm_michael = tfm;
  10188. + tkey->tfm_arc4 = tfm2;
  10189. + #else
  10190. + tkey->tx_tfm_michael = tfm;
  10191. + tkey->tx_tfm_arc4 = tfm2;
  10192. + tkey->rx_tfm_michael = tfm3;
  10193. + tkey->rx_tfm_arc4 = tfm4;
  10194. + #endif
  10195. +
  10196. + if (len == TKIP_KEY_LEN) {
  10197. + memcpy(tkey->key, key, TKIP_KEY_LEN);
  10198. + tkey->key_set = 1;
  10199. + tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
  10200. + if (seq) {
  10201. + tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
  10202. + (seq[3] << 8) | seq[2];
  10203. + tkey->rx_iv16 = (seq[1] << 8) | seq[0];
  10204. + }
  10205. + } else if (len == 0)
  10206. + tkey->key_set = 0;
  10207. + else
  10208. + return -1;
  10209. +
  10210. + return 0;
  10211. +}
  10212. +
  10213. +
  10214. +static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
  10215. +{
  10216. + struct ieee80211_tkip_data *tkey = priv;
  10217. +
  10218. + if (len < TKIP_KEY_LEN)
  10219. + return -1;
  10220. +
  10221. + if (!tkey->key_set)
  10222. + return 0;
  10223. + memcpy(key, tkey->key, TKIP_KEY_LEN);
  10224. +
  10225. + if (seq) {
  10226. + /* Return the sequence number of the last transmitted frame. */
  10227. + u16 iv16 = tkey->tx_iv16;
  10228. + u32 iv32 = tkey->tx_iv32;
  10229. + if (iv16 == 0)
  10230. + iv32--;
  10231. + iv16--;
  10232. + seq[0] = tkey->tx_iv16;
  10233. + seq[1] = tkey->tx_iv16 >> 8;
  10234. + seq[2] = tkey->tx_iv32;
  10235. + seq[3] = tkey->tx_iv32 >> 8;
  10236. + seq[4] = tkey->tx_iv32 >> 16;
  10237. + seq[5] = tkey->tx_iv32 >> 24;
  10238. + }
  10239. +
  10240. + return TKIP_KEY_LEN;
  10241. +}
  10242. +
  10243. +
  10244. +static char * ieee80211_tkip_print_stats(char *p, void *priv)
  10245. +{
  10246. + struct ieee80211_tkip_data *tkip = priv;
  10247. + p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
  10248. + "tx_pn=%02x%02x%02x%02x%02x%02x "
  10249. + "rx_pn=%02x%02x%02x%02x%02x%02x "
  10250. + "replays=%d icv_errors=%d local_mic_failures=%d\n",
  10251. + tkip->key_idx, tkip->key_set,
  10252. + (tkip->tx_iv32 >> 24) & 0xff,
  10253. + (tkip->tx_iv32 >> 16) & 0xff,
  10254. + (tkip->tx_iv32 >> 8) & 0xff,
  10255. + tkip->tx_iv32 & 0xff,
  10256. + (tkip->tx_iv16 >> 8) & 0xff,
  10257. + tkip->tx_iv16 & 0xff,
  10258. + (tkip->rx_iv32 >> 24) & 0xff,
  10259. + (tkip->rx_iv32 >> 16) & 0xff,
  10260. + (tkip->rx_iv32 >> 8) & 0xff,
  10261. + tkip->rx_iv32 & 0xff,
  10262. + (tkip->rx_iv16 >> 8) & 0xff,
  10263. + tkip->rx_iv16 & 0xff,
  10264. + tkip->dot11RSNAStatsTKIPReplays,
  10265. + tkip->dot11RSNAStatsTKIPICVErrors,
  10266. + tkip->dot11RSNAStatsTKIPLocalMICFailures);
  10267. + return p;
  10268. +}
  10269. +
  10270. +
  10271. +static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
  10272. + .name = "TKIP",
  10273. + .init = ieee80211_tkip_init,
  10274. + .deinit = ieee80211_tkip_deinit,
  10275. + .encrypt_mpdu = ieee80211_tkip_encrypt,
  10276. + .decrypt_mpdu = ieee80211_tkip_decrypt,
  10277. + .encrypt_msdu = ieee80211_michael_mic_add,
  10278. + .decrypt_msdu = ieee80211_michael_mic_verify,
  10279. + .set_key = ieee80211_tkip_set_key,
  10280. + .get_key = ieee80211_tkip_get_key,
  10281. + .print_stats = ieee80211_tkip_print_stats,
  10282. + .extra_prefix_len = 4 + 4, /* IV + ExtIV */
  10283. + .extra_postfix_len = 8 + 4, /* MIC + ICV */
  10284. + .owner = THIS_MODULE,
  10285. +};
  10286. +
  10287. +
  10288. +int __init ieee80211_crypto_tkip_init(void)
  10289. +{
  10290. + return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
  10291. +}
  10292. +
  10293. +
  10294. +void __exit ieee80211_crypto_tkip_exit(void)
  10295. +{
  10296. + ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
  10297. +}
  10298. +
  10299. +
  10300. +void ieee80211_tkip_null(void)
  10301. +{
  10302. +// printk("============>%s()\n", __FUNCTION__);
  10303. + return;
  10304. +}
  10305. +
  10306. +#if 0
  10307. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  10308. +EXPORT_SYMBOL(ieee80211_tkip_null);
  10309. +#else
  10310. +EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
  10311. +#endif
  10312. +
  10313. +
  10314. +module_init(ieee80211_crypto_tkip_init);
  10315. +module_exit(ieee80211_crypto_tkip_exit);
  10316. +#endif
  10317. 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
  10318. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 1970-01-01 01:00:00.000000000 +0100
  10319. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_crypt_wep.c 2010-05-27 18:12:39.532222207 +0200
  10320. @@ -0,0 +1,383 @@
  10321. +/*
  10322. + * Host AP crypt: host-based WEP encryption implementation for Host AP driver
  10323. + *
  10324. + * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
  10325. + *
  10326. + * This program is free software; you can redistribute it and/or modify
  10327. + * it under the terms of the GNU General Public License version 2 as
  10328. + * published by the Free Software Foundation. See README and COPYING for
  10329. + * more details.
  10330. + */
  10331. +
  10332. +//#include <linux/config.h>
  10333. +#include <linux/version.h>
  10334. +#include <linux/module.h>
  10335. +#include <linux/init.h>
  10336. +#include <linux/slab.h>
  10337. +#include <linux/random.h>
  10338. +#include <linux/skbuff.h>
  10339. +#include <asm/string.h>
  10340. +
  10341. +#include "ieee80211.h"
  10342. +
  10343. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  10344. +#include "rtl_crypto.h"
  10345. +#else
  10346. +#include <linux/crypto.h>
  10347. +#endif
  10348. +
  10349. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  10350. + #include <asm/scatterlist.h>
  10351. +#else
  10352. + #include <linux/scatterlist.h>
  10353. +#endif
  10354. +//#include <asm/scatterlist.h>
  10355. +#include <linux/crc32.h>
  10356. +
  10357. +MODULE_AUTHOR("Jouni Malinen");
  10358. +MODULE_DESCRIPTION("Host AP crypt: WEP");
  10359. +MODULE_LICENSE("GPL");
  10360. +
  10361. +
  10362. +struct prism2_wep_data {
  10363. + u32 iv;
  10364. +#define WEP_KEY_LEN 13
  10365. + u8 key[WEP_KEY_LEN + 1];
  10366. + u8 key_len;
  10367. + u8 key_idx;
  10368. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10369. + struct crypto_tfm *tfm;
  10370. + #else
  10371. + struct crypto_blkcipher *tx_tfm;
  10372. + struct crypto_blkcipher *rx_tfm;
  10373. + #endif
  10374. +};
  10375. +
  10376. +
  10377. +static void * prism2_wep_init(int keyidx)
  10378. +{
  10379. + struct prism2_wep_data *priv;
  10380. +
  10381. + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
  10382. + if (priv == NULL)
  10383. + goto fail;
  10384. + memset(priv, 0, sizeof(*priv));
  10385. + priv->key_idx = keyidx;
  10386. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10387. + priv->tfm = crypto_alloc_tfm("arc4", 0);
  10388. + if (priv->tfm == NULL) {
  10389. + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
  10390. + "crypto API arc4\n");
  10391. + goto fail;
  10392. + }
  10393. + #else
  10394. + priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
  10395. + if (IS_ERR(priv->tx_tfm)) {
  10396. + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
  10397. + "crypto API arc4\n");
  10398. + priv->tx_tfm = NULL;
  10399. + goto fail;
  10400. + }
  10401. + priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
  10402. + if (IS_ERR(priv->rx_tfm)) {
  10403. + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
  10404. + "crypto API arc4\n");
  10405. + priv->rx_tfm = NULL;
  10406. + goto fail;
  10407. + }
  10408. + #endif
  10409. +
  10410. + /* start WEP IV from a random value */
  10411. + get_random_bytes(&priv->iv, 4);
  10412. +
  10413. + return priv;
  10414. +
  10415. +fail:
  10416. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10417. + if (priv) {
  10418. + if (priv->tfm)
  10419. + crypto_free_tfm(priv->tfm);
  10420. + kfree(priv);
  10421. + }
  10422. + #else
  10423. + if (priv) {
  10424. + if (priv->tx_tfm)
  10425. + crypto_free_blkcipher(priv->tx_tfm);
  10426. + if (priv->rx_tfm)
  10427. + crypto_free_blkcipher(priv->rx_tfm);
  10428. + kfree(priv);
  10429. + }
  10430. + #endif
  10431. + return NULL;
  10432. +}
  10433. +
  10434. +
  10435. +static void prism2_wep_deinit(void *priv)
  10436. +{
  10437. + struct prism2_wep_data *_priv = priv;
  10438. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10439. + if (_priv && _priv->tfm)
  10440. + crypto_free_tfm(_priv->tfm);
  10441. + #else
  10442. + if (_priv) {
  10443. + if (_priv->tx_tfm)
  10444. + crypto_free_blkcipher(_priv->tx_tfm);
  10445. + if (_priv->rx_tfm)
  10446. + crypto_free_blkcipher(_priv->rx_tfm);
  10447. + }
  10448. + #endif
  10449. + kfree(priv);
  10450. +}
  10451. +
  10452. +
  10453. +/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
  10454. + * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
  10455. + * so the payload length increases with 8 bytes.
  10456. + *
  10457. + * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
  10458. + */
  10459. +static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
  10460. +{
  10461. + struct prism2_wep_data *wep = priv;
  10462. +#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  10463. + struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
  10464. +#endif
  10465. + u32 klen, len;
  10466. + u8 key[WEP_KEY_LEN + 3];
  10467. + u8 *pos;
  10468. +#ifndef JOHN_HWSEC
  10469. + u32 crc;
  10470. + u8 *icv;
  10471. + struct scatterlist sg;
  10472. +#endif
  10473. + if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
  10474. + skb->len < hdr_len)
  10475. + return -1;
  10476. +
  10477. + len = skb->len - hdr_len;
  10478. + pos = skb_push(skb, 4);
  10479. + memmove(pos, pos + 4, hdr_len);
  10480. + pos += hdr_len;
  10481. +
  10482. + klen = 3 + wep->key_len;
  10483. +
  10484. + wep->iv++;
  10485. +
  10486. + /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
  10487. + * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
  10488. + * can be used to speedup attacks, so avoid using them. */
  10489. + if ((wep->iv & 0xff00) == 0xff00) {
  10490. + u8 B = (wep->iv >> 16) & 0xff;
  10491. + if (B >= 3 && B < klen)
  10492. + wep->iv += 0x0100;
  10493. + }
  10494. +
  10495. + /* Prepend 24-bit IV to RC4 key and TX frame */
  10496. + *pos++ = key[0] = (wep->iv >> 16) & 0xff;
  10497. + *pos++ = key[1] = (wep->iv >> 8) & 0xff;
  10498. + *pos++ = key[2] = wep->iv & 0xff;
  10499. + *pos++ = wep->key_idx << 6;
  10500. +
  10501. + /* Copy rest of the WEP key (the secret part) */
  10502. + memcpy(key + 3, wep->key, wep->key_len);
  10503. +
  10504. +#ifndef JOHN_HWSEC
  10505. + /* Append little-endian CRC32 and encrypt it to produce ICV */
  10506. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  10507. + crc = ~crc32_le(~0, pos, len);
  10508. +#else
  10509. + crc = ~ether_crc_le(len, pos);
  10510. +#endif
  10511. + icv = skb_put(skb, 4);
  10512. + icv[0] = crc;
  10513. + icv[1] = crc >> 8;
  10514. + icv[2] = crc >> 16;
  10515. + icv[3] = crc >> 24;
  10516. +
  10517. + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10518. + crypto_cipher_setkey(wep->tfm, key, klen);
  10519. + sg.page = virt_to_page(pos);
  10520. + sg.offset = offset_in_page(pos);
  10521. + sg.length = len + 4;
  10522. + crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
  10523. +
  10524. + return 0;
  10525. + #else
  10526. + crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
  10527. + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
  10528. + sg.page = virt_to_page(pos);
  10529. + sg.offset = offset_in_page(pos);
  10530. + sg.length = len + 4;
  10531. + #else
  10532. + sg_init_one(&sg, pos, len + 4);
  10533. + #endif
  10534. + return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
  10535. + #endif
  10536. +#endif /* JOHN_HWSEC */
  10537. + return 0;
  10538. +}
  10539. +
  10540. +
  10541. +/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
  10542. + * the frame: IV (4 bytes), encrypted payload (including SNAP header),
  10543. + * ICV (4 bytes). len includes both IV and ICV.
  10544. + *
  10545. + * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
  10546. + * failure. If frame is OK, IV and ICV will be removed.
  10547. + */
  10548. +static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
  10549. +{
  10550. + struct prism2_wep_data *wep = priv;
  10551. + #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
  10552. + struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
  10553. + #endif
  10554. + u32 klen, plen;
  10555. + u8 key[WEP_KEY_LEN + 3];
  10556. + u8 keyidx, *pos;
  10557. +#ifndef JOHN_HWSEC
  10558. + u32 crc;
  10559. + u8 icv[4];
  10560. + struct scatterlist sg;
  10561. +#endif
  10562. + if (skb->len < hdr_len + 8)
  10563. + return -1;
  10564. +
  10565. + pos = skb->data + hdr_len;
  10566. + key[0] = *pos++;
  10567. + key[1] = *pos++;
  10568. + key[2] = *pos++;
  10569. + keyidx = *pos++ >> 6;
  10570. + if (keyidx != wep->key_idx)
  10571. + return -1;
  10572. +
  10573. + klen = 3 + wep->key_len;
  10574. +
  10575. + /* Copy rest of the WEP key (the secret part) */
  10576. + memcpy(key + 3, wep->key, wep->key_len);
  10577. +
  10578. + /* Apply RC4 to data and compute CRC32 over decrypted data */
  10579. + plen = skb->len - hdr_len - 8;
  10580. +#ifndef JOHN_HWSEC
  10581. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
  10582. + crypto_cipher_setkey(wep->tfm, key, klen);
  10583. + sg.page = virt_to_page(pos);
  10584. + sg.offset = offset_in_page(pos);
  10585. + sg.length = plen + 4;
  10586. + crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
  10587. +#else
  10588. + crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
  10589. + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  10590. + sg.page = virt_to_page(pos);
  10591. + sg.offset = offset_in_page(pos);
  10592. + sg.length = plen + 4;
  10593. + #else
  10594. + sg_init_one(&sg, pos, plen + 4);
  10595. + #endif
  10596. + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
  10597. + return -7;
  10598. +#endif
  10599. +
  10600. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  10601. + crc = ~crc32_le(~0, pos, plen);
  10602. +#else
  10603. + crc = ~ether_crc_le(plen, pos);
  10604. +#endif
  10605. + icv[0] = crc;
  10606. + icv[1] = crc >> 8;
  10607. + icv[2] = crc >> 16;
  10608. + icv[3] = crc >> 24;
  10609. +
  10610. + if (memcmp(icv, pos + plen, 4) != 0) {
  10611. + /* ICV mismatch - drop frame */
  10612. + return -2;
  10613. + }
  10614. +#endif /* JOHN_HWSEC */
  10615. +
  10616. + /* Remove IV and ICV */
  10617. + memmove(skb->data + 4, skb->data, hdr_len);
  10618. + skb_pull(skb, 4);
  10619. + skb_trim(skb, skb->len - 4);
  10620. + return 0;
  10621. +}
  10622. +
  10623. +
  10624. +static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
  10625. +{
  10626. + struct prism2_wep_data *wep = priv;
  10627. +
  10628. + if (len < 0 || len > WEP_KEY_LEN)
  10629. + return -1;
  10630. +
  10631. + memcpy(wep->key, key, len);
  10632. + wep->key_len = len;
  10633. +
  10634. + return 0;
  10635. +}
  10636. +
  10637. +
  10638. +static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
  10639. +{
  10640. + struct prism2_wep_data *wep = priv;
  10641. +
  10642. + if (len < wep->key_len)
  10643. + return -1;
  10644. +
  10645. + memcpy(key, wep->key, wep->key_len);
  10646. +
  10647. + return wep->key_len;
  10648. +}
  10649. +
  10650. +
  10651. +static char * prism2_wep_print_stats(char *p, void *priv)
  10652. +{
  10653. + struct prism2_wep_data *wep = priv;
  10654. + p += sprintf(p, "key[%d] alg=WEP len=%d\n",
  10655. + wep->key_idx, wep->key_len);
  10656. + return p;
  10657. +}
  10658. +
  10659. +
  10660. +static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
  10661. + .name = "WEP",
  10662. + .init = prism2_wep_init,
  10663. + .deinit = prism2_wep_deinit,
  10664. + .encrypt_mpdu = prism2_wep_encrypt,
  10665. + .decrypt_mpdu = prism2_wep_decrypt,
  10666. + .encrypt_msdu = NULL,
  10667. + .decrypt_msdu = NULL,
  10668. + .set_key = prism2_wep_set_key,
  10669. + .get_key = prism2_wep_get_key,
  10670. + .print_stats = prism2_wep_print_stats,
  10671. + .extra_prefix_len = 4, /* IV */
  10672. + .extra_postfix_len = 4, /* ICV */
  10673. + .owner = THIS_MODULE,
  10674. +};
  10675. +
  10676. +
  10677. +int __init ieee80211_crypto_wep_init(void)
  10678. +{
  10679. + return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
  10680. +}
  10681. +
  10682. +
  10683. +void __exit ieee80211_crypto_wep_exit(void)
  10684. +{
  10685. + ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
  10686. +}
  10687. +
  10688. +
  10689. +void ieee80211_wep_null(void)
  10690. +{
  10691. +// printk("============>%s()\n", __FUNCTION__);
  10692. + return;
  10693. +}
  10694. +#if 0
  10695. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  10696. +EXPORT_SYMBOL(ieee80211_wep_null);
  10697. +#else
  10698. +EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
  10699. +#endif
  10700. +
  10701. +module_init(ieee80211_crypto_wep_init);
  10702. +module_exit(ieee80211_crypto_wep_exit);
  10703. +#endif
  10704. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h
  10705. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 1970-01-01 01:00:00.000000000 +0100
  10706. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211.h 2010-05-27 18:12:39.532222207 +0200
  10707. @@ -0,0 +1,1903 @@
  10708. +/*
  10709. + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
  10710. + * remains copyright by the original authors
  10711. + *
  10712. + * Portions of the merged code are based on Host AP (software wireless
  10713. + * LAN access point) driver for Intersil Prism2/2.5/3.
  10714. + *
  10715. + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  10716. + * <jkmaline@cc.hut.fi>
  10717. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  10718. + *
  10719. + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
  10720. + * <jketreno@linux.intel.com>
  10721. + * Copyright (c) 2004, Intel Corporation
  10722. + *
  10723. + * Modified for Realtek's wi-fi cards by Andrea Merello
  10724. + * <andreamrl@tiscali.it>
  10725. + *
  10726. + * This program is free software; you can redistribute it and/or modify
  10727. + * it under the terms of the GNU General Public License version 2 as
  10728. + * published by the Free Software Foundation. See README and COPYING for
  10729. + * more details.
  10730. + */
  10731. +#ifndef IEEE80211_H
  10732. +#define IEEE80211_H
  10733. +#include <linux/if_ether.h> /* ETH_ALEN */
  10734. +#include <linux/kernel.h> /* ARRAY_SIZE */
  10735. +#include <linux/version.h>
  10736. +#include <linux/module.h>
  10737. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  10738. +#include <linux/jiffies.h>
  10739. +#else
  10740. +#include <linux/jffs.h>
  10741. +#include <linux/tqueue.h>
  10742. +#endif
  10743. +#include <linux/timer.h>
  10744. +#include <linux/sched.h>
  10745. +
  10746. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
  10747. +#include <linux/wireless.h>
  10748. +#endif
  10749. +/*
  10750. +#ifndef bool
  10751. +#define bool int
  10752. +#endif
  10753. +
  10754. +#ifndef true
  10755. +#define true 1
  10756. +#endif
  10757. +
  10758. +#ifndef false
  10759. +#define false 0
  10760. +#endif
  10761. +*/
  10762. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
  10763. +#ifndef bool
  10764. +typedef enum{false = 0, true} bool;
  10765. +#endif
  10766. +#endif
  10767. +//#ifdef JOHN_HWSEC
  10768. +#define KEY_TYPE_NA 0x0
  10769. +#define KEY_TYPE_WEP40 0x1
  10770. +#define KEY_TYPE_TKIP 0x2
  10771. +#define KEY_TYPE_CCMP 0x4
  10772. +#define KEY_TYPE_WEP104 0x5
  10773. +//#endif
  10774. +
  10775. +
  10776. +#define aSifsTime 10
  10777. +
  10778. +#define MGMT_QUEUE_NUM 5
  10779. +
  10780. +
  10781. +#define IEEE_CMD_SET_WPA_PARAM 1
  10782. +#define IEEE_CMD_SET_WPA_IE 2
  10783. +#define IEEE_CMD_SET_ENCRYPTION 3
  10784. +#define IEEE_CMD_MLME 4
  10785. +
  10786. +#define IEEE_PARAM_WPA_ENABLED 1
  10787. +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
  10788. +#define IEEE_PARAM_DROP_UNENCRYPTED 3
  10789. +#define IEEE_PARAM_PRIVACY_INVOKED 4
  10790. +#define IEEE_PARAM_AUTH_ALGS 5
  10791. +#define IEEE_PARAM_IEEE_802_1X 6
  10792. +//It should consistent with the driver_XXX.c
  10793. +// David, 2006.9.26
  10794. +#define IEEE_PARAM_WPAX_SELECT 7
  10795. +//Added for notify the encryption type selection
  10796. +// David, 2006.9.26
  10797. +#define IEEE_PROTO_WPA 1
  10798. +#define IEEE_PROTO_RSN 2
  10799. +//Added for notify the encryption type selection
  10800. +// David, 2006.9.26
  10801. +#define IEEE_WPAX_USEGROUP 0
  10802. +#define IEEE_WPAX_WEP40 1
  10803. +#define IEEE_WPAX_TKIP 2
  10804. +#define IEEE_WPAX_WRAP 3
  10805. +#define IEEE_WPAX_CCMP 4
  10806. +#define IEEE_WPAX_WEP104 5
  10807. +
  10808. +#define IEEE_KEY_MGMT_IEEE8021X 1
  10809. +#define IEEE_KEY_MGMT_PSK 2
  10810. +
  10811. +
  10812. +
  10813. +#define IEEE_MLME_STA_DEAUTH 1
  10814. +#define IEEE_MLME_STA_DISASSOC 2
  10815. +
  10816. +
  10817. +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
  10818. +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
  10819. +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
  10820. +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
  10821. +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
  10822. +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
  10823. +
  10824. +
  10825. +#define IEEE_CRYPT_ALG_NAME_LEN 16
  10826. +
  10827. +//#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
  10828. +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
  10829. +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
  10830. +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
  10831. +////////////////////////////////
  10832. +// added for kernel conflict under FC5
  10833. +#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
  10834. +#define free_ieee80211 free_ieee80211_rtl
  10835. +#define alloc_ieee80211 alloc_ieee80211_rtl
  10836. +///////////////////////////////
  10837. +//#endif
  10838. +#define ieee80211_rx ieee80211_rx_rtl
  10839. +#define ieee80211_wake_queue ieee80211_wake_queue_rtl
  10840. +#define ieee80211_stop_queue ieee80211_stop_queue_rtl
  10841. +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
  10842. +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
  10843. +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
  10844. +
  10845. +#define ieee80211_start_scan ieee80211_start_scan_rtl
  10846. +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
  10847. +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
  10848. +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
  10849. +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
  10850. +typedef struct ieee_param {
  10851. + u32 cmd;
  10852. + u8 sta_addr[ETH_ALEN];
  10853. + union {
  10854. + struct {
  10855. + u8 name;
  10856. + u32 value;
  10857. + } wpa_param;
  10858. + struct {
  10859. + u32 len;
  10860. + u8 reserved[32];
  10861. + u8 data[0];
  10862. + } wpa_ie;
  10863. + struct{
  10864. + int command;
  10865. + int reason_code;
  10866. + } mlme;
  10867. + struct {
  10868. + u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
  10869. + u8 set_tx;
  10870. + u32 err;
  10871. + u8 idx;
  10872. + u8 seq[8]; /* sequence counter (set: RX, get: TX) */
  10873. + u16 key_len;
  10874. + u8 key[0];
  10875. + } crypt;
  10876. +
  10877. + } u;
  10878. +}ieee_param;
  10879. +
  10880. +
  10881. +#if WIRELESS_EXT < 17
  10882. +#define IW_QUAL_QUAL_INVALID 0x10
  10883. +#define IW_QUAL_LEVEL_INVALID 0x20
  10884. +#define IW_QUAL_NOISE_INVALID 0x40
  10885. +#define IW_QUAL_QUAL_UPDATED 0x1
  10886. +#define IW_QUAL_LEVEL_UPDATED 0x2
  10887. +#define IW_QUAL_NOISE_UPDATED 0x4
  10888. +#endif
  10889. +
  10890. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  10891. +static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
  10892. +{
  10893. + task->routine = func;
  10894. + task->data = data;
  10895. + //task->next = NULL;
  10896. + INIT_LIST_HEAD(&task->list);
  10897. + task->sync = 0;
  10898. +}
  10899. +#endif
  10900. +
  10901. +// linux under 2.6.9 release may not support it, so modify it for common use
  10902. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
  10903. +//#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
  10904. +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
  10905. +static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
  10906. +{
  10907. + unsigned long timeout = MSECS(msecs) + 1;
  10908. +
  10909. + while (timeout) {
  10910. + set_current_state(TASK_UNINTERRUPTIBLE);
  10911. + timeout = schedule_timeout(timeout);
  10912. + }
  10913. + return timeout;
  10914. +}
  10915. +#else
  10916. +#define MSECS(t) msecs_to_jiffies(t)
  10917. +#define msleep_interruptible_rtl msleep_interruptible
  10918. +#endif
  10919. +
  10920. +#define IEEE80211_DATA_LEN 2304
  10921. +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
  10922. + 6.2.1.1.2.
  10923. +
  10924. + The figure in section 7.1.2 suggests a body size of up to 2312
  10925. + bytes is allowed, which is a bit confusing, I suspect this
  10926. + represents the 2304 bytes of real data, plus a possible 8 bytes of
  10927. + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
  10928. +
  10929. +
  10930. +#define IEEE80211_HLEN 30
  10931. +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
  10932. +
  10933. +/* this is stolen and modified from the madwifi driver*/
  10934. +#define IEEE80211_FC0_TYPE_MASK 0x0c
  10935. +#define IEEE80211_FC0_TYPE_DATA 0x08
  10936. +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
  10937. +#define IEEE80211_FC0_SUBTYPE_QOS 0x80
  10938. +
  10939. +#define IEEE80211_QOS_HAS_SEQ(fc) \
  10940. + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
  10941. + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
  10942. +
  10943. +/* this is stolen from ipw2200 driver */
  10944. +#define IEEE_IBSS_MAC_HASH_SIZE 31
  10945. +#define IEEE_MESH_MAC_HASH_SIZE 31
  10946. +struct ieee_ibss_seq {
  10947. + u8 mac[ETH_ALEN];
  10948. + u16 seq_num[17];
  10949. + u16 frag_num[17];
  10950. + unsigned long packet_time[17];
  10951. + struct list_head list;
  10952. +};
  10953. +
  10954. +struct ieee_mesh_seq {
  10955. + u8 mac[ETH_ALEN];
  10956. + u16 seq_num;
  10957. + u16 frag_num;
  10958. + unsigned long packet_time;
  10959. + struct list_head list;
  10960. +};
  10961. +
  10962. +struct ieee80211_hdr {
  10963. + u16 frame_ctl;
  10964. + u16 duration_id;
  10965. + u8 addr1[ETH_ALEN];
  10966. + u8 addr2[ETH_ALEN];
  10967. + u8 addr3[ETH_ALEN];
  10968. + u16 seq_ctl;
  10969. + u8 addr4[ETH_ALEN];
  10970. +} __attribute__ ((packed));
  10971. +
  10972. +struct ieee80211_hdr_QOS {
  10973. + u16 frame_ctl;
  10974. + u16 duration_id;
  10975. + u8 addr1[ETH_ALEN];
  10976. + u8 addr2[ETH_ALEN];
  10977. + u8 addr3[ETH_ALEN];
  10978. + u16 seq_ctl;
  10979. + u8 addr4[ETH_ALEN];
  10980. + u16 QOS_ctl;
  10981. +} __attribute__ ((packed));
  10982. +
  10983. +struct ieee80211_hdr_3addr {
  10984. + u16 frame_ctl;
  10985. + u16 duration_id;
  10986. + u8 addr1[ETH_ALEN];
  10987. + u8 addr2[ETH_ALEN];
  10988. + u8 addr3[ETH_ALEN];
  10989. + u16 seq_ctl;
  10990. +} __attribute__ ((packed));
  10991. +
  10992. +struct ieee80211_hdr_3addr_QOS {
  10993. + u16 frame_ctl;
  10994. + u16 duration_id;
  10995. + u8 addr1[ETH_ALEN];
  10996. + u8 addr2[ETH_ALEN];
  10997. + u8 addr3[ETH_ALEN];
  10998. + u16 seq_ctl;
  10999. + u16 QOS_ctl;
  11000. +} __attribute__ ((packed));
  11001. +
  11002. +enum eap_type {
  11003. + EAP_PACKET = 0,
  11004. + EAPOL_START,
  11005. + EAPOL_LOGOFF,
  11006. + EAPOL_KEY,
  11007. + EAPOL_ENCAP_ASF_ALERT
  11008. +};
  11009. +
  11010. +//by lizhaoming for LED 2008.6.23 from r8187_led.h
  11011. +#ifdef LED
  11012. +typedef enum _LED_CTL_MODE {
  11013. + LED_CTL_POWER_ON,
  11014. + LED_CTL_POWER_OFF,
  11015. + LED_CTL_LINK,
  11016. + LED_CTL_NO_LINK,
  11017. + LED_CTL_TX,
  11018. + LED_CTL_RX,
  11019. + LED_CTL_SITE_SURVEY,
  11020. +} LED_CTL_MODE;
  11021. +#endif
  11022. +
  11023. +static const char *eap_types[] = {
  11024. + [EAP_PACKET] = "EAP-Packet",
  11025. + [EAPOL_START] = "EAPOL-Start",
  11026. + [EAPOL_LOGOFF] = "EAPOL-Logoff",
  11027. + [EAPOL_KEY] = "EAPOL-Key",
  11028. + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
  11029. +};
  11030. +
  11031. +static inline const char *eap_get_type(int type)
  11032. +{
  11033. + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
  11034. +}
  11035. +
  11036. +struct eapol {
  11037. + u8 snap[6];
  11038. + u16 ethertype;
  11039. + u8 version;
  11040. + u8 type;
  11041. + u16 length;
  11042. +} __attribute__ ((packed));
  11043. +
  11044. +#define IEEE80211_3ADDR_LEN 24
  11045. +#define IEEE80211_4ADDR_LEN 30
  11046. +#define IEEE80211_FCS_LEN 4
  11047. +
  11048. +#define MIN_FRAG_THRESHOLD 256U
  11049. +#define MAX_FRAG_THRESHOLD 2346U
  11050. +
  11051. +/* Frame control field constants */
  11052. +#define IEEE80211_FCTL_VERS 0x0002
  11053. +#define IEEE80211_FCTL_FTYPE 0x000c
  11054. +#define IEEE80211_FCTL_STYPE 0x00f0
  11055. +#define IEEE80211_FCTL_TODS 0x0100
  11056. +#define IEEE80211_FCTL_FROMDS 0x0200
  11057. +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
  11058. +#define IEEE80211_FCTL_MOREFRAGS 0x0400
  11059. +#define IEEE80211_FCTL_RETRY 0x0800
  11060. +#define IEEE80211_FCTL_PM 0x1000
  11061. +#define IEEE80211_FCTL_MOREDATA 0x2000
  11062. +#define IEEE80211_FCTL_WEP 0x4000
  11063. +#define IEEE80211_FCTL_ORDER 0x8000
  11064. +
  11065. +#define IEEE80211_FTYPE_MGMT 0x0000
  11066. +#define IEEE80211_FTYPE_CTL 0x0004
  11067. +#define IEEE80211_FTYPE_DATA 0x0008
  11068. +
  11069. +/* management */
  11070. +#define IEEE80211_STYPE_ASSOC_REQ 0x0000
  11071. +#define IEEE80211_STYPE_ASSOC_RESP 0x0010
  11072. +#define IEEE80211_STYPE_REASSOC_REQ 0x0020
  11073. +#define IEEE80211_STYPE_REASSOC_RESP 0x0030
  11074. +#define IEEE80211_STYPE_PROBE_REQ 0x0040
  11075. +#define IEEE80211_STYPE_PROBE_RESP 0x0050
  11076. +#define IEEE80211_STYPE_BEACON 0x0080
  11077. +#define IEEE80211_STYPE_ATIM 0x0090
  11078. +#define IEEE80211_STYPE_DISASSOC 0x00A0
  11079. +#define IEEE80211_STYPE_AUTH 0x00B0
  11080. +#define IEEE80211_STYPE_DEAUTH 0x00C0
  11081. +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
  11082. +
  11083. +/* control */
  11084. +#define IEEE80211_STYPE_PSPOLL 0x00A0
  11085. +#define IEEE80211_STYPE_RTS 0x00B0
  11086. +#define IEEE80211_STYPE_CTS 0x00C0
  11087. +#define IEEE80211_STYPE_ACK 0x00D0
  11088. +#define IEEE80211_STYPE_CFEND 0x00E0
  11089. +#define IEEE80211_STYPE_CFENDACK 0x00F0
  11090. +
  11091. +/* data */
  11092. +#define IEEE80211_STYPE_DATA 0x0000
  11093. +#define IEEE80211_STYPE_DATA_CFACK 0x0010
  11094. +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
  11095. +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
  11096. +#define IEEE80211_STYPE_NULLFUNC 0x0040
  11097. +#define IEEE80211_STYPE_CFACK 0x0050
  11098. +#define IEEE80211_STYPE_CFPOLL 0x0060
  11099. +#define IEEE80211_STYPE_CFACKPOLL 0x0070
  11100. +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
  11101. +#define IEEE80211_STYPE_QOS_NULL 0x00C0
  11102. +
  11103. +
  11104. +#define IEEE80211_SCTL_FRAG 0x000F
  11105. +#define IEEE80211_SCTL_SEQ 0xFFF0
  11106. +
  11107. +
  11108. +/* debug macros */
  11109. +
  11110. +#ifdef CONFIG_IEEE80211_DEBUG
  11111. +extern u32 ieee80211_debug_level;
  11112. +#define IEEE80211_DEBUG(level, fmt, args...) \
  11113. +do { if (ieee80211_debug_level & (level)) \
  11114. + printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
  11115. + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
  11116. +#else
  11117. +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
  11118. +#endif /* CONFIG_IEEE80211_DEBUG */
  11119. +
  11120. +/*
  11121. + * To use the debug system;
  11122. + *
  11123. + * If you are defining a new debug classification, simply add it to the #define
  11124. + * list here in the form of:
  11125. + *
  11126. + * #define IEEE80211_DL_xxxx VALUE
  11127. + *
  11128. + * shifting value to the left one bit from the previous entry. xxxx should be
  11129. + * the name of the classification (for example, WEP)
  11130. + *
  11131. + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
  11132. + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
  11133. + * to send output to that classification.
  11134. + *
  11135. + * To add your debug level to the list of levels seen when you perform
  11136. + *
  11137. + * % cat /proc/net/ipw/debug_level
  11138. + *
  11139. + * you simply need to add your entry to the ipw_debug_levels array.
  11140. + *
  11141. + * If you do not see debug_level in /proc/net/ipw then you do not have
  11142. + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
  11143. + *
  11144. + */
  11145. +
  11146. +#define IEEE80211_DL_INFO (1<<0)
  11147. +#define IEEE80211_DL_WX (1<<1)
  11148. +#define IEEE80211_DL_SCAN (1<<2)
  11149. +#define IEEE80211_DL_STATE (1<<3)
  11150. +#define IEEE80211_DL_MGMT (1<<4)
  11151. +#define IEEE80211_DL_FRAG (1<<5)
  11152. +#define IEEE80211_DL_EAP (1<<6)
  11153. +#define IEEE80211_DL_DROP (1<<7)
  11154. +
  11155. +#define IEEE80211_DL_TX (1<<8)
  11156. +#define IEEE80211_DL_RX (1<<9)
  11157. +
  11158. +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
  11159. +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
  11160. +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
  11161. +
  11162. +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
  11163. +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
  11164. +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
  11165. +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
  11166. +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
  11167. +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
  11168. +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
  11169. +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
  11170. +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
  11171. +#include <linux/netdevice.h>
  11172. +#include <linux/wireless.h>
  11173. +#include <linux/if_arp.h> /* ARPHRD_ETHER */
  11174. +
  11175. +#ifndef WIRELESS_SPY
  11176. +#define WIRELESS_SPY // enable iwspy support
  11177. +#endif
  11178. +#include <net/iw_handler.h> // new driver API
  11179. +
  11180. +#ifndef ETH_P_PAE
  11181. +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
  11182. +#endif /* ETH_P_PAE */
  11183. +
  11184. +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
  11185. +
  11186. +#ifndef ETH_P_80211_RAW
  11187. +#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
  11188. +#endif
  11189. +
  11190. +/* IEEE 802.11 defines */
  11191. +
  11192. +#define P80211_OUI_LEN 3
  11193. +
  11194. +struct ieee80211_snap_hdr {
  11195. +
  11196. + u8 dsap; /* always 0xAA */
  11197. + u8 ssap; /* always 0xAA */
  11198. + u8 ctrl; /* always 0x03 */
  11199. + u8 oui[P80211_OUI_LEN]; /* organizational universal id */
  11200. +
  11201. +} __attribute__ ((packed));
  11202. +
  11203. +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
  11204. +
  11205. +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
  11206. +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
  11207. +
  11208. +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
  11209. +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
  11210. +
  11211. +/* Authentication algorithms */
  11212. +#define WLAN_AUTH_OPEN 0
  11213. +#define WLAN_AUTH_SHARED_KEY 1
  11214. +
  11215. +#define WLAN_AUTH_CHALLENGE_LEN 128
  11216. +
  11217. +#define WLAN_CAPABILITY_BSS (1<<0)
  11218. +#define WLAN_CAPABILITY_IBSS (1<<1)
  11219. +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
  11220. +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
  11221. +#define WLAN_CAPABILITY_PRIVACY (1<<4)
  11222. +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
  11223. +#define WLAN_CAPABILITY_PBCC (1<<6)
  11224. +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
  11225. +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
  11226. +
  11227. +/* Status codes */
  11228. +#define WLAN_STATUS_SUCCESS 0
  11229. +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
  11230. +#define WLAN_STATUS_CAPS_UNSUPPORTED 10
  11231. +#define WLAN_STATUS_REASSOC_NO_ASSOC 11
  11232. +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
  11233. +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
  11234. +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
  11235. +#define WLAN_STATUS_CHALLENGE_FAIL 15
  11236. +#define WLAN_STATUS_AUTH_TIMEOUT 16
  11237. +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
  11238. +#define WLAN_STATUS_ASSOC_DENIED_RATES 18
  11239. +/* 802.11b */
  11240. +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
  11241. +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
  11242. +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
  11243. +
  11244. +/* Reason codes */
  11245. +#define WLAN_REASON_UNSPECIFIED 1
  11246. +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
  11247. +#define WLAN_REASON_DEAUTH_LEAVING 3
  11248. +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
  11249. +#define WLAN_REASON_DISASSOC_AP_BUSY 5
  11250. +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
  11251. +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
  11252. +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
  11253. +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
  11254. +
  11255. +
  11256. +/* Information Element IDs */
  11257. +#define WLAN_EID_SSID 0
  11258. +#define WLAN_EID_SUPP_RATES 1
  11259. +#define WLAN_EID_FH_PARAMS 2
  11260. +#define WLAN_EID_DS_PARAMS 3
  11261. +#define WLAN_EID_CF_PARAMS 4
  11262. +#define WLAN_EID_TIM 5
  11263. +#define WLAN_EID_IBSS_PARAMS 6
  11264. +#define WLAN_EID_CHALLENGE 16
  11265. +#define WLAN_EID_RSN 48
  11266. +#define WLAN_EID_GENERIC 221
  11267. +
  11268. +#define IEEE80211_MGMT_HDR_LEN 24
  11269. +#define IEEE80211_DATA_HDR3_LEN 24
  11270. +#define IEEE80211_DATA_HDR4_LEN 30
  11271. +
  11272. +
  11273. +#define IEEE80211_STATMASK_SIGNAL (1<<0)
  11274. +#define IEEE80211_STATMASK_RSSI (1<<1)
  11275. +#define IEEE80211_STATMASK_NOISE (1<<2)
  11276. +#define IEEE80211_STATMASK_RATE (1<<3)
  11277. +#define IEEE80211_STATMASK_WEMASK 0x7
  11278. +
  11279. +
  11280. +#define IEEE80211_CCK_MODULATION (1<<0)
  11281. +#define IEEE80211_OFDM_MODULATION (1<<1)
  11282. +
  11283. +#define IEEE80211_24GHZ_BAND (1<<0)
  11284. +#define IEEE80211_52GHZ_BAND (1<<1)
  11285. +
  11286. +#define IEEE80211_CCK_RATE_LEN 4
  11287. +#define IEEE80211_CCK_RATE_1MB 0x02
  11288. +#define IEEE80211_CCK_RATE_2MB 0x04
  11289. +#define IEEE80211_CCK_RATE_5MB 0x0B
  11290. +#define IEEE80211_CCK_RATE_11MB 0x16
  11291. +#define IEEE80211_OFDM_RATE_LEN 8
  11292. +#define IEEE80211_OFDM_RATE_6MB 0x0C
  11293. +#define IEEE80211_OFDM_RATE_9MB 0x12
  11294. +#define IEEE80211_OFDM_RATE_12MB 0x18
  11295. +#define IEEE80211_OFDM_RATE_18MB 0x24
  11296. +#define IEEE80211_OFDM_RATE_24MB 0x30
  11297. +#define IEEE80211_OFDM_RATE_36MB 0x48
  11298. +#define IEEE80211_OFDM_RATE_48MB 0x60
  11299. +#define IEEE80211_OFDM_RATE_54MB 0x6C
  11300. +#define IEEE80211_BASIC_RATE_MASK 0x80
  11301. +
  11302. +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
  11303. +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
  11304. +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
  11305. +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
  11306. +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
  11307. +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
  11308. +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
  11309. +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
  11310. +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
  11311. +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
  11312. +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
  11313. +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
  11314. +
  11315. +#define IEEE80211_CCK_RATES_MASK 0x0000000F
  11316. +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
  11317. + IEEE80211_CCK_RATE_2MB_MASK)
  11318. +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
  11319. + IEEE80211_CCK_RATE_5MB_MASK | \
  11320. + IEEE80211_CCK_RATE_11MB_MASK)
  11321. +
  11322. +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
  11323. +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
  11324. + IEEE80211_OFDM_RATE_12MB_MASK | \
  11325. + IEEE80211_OFDM_RATE_24MB_MASK)
  11326. +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
  11327. + IEEE80211_OFDM_RATE_9MB_MASK | \
  11328. + IEEE80211_OFDM_RATE_18MB_MASK | \
  11329. + IEEE80211_OFDM_RATE_36MB_MASK | \
  11330. + IEEE80211_OFDM_RATE_48MB_MASK | \
  11331. + IEEE80211_OFDM_RATE_54MB_MASK)
  11332. +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
  11333. + IEEE80211_CCK_DEFAULT_RATES_MASK)
  11334. +
  11335. +#define IEEE80211_NUM_OFDM_RATES 8
  11336. +#define IEEE80211_NUM_CCK_RATES 4
  11337. +#define IEEE80211_OFDM_SHIFT_MASK_A 4
  11338. +
  11339. +
  11340. +
  11341. +
  11342. +/* NOTE: This data is for statistical purposes; not all hardware provides this
  11343. + * information for frames received. Not setting these will not cause
  11344. + * any adverse affects. */
  11345. +struct ieee80211_rx_stats {
  11346. + u32 mac_time[2];
  11347. + u8 signalstrength;
  11348. + s8 rssi;
  11349. + u8 signal;
  11350. + u8 noise;
  11351. + u16 rate; /* in 100 kbps */
  11352. + u8 received_channel;
  11353. + u8 control;
  11354. + u8 mask;
  11355. + u8 freq;
  11356. + u16 len;
  11357. + u8 nic_type;
  11358. +};
  11359. +
  11360. +/* IEEE 802.11 requires that STA supports concurrent reception of at least
  11361. + * three fragmented frames. This define can be increased to support more
  11362. + * concurrent frames, but it should be noted that each entry can consume about
  11363. + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
  11364. +#define IEEE80211_FRAG_CACHE_LEN 4
  11365. +
  11366. +struct ieee80211_frag_entry {
  11367. + unsigned long first_frag_time;
  11368. + unsigned int seq;
  11369. + unsigned int last_frag;
  11370. + struct sk_buff *skb;
  11371. + u8 src_addr[ETH_ALEN];
  11372. + u8 dst_addr[ETH_ALEN];
  11373. +};
  11374. +
  11375. +struct ieee80211_stats {
  11376. + unsigned int tx_unicast_frames;
  11377. + unsigned int tx_multicast_frames;
  11378. + unsigned int tx_fragments;
  11379. + unsigned int tx_unicast_octets;
  11380. + unsigned int tx_multicast_octets;
  11381. + unsigned int tx_deferred_transmissions;
  11382. + unsigned int tx_single_retry_frames;
  11383. + unsigned int tx_multiple_retry_frames;
  11384. + unsigned int tx_retry_limit_exceeded;
  11385. + unsigned int tx_discards;
  11386. + unsigned int rx_unicast_frames;
  11387. + unsigned int rx_multicast_frames;
  11388. + unsigned int rx_fragments;
  11389. + unsigned int rx_unicast_octets;
  11390. + unsigned int rx_multicast_octets;
  11391. + unsigned int rx_fcs_errors;
  11392. + unsigned int rx_discards_no_buffer;
  11393. + unsigned int tx_discards_wrong_sa;
  11394. + unsigned int rx_discards_undecryptable;
  11395. + unsigned int rx_message_in_msg_fragments;
  11396. + unsigned int rx_message_in_bad_msg_fragments;
  11397. +};
  11398. +
  11399. +struct ieee80211_softmac_stats{
  11400. + unsigned int rx_ass_ok;
  11401. + unsigned int rx_ass_err;
  11402. + unsigned int rx_probe_rq;
  11403. + unsigned int tx_probe_rs;
  11404. + unsigned int tx_beacons;
  11405. + unsigned int rx_auth_rq;
  11406. + unsigned int rx_auth_rs_ok;
  11407. + unsigned int rx_auth_rs_err;
  11408. + unsigned int tx_auth_rq;
  11409. + unsigned int no_auth_rs;
  11410. + unsigned int no_ass_rs;
  11411. + unsigned int tx_ass_rq;
  11412. + unsigned int rx_ass_rq;
  11413. + unsigned int tx_probe_rq;
  11414. + unsigned int reassoc;
  11415. + unsigned int swtxstop;
  11416. + unsigned int swtxawake;
  11417. +};
  11418. +
  11419. +struct ieee80211_device;
  11420. +
  11421. +#include "ieee80211_crypt.h"
  11422. +
  11423. +#define SEC_KEY_1 (1<<0)
  11424. +#define SEC_KEY_2 (1<<1)
  11425. +#define SEC_KEY_3 (1<<2)
  11426. +#define SEC_KEY_4 (1<<3)
  11427. +#define SEC_ACTIVE_KEY (1<<4)
  11428. +#define SEC_AUTH_MODE (1<<5)
  11429. +#define SEC_UNICAST_GROUP (1<<6)
  11430. +#define SEC_LEVEL (1<<7)
  11431. +#define SEC_ENABLED (1<<8)
  11432. +
  11433. +#define SEC_LEVEL_0 0 /* None */
  11434. +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
  11435. +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
  11436. +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
  11437. +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
  11438. +
  11439. +#define WEP_KEYS 4
  11440. +#define WEP_KEY_LEN 13
  11441. +#define ALG_KEY_LEN 32
  11442. +
  11443. +#ifdef _RTL8187_EXT_PATCH_
  11444. +#define MAX_MP 16
  11445. +#endif
  11446. +struct ieee80211_security {
  11447. + u16 active_key:2,
  11448. + enabled:1,
  11449. + auth_mode:2,
  11450. + auth_algo:4,
  11451. + unicast_uses_group:1;
  11452. + u8 key_sizes[WEP_KEYS];
  11453. + u8 keys[WEP_KEYS][ALG_KEY_LEN];
  11454. + u8 level;
  11455. + u16 flags;
  11456. +} __attribute__ ((packed));
  11457. +
  11458. +
  11459. +/*
  11460. +
  11461. + 802.11 data frame from AP
  11462. +
  11463. + ,-------------------------------------------------------------------.
  11464. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
  11465. + |------|------|---------|---------|---------|------|---------|------|
  11466. +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
  11467. + | | tion | (BSSID) | | | ence | data | |
  11468. + `-------------------------------------------------------------------'
  11469. +
  11470. +Total: 28-2340 bytes
  11471. +
  11472. +*/
  11473. +
  11474. +struct ieee80211_header_data {
  11475. + u16 frame_ctl;
  11476. + u16 duration_id;
  11477. + u8 addr1[6];
  11478. + u8 addr2[6];
  11479. + u8 addr3[6];
  11480. + u16 seq_ctrl;
  11481. +};
  11482. +
  11483. +#define BEACON_PROBE_SSID_ID_POSITION 12
  11484. +
  11485. +/* Management Frame Information Element Types */
  11486. +#define MFIE_TYPE_SSID 0
  11487. +#define MFIE_TYPE_RATES 1
  11488. +#define MFIE_TYPE_FH_SET 2
  11489. +#define MFIE_TYPE_DS_SET 3
  11490. +#define MFIE_TYPE_CF_SET 4
  11491. +#define MFIE_TYPE_TIM 5
  11492. +#define MFIE_TYPE_IBSS_SET 6
  11493. +#define MFIE_TYPE_COUNTRY 7
  11494. +#define MFIE_TYPE_CHALLENGE 16
  11495. +#define MFIE_TYPE_ERP 42
  11496. +#define MFIE_TYPE_RSN 48
  11497. +#define MFIE_TYPE_RATES_EX 50
  11498. +#define MFIE_TYPE_GENERIC 221
  11499. +
  11500. +#ifdef ENABLE_DOT11D
  11501. +typedef enum
  11502. +{
  11503. + COUNTRY_CODE_FCC = 0,
  11504. + COUNTRY_CODE_IC = 1,
  11505. + COUNTRY_CODE_ETSI = 2,
  11506. + COUNTRY_CODE_SPAIN = 3,
  11507. + COUNTRY_CODE_FRANCE = 4,
  11508. + COUNTRY_CODE_MKK = 5,
  11509. + COUNTRY_CODE_MKK1 = 6,
  11510. + COUNTRY_CODE_ISRAEL = 7,
  11511. + COUNTRY_CODE_TELEC = 8,
  11512. + COUNTRY_CODE_GLOBAL_DOMAIN = 9,
  11513. + COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
  11514. +}country_code_type_t;
  11515. +#endif
  11516. +
  11517. +
  11518. +struct ieee80211_info_element_hdr {
  11519. + u8 id;
  11520. + u8 len;
  11521. +} __attribute__ ((packed));
  11522. +
  11523. +struct ieee80211_info_element {
  11524. + u8 id;
  11525. + u8 len;
  11526. + u8 data[0];
  11527. +} __attribute__ ((packed));
  11528. +
  11529. +/*
  11530. + * These are the data types that can make up management packets
  11531. + *
  11532. + u16 auth_algorithm;
  11533. + u16 auth_sequence;
  11534. + u16 beacon_interval;
  11535. + u16 capability;
  11536. + u8 current_ap[ETH_ALEN];
  11537. + u16 listen_interval;
  11538. + struct {
  11539. + u16 association_id:14, reserved:2;
  11540. + } __attribute__ ((packed));
  11541. + u32 time_stamp[2];
  11542. + u16 reason;
  11543. + u16 status;
  11544. +*/
  11545. +
  11546. +#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
  11547. +#define IEEE80211_DEFAULT_BASIC_RATE 10
  11548. +#define IEEE80211_DEFAULT_MESHID "802.11s"
  11549. +#define IEEE80211_DEFAULT_MESH_CHAN 1
  11550. +
  11551. +struct ieee80211_authentication {
  11552. + struct ieee80211_header_data header;
  11553. + u16 algorithm;
  11554. + u16 transaction;
  11555. + u16 status;
  11556. + //struct ieee80211_info_element_hdr info_element;
  11557. +} __attribute__ ((packed));
  11558. +
  11559. +
  11560. +struct ieee80211_probe_response {
  11561. + struct ieee80211_header_data header;
  11562. + u32 time_stamp[2];
  11563. + u16 beacon_interval;
  11564. + u16 capability;
  11565. + struct ieee80211_info_element info_element;
  11566. +} __attribute__ ((packed));
  11567. +
  11568. +struct ieee80211_probe_request {
  11569. + struct ieee80211_header_data header;
  11570. + /*struct ieee80211_info_element info_element;*/
  11571. +} __attribute__ ((packed));
  11572. +
  11573. +struct ieee80211_assoc_request_frame {
  11574. + struct ieee80211_hdr_3addr header;
  11575. + u16 capability;
  11576. + u16 listen_interval;
  11577. + //u8 current_ap[ETH_ALEN];
  11578. + struct ieee80211_info_element_hdr info_element;
  11579. +} __attribute__ ((packed));
  11580. +
  11581. +struct ieee80211_assoc_response_frame {
  11582. + struct ieee80211_hdr_3addr header;
  11583. + u16 capability;
  11584. + u16 status;
  11585. + u16 aid;
  11586. + struct ieee80211_info_element info_element; /* supported rates */
  11587. +} __attribute__ ((packed));
  11588. +
  11589. +
  11590. +struct ieee80211_txb {
  11591. + u8 nr_frags;
  11592. + u8 encrypted;
  11593. + u16 reserved;
  11594. + u16 frag_size;
  11595. + u16 payload_size;
  11596. + struct sk_buff *fragments[0];
  11597. +};
  11598. +
  11599. +struct ieee80211_wmm_ac_param {
  11600. + u8 ac_aci_acm_aifsn;
  11601. + u8 ac_ecwmin_ecwmax;
  11602. + u16 ac_txop_limit;
  11603. +};
  11604. +
  11605. +struct ieee80211_wmm_ts_info {
  11606. + u8 ac_dir_tid;
  11607. + u8 ac_up_psb;
  11608. + u8 reserved;
  11609. +} __attribute__ ((packed));
  11610. +
  11611. +struct ieee80211_wmm_tspec_elem {
  11612. + struct ieee80211_wmm_ts_info ts_info;
  11613. + u16 norm_msdu_size;
  11614. + u16 max_msdu_size;
  11615. + u32 min_serv_inter;
  11616. + u32 max_serv_inter;
  11617. + u32 inact_inter;
  11618. + u32 suspen_inter;
  11619. + u32 serv_start_time;
  11620. + u32 min_data_rate;
  11621. + u32 mean_data_rate;
  11622. + u32 peak_data_rate;
  11623. + u32 max_burst_size;
  11624. + u32 delay_bound;
  11625. + u32 min_phy_rate;
  11626. + u16 surp_band_allow;
  11627. + u16 medium_time;
  11628. +}__attribute__((packed));
  11629. +
  11630. +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
  11631. +#define MAX_SP_Len (WMM_all_frame << 4)
  11632. +#define IEEE80211_QOS_TID 0x0f
  11633. +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
  11634. +
  11635. +/* SWEEP TABLE ENTRIES NUMBER*/
  11636. +#define MAX_SWEEP_TAB_ENTRIES 42
  11637. +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
  11638. +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
  11639. + * only use 8, and then use extended rates for the remaining supported
  11640. + * rates. Other APs, however, stick all of their supported rates on the
  11641. + * main rates information element... */
  11642. +#define MAX_RATES_LENGTH ((u8)12)
  11643. +#define MAX_RATES_EX_LENGTH ((u8)16)
  11644. +#define MAX_NETWORK_COUNT 128
  11645. +#ifdef ENABLE_DOT11D
  11646. +#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
  11647. +#define MAX_IE_LEN 0xFF //+YJ,080625
  11648. +#else
  11649. +#define MAX_CHANNEL_NUMBER 161
  11650. +#endif
  11651. +
  11652. +//#define IEEE80211_SOFTMAC_SCAN_TIME 400
  11653. +#define IEEE80211_SOFTMAC_SCAN_TIME 100//lzm mod 081209
  11654. +//(HZ / 2)
  11655. +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
  11656. +
  11657. +#define CRC_LENGTH 4U
  11658. +
  11659. +#define MAX_WPA_IE_LEN 64
  11660. +
  11661. +#define NETWORK_EMPTY_ESSID (1<<0)
  11662. +#define NETWORK_HAS_OFDM (1<<1)
  11663. +#define NETWORK_HAS_CCK (1<<2)
  11664. +
  11665. +#define IEEE80211_DTIM_MBCAST 4
  11666. +#define IEEE80211_DTIM_UCAST 2
  11667. +#define IEEE80211_DTIM_VALID 1
  11668. +#define IEEE80211_DTIM_INVALID 0
  11669. +
  11670. +#define IEEE80211_PS_DISABLED 0
  11671. +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
  11672. +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
  11673. +
  11674. +//added by David for QoS 2006/6/30
  11675. +//#define WMM_Hang_8187
  11676. +#ifdef WMM_Hang_8187
  11677. +#undef WMM_Hang_8187
  11678. +#endif
  11679. +
  11680. +#define WME_AC_BE 0x00
  11681. +#define WME_AC_BK 0x01
  11682. +#define WME_AC_VI 0x02
  11683. +#define WME_AC_VO 0x03
  11684. +#define WME_ACI_MASK 0x03
  11685. +#define WME_AIFSN_MASK 0x03
  11686. +#define WME_AC_PRAM_LEN 16
  11687. +
  11688. +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
  11689. +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
  11690. +#define UP2AC(up) ( \
  11691. + ((up) < 1) ? WME_AC_BE : \
  11692. + ((up) < 3) ? WME_AC_BK : \
  11693. + ((up) < 4) ? WME_AC_BE : \
  11694. + ((up) < 6) ? WME_AC_VI : \
  11695. + WME_AC_VO)
  11696. +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
  11697. +#define AC2UP(_ac) ( \
  11698. + ((_ac) == WME_AC_VO) ? 6 : \
  11699. + ((_ac) == WME_AC_VI) ? 5 : \
  11700. + ((_ac) == WME_AC_BK) ? 1 : \
  11701. + 0)
  11702. +
  11703. +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
  11704. +struct ether_header {
  11705. + u8 ether_dhost[ETHER_ADDR_LEN];
  11706. + u8 ether_shost[ETHER_ADDR_LEN];
  11707. + u16 ether_type;
  11708. +} __attribute__((packed));
  11709. +
  11710. +#ifndef ETHERTYPE_PAE
  11711. +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
  11712. +#endif
  11713. +#ifndef ETHERTYPE_IP
  11714. +#define ETHERTYPE_IP 0x0800 /* IP protocol */
  11715. +#endif
  11716. +
  11717. +struct ieee80211_network {
  11718. + /* These entries are used to identify a unique network */
  11719. + u8 bssid[ETH_ALEN];
  11720. + u8 channel;
  11721. + /* Ensure null-terminated for any debug msgs */
  11722. + u8 ssid[IW_ESSID_MAX_SIZE + 1];
  11723. + u8 ssid_len;
  11724. +
  11725. + /* These are network statistics */
  11726. + struct ieee80211_rx_stats stats;
  11727. + u16 capability;
  11728. + u8 rates[MAX_RATES_LENGTH];
  11729. + u8 rates_len;
  11730. + u8 rates_ex[MAX_RATES_EX_LENGTH];
  11731. + u8 rates_ex_len;
  11732. + unsigned long last_scanned;
  11733. + u8 mode;
  11734. + u8 flags;
  11735. + u32 last_associate;
  11736. + u32 time_stamp[2];
  11737. + u16 beacon_interval;
  11738. + u16 listen_interval;
  11739. + u16 atim_window;
  11740. + u8 wpa_ie[MAX_WPA_IE_LEN];
  11741. + size_t wpa_ie_len;
  11742. + u8 rsn_ie[MAX_WPA_IE_LEN];
  11743. + size_t rsn_ie_len;
  11744. + u8 dtim_period;
  11745. + u8 dtim_data;
  11746. + u32 last_dtim_sta_time[2];
  11747. +#ifdef _RTL8187_EXT_PATCH_
  11748. + void *ext_entry;
  11749. +#endif
  11750. + struct list_head list;
  11751. + //appeded for QoS
  11752. + u8 wmm_info;
  11753. + struct ieee80211_wmm_ac_param wmm_param[4];
  11754. + u8 QoS_Enable;
  11755. + u8 SignalStrength;
  11756. +#ifdef THOMAS_TURBO
  11757. + u8 Turbo_Enable;//enable turbo mode, added by thomas
  11758. +#endif
  11759. +
  11760. +#ifdef ENABLE_DOT11D
  11761. + u16 CountryIeLen;
  11762. + u8 CountryIeBuf[MAX_IE_LEN];
  11763. +#endif
  11764. +
  11765. +};
  11766. +
  11767. +enum ieee80211_state {
  11768. +
  11769. + /* the card is not linked at all */
  11770. + IEEE80211_NOLINK = 0,
  11771. +
  11772. + /* IEEE80211_ASSOCIATING* are for BSS client mode
  11773. + * the driver shall not perform RX filtering unless
  11774. + * the state is LINKED.
  11775. + * The driver shall just check for the state LINKED and
  11776. + * defaults to NOLINK for ALL the other states (including
  11777. + * LINKED_SCANNING)
  11778. + */
  11779. +
  11780. + /* the association procedure will start (wq scheduling)*/
  11781. + IEEE80211_ASSOCIATING,
  11782. + IEEE80211_ASSOCIATING_RETRY,
  11783. +
  11784. + /* the association procedure is sending AUTH request*/
  11785. + IEEE80211_ASSOCIATING_AUTHENTICATING,
  11786. +
  11787. + /* the association procedure has successfully authentcated
  11788. + * and is sending association request
  11789. + */
  11790. + IEEE80211_ASSOCIATING_AUTHENTICATED,
  11791. +
  11792. + /* the link is ok. the card associated to a BSS or linked
  11793. + * to a ibss cell or acting as an AP and creating the bss
  11794. + */
  11795. + IEEE80211_LINKED,
  11796. +
  11797. + /* same as LINKED, but the driver shall apply RX filter
  11798. + * rules as we are in NO_LINK mode. As the card is still
  11799. + * logically linked, but it is doing a syncro site survey
  11800. + * then it will be back to LINKED state.
  11801. + */
  11802. + IEEE80211_LINKED_SCANNING,
  11803. +//by amy for mesh
  11804. + IEEE80211_MESH_SCANNING,
  11805. + IEEE80211_MESH_LINKED,
  11806. +//by amy for mesh
  11807. +
  11808. +};
  11809. +
  11810. +#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
  11811. +#define DEFAULT_FTS 2346
  11812. +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
  11813. +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
  11814. +
  11815. +
  11816. +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
  11817. +extern inline int is_multicast_ether_addr(const u8 *addr)
  11818. +{
  11819. + return ((addr[0] != 0xff) && (0x01 & addr[0]));
  11820. +}
  11821. +#endif
  11822. +
  11823. +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
  11824. +extern inline int is_broadcast_ether_addr(const u8 *addr)
  11825. +{
  11826. + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
  11827. + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
  11828. +}
  11829. +#endif
  11830. +
  11831. +#define CFG_IEEE80211_RESERVE_FCS (1<<0)
  11832. +#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
  11833. +
  11834. +typedef struct tx_pending_t{
  11835. + int frag;
  11836. + struct ieee80211_txb *txb;
  11837. +}tx_pending_t;
  11838. +
  11839. +#ifdef _RTL8187_EXT_PATCH_
  11840. +struct ieee80211_crypt_data_list{
  11841. + u8 used;
  11842. + u8 mac_addr[ETH_ALEN]; //record mac_add
  11843. + struct ieee80211_crypt_data *crypt[WEP_KEYS];
  11844. +}__attribute__((packed));
  11845. +
  11846. +#endif
  11847. +
  11848. +struct ieee80211_device {
  11849. + struct net_device *dev;
  11850. +
  11851. + /* Bookkeeping structures */
  11852. + struct net_device_stats stats;
  11853. + struct ieee80211_stats ieee_stats;
  11854. + struct ieee80211_softmac_stats softmac_stats;
  11855. +
  11856. + /* Probe / Beacon management */
  11857. + struct list_head network_free_list;
  11858. + struct list_head network_list;
  11859. + struct ieee80211_network *networks;
  11860. + int scans;
  11861. + int scan_age;
  11862. +
  11863. + int iw_mode; /* operating mode (IW_MODE_*) */
  11864. +#ifdef _RTL8187_EXT_PATCH_
  11865. + int iw_ext_mode; // if iw_mode == iw_ext_mode, do ext_patch_**();
  11866. +#endif
  11867. +
  11868. + spinlock_t lock;
  11869. + spinlock_t wpax_suitlist_lock;
  11870. +
  11871. + int tx_headroom; /* Set to size of any additional room needed at front
  11872. + * of allocated Tx SKBs */
  11873. + u32 config;
  11874. +
  11875. + /* WEP and other encryption related settings at the device level */
  11876. + int open_wep; /* Set to 1 to allow unencrypted frames */
  11877. +
  11878. + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
  11879. + * WEP key changes */
  11880. +
  11881. + /* If the host performs {en,de}cryption, then set to 1 */
  11882. + int host_encrypt;
  11883. + int host_decrypt;
  11884. + int ieee802_1x; /* is IEEE 802.1X used */
  11885. +
  11886. + /* WPA data */
  11887. + int wpa_enabled;
  11888. + int drop_unencrypted;
  11889. + int tkip_countermeasures;
  11890. + int privacy_invoked;
  11891. + size_t wpa_ie_len;
  11892. + u8 *wpa_ie;
  11893. +
  11894. +//#ifdef JOHN_TKIP
  11895. + u8 ap_mac_addr[6];
  11896. + u16 pairwise_key_type;
  11897. + u16 broadcast_key_type;
  11898. +//#endif
  11899. + struct list_head crypt_deinit_list;
  11900. +#ifdef _RTL8187_EXT_PATCH_
  11901. + struct ieee80211_crypt_data_list* cryptlist[MAX_MP];
  11902. +#else
  11903. + struct ieee80211_crypt_data *crypt[WEP_KEYS];
  11904. +#endif
  11905. + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
  11906. + struct timer_list crypt_deinit_timer;
  11907. +
  11908. + int bcrx_sta_key; /* use individual keys to override default keys even
  11909. + * with RX of broad/multicast frames */
  11910. +
  11911. + /* Fragmentation structures */
  11912. + // each streaming contain a entry
  11913. + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
  11914. + unsigned int frag_next_idx[17];
  11915. + u16 fts; /* Fragmentation Threshold */
  11916. +
  11917. + /* This stores infos for the current network.
  11918. + * Either the network we are associated in INFRASTRUCTURE
  11919. + * or the network that we are creating in MASTER mode.
  11920. + * ad-hoc is a mixture ;-).
  11921. + * Note that in infrastructure mode, even when not associated,
  11922. + * fields bssid and essid may be valid (if wpa_set and essid_set
  11923. + * are true) as thy carry the value set by the user via iwconfig
  11924. + */
  11925. + struct ieee80211_network current_network;
  11926. +
  11927. +
  11928. + enum ieee80211_state state;
  11929. +
  11930. + int short_slot;
  11931. + int mode; /* A, B, G */
  11932. + int modulation; /* CCK, OFDM */
  11933. + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
  11934. + int abg_true; /* ABG flag */
  11935. +
  11936. + /* used for forcing the ibss workqueue to terminate
  11937. + * without wait for the syncro scan to terminate
  11938. + */
  11939. + short sync_scan_hurryup;
  11940. +
  11941. +#ifdef ENABLE_DOT11D
  11942. + void * pDot11dInfo;
  11943. + bool bGlobalDomain;
  11944. + bool bWorldWide13;//lzm add 20081205
  11945. +
  11946. + // For Liteon Ch12~13 passive scan
  11947. + u8 MinPassiveChnlNum;
  11948. + u8 IbssStartChnl;
  11949. +#else
  11950. + /* map of allowed channels. 0 is dummy */
  11951. + // FIXME: remeber to default to a basic channel plan depending of the PHY type
  11952. + int channel_map[MAX_CHANNEL_NUMBER+1];
  11953. +#endif
  11954. +
  11955. + int rate; /* current rate */
  11956. + int basic_rate;
  11957. + //FIXME: pleace callback, see if redundant with softmac_features
  11958. + short active_scan;
  11959. +
  11960. +#ifdef _RTL8187_EXT_PATCH_
  11961. +// short ch_lock;
  11962. + short meshScanMode;
  11963. +#endif
  11964. + /* this contains flags for selectively enable softmac support */
  11965. + u16 softmac_features;
  11966. +
  11967. + /* if the sequence control field is not filled by HW */
  11968. + u16 seq_ctrl[5];
  11969. +
  11970. + /* association procedure transaction sequence number */
  11971. + u16 associate_seq;
  11972. +
  11973. + /* AID for RTXed association responses */
  11974. + u16 assoc_id;
  11975. +
  11976. + /* power save mode related*/
  11977. + short ps;
  11978. + short sta_sleep;
  11979. + int ps_timeout;
  11980. + struct tasklet_struct ps_task;
  11981. + u32 ps_th;
  11982. + u32 ps_tl;
  11983. +
  11984. + short raw_tx;
  11985. + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
  11986. + short queue_stop;
  11987. + short scanning;
  11988. + short scan_watchdog;//lzm add 081215 for roaming
  11989. + short proto_started;
  11990. +
  11991. + struct semaphore wx_sem;
  11992. + struct semaphore scan_sem;
  11993. + struct semaphore ips_sem;
  11994. + spinlock_t mgmt_tx_lock;
  11995. + spinlock_t beacon_lock;
  11996. + spinlock_t beaconflag_lock;
  11997. + short beacon_txing;
  11998. +
  11999. + short wap_set;
  12000. + short ssid_set;
  12001. +
  12002. + u8 wpax_type_set; //{added by David, 2006.9.28}
  12003. + u32 wpax_type_notify; //{added by David, 2006.9.26}
  12004. +
  12005. + /* QoS related flag */
  12006. + char init_wmmparam_flag;
  12007. +
  12008. + /* for discarding duplicated packets in IBSS */
  12009. + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
  12010. +
  12011. + /* for discarding duplicated packets in Mesh */ //added by david 2008.2.28/
  12012. + struct list_head mesh_mac_hash[IEEE_MESH_MAC_HASH_SIZE];
  12013. +
  12014. + /* for discarding duplicated packets in BSS */
  12015. + u16 last_rxseq_num[17]; /* rx seq previous per-tid */
  12016. + u16 last_rxfrag_num[17];/* tx frag previous per-tid */
  12017. + unsigned long last_packet_time[17];
  12018. +
  12019. + /* for PS mode */
  12020. + unsigned long last_rx_ps_time;
  12021. +
  12022. + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
  12023. + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
  12024. + int mgmt_queue_head;
  12025. + int mgmt_queue_tail;
  12026. +//by amy for ps
  12027. + bool bInactivePs;
  12028. + bool actscanning;
  12029. + u16 ListenInterval;
  12030. + u32 NumRxData;
  12031. + unsigned long NumRxDataInPeriod; //YJ,add,080828
  12032. + unsigned long NumRxBcnInPeriod; //YJ,add,080828
  12033. +//by amy for ps
  12034. + short meshid_set;
  12035. + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
  12036. + struct tx_pending_t tx_pending;
  12037. +
  12038. + /* used if IEEE_SOFTMAC_ASSOCIATE is set */
  12039. + struct timer_list associate_timer;
  12040. +
  12041. + /* used if IEEE_SOFTMAC_BEACONS is set */
  12042. + struct timer_list beacon_timer;
  12043. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  12044. + struct work_struct associate_complete_wq;
  12045. +// struct work_struct associate_retry_wq;
  12046. +// struct work_struct start_ibss_wq;
  12047. + struct work_struct associate_procedure_wq;
  12048. + struct work_struct ips_leave_wq; //YJ,add,081230,for IPS
  12049. + bool bHwRadioOff;//by lizhaoming
  12050. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  12051. + struct delayed_work softmac_scan_wq;
  12052. + struct delayed_work start_ibss_wq;
  12053. + struct delayed_work associate_retry_wq;
  12054. +//by amy for rate adaptive
  12055. + struct delayed_work rate_adapter_wq;
  12056. +//by amy for rate adaptive
  12057. + struct delayed_work watch_dog_wq;
  12058. + struct delayed_work hw_dig_wq;
  12059. + struct delayed_work tx_pw_wq;
  12060. +
  12061. +#ifdef SW_ANTE_DIVERSITY
  12062. + struct delayed_work SwAntennaWorkItem;
  12063. +#endif
  12064. +
  12065. +#else
  12066. + struct work_struct softmac_scan_wq;
  12067. + struct work_struct start_ibss_wq;
  12068. + struct work_struct associate_retry_wq;
  12069. +//by amy for rate adaptive
  12070. + struct work_struct rate_adapter_wq;
  12071. +//by amy for rate adaptive
  12072. + struct work_struct watch_dog_wq;
  12073. + struct work_struct hw_dig_wq;
  12074. + struct work_struct tx_pw_wq;
  12075. +
  12076. +#ifdef SW_ANTE_DIVERSITY
  12077. + struct work_struct SwAntennaWorkItem;
  12078. +#endif
  12079. +
  12080. +#endif
  12081. +
  12082. +//struct work_struct softmac_scan_wq;
  12083. + struct work_struct wx_sync_scan_wq;
  12084. + struct work_struct wmm_param_update_wq;
  12085. +#ifdef _RTL8187_EXT_PATCH_
  12086. + struct work_struct ext_stop_scan_wq;
  12087. + struct work_struct ext_send_beacon_wq;
  12088. +#endif
  12089. + struct workqueue_struct *wq;
  12090. +#else
  12091. + /* used for periodly scan */
  12092. + struct timer_list scan_timer;
  12093. +
  12094. + struct tq_struct associate_complete_wq;
  12095. + struct tq_struct associate_retry_wq;
  12096. + struct tq_struct start_ibss_wq;
  12097. + struct tq_struct associate_procedure_wq;
  12098. + struct tq_struct ips_leave_wq; //YJ,add,081230,for IPS
  12099. + struct tq_struct softmac_scan_wq;
  12100. + struct tq_struct wx_sync_scan_wq;
  12101. + struct tq_struct wmm_param_update_wq;
  12102. +#ifdef _RTL8187_EXT_PATCH_
  12103. + struct tq_struct ext_stop_scan_wq;
  12104. + struct tq_struct ext_send_beacon_wq;
  12105. +#endif
  12106. +#endif
  12107. +
  12108. + /* Callback functions */
  12109. + void (*set_security)(struct net_device *dev,
  12110. + struct ieee80211_security *sec);
  12111. +
  12112. + /* Used to TX data frame by using txb structs.
  12113. + * this is not used if in the softmac_features
  12114. + * is set the flag IEEE_SOFTMAC_TX_QUEUE
  12115. + */
  12116. + int (*hard_start_xmit)(struct ieee80211_txb *txb,
  12117. + struct net_device *dev);
  12118. +
  12119. + int (*reset_port)(struct net_device *dev);
  12120. +
  12121. + /* Softmac-generated frames (mamagement) are TXed via this
  12122. + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
  12123. + * not set. As some cards may have different HW queues that
  12124. + * one might want to use for data and management frames
  12125. + * the option to have two callbacks might be useful.
  12126. + * This fucntion can't sleep.
  12127. + */
  12128. + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
  12129. + struct net_device *dev);
  12130. +
  12131. + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
  12132. + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
  12133. + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
  12134. + * then also management frames are sent via this callback.
  12135. + * This function can't sleep.
  12136. + */
  12137. + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
  12138. + struct net_device *dev,int rate);
  12139. +
  12140. + /* stops the HW queue for DATA frames. Useful to avoid
  12141. + * waste time to TX data frame when we are reassociating
  12142. + * This function can sleep.
  12143. + */
  12144. + void (*data_hard_stop)(struct net_device *dev);
  12145. +
  12146. + /* OK this is complementar to data_poll_hard_stop */
  12147. + void (*data_hard_resume)(struct net_device *dev);
  12148. +
  12149. + /* ask to the driver to retune the radio .
  12150. + * This function can sleep. the driver should ensure
  12151. + * the radio has been swithced before return.
  12152. + */
  12153. + void (*set_chan)(struct net_device *dev,short ch);
  12154. +
  12155. + /* These are not used if the ieee stack takes care of
  12156. + * scanning (IEEE_SOFTMAC_SCAN feature set).
  12157. + * In this case only the set_chan is used.
  12158. + *
  12159. + * The syncro version is similar to the start_scan but
  12160. + * does not return until all channels has been scanned.
  12161. + * this is called in user context and should sleep,
  12162. + * it is called in a work_queue when swithcing to ad-hoc mode
  12163. + * or in behalf of iwlist scan when the card is associated
  12164. + * and root user ask for a scan.
  12165. + * the fucntion stop_scan should stop both the syncro and
  12166. + * background scanning and can sleep.
  12167. + * The fucntion start_scan should initiate the background
  12168. + * scanning and can't sleep.
  12169. + */
  12170. + void (*scan_syncro)(struct net_device *dev);
  12171. + void (*start_scan)(struct net_device *dev);
  12172. + void (*stop_scan)(struct net_device *dev);
  12173. +
  12174. + /* indicate the driver that the link state is changed
  12175. + * for example it may indicate the card is associated now.
  12176. + * Driver might be interested in this to apply RX filter
  12177. + * rules or simply light the LINK led
  12178. + */
  12179. + void (*link_change)(struct net_device *dev);
  12180. +
  12181. + /* these two function indicates to the HW when to start
  12182. + * and stop to send beacons. This is used when the
  12183. + * IEEE_SOFTMAC_BEACONS is not set. For now the
  12184. + * stop_send_bacons is NOT guaranteed to be called only
  12185. + * after start_send_beacons.
  12186. + */
  12187. + void (*start_send_beacons) (struct net_device *dev);
  12188. + void (*stop_send_beacons) (struct net_device *dev);
  12189. +
  12190. + /* power save mode related */
  12191. + void (*sta_wake_up) (struct net_device *dev);
  12192. + void (*ps_request_tx_ack) (struct net_device *dev);
  12193. + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
  12194. + short (*ps_is_queue_empty) (struct net_device *dev);
  12195. +
  12196. +//by lizhaoming for LED 2008.6.23
  12197. +#ifdef LED
  12198. + void (*ieee80211_led_contorl) (struct net_device *dev, LED_CTL_MODE LedAction);
  12199. +#endif
  12200. +#ifdef CONFIG_IPS
  12201. + void (*ieee80211_ips_leave) (struct net_device *dev);
  12202. +#endif
  12203. + /* QoS related */
  12204. + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
  12205. + //void (*wmm_param_update) (struct ieee80211_device *ieee);
  12206. +
  12207. +
  12208. +#ifdef _RTL8187_EXT_PATCH_
  12209. +
  12210. + /// ieee80211_softmac.c
  12211. + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
  12212. +
  12213. + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
  12214. + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
  12215. +
  12216. + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
  12217. +
  12218. + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
  12219. + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
  12220. +
  12221. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
  12222. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
  12223. +
  12224. + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
  12225. + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
  12226. +
  12227. + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
  12228. +
  12229. + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
  12230. +
  12231. + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  12232. + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  12233. +//by amy for mesh
  12234. + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
  12235. +//by amy for mesh
  12236. + // ieee80211_rx.c
  12237. + // rz
  12238. + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
  12239. + unsigned int(*ext_patch_ieee80211_process_probe_response_1)(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
  12240. +
  12241. + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
  12242. + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
  12243. +
  12244. + // success(return 0) is responsible to free skb
  12245. + 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);
  12246. +
  12247. + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
  12248. +
  12249. + // Check whether or not accept the incoming frame. return 0: not accept, >0: accept
  12250. + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
  12251. +
  12252. + // return > 0 is success. 0 when failed
  12253. + // success(return >0) is responsible to free skb
  12254. + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  12255. +
  12256. + /* added by david for setting acl dynamically */
  12257. + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
  12258. +
  12259. + // int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
  12260. +
  12261. + // ieee80211_tx.c
  12262. +
  12263. + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
  12264. + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
  12265. +
  12266. +
  12267. +#endif // _RTL8187_EXT_PATCH_
  12268. +
  12269. + /* This must be the last item so that it points to the data
  12270. + * allocated beyond this structure by alloc_ieee80211 */
  12271. + u8 priv[0];
  12272. +};
  12273. +
  12274. +#define IEEE_A (1<<0)
  12275. +#define IEEE_B (1<<1)
  12276. +#define IEEE_G (1<<2)
  12277. +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
  12278. +
  12279. +/* Generate a 802.11 header */
  12280. +
  12281. +/* Uses the channel change callback directly
  12282. + * instead of [start/stop] scan callbacks
  12283. + */
  12284. +#define IEEE_SOFTMAC_SCAN (1<<2)
  12285. +
  12286. +/* Perform authentication and association handshake */
  12287. +#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
  12288. +
  12289. +/* Generate probe requests */
  12290. +#define IEEE_SOFTMAC_PROBERQ (1<<4)
  12291. +
  12292. +/* Generate respones to probe requests */
  12293. +#define IEEE_SOFTMAC_PROBERS (1<<5)
  12294. +
  12295. +/* The ieee802.11 stack will manages the netif queue
  12296. + * wake/stop for the driver, taking care of 802.11
  12297. + * fragmentation. See softmac.c for details. */
  12298. +#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
  12299. +
  12300. +/* Uses only the softmac_data_hard_start_xmit
  12301. + * even for TX management frames.
  12302. + */
  12303. +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
  12304. +
  12305. +/* Generate beacons. The stack will enqueue beacons
  12306. + * to the card
  12307. + */
  12308. +#define IEEE_SOFTMAC_BEACONS (1<<6)
  12309. +#ifdef _RTL8187_EXT_PATCH_
  12310. +extern inline int ieee80211_find_MP(struct ieee80211_device* ieee, const u8* addr, u8 set)
  12311. +{
  12312. + int i=0;
  12313. + for (i=1; i<MAX_MP; i++)
  12314. + {
  12315. + if ((ieee->cryptlist[i]->used == 0)&&set)
  12316. + {//entry is empty
  12317. + memcpy(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN);
  12318. + ieee->cryptlist[i]->used = 1;
  12319. + return i;
  12320. + }
  12321. + else if (0 == memcmp(ieee->cryptlist[i]->mac_addr, addr, ETH_ALEN)) //find matched entry
  12322. + {
  12323. + return i;
  12324. + }
  12325. + }
  12326. + return -1;
  12327. +}
  12328. +#endif
  12329. +
  12330. +
  12331. +
  12332. +static inline void *ieee80211_priv(struct net_device *dev)
  12333. +{
  12334. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  12335. + return ((struct ieee80211_device *)netdev_priv(dev))->priv;
  12336. +#else
  12337. + return ((struct ieee80211_device *)dev->priv)->priv;
  12338. +#endif
  12339. +}
  12340. +
  12341. +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
  12342. +{
  12343. + /* Single white space is for Linksys APs */
  12344. + if (essid_len == 1 && essid[0] == ' ')
  12345. + return 1;
  12346. +
  12347. + /* Otherwise, if the entire essid is 0, we assume it is hidden */
  12348. + while (essid_len) {
  12349. + essid_len--;
  12350. + if (essid[essid_len] != '\0')
  12351. + return 0;
  12352. + }
  12353. +
  12354. + return 1;
  12355. +}
  12356. +
  12357. +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
  12358. +{
  12359. + /*
  12360. + * It is possible for both access points and our device to support
  12361. + * combinations of modes, so as long as there is one valid combination
  12362. + * of ap/device supported modes, then return success
  12363. + *
  12364. + */
  12365. + if ((mode & IEEE_A) &&
  12366. + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
  12367. + (ieee->freq_band & IEEE80211_52GHZ_BAND))
  12368. + return 1;
  12369. +
  12370. + if ((mode & IEEE_G) &&
  12371. + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
  12372. + (ieee->freq_band & IEEE80211_24GHZ_BAND))
  12373. + return 1;
  12374. +
  12375. + if ((mode & IEEE_B) &&
  12376. + (ieee->modulation & IEEE80211_CCK_MODULATION) &&
  12377. + (ieee->freq_band & IEEE80211_24GHZ_BAND))
  12378. + return 1;
  12379. +
  12380. + return 0;
  12381. +}
  12382. +
  12383. +extern inline int ieee80211_get_hdrlen(u16 fc)
  12384. +{
  12385. + int hdrlen = 24;
  12386. +
  12387. + switch (WLAN_FC_GET_TYPE(fc)) {
  12388. + case IEEE80211_FTYPE_DATA:
  12389. + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
  12390. + hdrlen = 30; /* Addr4 */
  12391. + if(IEEE80211_QOS_HAS_SEQ(fc))
  12392. + hdrlen += 2; /* QOS ctrl*/
  12393. + break;
  12394. + case IEEE80211_FTYPE_CTL:
  12395. + switch (WLAN_FC_GET_STYPE(fc)) {
  12396. + case IEEE80211_STYPE_CTS:
  12397. + case IEEE80211_STYPE_ACK:
  12398. + hdrlen = 10;
  12399. + break;
  12400. + default:
  12401. + hdrlen = 16;
  12402. + break;
  12403. + }
  12404. + break;
  12405. + }
  12406. +
  12407. + return hdrlen;
  12408. +}
  12409. +
  12410. +
  12411. +
  12412. +/* ieee80211.c */
  12413. +extern void free_ieee80211(struct net_device *dev);
  12414. +extern struct net_device *alloc_ieee80211(int sizeof_priv);
  12415. +
  12416. +extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
  12417. +
  12418. +/* ieee80211_tx.c */
  12419. +
  12420. +extern int ieee80211_encrypt_fragment(
  12421. + struct ieee80211_device *ieee,
  12422. + struct sk_buff *frag,
  12423. + int hdr_len);
  12424. +
  12425. +extern int ieee80211_xmit(struct sk_buff *skb,
  12426. + struct net_device *dev);
  12427. +extern void ieee80211_txb_free(struct ieee80211_txb *);
  12428. +
  12429. +
  12430. +/* ieee80211_rx.c */
  12431. +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
  12432. + struct ieee80211_rx_stats *rx_stats);
  12433. +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
  12434. + struct ieee80211_hdr *header,
  12435. + struct ieee80211_rx_stats *stats);
  12436. +
  12437. +/* ieee80211_wx.c */
  12438. +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
  12439. + struct iw_request_info *info,
  12440. + union iwreq_data *wrqu, char *key);
  12441. +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
  12442. + struct iw_request_info *info,
  12443. + union iwreq_data *wrqu, char *key);
  12444. +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
  12445. + struct iw_request_info *info,
  12446. + union iwreq_data *wrqu, char *key);
  12447. +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
  12448. + struct iw_request_info *info,
  12449. + union iwreq_data* wrqu, char *extra);
  12450. +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
  12451. + struct iw_request_info *info,
  12452. + struct iw_param *data, char *extra);
  12453. +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
  12454. + struct iw_request_info *info,
  12455. + union iwreq_data *wrqu, char *extra);
  12456. +
  12457. +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
  12458. +/* ieee80211_softmac.c */
  12459. +extern short ieee80211_is_54g(struct ieee80211_network net);
  12460. +extern short ieee80211_is_shortslot(struct ieee80211_network net);
  12461. +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
  12462. + struct ieee80211_rx_stats *rx_stats, u16 type,
  12463. + u16 stype);
  12464. +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
  12465. +
  12466. +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
  12467. +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
  12468. +extern void ieee80211_start_bss(struct ieee80211_device *ieee);
  12469. +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
  12470. +extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
  12471. +extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
  12472. +extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
  12473. +extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
  12474. +extern void ieee80211_disassociate(struct ieee80211_device *ieee);
  12475. +extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
  12476. +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
  12477. +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
  12478. +extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
  12479. +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
  12480. +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
  12481. +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
  12482. +extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
  12483. +extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
  12484. +extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
  12485. +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
  12486. +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
  12487. +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
  12488. +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
  12489. +extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
  12490. +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
  12491. +extern void ieee80211_start_scan(struct ieee80211_device *ieee);
  12492. +
  12493. +#ifdef _RTL8187_EXT_PATCH_
  12494. +extern void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb);
  12495. +extern void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat);
  12496. +extern void ieee80211_associate_step1(struct ieee80211_device *ieee);
  12497. +extern void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason);
  12498. +extern void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type);
  12499. +extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
  12500. +extern struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
  12501. +extern int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_network *network, struct ieee80211_rx_stats *stats);
  12502. +extern struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, int gfp_mask);
  12503. +extern void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee);
  12504. +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);
  12505. +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);
  12506. +extern int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src);
  12507. +#endif
  12508. +
  12509. +/* ieee80211_crypt_ccmp&tkip&wep.c */
  12510. +extern void ieee80211_tkip_null(void);
  12511. +extern void ieee80211_wep_null(void);
  12512. +extern void ieee80211_ccmp_null(void);
  12513. +/* ieee80211_softmac_wx.c */
  12514. +
  12515. +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
  12516. + struct iw_request_info *info,
  12517. + union iwreq_data *wrqu, char *ext);
  12518. +
  12519. +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
  12520. + struct iw_request_info *info,
  12521. + union iwreq_data *awrq,
  12522. + char *extra);
  12523. +
  12524. +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
  12525. +
  12526. +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
  12527. + struct iw_request_info *info,
  12528. + union iwreq_data *wrqu, char *extra);
  12529. +
  12530. +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
  12531. + struct iw_request_info *info,
  12532. + union iwreq_data *wrqu, char *extra);
  12533. +
  12534. +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  12535. + union iwreq_data *wrqu, char *b);
  12536. +
  12537. +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
  12538. + union iwreq_data *wrqu, char *b);
  12539. +
  12540. +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
  12541. + struct iw_request_info *a,
  12542. + union iwreq_data *wrqu, char *extra);
  12543. +
  12544. +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  12545. + union iwreq_data *wrqu, char *b);
  12546. +
  12547. +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
  12548. + union iwreq_data *wrqu, char *b);
  12549. +
  12550. +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
  12551. + union iwreq_data *wrqu, char *b);
  12552. +
  12553. +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
  12554. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  12555. +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
  12556. +#else
  12557. + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
  12558. +#endif
  12559. +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
  12560. + struct iw_request_info *info,
  12561. + union iwreq_data *wrqu, char *extra);
  12562. +
  12563. +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
  12564. + struct iw_request_info *info,
  12565. + union iwreq_data *wrqu, char *extra);
  12566. +
  12567. +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
  12568. + struct iw_request_info *info,
  12569. + union iwreq_data *wrqu, char *extra);
  12570. +
  12571. +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
  12572. + struct iw_request_info *info,
  12573. + union iwreq_data *wrqu, char *extra);
  12574. +
  12575. +extern const long ieee80211_wlan_frequencies[];
  12576. +
  12577. +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
  12578. +{
  12579. + ieee->scans++;
  12580. +}
  12581. +
  12582. +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
  12583. +{
  12584. + return ieee->scans;
  12585. +}
  12586. +
  12587. +static inline const char *escape_essid(const char *essid, u8 essid_len) {
  12588. + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
  12589. + const char *s = essid;
  12590. + char *d = escaped;
  12591. +
  12592. + if (ieee80211_is_empty_essid(essid, essid_len)) {
  12593. + memcpy(escaped, "<hidden>", sizeof("<hidden>"));
  12594. + return escaped;
  12595. + }
  12596. +
  12597. + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
  12598. + while (essid_len--) {
  12599. + if (*s == '\0') {
  12600. + *d++ = '\\';
  12601. + *d++ = '0';
  12602. + s++;
  12603. + } else {
  12604. + *d++ = *s++;
  12605. + }
  12606. + }
  12607. + *d = '\0';
  12608. + return escaped;
  12609. +}
  12610. +#endif /* IEEE80211_H */
  12611. 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
  12612. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 1970-01-01 01:00:00.000000000 +0100
  12613. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_module.c 2010-05-27 18:12:39.532222207 +0200
  12614. @@ -0,0 +1,385 @@
  12615. +/*******************************************************************************
  12616. +
  12617. + Copyright(c) 2004 Intel Corporation. All rights reserved.
  12618. +
  12619. + Portions of this file are based on the WEP enablement code provided by the
  12620. + Host AP project hostap-drivers v0.1.3
  12621. + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  12622. + <jkmaline@cc.hut.fi>
  12623. + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  12624. +
  12625. + This program is free software; you can redistribute it and/or modify it
  12626. + under the terms of version 2 of the GNU General Public License as
  12627. + published by the Free Software Foundation.
  12628. +
  12629. + This program is distributed in the hope that it will be useful, but WITHOUT
  12630. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12631. + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12632. + more details.
  12633. +
  12634. + You should have received a copy of the GNU General Public License along with
  12635. + this program; if not, write to the Free Software Foundation, Inc., 59
  12636. + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  12637. +
  12638. + The full GNU General Public License is included in this distribution in the
  12639. + file called LICENSE.
  12640. +
  12641. + Contact Information:
  12642. + James P. Ketrenos <ipw2100-admin@linux.intel.com>
  12643. + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  12644. +
  12645. +*******************************************************************************/
  12646. +
  12647. +#include <linux/compiler.h>
  12648. +//#include <linux/config.h>
  12649. +#include <linux/errno.h>
  12650. +#include <linux/if_arp.h>
  12651. +#include <linux/in6.h>
  12652. +#include <linux/in.h>
  12653. +#include <linux/ip.h>
  12654. +#include <linux/kernel.h>
  12655. +#include <linux/module.h>
  12656. +#include <linux/netdevice.h>
  12657. +#include <linux/pci.h>
  12658. +#include <linux/proc_fs.h>
  12659. +#include <linux/skbuff.h>
  12660. +#include <linux/slab.h>
  12661. +#include <linux/tcp.h>
  12662. +#include <linux/types.h>
  12663. +#include <linux/version.h>
  12664. +#include <linux/wireless.h>
  12665. +#include <linux/etherdevice.h>
  12666. +#include <asm/uaccess.h>
  12667. +#include <net/arp.h>
  12668. +
  12669. +#include "ieee80211.h"
  12670. +
  12671. +MODULE_DESCRIPTION("802.11 data/management/control stack");
  12672. +MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
  12673. +MODULE_LICENSE("GPL");
  12674. +
  12675. +#define DRV_NAME "ieee80211"
  12676. +
  12677. +static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
  12678. +{
  12679. + if (ieee->networks)
  12680. + return 0;
  12681. +
  12682. + ieee->networks = kmalloc(
  12683. + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
  12684. + GFP_KERNEL);
  12685. + if (!ieee->networks) {
  12686. + printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
  12687. + ieee->dev->name);
  12688. + return -ENOMEM;
  12689. + }
  12690. +
  12691. + memset(ieee->networks, 0,
  12692. + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
  12693. +
  12694. + return 0;
  12695. +}
  12696. +
  12697. +static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
  12698. +{
  12699. + if (!ieee->networks)
  12700. + return;
  12701. + kfree(ieee->networks);
  12702. + ieee->networks = NULL;
  12703. +}
  12704. +
  12705. +static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
  12706. +{
  12707. + int i;
  12708. +
  12709. + INIT_LIST_HEAD(&ieee->network_free_list);
  12710. + INIT_LIST_HEAD(&ieee->network_list);
  12711. + for (i = 0; i < MAX_NETWORK_COUNT; i++)
  12712. + list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
  12713. +}
  12714. +
  12715. +
  12716. +struct net_device *alloc_ieee80211(int sizeof_priv)
  12717. +{
  12718. + struct ieee80211_device *ieee;
  12719. + struct net_device *dev;
  12720. + int i,err;
  12721. +
  12722. + IEEE80211_DEBUG_INFO("Initializing...\n");
  12723. +
  12724. + dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
  12725. + if (!dev) {
  12726. + IEEE80211_ERROR("Unable to network device.\n");
  12727. + goto failed;
  12728. + }
  12729. +
  12730. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  12731. + ieee = netdev_priv(dev);
  12732. +#else
  12733. + ieee = (struct ieee80211_device *)dev->priv;
  12734. +#endif
  12735. +
  12736. + ieee->dev = dev;
  12737. +
  12738. + err = ieee80211_networks_allocate(ieee);
  12739. + if (err) {
  12740. + IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
  12741. + err);
  12742. + goto failed;
  12743. + }
  12744. + ieee80211_networks_initialize(ieee);
  12745. +
  12746. + /* Default fragmentation threshold is maximum payload size */
  12747. + ieee->fts = DEFAULT_FTS;
  12748. + ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
  12749. + ieee->open_wep = 1;
  12750. +
  12751. + /* Default to enabling full open WEP with host based encrypt/decrypt */
  12752. + ieee->host_encrypt = 1;
  12753. + ieee->host_decrypt = 1;
  12754. + ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
  12755. +
  12756. + INIT_LIST_HEAD(&ieee->crypt_deinit_list);
  12757. + init_timer(&ieee->crypt_deinit_timer);
  12758. + ieee->crypt_deinit_timer.data = (unsigned long)ieee;
  12759. + ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
  12760. +
  12761. + spin_lock_init(&ieee->lock);
  12762. + spin_lock_init(&ieee->wpax_suitlist_lock);
  12763. +
  12764. + ieee->wpax_type_set = 0;
  12765. + ieee->wpa_enabled = 0;
  12766. + ieee->tkip_countermeasures = 0;
  12767. + ieee->drop_unencrypted = 0;
  12768. + ieee->privacy_invoked = 0;
  12769. + ieee->ieee802_1x = 1;
  12770. + ieee->raw_tx = 0;
  12771. +#ifdef _RTL8187_EXT_PATCH_
  12772. + for (i=0; i<MAX_MP; i++)
  12773. + {
  12774. + ieee->cryptlist[i] = (struct ieee80211_crypt_data_list*) kmalloc(sizeof(struct ieee80211_crypt_data_list), GFP_KERNEL);
  12775. + if (NULL == ieee->cryptlist[i])
  12776. + {
  12777. + printk("error kmalloc cryptlist\n");
  12778. + goto failed;
  12779. + }
  12780. + memset(ieee->cryptlist[i], 0, sizeof(struct ieee80211_crypt_data_list));
  12781. +
  12782. + }
  12783. +#endif
  12784. + ieee80211_softmac_init(ieee);
  12785. +
  12786. + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
  12787. + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
  12788. +
  12789. + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++)
  12790. + INIT_LIST_HEAD(&ieee->mesh_mac_hash[i]);
  12791. +
  12792. + for (i = 0; i < 17; i++) {
  12793. + ieee->last_rxseq_num[i] = -1;
  12794. + ieee->last_rxfrag_num[i] = -1;
  12795. + ieee->last_packet_time[i] = 0;
  12796. + }
  12797. +#if 1 //added these to autoload encryption module. WB
  12798. + ieee80211_tkip_null();
  12799. + ieee80211_wep_null();
  12800. + ieee80211_ccmp_null();
  12801. +#endif
  12802. + return dev;
  12803. +
  12804. + failed:
  12805. +#ifdef _RTL8187_EXT_PATCH_
  12806. + for (i=0; i<MAX_MP; i++)
  12807. + {
  12808. + if (ieee->cryptlist[i]==NULL){
  12809. + continue;
  12810. + }
  12811. + kfree(ieee->cryptlist[i]);
  12812. + ieee->cryptlist[i] = NULL;
  12813. +
  12814. + }
  12815. +#endif
  12816. + if (dev)
  12817. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  12818. + free_netdev(dev);
  12819. +#else
  12820. + kfree(dev);
  12821. +#endif
  12822. + return NULL;
  12823. +}
  12824. +
  12825. +
  12826. +void free_ieee80211(struct net_device *dev)
  12827. +{
  12828. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  12829. + struct ieee80211_device *ieee = netdev_priv(dev);
  12830. +#else
  12831. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  12832. +#endif
  12833. + int i;//,j;
  12834. + struct list_head *p, *q;
  12835. +
  12836. +
  12837. + ieee80211_softmac_free(ieee);
  12838. + del_timer_sync(&ieee->crypt_deinit_timer);
  12839. + ieee80211_crypt_deinit_entries(ieee, 1);
  12840. +#if 1
  12841. + ieee80211_tkip_null();
  12842. + ieee80211_wep_null();
  12843. + ieee80211_ccmp_null();
  12844. +#endif
  12845. + for (i = 0; i < WEP_KEYS; i++) {
  12846. +#ifdef _RTL8187_EXT_PATCH_
  12847. +{
  12848. + // int j;
  12849. + for (j=0;j<MAX_MP; j++){
  12850. + if (ieee->cryptlist[j] == NULL)
  12851. + continue;
  12852. + struct ieee80211_crypt_data *crypt = ieee->cryptlist[j]->crypt[i];
  12853. +#else
  12854. + struct ieee80211_crypt_data *crypt = ieee->crypt[i];
  12855. +#endif
  12856. + if (crypt) {
  12857. + if (crypt->ops) {
  12858. + crypt->ops->deinit(crypt->priv);
  12859. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  12860. + module_put(crypt->ops->owner);
  12861. +#else
  12862. + __MOD_DEC_USE_COUNT(crypt->ops->owner);
  12863. +#endif
  12864. + }
  12865. + kfree(crypt);
  12866. +#ifdef _RTL8187_EXT_PATCH_
  12867. + ieee->cryptlist[j]->crypt[i] = NULL;
  12868. + //kfree(ieee->cryptlist[j]);
  12869. + //ieee->cryptlist[j] = NULL;
  12870. +#else
  12871. + ieee->crypt[i] = NULL;
  12872. +#endif
  12873. + }
  12874. +#ifdef _RTL8187_EXT_PATCH_
  12875. + }
  12876. + }
  12877. +#endif
  12878. +}
  12879. +#ifdef _RTL8187_EXT_PATCH_
  12880. +for(j=0;j<MAX_MP;j++)
  12881. + {
  12882. + if (ieee->cryptlist[j])
  12883. + {
  12884. + kfree(ieee->cryptlist[j]);
  12885. + ieee->cryptlist[j] = NULL;
  12886. + }
  12887. + }
  12888. +
  12889. + for (i = 0; i < IEEE_MESH_MAC_HASH_SIZE; i++) {
  12890. + list_for_each_safe(p, q, &ieee->mesh_mac_hash[i]) {
  12891. + kfree(list_entry(p, struct ieee_mesh_seq, list));
  12892. + list_del(p);
  12893. + }
  12894. + }
  12895. +#endif
  12896. + ieee80211_networks_free(ieee);
  12897. +
  12898. + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
  12899. + list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
  12900. + kfree(list_entry(p, struct ieee_ibss_seq, list));
  12901. + list_del(p);
  12902. + }
  12903. + }
  12904. +
  12905. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  12906. + free_netdev(dev);
  12907. +#else
  12908. + kfree(dev);
  12909. +#endif
  12910. +}
  12911. +
  12912. +#ifdef CONFIG_IEEE80211_DEBUG
  12913. +
  12914. +static int debug = 0;
  12915. +u32 ieee80211_debug_level = 0;
  12916. +struct proc_dir_entry *ieee80211_proc = NULL;
  12917. +
  12918. +static int show_debug_level(char *page, char **start, off_t offset,
  12919. + int count, int *eof, void *data)
  12920. +{
  12921. + return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
  12922. +}
  12923. +
  12924. +static int store_debug_level(struct file *file, const char *buffer,
  12925. + unsigned long count, void *data)
  12926. +{
  12927. + char buf[] = "0x00000000";
  12928. + unsigned long len = min(sizeof(buf) - 1, (u32)count);
  12929. + char *p = (char *)buf;
  12930. + unsigned long val;
  12931. +
  12932. + if (copy_from_user(buf, buffer, len))
  12933. + return count;
  12934. + buf[len] = 0;
  12935. + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
  12936. + p++;
  12937. + if (p[0] == 'x' || p[0] == 'X')
  12938. + p++;
  12939. + val = simple_strtoul(p, &p, 16);
  12940. + } else
  12941. + val = simple_strtoul(p, &p, 10);
  12942. + if (p == buf)
  12943. + printk(KERN_INFO DRV_NAME
  12944. + ": %s is not in hex or decimal form.\n", buf);
  12945. + else
  12946. + ieee80211_debug_level = val;
  12947. +
  12948. + return strnlen(buf, count);
  12949. +}
  12950. +
  12951. +static int __init ieee80211_init(void)
  12952. +{
  12953. + struct proc_dir_entry *e;
  12954. +
  12955. + ieee80211_debug_level = debug;
  12956. + ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
  12957. + if (ieee80211_proc == NULL) {
  12958. + IEEE80211_ERROR("Unable to create " DRV_NAME
  12959. + " proc directory\n");
  12960. + return -EIO;
  12961. + }
  12962. + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
  12963. + ieee80211_proc);
  12964. + if (!e) {
  12965. + remove_proc_entry(DRV_NAME, proc_net);
  12966. + ieee80211_proc = NULL;
  12967. + return -EIO;
  12968. + }
  12969. + e->read_proc = show_debug_level;
  12970. + e->write_proc = store_debug_level;
  12971. + e->data = NULL;
  12972. +
  12973. + return 0;
  12974. +}
  12975. +
  12976. +static void __exit ieee80211_exit(void)
  12977. +{
  12978. + if (ieee80211_proc) {
  12979. + remove_proc_entry("debug_level", ieee80211_proc);
  12980. + remove_proc_entry(DRV_NAME, proc_net);
  12981. + ieee80211_proc = NULL;
  12982. + }
  12983. +}
  12984. +
  12985. +#include <linux/moduleparam.h>
  12986. +module_param(debug, int, 0444);
  12987. +MODULE_PARM_DESC(debug, "debug output mask");
  12988. +
  12989. +
  12990. +module_exit(ieee80211_exit);
  12991. +module_init(ieee80211_init);
  12992. +#endif
  12993. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  12994. +EXPORT_SYMBOL(alloc_ieee80211);
  12995. +EXPORT_SYMBOL(free_ieee80211);
  12996. +#else
  12997. +EXPORT_SYMBOL_NOVERS(alloc_ieee80211);
  12998. +EXPORT_SYMBOL_NOVERS(free_ieee80211);
  12999. +#endif
  13000. 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
  13001. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 1970-01-01 01:00:00.000000000 +0100
  13002. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_rx.c 2010-05-27 18:12:39.532222207 +0200
  13003. @@ -0,0 +1,2074 @@
  13004. +/*
  13005. + * Original code based Host AP (software wireless LAN access point) driver
  13006. + * for Intersil Prism2/2.5/3 - hostap.o module, common routines
  13007. + *
  13008. + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  13009. + * <jkmaline@cc.hut.fi>
  13010. + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  13011. + * Copyright (c) 2004, Intel Corporation
  13012. + *
  13013. + * This program is free software; you can redistribute it and/or modify
  13014. + * it under the terms of the GNU General Public License version 2 as
  13015. + * published by the Free Software Foundation. See README and COPYING for
  13016. + * more details.
  13017. + ******************************************************************************
  13018. +
  13019. + Few modifications for Realtek's Wi-Fi drivers by
  13020. + Andrea Merello <andreamrl@tiscali.it>
  13021. +
  13022. + A special thanks goes to Realtek for their support !
  13023. +
  13024. +******************************************************************************/
  13025. +
  13026. +
  13027. +#include <linux/compiler.h>
  13028. +//#include <linux/config.h>
  13029. +#include <linux/errno.h>
  13030. +#include <linux/if_arp.h>
  13031. +#include <linux/in6.h>
  13032. +#include <linux/in.h>
  13033. +#include <linux/ip.h>
  13034. +#include <linux/kernel.h>
  13035. +#include <linux/module.h>
  13036. +#include <linux/netdevice.h>
  13037. +#include <linux/pci.h>
  13038. +#include <linux/proc_fs.h>
  13039. +#include <linux/skbuff.h>
  13040. +#include <linux/slab.h>
  13041. +#include <linux/tcp.h>
  13042. +#include <linux/types.h>
  13043. +#include <linux/version.h>
  13044. +#include <linux/wireless.h>
  13045. +#include <linux/etherdevice.h>
  13046. +#include <asm/uaccess.h>
  13047. +#include <linux/ctype.h>
  13048. +
  13049. +#include "ieee80211.h"
  13050. +#ifdef ENABLE_DOT11D
  13051. +#include "dot11d.h"
  13052. +#endif
  13053. +
  13054. +static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
  13055. + struct sk_buff *skb,
  13056. + struct ieee80211_rx_stats *rx_stats)
  13057. +{
  13058. + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  13059. + u16 fc = le16_to_cpu(hdr->frame_ctl);
  13060. +
  13061. + skb->dev = ieee->dev;
  13062. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
  13063. + skb_reset_mac_header(skb);
  13064. +#else
  13065. + skb->mac.raw = skb->data;
  13066. +#endif
  13067. +
  13068. + //skb->mac.raw = skb->data;
  13069. + skb_pull(skb, ieee80211_get_hdrlen(fc));
  13070. + skb->pkt_type = PACKET_OTHERHOST;
  13071. + skb->protocol = __constant_htons(ETH_P_80211_RAW);
  13072. + memset(skb->cb, 0, sizeof(skb->cb));
  13073. + netif_rx(skb);
  13074. +}
  13075. +
  13076. +
  13077. +/* Called only as a tasklet (software IRQ) */
  13078. +static struct ieee80211_frag_entry *
  13079. +ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
  13080. + unsigned int frag, u8 tid,u8 *src, u8 *dst)
  13081. +{
  13082. + struct ieee80211_frag_entry *entry;
  13083. + int i;
  13084. +
  13085. + for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
  13086. + entry = &ieee->frag_cache[tid][i];
  13087. + if (entry->skb != NULL &&
  13088. + time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
  13089. + IEEE80211_DEBUG_FRAG(
  13090. + "expiring fragment cache entry "
  13091. + "seq=%u last_frag=%u\n",
  13092. + entry->seq, entry->last_frag);
  13093. + dev_kfree_skb_any(entry->skb);
  13094. + entry->skb = NULL;
  13095. + }
  13096. +
  13097. + if (entry->skb != NULL && entry->seq == seq &&
  13098. + (entry->last_frag + 1 == frag || frag == -1) &&
  13099. + memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
  13100. + memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
  13101. + return entry;
  13102. + }
  13103. +
  13104. + return NULL;
  13105. +}
  13106. +
  13107. +/* Called only as a tasklet (software IRQ) */
  13108. +static struct sk_buff *
  13109. +ieee80211_frag_cache_get(struct ieee80211_device *ieee,
  13110. + struct ieee80211_hdr *hdr)
  13111. +{
  13112. + struct sk_buff *skb = NULL;
  13113. + u16 fc = le16_to_cpu(hdr->frame_ctl);
  13114. + u16 sc = le16_to_cpu(hdr->seq_ctl);
  13115. + unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
  13116. + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
  13117. + struct ieee80211_frag_entry *entry;
  13118. + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
  13119. + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
  13120. + u8 tid;
  13121. +
  13122. +#ifdef _RTL8187_EXT_PATCH_
  13123. + if(ieee->iw_mode == ieee->iw_ext_mode)
  13124. + {
  13125. + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
  13126. + }
  13127. + else
  13128. +#endif
  13129. + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  13130. + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
  13131. + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  13132. + tid = UP2AC(tid);
  13133. + tid ++;
  13134. + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
  13135. + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
  13136. + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  13137. + tid = UP2AC(tid);
  13138. + tid ++;
  13139. + } else {
  13140. + tid = 0;
  13141. + }
  13142. +
  13143. + if (frag == 0) {
  13144. + /* Reserve enough space to fit maximum frame length */
  13145. + skb = dev_alloc_skb(ieee->dev->mtu +
  13146. + sizeof(struct ieee80211_hdr) +
  13147. + 8 /* LLC */ +
  13148. + 2 /* alignment */ +
  13149. + 8 /* WEP */ +
  13150. + ETH_ALEN /* WDS */ +
  13151. + (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
  13152. + if (skb == NULL)
  13153. + return NULL;
  13154. +
  13155. + entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
  13156. + ieee->frag_next_idx[tid]++;
  13157. + if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
  13158. + ieee->frag_next_idx[tid] = 0;
  13159. +
  13160. + if (entry->skb != NULL)
  13161. + dev_kfree_skb_any(entry->skb);
  13162. +
  13163. + entry->first_frag_time = jiffies;
  13164. + entry->seq = seq;
  13165. + entry->last_frag = frag;
  13166. + entry->skb = skb;
  13167. + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
  13168. + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
  13169. + } else {
  13170. + /* received a fragment of a frame for which the head fragment
  13171. + * should have already been received */
  13172. + entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
  13173. + hdr->addr1);
  13174. + if (entry != NULL) {
  13175. + entry->last_frag = frag;
  13176. + skb = entry->skb;
  13177. + }
  13178. + }
  13179. +
  13180. + return skb;
  13181. +}
  13182. +
  13183. +
  13184. +/* Called only as a tasklet (software IRQ) */
  13185. +static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
  13186. + struct ieee80211_hdr *hdr)
  13187. +{
  13188. + u16 fc = le16_to_cpu(hdr->frame_ctl);
  13189. + u16 sc = le16_to_cpu(hdr->seq_ctl);
  13190. + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
  13191. + struct ieee80211_frag_entry *entry;
  13192. + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
  13193. + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
  13194. + u8 tid;
  13195. +
  13196. +#ifdef _RTL8187_EXT_PATCH_
  13197. + if(ieee->iw_mode == ieee->iw_ext_mode)
  13198. + {
  13199. + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
  13200. + }
  13201. + else
  13202. +#endif
  13203. + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  13204. + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
  13205. + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  13206. + tid = UP2AC(tid);
  13207. + tid ++;
  13208. + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
  13209. + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
  13210. + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  13211. + tid = UP2AC(tid);
  13212. + tid ++;
  13213. + } else {
  13214. + tid = 0;
  13215. + }
  13216. +
  13217. + entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
  13218. + hdr->addr1);
  13219. +
  13220. + if (entry == NULL) {
  13221. + IEEE80211_DEBUG_FRAG(
  13222. + "could not invalidate fragment cache "
  13223. + "entry (seq=%u)\n", seq);
  13224. + return -1;
  13225. + }
  13226. +
  13227. + entry->skb = NULL;
  13228. + return 0;
  13229. +}
  13230. +
  13231. +
  13232. +
  13233. +/* ieee80211_rx_frame_mgtmt
  13234. + *
  13235. + * Responsible for handling management control frames
  13236. + *
  13237. + * Called by ieee80211_rx */
  13238. +static inline int
  13239. +ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
  13240. + struct ieee80211_rx_stats *rx_stats, u16 type,
  13241. + u16 stype)
  13242. +{
  13243. + /* On the struct stats definition there is written that
  13244. + * this is not mandatory.... but seems that the probe
  13245. + * response parser uses it
  13246. + */
  13247. + struct ieee80211_hdr * hdr = (struct ieee80211_hdr*)skb->data;
  13248. + rx_stats->len = skb->len;
  13249. + ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
  13250. +
  13251. + if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN)))
  13252. + {
  13253. + dev_kfree_skb_any(skb);
  13254. + return 0;
  13255. + }
  13256. +
  13257. + ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
  13258. +
  13259. + dev_kfree_skb_any(skb);
  13260. +
  13261. + return 0;
  13262. +
  13263. + #ifdef NOT_YET
  13264. + if (ieee->iw_mode == IW_MODE_MASTER) {
  13265. + printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
  13266. + ieee->dev->name);
  13267. + return 0;
  13268. +/*
  13269. + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
  13270. + skb->data);*/
  13271. + }
  13272. +
  13273. + if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
  13274. + if (stype == WLAN_FC_STYPE_BEACON &&
  13275. + ieee->iw_mode == IW_MODE_MASTER) {
  13276. + struct sk_buff *skb2;
  13277. + /* Process beacon frames also in kernel driver to
  13278. + * update STA(AP) table statistics */
  13279. + skb2 = skb_clone(skb, GFP_ATOMIC);
  13280. + if (skb2)
  13281. + hostap_rx(skb2->dev, skb2, rx_stats);
  13282. + }
  13283. +
  13284. + /* send management frames to the user space daemon for
  13285. + * processing */
  13286. + ieee->apdevstats.rx_packets++;
  13287. + ieee->apdevstats.rx_bytes += skb->len;
  13288. + prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
  13289. + return 0;
  13290. + }
  13291. +
  13292. + if (ieee->iw_mode == IW_MODE_MASTER) {
  13293. + if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
  13294. + printk(KERN_DEBUG "%s: unknown management frame "
  13295. + "(type=0x%02x, stype=0x%02x) dropped\n",
  13296. + skb->dev->name, type, stype);
  13297. + return -1;
  13298. + }
  13299. +
  13300. + hostap_rx(skb->dev, skb, rx_stats);
  13301. + return 0;
  13302. + }
  13303. +
  13304. + printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
  13305. + "received in non-Host AP mode\n", skb->dev->name);
  13306. + return -1;
  13307. + #endif
  13308. +}
  13309. +
  13310. +
  13311. +
  13312. +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
  13313. +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
  13314. +static unsigned char rfc1042_header[] =
  13315. +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
  13316. +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
  13317. +static unsigned char bridge_tunnel_header[] =
  13318. +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
  13319. +/* No encapsulation header if EtherType < 0x600 (=length) */
  13320. +
  13321. +/* Called by ieee80211_rx_frame_decrypt */
  13322. +static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
  13323. + struct sk_buff *skb, size_t hdrlen)
  13324. +{
  13325. + struct net_device *dev = ieee->dev;
  13326. + u16 fc, ethertype;
  13327. + struct ieee80211_hdr *hdr;
  13328. + u8 *pos;
  13329. +
  13330. + if (skb->len < 24)
  13331. + return 0;
  13332. +
  13333. + hdr = (struct ieee80211_hdr *) skb->data;
  13334. + fc = le16_to_cpu(hdr->frame_ctl);
  13335. +
  13336. + /* check that the frame is unicast frame to us */
  13337. + if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  13338. + IEEE80211_FCTL_TODS &&
  13339. + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
  13340. + memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
  13341. + /* ToDS frame with own addr BSSID and DA */
  13342. + } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  13343. + IEEE80211_FCTL_FROMDS &&
  13344. + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
  13345. + /* FromDS frame with own addr as DA */
  13346. + } else
  13347. + return 0;
  13348. +
  13349. + if (skb->len < 24 + 8)
  13350. + return 0;
  13351. +
  13352. + /* check for port access entity Ethernet type */
  13353. +// pos = skb->data + 24;
  13354. + pos = skb->data + hdrlen;
  13355. + ethertype = (pos[6] << 8) | pos[7];
  13356. + if (ethertype == ETH_P_PAE)
  13357. + return 1;
  13358. +
  13359. + return 0;
  13360. +}
  13361. +
  13362. +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
  13363. +static inline int
  13364. +ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
  13365. + struct ieee80211_crypt_data *crypt)
  13366. +{
  13367. + struct ieee80211_hdr *hdr;
  13368. + int res, hdrlen;
  13369. +
  13370. + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
  13371. + return 0;
  13372. +
  13373. + hdr = (struct ieee80211_hdr *) skb->data;
  13374. +#ifdef _RTL8187_EXT_PATCH_
  13375. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
  13376. + {
  13377. + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
  13378. + }
  13379. + else
  13380. +#endif
  13381. + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
  13382. +
  13383. +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
  13384. + if (ieee->tkip_countermeasures &&
  13385. + strcmp(crypt->ops->name, "TKIP") == 0) {
  13386. + if (net_ratelimit()) {
  13387. + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
  13388. + "received packet from " MAC_FMT "\n",
  13389. + ieee->dev->name, MAC_ARG(hdr->addr2));
  13390. + }
  13391. + return -1;
  13392. + }
  13393. +#endif
  13394. +
  13395. + atomic_inc(&crypt->refcnt);
  13396. + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
  13397. + atomic_dec(&crypt->refcnt);
  13398. + if (res < 0) {
  13399. + IEEE80211_DEBUG_DROP(
  13400. + "decryption failed (SA=" MAC_FMT
  13401. + ") res=%d\n", MAC_ARG(hdr->addr2), res);
  13402. + if (res == -2)
  13403. + IEEE80211_DEBUG_DROP("Decryption failed ICV "
  13404. + "mismatch (key %d)\n",
  13405. + skb->data[hdrlen + 3] >> 6);
  13406. + ieee->ieee_stats.rx_discards_undecryptable++;
  13407. + return -1;
  13408. + }
  13409. +
  13410. + return res;
  13411. +}
  13412. +
  13413. +
  13414. +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
  13415. +static inline int
  13416. +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
  13417. + int keyidx, struct ieee80211_crypt_data *crypt)
  13418. +{
  13419. + struct ieee80211_hdr *hdr;
  13420. + int res, hdrlen;
  13421. +
  13422. + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
  13423. + return 0;
  13424. +
  13425. + hdr = (struct ieee80211_hdr *) skb->data;
  13426. +#ifdef _RTL8187_EXT_PATCH_
  13427. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
  13428. + {
  13429. + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
  13430. + }
  13431. + else
  13432. +#endif
  13433. + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
  13434. +
  13435. + atomic_inc(&crypt->refcnt);
  13436. + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
  13437. + atomic_dec(&crypt->refcnt);
  13438. + if (res < 0) {
  13439. + printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
  13440. + " (SA=" MAC_FMT " keyidx=%d)\n",
  13441. + ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
  13442. + return -1;
  13443. + }
  13444. +
  13445. + return 0;
  13446. +}
  13447. +
  13448. +
  13449. +/* this function is stolen from ipw2200 driver*/
  13450. +#define IEEE_PACKET_RETRY_TIME (5*HZ)
  13451. +static int is_duplicate_packet(struct ieee80211_device *ieee,
  13452. + struct ieee80211_hdr *header)
  13453. +{
  13454. + u16 fc = le16_to_cpu(header->frame_ctl);
  13455. + u16 sc = le16_to_cpu(header->seq_ctl);
  13456. + u16 seq = WLAN_GET_SEQ_SEQ(sc);
  13457. + u16 frag = WLAN_GET_SEQ_FRAG(sc);
  13458. + u16 *last_seq, *last_frag;
  13459. + unsigned long *last_time;
  13460. + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
  13461. + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
  13462. + u8 tid;
  13463. +
  13464. +#ifdef _RTL8187_EXT_PATCH_
  13465. + if(ieee->iw_mode == ieee->iw_ext_mode)
  13466. + {
  13467. + tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
  13468. + }
  13469. + else
  13470. +#endif
  13471. + //TO2DS and QoS
  13472. + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  13473. + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
  13474. + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  13475. + tid = UP2AC(tid);
  13476. + tid ++;
  13477. + } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
  13478. + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
  13479. + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
  13480. + tid = UP2AC(tid);
  13481. + tid ++;
  13482. + } else { // no QoS
  13483. + tid = 0;
  13484. + }
  13485. +
  13486. + switch (ieee->iw_mode) {
  13487. + case IW_MODE_ADHOC:
  13488. + {
  13489. + struct list_head *p;
  13490. + struct ieee_ibss_seq *entry = NULL;
  13491. + u8 *mac = header->addr2;
  13492. + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
  13493. + //for (pos = (head)->next; pos != (head); pos = pos->next)
  13494. + __list_for_each(p, &ieee->ibss_mac_hash[index]) {
  13495. + entry = list_entry(p, struct ieee_ibss_seq, list);
  13496. + if (!memcmp(entry->mac, mac, ETH_ALEN))
  13497. + break;
  13498. + }
  13499. + // if (memcmp(entry->mac, mac, ETH_ALEN)){
  13500. + if (p == &ieee->ibss_mac_hash[index]) {
  13501. + entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
  13502. + if (!entry) {
  13503. + printk(KERN_WARNING "Cannot malloc new mac entry\n");
  13504. + return 0;
  13505. + }
  13506. + memcpy(entry->mac, mac, ETH_ALEN);
  13507. + entry->seq_num[tid] = seq;
  13508. + entry->frag_num[tid] = frag;
  13509. + entry->packet_time[tid] = jiffies;
  13510. + list_add(&entry->list, &ieee->ibss_mac_hash[index]);
  13511. + return 0;
  13512. + }
  13513. + last_seq = &entry->seq_num[tid];
  13514. + last_frag = &entry->frag_num[tid];
  13515. + last_time = &entry->packet_time[tid];
  13516. + break;
  13517. + }
  13518. +
  13519. + case IW_MODE_INFRA:
  13520. + last_seq = &ieee->last_rxseq_num[tid];
  13521. + last_frag = &ieee->last_rxfrag_num[tid];
  13522. + last_time = &ieee->last_packet_time[tid];
  13523. +
  13524. + break;
  13525. + default:
  13526. +#ifdef _RTL8187_EXT_PATCH_
  13527. + if(ieee->iw_mode == ieee->iw_ext_mode)
  13528. + {
  13529. +#if 0
  13530. + printk("==============> tid = %d\n", tid);
  13531. + last_seq = &ieee->last_rxseq_num[tid];
  13532. + last_frag = &ieee->last_rxfrag_num[tid];
  13533. + last_time = &ieee->last_packet_time[tid];
  13534. +#else
  13535. + struct list_head *p;
  13536. + struct ieee_mesh_seq *entry = NULL;
  13537. + u8 *mac = header->addr2;
  13538. + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
  13539. +
  13540. + __list_for_each(p, &ieee->mesh_mac_hash[index]) {
  13541. + entry = list_entry(p, struct ieee_mesh_seq, list);
  13542. + if (!memcmp(entry->mac, mac, ETH_ALEN))
  13543. + break;
  13544. + }
  13545. + if (p == &ieee->mesh_mac_hash[index]) {
  13546. + entry = kmalloc(sizeof(struct ieee_mesh_seq), GFP_ATOMIC);
  13547. + if (!entry) {
  13548. + printk(KERN_WARNING "Cannot malloc new mac entry for mesh\n");
  13549. + return 0;
  13550. + }
  13551. + memcpy(entry->mac, mac, ETH_ALEN);
  13552. + entry->seq_num = seq;
  13553. + entry->frag_num = frag;
  13554. + entry->packet_time = jiffies;
  13555. + list_add(&entry->list, &ieee->mesh_mac_hash[index]);
  13556. + return 0;
  13557. + }
  13558. + last_seq = &entry->seq_num;
  13559. + last_frag = &entry->frag_num;
  13560. + last_time = &entry->packet_time;
  13561. +#endif
  13562. + break;
  13563. + }
  13564. + else
  13565. +#endif
  13566. + return 0;
  13567. + }
  13568. +
  13569. +// if(tid != 0) {
  13570. +// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
  13571. +// }
  13572. + if ((*last_seq == seq) &&
  13573. + time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
  13574. + if (*last_frag == frag){
  13575. + //printk(KERN_WARNING "[1] go drop!\n");
  13576. + goto drop;
  13577. +
  13578. + }
  13579. + if (*last_frag + 1 != frag)
  13580. + /* out-of-order fragment */
  13581. + //printk(KERN_WARNING "[2] go drop!\n");
  13582. + goto drop;
  13583. + } else
  13584. + *last_seq = seq;
  13585. +
  13586. + *last_frag = frag;
  13587. + *last_time = jiffies;
  13588. + return 0;
  13589. +
  13590. +drop:
  13591. +// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
  13592. +// printk("DUP\n");
  13593. +
  13594. + return 1;
  13595. +}
  13596. +#ifdef JUST_FOR_87SEMESH
  13597. +#define ActionHeadLen 30
  13598. +#define WIFI_MESH_TYPE IEEE80211_FTYPE_DATA
  13599. +#define WIFI_11S_MESH_ACTION 0x00A0
  13600. +#endif
  13601. +
  13602. +/* All received frames are sent to this function. @skb contains the frame in
  13603. + * IEEE 802.11 format, i.e., in the format it was sent over air.
  13604. + * This function is called only as a tasklet (software IRQ). */
  13605. +int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
  13606. + struct ieee80211_rx_stats *rx_stats)
  13607. +{
  13608. + struct net_device *dev = ieee->dev;
  13609. + struct ieee80211_hdr *hdr;
  13610. + //struct ieee80211_hdr_3addr_QOS *hdr;
  13611. +
  13612. + size_t hdrlen;
  13613. + u16 fc, type, stype, sc;
  13614. + struct net_device_stats *stats;
  13615. + unsigned int frag;
  13616. + u8 *payload;
  13617. + u16 ethertype;
  13618. +#ifdef NOT_YET
  13619. + struct net_device *wds = NULL;
  13620. + struct sk_buff *skb2 = NULL;
  13621. + struct net_device *wds = NULL;
  13622. + int frame_authorized = 0;
  13623. + int from_assoc_ap = 0;
  13624. + void *sta = NULL;
  13625. +#endif
  13626. +// u16 QOS_ctl = 0;
  13627. + u8 dst[ETH_ALEN];
  13628. + u8 src[ETH_ALEN];
  13629. + u8 bssid[ETH_ALEN];
  13630. + struct ieee80211_crypt_data *crypt = NULL;
  13631. + int keyidx = 0;
  13632. +
  13633. + //Added for mesh by Lawrence.
  13634. + //u8 status;
  13635. + //u32 flags;
  13636. +
  13637. + // cheat the the hdr type
  13638. + hdr = (struct ieee80211_hdr *)skb->data;
  13639. + stats = &ieee->stats;
  13640. +
  13641. + if (skb->len < 10) {
  13642. + printk(KERN_INFO "%s: SKB length < 10\n",
  13643. + dev->name);
  13644. + goto rx_dropped;
  13645. + }
  13646. +#if 0
  13647. +//{added by david for filter the packet listed in the filter table
  13648. +#ifdef _RTL8187_EXT_PATCH_
  13649. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
  13650. + {
  13651. + if(!ieee->ext_patch_ieee80211_acl_query(ieee, hdr->addr2))
  13652. + goto rx_dropped;
  13653. + }
  13654. +#endif
  13655. +//}
  13656. +#endif
  13657. + fc = le16_to_cpu(hdr->frame_ctl);
  13658. + type = WLAN_FC_GET_TYPE(fc);
  13659. + stype = WLAN_FC_GET_STYPE(fc);
  13660. +
  13661. + //Because 87se's bad feature,do more handle.
  13662. +#ifdef JUST_FOR_87SEMESH
  13663. +
  13664. +u8 tmphead[ActionHeadLen];
  13665. + if(type ==WIFI_MESH_TYPE && stype== WIFI_11S_MESH_ACTION )
  13666. + //head=sizeof(struct ieee80211_hdr)=30
  13667. + {
  13668. + memset(tmphead,0,ActionHeadLen);
  13669. + memcpy(tmphead,skb->data,ActionHeadLen);
  13670. +
  13671. + skb_pull(skb,ActionHeadLen+2);
  13672. + memcpy(skb_push(skb,ActionHeadLen),tmphead,ActionHeadLen);
  13673. + hdr = (struct ieee80211_hdr *)skb->data;
  13674. + }
  13675. +
  13676. +#endif
  13677. + sc = le16_to_cpu(hdr->seq_ctl);
  13678. +
  13679. + frag = WLAN_GET_SEQ_FRAG(sc);
  13680. +#ifdef _RTL8187_EXT_PATCH_
  13681. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
  13682. + {
  13683. + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
  13684. + if(skb->len < hdrlen)
  13685. + goto rx_dropped;
  13686. + }
  13687. + else
  13688. +#endif
  13689. + hdrlen = ieee80211_get_hdrlen(fc);
  13690. +
  13691. +#ifdef NOT_YET
  13692. +#if WIRELESS_EXT > 15
  13693. + /* Put this code here so that we avoid duplicating it in all
  13694. + * Rx paths. - Jean II */
  13695. +#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
  13696. + /* If spy monitoring on */
  13697. + if (iface->spy_data.spy_number > 0) {
  13698. + struct iw_quality wstats;
  13699. + wstats.level = rx_stats->signal;
  13700. + wstats.noise = rx_stats->noise;
  13701. + wstats.updated = 6; /* No qual value */
  13702. + /* Update spy records */
  13703. + wireless_spy_update(dev, hdr->addr2, &wstats);
  13704. + }
  13705. +#endif /* IW_WIRELESS_SPY */
  13706. +#endif /* WIRELESS_EXT > 15 */
  13707. + hostap_update_rx_stats(local->ap, hdr, rx_stats);
  13708. +#endif
  13709. +
  13710. +#if WIRELESS_EXT > 15
  13711. + if (ieee->iw_mode == IW_MODE_MONITOR) {
  13712. + ieee80211_monitor_rx(ieee, skb, rx_stats);
  13713. + stats->rx_packets++;
  13714. + stats->rx_bytes += skb->len;
  13715. + return 1;
  13716. + }
  13717. +#endif
  13718. + if (ieee->host_decrypt) {
  13719. + int idx = 0;
  13720. + if (skb->len >= hdrlen + 3)
  13721. + idx = skb->data[hdrlen + 3] >> 6;
  13722. +#ifdef _RTL8187_EXT_PATCH_
  13723. +
  13724. + crypt = ieee->cryptlist[0]->crypt[idx];
  13725. +#if 0
  13726. + {
  13727. + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2);
  13728. + if (i == -1)
  13729. + {
  13730. + printk("error find entry in entry list\n");
  13731. + goto rx_dropped;
  13732. + }
  13733. + //printk("%s():"MAC_FMT", find in index:%d", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
  13734. + crypt = ieee->cryptlist[i]->crypt[idx];
  13735. + }
  13736. +#endif
  13737. +#else
  13738. + crypt = ieee->crypt[idx];
  13739. +#endif
  13740. +
  13741. +#ifdef NOT_YET
  13742. + sta = NULL;
  13743. +
  13744. + /* Use station specific key to override default keys if the
  13745. + * receiver address is a unicast address ("individual RA"). If
  13746. + * bcrx_sta_key parameter is set, station specific key is used
  13747. + * even with broad/multicast targets (this is against IEEE
  13748. + * 802.11, but makes it easier to use different keys with
  13749. + * stations that do not support WEP key mapping). */
  13750. +
  13751. + if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
  13752. + (void) hostap_handle_sta_crypto(local, hdr, &crypt,
  13753. + &sta);
  13754. +#endif
  13755. +
  13756. + /* allow NULL decrypt to indicate an station specific override
  13757. + * for default encryption */
  13758. + if (crypt && (crypt->ops == NULL ||
  13759. + crypt->ops->decrypt_mpdu == NULL))
  13760. + crypt = NULL;
  13761. +
  13762. + if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
  13763. + /* This seems to be triggered by some (multicast?)
  13764. + * frames from other than current BSS, so just drop the
  13765. + * frames silently instead of filling system log with
  13766. + * these reports. */
  13767. + IEEE80211_DEBUG_DROP("Decryption failed (not set)"
  13768. + " (SA=" MAC_FMT ")\n",
  13769. + MAC_ARG(hdr->addr2));
  13770. + ieee->ieee_stats.rx_discards_undecryptable++;
  13771. + goto rx_dropped;
  13772. + }
  13773. + }
  13774. +
  13775. + if (skb->len < IEEE80211_DATA_HDR3_LEN)
  13776. + goto rx_dropped;
  13777. +
  13778. + // if QoS enabled, should check the sequence for each of the AC
  13779. + if (is_duplicate_packet(ieee, hdr))
  13780. + goto rx_dropped;
  13781. +
  13782. +#ifdef _RTL8187_EXT_PATCH_
  13783. + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire )
  13784. + ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb );
  13785. +#endif
  13786. +
  13787. + if (type == IEEE80211_FTYPE_MGMT) {
  13788. +
  13789. + #if 0
  13790. + if ( stype == IEEE80211_STYPE_AUTH &&
  13791. + fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
  13792. + (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
  13793. + {
  13794. + printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
  13795. + "from " MAC_FMT "\n", dev->name,
  13796. + MAC_ARG(hdr->addr2));
  13797. + /* TODO: could inform hostapd about this so that it
  13798. + * could send auth failure report */
  13799. + goto rx_dropped;
  13800. + }
  13801. + #endif
  13802. +
  13803. +
  13804. + if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
  13805. + goto rx_dropped;
  13806. + else
  13807. + goto rx_exit;
  13808. + }
  13809. +
  13810. +#ifdef _RTL8187_EXT_PATCH_
  13811. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
  13812. + {
  13813. + if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
  13814. + {
  13815. + goto rx_exit;
  13816. + }
  13817. + }
  13818. +#endif
  13819. +
  13820. + /* Data frame - extract src/dst addresses */
  13821. + switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
  13822. + case IEEE80211_FCTL_FROMDS:
  13823. + memcpy(dst, hdr->addr1, ETH_ALEN);
  13824. + memcpy(src, hdr->addr3, ETH_ALEN);
  13825. + memcpy(bssid, hdr->addr2, ETH_ALEN);
  13826. + break;
  13827. + case IEEE80211_FCTL_TODS:
  13828. + memcpy(dst, hdr->addr3, ETH_ALEN);
  13829. + memcpy(src, hdr->addr2, ETH_ALEN);
  13830. + memcpy(bssid, hdr->addr1, ETH_ALEN);
  13831. + break;
  13832. + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
  13833. + if (skb->len < IEEE80211_DATA_HDR4_LEN)
  13834. + goto rx_dropped;
  13835. + memcpy(dst, hdr->addr3, ETH_ALEN);
  13836. + memcpy(src, hdr->addr4, ETH_ALEN);
  13837. + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
  13838. + break;
  13839. + case 0:
  13840. + memcpy(dst, hdr->addr1, ETH_ALEN);
  13841. + memcpy(src, hdr->addr2, ETH_ALEN);
  13842. + memcpy(bssid, hdr->addr3, ETH_ALEN);
  13843. + break;
  13844. + }
  13845. +
  13846. +#ifdef NOT_YET
  13847. + if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
  13848. + goto rx_dropped;
  13849. + if (wds) {
  13850. + skb->dev = dev = wds;
  13851. + stats = hostap_get_stats(dev);
  13852. + }
  13853. +
  13854. + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
  13855. + (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
  13856. + ieee->stadev &&
  13857. + memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
  13858. + /* Frame from BSSID of the AP for which we are a client */
  13859. + skb->dev = dev = ieee->stadev;
  13860. + stats = hostap_get_stats(dev);
  13861. + from_assoc_ap = 1;
  13862. + }
  13863. +#endif
  13864. +
  13865. + dev->last_rx = jiffies;
  13866. +
  13867. +#ifdef NOT_YET
  13868. + if ((ieee->iw_mode == IW_MODE_MASTER ||
  13869. + ieee->iw_mode == IW_MODE_REPEAT) &&
  13870. + !from_assoc_ap) {
  13871. + switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
  13872. + wds != NULL)) {
  13873. + case AP_RX_CONTINUE_NOT_AUTHORIZED:
  13874. + frame_authorized = 0;
  13875. + break;
  13876. + case AP_RX_CONTINUE:
  13877. + frame_authorized = 1;
  13878. + break;
  13879. + case AP_RX_DROP:
  13880. + goto rx_dropped;
  13881. + case AP_RX_EXIT:
  13882. + goto rx_exit;
  13883. + }
  13884. + }
  13885. +#endif
  13886. +
  13887. +#ifdef _RTL8187_EXT_PATCH_
  13888. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
  13889. + {
  13890. + if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
  13891. + goto rx_dropped;
  13892. + }
  13893. + else
  13894. +#endif
  13895. + /* Nullfunc frames may have PS-bit set, so they must be passed to
  13896. + * hostap_handle_sta_rx() before being dropped here. */
  13897. + if (stype != IEEE80211_STYPE_DATA &&
  13898. + stype != IEEE80211_STYPE_DATA_CFACK &&
  13899. + stype != IEEE80211_STYPE_DATA_CFPOLL &&
  13900. + stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
  13901. + stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
  13902. + ) {
  13903. + if (stype != IEEE80211_STYPE_NULLFUNC)
  13904. + IEEE80211_DEBUG_DROP(
  13905. + "RX: dropped data frame "
  13906. + "with no data (type=0x%02x, "
  13907. + "subtype=0x%02x, len=%d)\n",
  13908. + type, stype, skb->len);
  13909. + goto rx_dropped;
  13910. + }
  13911. +
  13912. + if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
  13913. + goto rx_dropped;
  13914. +
  13915. + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
  13916. +#ifdef _RTL8187_EXT_PATCH_
  13917. + if (ieee->host_decrypt && crypt) {
  13918. + int idx = 0;
  13919. + if (skb->len >= hdrlen + 3)
  13920. + idx = skb->data[hdrlen + 3] >> 6;
  13921. + if (ieee->iw_ext_mode == ieee->iw_mode) //if in mesh mode
  13922. + {
  13923. + int i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*)skb->data)->addr2, 0);
  13924. + if (i == -1)
  13925. + {
  13926. + printk("error find entry in entry list\n");
  13927. + goto rx_dropped;
  13928. + }
  13929. + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)skb->data)->addr2), i);
  13930. + if (ieee->cryptlist[i]&&ieee->cryptlist[i]->crypt[idx])
  13931. + crypt = ieee->cryptlist[i]->crypt[idx];
  13932. +
  13933. + else
  13934. + crypt = NULL;
  13935. + }
  13936. + else
  13937. + crypt = ieee->cryptlist[0]->crypt[idx];
  13938. + }
  13939. +#endif
  13940. +
  13941. + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  13942. + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
  13943. + goto rx_dropped;
  13944. +
  13945. + hdr = (struct ieee80211_hdr *) skb->data;
  13946. +
  13947. + /* skb: hdr + (possibly fragmented) plaintext payload */
  13948. + // PR: FIXME: hostap has additional conditions in the "if" below:
  13949. + // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  13950. + if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
  13951. + int flen;
  13952. + struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
  13953. + IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
  13954. +
  13955. + if (!frag_skb) {
  13956. + IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
  13957. + "Rx cannot get skb from fragment "
  13958. + "cache (morefrag=%d seq=%u frag=%u)\n",
  13959. + (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
  13960. + WLAN_GET_SEQ_SEQ(sc), frag);
  13961. + goto rx_dropped;
  13962. + }
  13963. + flen = skb->len;
  13964. + if (frag != 0)
  13965. + flen -= hdrlen;
  13966. +
  13967. + if (frag_skb->tail + flen > frag_skb->end) {
  13968. + printk(KERN_WARNING "%s: host decrypted and "
  13969. + "reassembled frame did not fit skb\n",
  13970. + dev->name);
  13971. + ieee80211_frag_cache_invalidate(ieee, hdr);
  13972. + goto rx_dropped;
  13973. + }
  13974. +
  13975. + if (frag == 0) {
  13976. + /* copy first fragment (including full headers) into
  13977. + * beginning of the fragment cache skb */
  13978. + memcpy(skb_put(frag_skb, flen), skb->data, flen);
  13979. + } else {
  13980. + /* append frame payload to the end of the fragment
  13981. + * cache skb */
  13982. + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
  13983. + flen);
  13984. + }
  13985. + dev_kfree_skb_any(skb);
  13986. + skb = NULL;
  13987. +
  13988. + if (fc & IEEE80211_FCTL_MOREFRAGS) {
  13989. + /* more fragments expected - leave the skb in fragment
  13990. + * cache for now; it will be delivered to upper layers
  13991. + * after all fragments have been received */
  13992. + goto rx_exit;
  13993. + }
  13994. +
  13995. + /* this was the last fragment and the frame will be
  13996. + * delivered, so remove skb from fragment cache */
  13997. + skb = frag_skb;
  13998. + hdr = (struct ieee80211_hdr *) skb->data;
  13999. + ieee80211_frag_cache_invalidate(ieee, hdr);
  14000. + }
  14001. +
  14002. + /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
  14003. + * encrypted/authenticated */
  14004. + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  14005. + ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
  14006. + goto rx_dropped;
  14007. +
  14008. + hdr = (struct ieee80211_hdr *) skb->data;
  14009. + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
  14010. + if (/*ieee->ieee802_1x &&*/
  14011. + ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  14012. +
  14013. +#ifdef CONFIG_IEEE80211_DEBUG
  14014. + /* pass unencrypted EAPOL frames even if encryption is
  14015. + * configured */
  14016. + struct eapol *eap = (struct eapol *)(skb->data +
  14017. + 24);
  14018. + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
  14019. + eap_get_type(eap->type));
  14020. +#endif
  14021. + } else {
  14022. + IEEE80211_DEBUG_DROP(
  14023. + "encryption configured, but RX "
  14024. + "frame not encrypted (SA=" MAC_FMT ")\n",
  14025. + MAC_ARG(hdr->addr2));
  14026. + goto rx_dropped;
  14027. + }
  14028. + }
  14029. +
  14030. +#ifdef CONFIG_IEEE80211_DEBUG
  14031. + if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
  14032. + ieee80211_is_eapol_frame(ieee, skb)) {
  14033. + struct eapol *eap = (struct eapol *)(skb->data +
  14034. + 24);
  14035. + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
  14036. + eap_get_type(eap->type));
  14037. + }
  14038. +#endif
  14039. +
  14040. + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
  14041. + !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  14042. + IEEE80211_DEBUG_DROP(
  14043. + "dropped unencrypted RX data "
  14044. + "frame from " MAC_FMT
  14045. + " (drop_unencrypted=1)\n",
  14046. + MAC_ARG(hdr->addr2));
  14047. + goto rx_dropped;
  14048. + }
  14049. +/*
  14050. + if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  14051. + printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
  14052. + }
  14053. +*/
  14054. + /* skb: hdr + (possible reassembled) full plaintext payload */
  14055. + payload = skb->data + hdrlen;
  14056. + ethertype = (payload[6] << 8) | payload[7];
  14057. +
  14058. +#ifdef NOT_YET
  14059. + /* If IEEE 802.1X is used, check whether the port is authorized to send
  14060. + * the received frame. */
  14061. + if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
  14062. + if (ethertype == ETH_P_PAE) {
  14063. + printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
  14064. + dev->name);
  14065. + if (ieee->hostapd && ieee->apdev) {
  14066. + /* Send IEEE 802.1X frames to the user
  14067. + * space daemon for processing */
  14068. + prism2_rx_80211(ieee->apdev, skb, rx_stats,
  14069. + PRISM2_RX_MGMT);
  14070. + ieee->apdevstats.rx_packets++;
  14071. + ieee->apdevstats.rx_bytes += skb->len;
  14072. + goto rx_exit;
  14073. + }
  14074. + } else if (!frame_authorized) {
  14075. + printk(KERN_DEBUG "%s: dropped frame from "
  14076. + "unauthorized port (IEEE 802.1X): "
  14077. + "ethertype=0x%04x\n",
  14078. + dev->name, ethertype);
  14079. + goto rx_dropped;
  14080. + }
  14081. + }
  14082. +#endif
  14083. +
  14084. +#ifdef _RTL8187_EXT_PATCH_
  14085. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
  14086. + {
  14087. + if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
  14088. + {
  14089. + stats->rx_packets++;
  14090. + stats->rx_bytes += skb->len;
  14091. + goto rx_exit;
  14092. + }
  14093. + else
  14094. + goto rx_dropped;
  14095. + }
  14096. +#endif
  14097. + ieee->NumRxDataInPeriod++;
  14098. +// ieee->NumRxOkTotal++;
  14099. + /* convert hdr + possible LLC headers into Ethernet header */
  14100. + if (skb->len - hdrlen >= 8 &&
  14101. + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
  14102. + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
  14103. + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
  14104. + /* remove RFC1042 or Bridge-Tunnel encapsulation and
  14105. + * replace EtherType */
  14106. + skb_pull(skb, hdrlen + SNAP_SIZE);
  14107. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  14108. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  14109. + } else {
  14110. + u16 len;
  14111. + /* Leave Ethernet header part of hdr and full payload */
  14112. + skb_pull(skb, hdrlen);
  14113. + len = htons(skb->len);
  14114. + memcpy(skb_push(skb, 2), &len, 2);
  14115. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  14116. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  14117. + }
  14118. +
  14119. +#ifdef NOT_YET
  14120. + if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  14121. + IEEE80211_FCTL_TODS) &&
  14122. + skb->len >= ETH_HLEN + ETH_ALEN) {
  14123. + /* Non-standard frame: get addr4 from its bogus location after
  14124. + * the payload */
  14125. + memcpy(skb->data + ETH_ALEN,
  14126. + skb->data + skb->len - ETH_ALEN, ETH_ALEN);
  14127. + skb_trim(skb, skb->len - ETH_ALEN);
  14128. + }
  14129. +#endif
  14130. +
  14131. + stats->rx_packets++;
  14132. + stats->rx_bytes += skb->len;
  14133. +
  14134. +#ifdef NOT_YET
  14135. + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
  14136. + ieee->ap->bridge_packets) {
  14137. + if (dst[0] & 0x01) {
  14138. + /* copy multicast frame both to the higher layers and
  14139. + * to the wireless media */
  14140. + ieee->ap->bridged_multicast++;
  14141. + skb2 = skb_clone(skb, GFP_ATOMIC);
  14142. + if (skb2 == NULL)
  14143. + printk(KERN_DEBUG "%s: skb_clone failed for "
  14144. + "multicast frame\n", dev->name);
  14145. + } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
  14146. + /* send frame directly to the associated STA using
  14147. + * wireless media and not passing to higher layers */
  14148. + ieee->ap->bridged_unicast++;
  14149. + skb2 = skb;
  14150. + skb = NULL;
  14151. + }
  14152. + }
  14153. +
  14154. + if (skb2 != NULL) {
  14155. + /* send to wireless media */
  14156. + skb2->protocol = __constant_htons(ETH_P_802_3);
  14157. + skb2->mac.raw = skb2->nh.raw = skb2->data;
  14158. + /* skb2->nh.raw = skb2->data + ETH_HLEN; */
  14159. + skb2->dev = dev;
  14160. + dev_queue_xmit(skb2);
  14161. + }
  14162. +
  14163. +#endif
  14164. + if (skb) {
  14165. + //printk("0skb_len(%d)\n", skb->len);
  14166. + skb->protocol = eth_type_trans(skb, dev);
  14167. + memset(skb->cb, 0, sizeof(skb->cb));
  14168. + skb->dev = dev;
  14169. + skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
  14170. + //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
  14171. + ieee->last_rx_ps_time = jiffies;
  14172. + //printk("1skb_len(%d)\n", skb->len);
  14173. + netif_rx(skb);
  14174. + }
  14175. +
  14176. +//by lizhaoming for LED_RX 2008.6.23
  14177. +#ifdef LED_SHIN
  14178. +// printk("==================>data rcvd\n");
  14179. + ieee->ieee80211_led_contorl(dev,LED_CTL_RX);
  14180. +#endif
  14181. +
  14182. + rx_exit:
  14183. +#ifdef NOT_YET
  14184. + if (sta)
  14185. + hostap_handle_sta_release(sta);
  14186. +#endif
  14187. + return 1;
  14188. +
  14189. + rx_dropped:
  14190. + stats->rx_dropped++;
  14191. +#if 0
  14192. + int i;
  14193. + 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);
  14194. + for (i = 0; i < skb->len; i++) {
  14195. + if (i % 16 == 0) printk("\n\t");
  14196. + printk("%2x ", *(skb->data+i));
  14197. + }
  14198. +
  14199. + printk("\n");
  14200. +#endif
  14201. + /* Returning 0 indicates to caller that we have not handled the SKB--
  14202. + * so it is still allocated and can be used again by underlying
  14203. + * hardware as a DMA target */
  14204. + return 0;
  14205. +}
  14206. +
  14207. +#ifdef _RTL8187_EXT_PATCH_
  14208. +int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
  14209. +{
  14210. + u8 *payload;
  14211. + u16 ethertype;
  14212. +
  14213. + /* skb: hdr + (possible reassembled) full plaintext payload */
  14214. + payload = skb->data + hdrlen;
  14215. + ethertype = (payload[6] << 8) | payload[7];
  14216. +
  14217. + /* convert hdr + possible LLC headers into Ethernet header */
  14218. + if (skb->len - hdrlen >= 8 &&
  14219. + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
  14220. + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
  14221. + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
  14222. + /* remove RFC1042 or Bridge-Tunnel encapsulation and
  14223. + * replace EtherType */
  14224. + skb_pull(skb, hdrlen + SNAP_SIZE);
  14225. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  14226. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  14227. + } else {
  14228. + u16 len;
  14229. + /* Leave Ethernet header part of hdr and full payload */
  14230. + skb_pull(skb, hdrlen);
  14231. + len = htons(skb->len);
  14232. + memcpy(skb_push(skb, 2), &len, 2);
  14233. + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  14234. + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  14235. + }
  14236. +
  14237. + return 1;
  14238. +}
  14239. +#endif // _RTL8187_EXT_PATCH_
  14240. +
  14241. +
  14242. +#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
  14243. +
  14244. +static inline int ieee80211_is_ofdm_rate(u8 rate)
  14245. +{
  14246. + switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
  14247. + case IEEE80211_OFDM_RATE_6MB:
  14248. + case IEEE80211_OFDM_RATE_9MB:
  14249. + case IEEE80211_OFDM_RATE_12MB:
  14250. + case IEEE80211_OFDM_RATE_18MB:
  14251. + case IEEE80211_OFDM_RATE_24MB:
  14252. + case IEEE80211_OFDM_RATE_36MB:
  14253. + case IEEE80211_OFDM_RATE_48MB:
  14254. + case IEEE80211_OFDM_RATE_54MB:
  14255. + return 1;
  14256. + }
  14257. + return 0;
  14258. +}
  14259. +
  14260. +
  14261. +//
  14262. +// Description:
  14263. +// Translate 0-100 signal strength index into dBm.
  14264. +//
  14265. +int
  14266. +TranslateToDbm8187(
  14267. + unsigned char SignalStrengthIndex // 0-100 index.
  14268. + )
  14269. +{
  14270. + unsigned char SignalPower; // in dBm.
  14271. +
  14272. + // Translate to dBm (x=0.5y-95).
  14273. + //SignalPower = (int)((SignalStrengthIndex + 1) >> 1);
  14274. + SignalPower = (int)SignalStrengthIndex * 7 / 10;
  14275. + SignalPower -= 95;
  14276. +// printk("==>SignalPower:%d\n", SignalPower);
  14277. + return SignalPower;
  14278. +}
  14279. +
  14280. +static inline int ieee80211_SignalStrengthTranslate(
  14281. + int CurrSS
  14282. + )
  14283. +{
  14284. + int RetSS;
  14285. +
  14286. + // Step 1. Scale mapping.
  14287. + if(CurrSS >= 71 && CurrSS <= 100)
  14288. + {
  14289. + RetSS = 95 + (((CurrSS - 70) / 6 == 5) ? 5 : ((CurrSS - 70) / 6 + 1));
  14290. + }
  14291. + else if(CurrSS >= 41 && CurrSS <= 70)
  14292. + {
  14293. + RetSS = 83 + ((CurrSS - 40) / 3);
  14294. + }
  14295. + else if(CurrSS >= 31 && CurrSS <= 40)
  14296. + {
  14297. + RetSS = 71 + (CurrSS - 30);
  14298. + }
  14299. + else if(CurrSS >= 21 && CurrSS <= 30)
  14300. + {
  14301. + RetSS = 59 + (CurrSS - 20);
  14302. + }
  14303. + else if(CurrSS >= 5 && CurrSS <= 20)
  14304. + {
  14305. + RetSS = 47 + (((CurrSS - 5) * 2) / 3);
  14306. + }
  14307. + else if(CurrSS == 4)
  14308. + {
  14309. + RetSS = 37;
  14310. + }
  14311. + else if(CurrSS == 3)
  14312. + {
  14313. + RetSS = 27;
  14314. + }
  14315. + else if(CurrSS == 2)
  14316. + {
  14317. + RetSS = 18;
  14318. + }
  14319. + else if(CurrSS == 1)
  14320. + {
  14321. + RetSS = 9;
  14322. + }
  14323. + else
  14324. + {
  14325. + RetSS = CurrSS;
  14326. + }
  14327. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  14328. +
  14329. + // Step 2. Smoothing.
  14330. +
  14331. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  14332. +
  14333. + return RetSS;
  14334. +}
  14335. +
  14336. +#ifdef ENABLE_DOT11D
  14337. +static inline void ieee80211_extract_country_ie(
  14338. + struct ieee80211_device *ieee,
  14339. + struct ieee80211_info_element *info_element,
  14340. + struct ieee80211_network *network,
  14341. + u8 * addr2
  14342. +)
  14343. +{
  14344. +#if 0
  14345. + u32 i = 0;
  14346. + u8 * p = (u8*)info_element->data;
  14347. + printk("-----------------------\n");
  14348. + printk("%s Country IE:", network->ssid);
  14349. + for(i=0; i<info_element->len; i++)
  14350. + printk("\t%2.2x", *(p+i));
  14351. + printk("\n-----------------------\n");
  14352. +#endif
  14353. + if(IS_DOT11D_ENABLE(ieee))
  14354. + {
  14355. + if(info_element->len!= 0)
  14356. + {
  14357. + memcpy(network->CountryIeBuf, info_element->data, info_element->len);
  14358. + network->CountryIeLen = info_element->len;
  14359. +
  14360. + if(!IS_COUNTRY_IE_VALID(ieee))
  14361. + {
  14362. + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
  14363. + }
  14364. + }
  14365. +
  14366. + //
  14367. + // 070305, rcnjko: I update country IE watch dog here because
  14368. + // some AP (e.g. Cisco 1242) don't include country IE in their
  14369. + // probe response frame.
  14370. + //
  14371. + if(IS_EQUAL_CIE_SRC(ieee, addr2) )
  14372. + {
  14373. + UPDATE_CIE_WATCHDOG(ieee);
  14374. + }
  14375. + }
  14376. +
  14377. +}
  14378. +#endif
  14379. +
  14380. +
  14381. + inline int ieee80211_network_init(
  14382. + struct ieee80211_device *ieee,
  14383. + struct ieee80211_probe_response *beacon,
  14384. + struct ieee80211_network *network,
  14385. + struct ieee80211_rx_stats *stats)
  14386. +{
  14387. +#ifdef CONFIG_IEEE80211_DEBUG
  14388. + char rates_str[64];
  14389. + char *p;
  14390. +#endif
  14391. + struct ieee80211_info_element *info_element;
  14392. + u16 left;
  14393. + u8 i;
  14394. + short offset;
  14395. +
  14396. + /* Pull out fixed field data */
  14397. + memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
  14398. + network->capability = beacon->capability;
  14399. + network->last_scanned = jiffies;
  14400. + network->time_stamp[0] = beacon->time_stamp[0];
  14401. + network->time_stamp[1] = beacon->time_stamp[1];
  14402. + network->beacon_interval = beacon->beacon_interval;
  14403. + /* Where to pull this? beacon->listen_interval;*/
  14404. + network->listen_interval = 0x0A;
  14405. + network->rates_len = network->rates_ex_len = 0;
  14406. + network->last_associate = 0;
  14407. + network->ssid_len = 0;
  14408. + network->flags = 0;
  14409. + network->atim_window = 0;
  14410. + network->QoS_Enable = 0;
  14411. +#ifdef THOMAS_TURBO
  14412. + network->Turbo_Enable = 0;
  14413. +#endif
  14414. +#ifdef ENABLE_DOT11D
  14415. + network->CountryIeLen = 0;
  14416. + memset(network->CountryIeBuf, 0, MAX_IE_LEN);
  14417. +#endif
  14418. +
  14419. + if (stats->freq == IEEE80211_52GHZ_BAND) {
  14420. + /* for A band (No DS info) */
  14421. + network->channel = stats->received_channel;
  14422. + } else
  14423. + network->flags |= NETWORK_HAS_CCK;
  14424. +
  14425. + network->wpa_ie_len = 0;
  14426. + network->rsn_ie_len = 0;
  14427. +
  14428. + info_element = &beacon->info_element;
  14429. + left = stats->len - ((void *)info_element - (void *)beacon);
  14430. + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
  14431. + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
  14432. + IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
  14433. + info_element->len + sizeof(struct ieee80211_info_element),
  14434. + left);
  14435. + return 1;
  14436. + }
  14437. +
  14438. + switch (info_element->id) {
  14439. + case MFIE_TYPE_SSID:
  14440. + if (ieee80211_is_empty_essid(info_element->data,
  14441. + info_element->len)) {
  14442. + network->flags |= NETWORK_EMPTY_ESSID;
  14443. + break;
  14444. + }
  14445. +
  14446. + network->ssid_len = min(info_element->len,
  14447. + (u8)IW_ESSID_MAX_SIZE);
  14448. + memcpy(network->ssid, info_element->data, network->ssid_len);
  14449. + if (network->ssid_len < IW_ESSID_MAX_SIZE)
  14450. + memset(network->ssid + network->ssid_len, 0,
  14451. + IW_ESSID_MAX_SIZE - network->ssid_len);
  14452. +
  14453. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
  14454. + network->ssid, network->ssid_len);
  14455. + break;
  14456. +
  14457. + case MFIE_TYPE_RATES:
  14458. +#ifdef CONFIG_IEEE80211_DEBUG
  14459. + p = rates_str;
  14460. +#endif
  14461. + network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
  14462. + for (i = 0; i < network->rates_len; i++) {
  14463. + network->rates[i] = info_element->data[i];
  14464. +#ifdef CONFIG_IEEE80211_DEBUG
  14465. + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
  14466. +#endif
  14467. + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
  14468. + network->flags |= NETWORK_HAS_OFDM;
  14469. + if (info_element->data[i] &
  14470. + IEEE80211_BASIC_RATE_MASK)
  14471. + network->flags &=
  14472. + ~NETWORK_HAS_CCK;
  14473. + }
  14474. + }
  14475. +
  14476. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
  14477. + rates_str, network->rates_len);
  14478. + break;
  14479. +
  14480. + case MFIE_TYPE_RATES_EX:
  14481. +#ifdef CONFIG_IEEE80211_DEBUG
  14482. + p = rates_str;
  14483. +#endif
  14484. + network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
  14485. + for (i = 0; i < network->rates_ex_len; i++) {
  14486. + network->rates_ex[i] = info_element->data[i];
  14487. +#ifdef CONFIG_IEEE80211_DEBUG
  14488. + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
  14489. +#endif
  14490. + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
  14491. + network->flags |= NETWORK_HAS_OFDM;
  14492. + if (info_element->data[i] &
  14493. + IEEE80211_BASIC_RATE_MASK)
  14494. + network->flags &=
  14495. + ~NETWORK_HAS_CCK;
  14496. + }
  14497. + }
  14498. +
  14499. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
  14500. + rates_str, network->rates_ex_len);
  14501. + break;
  14502. +
  14503. + case MFIE_TYPE_DS_SET:
  14504. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
  14505. + info_element->data[0]);
  14506. + if (stats->freq == IEEE80211_24GHZ_BAND)
  14507. + network->channel = info_element->data[0];
  14508. + break;
  14509. +
  14510. + case MFIE_TYPE_FH_SET:
  14511. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
  14512. + break;
  14513. +
  14514. + case MFIE_TYPE_CF_SET:
  14515. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
  14516. + break;
  14517. +
  14518. + case MFIE_TYPE_TIM:
  14519. +
  14520. + if(info_element->len < 4)
  14521. + break;
  14522. +
  14523. + network->dtim_period = info_element->data[1];
  14524. +
  14525. + if(ieee->state != IEEE80211_LINKED)
  14526. + break;
  14527. +
  14528. + network->last_dtim_sta_time[0] = stats->mac_time[0];
  14529. + network->last_dtim_sta_time[1] = stats->mac_time[1];
  14530. +
  14531. + network->dtim_data = IEEE80211_DTIM_VALID;
  14532. +
  14533. + if(info_element->data[0] != 0)
  14534. + break;
  14535. +
  14536. + if(info_element->data[2] & 1)
  14537. + network->dtim_data |= IEEE80211_DTIM_MBCAST;
  14538. +
  14539. + offset = (info_element->data[2] >> 1)*2;
  14540. +
  14541. + //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
  14542. +
  14543. + if(ieee->assoc_id < offset ||
  14544. + ieee->assoc_id > 8*(offset + info_element->len -3))
  14545. +
  14546. + break;
  14547. +
  14548. +
  14549. + offset = offset + ieee->assoc_id / 8;// + ((aid % 8)? 0 : 1) ;
  14550. +
  14551. + // printk("offset:%x data:%x, ucast:%d\n", offset,
  14552. + // info_element->data[3+offset] ,
  14553. + // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
  14554. +
  14555. + if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
  14556. + network->dtim_data |= IEEE80211_DTIM_UCAST;
  14557. +
  14558. + break;
  14559. +
  14560. + case MFIE_TYPE_IBSS_SET:
  14561. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
  14562. + break;
  14563. +
  14564. + case MFIE_TYPE_CHALLENGE:
  14565. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
  14566. + break;
  14567. +
  14568. + case MFIE_TYPE_GENERIC:
  14569. + //nic is 87B
  14570. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
  14571. + info_element->len);
  14572. + if (info_element->len >= 4 &&
  14573. + info_element->data[0] == 0x00 &&
  14574. + info_element->data[1] == 0x50 &&
  14575. + info_element->data[2] == 0xf2 &&
  14576. + info_element->data[3] == 0x01) {
  14577. + network->wpa_ie_len = min(info_element->len + 2,
  14578. + MAX_WPA_IE_LEN);
  14579. + memcpy(network->wpa_ie, info_element,
  14580. + network->wpa_ie_len);
  14581. + }
  14582. +
  14583. +#ifdef THOMAS_TURBO
  14584. + if (info_element->len == 7 &&
  14585. + info_element->data[0] == 0x00 &&
  14586. + info_element->data[1] == 0xe0 &&
  14587. + info_element->data[2] == 0x4c &&
  14588. + info_element->data[3] == 0x01 &&
  14589. + info_element->data[4] == 0x02) {
  14590. + network->Turbo_Enable = 1;
  14591. + }
  14592. +#endif
  14593. + if (1 == stats->nic_type) {//nic 87
  14594. + break;
  14595. + }
  14596. +
  14597. + if (info_element->len >= 5 &&
  14598. + info_element->data[0] == 0x00 &&
  14599. + info_element->data[1] == 0x50 &&
  14600. + info_element->data[2] == 0xf2 &&
  14601. + info_element->data[3] == 0x02 &&
  14602. + info_element->data[4] == 0x00) {
  14603. + //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
  14604. + //WMM Information Element
  14605. + network->wmm_info = info_element->data[6];
  14606. + network->QoS_Enable = 1;
  14607. + }
  14608. +
  14609. + if (info_element->len >= 8 &&
  14610. + info_element->data[0] == 0x00 &&
  14611. + info_element->data[1] == 0x50 &&
  14612. + info_element->data[2] == 0xf2 &&
  14613. + info_element->data[3] == 0x02 &&
  14614. + info_element->data[4] == 0x01) {
  14615. + // Not care about version at present.
  14616. + //WMM Information Element
  14617. + //printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
  14618. + network->wmm_info = info_element->data[6];
  14619. + //WMM Parameter Element
  14620. + memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
  14621. + network->QoS_Enable = 1;
  14622. + }
  14623. + break;
  14624. +
  14625. + case MFIE_TYPE_RSN:
  14626. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
  14627. + info_element->len);
  14628. + network->rsn_ie_len = min(info_element->len + 2,
  14629. + MAX_WPA_IE_LEN);
  14630. + memcpy(network->rsn_ie, info_element,
  14631. + network->rsn_ie_len);
  14632. + break;
  14633. +
  14634. +#ifdef ENABLE_DOT11D
  14635. + case MFIE_TYPE_COUNTRY:
  14636. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
  14637. + info_element->len);
  14638. +// printk("=====>Receive <%s> Country IE\n",network->ssid);
  14639. + ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
  14640. + break;
  14641. +#endif
  14642. +
  14643. + default:
  14644. + IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
  14645. + info_element->id);
  14646. + break;
  14647. + }
  14648. +
  14649. + left -= sizeof(struct ieee80211_info_element_hdr) +
  14650. + info_element->len;
  14651. + info_element = (struct ieee80211_info_element *)
  14652. + &info_element->data[info_element->len];
  14653. + }
  14654. +
  14655. + network->mode = 0;
  14656. + if (stats->freq == IEEE80211_52GHZ_BAND)
  14657. + network->mode = IEEE_A;
  14658. + else {
  14659. + if (network->flags & NETWORK_HAS_OFDM)
  14660. + network->mode |= IEEE_G;
  14661. + if (network->flags & NETWORK_HAS_CCK)
  14662. + network->mode |= IEEE_B;
  14663. + }
  14664. +
  14665. + if (network->mode == 0) {
  14666. + IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
  14667. + "network.\n",
  14668. + escape_essid(network->ssid,
  14669. + network->ssid_len),
  14670. + MAC_ARG(network->bssid));
  14671. + return 1;
  14672. + }
  14673. +
  14674. + if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
  14675. + network->flags |= NETWORK_EMPTY_ESSID;
  14676. +
  14677. +#if 1
  14678. + //if(strcmp(network->ssid, "linksys_lzm000") == 0)
  14679. + // printk("----signalstrength = %d ", stats->signalstrength);
  14680. + stats->signal = TranslateToDbm8187(stats->signalstrength);
  14681. + //stats->noise = stats->signal - stats->noise;
  14682. + stats->noise = TranslateToDbm8187(100 - stats->signalstrength) - 25;
  14683. +#endif
  14684. + memcpy(&network->stats, stats, sizeof(network->stats));
  14685. +
  14686. + //YJ,test,080611
  14687. + //if(strcmp(network->ssid, "ZyXEL") == 0)
  14688. + // IEEE_NET_DUMP(network);
  14689. +
  14690. + return 0;
  14691. +}
  14692. +
  14693. +static inline int is_same_network(struct ieee80211_network *src,
  14694. + struct ieee80211_network *dst,
  14695. + struct ieee80211_device * ieee)
  14696. +{
  14697. + /* A network is only a duplicate if the channel, BSSID, ESSID
  14698. + * and the capability field (in particular IBSS and BSS) all match.
  14699. + * We treat all <hidden> with the same BSSID and channel
  14700. + * as one network */
  14701. + return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
  14702. + //((src->ssid_len == dst->ssid_len) &&
  14703. + (src->channel == dst->channel) &&
  14704. + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
  14705. + (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
  14706. + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
  14707. + ((src->capability & WLAN_CAPABILITY_IBSS) ==
  14708. + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
  14709. + ((src->capability & WLAN_CAPABILITY_BSS) ==
  14710. + (dst->capability & WLAN_CAPABILITY_BSS)));
  14711. +}
  14712. +
  14713. +inline void update_network(struct ieee80211_network *dst,
  14714. + struct ieee80211_network *src)
  14715. +{
  14716. + unsigned char quality = src->stats.signalstrength;
  14717. + unsigned char signal = 0;
  14718. + unsigned char noise = 0;
  14719. + if(dst->stats.signalstrength > 0) {
  14720. + quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
  14721. + }
  14722. + signal = TranslateToDbm8187(quality);
  14723. + //noise = signal - src->stats.noise;
  14724. + if(dst->stats.noise > 0)
  14725. + noise = (dst->stats.noise * 5 + src->stats.noise)/6;
  14726. + //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
  14727. +// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
  14728. + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
  14729. + dst->stats.signalstrength = quality;
  14730. + dst->stats.signal = signal;
  14731. + dst->stats.noise = noise;
  14732. + dst->capability = src->capability;
  14733. + memcpy(dst->rates, src->rates, src->rates_len);
  14734. + dst->rates_len = src->rates_len;
  14735. + memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
  14736. + dst->rates_ex_len = src->rates_ex_len;
  14737. +
  14738. + //YJ,add,080819,for hidden ap
  14739. + if(src->ssid_len > 0)
  14740. + {
  14741. + //if(src->ssid_len == 13)
  14742. + // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
  14743. + memset(dst->ssid, 0, dst->ssid_len);
  14744. + dst->ssid_len = src->ssid_len;
  14745. + memcpy(dst->ssid, src->ssid, src->ssid_len);
  14746. + }
  14747. + //YJ,add,080819,for hidden ap,end
  14748. + dst->channel = src->channel;
  14749. + dst->mode = src->mode;
  14750. + dst->flags = src->flags;
  14751. + dst->time_stamp[0] = src->time_stamp[0];
  14752. + dst->time_stamp[1] = src->time_stamp[1];
  14753. +
  14754. + dst->beacon_interval = src->beacon_interval;
  14755. + dst->listen_interval = src->listen_interval;
  14756. + dst->atim_window = src->atim_window;
  14757. + dst->dtim_period = src->dtim_period;
  14758. + dst->dtim_data = src->dtim_data;
  14759. + dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
  14760. + dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
  14761. +
  14762. + memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
  14763. + dst->wpa_ie_len = src->wpa_ie_len;
  14764. + memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
  14765. + dst->rsn_ie_len = src->rsn_ie_len;
  14766. +
  14767. + dst->last_scanned = jiffies;
  14768. + /* dst->last_associate is not overwritten */
  14769. +#if 1
  14770. + dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
  14771. +/*
  14772. + if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
  14773. + memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
  14774. + }
  14775. +*/
  14776. + if(src->wmm_param[0].ac_aci_acm_aifsn|| \
  14777. + src->wmm_param[1].ac_aci_acm_aifsn|| \
  14778. + src->wmm_param[2].ac_aci_acm_aifsn|| \
  14779. + src->wmm_param[1].ac_aci_acm_aifsn) {
  14780. + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
  14781. + }
  14782. + dst->QoS_Enable = src->QoS_Enable;
  14783. +#else
  14784. + dst->QoS_Enable = 1;//for Rtl8187 simulation
  14785. +#endif
  14786. + dst->SignalStrength = src->SignalStrength;
  14787. +#ifdef THOMAS_TURBO
  14788. + dst->Turbo_Enable = src->Turbo_Enable;
  14789. +#endif
  14790. +#ifdef ENABLE_DOT11D
  14791. + dst->CountryIeLen = src->CountryIeLen;
  14792. + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
  14793. +#endif
  14794. +
  14795. +}
  14796. +
  14797. +inline void ieee80211_process_probe_response(
  14798. + struct ieee80211_device *ieee,
  14799. + struct ieee80211_probe_response *beacon,
  14800. + struct ieee80211_rx_stats *stats)
  14801. +{
  14802. + struct ieee80211_network network;
  14803. + struct ieee80211_network *target;
  14804. + struct ieee80211_network *oldest = NULL;
  14805. +#ifdef CONFIG_IEEE80211_DEBUG
  14806. + struct ieee80211_info_element *info_element = &beacon->info_element;
  14807. +#endif
  14808. + unsigned long flags;
  14809. + short renew;
  14810. + u8 wmm_info;
  14811. + u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0;
  14812. +
  14813. + memset(&network, 0, sizeof(struct ieee80211_network));
  14814. +//rz
  14815. +#ifdef _RTL8187_EXT_PATCH_
  14816. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) {
  14817. + ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats);
  14818. + return;
  14819. + }
  14820. +#endif
  14821. + IEEE80211_DEBUG_SCAN(
  14822. + "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
  14823. + escape_essid(info_element->data, info_element->len),
  14824. + MAC_ARG(beacon->header.addr3),
  14825. + (beacon->capability & (1<<0xf)) ? '1' : '0',
  14826. + (beacon->capability & (1<<0xe)) ? '1' : '0',
  14827. + (beacon->capability & (1<<0xd)) ? '1' : '0',
  14828. + (beacon->capability & (1<<0xc)) ? '1' : '0',
  14829. + (beacon->capability & (1<<0xb)) ? '1' : '0',
  14830. + (beacon->capability & (1<<0xa)) ? '1' : '0',
  14831. + (beacon->capability & (1<<0x9)) ? '1' : '0',
  14832. + (beacon->capability & (1<<0x8)) ? '1' : '0',
  14833. + (beacon->capability & (1<<0x7)) ? '1' : '0',
  14834. + (beacon->capability & (1<<0x6)) ? '1' : '0',
  14835. + (beacon->capability & (1<<0x5)) ? '1' : '0',
  14836. + (beacon->capability & (1<<0x4)) ? '1' : '0',
  14837. + (beacon->capability & (1<<0x3)) ? '1' : '0',
  14838. + (beacon->capability & (1<<0x2)) ? '1' : '0',
  14839. + (beacon->capability & (1<<0x1)) ? '1' : '0',
  14840. + (beacon->capability & (1<<0x0)) ? '1' : '0');
  14841. +
  14842. + if (ieee80211_network_init(ieee, beacon, &network, stats)) {
  14843. + IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
  14844. + escape_essid(info_element->data,
  14845. + info_element->len),
  14846. + MAC_ARG(beacon->header.addr3),
  14847. + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  14848. + IEEE80211_STYPE_PROBE_RESP ?
  14849. + "PROBE RESPONSE" : "BEACON");
  14850. + return;
  14851. + }
  14852. +
  14853. +#ifdef ENABLE_DOT11D
  14854. + // For Asus EeePc request,
  14855. + // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
  14856. + // wireless adapter should follow the country code.
  14857. + // (2) If there is no any country code in beacon,
  14858. + // then wireless adapter should do active scan from ch1~11 and
  14859. + // passive scan from ch12~14
  14860. + if(ieee->bGlobalDomain)
  14861. + {
  14862. + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
  14863. + {
  14864. + // Case 1: Country code
  14865. + if(IS_COUNTRY_IE_VALID(ieee) )
  14866. + {
  14867. + if( !IsLegalChannel(ieee, network.channel) )
  14868. + {
  14869. + printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
  14870. + return;
  14871. + }
  14872. + }
  14873. + // Case 2: No any country code.
  14874. + else
  14875. + {
  14876. + // Filter over channel ch12~14
  14877. + if(network.channel > 11)
  14878. + {
  14879. + printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
  14880. + return;
  14881. + }
  14882. + }
  14883. + }
  14884. + else
  14885. + {
  14886. + // Case 1: Country code
  14887. + if(IS_COUNTRY_IE_VALID(ieee) )
  14888. + {
  14889. + if( !IsLegalChannel(ieee, network.channel) )
  14890. + {
  14891. + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
  14892. + return;
  14893. + }
  14894. + }
  14895. + // Case 2: No any country code.
  14896. + else
  14897. + {
  14898. + // Filter over channel ch12~14
  14899. + if(network.channel > 14)
  14900. + {
  14901. + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
  14902. + return;
  14903. + }
  14904. + }
  14905. + }
  14906. + }
  14907. +
  14908. + //lzm add 081205
  14909. + // for Toshiba request, we use channel_plan COUNTRY_CODE_WORLD_WIDE_13_INDEX,
  14910. + // For Liteon "World Wide 13" Domain name:ch1~11 active scan & ch12~13 passive scan
  14911. + // So we shoud only rcv beacon in 12-13, and filter probe resp in 12-13.
  14912. + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
  14913. + {
  14914. + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
  14915. + {
  14916. + // Filter over channel ch12~13
  14917. + if(network.channel >= ieee->MinPassiveChnlNum)
  14918. + {
  14919. + printk("GetScanInfo(): passive scan, filter probe resp at channel(%d).\n", network.channel);
  14920. + return;
  14921. + }
  14922. + }
  14923. + }
  14924. +#endif
  14925. +
  14926. +
  14927. + /* The network parsed correctly -- so now we scan our known networks
  14928. + * to see if we can find it in our list.
  14929. + *
  14930. + * NOTE: This search is definitely not optimized. Once its doing
  14931. + * the "right thing" we'll optimize it for efficiency if
  14932. + * necessary */
  14933. +
  14934. + /* Search for this entry in the list and update it if it is
  14935. + * already there. */
  14936. +
  14937. + spin_lock_irqsave(&ieee->lock, flags);
  14938. +
  14939. + if(is_same_network(&ieee->current_network, &network, ieee)) {
  14940. + //YJ,add,080819,for hidden ap
  14941. + if(is_beacon == 0)
  14942. + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
  14943. + if ((ieee->state == IEEE80211_LINKED) && is_beacon)
  14944. + ieee->NumRxBcnInPeriod++;
  14945. + wmm_info = ieee->current_network.wmm_info;
  14946. + update_network(&ieee->current_network, &network);
  14947. + }
  14948. +
  14949. + list_for_each_entry(target, &ieee->network_list, list) {
  14950. + if (is_same_network(target, &network, ieee))
  14951. + break;
  14952. + if ((oldest == NULL) ||
  14953. + (target->last_scanned < oldest->last_scanned))
  14954. + oldest = target;
  14955. + }
  14956. +
  14957. + /* If we didn't find a match, then get a new network slot to initialize
  14958. + * with this beacon's information */
  14959. + if (&target->list == &ieee->network_list) {
  14960. + if (list_empty(&ieee->network_free_list)) {
  14961. + /* If there are no more slots, expire the oldest */
  14962. + list_del(&oldest->list);
  14963. + target = oldest;
  14964. + IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
  14965. + "network list.\n",
  14966. + escape_essid(target->ssid,
  14967. + target->ssid_len),
  14968. + MAC_ARG(target->bssid));
  14969. + } else {
  14970. + /* Otherwise just pull from the free list */
  14971. + target = list_entry(ieee->network_free_list.next,
  14972. + struct ieee80211_network, list);
  14973. + list_del(ieee->network_free_list.next);
  14974. + }
  14975. +
  14976. +
  14977. +#ifdef CONFIG_IEEE80211_DEBUG
  14978. + IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
  14979. + escape_essid(network.ssid,
  14980. + network.ssid_len),
  14981. + MAC_ARG(network.bssid),
  14982. + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  14983. + IEEE80211_STYPE_PROBE_RESP ?
  14984. + "PROBE RESPONSE" : "BEACON");
  14985. +#endif
  14986. +
  14987. +#ifdef _RTL8187_EXT_PATCH_
  14988. + network.ext_entry = target->ext_entry;
  14989. +#endif
  14990. + memcpy(target, &network, sizeof(*target));
  14991. + list_add_tail(&target->list, &ieee->network_list);
  14992. + if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
  14993. + ieee80211_softmac_new_net(ieee,&network);
  14994. + } else {
  14995. + IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
  14996. + escape_essid(target->ssid,
  14997. + target->ssid_len),
  14998. + MAC_ARG(target->bssid),
  14999. + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  15000. + IEEE80211_STYPE_PROBE_RESP ?
  15001. + "PROBE RESPONSE" : "BEACON");
  15002. +
  15003. + /* we have an entry and we are going to update it. But this entry may
  15004. + * be already expired. In this case we do the same as we found a new
  15005. + * net and call the new_net handler
  15006. + */
  15007. + renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
  15008. + //YJ,add,080819,for hidden ap
  15009. + if(is_beacon == 0)
  15010. + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
  15011. + //if(strncmp(network.ssid, "linksys-c",9) == 0)
  15012. + // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
  15013. + if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
  15014. + && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
  15015. + ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
  15016. + renew = 1;
  15017. + //YJ,add,080819,for hidden ap,end
  15018. + update_network(target, &network);
  15019. + if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
  15020. + ieee80211_softmac_new_net(ieee,&network);
  15021. + }
  15022. +
  15023. + spin_unlock_irqrestore(&ieee->lock, flags);
  15024. +}
  15025. +
  15026. +void ieee80211_rx_mgt(struct ieee80211_device *ieee,
  15027. + struct ieee80211_hdr *header,
  15028. + struct ieee80211_rx_stats *stats)
  15029. +{
  15030. + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
  15031. +
  15032. + case IEEE80211_STYPE_BEACON:
  15033. + IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
  15034. + WLAN_FC_GET_STYPE(header->frame_ctl));
  15035. + IEEE80211_DEBUG_SCAN("Beacon\n");
  15036. + ieee80211_process_probe_response(
  15037. + ieee, (struct ieee80211_probe_response *)header, stats);
  15038. + break;
  15039. +
  15040. + case IEEE80211_STYPE_PROBE_RESP:
  15041. + IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
  15042. + WLAN_FC_GET_STYPE(header->frame_ctl));
  15043. + IEEE80211_DEBUG_SCAN("Probe response\n");
  15044. + ieee80211_process_probe_response(
  15045. + ieee, (struct ieee80211_probe_response *)header, stats);
  15046. + break;
  15047. +//rz
  15048. +#ifdef _RTL8187_EXT_PATCH_
  15049. + case IEEE80211_STYPE_PROBE_REQ:
  15050. + IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n",
  15051. + WLAN_FC_GET_STYPE(header->frame_ctl));
  15052. + IEEE80211_DEBUG_SCAN("Probe request\n");
  15053. + ///
  15054. + //printk("Probe request\n");
  15055. + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req )
  15056. + ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats);
  15057. + break;
  15058. +#endif // _RTL8187_EXT_PATCH_
  15059. +
  15060. + }
  15061. +}
  15062. +
  15063. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  15064. +EXPORT_SYMBOL(ieee80211_rx_mgt);
  15065. +EXPORT_SYMBOL(ieee80211_rx);
  15066. +EXPORT_SYMBOL(ieee80211_network_init);
  15067. +#ifdef _RTL8187_EXT_PATCH_
  15068. +EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether);
  15069. +#endif
  15070. +#else
  15071. +EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
  15072. +EXPORT_SYMBOL_NOVERS(ieee80211_rx);
  15073. +EXPORT_SYMBOL_NOVERS(ieee80211_network_init);
  15074. +#ifdef _RTL8187_EXT_PATCH_
  15075. +EXPORT_SYMBOL_NOVERS(ieee_ext_skb_p80211_to_ether);
  15076. +#endif
  15077. +#endif
  15078. 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
  15079. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 1970-01-01 01:00:00.000000000 +0100
  15080. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac.c 2010-05-27 18:12:39.532222207 +0200
  15081. @@ -0,0 +1,4083 @@
  15082. +/* IEEE 802.11 SoftMAC layer
  15083. + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  15084. + *
  15085. + * Mostly extracted from the rtl8180-sa2400 driver for the
  15086. + * in-kernel generic ieee802.11 stack.
  15087. + *
  15088. + * Few lines might be stolen from other part of the ieee80211
  15089. + * stack. Copyright who own it's copyright
  15090. + *
  15091. + * WPA code stolen from the ipw2200 driver.
  15092. + * Copyright who own it's copyright.
  15093. + *
  15094. + * released under the GPL
  15095. + */
  15096. +
  15097. +
  15098. +#include "ieee80211.h"
  15099. +
  15100. +#include <linux/random.h>
  15101. +#include <linux/delay.h>
  15102. +#include <linux/version.h>
  15103. +#include <asm/uaccess.h>
  15104. +
  15105. +#ifdef ENABLE_DOT11D
  15106. +#include "dot11d.h"
  15107. +#endif
  15108. +
  15109. +
  15110. +u8 rsn_authen_cipher_suite[16][4] = {
  15111. + {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
  15112. + {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
  15113. + {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
  15114. + {0x00,0x0F,0xAC,0x03}, //WRAP-historical
  15115. + {0x00,0x0F,0xAC,0x04}, //CCMP
  15116. + {0x00,0x0F,0xAC,0x05}, //WEP-104
  15117. +};
  15118. +
  15119. +short ieee80211_is_54g(struct ieee80211_network net)
  15120. +{
  15121. + return ((net.rates_ex_len > 0) || (net.rates_len > 4));
  15122. +}
  15123. +
  15124. +short ieee80211_is_shortslot(struct ieee80211_network net)
  15125. +{
  15126. + return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
  15127. +}
  15128. +
  15129. +/* returns the total length needed for pleacing the RATE MFIE
  15130. + * tag and the EXTENDED RATE MFIE tag if needed.
  15131. + * It encludes two bytes per tag for the tag itself and its len
  15132. + */
  15133. +unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
  15134. +{
  15135. + unsigned int rate_len = 0;
  15136. +
  15137. + if (ieee->modulation & IEEE80211_CCK_MODULATION)
  15138. + rate_len = IEEE80211_CCK_RATE_LEN + 2;
  15139. +
  15140. + if (ieee->modulation & IEEE80211_OFDM_MODULATION)
  15141. +
  15142. + rate_len += IEEE80211_OFDM_RATE_LEN + 2;
  15143. +
  15144. + return rate_len;
  15145. +}
  15146. +
  15147. +/* pleace the MFIE rate, tag to the memory (double) poined.
  15148. + * Then it updates the pointer so that
  15149. + * it points after the new MFIE tag added.
  15150. + */
  15151. +void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
  15152. +{
  15153. + u8 *tag = *tag_p;
  15154. +
  15155. + if (ieee->modulation & IEEE80211_CCK_MODULATION){
  15156. + *tag++ = MFIE_TYPE_RATES;
  15157. + *tag++ = 7;
  15158. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
  15159. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
  15160. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
  15161. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
  15162. + //added for basic rate set
  15163. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
  15164. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
  15165. + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
  15166. + }
  15167. +
  15168. + /* We may add an option for custom rates that specific HW might support */
  15169. + *tag_p = tag;
  15170. +}
  15171. +
  15172. +void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
  15173. +{
  15174. + u8 *tag = *tag_p;
  15175. +
  15176. + if (ieee->modulation & IEEE80211_OFDM_MODULATION){
  15177. +
  15178. + *tag++ = MFIE_TYPE_RATES_EX;
  15179. + *tag++ = 5;
  15180. + *tag++ = IEEE80211_OFDM_RATE_9MB;
  15181. + *tag++ = IEEE80211_OFDM_RATE_18MB;
  15182. + *tag++ = IEEE80211_OFDM_RATE_36MB;
  15183. + *tag++ = IEEE80211_OFDM_RATE_48MB;
  15184. + *tag++ = IEEE80211_OFDM_RATE_54MB;
  15185. +
  15186. + }
  15187. +
  15188. + /* We may add an option for custom rates that specific HW might support */
  15189. + *tag_p = tag;
  15190. +}
  15191. +
  15192. +
  15193. +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
  15194. + u8 *tag = *tag_p;
  15195. +
  15196. + *tag++ = MFIE_TYPE_GENERIC; //0
  15197. + *tag++ = 7;
  15198. + *tag++ = 0x00;
  15199. + *tag++ = 0x50;
  15200. + *tag++ = 0xf2;
  15201. + *tag++ = 0x02;//5
  15202. + *tag++ = 0x00;
  15203. + *tag++ = 0x01;
  15204. +#ifdef SUPPORT_USPD
  15205. + if(ieee->current_network.wmm_info & 0x80) {
  15206. + *tag++ = 0x0f|MAX_SP_Len;
  15207. + } else {
  15208. + *tag++ = MAX_SP_Len;
  15209. + }
  15210. +#else
  15211. + *tag++ = MAX_SP_Len;
  15212. +#endif
  15213. + *tag_p = tag;
  15214. +}
  15215. +
  15216. +#ifdef THOMAS_TURBO
  15217. +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
  15218. + u8 *tag = *tag_p;
  15219. +
  15220. + *tag++ = MFIE_TYPE_GENERIC; //0
  15221. + *tag++ = 7;
  15222. + *tag++ = 0x00;
  15223. + *tag++ = 0xe0;
  15224. + *tag++ = 0x4c;
  15225. + *tag++ = 0x01;//5
  15226. + *tag++ = 0x02;
  15227. + *tag++ = 0x11;
  15228. + *tag++ = 0x00;
  15229. +
  15230. + *tag_p = tag;
  15231. + printk(KERN_ALERT "This is enable turbo mode IE process\n");
  15232. +}
  15233. +#endif
  15234. +
  15235. +void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
  15236. +{
  15237. + int nh;
  15238. + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
  15239. +
  15240. +/*
  15241. + * if the queue is full but we have newer frames then
  15242. + * just overwrites the oldest.
  15243. + *
  15244. + * if (nh == ieee->mgmt_queue_tail)
  15245. + * return -1;
  15246. + */
  15247. + ieee->mgmt_queue_head = nh;
  15248. + ieee->mgmt_queue_ring[nh] = skb;
  15249. +
  15250. + //return 0;
  15251. +}
  15252. +
  15253. +struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
  15254. +{
  15255. + struct sk_buff *ret;
  15256. +
  15257. + if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
  15258. + return NULL;
  15259. +
  15260. + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
  15261. +
  15262. + ieee->mgmt_queue_tail =
  15263. + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
  15264. +
  15265. + return ret;
  15266. +}
  15267. +
  15268. +void init_mgmt_queue(struct ieee80211_device *ieee)
  15269. +{
  15270. + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
  15271. +}
  15272. +
  15273. +
  15274. +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
  15275. +
  15276. +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
  15277. +{
  15278. + unsigned long flags;
  15279. + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
  15280. + struct ieee80211_hdr_3addr *header=
  15281. + (struct ieee80211_hdr_3addr *) skb->data;
  15282. +
  15283. +
  15284. + spin_lock_irqsave(&ieee->lock, flags);
  15285. +
  15286. + /* called with 2nd param 0, no mgmt lock required */
  15287. + ieee80211_sta_wakeup(ieee,0);
  15288. +
  15289. + if(single){
  15290. + if(ieee->queue_stop){
  15291. +
  15292. + enqueue_mgmt(ieee,skb);
  15293. + }else{
  15294. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
  15295. +
  15296. + if (ieee->seq_ctrl[0] == 0xFFF)
  15297. + ieee->seq_ctrl[0] = 0;
  15298. + else
  15299. + ieee->seq_ctrl[0]++;
  15300. +
  15301. + /* avoid watchdog triggers */
  15302. + ieee->dev->trans_start = jiffies;
  15303. + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  15304. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  15305. +// dev_kfree_skb_any(skb);//edit by thomas //'cause this function will cause Oops called in interrupt context in old version 101907
  15306. +#endif
  15307. + }
  15308. +
  15309. + spin_unlock_irqrestore(&ieee->lock, flags);
  15310. + }else{
  15311. + spin_unlock_irqrestore(&ieee->lock, flags);
  15312. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
  15313. +
  15314. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  15315. +
  15316. + if (ieee->seq_ctrl[0] == 0xFFF)
  15317. + ieee->seq_ctrl[0] = 0;
  15318. + else
  15319. + ieee->seq_ctrl[0]++;
  15320. +
  15321. + ieee->softmac_hard_start_xmit(skb,ieee->dev);
  15322. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  15323. +// dev_kfree_skb_any(skb);//edit by thomas
  15324. +#endif
  15325. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
  15326. + }
  15327. +}
  15328. +
  15329. +
  15330. +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
  15331. +{
  15332. +
  15333. + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
  15334. + struct ieee80211_hdr_3addr *header =
  15335. + (struct ieee80211_hdr_3addr *) skb->data;
  15336. +
  15337. +
  15338. + if(single){
  15339. +
  15340. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  15341. +
  15342. + if (ieee->seq_ctrl[0] == 0xFFF)
  15343. + ieee->seq_ctrl[0] = 0;
  15344. + else
  15345. + ieee->seq_ctrl[0]++;
  15346. +
  15347. + /* avoid watchdog triggers */
  15348. + ieee->dev->trans_start = jiffies;
  15349. + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  15350. +
  15351. + }else{
  15352. +
  15353. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  15354. +
  15355. + if (ieee->seq_ctrl[0] == 0xFFF)
  15356. + ieee->seq_ctrl[0] = 0;
  15357. + else
  15358. + ieee->seq_ctrl[0]++;
  15359. +
  15360. + ieee->softmac_hard_start_xmit(skb,ieee->dev);
  15361. +
  15362. + }
  15363. + dev_kfree_skb_any(skb);//edit by thomas
  15364. +}
  15365. +
  15366. +inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
  15367. +{
  15368. + unsigned int len,rate_len;
  15369. + u8 *tag;
  15370. + struct sk_buff *skb;
  15371. + struct ieee80211_probe_request *req;
  15372. +
  15373. +#ifdef _RTL8187_EXT_PATCH_
  15374. + short extMore = 0;
  15375. + if(ieee->ext_patch_ieee80211_probe_req_1)
  15376. + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
  15377. +#endif
  15378. +
  15379. + len = ieee->current_network.ssid_len;
  15380. +
  15381. + rate_len = ieee80211_MFIE_rate_len(ieee);
  15382. +
  15383. +#ifdef _RTL8187_EXT_PATCH_
  15384. + if(!extMore)
  15385. +#endif
  15386. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  15387. + 2 + len + rate_len);
  15388. +#ifdef _RTL8187_EXT_PATCH_
  15389. + else
  15390. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  15391. + 2 + len + rate_len+128); // MESHID + CAP
  15392. +#endif
  15393. +
  15394. + if (!skb)
  15395. + return NULL;
  15396. +
  15397. + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
  15398. + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
  15399. + req->header.duration_id = 0; //FIXME: is this OK ?
  15400. +
  15401. + memset(req->header.addr1, 0xff, ETH_ALEN);
  15402. + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  15403. + memset(req->header.addr3, 0xff, ETH_ALEN);
  15404. +
  15405. + tag = (u8 *) skb_put(skb,len+2+rate_len);
  15406. +
  15407. + *tag++ = MFIE_TYPE_SSID;
  15408. + *tag++ = len;
  15409. + memcpy(tag, ieee->current_network.ssid, len);
  15410. + tag += len;
  15411. +
  15412. + ieee80211_MFIE_Brate(ieee,&tag);
  15413. + ieee80211_MFIE_Grate(ieee,&tag);
  15414. +
  15415. +#ifdef _RTL8187_EXT_PATCH_
  15416. + if(extMore)
  15417. + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
  15418. +#endif
  15419. + return skb;
  15420. +}
  15421. +
  15422. +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
  15423. +
  15424. +#ifdef _RTL8187_EXT_PATCH_
  15425. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15426. +void ext_ieee80211_send_beacon_wq(struct work_struct *work)
  15427. +{
  15428. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
  15429. +#else
  15430. +void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
  15431. +{
  15432. +#endif
  15433. +
  15434. + struct sk_buff *skb;
  15435. +
  15436. + //unsigned long flags;
  15437. +// printk("=========>%s()\n", __FUNCTION__);
  15438. + skb = ieee80211_get_beacon_(ieee);
  15439. +
  15440. + if (skb){
  15441. + softmac_mgmt_xmit(skb, ieee);
  15442. + ieee->softmac_stats.tx_beacons++;
  15443. + dev_kfree_skb_any(skb);//edit by thomas
  15444. + }
  15445. +
  15446. +
  15447. + //printk(KERN_WARNING "[1] beacon sending!\n");
  15448. +// ieee->beacon_timer.expires = jiffies +
  15449. +// (MSECS( ieee->current_network.beacon_interval -5));
  15450. +
  15451. + //spin_lock_irqsave(&ieee->beacon_lock,flags);
  15452. +// if(ieee->beacon_txing)
  15453. +// add_timer(&ieee->beacon_timer);
  15454. + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  15455. +}
  15456. +#endif
  15457. +
  15458. +void ieee80211_send_beacon(struct ieee80211_device *ieee)
  15459. +{
  15460. + struct sk_buff *skb;
  15461. +
  15462. + //unsigned long flags;
  15463. +// printk("=========>%s()\n", __FUNCTION__);
  15464. + skb = ieee80211_get_beacon_(ieee);
  15465. +
  15466. + if (skb){
  15467. + softmac_mgmt_xmit(skb, ieee);
  15468. + ieee->softmac_stats.tx_beacons++;
  15469. + dev_kfree_skb_any(skb);//edit by thomas
  15470. + }
  15471. +
  15472. +
  15473. + //printk(KERN_WARNING "[1] beacon sending!\n");
  15474. + ieee->beacon_timer.expires = jiffies +
  15475. + (MSECS( ieee->current_network.beacon_interval -5));
  15476. +
  15477. + //spin_lock_irqsave(&ieee->beacon_lock,flags);
  15478. + if(ieee->beacon_txing)
  15479. + add_timer(&ieee->beacon_timer);
  15480. + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  15481. +}
  15482. +
  15483. +
  15484. +void ieee80211_send_beacon_cb(unsigned long _ieee)
  15485. +{
  15486. + struct ieee80211_device *ieee =
  15487. + (struct ieee80211_device *) _ieee;
  15488. + unsigned long flags;
  15489. +
  15490. + spin_lock_irqsave(&ieee->beacon_lock, flags);
  15491. + ieee80211_send_beacon(ieee);
  15492. + spin_unlock_irqrestore(&ieee->beacon_lock, flags);
  15493. +}
  15494. +
  15495. +#ifdef _RTL8187_EXT_PATCH_
  15496. +
  15497. +inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
  15498. +{
  15499. + unsigned int len,rate_len;
  15500. + u8 *tag;
  15501. + struct sk_buff *skb;
  15502. + struct ieee80211_probe_request *req;
  15503. +
  15504. +#ifdef _RTL8187_EXT_PATCH_
  15505. + short extMore = 0;
  15506. + if(ieee->ext_patch_ieee80211_probe_req_1)
  15507. + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
  15508. +#endif
  15509. +
  15510. + len = len_ssid;
  15511. +
  15512. + rate_len = ieee80211_MFIE_rate_len(ieee);
  15513. +
  15514. +#ifdef _RTL8187_EXT_PATCH_
  15515. + if(!extMore)
  15516. +#endif
  15517. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  15518. + 2 + len + rate_len);
  15519. +#ifdef _RTL8187_EXT_PATCH_
  15520. + else
  15521. + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
  15522. + 2 + len + rate_len+128); // MESHID + CAP
  15523. +#endif
  15524. +
  15525. + if (!skb)
  15526. + return NULL;
  15527. +
  15528. + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
  15529. + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
  15530. + req->header.duration_id = 0; //FIXME: is this OK ?
  15531. +
  15532. + memset(req->header.addr1, 0xff, ETH_ALEN);
  15533. + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  15534. + memset(req->header.addr3, 0xff, ETH_ALEN);
  15535. +
  15536. + tag = (u8 *) skb_put(skb,len+2+rate_len);
  15537. +
  15538. + *tag++ = MFIE_TYPE_SSID;
  15539. + *tag++ = len;
  15540. + if(len)
  15541. + {
  15542. + memcpy(tag, ssid, len);
  15543. + tag += len;
  15544. + }
  15545. +
  15546. + ieee80211_MFIE_Brate(ieee,&tag);
  15547. + ieee80211_MFIE_Grate(ieee,&tag);
  15548. +
  15549. +#ifdef _RTL8187_EXT_PATCH_
  15550. + if(extMore)
  15551. + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
  15552. +#endif
  15553. + return skb;
  15554. +}
  15555. +
  15556. +#endif // _RTL8187_EXT_PATCH_
  15557. +
  15558. +
  15559. +void ieee80211_send_probe(struct ieee80211_device *ieee)
  15560. +{
  15561. + struct sk_buff *skb;
  15562. +
  15563. +#ifdef _RTL8187_EXT_PATCH_
  15564. + if(ieee->iw_mode == ieee->iw_ext_mode)
  15565. + skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
  15566. + else
  15567. +#endif
  15568. + skb = ieee80211_probe_req(ieee);
  15569. + if (skb){
  15570. + softmac_mgmt_xmit(skb, ieee);
  15571. + ieee->softmac_stats.tx_probe_rq++;
  15572. + dev_kfree_skb_any(skb);//edit by thomas
  15573. + }
  15574. +}
  15575. +
  15576. +void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
  15577. +{
  15578. + if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
  15579. + ieee80211_send_probe(ieee);
  15580. + ieee80211_send_probe(ieee);
  15581. + }
  15582. +}
  15583. +
  15584. +/* this performs syncro scan blocking the caller until all channels
  15585. + * in the allowed channel map has been checked.
  15586. + */
  15587. +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
  15588. +{
  15589. + short ch = 0;
  15590. +#ifdef ENABLE_DOT11D
  15591. + u8 channel_map[MAX_CHANNEL_NUMBER+1];
  15592. + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
  15593. +#endif
  15594. +
  15595. +
  15596. + down(&ieee->scan_sem);
  15597. +
  15598. + while(1)
  15599. + {
  15600. +
  15601. + do{
  15602. + ch++;
  15603. + if (ch > MAX_CHANNEL_NUMBER)
  15604. + goto out; /* scan completed */
  15605. +
  15606. +#ifdef ENABLE_DOT11D
  15607. + }while(!channel_map[ch]);
  15608. +#else
  15609. + }while(!ieee->channel_map[ch]);
  15610. +#endif
  15611. +
  15612. + //printk("=>current channel is %d\n",ch);
  15613. +
  15614. + /* this fuction can be called in two situations
  15615. + * 1- We have switched to ad-hoc mode and we are
  15616. + * performing a complete syncro scan before conclude
  15617. + * there are no interesting cell and to create a
  15618. + * new one. In this case the link state is
  15619. + * IEEE80211_NOLINK until we found an interesting cell.
  15620. + * If so the ieee8021_new_net, called by the RX path
  15621. + * will set the state to IEEE80211_LINKED, so we stop
  15622. + * scanning
  15623. + * 2- We are linked and the root uses run iwlist scan.
  15624. + * So we switch to IEEE80211_LINKED_SCANNING to remember
  15625. + * that we are still logically linked (not interested in
  15626. + * new network events, despite for updating the net list,
  15627. + * but we are temporarly 'unlinked' as the driver shall
  15628. + * not filter RX frames and the channel is changing.
  15629. + * So the only situation in witch are interested is to check
  15630. + * if the state become LINKED because of the #1 situation
  15631. + */
  15632. +
  15633. + if (ieee->state == IEEE80211_LINKED)
  15634. + goto out;
  15635. +
  15636. + //printk("---->%s: chan %d\n", __func__, ch);
  15637. + ieee->set_chan(ieee->dev, ch);
  15638. +#ifdef ENABLE_DOT11D
  15639. + if(channel_map[ch] == 1)
  15640. +#endif
  15641. + {
  15642. + ieee80211_send_probe_requests(ieee);
  15643. + }
  15644. +
  15645. + /* this prevent excessive time wait when we
  15646. + * need to wait for a syncro scan to end..
  15647. + */
  15648. + if (ieee->sync_scan_hurryup)
  15649. + goto out;
  15650. +
  15651. +
  15652. + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
  15653. +
  15654. + }
  15655. +out:
  15656. + ieee->sync_scan_hurryup = 0;
  15657. + up(&ieee->scan_sem);
  15658. +#ifdef ENABLE_DOT11D
  15659. + if(IS_DOT11D_ENABLE(ieee))
  15660. + DOT11D_ScanComplete(ieee);
  15661. +#endif
  15662. +
  15663. +}
  15664. +
  15665. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  15666. +/* called both by wq with ieee->lock held */
  15667. +void ieee80211_softmac_scan(struct ieee80211_device *ieee)
  15668. +{
  15669. +#if 0
  15670. + short watchdog = 0;
  15671. + do{
  15672. + ieee->current_network.channel =
  15673. + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
  15674. + if (watchdog++ > MAX_CHANNEL_NUMBER)
  15675. + return; /* no good chans */
  15676. +
  15677. + }while(!ieee->channel_map[ieee->current_network.channel]);
  15678. +#endif
  15679. +
  15680. + schedule_task(&ieee->softmac_scan_wq);
  15681. +}
  15682. +#endif
  15683. +
  15684. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  15685. +void ieee80211_softmac_scan_wq(struct work_struct *work)
  15686. +{
  15687. + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  15688. + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
  15689. +#else
  15690. +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
  15691. +{
  15692. +#endif
  15693. + //static short watchdog = 0;
  15694. + //short watchdog = 0;//lzm move into ieee->scan_watchdog 081215 for roaming
  15695. + u8 channel_bak = ieee->current_network.channel;//lzm for channel+1
  15696. +#ifdef ENABLE_DOT11D
  15697. + u8 channel_map[MAX_CHANNEL_NUMBER+1];
  15698. + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
  15699. +#endif
  15700. + down(&ieee->scan_sem);
  15701. +
  15702. + do{
  15703. + ieee->current_network.channel =
  15704. + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
  15705. + if (ieee->scan_watchdog++ > MAX_CHANNEL_NUMBER)
  15706. + goto out; /* no good chans */
  15707. +#ifdef ENABLE_DOT11D
  15708. + }while(!channel_map[ieee->current_network.channel]);
  15709. +#else
  15710. + }while(!ieee->channel_map[ieee->current_network.channel]);
  15711. +#endif
  15712. +
  15713. + if (ieee->scanning == 0 )
  15714. + goto out;
  15715. +
  15716. + //printk("current channel is %d\n",ieee->current_network.channel);
  15717. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  15718. +#ifdef ENABLE_DOT11D
  15719. + if(channel_map[ieee->current_network.channel] == 1)
  15720. +#endif
  15721. + {
  15722. + ieee80211_send_probe_requests(ieee);
  15723. + }
  15724. +
  15725. +
  15726. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  15727. + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
  15728. +#else
  15729. + ieee->scan_timer.expires = jiffies + (IEEE80211_SOFTMAC_SCAN_TIME);
  15730. + if (ieee->scanning == 1)
  15731. + add_timer(&ieee->scan_timer);
  15732. +#endif
  15733. +
  15734. + up(&ieee->scan_sem);
  15735. + return;
  15736. +out:
  15737. + //printk("%s():Stop scan now\n",__FUNCTION__);
  15738. + ieee->actscanning = false;
  15739. + ieee->scan_watchdog = 0;
  15740. + ieee->scanning = 0;
  15741. + ieee->current_network.channel = channel_bak;
  15742. + up(&ieee->scan_sem);
  15743. +#ifdef ENABLE_DOT11D
  15744. + if(IS_DOT11D_ENABLE(ieee))
  15745. + DOT11D_ScanComplete(ieee);
  15746. +#endif
  15747. +
  15748. + return;
  15749. +}
  15750. +
  15751. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  15752. +void ieee80211_softmac_scan_cb(unsigned long _dev)
  15753. +{
  15754. + unsigned long flags;
  15755. + struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
  15756. +
  15757. + spin_lock_irqsave(&ieee->lock, flags);
  15758. + ieee80211_softmac_scan(ieee);
  15759. + spin_unlock_irqrestore(&ieee->lock, flags);
  15760. +}
  15761. +#endif
  15762. +
  15763. +
  15764. +void ieee80211_beacons_start(struct ieee80211_device *ieee)
  15765. +{
  15766. + unsigned long flags;
  15767. +
  15768. + spin_lock_irqsave(&ieee->beacon_lock,flags);
  15769. +
  15770. + ieee->beacon_txing = 1;
  15771. + ieee80211_send_beacon(ieee);
  15772. +
  15773. + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  15774. +}
  15775. +
  15776. +void ieee80211_beacons_stop(struct ieee80211_device *ieee)
  15777. +{
  15778. + unsigned long flags;
  15779. +
  15780. + spin_lock_irqsave(&ieee->beacon_lock,flags);
  15781. +
  15782. + ieee->beacon_txing = 0;
  15783. + del_timer_sync(&ieee->beacon_timer);
  15784. +
  15785. + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
  15786. +
  15787. +}
  15788. +
  15789. +
  15790. +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
  15791. +{
  15792. + if(ieee->stop_send_beacons)
  15793. + ieee->stop_send_beacons(ieee->dev);
  15794. + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
  15795. + ieee80211_beacons_stop(ieee);
  15796. +}
  15797. +
  15798. +
  15799. +void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
  15800. +{
  15801. + if(ieee->start_send_beacons)
  15802. + ieee->start_send_beacons(ieee->dev);
  15803. + if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
  15804. + ieee80211_beacons_start(ieee);
  15805. +}
  15806. +
  15807. +
  15808. +void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
  15809. +{
  15810. +// unsigned long flags;
  15811. +
  15812. + ieee->sync_scan_hurryup = 1;
  15813. +
  15814. + down(&ieee->scan_sem);
  15815. +// spin_lock_irqsave(&ieee->lock, flags);
  15816. +
  15817. + if (ieee->scanning == 1){
  15818. + //printk("%s():Stop scan now\n",__FUNCTION__);
  15819. + ieee->scanning = 0;
  15820. + //lzm add for softmac_scan_wq can't return from out
  15821. + //example: rcv probe_response
  15822. + ieee->scan_watchdog = 0;//lzm add 081215 for roaming
  15823. + ieee->actscanning = false;
  15824. +
  15825. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  15826. + cancel_delayed_work(&ieee->softmac_scan_wq);
  15827. +#else
  15828. + del_timer_sync(&ieee->scan_timer);
  15829. +#endif
  15830. + }
  15831. +
  15832. +// spin_unlock_irqrestore(&ieee->lock, flags);
  15833. + up(&ieee->scan_sem);
  15834. +}
  15835. +
  15836. +void ieee80211_stop_scan(struct ieee80211_device *ieee)
  15837. +{
  15838. + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
  15839. + ieee80211_softmac_stop_scan(ieee);
  15840. + else
  15841. + ieee->stop_scan(ieee->dev);
  15842. +}
  15843. +
  15844. +/* called with ieee->lock held */
  15845. +void ieee80211_start_scan(struct ieee80211_device *ieee)
  15846. +{
  15847. + ieee->actscanning = true;
  15848. +#ifdef CONFIG_IPS
  15849. + ieee->ieee80211_ips_leave(ieee->dev);
  15850. +#endif
  15851. +
  15852. +#ifdef ENABLE_DOT11D
  15853. + if(IS_DOT11D_ENABLE(ieee) )
  15854. + {
  15855. + if(IS_COUNTRY_IE_VALID(ieee))
  15856. + {
  15857. + RESET_CIE_WATCHDOG(ieee);
  15858. + }
  15859. + }
  15860. +#endif
  15861. +
  15862. + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
  15863. + if (ieee->scanning == 0){
  15864. + ieee->scanning = 1;
  15865. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  15866. + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0);
  15867. +#else
  15868. + ieee80211_softmac_scan(ieee);
  15869. +#endif
  15870. + }
  15871. + }else
  15872. + ieee->start_scan(ieee->dev);
  15873. +
  15874. +}
  15875. +
  15876. +/* called with wx_sem held */
  15877. +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
  15878. +{
  15879. + //printk("====>%s()\n", __func__);
  15880. +#ifdef CONFIG_IPS
  15881. + ieee->ieee80211_ips_leave(ieee->dev);
  15882. +#endif
  15883. + ieee->actscanning = true;
  15884. +
  15885. +#ifdef ENABLE_DOT11D
  15886. + if(IS_DOT11D_ENABLE(ieee) )
  15887. + {
  15888. + if(IS_COUNTRY_IE_VALID(ieee))
  15889. + {
  15890. + RESET_CIE_WATCHDOG(ieee);
  15891. + }
  15892. + }
  15893. +#endif
  15894. +
  15895. + ieee->sync_scan_hurryup = 0;
  15896. +
  15897. + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
  15898. + ieee80211_softmac_scan_syncro(ieee);
  15899. + else
  15900. + ieee->scan_syncro(ieee->dev);
  15901. +
  15902. + ieee->actscanning = false;
  15903. + //printk("<====%s()\n", __func__);
  15904. +}
  15905. +
  15906. +inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
  15907. + struct ieee80211_device *ieee, int challengelen)
  15908. +{
  15909. + struct sk_buff *skb;
  15910. + struct ieee80211_authentication *auth;
  15911. +
  15912. + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
  15913. +
  15914. + if (!skb) return NULL;
  15915. +
  15916. + auth = (struct ieee80211_authentication *)
  15917. + skb_put(skb, sizeof(struct ieee80211_authentication));
  15918. +
  15919. + auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
  15920. + if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
  15921. +
  15922. + auth->header.duration_id = 0x013a; //FIXME
  15923. +
  15924. + memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
  15925. + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  15926. + memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
  15927. +
  15928. + auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
  15929. +
  15930. + auth->transaction = cpu_to_le16(ieee->associate_seq);
  15931. + ieee->associate_seq++;
  15932. +
  15933. + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
  15934. +
  15935. + return skb;
  15936. +
  15937. +}
  15938. +
  15939. +u8 WPA_OUI[3] = {0x00, 0x50, 0xf2};
  15940. +
  15941. +static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
  15942. +{
  15943. + u8 *tag;
  15944. + int beacon_size;
  15945. + struct ieee80211_probe_response *beacon_buf;
  15946. + struct sk_buff *skb;
  15947. + int encrypt;
  15948. + int atim_len,erp_len;
  15949. + struct ieee80211_crypt_data* crypt;
  15950. +
  15951. + char *ssid = ieee->current_network.ssid;
  15952. + int ssid_len = ieee->current_network.ssid_len;
  15953. + int rate_len = ieee->current_network.rates_len+2;
  15954. + int rate_ex_len = ieee->current_network.rates_ex_len;
  15955. +
  15956. + int wpa_ie_len = 0, wpa_type=0;
  15957. + if(rate_ex_len > 0) rate_ex_len+=2;
  15958. +
  15959. + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
  15960. + atim_len = 4;
  15961. + else
  15962. + atim_len = 0;
  15963. +
  15964. + if(ieee80211_is_54g(ieee->current_network))
  15965. + erp_len = 3;
  15966. + else
  15967. + erp_len = 0;
  15968. + if (ieee->wpa_enabled)
  15969. + {
  15970. + // printk("hoho wpa_enalbe\n");
  15971. + wpa_ie_len = ieee->wpa_ie_len; //24-2
  15972. + }
  15973. + beacon_size = sizeof(struct ieee80211_probe_response)+
  15974. + ssid_len
  15975. + +3 //channel
  15976. + +rate_len
  15977. + +rate_ex_len
  15978. + +atim_len
  15979. + +erp_len
  15980. + +wpa_ie_len;
  15981. +
  15982. + skb = dev_alloc_skb(beacon_size);
  15983. +
  15984. + if (!skb)
  15985. + return NULL;
  15986. +
  15987. + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
  15988. +
  15989. + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
  15990. + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  15991. + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
  15992. +
  15993. + beacon_buf->header.duration_id = 0; //FIXME
  15994. + beacon_buf->beacon_interval =
  15995. + cpu_to_le16(ieee->current_network.beacon_interval);
  15996. + beacon_buf->capability =
  15997. + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
  15998. +
  15999. + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
  16000. + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
  16001. +#ifdef _RTL8187_EXT_PATCH_
  16002. +{
  16003. +/* struct ieee80211_crypt_data_list* cryptlist = ieee->cryptlist[1];
  16004. + u8 i = cryptlist->used;
  16005. + crypt = cryptlist ->crypt[ieee->tx_keyidx];
  16006. +*/
  16007. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  16008. +}
  16009. +#else
  16010. +
  16011. + crypt = ieee->crypt[ieee->tx_keyidx];
  16012. +#endif
  16013. + if (crypt)
  16014. + wpa_type = strcmp(crypt->ops->name, "TKIP");
  16015. +
  16016. +
  16017. + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
  16018. + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
  16019. +
  16020. + if (encrypt)
  16021. + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  16022. +
  16023. +
  16024. + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
  16025. +
  16026. + beacon_buf->info_element.id = MFIE_TYPE_SSID;
  16027. + beacon_buf->info_element.len = ssid_len;
  16028. +
  16029. + tag = (u8*) beacon_buf->info_element.data;
  16030. +
  16031. + memcpy(tag, ssid, ssid_len);
  16032. +
  16033. + tag += ssid_len;
  16034. +
  16035. + *(tag++) = MFIE_TYPE_RATES;
  16036. + *(tag++) = rate_len-2;
  16037. + memcpy(tag,ieee->current_network.rates,rate_len-2);
  16038. + tag+=rate_len-2;
  16039. +
  16040. + *(tag++) = MFIE_TYPE_DS_SET;
  16041. + *(tag++) = 1;
  16042. + *(tag++) = ieee->current_network.channel;
  16043. +
  16044. + if(atim_len){
  16045. + u16 val16;
  16046. + *(tag++) = MFIE_TYPE_IBSS_SET;
  16047. + *(tag++) = 2;
  16048. + val16 = cpu_to_le16(ieee->current_network.atim_window);
  16049. + //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
  16050. + memcpy((u8 *)tag,(u8 *)&val16,2);
  16051. + tag+=2;
  16052. + }
  16053. +
  16054. + if(erp_len){
  16055. + *(tag++) = MFIE_TYPE_ERP;
  16056. + *(tag++) = 1;
  16057. + *(tag++) = 0;
  16058. + }
  16059. +
  16060. + if(rate_ex_len){
  16061. + *(tag++) = MFIE_TYPE_RATES_EX;
  16062. + *(tag++) = rate_ex_len-2;
  16063. + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
  16064. + tag+=rate_ex_len-2;
  16065. + }
  16066. + if (wpa_ie_len)
  16067. + {
  16068. +#if 0
  16069. + *(tag++) = 0xdd;
  16070. + *(tag++) = wpa_ie_len-2;
  16071. + memcpy(tag, WPA_OUI, 3);
  16072. + tag += 3;
  16073. + *(tag++) = 1;
  16074. + *(tag++) = 1;
  16075. + *(tag++) = 0;
  16076. +
  16077. + memcpy(tag, WPA_OUI, 3);
  16078. + tag += 3;
  16079. + *(tag++) = wpa_type ? 4:2;
  16080. + *(tag++) = 1;
  16081. + *(tag++) = 0;
  16082. +
  16083. +
  16084. + memcpy(tag, WPA_OUI, 3);
  16085. + tag += 3;
  16086. + *(tag++) = wpa_type ? 4:0;
  16087. + *(tag++) = 1;
  16088. + *(tag++) = 0;
  16089. +
  16090. + memcpy(tag, WPA_OUI, 3);
  16091. + tag += 3;
  16092. + *(tag++) = 0;
  16093. +#else
  16094. + if (ieee->iw_mode == IW_MODE_ADHOC)
  16095. + {//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
  16096. + memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
  16097. + }
  16098. +
  16099. + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
  16100. +
  16101. +#endif
  16102. + }
  16103. +
  16104. +
  16105. + skb->dev = ieee->dev;
  16106. + return skb;
  16107. +}
  16108. +
  16109. +
  16110. +#ifdef _RTL8187_EXT_PATCH_
  16111. +struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net)
  16112. +{
  16113. + u8 *tag;
  16114. + int beacon_size;
  16115. + struct ieee80211_probe_response *beacon_buf;
  16116. + struct sk_buff *skb;
  16117. + int encrypt;
  16118. + int atim_len,erp_len;
  16119. + struct ieee80211_crypt_data* crypt;
  16120. + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
  16121. +
  16122. + char *ssid = net->ssid;
  16123. + int ssid_len = net->ssid_len;
  16124. +
  16125. + int rate_len = ieee->current_network.rates_len+2;
  16126. + int rate_ex_len = ieee->current_network.rates_ex_len;
  16127. + int wpa_ie_len = 0, wpa_type=0;
  16128. + if(rate_ex_len > 0) rate_ex_len+=2;
  16129. +
  16130. + if( ieee->meshScanMode&4)
  16131. + ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
  16132. + if( ieee->meshScanMode&6)
  16133. + {
  16134. +
  16135. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  16136. + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
  16137. +#else
  16138. + schedule_task(&ieee->ext_stop_scan_wq);
  16139. +#endif
  16140. + }
  16141. + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
  16142. + atim_len = 4;
  16143. + else
  16144. + atim_len = 0;
  16145. +
  16146. + if(ieee80211_is_54g(*net))
  16147. + erp_len = 3;
  16148. + else
  16149. + erp_len = 0;
  16150. +
  16151. + if (ieee->wpa_enabled &&(ieee->iw_ext_mode==ieee->iw_mode))
  16152. + {
  16153. +// printk("hoho wpa_enalbe\n");
  16154. + wpa_ie_len = ieee->wpa_ie_len; //24-2
  16155. + }
  16156. +
  16157. + beacon_size = sizeof(struct ieee80211_probe_response)+
  16158. + ssid_len
  16159. + +3 //channel
  16160. + +rate_len
  16161. + +rate_ex_len
  16162. + +atim_len
  16163. + +erp_len
  16164. + +wpa_ie_len;
  16165. +//b
  16166. + skb = dev_alloc_skb(beacon_size+196);
  16167. +
  16168. + if (!skb)
  16169. + return NULL;
  16170. +
  16171. + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
  16172. +
  16173. + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
  16174. + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  16175. + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
  16176. +
  16177. + beacon_buf->header.duration_id = 0; //FIXME
  16178. +
  16179. + beacon_buf->beacon_interval =
  16180. + cpu_to_le16(ieee->current_network.beacon_interval); // use current_network here
  16181. + beacon_buf->capability =
  16182. + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
  16183. +
  16184. + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
  16185. + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
  16186. +#ifdef _RTL8187_EXT_PATCH_
  16187. +
  16188. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  16189. +#else
  16190. +
  16191. + crypt = ieee->crypt[ieee->tx_keyidx];
  16192. +#endif
  16193. +
  16194. +// crypt = ieee->crypt[ieee->tx_keyidx];
  16195. + if (crypt)
  16196. + wpa_type = strcmp(crypt->ops->name, "TKIP");
  16197. +
  16198. + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
  16199. + ((0 == strcmp(crypt->ops->name, "WEP")||wpa_ie_len));
  16200. +
  16201. + if (encrypt)
  16202. + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  16203. +
  16204. +
  16205. + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
  16206. +
  16207. + beacon_buf->info_element.id = MFIE_TYPE_SSID;
  16208. + beacon_buf->info_element.len = ssid_len;
  16209. +
  16210. + tag = (u8*) beacon_buf->info_element.data;
  16211. +
  16212. + // brocad cast / probe rsp
  16213. + if(memcmp(dest, broadcast_addr, ETH_ALEN ))
  16214. + memcpy(tag, ssid, ssid_len);
  16215. + else
  16216. + ssid_len=0;
  16217. +
  16218. + tag += ssid_len;
  16219. +
  16220. +//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
  16221. +//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
  16222. +
  16223. + *(tag++) = MFIE_TYPE_RATES;
  16224. + *(tag++) = rate_len-2;
  16225. + memcpy(tag,ieee->current_network.rates,rate_len-2);
  16226. + tag+=rate_len-2;
  16227. +
  16228. + *(tag++) = MFIE_TYPE_DS_SET;
  16229. + *(tag++) = 1;
  16230. + *(tag++) = ieee->current_network.channel; // use current_network here
  16231. +
  16232. +
  16233. + if(atim_len){
  16234. + *(tag++) = MFIE_TYPE_IBSS_SET;
  16235. + *(tag++) = 2;
  16236. + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
  16237. + tag+=2;
  16238. + }
  16239. +
  16240. + if(erp_len){
  16241. + *(tag++) = MFIE_TYPE_ERP;
  16242. + *(tag++) = 1;
  16243. + *(tag++) = 0;
  16244. + }
  16245. +
  16246. + if(rate_ex_len){
  16247. + *(tag++) = MFIE_TYPE_RATES_EX;
  16248. + *(tag++) = rate_ex_len-2;
  16249. + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
  16250. + tag+=rate_ex_len-2;
  16251. + }
  16252. +
  16253. + if (wpa_ie_len)
  16254. + {
  16255. +#if 0
  16256. + *(tag++) = 0xdd;
  16257. + *(tag++) = wpa_ie_len-2;
  16258. + memcpy(tag, WPA_OUI, 3);
  16259. + tag += 3;
  16260. + *(tag++) = 1;
  16261. + *(tag++) = 1;
  16262. + *(tag++) = 0;
  16263. +
  16264. + memcpy(tag, WPA_OUI, 3);
  16265. + tag += 3;
  16266. + *(tag++) = wpa_type ? 4:2;
  16267. + *(tag++) = 1;
  16268. + *(tag++) = 0;
  16269. +
  16270. +
  16271. + memcpy(tag, WPA_OUI, 3);
  16272. + tag += 3;
  16273. + *(tag++) = wpa_type ? 4:0;
  16274. + *(tag++) = 1;
  16275. + *(tag++) = 0;
  16276. +
  16277. + memcpy(tag, WPA_OUI, 3);
  16278. + tag += 3;
  16279. + *(tag++) = 0;
  16280. +#else
  16281. + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
  16282. +#endif
  16283. + }
  16284. +
  16285. +
  16286. + skb->dev = ieee->dev;
  16287. + return skb;
  16288. +}
  16289. +#endif // _RTL8187_EXT_PATCH_
  16290. +
  16291. +
  16292. +struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
  16293. +{
  16294. + struct sk_buff *skb;
  16295. + u8* tag;
  16296. +
  16297. + struct ieee80211_crypt_data* crypt;
  16298. + struct ieee80211_assoc_response_frame *assoc;
  16299. + short encrypt;
  16300. +
  16301. + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  16302. + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
  16303. +
  16304. + skb = dev_alloc_skb(len);
  16305. +
  16306. + if (!skb)
  16307. + return NULL;
  16308. +
  16309. + assoc = (struct ieee80211_assoc_response_frame *)
  16310. + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
  16311. +
  16312. + assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
  16313. + memcpy(assoc->header.addr1, dest,ETH_ALEN);
  16314. + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  16315. + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  16316. + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
  16317. + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
  16318. +
  16319. +
  16320. + if(ieee->short_slot)
  16321. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  16322. +
  16323. + if (ieee->host_encrypt){
  16324. +#ifdef _RTL8187_EXT_PATCH_
  16325. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  16326. +#else
  16327. + crypt = ieee->crypt[ieee->tx_keyidx];
  16328. +#endif
  16329. + }
  16330. + else crypt = NULL;
  16331. +
  16332. + encrypt = ( crypt && crypt->ops);
  16333. +
  16334. + if (encrypt)
  16335. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  16336. +
  16337. + assoc->status = 0;
  16338. + assoc->aid = cpu_to_le16(ieee->assoc_id);
  16339. + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
  16340. + else ieee->assoc_id++;
  16341. +
  16342. + tag = (u8*) skb_put(skb, rate_len);
  16343. +
  16344. + ieee80211_MFIE_Brate(ieee, &tag);
  16345. + ieee80211_MFIE_Grate(ieee, &tag);
  16346. +
  16347. + return skb;
  16348. +}
  16349. +
  16350. +struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
  16351. +{
  16352. + struct sk_buff *skb;
  16353. + struct ieee80211_authentication *auth;
  16354. +
  16355. + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
  16356. +
  16357. + if (!skb)
  16358. + return NULL;
  16359. +
  16360. + skb->len = sizeof(struct ieee80211_authentication);
  16361. +
  16362. + auth = (struct ieee80211_authentication *)skb->data;
  16363. +
  16364. + auth->status = cpu_to_le16(status);
  16365. + auth->transaction = cpu_to_le16(2);
  16366. + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
  16367. +
  16368. +#ifdef _RTL8187_EXT_PATCH_
  16369. + if(ieee->iw_mode == ieee->iw_ext_mode)
  16370. + memcpy(auth->header.addr3, dest, ETH_ALEN);
  16371. +#else
  16372. + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  16373. +#endif
  16374. + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  16375. + memcpy(auth->header.addr1, dest, ETH_ALEN);
  16376. + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
  16377. + return skb;
  16378. +
  16379. +
  16380. +}
  16381. +
  16382. +struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
  16383. +{
  16384. + struct sk_buff *skb;
  16385. + struct ieee80211_hdr_3addr* hdr;
  16386. +
  16387. + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
  16388. +
  16389. + if (!skb)
  16390. + return NULL;
  16391. +
  16392. + hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
  16393. +
  16394. + memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
  16395. + memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
  16396. + memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
  16397. +
  16398. + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
  16399. + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
  16400. + (pwr ? IEEE80211_FCTL_PM:0));
  16401. +
  16402. + return skb;
  16403. +
  16404. +
  16405. +}
  16406. +
  16407. +
  16408. +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
  16409. +{
  16410. + struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
  16411. +
  16412. + if (buf){
  16413. + softmac_mgmt_xmit(buf, ieee);
  16414. + dev_kfree_skb_any(buf);//edit by thomas
  16415. + }
  16416. +}
  16417. +
  16418. +
  16419. +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
  16420. +{
  16421. + struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
  16422. +
  16423. + if (buf){
  16424. + softmac_mgmt_xmit(buf, ieee);
  16425. + dev_kfree_skb_any(buf);//edit by thomas
  16426. + }
  16427. +}
  16428. +
  16429. +
  16430. +void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
  16431. +{
  16432. +
  16433. + struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
  16434. +
  16435. + if (buf) {
  16436. + softmac_mgmt_xmit(buf, ieee);
  16437. + dev_kfree_skb_any(buf);//edit by thomas
  16438. + }
  16439. +}
  16440. +
  16441. +
  16442. +inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
  16443. +{
  16444. + struct sk_buff *skb;
  16445. +
  16446. + struct ieee80211_assoc_request_frame *hdr;
  16447. + u8 *tag;
  16448. + //int i;
  16449. + unsigned int wpa_len = beacon->wpa_ie_len;
  16450. +#if 1
  16451. + // for testing purpose
  16452. + unsigned int rsn_len = beacon->rsn_ie_len;
  16453. +#else
  16454. + unsigned int rsn_len = beacon->rsn_ie_len - 4;
  16455. +#endif
  16456. + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  16457. + unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
  16458. +#ifdef THOMAS_TURBO
  16459. + unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
  16460. +#endif
  16461. +
  16462. + u8 encry_proto = ieee->wpax_type_notify & 0xff;
  16463. +
  16464. +
  16465. + int len = 0;
  16466. +
  16467. + //[0] Notify type of encryption: WPA/WPA2
  16468. + //[1] pair wise type
  16469. + //[2] authen type
  16470. + if(ieee->wpax_type_set) {
  16471. + if (IEEE_PROTO_WPA == encry_proto) {
  16472. + rsn_len = 0;
  16473. + } else if (IEEE_PROTO_RSN == encry_proto) {
  16474. + wpa_len = 0;
  16475. + }
  16476. + }
  16477. +#ifdef THOMAS_TURBO
  16478. + len = sizeof(struct ieee80211_assoc_request_frame)+
  16479. + + beacon->ssid_len//essid tagged val
  16480. + + rate_len//rates tagged val
  16481. + + wpa_len
  16482. + + rsn_len
  16483. + + wmm_info_len
  16484. + + turbo_info_len;
  16485. +#else
  16486. + len = sizeof(struct ieee80211_assoc_request_frame)+
  16487. + + beacon->ssid_len//essid tagged val
  16488. + + rate_len//rates tagged val
  16489. + + wpa_len
  16490. + + rsn_len
  16491. + + wmm_info_len;
  16492. +#endif
  16493. +
  16494. +#ifdef _RTL8187_EXT_PATCH_
  16495. + if(ieee->iw_mode == ieee->iw_ext_mode)
  16496. + skb = dev_alloc_skb(len+256); // stanley
  16497. + else
  16498. +#endif
  16499. + skb = dev_alloc_skb(len);
  16500. +
  16501. + if (!skb)
  16502. + return NULL;
  16503. +
  16504. + hdr = (struct ieee80211_assoc_request_frame *)
  16505. + skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
  16506. +
  16507. +
  16508. + hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
  16509. + hdr->header.duration_id= 37; //FIXME
  16510. + memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
  16511. + memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  16512. + memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
  16513. + memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
  16514. +
  16515. + hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
  16516. + if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
  16517. + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  16518. +
  16519. + if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE )
  16520. + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
  16521. +
  16522. + if(ieee->short_slot)
  16523. + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  16524. +
  16525. +#ifdef _RTL8187_EXT_PATCH_
  16526. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1)
  16527. + ieee->ext_patch_ieee80211_association_req_1(hdr);
  16528. +#endif
  16529. +
  16530. + hdr->listen_interval = 0xa; //FIXME
  16531. +
  16532. + hdr->info_element.id = MFIE_TYPE_SSID;
  16533. +
  16534. + hdr->info_element.len = beacon->ssid_len;
  16535. + tag = skb_put(skb, beacon->ssid_len);
  16536. + memcpy(tag, beacon->ssid, beacon->ssid_len);
  16537. +
  16538. + tag = skb_put(skb, rate_len);
  16539. +
  16540. + ieee80211_MFIE_Brate(ieee, &tag);
  16541. + ieee80211_MFIE_Grate(ieee, &tag);
  16542. +
  16543. + //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
  16544. + //choose AES encryption as default algorithm while using mixed mode
  16545. +#if 0
  16546. + if(rsn_len == 0){
  16547. +
  16548. + tag = skb_put(skb,wpa_len);
  16549. +
  16550. + if(wpa_len) {
  16551. +
  16552. +
  16553. + //{add by david. 2006.8.31
  16554. + //fix linksys compatibility bug
  16555. + //}
  16556. + if(wpa_len > 24) {//22+2, mean include the capability
  16557. + beacon->wpa_ie[wpa_len - 2] = 0;
  16558. + }
  16559. + //multicast cipher OUI
  16560. + if( beacon->wpa_ie[11]==0x2 ){ //0x0050f202 is the oui of tkip
  16561. + ieee->broadcast_key_type = KEY_TYPE_TKIP;
  16562. + }
  16563. + else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp
  16564. + ieee->broadcast_key_type = KEY_TYPE_CCMP;
  16565. + }
  16566. + //unicast cipher OUI
  16567. + if( beacon->wpa_ie[14]==0
  16568. + && beacon->wpa_ie[15]==0x50
  16569. + && beacon->wpa_ie[16]==0xf2
  16570. + && beacon->wpa_ie[17]==0x2 ){ //0x0050f202 is the oui of tkip
  16571. + ieee->pairwise_key_type = KEY_TYPE_TKIP;
  16572. + }
  16573. +
  16574. + else if( beacon->wpa_ie[14]==0
  16575. + && beacon->wpa_ie[15]==0x50
  16576. + && beacon->wpa_ie[16]==0xf2
  16577. + && beacon->wpa_ie[17]==0x4 ){//0x0050f204 is the oui of ccmp
  16578. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  16579. + }
  16580. + //indicate the wpa_ie content to WPA_SUPPLICANT
  16581. + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
  16582. + memset(buff, 0, IW_CUSTOM_MAX);
  16583. + p=buff;
  16584. + p += sprintf(p, "ASSOCINFO(ReqIEs=");
  16585. + for(i=0;i<wpa_len;i++){
  16586. + p += sprintf(p, "%02x", beacon->wpa_ie[i]);
  16587. + }
  16588. + p += sprintf(p, ")");
  16589. + memset(&wrqu, 0, sizeof(wrqu) );
  16590. + wrqu.data.length = p - buff;
  16591. +
  16592. + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
  16593. + memcpy(tag,beacon->wpa_ie,wpa_len);
  16594. + }
  16595. +
  16596. + }
  16597. +
  16598. + if(rsn_len > 22) {
  16599. +
  16600. + if( beacon->rsn_ie[4]==0x0 &&
  16601. + beacon->rsn_ie[5]==0xf &&
  16602. + beacon->rsn_ie[6]==0xac){
  16603. +
  16604. + switch(beacon->rsn_ie[7]){
  16605. + case 0x1:
  16606. + ieee->broadcast_key_type = KEY_TYPE_WEP40;
  16607. + break;
  16608. + case 0x2:
  16609. + ieee->broadcast_key_type = KEY_TYPE_TKIP;
  16610. + break;
  16611. + case 0x4:
  16612. + ieee->broadcast_key_type = KEY_TYPE_CCMP;
  16613. + break;
  16614. + case 0x5:
  16615. + ieee->broadcast_key_type = KEY_TYPE_WEP104;
  16616. + break;
  16617. + default:
  16618. + printk("fault suite type in RSN broadcast key\n");
  16619. + break;
  16620. + }
  16621. + }
  16622. +
  16623. + if( beacon->rsn_ie[10]==0x0 &&
  16624. + beacon->rsn_ie[11]==0xf &&
  16625. + beacon->rsn_ie[12]==0xac){
  16626. + if(beacon->rsn_ie[8]==1){//not mixed mode
  16627. + switch(beacon->rsn_ie[13]){
  16628. + case 0x2:
  16629. + ieee->pairwise_key_type = KEY_TYPE_TKIP;
  16630. + break;
  16631. + case 0x4:
  16632. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  16633. + break;
  16634. + default:
  16635. + printk("fault suite type in RSN pairwise key\n");
  16636. + break;
  16637. + }
  16638. + }
  16639. + else if(beacon->rsn_ie[8]==2){//mixed mode
  16640. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  16641. + }
  16642. + }
  16643. +
  16644. +
  16645. +
  16646. + tag = skb_put(skb,22);
  16647. + memcpy(tag,(beacon->rsn_ie + info_addr),8);
  16648. + tag[1] = 20;
  16649. + tag += 8;
  16650. + info_addr += 8;
  16651. +
  16652. + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
  16653. + for (i = 0; i < 2; i++) {
  16654. + tag[0] = 1;
  16655. + tag[1] = 0;
  16656. + tag += 2;
  16657. + suite_count = beacon->rsn_ie[info_addr] + \
  16658. + (beacon->rsn_ie[info_addr + 1] << 8);
  16659. + info_addr += 2;
  16660. + if(1 == suite_count) {
  16661. + memcpy(tag,(beacon->rsn_ie + info_addr),4);
  16662. + info_addr += 4;
  16663. + } else {
  16664. + // if the wpax_type_notify has been set by the application,
  16665. + // just use it, otherwise just use the default one.
  16666. + if(ieee->wpax_type_set) {
  16667. + suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ;
  16668. + memcpy(tag,rsn_authen_cipher_suite[suit_select],4);
  16669. + } else {
  16670. + //default set as ccmp, or none authentication
  16671. + if(i == 0) {
  16672. + memcpy(tag,rsn_authen_cipher_suite[4],4);
  16673. + } else {
  16674. + memcpy(tag,rsn_authen_cipher_suite[2],4);
  16675. + }
  16676. +
  16677. + }
  16678. +
  16679. + info_addr += (suite_count * 4);
  16680. + }
  16681. + tag += 4;
  16682. + }
  16683. + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
  16684. +
  16685. + tag[0] = 0;
  16686. + tag[1] = beacon->rsn_ie[info_addr+1];
  16687. +
  16688. +
  16689. +
  16690. + } else {
  16691. + tag = skb_put(skb,rsn_len);
  16692. + if(rsn_len) {
  16693. +
  16694. +
  16695. + if( beacon->rsn_ie[4]==0x0 &&
  16696. + beacon->rsn_ie[5]==0xf &&
  16697. + beacon->rsn_ie[6]==0xac){
  16698. + switch(beacon->rsn_ie[7]){
  16699. + case 0x1:
  16700. + ieee->broadcast_key_type = KEY_TYPE_WEP40;
  16701. + break;
  16702. + case 0x2:
  16703. + ieee->broadcast_key_type = KEY_TYPE_TKIP;
  16704. + break;
  16705. + case 0x4:
  16706. + ieee->broadcast_key_type = KEY_TYPE_CCMP;
  16707. + break;
  16708. + case 0x5:
  16709. + ieee->broadcast_key_type = KEY_TYPE_WEP104;
  16710. + break;
  16711. + default:
  16712. + printk("fault suite type in RSN broadcast key\n");
  16713. + break;
  16714. + }
  16715. + }
  16716. + if( beacon->rsn_ie[10]==0x0 &&
  16717. + beacon->rsn_ie[11]==0xf &&
  16718. + beacon->rsn_ie[12]==0xac){
  16719. + if(beacon->rsn_ie[8]==1){//not mixed mode
  16720. + switch(beacon->rsn_ie[13]){
  16721. + case 0x2:
  16722. + ieee->pairwise_key_type = KEY_TYPE_TKIP;
  16723. + break;
  16724. + case 0x4:
  16725. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  16726. + break;
  16727. + default:
  16728. + printk("fault suite type in RSN pairwise key\n");
  16729. + break;
  16730. + }
  16731. +
  16732. + }
  16733. + else if(beacon->rsn_ie[8]==2){//mixed mode
  16734. + ieee->pairwise_key_type = KEY_TYPE_CCMP;
  16735. + }
  16736. + }
  16737. +
  16738. +
  16739. + beacon->rsn_ie[rsn_len - 2] = 0;
  16740. + memcpy(tag,beacon->rsn_ie,rsn_len);
  16741. + }
  16742. + }
  16743. +#else
  16744. + if (ieee->wpa_ie){
  16745. + tag = skb_put(skb,ieee->wpa_ie_len);
  16746. + memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
  16747. + }
  16748. +#endif
  16749. + tag = skb_put(skb,wmm_info_len);
  16750. + if(wmm_info_len) {
  16751. + ieee80211_WMM_Info(ieee, &tag);
  16752. + }
  16753. +#ifdef THOMAS_TURBO
  16754. + tag = skb_put(skb,turbo_info_len);
  16755. + if(turbo_info_len) {
  16756. + ieee80211_TURBO_Info(ieee, &tag);
  16757. + }
  16758. +#endif
  16759. +
  16760. +#ifdef _RTL8187_EXT_PATCH_
  16761. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2)
  16762. + ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb);
  16763. +#endif
  16764. +
  16765. + return skb;
  16766. +}
  16767. +
  16768. +void ieee80211_associate_abort(struct ieee80211_device *ieee)
  16769. +{
  16770. +
  16771. + unsigned long flags;
  16772. + spin_lock_irqsave(&ieee->lock, flags);
  16773. +
  16774. + ieee->associate_seq++;
  16775. +
  16776. + /* don't scan, and avoid to have the RX path possibily
  16777. + * try again to associate. Even do not react to AUTH or
  16778. + * ASSOC response. Just wait for the retry wq to be scheduled.
  16779. + * Here we will check if there are good nets to associate
  16780. + * with, so we retry or just get back to NO_LINK and scanning
  16781. + */
  16782. + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
  16783. + IEEE80211_DEBUG_MGMT("Authentication failed\n");
  16784. + ieee->softmac_stats.no_auth_rs++;
  16785. + }else{
  16786. + IEEE80211_DEBUG_MGMT("Association failed\n");
  16787. + ieee->softmac_stats.no_ass_rs++;
  16788. + }
  16789. +
  16790. + ieee->state = IEEE80211_ASSOCIATING_RETRY;
  16791. +
  16792. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  16793. + queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
  16794. + IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
  16795. +#else
  16796. + schedule_task(&ieee->associate_retry_wq);
  16797. +#endif
  16798. +
  16799. + spin_unlock_irqrestore(&ieee->lock, flags);
  16800. +}
  16801. +
  16802. +void ieee80211_associate_abort_cb(unsigned long dev)
  16803. +{
  16804. + ieee80211_associate_abort((struct ieee80211_device *) dev);
  16805. +}
  16806. +
  16807. +
  16808. +void ieee80211_associate_step1(struct ieee80211_device *ieee)
  16809. +{
  16810. + struct ieee80211_network *beacon = &ieee->current_network;
  16811. + struct sk_buff *skb;
  16812. +
  16813. + IEEE80211_DEBUG_MGMT("Stopping scan\n");
  16814. +
  16815. + ieee->softmac_stats.tx_auth_rq++;
  16816. + skb=ieee80211_authentication_req(beacon, ieee, 0);
  16817. +
  16818. +#ifdef _RTL8187_EXT_PATCH_
  16819. + if(ieee->iw_mode == ieee->iw_ext_mode ) {
  16820. + if(skb)
  16821. + softmac_mgmt_xmit(skb, ieee);
  16822. + return;
  16823. + }else
  16824. +#endif
  16825. + if (!skb)
  16826. + ieee80211_associate_abort(ieee);
  16827. + else{
  16828. + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
  16829. + IEEE80211_DEBUG_MGMT("Sending authentication request\n");
  16830. + //printk(KERN_WARNING "Sending authentication request\n");
  16831. + softmac_mgmt_xmit(skb, ieee);
  16832. + //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
  16833. + if(!timer_pending(&ieee->associate_timer)){
  16834. + ieee->associate_timer.expires = jiffies + (HZ / 2);
  16835. + add_timer(&ieee->associate_timer);
  16836. + }
  16837. + dev_kfree_skb_any(skb);//edit by thomas
  16838. + }
  16839. +}
  16840. +
  16841. +void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
  16842. +{
  16843. + u8 *c;
  16844. + struct sk_buff *skb;
  16845. + struct ieee80211_network *beacon = &ieee->current_network;
  16846. +// int hlen = sizeof(struct ieee80211_authentication);
  16847. +
  16848. + ieee->associate_seq++;
  16849. + ieee->softmac_stats.tx_auth_rq++;
  16850. +
  16851. + skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
  16852. + if (!skb)
  16853. + ieee80211_associate_abort(ieee);
  16854. + else{
  16855. + c = skb_put(skb, chlen+2);
  16856. + *(c++) = MFIE_TYPE_CHALLENGE;
  16857. + *(c++) = chlen;
  16858. + memcpy(c, challenge, chlen);
  16859. +
  16860. + IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
  16861. +
  16862. + ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
  16863. +
  16864. + softmac_mgmt_xmit(skb, ieee);
  16865. +
  16866. + if(!timer_pending(&ieee->associate_timer)){
  16867. + ieee->associate_timer.expires = jiffies + (HZ / 2);
  16868. + add_timer(&ieee->associate_timer);
  16869. + }
  16870. + dev_kfree_skb_any(skb);//edit by thomas
  16871. + }
  16872. + kfree(challenge);
  16873. +}
  16874. +
  16875. +#ifdef _RTL8187_EXT_PATCH_
  16876. +
  16877. +// based on ieee80211_assoc_resp
  16878. +struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
  16879. +{
  16880. + struct sk_buff *skb;
  16881. + u8* tag;
  16882. +
  16883. + struct ieee80211_crypt_data* crypt;
  16884. + struct ieee80211_assoc_response_frame *assoc;
  16885. + short encrypt;
  16886. +
  16887. + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
  16888. + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
  16889. +
  16890. + if(ieee->iw_mode == ieee->iw_ext_mode)
  16891. + skb = dev_alloc_skb(len+256); // stanley
  16892. + else
  16893. + skb = dev_alloc_skb(len);
  16894. +
  16895. + if (!skb)
  16896. + return NULL;
  16897. +
  16898. + assoc = (struct ieee80211_assoc_response_frame *)
  16899. + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
  16900. +
  16901. + assoc->header.frame_ctl = cpu_to_le16(pkt_type);
  16902. +
  16903. + memcpy(assoc->header.addr1, dest,ETH_ALEN);
  16904. + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
  16905. + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
  16906. + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
  16907. + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
  16908. +
  16909. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1)
  16910. + ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc);
  16911. +
  16912. + if(ieee->short_slot)
  16913. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
  16914. +
  16915. + if (ieee->host_encrypt)
  16916. +#ifdef _RTL8187_EXT_PATCH_
  16917. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  16918. +#else
  16919. + crypt = ieee->crypt[ieee->tx_keyidx];
  16920. +#endif
  16921. +
  16922. + else crypt = NULL;
  16923. +
  16924. + encrypt = ( crypt && crypt->ops);
  16925. +
  16926. + if (encrypt)
  16927. + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
  16928. +
  16929. + assoc->status = 0;
  16930. + assoc->aid = cpu_to_le16(ieee->assoc_id);
  16931. + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
  16932. + else ieee->assoc_id++;
  16933. +
  16934. + assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
  16935. + assoc->info_element.len = 0;
  16936. +
  16937. + tag = (u8*) skb_put(skb, rate_len);
  16938. +
  16939. + ieee80211_MFIE_Brate(ieee, &tag);
  16940. + ieee80211_MFIE_Grate(ieee, &tag);
  16941. +
  16942. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2)
  16943. + ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb);
  16944. +
  16945. + return skb;
  16946. +}
  16947. +
  16948. +// based on ieee80211_resp_to_assoc_rq
  16949. +void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
  16950. +{
  16951. + struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
  16952. +
  16953. + if (buf)
  16954. + softmac_mgmt_xmit(buf, ieee);
  16955. +}
  16956. +
  16957. +// based on ieee80211_associate_step2
  16958. +void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
  16959. +{
  16960. +
  16961. + struct sk_buff* skb;
  16962. +
  16963. + // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
  16964. +
  16965. + ieee->softmac_stats.tx_ass_rq++;
  16966. + skb=ieee80211_association_req(pstat, ieee);
  16967. + if (skb)
  16968. + softmac_mgmt_xmit(skb, ieee);
  16969. +}
  16970. +
  16971. +void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
  16972. +{
  16973. + // do nothing
  16974. + // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
  16975. + return;
  16976. +}
  16977. +#endif // _RTL8187_EXT_PATCH_
  16978. +
  16979. +void ieee80211_associate_step2(struct ieee80211_device *ieee)
  16980. +{
  16981. + struct sk_buff* skb;
  16982. + struct ieee80211_network *beacon = &ieee->current_network;
  16983. +
  16984. +// del_timer_sync(&ieee->associate_timer);
  16985. +
  16986. + IEEE80211_DEBUG_MGMT("Sending association request\n");
  16987. +
  16988. + ieee->softmac_stats.tx_ass_rq++;
  16989. + skb=ieee80211_association_req(beacon, ieee);
  16990. + if (!skb)
  16991. + ieee80211_associate_abort(ieee);
  16992. + else{
  16993. + softmac_mgmt_xmit(skb, ieee);
  16994. + if(!timer_pending(&ieee->associate_timer)){
  16995. + ieee->associate_timer.expires = jiffies + (HZ / 2);
  16996. + add_timer(&ieee->associate_timer);
  16997. + }
  16998. + dev_kfree_skb_any(skb);//edit by thomas
  16999. + }
  17000. +}
  17001. +
  17002. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  17003. +void ieee80211_associate_complete_wq(struct work_struct *work)
  17004. +{
  17005. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
  17006. +#else
  17007. +void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
  17008. +{
  17009. +#endif
  17010. + printk(KERN_INFO "Associated successfully\n");
  17011. + if(ieee80211_is_54g(ieee->current_network) &&
  17012. + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
  17013. +
  17014. + ieee->rate = 540;
  17015. + printk(KERN_INFO"Using G rates\n");
  17016. + }else{
  17017. + ieee->rate = 110;
  17018. + printk(KERN_INFO"Using B rates\n");
  17019. + }
  17020. +
  17021. +//by lizhaoming for LED LINK
  17022. +#ifdef LED_SHIN
  17023. + {
  17024. + struct net_device *dev = ieee->dev;
  17025. + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  17026. + }
  17027. +#endif
  17028. +
  17029. + ieee->link_change(ieee->dev);
  17030. + notify_wx_assoc_event(ieee);
  17031. + if (ieee->data_hard_resume)
  17032. + ieee->data_hard_resume(ieee->dev);
  17033. + netif_carrier_on(ieee->dev);
  17034. +}
  17035. +
  17036. +void ieee80211_associate_complete(struct ieee80211_device *ieee)
  17037. +{
  17038. + int i;
  17039. +// struct net_device *dev = ieee->dev;
  17040. + del_timer_sync(&ieee->associate_timer);
  17041. +
  17042. + for(i = 0; i < 6; i++) {
  17043. +// ieee->seq_ctrl[i] = 0;
  17044. + }
  17045. + ieee->state = IEEE80211_LINKED;
  17046. + IEEE80211_DEBUG_MGMT("Successfully associated\n");
  17047. +
  17048. + //by lizhaoming for LED LINK
  17049. + //ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  17050. +
  17051. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  17052. + queue_work(ieee->wq, &ieee->associate_complete_wq);
  17053. +#else
  17054. + schedule_task(&ieee->associate_complete_wq);
  17055. +#endif
  17056. +}
  17057. +
  17058. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  17059. +void ieee80211_associate_procedure_wq(struct work_struct *work)
  17060. +{
  17061. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
  17062. +#else
  17063. +void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
  17064. +{
  17065. +#endif
  17066. + ieee->sync_scan_hurryup = 1;
  17067. + down(&ieee->wx_sem);
  17068. +
  17069. + if (ieee->data_hard_stop)
  17070. + ieee->data_hard_stop(ieee->dev);
  17071. +
  17072. + ieee80211_stop_scan(ieee);
  17073. + //printk("=======>%s set chan:%d\n", __func__, ieee->current_network.channel);
  17074. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  17075. +
  17076. + ieee->associate_seq = 1;
  17077. + ieee80211_associate_step1(ieee);
  17078. +
  17079. + up(&ieee->wx_sem);
  17080. +}
  17081. +#ifdef _RTL8187_EXT_PATCH_
  17082. +// based on ieee80211_associate_procedure_wq
  17083. +
  17084. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17085. +void ieee80211_ext_stop_scan_wq(struct work_struct *work)
  17086. +{
  17087. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
  17088. +#else
  17089. +void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
  17090. +{
  17091. +#endif
  17092. +/*
  17093. + if (ieee->scanning == 0)
  17094. + {
  17095. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
  17096. + && ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) )
  17097. + return;
  17098. + }
  17099. +*/
  17100. + ieee->sync_scan_hurryup = 1;
  17101. +
  17102. + down(&ieee->wx_sem);
  17103. +
  17104. + // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
  17105. + if (ieee->data_hard_stop)
  17106. + ieee->data_hard_stop(ieee->dev);
  17107. +
  17108. + ieee80211_stop_scan(ieee);
  17109. +
  17110. + // set channel
  17111. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel)
  17112. + {
  17113. + int ch = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
  17114. + ieee->current_network.channel = ch;
  17115. + ieee->set_chan(ieee->dev, ch);
  17116. + }
  17117. + else
  17118. + {
  17119. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  17120. + }
  17121. + //
  17122. + up(&ieee->wx_sem);
  17123. +}
  17124. +
  17125. +
  17126. +void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
  17127. +{
  17128. + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  17129. + queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
  17130. + #else
  17131. + schedule_task(&ieee->ext_send_beacon_wq);
  17132. + #endif
  17133. +
  17134. +}
  17135. +
  17136. +#endif // _RTL8187_EXT_PATCH_
  17137. +
  17138. +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
  17139. +{
  17140. + u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
  17141. + int tmp_ssid_len = 0;
  17142. +
  17143. + short apset,ssidset,ssidbroad,apmatch,ssidmatch;
  17144. +// printk("===============>%s()\n",__FUNCTION__);
  17145. + /* we are interested in new new only if we are not associated
  17146. + * and we are not associating / authenticating
  17147. + */
  17148. + if (ieee->state != IEEE80211_NOLINK)
  17149. + return;
  17150. +
  17151. + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
  17152. + return;
  17153. +
  17154. + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
  17155. + return;
  17156. +
  17157. +
  17158. + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
  17159. + /* if the user specified the AP MAC, we need also the essid
  17160. + * This could be obtained by beacons or, if the network does not
  17161. + * broadcast it, it can be put manually.
  17162. + */
  17163. + apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
  17164. + ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
  17165. + ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
  17166. + apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
  17167. + if(ieee->current_network.ssid_len != net->ssid_len)
  17168. + ssidmatch = 0;
  17169. + else
  17170. + ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
  17171. +
  17172. +
  17173. +
  17174. + if ( /* if the user set the AP check if match.
  17175. + * if the network does not broadcast essid we check the user supplyed ANY essid
  17176. + * if the network does broadcast and the user does not set essid it is OK
  17177. + * if the network does broadcast and the user did set essid chech if essid match
  17178. + */
  17179. + ( apset && apmatch &&
  17180. + //((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
  17181. + ((ssidset && ssidbroad && ssidmatch) || (!ssidbroad && ssidset)) ) ||
  17182. + /* if the ap is not set, check that the user set the bssid
  17183. + * and the network does bradcast and that those two bssid matches
  17184. + */
  17185. + (!apset && ssidset && ssidbroad && ssidmatch)
  17186. + ){
  17187. + /* if the essid is hidden replace it with the
  17188. + * essid provided by the user.
  17189. + */
  17190. + if (!ssidbroad){
  17191. + strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
  17192. + tmp_ssid_len = ieee->current_network.ssid_len;
  17193. + }
  17194. + memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
  17195. +
  17196. + if (!ssidbroad){
  17197. + strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
  17198. + ieee->current_network.ssid_len = tmp_ssid_len;
  17199. + }
  17200. + printk(KERN_INFO"Linking with %s, channel:%d\n",ieee->current_network.ssid, ieee->current_network.channel);
  17201. +
  17202. +#ifdef CONFIG_IPS
  17203. + ieee->ieee80211_ips_leave(ieee->dev);
  17204. +#endif
  17205. +
  17206. + if (ieee->iw_mode == IW_MODE_INFRA){
  17207. + ieee->state = IEEE80211_ASSOCIATING;
  17208. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  17209. + queue_work(ieee->wq, &ieee->associate_procedure_wq);
  17210. +#else
  17211. + schedule_task(&ieee->associate_procedure_wq);
  17212. +#endif
  17213. + }else{
  17214. + ieee->state = IEEE80211_LINKED;
  17215. + if(ieee80211_is_54g(ieee->current_network) &&
  17216. + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
  17217. + ieee->rate = 540;
  17218. + printk(KERN_INFO"Using G rates\n");
  17219. + }else{
  17220. + ieee->rate = 110;
  17221. + printk(KERN_INFO"Using B rates\n");
  17222. + }
  17223. + }
  17224. +
  17225. + }
  17226. + }
  17227. +
  17228. +}
  17229. +
  17230. +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
  17231. +{
  17232. + unsigned long flags;
  17233. + struct ieee80211_network *target;
  17234. +
  17235. + spin_lock_irqsave(&ieee->lock, flags);
  17236. +#if 0
  17237. + list_for_each_entry(target, &ieee->network_list, list) {
  17238. + printk(KERN_INFO"check network list SSID: %s, channel: %d\n",target->ssid,target->channel);
  17239. + }
  17240. +#endif
  17241. + list_for_each_entry(target, &ieee->network_list, list) {
  17242. +
  17243. + /* if the state become different that NOLINK means
  17244. + * we had found what we are searching for
  17245. + */
  17246. +
  17247. + if (ieee->state != IEEE80211_NOLINK)
  17248. + break;
  17249. +
  17250. + if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
  17251. + ieee80211_softmac_new_net(ieee, target);
  17252. + }
  17253. +
  17254. + spin_unlock_irqrestore(&ieee->lock, flags);
  17255. +
  17256. + //printk("<=====%s\n", __func__);
  17257. +}
  17258. +
  17259. +
  17260. +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
  17261. +{
  17262. + struct ieee80211_authentication *a;
  17263. + u8 *t;
  17264. + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
  17265. + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
  17266. + return 0xcafe;
  17267. + }
  17268. + *challenge = NULL;
  17269. + a = (struct ieee80211_authentication*) skb->data;
  17270. + if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
  17271. + t = skb->data + sizeof(struct ieee80211_authentication);
  17272. +
  17273. + if(*(t++) == MFIE_TYPE_CHALLENGE){
  17274. + *chlen = *(t++);
  17275. + *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
  17276. + memcpy(*challenge, t, *chlen);
  17277. + }
  17278. + }
  17279. +
  17280. + return cpu_to_le16(a->status);
  17281. +
  17282. +}
  17283. +
  17284. +
  17285. +int auth_rq_parse(struct sk_buff *skb,u8* dest)
  17286. +{
  17287. + struct ieee80211_authentication *a;
  17288. +
  17289. + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
  17290. + IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
  17291. + return -1;
  17292. + }
  17293. + a = (struct ieee80211_authentication*) skb->data;
  17294. +
  17295. + memcpy(dest,a->header.addr2, ETH_ALEN);
  17296. +
  17297. + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
  17298. + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
  17299. +
  17300. + return WLAN_STATUS_SUCCESS;
  17301. +}
  17302. +
  17303. +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
  17304. +{
  17305. + u8 *tag;
  17306. + u8 *skbend;
  17307. + u8 *ssid=NULL;
  17308. + u8 ssidlen = 0;
  17309. +
  17310. + struct ieee80211_hdr_3addr *header =
  17311. + (struct ieee80211_hdr_3addr *) skb->data;
  17312. +
  17313. + if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
  17314. + return -1; /* corrupted */
  17315. +
  17316. + memcpy(src,header->addr2, ETH_ALEN);
  17317. +
  17318. + skbend = (u8*)skb->data + skb->len;
  17319. +
  17320. + tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
  17321. +
  17322. + while (tag+1 < skbend){
  17323. + if (*tag == 0){
  17324. + ssid = tag+2;
  17325. + ssidlen = *(tag+1);
  17326. + break;
  17327. + }
  17328. + tag++; /* point to the len field */
  17329. + tag = tag + *(tag); /* point to the last data byte of the tag */
  17330. + tag++; /* point to the next tag */
  17331. + }
  17332. +
  17333. + //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
  17334. + if (ssidlen == 0) return 1;
  17335. +
  17336. + if (!ssid) return 1; /* ssid not found in tagged param */
  17337. + return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
  17338. +
  17339. +}
  17340. +
  17341. +int assoc_rq_parse(struct sk_buff *skb,u8* dest)
  17342. +{
  17343. + struct ieee80211_assoc_request_frame *a;
  17344. +
  17345. + if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
  17346. + sizeof(struct ieee80211_info_element))) {
  17347. +
  17348. + IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
  17349. + return -1;
  17350. + }
  17351. +
  17352. + a = (struct ieee80211_assoc_request_frame*) skb->data;
  17353. +
  17354. + memcpy(dest,a->header.addr2,ETH_ALEN);
  17355. +
  17356. + return 0;
  17357. +}
  17358. +
  17359. +static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
  17360. +{
  17361. + struct ieee80211_assoc_response_frame *a;
  17362. + if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
  17363. + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
  17364. + return 0xcafe;
  17365. + }
  17366. +
  17367. + a = (struct ieee80211_assoc_response_frame*) skb->data;
  17368. + *aid = le16_to_cpu(a->aid) & 0x3fff;
  17369. + return le16_to_cpu(a->status);
  17370. +}
  17371. +
  17372. +static inline void
  17373. +ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  17374. +{
  17375. + u8 dest[ETH_ALEN];
  17376. +
  17377. + //IEEE80211DMESG("Rx probe");
  17378. + ieee->softmac_stats.rx_probe_rq++;
  17379. + //DMESG("Dest is "MACSTR, MAC2STR(dest));
  17380. + if (probe_rq_parse(ieee, skb, dest)){
  17381. + //IEEE80211DMESG("Was for me!");
  17382. + ieee->softmac_stats.tx_probe_rs++;
  17383. + ieee80211_resp_to_probe(ieee, dest);
  17384. + }
  17385. +}
  17386. +
  17387. +//static inline void
  17388. +inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  17389. +{
  17390. + u8 dest[ETH_ALEN];
  17391. + int status;
  17392. + //IEEE80211DMESG("Rx probe");
  17393. + ieee->softmac_stats.rx_auth_rq++;
  17394. +
  17395. + if ((status = auth_rq_parse(skb, dest))!= -1){
  17396. + ieee80211_resp_to_auth(ieee, status, dest);
  17397. + }
  17398. + //DMESG("Dest is "MACSTR, MAC2STR(dest));
  17399. +
  17400. +}
  17401. +
  17402. +//static inline void
  17403. +inline void
  17404. +ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
  17405. +{
  17406. +
  17407. + u8 dest[ETH_ALEN];
  17408. + //unsigned long flags;
  17409. +
  17410. + ieee->softmac_stats.rx_ass_rq++;
  17411. + if (assoc_rq_parse(skb,dest) != -1){
  17412. + ieee80211_resp_to_assoc_rq(ieee, dest);
  17413. + }
  17414. +
  17415. + printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
  17416. + //FIXME
  17417. + #if 0
  17418. + spin_lock_irqsave(&ieee->lock,flags);
  17419. + add_associate(ieee,dest);
  17420. + spin_unlock_irqrestore(&ieee->lock,flags);
  17421. + #endif
  17422. +}
  17423. +
  17424. +
  17425. +
  17426. +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
  17427. +{
  17428. +
  17429. + struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
  17430. +
  17431. + printk(KERN_ALERT "ieee80211_sta_ps_send_null_frame \n");
  17432. + if (buf)
  17433. + softmac_ps_mgmt_xmit(buf, ieee);
  17434. +
  17435. +}
  17436. +
  17437. +
  17438. +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
  17439. +{
  17440. + int timeout = ieee->ps_timeout;
  17441. + u8 dtim;
  17442. + /*if(ieee->ps == IEEE80211_PS_DISABLED ||
  17443. + ieee->iw_mode != IW_MODE_INFRA ||
  17444. + ieee->state != IEEE80211_LINKED)
  17445. +
  17446. + return 0;
  17447. + */
  17448. + dtim = ieee->current_network.dtim_data;
  17449. + //printk("DTIM\n");
  17450. + if(!(dtim & IEEE80211_DTIM_VALID))
  17451. + return 0;
  17452. + //printk("VALID\n");
  17453. + ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
  17454. +
  17455. + if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
  17456. + return 2;
  17457. +
  17458. + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
  17459. + return 0;
  17460. +
  17461. + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
  17462. + return 0;
  17463. +
  17464. + if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
  17465. + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
  17466. + return 0;
  17467. +
  17468. + if(time_l){
  17469. + *time_l = ieee->current_network.last_dtim_sta_time[0]
  17470. + + (ieee->current_network.beacon_interval
  17471. + * ieee->current_network.dtim_period) * 1000;
  17472. + }
  17473. +
  17474. + if(time_h){
  17475. + *time_h = ieee->current_network.last_dtim_sta_time[1];
  17476. + if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
  17477. + *time_h += 1;
  17478. + }
  17479. +
  17480. + return 1;
  17481. +
  17482. +
  17483. +}
  17484. +
  17485. +inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
  17486. +{
  17487. +
  17488. + u32 th,tl;
  17489. + short sleep;
  17490. +
  17491. + unsigned long flags,flags2;
  17492. +
  17493. + spin_lock_irqsave(&ieee->lock, flags);
  17494. +
  17495. + if((ieee->ps == IEEE80211_PS_DISABLED ||
  17496. + ieee->iw_mode != IW_MODE_INFRA ||
  17497. + ieee->state != IEEE80211_LINKED)){
  17498. +
  17499. + // #warning CHECK_LOCK_HERE
  17500. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  17501. +
  17502. + ieee80211_sta_wakeup(ieee, 1);
  17503. +
  17504. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  17505. + }
  17506. +
  17507. + sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
  17508. + /* 2 wake, 1 sleep, 0 do nothing */
  17509. + if(sleep == 0)
  17510. + goto out;
  17511. +
  17512. + if(sleep == 1){
  17513. +
  17514. + if(ieee->sta_sleep == 1)
  17515. + ieee->enter_sleep_state(ieee->dev,th,tl);
  17516. +
  17517. + else if(ieee->sta_sleep == 0){
  17518. + // printk("send null 1\n");
  17519. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  17520. +
  17521. + if(ieee->ps_is_queue_empty(ieee->dev)){
  17522. +
  17523. +
  17524. + ieee->sta_sleep = 2;
  17525. +
  17526. + ieee->ps_request_tx_ack(ieee->dev);
  17527. +
  17528. + ieee80211_sta_ps_send_null_frame(ieee,1);
  17529. +
  17530. + ieee->ps_th = th;
  17531. + ieee->ps_tl = tl;
  17532. + }
  17533. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  17534. +
  17535. + }
  17536. +
  17537. +
  17538. + }else if(sleep == 2){
  17539. +//#warning CHECK_LOCK_HERE
  17540. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  17541. +
  17542. + ieee80211_sta_wakeup(ieee,1);
  17543. +
  17544. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  17545. + }
  17546. +
  17547. +out:
  17548. + spin_unlock_irqrestore(&ieee->lock, flags);
  17549. +
  17550. +}
  17551. +
  17552. +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
  17553. +{
  17554. + if(ieee->sta_sleep == 0){
  17555. + if(nl){
  17556. + printk("Warning: driver is probably failing to report TX ps error\n");
  17557. + ieee->ps_request_tx_ack(ieee->dev);
  17558. + ieee80211_sta_ps_send_null_frame(ieee, 0);
  17559. + }
  17560. + return;
  17561. +
  17562. + }
  17563. +
  17564. + if(ieee->sta_sleep == 1)
  17565. + ieee->sta_wake_up(ieee->dev);
  17566. +
  17567. + ieee->sta_sleep = 0;
  17568. +
  17569. + if(nl){
  17570. + ieee->ps_request_tx_ack(ieee->dev);
  17571. + ieee80211_sta_ps_send_null_frame(ieee, 0);
  17572. + }
  17573. +}
  17574. +
  17575. +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
  17576. +{
  17577. + unsigned long flags,flags2;
  17578. +
  17579. + spin_lock_irqsave(&ieee->lock, flags);
  17580. +
  17581. + if(ieee->sta_sleep == 2){
  17582. + /* Null frame with PS bit set */
  17583. + if(success){
  17584. + ieee->sta_sleep = 1;
  17585. + ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
  17586. + }
  17587. + /* if the card report not success we can't be sure the AP
  17588. + * has not RXed so we can't assume the AP believe us awake
  17589. + */
  17590. + }
  17591. + /* 21112005 - tx again null without PS bit if lost */
  17592. + else {
  17593. +
  17594. + if((ieee->sta_sleep == 0) && !success){
  17595. + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
  17596. + ieee80211_sta_ps_send_null_frame(ieee, 0);
  17597. + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
  17598. + }
  17599. + }
  17600. + spin_unlock_irqrestore(&ieee->lock, flags);
  17601. +}
  17602. +
  17603. +inline int
  17604. +ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
  17605. + struct ieee80211_rx_stats *rx_stats, u16 type,
  17606. + u16 stype)
  17607. +{
  17608. + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
  17609. + u16 errcode;
  17610. + u8* challenge=NULL;
  17611. + int chlen=0;
  17612. + int aid=0;
  17613. + struct ieee80211_assoc_response_frame *assoc_resp;
  17614. + struct ieee80211_info_element *info_element;
  17615. +
  17616. + if(!ieee->proto_started)
  17617. + return 0;
  17618. +
  17619. + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
  17620. + ieee->iw_mode == IW_MODE_INFRA &&
  17621. + ieee->state == IEEE80211_LINKED))
  17622. +
  17623. + tasklet_schedule(&ieee->ps_task);
  17624. +
  17625. + if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
  17626. + WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
  17627. + ieee->last_rx_ps_time = jiffies;
  17628. +
  17629. + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
  17630. + case IEEE80211_STYPE_ASSOC_RESP:
  17631. + case IEEE80211_STYPE_REASSOC_RESP:
  17632. +
  17633. + IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
  17634. + WLAN_FC_GET_STYPE(header->frame_ctl));
  17635. + //printk(KERN_WARNING "Received association response\n");
  17636. + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  17637. + ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
  17638. + ieee->iw_mode == IW_MODE_INFRA){
  17639. + if (0 == (errcode=assoc_parse(skb, &aid))){
  17640. + u16 left;
  17641. +
  17642. + ieee->state=IEEE80211_LINKED;
  17643. + ieee->assoc_id = aid;
  17644. + ieee->softmac_stats.rx_ass_ok++;
  17645. +
  17646. + //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B");
  17647. + if(1 == rx_stats->nic_type) //card type is 8187
  17648. + {
  17649. + goto associate_complete;
  17650. + }
  17651. + assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
  17652. + info_element = &assoc_resp->info_element;
  17653. + left = skb->len - ((void*)info_element - (void*)assoc_resp);
  17654. +
  17655. + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
  17656. + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
  17657. + printk(KERN_WARNING "[re]associate reeponse error!");
  17658. + return 1;
  17659. + }
  17660. + switch (info_element->id) {
  17661. + case MFIE_TYPE_GENERIC:
  17662. + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
  17663. + if (info_element->len >= 8 &&
  17664. + info_element->data[0] == 0x00 &&
  17665. + info_element->data[1] == 0x50 &&
  17666. + info_element->data[2] == 0xf2 &&
  17667. + info_element->data[3] == 0x02 &&
  17668. + info_element->data[4] == 0x01) {
  17669. + // Not care about version at present.
  17670. + //WMM Parameter Element
  17671. + memcpy(ieee->current_network.wmm_param,(u8*)(info_element->data\
  17672. + + 8),(info_element->len - 8));
  17673. +
  17674. + if (((ieee->current_network.wmm_info^info_element->data[6])& \
  17675. + 0x0f)||(!ieee->init_wmmparam_flag)) {
  17676. + //refresh paramete element for current network
  17677. + // update the register parameter for hardware
  17678. + ieee->init_wmmparam_flag = 1;
  17679. + //ieee->wmm_param_update(ieee);
  17680. + //schedule_work(&ieee->wmm_param_update_wq);
  17681. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  17682. + queue_work(ieee->wq, &ieee->wmm_param_update_wq);
  17683. +#else
  17684. + schedule_task(&ieee->wmm_param_update_wq);
  17685. +#endif
  17686. +
  17687. + }
  17688. + //update info_element for current network
  17689. + ieee->current_network.wmm_info = info_element->data[6];
  17690. + }
  17691. + break;
  17692. + default:
  17693. + //nothing to do at present!!!
  17694. + break;
  17695. + }
  17696. +
  17697. + left -= sizeof(struct ieee80211_info_element_hdr) +
  17698. + info_element->len;
  17699. + info_element = (struct ieee80211_info_element *)
  17700. + &info_element->data[info_element->len];
  17701. + }
  17702. + if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register
  17703. + {
  17704. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  17705. + queue_work(ieee->wq,&ieee->wmm_param_update_wq);
  17706. +#else
  17707. + schedule_task(&ieee->wmm_param_update_wq);
  17708. +#endif
  17709. + ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate
  17710. + }
  17711. +associate_complete:
  17712. + ieee80211_associate_complete(ieee);
  17713. + }else{
  17714. + ieee->softmac_stats.rx_ass_err++;
  17715. + IEEE80211_DEBUG_MGMT(
  17716. + "Association response status code 0x%x\n",
  17717. + errcode);
  17718. + printk(KERN_WARNING "Association response status code 0x%x\n",
  17719. + errcode);
  17720. + ieee80211_associate_abort(ieee);
  17721. + }
  17722. + }
  17723. +#ifdef _RTL8187_EXT_PATCH_
  17724. + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp)
  17725. + {
  17726. + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
  17727. + }
  17728. +#endif
  17729. + break;
  17730. +
  17731. + case IEEE80211_STYPE_ASSOC_REQ:
  17732. + case IEEE80211_STYPE_REASSOC_REQ:
  17733. + //printk("Received IEEE80211_STYPE_ASSOC_REQ\n");
  17734. +
  17735. + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  17736. + ieee->iw_mode == IW_MODE_MASTER)
  17737. +
  17738. + ieee80211_rx_assoc_rq(ieee, skb);
  17739. +#ifdef _RTL8187_EXT_PATCH_
  17740. + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req)
  17741. + {
  17742. + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
  17743. + }
  17744. +#endif
  17745. + break;
  17746. +
  17747. + case IEEE80211_STYPE_AUTH:
  17748. + //printk("Received authentication response\n");
  17749. +
  17750. +#ifdef _RTL8187_EXT_PATCH_
  17751. +//printk("IEEE80211_STYPE_AUTH\n");
  17752. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth)
  17753. + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) );
  17754. +#endif
  17755. + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
  17756. + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
  17757. + ieee->iw_mode == IW_MODE_INFRA){
  17758. +
  17759. + IEEE80211_DEBUG_MGMT("Received authentication response");
  17760. +
  17761. + if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
  17762. + if(ieee->open_wep || !challenge){
  17763. + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
  17764. + ieee->softmac_stats.rx_auth_rs_ok++;
  17765. +
  17766. + ieee80211_associate_step2(ieee);
  17767. + }else{
  17768. + ieee80211_auth_challenge(ieee, challenge, chlen);
  17769. + }
  17770. + }else{
  17771. + ieee->softmac_stats.rx_auth_rs_err++;
  17772. + IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
  17773. + ieee80211_associate_abort(ieee);
  17774. + }
  17775. +
  17776. + }else if (ieee->iw_mode == IW_MODE_MASTER){
  17777. + ieee80211_rx_auth_rq(ieee, skb);
  17778. + }
  17779. + }
  17780. + break;
  17781. +
  17782. + case IEEE80211_STYPE_PROBE_REQ:
  17783. + //printk("Received IEEE80211_STYPE_PROBE_REQ\n");
  17784. +
  17785. + if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
  17786. + ((ieee->iw_mode == IW_MODE_ADHOC ||
  17787. + ieee->iw_mode == IW_MODE_MASTER) &&
  17788. + ieee->state == IEEE80211_LINKED))
  17789. +
  17790. + ieee80211_rx_probe_rq(ieee, skb);
  17791. + break;
  17792. +
  17793. + case IEEE80211_STYPE_DISASSOC:
  17794. + case IEEE80211_STYPE_DEAUTH:
  17795. + //printk("Received IEEE80211_STYPE_DISASSOC\n");
  17796. +#ifdef _RTL8187_EXT_PATCH_
  17797. +//printk("IEEE80211_STYPE_DEAUTH\n");
  17798. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth)
  17799. + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) ) ;
  17800. +#endif
  17801. + /* FIXME for now repeat all the association procedure
  17802. + * both for disassociation and deauthentication
  17803. + */
  17804. + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
  17805. + ieee->state == IEEE80211_LINKED &&
  17806. + ieee->iw_mode == IW_MODE_INFRA){
  17807. +
  17808. + ieee->state = IEEE80211_ASSOCIATING;
  17809. + ieee->softmac_stats.reassoc++;
  17810. +
  17811. + notify_wx_assoc_event(ieee);
  17812. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  17813. + queue_work(ieee->wq, &ieee->associate_procedure_wq);
  17814. +#else
  17815. + schedule_task(&ieee->associate_procedure_wq);
  17816. +#endif
  17817. + }
  17818. +
  17819. + break;
  17820. +
  17821. + default:
  17822. + return -1;
  17823. + break;
  17824. + }
  17825. +
  17826. + //dev_kfree_skb_any(skb);
  17827. + return 0;
  17828. +}
  17829. +
  17830. +
  17831. +
  17832. +/* following are for a simplier TX queue management.
  17833. + * Instead of using netif_[stop/wake]_queue the driver
  17834. + * will uses these two function (plus a reset one), that
  17835. + * will internally uses the kernel netif_* and takes
  17836. + * care of the ieee802.11 fragmentation.
  17837. + * So the driver receives a fragment per time and might
  17838. + * call the stop function when it want without take care
  17839. + * to have enought room to TX an entire packet.
  17840. + * This might be useful if each fragment need it's own
  17841. + * descriptor, thus just keep a total free memory > than
  17842. + * the max fragmentation treshold is not enought.. If the
  17843. + * ieee802.11 stack passed a TXB struct then you needed
  17844. + * to keep N free descriptors where
  17845. + * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
  17846. + * In this way you need just one and the 802.11 stack
  17847. + * will take care of buffering fragments and pass them to
  17848. + * to the driver later, when it wakes the queue.
  17849. + */
  17850. +
  17851. +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
  17852. +{
  17853. +
  17854. +
  17855. + unsigned long flags;
  17856. + int i;
  17857. +#ifdef _RTL8187_EXT_PATCH_
  17858. + int rate = ieee->rate;
  17859. +#endif
  17860. +
  17861. + spin_lock_irqsave(&ieee->lock,flags);
  17862. + #if 0
  17863. + if(ieee->queue_stop){
  17864. + IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
  17865. + netif_stop_queue(ieee->dev);
  17866. + ieee->ieee_stats.swtxstop++;
  17867. + //dev_kfree_skb_any(skb);
  17868. + err = 1;
  17869. + goto exit;
  17870. + }
  17871. +
  17872. + ieee->stats.tx_bytes+=skb->len;
  17873. +
  17874. +
  17875. + txb=ieee80211_skb_to_txb(ieee,skb);
  17876. +
  17877. +
  17878. + if(txb==NULL){
  17879. + IEEE80211DMESG("WW: IEEE stack failed to provide txb");
  17880. + //dev_kfree_skb_any(skb);
  17881. + err = 1;
  17882. + goto exit;
  17883. + }
  17884. + #endif
  17885. +
  17886. +#ifdef _RTL8187_EXT_PATCH_
  17887. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags)
  17888. + {
  17889. + rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
  17890. + }
  17891. +#endif
  17892. + /* called with 2nd parm 0, no tx mgmt lock required */
  17893. + ieee80211_sta_wakeup(ieee,0);
  17894. +
  17895. + for(i = 0; i < txb->nr_frags; i++) {
  17896. +
  17897. + if (ieee->queue_stop){
  17898. + ieee->tx_pending.txb = txb;
  17899. + ieee->tx_pending.frag = i;
  17900. + goto exit;
  17901. + }else{
  17902. + ieee->softmac_data_hard_start_xmit(
  17903. + txb->fragments[i],
  17904. +#ifdef _RTL8187_EXT_PATCH_
  17905. + ieee->dev, rate);
  17906. +#else
  17907. + ieee->dev,ieee->rate);
  17908. +#endif
  17909. + //(i+1)<txb->nr_frags);
  17910. + ieee->stats.tx_packets++;
  17911. + ieee->stats.tx_bytes += txb->fragments[i]->len;
  17912. + ieee->dev->trans_start = jiffies;
  17913. + }
  17914. + }
  17915. +
  17916. + ieee80211_txb_free(txb);
  17917. +
  17918. + exit:
  17919. + spin_unlock_irqrestore(&ieee->lock,flags);
  17920. +
  17921. +}
  17922. +
  17923. +/* called with ieee->lock acquired */
  17924. +void ieee80211_resume_tx(struct ieee80211_device *ieee)
  17925. +{
  17926. + int i;
  17927. + for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
  17928. +
  17929. + if (ieee->queue_stop){
  17930. + ieee->tx_pending.frag = i;
  17931. + return;
  17932. + }else{
  17933. +
  17934. + ieee->softmac_data_hard_start_xmit(
  17935. + ieee->tx_pending.txb->fragments[i],
  17936. + ieee->dev,ieee->rate);
  17937. + //(i+1)<ieee->tx_pending.txb->nr_frags);
  17938. + ieee->stats.tx_packets++;
  17939. + ieee->dev->trans_start = jiffies;
  17940. + }
  17941. + }
  17942. +
  17943. +
  17944. + ieee80211_txb_free(ieee->tx_pending.txb);
  17945. + ieee->tx_pending.txb = NULL;
  17946. +}
  17947. +
  17948. +
  17949. +void ieee80211_reset_queue(struct ieee80211_device *ieee)
  17950. +{
  17951. + unsigned long flags;
  17952. +
  17953. + spin_lock_irqsave(&ieee->lock,flags);
  17954. + init_mgmt_queue(ieee);
  17955. + if (ieee->tx_pending.txb){
  17956. + ieee80211_txb_free(ieee->tx_pending.txb);
  17957. + ieee->tx_pending.txb = NULL;
  17958. + }
  17959. + ieee->queue_stop = 0;
  17960. + spin_unlock_irqrestore(&ieee->lock,flags);
  17961. +
  17962. +}
  17963. +
  17964. +void ieee80211_wake_queue(struct ieee80211_device *ieee)
  17965. +{
  17966. +
  17967. + unsigned long flags;
  17968. + struct sk_buff *skb;
  17969. + struct ieee80211_hdr_3addr *header;
  17970. +
  17971. + spin_lock_irqsave(&ieee->lock,flags);
  17972. + if (! ieee->queue_stop) goto exit;
  17973. +
  17974. + ieee->queue_stop = 0;
  17975. +
  17976. + if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
  17977. + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
  17978. +
  17979. + header = (struct ieee80211_hdr_3addr *) skb->data;
  17980. +
  17981. + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  17982. +
  17983. + if (ieee->seq_ctrl[0] == 0xFFF)
  17984. + ieee->seq_ctrl[0] = 0;
  17985. + else
  17986. + ieee->seq_ctrl[0]++;
  17987. +
  17988. + printk(KERN_ALERT "ieee80211_wake_queue \n");
  17989. + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
  17990. + dev_kfree_skb_any(skb);//edit by thomas
  17991. + }
  17992. + }
  17993. + if (!ieee->queue_stop && ieee->tx_pending.txb)
  17994. + ieee80211_resume_tx(ieee);
  17995. +
  17996. + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
  17997. + ieee->softmac_stats.swtxawake++;
  17998. + netif_wake_queue(ieee->dev);
  17999. + }
  18000. +
  18001. +exit :
  18002. + spin_unlock_irqrestore(&ieee->lock,flags);
  18003. +}
  18004. +
  18005. +
  18006. +void ieee80211_stop_queue(struct ieee80211_device *ieee)
  18007. +{
  18008. + //unsigned long flags;
  18009. + //spin_lock_irqsave(&ieee->lock,flags);
  18010. +
  18011. + if (! netif_queue_stopped(ieee->dev)){
  18012. + netif_stop_queue(ieee->dev);
  18013. + ieee->softmac_stats.swtxstop++;
  18014. + }
  18015. + ieee->queue_stop = 1;
  18016. + //spin_unlock_irqrestore(&ieee->lock,flags);
  18017. +
  18018. +}
  18019. +
  18020. +
  18021. +inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
  18022. +{
  18023. +
  18024. + get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
  18025. +
  18026. + /* an IBSS cell address must have the two less significant
  18027. + * bits of the first byte = 2
  18028. + */
  18029. + ieee->current_network.bssid[0] &= ~0x01;
  18030. + ieee->current_network.bssid[0] |= 0x02;
  18031. +}
  18032. +
  18033. +/* called in user context only */
  18034. +void ieee80211_start_master_bss(struct ieee80211_device *ieee)
  18035. +{
  18036. + ieee->assoc_id = 1;
  18037. +
  18038. + if (ieee->current_network.ssid_len == 0){
  18039. + strncpy(ieee->current_network.ssid,
  18040. + IEEE80211_DEFAULT_TX_ESSID,
  18041. + IW_ESSID_MAX_SIZE);
  18042. +
  18043. + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
  18044. + ieee->ssid_set = 1;
  18045. + }
  18046. +
  18047. + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
  18048. +
  18049. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  18050. + ieee->state = IEEE80211_LINKED;
  18051. +
  18052. +//by lizhaoming for LED LINK
  18053. +#ifdef LED_SHIN
  18054. + {
  18055. + struct net_device *dev = ieee->dev;
  18056. + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  18057. + }
  18058. +#endif
  18059. + ieee->link_change(ieee->dev);
  18060. + notify_wx_assoc_event(ieee);
  18061. +
  18062. + if (ieee->data_hard_resume)
  18063. + ieee->data_hard_resume(ieee->dev);
  18064. +
  18065. + netif_carrier_on(ieee->dev);
  18066. +}
  18067. +
  18068. +void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
  18069. +{
  18070. + if(ieee->raw_tx){
  18071. +
  18072. + if (ieee->data_hard_resume)
  18073. + ieee->data_hard_resume(ieee->dev);
  18074. +
  18075. + netif_carrier_on(ieee->dev);
  18076. + }
  18077. +}
  18078. +
  18079. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  18080. +void ieee80211_start_ibss_wq(struct work_struct *work)
  18081. +{
  18082. + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  18083. + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
  18084. +#else
  18085. +void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
  18086. +{
  18087. +#endif
  18088. +
  18089. + /* iwconfig mode ad-hoc will schedule this and return
  18090. + * on the other hand this will block further iwconfig SET
  18091. + * operations because of the wx_sem hold.
  18092. + * Anyway some most set operations set a flag to speed-up
  18093. + * (abort) this wq (when syncro scanning) before sleeping
  18094. + * on the semaphore
  18095. + */
  18096. +
  18097. + down(&ieee->wx_sem);
  18098. +
  18099. + if (ieee->current_network.ssid_len == 0){
  18100. + strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
  18101. + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
  18102. + ieee->ssid_set = 1;
  18103. + }
  18104. +
  18105. +//by lizhaoming for LED BLINK 2008.6.23
  18106. +#ifdef LED_SHIN
  18107. + {
  18108. + struct net_device *dev = ieee->dev;
  18109. + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
  18110. + }
  18111. +#endif
  18112. +
  18113. + /* check if we have this cell in our network list */
  18114. + ieee80211_softmac_check_all_nets(ieee);
  18115. +
  18116. +#ifdef ENABLE_DOT11D
  18117. + //[World wide 13]:
  18118. + // Adhoc:
  18119. + // (1) active scan from ch1~11 and passive scan from ch12~13
  18120. + // (2) IBSS can join ch1~13 adhoc, but only start at ch10.
  18121. + if(ieee->state == IEEE80211_NOLINK)
  18122. + if(ieee->IbssStartChnl != 0)
  18123. + ieee->current_network.channel = ieee->IbssStartChnl;//chan 10
  18124. +#endif
  18125. +
  18126. + /* if not then the state is not linked. Maybe the user swithced to
  18127. + * ad-hoc mode just after being in monitor mode, or just after
  18128. + * being very few time in managed mode (so the card have had no
  18129. + * time to scan all the chans..) or we have just run up the iface
  18130. + * after setting ad-hoc mode. So we have to give another try..
  18131. + * Here, in ibss mode, should be safe to do this without extra care
  18132. + * (in bss mode we had to make sure no-one tryed to associate when
  18133. + * we had just checked the ieee->state and we was going to start the
  18134. + * scan) beacause in ibss mode the ieee80211_new_net function, when
  18135. + * finds a good net, just set the ieee->state to IEEE80211_LINKED,
  18136. + * so, at worst, we waste a bit of time to initiate an unneeded syncro
  18137. + * scan, that will stop at the first round because it sees the state
  18138. + * associated.
  18139. + */
  18140. + if (ieee->state == IEEE80211_NOLINK){
  18141. + ieee80211_start_scan_syncro(ieee);
  18142. + }
  18143. +
  18144. + /* the network definitively is not here.. create a new cell */
  18145. + if (ieee->state == IEEE80211_NOLINK){
  18146. + printk("creating new IBSS cell\n");
  18147. + ieee->state = IEEE80211_LINKED;
  18148. + if(!ieee->wap_set)
  18149. + ieee80211_randomize_cell(ieee);
  18150. +
  18151. + if(ieee->modulation & IEEE80211_CCK_MODULATION){
  18152. +
  18153. + ieee->current_network.rates_len = 4;
  18154. +
  18155. + ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
  18156. + ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
  18157. + ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
  18158. + ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
  18159. +
  18160. + }else
  18161. + ieee->current_network.rates_len = 0;
  18162. +
  18163. + if(ieee->modulation & IEEE80211_OFDM_MODULATION){
  18164. + ieee->current_network.rates_ex_len = 8;
  18165. +
  18166. + ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
  18167. + ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
  18168. + ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
  18169. + ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
  18170. + ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
  18171. + ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
  18172. + ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
  18173. + ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
  18174. +
  18175. + ieee->rate = 540;
  18176. + }else{
  18177. + ieee->current_network.rates_ex_len = 0;
  18178. + ieee->rate = 110;
  18179. + }
  18180. +
  18181. + // By default, WMM function will be disabled in IBSS mode
  18182. + ieee->current_network.QoS_Enable = 0;
  18183. +
  18184. + ieee->current_network.atim_window = 0;
  18185. + ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
  18186. + if(ieee->short_slot)
  18187. + ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
  18188. +
  18189. + }
  18190. +
  18191. + ieee->state = IEEE80211_LINKED;
  18192. +
  18193. +//by lizhaoming for LED LINK
  18194. +#ifdef LED_SHIN
  18195. + {
  18196. + struct net_device *dev = ieee->dev;
  18197. + ieee->ieee80211_led_contorl(dev, LED_CTL_LINK);
  18198. + }
  18199. +#endif
  18200. +
  18201. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  18202. + ieee->link_change(ieee->dev);
  18203. +
  18204. + notify_wx_assoc_event(ieee);
  18205. +
  18206. + ieee80211_start_send_beacons(ieee);
  18207. + printk(KERN_WARNING "after sending beacon packet!\n");
  18208. +
  18209. + if (ieee->data_hard_resume)
  18210. + ieee->data_hard_resume(ieee->dev);
  18211. +
  18212. + netif_carrier_on(ieee->dev);
  18213. +
  18214. + up(&ieee->wx_sem);
  18215. +}
  18216. +
  18217. +inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
  18218. +{
  18219. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  18220. + queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); //change to delayed work, delayed time is need to check
  18221. +#else
  18222. + schedule_task(&ieee->start_ibss_wq);
  18223. +#endif
  18224. +}
  18225. +
  18226. +/* this is called only in user context, with wx_sem held */
  18227. +void ieee80211_start_bss(struct ieee80211_device *ieee)
  18228. +{
  18229. + unsigned long flags;
  18230. + /* check if we have already found the net we
  18231. + * are interested in (if any).
  18232. + * if not (we are disassociated and we are not
  18233. + * in associating / authenticating phase) start the background scanning.
  18234. + */
  18235. +
  18236. +//by lizhaoming for LED BLINK 2008.6.23
  18237. +#ifdef LED_SHIN
  18238. + {
  18239. + struct net_device *dev = ieee->dev;
  18240. + ieee->ieee80211_led_contorl(dev, LED_CTL_SITE_SURVEY);
  18241. + }
  18242. +#endif
  18243. +
  18244. +#ifdef ENABLE_DOT11D
  18245. + //
  18246. + // Ref: 802.11d 11.1.3.3
  18247. + // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
  18248. + //
  18249. + if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
  18250. + {
  18251. + if(! ieee->bGlobalDomain)
  18252. + {
  18253. + return;
  18254. + }
  18255. + }
  18256. +#endif
  18257. + //printk("======>%s()\n",__FUNCTION__);
  18258. + ieee80211_softmac_check_all_nets(ieee);
  18259. +
  18260. + /* ensure no-one start an associating process (thus setting
  18261. + * the ieee->state to ieee80211_ASSOCIATING) while we
  18262. + * have just cheked it and we are going to enable scan.
  18263. + * The ieee80211_new_net function is always called with
  18264. + * lock held (from both ieee80211_softmac_check_all_nets and
  18265. + * the rx path), so we cannot be in the middle of such function
  18266. + */
  18267. +
  18268. + spin_lock_irqsave(&ieee->lock, flags);
  18269. + if (ieee->state == IEEE80211_NOLINK){
  18270. + //printk("Not find SSID in network list scan now\n");
  18271. + ieee80211_start_scan(ieee);
  18272. + }
  18273. + spin_unlock_irqrestore(&ieee->lock, flags);
  18274. +
  18275. +}
  18276. +
  18277. +/* called only in userspace context */
  18278. +void ieee80211_disassociate(struct ieee80211_device *ieee)
  18279. +{
  18280. + netif_carrier_off(ieee->dev);
  18281. +
  18282. + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
  18283. + ieee80211_reset_queue(ieee);
  18284. +
  18285. + if (ieee->data_hard_stop)
  18286. + ieee->data_hard_stop(ieee->dev);
  18287. +
  18288. +#ifdef ENABLE_DOT11D
  18289. + if(IS_DOT11D_ENABLE(ieee))
  18290. + Dot11d_Reset(ieee);
  18291. +#endif
  18292. +
  18293. + ieee->state = IEEE80211_NOLINK;
  18294. + ieee->link_change(ieee->dev);
  18295. + notify_wx_assoc_event(ieee);
  18296. +
  18297. +}
  18298. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  18299. +void ieee80211_associate_retry_wq(struct work_struct *work)
  18300. +{
  18301. + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
  18302. + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
  18303. +#else
  18304. +void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
  18305. +{
  18306. +#endif
  18307. + unsigned long flags;
  18308. +
  18309. + down(&ieee->wx_sem);
  18310. + if(!ieee->proto_started)
  18311. + goto exit;
  18312. +
  18313. + if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
  18314. + goto exit;
  18315. +
  18316. + /* until we do not set the state to IEEE80211_NOLINK
  18317. + * there are no possibility to have someone else trying
  18318. + * to start an association procdure (we get here with
  18319. + * ieee->state = IEEE80211_ASSOCIATING).
  18320. + * When we set the state to IEEE80211_NOLINK it is possible
  18321. + * that the RX path run an attempt to associate, but
  18322. + * both ieee80211_softmac_check_all_nets and the
  18323. + * RX path works with ieee->lock held so there are no
  18324. + * problems. If we are still disassociated then start a scan.
  18325. + * the lock here is necessary to ensure no one try to start
  18326. + * an association procedure when we have just checked the
  18327. + * state and we are going to start the scan.
  18328. + */
  18329. + ieee->state = IEEE80211_NOLINK;
  18330. +
  18331. + ieee80211_softmac_check_all_nets(ieee);
  18332. +
  18333. + spin_lock_irqsave(&ieee->lock, flags);
  18334. + if(ieee->state == IEEE80211_NOLINK)
  18335. + {
  18336. + printk("%s():Not find SSID:%s[ch=%d, mode=%s] in network list scan now\n", __FUNCTION__,
  18337. + ieee->current_network.ssid,ieee->current_network.channel,
  18338. + (ieee->iw_mode == IW_MODE_INFRA) ? "BSS" : "IBSS");
  18339. +
  18340. + ieee80211_start_scan(ieee);
  18341. + }
  18342. +
  18343. + spin_unlock_irqrestore(&ieee->lock, flags);
  18344. +
  18345. +exit:
  18346. + up(&ieee->wx_sem);
  18347. +}
  18348. +
  18349. +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
  18350. +{
  18351. + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
  18352. +
  18353. + struct sk_buff *skb = NULL;
  18354. + struct ieee80211_probe_response *b;
  18355. +
  18356. +//rz
  18357. +#ifdef _RTL8187_EXT_PATCH_
  18358. + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp )
  18359. + skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network));
  18360. + else
  18361. + skb = ieee80211_probe_resp(ieee, broadcast_addr);
  18362. +#else
  18363. + skb = ieee80211_probe_resp(ieee, broadcast_addr);
  18364. +#endif
  18365. +//
  18366. + if (!skb)
  18367. + return NULL;
  18368. +
  18369. + b = (struct ieee80211_probe_response *) skb->data;
  18370. + b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
  18371. +
  18372. + return skb;
  18373. +
  18374. +}
  18375. +
  18376. +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
  18377. +{
  18378. + struct sk_buff *skb;
  18379. + struct ieee80211_probe_response *b;
  18380. +// printk("=========>%s()\n", __FUNCTION__);
  18381. + skb = ieee80211_get_beacon_(ieee);
  18382. + if(!skb)
  18383. + return NULL;
  18384. +
  18385. + b = (struct ieee80211_probe_response *) skb->data;
  18386. + b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
  18387. +
  18388. + if (ieee->seq_ctrl[0] == 0xFFF)
  18389. + ieee->seq_ctrl[0] = 0;
  18390. + else
  18391. + ieee->seq_ctrl[0]++;
  18392. +
  18393. + return skb;
  18394. +}
  18395. +
  18396. +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
  18397. +{
  18398. + ieee->sync_scan_hurryup = 1;
  18399. + down(&ieee->wx_sem);
  18400. + ieee80211_stop_protocol(ieee);
  18401. + up(&ieee->wx_sem);
  18402. +}
  18403. +
  18404. +
  18405. +void ieee80211_stop_protocol(struct ieee80211_device *ieee)
  18406. +{
  18407. + if (!ieee->proto_started)
  18408. + return;
  18409. +
  18410. + ieee->proto_started = 0;
  18411. + //printk("=====>%s\n", __func__);
  18412. +
  18413. +#ifdef _RTL8187_EXT_PATCH_
  18414. + if(ieee->ext_patch_ieee80211_stop_protocol)
  18415. + ieee->ext_patch_ieee80211_stop_protocol(ieee);
  18416. +//if call queue_delayed_work,can call this,or do nothing..
  18417. +//edit by lawrence,20071118
  18418. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  18419. +// cancel_delayed_work(&ieee->ext_stop_scan_wq);
  18420. +// cancel_delayed_work(&ieee->ext_send_beacon_wq);
  18421. +#endif
  18422. +#endif // _RTL8187_EXT_PATCH_
  18423. +
  18424. + ieee80211_stop_send_beacons(ieee);
  18425. +
  18426. + del_timer_sync(&ieee->associate_timer);
  18427. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  18428. + cancel_delayed_work(&ieee->associate_retry_wq);
  18429. + cancel_delayed_work(&ieee->start_ibss_wq); //cancel ibss start workqueue when stop protocol
  18430. +#endif
  18431. + ieee80211_stop_scan(ieee);
  18432. +
  18433. + ieee80211_disassociate(ieee);
  18434. + //printk("<=====%s\n", __func__);
  18435. +
  18436. +}
  18437. +
  18438. +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
  18439. +{
  18440. + ieee->sync_scan_hurryup = 0;
  18441. + down(&ieee->wx_sem);
  18442. + ieee80211_start_protocol(ieee);
  18443. + up(&ieee->wx_sem);
  18444. +}
  18445. +
  18446. +void ieee80211_start_protocol(struct ieee80211_device *ieee)
  18447. +{
  18448. + short ch = 0;
  18449. + int i = 0;
  18450. +
  18451. + if (ieee->proto_started)
  18452. + return;
  18453. +
  18454. + //printk("=====>%s\n", __func__);
  18455. +
  18456. + ieee->proto_started = 1;
  18457. +
  18458. + if (ieee->current_network.channel == 0){
  18459. + do{
  18460. + ch++;
  18461. + if (ch > MAX_CHANNEL_NUMBER)
  18462. + return; /* no channel found */
  18463. +#ifdef ENABLE_DOT11D
  18464. + }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
  18465. +#else
  18466. + }while(!ieee->channel_map[ch]);
  18467. +#endif
  18468. + ieee->current_network.channel = ch;
  18469. + }
  18470. +
  18471. + if (ieee->current_network.beacon_interval == 0)
  18472. + ieee->current_network.beacon_interval = 100;
  18473. +
  18474. + ieee->set_chan(ieee->dev,ieee->current_network.channel);
  18475. + mdelay(10);//must or link change will fail lzm
  18476. +
  18477. + for(i = 0; i < 17; i++) {
  18478. + ieee->last_rxseq_num[i] = -1;
  18479. + ieee->last_rxfrag_num[i] = -1;
  18480. + ieee->last_packet_time[i] = 0;
  18481. + }
  18482. +
  18483. + ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
  18484. +
  18485. +
  18486. + /* if the user set the MAC of the ad-hoc cell and then
  18487. + * switch to managed mode, shall we make sure that association
  18488. + * attempts does not fail just because the user provide the essid
  18489. + * and the nic is still checking for the AP MAC ??
  18490. + */
  18491. +
  18492. + if (ieee->iw_mode == IW_MODE_INFRA){
  18493. + ieee80211_start_bss(ieee);
  18494. + // printk("==========> IW_MODE_INFRA\n");
  18495. + }
  18496. + else if (ieee->iw_mode == IW_MODE_ADHOC){
  18497. + // printk("==========> IW_MODE_ADHOC\n");
  18498. + ieee80211_start_ibss(ieee);
  18499. + }
  18500. + else if (ieee->iw_mode == IW_MODE_MASTER){
  18501. + ieee80211_start_master_bss(ieee);
  18502. +// printk("==========> IW_MODE_MASTER\n");
  18503. + }
  18504. + else if(ieee->iw_mode == IW_MODE_MONITOR){
  18505. + ieee80211_start_monitor_mode(ieee);
  18506. +// printk("==========> IW_MODE_MONITOR\n");
  18507. + }
  18508. +
  18509. +#ifdef _RTL8187_EXT_PATCH_
  18510. +// else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol && ieee->ext_patch_ieee80211_start_protocol(ieee))
  18511. + else if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_start_protocol)
  18512. + {
  18513. + ieee->ext_patch_ieee80211_start_mesh(ieee);
  18514. + }
  18515. +#endif
  18516. +}
  18517. +
  18518. +
  18519. +#define DRV_NAME "Ieee80211"
  18520. +void ieee80211_softmac_init(struct ieee80211_device *ieee)
  18521. +{
  18522. + int i;
  18523. + memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
  18524. +
  18525. + ieee->state = IEEE80211_NOLINK;
  18526. + ieee->sync_scan_hurryup = 0;
  18527. + for(i = 0; i < 5; i++) {
  18528. + ieee->seq_ctrl[i] = 0;
  18529. + }
  18530. +
  18531. + ieee->assoc_id = 0;
  18532. + ieee->queue_stop = 0;
  18533. + ieee->scanning = 0;
  18534. + ieee->scan_watchdog = 0;//lzm add 081215 for roaming
  18535. + ieee->softmac_features = 0; //so IEEE2100-like driver are happy
  18536. + ieee->wap_set = 0;
  18537. + ieee->ssid_set = 0;
  18538. + ieee->proto_started = 0;
  18539. + ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
  18540. + ieee->rate = 3;
  18541. + ieee->ps = IEEE80211_PS_DISABLED;
  18542. + ieee->sta_sleep = 0;
  18543. +//by amy
  18544. + ieee->bInactivePs = false;
  18545. + ieee->actscanning = false;
  18546. + ieee->ListenInterval = 2;
  18547. + ieee->NumRxData = 0;
  18548. + ieee->NumRxDataInPeriod = 0; //YJ,add,080828
  18549. + ieee->NumRxBcnInPeriod = 0; //YJ,add,080828
  18550. + ieee->bHwRadioOff = false;//by lizhaoming
  18551. +//by amy
  18552. +#ifdef _RTL8187_EXT_PATCH_
  18553. + ieee->iw_ext_mode = 999;
  18554. +#endif
  18555. +
  18556. + init_mgmt_queue(ieee);
  18557. +
  18558. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  18559. + init_timer(&ieee->scan_timer);
  18560. + ieee->scan_timer.data = (unsigned long)ieee;
  18561. + ieee->scan_timer.function = ieee80211_softmac_scan_cb;
  18562. +#endif
  18563. + ieee->tx_pending.txb = NULL;
  18564. +
  18565. + init_timer(&ieee->associate_timer);
  18566. + ieee->associate_timer.data = (unsigned long)ieee;
  18567. + ieee->associate_timer.function = ieee80211_associate_abort_cb;
  18568. +
  18569. + init_timer(&ieee->beacon_timer);
  18570. + ieee->beacon_timer.data = (unsigned long) ieee;
  18571. + ieee->beacon_timer.function = ieee80211_send_beacon_cb;
  18572. +
  18573. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  18574. +#ifdef PF_SYNCTHREAD
  18575. + ieee->wq = create_workqueue(DRV_NAME,0);
  18576. +#else
  18577. + ieee->wq = create_workqueue(DRV_NAME);
  18578. +#endif
  18579. +#endif
  18580. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  18581. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
  18582. + INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
  18583. + INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
  18584. + INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
  18585. + INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
  18586. + INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
  18587. + INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
  18588. +//added by lawrence,20071118
  18589. +#ifdef _RTL8187_EXT_PATCH_
  18590. + INIT_WORK(&ieee->ext_stop_scan_wq, ieee80211_ext_stop_scan_wq);
  18591. + //INIT_WORK(&ieee->ext_send_beacon_wq, ieee80211_beacons_start,ieee);
  18592. + INIT_WORK(&ieee->ext_send_beacon_wq, ext_ieee80211_send_beacon_wq);
  18593. +#endif //_RTL8187_EXT_PATCH_
  18594. +#else
  18595. + INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
  18596. + INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
  18597. + INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
  18598. + INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
  18599. + INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
  18600. + INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
  18601. +#ifdef _RTL8187_EXT_PATCH_
  18602. + INIT_WORK(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
  18603. + //INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
  18604. + INIT_WORK(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
  18605. +#endif
  18606. +#endif
  18607. +#else
  18608. + tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
  18609. + tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
  18610. + tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
  18611. + tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
  18612. + tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
  18613. + tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
  18614. +#ifdef _RTL8187_EXT_PATCH_
  18615. + tq_init(&ieee->ext_stop_scan_wq,(void(*)(void*)) ieee80211_ext_stop_scan_wq,ieee);
  18616. + //tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ieee80211_beacons_start,ieee);
  18617. + tq_init(&ieee->ext_send_beacon_wq,(void(*)(void*)) ext_ieee80211_send_beacon_wq,ieee);
  18618. +#endif
  18619. +#endif
  18620. + sema_init(&ieee->wx_sem, 1);
  18621. + sema_init(&ieee->scan_sem, 1);
  18622. + sema_init(&ieee->ips_sem,1);
  18623. + spin_lock_init(&ieee->mgmt_tx_lock);
  18624. + spin_lock_init(&ieee->beacon_lock);
  18625. + spin_lock_init(&ieee->beaconflag_lock);
  18626. + tasklet_init(&ieee->ps_task,
  18627. + (void(*)(unsigned long)) ieee80211_sta_ps,
  18628. + (unsigned long)ieee);
  18629. +#ifdef ENABLE_DOT11D
  18630. + ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
  18631. +#endif
  18632. +
  18633. +}
  18634. +
  18635. +void ieee80211_softmac_free(struct ieee80211_device *ieee)
  18636. +{
  18637. + down(&ieee->wx_sem);
  18638. +
  18639. + del_timer_sync(&ieee->associate_timer);
  18640. +
  18641. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  18642. + cancel_delayed_work(&ieee->associate_retry_wq);
  18643. +
  18644. +
  18645. +
  18646. +#ifdef _RTL8187_EXT_PATCH_
  18647. + //When kernel>2.6.20,crash....
  18648. +// cancel_delayed_work(&ieee->ext_stop_scan_wq);
  18649. +// cancel_delayed_work(&ieee->ext_send_beacon_wq);
  18650. +#endif
  18651. + destroy_workqueue(ieee->wq);
  18652. +#endif
  18653. +
  18654. +#ifdef ENABLE_DOT11D
  18655. + if(NULL != ieee->pDot11dInfo)
  18656. + kfree(ieee->pDot11dInfo);
  18657. +#endif
  18658. +
  18659. + up(&ieee->wx_sem);
  18660. +}
  18661. +
  18662. +/********************************************************
  18663. + * Start of WPA code. *
  18664. + * this is stolen from the ipw2200 driver *
  18665. + ********************************************************/
  18666. +
  18667. +
  18668. +static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
  18669. +{
  18670. + /* This is called when wpa_supplicant loads and closes the driver
  18671. + * interface. */
  18672. + printk("%s WPA\n",value ? "enabling" : "disabling");
  18673. + ieee->wpa_enabled = value;
  18674. + return 0;
  18675. +}
  18676. +
  18677. +
  18678. +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
  18679. +{
  18680. + /* make sure WPA is enabled */
  18681. + ieee80211_wpa_enable(ieee, 1);
  18682. +
  18683. + ieee80211_disassociate(ieee);
  18684. +}
  18685. +
  18686. +
  18687. +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
  18688. +{
  18689. +
  18690. + int ret = 0;
  18691. +
  18692. + switch (command) {
  18693. + case IEEE_MLME_STA_DEAUTH:
  18694. + // silently ignore
  18695. + break;
  18696. +
  18697. + case IEEE_MLME_STA_DISASSOC:
  18698. + ieee80211_disassociate(ieee);
  18699. + break;
  18700. +
  18701. + default:
  18702. + printk("Unknown MLME request: %d\n", command);
  18703. + ret = -EOPNOTSUPP;
  18704. + }
  18705. +
  18706. + return ret;
  18707. +}
  18708. +
  18709. +
  18710. +static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
  18711. + struct ieee_param *param, int plen)
  18712. +{
  18713. + u8 *buf;
  18714. +
  18715. + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
  18716. + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
  18717. + return -EINVAL;
  18718. +
  18719. + if (param->u.wpa_ie.len) {
  18720. + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
  18721. + if (buf == NULL)
  18722. + return -ENOMEM;
  18723. +
  18724. + memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
  18725. + kfree(ieee->wpa_ie);
  18726. + ieee->wpa_ie = buf;
  18727. + ieee->wpa_ie_len = param->u.wpa_ie.len;
  18728. + } else {
  18729. + kfree(ieee->wpa_ie);
  18730. + ieee->wpa_ie = NULL;
  18731. + ieee->wpa_ie_len = 0;
  18732. + }
  18733. +
  18734. + ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
  18735. + return 0;
  18736. +}
  18737. +
  18738. +#define AUTH_ALG_OPEN_SYSTEM 0x1
  18739. +#define AUTH_ALG_SHARED_KEY 0x2
  18740. +
  18741. +static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
  18742. +{
  18743. +
  18744. + struct ieee80211_security sec = {
  18745. + .flags = SEC_AUTH_MODE,
  18746. + };
  18747. + int ret = 0;
  18748. +
  18749. + if (value & AUTH_ALG_SHARED_KEY) {
  18750. + sec.auth_mode = WLAN_AUTH_SHARED_KEY;
  18751. + ieee->open_wep = 0;
  18752. + } else {
  18753. + sec.auth_mode = WLAN_AUTH_OPEN;
  18754. + ieee->open_wep = 1;
  18755. + }
  18756. +
  18757. + if (ieee->set_security)
  18758. + ieee->set_security(ieee->dev, &sec);
  18759. + else
  18760. + ret = -EOPNOTSUPP;
  18761. +
  18762. + return ret;
  18763. +}
  18764. +
  18765. +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
  18766. +{
  18767. + int ret=0;
  18768. + unsigned long flags;
  18769. +
  18770. + switch (name) {
  18771. + case IEEE_PARAM_WPA_ENABLED:
  18772. + ret = ieee80211_wpa_enable(ieee, value);
  18773. + break;
  18774. +
  18775. + case IEEE_PARAM_TKIP_COUNTERMEASURES:
  18776. + ieee->tkip_countermeasures=value;
  18777. + break;
  18778. +
  18779. + case IEEE_PARAM_DROP_UNENCRYPTED: {
  18780. + /* HACK:
  18781. + *
  18782. + * wpa_supplicant calls set_wpa_enabled when the driver
  18783. + * is loaded and unloaded, regardless of if WPA is being
  18784. + * used. No other calls are made which can be used to
  18785. + * determine if encryption will be used or not prior to
  18786. + * association being expected. If encryption is not being
  18787. + * used, drop_unencrypted is set to false, else true -- we
  18788. + * can use this to determine if the CAP_PRIVACY_ON bit should
  18789. + * be set.
  18790. + */
  18791. + struct ieee80211_security sec = {
  18792. + .flags = SEC_ENABLED,
  18793. + .enabled = value,
  18794. + };
  18795. + ieee->drop_unencrypted = value;
  18796. + /* We only change SEC_LEVEL for open mode. Others
  18797. + * are set by ipw_wpa_set_encryption.
  18798. + */
  18799. + if (!value) {
  18800. + sec.flags |= SEC_LEVEL;
  18801. + sec.level = SEC_LEVEL_0;
  18802. + }
  18803. + else {
  18804. + sec.flags |= SEC_LEVEL;
  18805. + sec.level = SEC_LEVEL_1;
  18806. + }
  18807. + if (ieee->set_security)
  18808. + ieee->set_security(ieee->dev, &sec);
  18809. + break;
  18810. + }
  18811. +
  18812. + case IEEE_PARAM_PRIVACY_INVOKED:
  18813. + ieee->privacy_invoked=value;
  18814. + break;
  18815. +
  18816. + case IEEE_PARAM_AUTH_ALGS:
  18817. + ret = ieee80211_wpa_set_auth_algs(ieee, value);
  18818. + break;
  18819. +
  18820. + case IEEE_PARAM_IEEE_802_1X:
  18821. + ieee->ieee802_1x=value;
  18822. + break;
  18823. + case IEEE_PARAM_WPAX_SELECT:
  18824. + // added for WPA2 mixed mode
  18825. + //printk(KERN_WARNING "------------------------>wpax value = %x\n", value);
  18826. + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
  18827. + ieee->wpax_type_set = 1;
  18828. + ieee->wpax_type_notify = value;
  18829. + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
  18830. + break;
  18831. +
  18832. + default:
  18833. + printk("Unknown WPA param: %d\n",name);
  18834. + ret = -EOPNOTSUPP;
  18835. + }
  18836. +
  18837. + return ret;
  18838. +}
  18839. +
  18840. +/* implementation borrowed from hostap driver */
  18841. +
  18842. +static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
  18843. + struct ieee_param *param, int param_len)
  18844. +{
  18845. + int ret = 0;
  18846. +
  18847. + struct ieee80211_crypto_ops *ops;
  18848. + struct ieee80211_crypt_data **crypt;
  18849. +
  18850. + struct ieee80211_security sec = {
  18851. + .flags = 0,
  18852. + };
  18853. +
  18854. + param->u.crypt.err = 0;
  18855. + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
  18856. +
  18857. + if (param_len !=
  18858. + (int) ((char *) param->u.crypt.key - (char *) param) +
  18859. + param->u.crypt.key_len) {
  18860. + printk("Len mismatch %d, %d\n", param_len,
  18861. + param->u.crypt.key_len);
  18862. + return -EINVAL;
  18863. + }
  18864. + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
  18865. + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
  18866. + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
  18867. + if (param->u.crypt.idx >= WEP_KEYS)
  18868. + return -EINVAL;
  18869. +#ifdef _RTL8187_EXT_PATCH_
  18870. + crypt = &ieee->cryptlist[0]->crypt[param->u.crypt.idx];
  18871. +#else
  18872. + crypt = &ieee->crypt[param->u.crypt.idx];
  18873. +#endif
  18874. +
  18875. + } else {
  18876. + return -EINVAL;
  18877. + }
  18878. +
  18879. + if (strcmp(param->u.crypt.alg, "none") == 0) {
  18880. + if (crypt) {
  18881. + sec.enabled = 0;
  18882. + // FIXME FIXME
  18883. + //sec.encrypt = 0;
  18884. + sec.level = SEC_LEVEL_0;
  18885. + sec.flags |= SEC_ENABLED | SEC_LEVEL;
  18886. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  18887. + }
  18888. + goto done;
  18889. + }
  18890. + sec.enabled = 1;
  18891. +// FIXME FIXME
  18892. +// sec.encrypt = 1;
  18893. + sec.flags |= SEC_ENABLED;
  18894. +
  18895. + /* IPW HW cannot build TKIP MIC, host decryption still needed. */
  18896. + if (!(ieee->host_encrypt || ieee->host_decrypt) &&
  18897. + strcmp(param->u.crypt.alg, "TKIP"))
  18898. + goto skip_host_crypt;
  18899. +
  18900. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  18901. + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
  18902. + request_module("ieee80211_crypt_wep");
  18903. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  18904. + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
  18905. + request_module("ieee80211_crypt_tkip");
  18906. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  18907. + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
  18908. + request_module("ieee80211_crypt_ccmp");
  18909. + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
  18910. + }
  18911. + if (ops == NULL) {
  18912. + printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
  18913. + param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
  18914. + ret = -EINVAL;
  18915. + goto done;
  18916. + }
  18917. +
  18918. +#ifdef _RTL8187_EXT_PATCH_
  18919. + u8 i;
  18920. + for (i=0; i<MAX_MP; i++){
  18921. + crypt = &ieee->cryptlist[i]->crypt[param->u.crypt.idx];
  18922. +// if (crypt != NULL) printk("crypt not null\n", crypt);
  18923. +
  18924. + *crypt = ieee->cryptlist[i]->crypt[param->u.crypt.idx];
  18925. +#endif
  18926. + if (*crypt == NULL || (*crypt)->ops != ops) {
  18927. + struct ieee80211_crypt_data *new_crypt;
  18928. +
  18929. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  18930. +
  18931. + new_crypt = (struct ieee80211_crypt_data *)
  18932. + kmalloc(sizeof(*new_crypt), GFP_KERNEL);
  18933. + if (new_crypt == NULL) {
  18934. + ret = -ENOMEM;
  18935. + goto done;
  18936. + }
  18937. + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
  18938. + new_crypt->ops = ops;
  18939. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  18940. + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  18941. +#else
  18942. + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
  18943. +#endif
  18944. + new_crypt->priv =
  18945. + new_crypt->ops->init(param->u.crypt.idx);
  18946. +
  18947. + if (new_crypt->priv == NULL) {
  18948. + kfree(new_crypt);
  18949. + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
  18950. + ret = -EINVAL;
  18951. + goto done;
  18952. + }
  18953. +
  18954. + *crypt = new_crypt;
  18955. + }
  18956. +
  18957. + if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
  18958. + (*crypt)->ops->set_key(param->u.crypt.key,
  18959. + param->u.crypt.key_len, param->u.crypt.seq,
  18960. + (*crypt)->priv) < 0) {
  18961. + printk("key setting failed\n");
  18962. + param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
  18963. + ret = -EINVAL;
  18964. + goto done;
  18965. + }
  18966. +#ifdef _RTL8187_EXT_PATCH_
  18967. + }
  18968. +#endif
  18969. + skip_host_crypt:
  18970. + if (param->u.crypt.set_tx) {
  18971. + ieee->tx_keyidx = param->u.crypt.idx;
  18972. + sec.active_key = param->u.crypt.idx;
  18973. + sec.flags |= SEC_ACTIVE_KEY;
  18974. + } else
  18975. + sec.flags &= ~SEC_ACTIVE_KEY;
  18976. +
  18977. + if (param->u.crypt.alg != NULL) {
  18978. + memcpy(sec.keys[param->u.crypt.idx],
  18979. + param->u.crypt.key,
  18980. + param->u.crypt.key_len);
  18981. + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
  18982. + sec.flags |= (1 << param->u.crypt.idx);
  18983. +
  18984. + if (strcmp(param->u.crypt.alg, "WEP") == 0) {
  18985. + sec.flags |= SEC_LEVEL;
  18986. + sec.level = SEC_LEVEL_1;
  18987. + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
  18988. + sec.flags |= SEC_LEVEL;
  18989. + sec.level = SEC_LEVEL_2;
  18990. + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
  18991. + sec.flags |= SEC_LEVEL;
  18992. + sec.level = SEC_LEVEL_3;
  18993. + }
  18994. + }
  18995. + done:
  18996. + if (ieee->set_security)
  18997. + ieee->set_security(ieee->dev, &sec);
  18998. +#if 1
  18999. +#ifdef _RTL8187_EXT_PATCH_
  19000. + if (ret != 0)//error out
  19001. + {
  19002. + for (i=0; i<MAX_MP; i++)
  19003. + {
  19004. + if (ieee->cryptlist[i]->crypt[param->u.crypt.idx]==NULL){
  19005. + break;
  19006. + }
  19007. + else{
  19008. + //if (ieee->cryptlist[i]->crypt[param->u.crypt.idx] != NULL)
  19009. + // {
  19010. + kfree(ieee->cryptlist[i]->crypt[param->u.crypt.idx]);
  19011. + ieee->cryptlist[i]->crypt[param->u.crypt.idx] = NULL;
  19012. + // }
  19013. + // kfree(ieee->cryptlist[i]);
  19014. + // ieee->cryptlist[i] = NULL;
  19015. + }
  19016. + }
  19017. + }
  19018. +#endif
  19019. +#endif
  19020. + /* Do not reset port if card is in Managed mode since resetting will
  19021. + * generate new IEEE 802.11 authentication which may end up in looping
  19022. + * with IEEE 802.1X. If your hardware requires a reset after WEP
  19023. + * configuration (for example... Prism2), implement the reset_port in
  19024. + * the callbacks structures used to initialize the 802.11 stack. */
  19025. + if (ieee->reset_on_keychange &&
  19026. + ieee->iw_mode != IW_MODE_INFRA &&
  19027. + ieee->reset_port &&
  19028. + ieee->reset_port(ieee->dev)) {
  19029. + printk("reset_port failed\n");
  19030. + param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
  19031. + return -EINVAL;
  19032. + }
  19033. +
  19034. + return ret;
  19035. +}
  19036. +
  19037. +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
  19038. +{
  19039. + struct ieee_param *param;
  19040. + int ret=0;
  19041. +
  19042. + down(&ieee->wx_sem);
  19043. + //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
  19044. +
  19045. + if (p->length < sizeof(struct ieee_param) || !p->pointer){
  19046. + ret = -EINVAL;
  19047. + goto out;
  19048. + }
  19049. +
  19050. + param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
  19051. + if (param == NULL){
  19052. + ret = -ENOMEM;
  19053. + goto out;
  19054. + }
  19055. + if (copy_from_user(param, p->pointer, p->length)) {
  19056. + kfree(param);
  19057. + ret = -EFAULT;
  19058. + goto out;
  19059. + }
  19060. +
  19061. + switch (param->cmd) {
  19062. +
  19063. + case IEEE_CMD_SET_WPA_PARAM:
  19064. + ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
  19065. + param->u.wpa_param.value);
  19066. + break;
  19067. +
  19068. + case IEEE_CMD_SET_WPA_IE:
  19069. + ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
  19070. + break;
  19071. +
  19072. + case IEEE_CMD_SET_ENCRYPTION:
  19073. + ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
  19074. + break;
  19075. +
  19076. + case IEEE_CMD_MLME:
  19077. + ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
  19078. + param->u.mlme.reason_code);
  19079. + break;
  19080. +
  19081. + default:
  19082. + printk("Unknown WPA supplicant request: %d\n",param->cmd);
  19083. + ret = -EOPNOTSUPP;
  19084. + break;
  19085. + }
  19086. +
  19087. + if (ret == 0 && copy_to_user(p->pointer, param, p->length))
  19088. + ret = -EFAULT;
  19089. +
  19090. + kfree(param);
  19091. +out:
  19092. + up(&ieee->wx_sem);
  19093. +
  19094. + return ret;
  19095. +}
  19096. +
  19097. +void notify_wx_assoc_event(struct ieee80211_device *ieee)
  19098. +{
  19099. + union iwreq_data wrqu;
  19100. + wrqu.ap_addr.sa_family = ARPHRD_ETHER;
  19101. + if (ieee->state == IEEE80211_LINKED)
  19102. + memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
  19103. + else
  19104. + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
  19105. + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
  19106. +}
  19107. +
  19108. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  19109. +EXPORT_SYMBOL(ieee80211_get_beacon);
  19110. +EXPORT_SYMBOL(ieee80211_wake_queue);
  19111. +EXPORT_SYMBOL(ieee80211_stop_queue);
  19112. +EXPORT_SYMBOL(ieee80211_reset_queue);
  19113. +EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
  19114. +EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
  19115. +EXPORT_SYMBOL(ieee80211_is_shortslot);
  19116. +EXPORT_SYMBOL(ieee80211_is_54g);
  19117. +EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
  19118. +EXPORT_SYMBOL(ieee80211_ps_tx_ack);
  19119. +EXPORT_SYMBOL(notify_wx_assoc_event);
  19120. +EXPORT_SYMBOL(ieee80211_stop_send_beacons);
  19121. +EXPORT_SYMBOL(ieee80211_start_send_beacons);
  19122. +EXPORT_SYMBOL(ieee80211_start_scan_syncro);
  19123. +EXPORT_SYMBOL(ieee80211_start_protocol);
  19124. +EXPORT_SYMBOL(ieee80211_stop_protocol);
  19125. +EXPORT_SYMBOL(ieee80211_start_scan);
  19126. +EXPORT_SYMBOL(ieee80211_stop_scan);
  19127. +#ifdef _RTL8187_EXT_PATCH_
  19128. +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req);
  19129. +EXPORT_SYMBOL(ieee80211_ext_issue_disassoc);
  19130. +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp);
  19131. +EXPORT_SYMBOL(softmac_mgmt_xmit);
  19132. +EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net);
  19133. +EXPORT_SYMBOL(ieee80211_stop_scan);
  19134. +EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon);
  19135. +EXPORT_SYMBOL(ieee80211_rx_auth_rq);
  19136. +EXPORT_SYMBOL(ieee80211_associate_step1);
  19137. +#endif // _RTL8187_EXT_PATCH_
  19138. +#else
  19139. +EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
  19140. +EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue);
  19141. +EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue);
  19142. +EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
  19143. +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
  19144. +EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
  19145. +EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot);
  19146. +EXPORT_SYMBOL_NOVERS(ieee80211_is_54g);
  19147. +EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl);
  19148. +EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack);
  19149. +EXPORT_SYMBOL_NOVERS(ieee80211_start_scan);
  19150. +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
  19151. +#ifdef _RTL8187_EXT_PATCH_
  19152. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_req);
  19153. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_disassoc);
  19154. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_issue_assoc_rsp);
  19155. +EXPORT_SYMBOL_NOVERS(softmac_mgmt_xmit);
  19156. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_probe_resp_by_net);
  19157. +EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
  19158. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_send_11s_beacon);
  19159. +EXPORT_SYMBOL_NOVERS(ieee80211_rx_auth_rq);
  19160. +EXPORT_SYMBOL(ieee80211_associate_step1);
  19161. +#endif // _RTL8187_EXT_PATCH_
  19162. +
  19163. +#endif
  19164. +//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
  19165. 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
  19166. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 1970-01-01 01:00:00.000000000 +0100
  19167. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_softmac_wx.c 2010-05-27 18:12:39.532222207 +0200
  19168. @@ -0,0 +1,629 @@
  19169. +/* IEEE 802.11 SoftMAC layer
  19170. + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  19171. + *
  19172. + * Mostly extracted from the rtl8180-sa2400 driver for the
  19173. + * in-kernel generic ieee802.11 stack.
  19174. + *
  19175. + * Some pieces of code might be stolen from ipw2100 driver
  19176. + * copyright of who own it's copyright ;-)
  19177. + *
  19178. + * PS wx handler mostly stolen from hostap, copyright who
  19179. + * own it's copyright ;-)
  19180. + *
  19181. + * released under the GPL
  19182. + */
  19183. +
  19184. +
  19185. +#include "ieee80211.h"
  19186. +#ifdef ENABLE_DOT11D
  19187. +#include "dot11d.h"
  19188. +#endif
  19189. +
  19190. +/* FIXME: add A freqs */
  19191. +
  19192. +const long ieee80211_wlan_frequencies[] = {
  19193. + 2412, 2417, 2422, 2427,
  19194. + 2432, 2437, 2442, 2447,
  19195. + 2452, 2457, 2462, 2467,
  19196. + 2472, 2484
  19197. +};
  19198. +
  19199. +
  19200. +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
  19201. + union iwreq_data *wrqu, char *b)
  19202. +{
  19203. + int ret;
  19204. + struct iw_freq *fwrq = & wrqu->freq;
  19205. +
  19206. + down(&ieee->wx_sem);
  19207. +
  19208. + if(ieee->iw_mode == IW_MODE_INFRA){
  19209. + ret = -EOPNOTSUPP;
  19210. + goto out;
  19211. + }
  19212. +
  19213. + /* if setting by freq convert to channel */
  19214. + if (fwrq->e == 1) {
  19215. + if ((fwrq->m >= (int) 2.412e8 &&
  19216. + fwrq->m <= (int) 2.487e8)) {
  19217. + int f = fwrq->m / 100000;
  19218. + int c = 0;
  19219. +
  19220. + while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
  19221. + c++;
  19222. +
  19223. + /* hack to fall through */
  19224. + fwrq->e = 0;
  19225. + fwrq->m = c + 1;
  19226. + }
  19227. + }
  19228. +
  19229. + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
  19230. + ret = -EOPNOTSUPP;
  19231. + goto out;
  19232. +
  19233. + }else { /* Set the channel */
  19234. +
  19235. +#ifdef ENABLE_DOT11D
  19236. + if(!IsLegalChannel(ieee, fwrq->m) )
  19237. + {
  19238. + printk("channel(%d). is invalide\n", fwrq->m);
  19239. + ret = -EOPNOTSUPP;
  19240. + goto out;
  19241. + }
  19242. + else
  19243. + {
  19244. + if(ieee->iw_mode == IW_MODE_ADHOC)
  19245. + {
  19246. + if(ieee->MinPassiveChnlNum != MAX_CHANNEL_NUMBER+1)
  19247. + {
  19248. + if(fwrq->m >= ieee->MinPassiveChnlNum)
  19249. + {
  19250. + ret = -EOPNOTSUPP;
  19251. + goto out;
  19252. + }
  19253. + }
  19254. + }
  19255. + }
  19256. +#endif
  19257. + ieee->current_network.channel = fwrq->m;
  19258. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  19259. +
  19260. + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
  19261. + if(ieee->state == IEEE80211_LINKED){
  19262. +
  19263. + ieee80211_stop_send_beacons(ieee);
  19264. + ieee80211_start_send_beacons(ieee);
  19265. + }
  19266. + }
  19267. +
  19268. + ret = 0;
  19269. +out:
  19270. + up(&ieee->wx_sem);
  19271. + return ret;
  19272. +}
  19273. +
  19274. +
  19275. +int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
  19276. + struct iw_request_info *a,
  19277. + union iwreq_data *wrqu, char *b)
  19278. +{
  19279. + struct iw_freq *fwrq = & wrqu->freq;
  19280. +
  19281. + if (ieee->current_network.channel == 0)
  19282. + return -1;
  19283. +
  19284. + fwrq->m = ieee->current_network.channel;
  19285. + fwrq->e = 0;
  19286. +
  19287. + return 0;
  19288. +}
  19289. +
  19290. +int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
  19291. + struct iw_request_info *info,
  19292. + union iwreq_data *wrqu, char *extra)
  19293. +{
  19294. + unsigned long flags;
  19295. +
  19296. + wrqu->ap_addr.sa_family = ARPHRD_ETHER;
  19297. +
  19298. + if (ieee->iw_mode == IW_MODE_MONITOR)
  19299. + return -1;
  19300. +
  19301. + /* We want avoid to give to the user inconsistent infos*/
  19302. + spin_lock_irqsave(&ieee->lock, flags);
  19303. +
  19304. + if (ieee->state != IEEE80211_LINKED &&
  19305. + ieee->state != IEEE80211_LINKED_SCANNING &&
  19306. + ieee->wap_set == 0)
  19307. +
  19308. + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
  19309. + else
  19310. + memcpy(wrqu->ap_addr.sa_data,
  19311. + ieee->current_network.bssid, ETH_ALEN);
  19312. +
  19313. + spin_unlock_irqrestore(&ieee->lock, flags);
  19314. +
  19315. + return 0;
  19316. +}
  19317. +
  19318. +
  19319. +int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
  19320. + struct iw_request_info *info,
  19321. + union iwreq_data *awrq,
  19322. + char *extra)
  19323. +{
  19324. +
  19325. + int ret = 0;
  19326. + u8 zero[] = {0,0,0,0,0,0};
  19327. + unsigned long flags;
  19328. +
  19329. + short ifup = ieee->proto_started;//dev->flags & IFF_UP;
  19330. + struct sockaddr *temp = (struct sockaddr *)awrq;
  19331. +
  19332. + ieee->sync_scan_hurryup = 1;
  19333. +
  19334. + down(&ieee->wx_sem);
  19335. + /* use ifconfig hw ether */
  19336. + if (ieee->iw_mode == IW_MODE_MASTER){
  19337. + ret = -1;
  19338. + goto out;
  19339. + }
  19340. +
  19341. + if (temp->sa_family != ARPHRD_ETHER){
  19342. + ret = -EINVAL;
  19343. + goto out;
  19344. + }
  19345. +
  19346. + if (ifup)
  19347. + ieee80211_stop_protocol(ieee);
  19348. +
  19349. + /* just to avoid to give inconsistent infos in the
  19350. + * get wx method. not really needed otherwise
  19351. + */
  19352. + spin_lock_irqsave(&ieee->lock, flags);
  19353. +
  19354. + memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
  19355. + ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
  19356. +
  19357. + spin_unlock_irqrestore(&ieee->lock, flags);
  19358. +
  19359. + if (ifup)
  19360. + ieee80211_start_protocol(ieee);
  19361. +
  19362. +out:
  19363. + up(&ieee->wx_sem);
  19364. + return ret;
  19365. +}
  19366. +
  19367. + int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
  19368. +{
  19369. + int len,ret = 0;
  19370. + unsigned long flags;
  19371. +
  19372. + if (ieee->iw_mode == IW_MODE_MONITOR)
  19373. + return -1;
  19374. +
  19375. + /* We want avoid to give to the user inconsistent infos*/
  19376. + spin_lock_irqsave(&ieee->lock, flags);
  19377. +
  19378. + if (ieee->current_network.ssid[0] == '\0' ||
  19379. + ieee->current_network.ssid_len == 0){
  19380. + ret = -1;
  19381. + goto out;
  19382. + }
  19383. +
  19384. + if (ieee->state != IEEE80211_LINKED &&
  19385. + ieee->state != IEEE80211_LINKED_SCANNING &&
  19386. + ieee->ssid_set == 0){
  19387. + ret = -1;
  19388. + goto out;
  19389. + }
  19390. + len = ieee->current_network.ssid_len;
  19391. + wrqu->essid.length = len;
  19392. + strncpy(b,ieee->current_network.ssid,len);
  19393. + wrqu->essid.flags = 1;
  19394. +
  19395. +out:
  19396. + spin_unlock_irqrestore(&ieee->lock, flags);
  19397. +
  19398. + return ret;
  19399. +
  19400. +}
  19401. +
  19402. +int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
  19403. + struct iw_request_info *info,
  19404. + union iwreq_data *wrqu, char *extra)
  19405. +{
  19406. +
  19407. + u32 target_rate = wrqu->bitrate.value;
  19408. +
  19409. + ieee->rate = target_rate/100000;
  19410. + //FIXME: we might want to limit rate also in management protocols.
  19411. + return 0;
  19412. +}
  19413. +
  19414. +
  19415. +
  19416. +int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
  19417. + struct iw_request_info *info,
  19418. + union iwreq_data *wrqu, char *extra)
  19419. +{
  19420. +
  19421. + wrqu->bitrate.value = ieee->rate * 100000;
  19422. +
  19423. + return 0;
  19424. +}
  19425. +
  19426. +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  19427. + union iwreq_data *wrqu, char *b)
  19428. +{
  19429. +
  19430. + ieee->sync_scan_hurryup = 1;
  19431. +
  19432. + down(&ieee->wx_sem);
  19433. + //printk("=======>%s\n", __func__);
  19434. +
  19435. + if (wrqu->mode == ieee->iw_mode)
  19436. + goto out;
  19437. +
  19438. + if (wrqu->mode == IW_MODE_MONITOR){
  19439. +
  19440. + ieee->dev->type = ARPHRD_IEEE80211;
  19441. + }else{
  19442. + ieee->dev->type = ARPHRD_ETHER;
  19443. + }
  19444. +
  19445. + if (!ieee->proto_started){
  19446. + ieee->iw_mode = wrqu->mode;
  19447. + }else{
  19448. + ieee80211_stop_protocol(ieee);
  19449. + ieee->iw_mode = wrqu->mode;
  19450. + ieee80211_start_protocol(ieee);
  19451. + }
  19452. +
  19453. +out:
  19454. + up(&ieee->wx_sem);
  19455. + return 0;
  19456. +}
  19457. +
  19458. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  19459. +void ieee80211_wx_sync_scan_wq(struct work_struct *work)
  19460. +{
  19461. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
  19462. +#else
  19463. +void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
  19464. +{
  19465. +#endif
  19466. + short chan;
  19467. +
  19468. + chan = ieee->current_network.channel;
  19469. +
  19470. + netif_carrier_off(ieee->dev);
  19471. +
  19472. + if (ieee->data_hard_stop)
  19473. + ieee->data_hard_stop(ieee->dev);
  19474. +
  19475. + ieee80211_stop_send_beacons(ieee);
  19476. +
  19477. + ieee->state = IEEE80211_LINKED_SCANNING;
  19478. + ieee->link_change(ieee->dev);
  19479. +
  19480. + ieee80211_start_scan_syncro(ieee);
  19481. +
  19482. + ieee->set_chan(ieee->dev, chan);
  19483. +
  19484. + ieee->state = IEEE80211_LINKED;
  19485. + ieee->link_change(ieee->dev);
  19486. +
  19487. + if (ieee->data_hard_resume)
  19488. + ieee->data_hard_resume(ieee->dev);
  19489. +
  19490. + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
  19491. + ieee80211_start_send_beacons(ieee);
  19492. +
  19493. + netif_carrier_on(ieee->dev);
  19494. +
  19495. + up(&ieee->wx_sem);
  19496. +
  19497. +}
  19498. +
  19499. +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
  19500. + union iwreq_data *wrqu, char *b)
  19501. +{
  19502. + int ret = 0;
  19503. +
  19504. + down(&ieee->wx_sem);
  19505. +
  19506. + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
  19507. + ret = -1;
  19508. + goto out;
  19509. + }
  19510. +
  19511. + if ( ieee->state == IEEE80211_LINKED){
  19512. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  19513. + queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
  19514. +#else
  19515. + schedule_task(&ieee->wx_sync_scan_wq);
  19516. +#endif
  19517. + /* intentionally forget to up sem */
  19518. + return 0;
  19519. + }
  19520. +
  19521. +out:
  19522. + up(&ieee->wx_sem);
  19523. + return ret;
  19524. +}
  19525. +
  19526. +int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
  19527. + struct iw_request_info *a,
  19528. + union iwreq_data *wrqu, char *extra)
  19529. +{
  19530. +
  19531. + int ret=0,len;
  19532. + short proto_started;
  19533. + unsigned long flags;
  19534. +
  19535. + ieee->sync_scan_hurryup = 1;
  19536. +
  19537. + down(&ieee->wx_sem);
  19538. +
  19539. + //printk("=======>%s\n", __func__);
  19540. + proto_started = ieee->proto_started;
  19541. +
  19542. + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
  19543. + ret= -E2BIG;
  19544. + goto out;
  19545. + }
  19546. +
  19547. + if (ieee->iw_mode == IW_MODE_MONITOR){
  19548. + ret= -1;
  19549. + goto out;
  19550. + }
  19551. +
  19552. + if(proto_started){
  19553. + ieee80211_stop_protocol(ieee);
  19554. + }
  19555. +
  19556. + /* this is just to be sure that the GET wx callback
  19557. + * has consisten infos. not needed otherwise
  19558. + */
  19559. + spin_lock_irqsave(&ieee->lock, flags);
  19560. +
  19561. + if (wrqu->essid.flags && wrqu->essid.length) {
  19562. + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
  19563. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  19564. + strncpy(ieee->current_network.ssid, extra, len);
  19565. + ieee->current_network.ssid_len = len;
  19566. +#else
  19567. + strncpy(ieee->current_network.ssid, extra, len+1);
  19568. + ieee->current_network.ssid_len = len+1;
  19569. +#endif
  19570. + ieee->ssid_set = 1;
  19571. + //YJ,add,080819,for hidden ap
  19572. + if(len == 0){
  19573. + memset(ieee->current_network.bssid, 0, ETH_ALEN);
  19574. + ieee->current_network.capability = 0;
  19575. + }
  19576. + //YJ,add,080819,for hidden ap,end
  19577. + }
  19578. + else{
  19579. + ieee->ssid_set = 0;
  19580. + ieee->current_network.ssid[0] = '\0';
  19581. + ieee->current_network.ssid_len = 0;
  19582. + }
  19583. +
  19584. + spin_unlock_irqrestore(&ieee->lock, flags);
  19585. +
  19586. + if (proto_started){
  19587. + ieee80211_start_protocol(ieee);
  19588. + }
  19589. +out:
  19590. + up(&ieee->wx_sem);
  19591. + return ret;
  19592. +}
  19593. +
  19594. + int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
  19595. + union iwreq_data *wrqu, char *b)
  19596. +{
  19597. +
  19598. + wrqu->mode = ieee->iw_mode;
  19599. + return 0;
  19600. +}
  19601. +
  19602. + int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
  19603. + struct iw_request_info *info,
  19604. + union iwreq_data *wrqu, char *extra)
  19605. +{
  19606. +
  19607. + int *parms = (int *)extra;
  19608. + int enable = (parms[0] > 0);
  19609. + short prev = ieee->raw_tx;
  19610. +
  19611. + down(&ieee->wx_sem);
  19612. +
  19613. + if(enable)
  19614. + ieee->raw_tx = 1;
  19615. + else
  19616. + ieee->raw_tx = 0;
  19617. +
  19618. + printk(KERN_INFO"raw TX is %s\n",
  19619. + ieee->raw_tx ? "enabled" : "disabled");
  19620. +
  19621. + if(ieee->iw_mode == IW_MODE_MONITOR)
  19622. + {
  19623. + if(prev == 0 && ieee->raw_tx){
  19624. + if (ieee->data_hard_resume)
  19625. + ieee->data_hard_resume(ieee->dev);
  19626. +
  19627. + netif_carrier_on(ieee->dev);
  19628. + }
  19629. +
  19630. + if(prev && ieee->raw_tx == 1)
  19631. + netif_carrier_off(ieee->dev);
  19632. + }
  19633. +
  19634. + up(&ieee->wx_sem);
  19635. +
  19636. + return 0;
  19637. +}
  19638. +
  19639. +int ieee80211_wx_get_name(struct ieee80211_device *ieee,
  19640. + struct iw_request_info *info,
  19641. + union iwreq_data *wrqu, char *extra)
  19642. +{
  19643. + strcpy(wrqu->name, "802.11");
  19644. + if(ieee->modulation & IEEE80211_CCK_MODULATION){
  19645. + strcat(wrqu->name, "b");
  19646. + if(ieee->modulation & IEEE80211_OFDM_MODULATION)
  19647. + strcat(wrqu->name, "/g");
  19648. + }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
  19649. + strcat(wrqu->name, "g");
  19650. +
  19651. + if((ieee->state == IEEE80211_LINKED) ||
  19652. + (ieee->state == IEEE80211_LINKED_SCANNING))
  19653. + strcat(wrqu->name," linked");
  19654. + else if(ieee->state != IEEE80211_NOLINK)
  19655. + strcat(wrqu->name," link..");
  19656. +
  19657. +
  19658. + return 0;
  19659. +}
  19660. +
  19661. +
  19662. +/* this is mostly stolen from hostap */
  19663. +int ieee80211_wx_set_power(struct ieee80211_device *ieee,
  19664. + struct iw_request_info *info,
  19665. + union iwreq_data *wrqu, char *extra)
  19666. +{
  19667. + int ret = 0;
  19668. +
  19669. + if(
  19670. + (!ieee->sta_wake_up) ||
  19671. + (!ieee->ps_request_tx_ack) ||
  19672. + (!ieee->enter_sleep_state) ||
  19673. + (!ieee->ps_is_queue_empty)){
  19674. +
  19675. + printk("ERROR. PS mode is tryied to be use but\
  19676. +driver missed a callback\n\n");
  19677. +
  19678. + return -1;
  19679. + }
  19680. +
  19681. + down(&ieee->wx_sem);
  19682. +
  19683. + if (wrqu->power.disabled){
  19684. + ieee->ps = IEEE80211_PS_DISABLED;
  19685. +
  19686. + goto exit;
  19687. + }
  19688. + switch (wrqu->power.flags & IW_POWER_MODE) {
  19689. + case IW_POWER_UNICAST_R:
  19690. + ieee->ps = IEEE80211_PS_UNICAST;
  19691. +
  19692. + break;
  19693. + case IW_POWER_ALL_R:
  19694. + ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
  19695. + break;
  19696. +
  19697. + case IW_POWER_ON:
  19698. + ieee->ps = IEEE80211_PS_DISABLED;
  19699. + break;
  19700. +
  19701. + default:
  19702. + ret = -EINVAL;
  19703. + goto exit;
  19704. + }
  19705. +
  19706. + if (wrqu->power.flags & IW_POWER_TIMEOUT) {
  19707. +
  19708. + ieee->ps_timeout = wrqu->power.value / 1000;
  19709. + printk("Timeout %d\n",ieee->ps_timeout);
  19710. + }
  19711. +
  19712. + if (wrqu->power.flags & IW_POWER_PERIOD) {
  19713. +
  19714. + ret = -EOPNOTSUPP;
  19715. + goto exit;
  19716. + //wrq->value / 1024;
  19717. +
  19718. + }
  19719. +exit:
  19720. + up(&ieee->wx_sem);
  19721. + return ret;
  19722. +
  19723. +}
  19724. +
  19725. +/* this is stolen from hostap */
  19726. +int ieee80211_wx_get_power(struct ieee80211_device *ieee,
  19727. + struct iw_request_info *info,
  19728. + union iwreq_data *wrqu, char *extra)
  19729. +{
  19730. + int ret =0;
  19731. +
  19732. + down(&ieee->wx_sem);
  19733. +
  19734. + if(ieee->ps == IEEE80211_PS_DISABLED){
  19735. + wrqu->power.disabled = 1;
  19736. + goto exit;
  19737. + }
  19738. +
  19739. + wrqu->power.disabled = 0;
  19740. +
  19741. +// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
  19742. + wrqu->power.flags = IW_POWER_TIMEOUT;
  19743. + wrqu->power.value = ieee->ps_timeout * 1000;
  19744. +// } else {
  19745. +// ret = -EOPNOTSUPP;
  19746. +// goto exit;
  19747. + //wrqu->power.flags = IW_POWER_PERIOD;
  19748. + //wrqu->power.value = ieee->current_network.dtim_period *
  19749. + // ieee->current_network.beacon_interval * 1024;
  19750. +// }
  19751. +
  19752. +
  19753. + if (ieee->ps & IEEE80211_PS_MBCAST)
  19754. + wrqu->power.flags |= IW_POWER_ALL_R;
  19755. + else
  19756. + wrqu->power.flags |= IW_POWER_UNICAST_R;
  19757. +
  19758. +exit:
  19759. + up(&ieee->wx_sem);
  19760. + return ret;
  19761. +
  19762. +}
  19763. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  19764. +EXPORT_SYMBOL(ieee80211_wx_get_essid);
  19765. +EXPORT_SYMBOL(ieee80211_wx_set_essid);
  19766. +EXPORT_SYMBOL(ieee80211_wx_set_rate);
  19767. +EXPORT_SYMBOL(ieee80211_wx_get_rate);
  19768. +EXPORT_SYMBOL(ieee80211_wx_set_wap);
  19769. +EXPORT_SYMBOL(ieee80211_wx_get_wap);
  19770. +EXPORT_SYMBOL(ieee80211_wx_set_mode);
  19771. +EXPORT_SYMBOL(ieee80211_wx_get_mode);
  19772. +EXPORT_SYMBOL(ieee80211_wx_set_scan);
  19773. +EXPORT_SYMBOL(ieee80211_wx_get_freq);
  19774. +EXPORT_SYMBOL(ieee80211_wx_set_freq);
  19775. +EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
  19776. +EXPORT_SYMBOL(ieee80211_wx_get_name);
  19777. +EXPORT_SYMBOL(ieee80211_wx_set_power);
  19778. +EXPORT_SYMBOL(ieee80211_wx_get_power);
  19779. +EXPORT_SYMBOL(ieee80211_wlan_frequencies);
  19780. +#else
  19781. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid);
  19782. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid);
  19783. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate);
  19784. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate);
  19785. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap);
  19786. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap);
  19787. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode);
  19788. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode);
  19789. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan);
  19790. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq);
  19791. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq);
  19792. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx);
  19793. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name);
  19794. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power);
  19795. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power);
  19796. +EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies);
  19797. +#endif
  19798. 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
  19799. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 1970-01-01 01:00:00.000000000 +0100
  19800. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_tx.c 2010-05-27 18:12:39.532222207 +0200
  19801. @@ -0,0 +1,876 @@
  19802. +/******************************************************************************
  19803. +
  19804. + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
  19805. +
  19806. + This program is free software; you can redistribute it and/or modify it
  19807. + under the terms of version 2 of the GNU General Public License as
  19808. + published by the Free Software Foundation.
  19809. +
  19810. + This program is distributed in the hope that it will be useful, but WITHOUT
  19811. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  19812. + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  19813. + more details.
  19814. +
  19815. + You should have received a copy of the GNU General Public License along with
  19816. + this program; if not, write to the Free Software Foundation, Inc., 59
  19817. + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19818. +
  19819. + The full GNU General Public License is included in this distribution in the
  19820. + file called LICENSE.
  19821. +
  19822. + Contact Information:
  19823. + James P. Ketrenos <ipw2100-admin@linux.intel.com>
  19824. + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  19825. +
  19826. +******************************************************************************
  19827. +
  19828. + Few modifications for Realtek's Wi-Fi drivers by
  19829. + Andrea Merello <andreamrl@tiscali.it>
  19830. +
  19831. + A special thanks goes to Realtek for their support !
  19832. +
  19833. +******************************************************************************/
  19834. +
  19835. +#include <linux/compiler.h>
  19836. +//#include <linux/config.h>
  19837. +#include <linux/errno.h>
  19838. +#include <linux/if_arp.h>
  19839. +#include <linux/in6.h>
  19840. +#include <linux/in.h>
  19841. +#include <linux/ip.h>
  19842. +#include <linux/kernel.h>
  19843. +#include <linux/module.h>
  19844. +#include <linux/netdevice.h>
  19845. +#include <linux/pci.h>
  19846. +#include <linux/proc_fs.h>
  19847. +#include <linux/skbuff.h>
  19848. +#include <linux/slab.h>
  19849. +#include <linux/tcp.h>
  19850. +#include <linux/types.h>
  19851. +#include <linux/version.h>
  19852. +#include <linux/wireless.h>
  19853. +#include <linux/etherdevice.h>
  19854. +#include <asm/uaccess.h>
  19855. +#include <linux/if_vlan.h>
  19856. +
  19857. +#include "ieee80211.h"
  19858. +
  19859. +
  19860. +/*
  19861. +
  19862. +
  19863. +802.11 Data Frame
  19864. +
  19865. +
  19866. +802.11 frame_contorl for data frames - 2 bytes
  19867. + ,-----------------------------------------------------------------------------------------.
  19868. +bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
  19869. + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  19870. +val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
  19871. + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
  19872. +desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
  19873. + | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
  19874. + '-----------------------------------------------------------------------------------------'
  19875. + /\
  19876. + |
  19877. +802.11 Data Frame |
  19878. + ,--------- 'ctrl' expands to >-----------'
  19879. + |
  19880. + ,--'---,-------------------------------------------------------------.
  19881. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
  19882. + |------|------|---------|---------|---------|------|---------|------|
  19883. +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
  19884. + | | tion | (BSSID) | | | ence | data | |
  19885. + `--------------------------------------------------| |------'
  19886. +Total: 28 non-data bytes `----.----'
  19887. + |
  19888. + .- 'Frame data' expands to <---------------------------'
  19889. + |
  19890. + V
  19891. + ,---------------------------------------------------.
  19892. +Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
  19893. + |------|------|---------|----------|------|---------|
  19894. +Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
  19895. + | DSAP | SSAP | | | | Packet |
  19896. + | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
  19897. + `-----------------------------------------| |
  19898. +Total: 8 non-data bytes `----.----'
  19899. + |
  19900. + .- 'IP Packet' expands, if WEP enabled, to <--'
  19901. + |
  19902. + V
  19903. + ,-----------------------.
  19904. +Bytes | 4 | 0-2296 | 4 |
  19905. + |-----|-----------|-----|
  19906. +Desc. | IV | Encrypted | ICV |
  19907. + | | IP Packet | |
  19908. + `-----------------------'
  19909. +Total: 8 non-data bytes
  19910. +
  19911. +
  19912. +802.3 Ethernet Data Frame
  19913. +
  19914. + ,-----------------------------------------.
  19915. +Bytes | 6 | 6 | 2 | Variable | 4 |
  19916. + |-------|-------|------|-----------|------|
  19917. +Desc. | Dest. | Source| Type | IP Packet | fcs |
  19918. + | MAC | MAC | | | |
  19919. + `-----------------------------------------'
  19920. +Total: 18 non-data bytes
  19921. +
  19922. +In the event that fragmentation is required, the incoming payload is split into
  19923. +N parts of size ieee->fts. The first fragment contains the SNAP header and the
  19924. +remaining packets are just data.
  19925. +
  19926. +If encryption is enabled, each fragment payload size is reduced by enough space
  19927. +to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
  19928. +So if you have 1500 bytes of payload with ieee->fts set to 500 without
  19929. +encryption it will take 3 frames. With WEP it will take 4 frames as the
  19930. +payload of each frame is reduced to 492 bytes.
  19931. +
  19932. +* SKB visualization
  19933. +*
  19934. +* ,- skb->data
  19935. +* |
  19936. +* | ETHERNET HEADER ,-<-- PAYLOAD
  19937. +* | | 14 bytes from skb->data
  19938. +* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
  19939. +* | | | |
  19940. +* |,-Dest.--. ,--Src.---. | | |
  19941. +* | 6 bytes| | 6 bytes | | | |
  19942. +* v | | | | | |
  19943. +* 0 | v 1 | v | v 2
  19944. +* 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
  19945. +* ^ | ^ | ^ |
  19946. +* | | | | | |
  19947. +* | | | | `T' <---- 2 bytes for Type
  19948. +* | | | |
  19949. +* | | '---SNAP--' <-------- 6 bytes for SNAP
  19950. +* | |
  19951. +* `-IV--' <-------------------- 4 bytes for IV (WEP)
  19952. +*
  19953. +* SNAP HEADER
  19954. +*
  19955. +*/
  19956. +
  19957. +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
  19958. +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
  19959. +
  19960. +static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
  19961. +{
  19962. + struct ieee80211_snap_hdr *snap;
  19963. + u8 *oui;
  19964. +
  19965. + snap = (struct ieee80211_snap_hdr *)data;
  19966. + snap->dsap = 0xaa;
  19967. + snap->ssap = 0xaa;
  19968. + snap->ctrl = 0x03;
  19969. +
  19970. + if (h_proto == 0x8137 || h_proto == 0x80f3)
  19971. + oui = P802_1H_OUI;
  19972. + else
  19973. + oui = RFC1042_OUI;
  19974. + snap->oui[0] = oui[0];
  19975. + snap->oui[1] = oui[1];
  19976. + snap->oui[2] = oui[2];
  19977. +
  19978. + *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
  19979. +
  19980. + return SNAP_SIZE + sizeof(u16);
  19981. +}
  19982. +
  19983. +int ieee80211_encrypt_fragment(
  19984. + struct ieee80211_device *ieee,
  19985. + struct sk_buff *frag,
  19986. + int hdr_len)
  19987. +{
  19988. + struct ieee80211_crypt_data* crypt = NULL;//ieee->crypt[ieee->tx_keyidx];
  19989. + int res;//, i;
  19990. +// printk("====>wwwwww%s():ieee:%x, hdr_len:%d\n", __FUNCTION__, ieee, hdr_len);
  19991. +/* printk("\n%s(), hdr_len:%d\n", __FUNCTION__, hdr_len);
  19992. + for (i = 0; i < 48; i++) {
  19993. + if (i % 16 == 0) printk("\n\t");
  19994. + printk("%2x ", *(frag->data+i));
  19995. + }
  19996. +*/
  19997. +
  19998. +#ifdef _RTL8187_EXT_PATCH_
  19999. +#if 0
  20000. + i = ieee80211_find_MP(ieee, ((struct ieee80211_hdr*) frag->data)->addr1);
  20001. + if (i== -1){
  20002. + printk("error find MP entry in %s()\n", __FUNCTION__);
  20003. + return i;
  20004. + }
  20005. + // printk("%s():"MAC_FMT", find in index:%d\n", __FUNCTION__, MAC_ARG(((struct ieee80211_hdr*)frag->data)->addr1), i);
  20006. +#endif
  20007. +// crypt = ieee->cryptlist[MAX_MP-1]->crypt[ieee->tx_keyidx];
  20008. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  20009. +#else
  20010. + crypt = ieee->crypt[ieee->tx_keyidx];
  20011. +#endif
  20012. + /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
  20013. + if (!crypt || !crypt->ops)
  20014. + return -1;
  20015. +
  20016. +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
  20017. + struct ieee80211_hdr *header;
  20018. +
  20019. + if (ieee->tkip_countermeasures &&
  20020. + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
  20021. + header = (struct ieee80211_hdr *) frag->data;
  20022. + if (net_ratelimit()) {
  20023. + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
  20024. + "TX packet to " MAC_FMT "\n",
  20025. + ieee->dev->name, MAC_ARG(header->addr1));
  20026. + }
  20027. + return -1;
  20028. + }
  20029. +#endif
  20030. + /* To encrypt, frame format is:
  20031. + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
  20032. +
  20033. + // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
  20034. + /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
  20035. + * call both MSDU and MPDU encryption functions from here. */
  20036. + atomic_inc(&crypt->refcnt);
  20037. + res = 0;
  20038. + if (crypt->ops->encrypt_msdu)
  20039. + res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
  20040. + if (res == 0 && crypt->ops->encrypt_mpdu)
  20041. + res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
  20042. + atomic_dec(&crypt->refcnt);
  20043. + if (res < 0) {
  20044. + printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
  20045. + ieee->dev->name, frag->len);
  20046. + ieee->ieee_stats.tx_discards++;
  20047. + return -1;
  20048. + }
  20049. +
  20050. + return 0;
  20051. +}
  20052. +
  20053. +
  20054. +void ieee80211_txb_free(struct ieee80211_txb *txb) {
  20055. + int i;
  20056. + if (unlikely(!txb))
  20057. + return;
  20058. + for (i = 0; i < txb->nr_frags; i++)
  20059. + if (txb->fragments[i])
  20060. + dev_kfree_skb_any(txb->fragments[i]);
  20061. + kfree(txb);
  20062. +}
  20063. +
  20064. +struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
  20065. + int gfp_mask)
  20066. +{
  20067. + struct ieee80211_txb *txb;
  20068. + int i;
  20069. + txb = kmalloc(
  20070. + sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
  20071. + gfp_mask);
  20072. + if (!txb)
  20073. + return NULL;
  20074. +
  20075. + memset(txb, 0, sizeof(struct ieee80211_txb));
  20076. + txb->nr_frags = nr_frags;
  20077. + txb->frag_size = txb_size;
  20078. +
  20079. + for (i = 0; i < nr_frags; i++) {
  20080. + txb->fragments[i] = dev_alloc_skb(txb_size);
  20081. + if (unlikely(!txb->fragments[i])) {
  20082. + i--;
  20083. + break;
  20084. + }
  20085. + }
  20086. + if (unlikely(i != nr_frags)) {
  20087. + while (i >= 0)
  20088. + dev_kfree_skb_any(txb->fragments[i--]);
  20089. + kfree(txb);
  20090. + return NULL;
  20091. + }
  20092. + return txb;
  20093. +}
  20094. +
  20095. +// Classify the to-be send data packet
  20096. +// Need to acquire the sent queue index.
  20097. +static int
  20098. +ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
  20099. +{
  20100. + struct ether_header *eh = (struct ether_header*)skb->data;
  20101. + unsigned int wme_UP = 0;
  20102. +
  20103. + if(!network->QoS_Enable) {
  20104. + skb->priority = 0;
  20105. + return(wme_UP);
  20106. + }
  20107. +
  20108. + if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
  20109. + const struct iphdr *ih = (struct iphdr*)(skb->data + \
  20110. + sizeof(struct ether_header));
  20111. + wme_UP = (ih->tos >> 5)&0x07;
  20112. + } else if (vlan_tx_tag_present(skb)) {//vtag packet
  20113. +#ifndef VLAN_PRI_SHIFT
  20114. +#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
  20115. +#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
  20116. +#endif
  20117. + u32 tag = vlan_tx_tag_get(skb);
  20118. + wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
  20119. + } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
  20120. + //printk(KERN_WARNING "type = normal packet\n");
  20121. + wme_UP = 7;
  20122. + }
  20123. + skb->priority = wme_UP;
  20124. +/*
  20125. + if (network->QoS_Enable) {
  20126. + skb->priority = wme_UP;
  20127. + }else {
  20128. + skb->priority = 0;
  20129. + }
  20130. +*/
  20131. + return(wme_UP);
  20132. +}
  20133. +
  20134. +#ifdef _RTL8187_EXT_PATCH_
  20135. +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
  20136. +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)
  20137. +{
  20138. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  20139. + struct ieee80211_device *ieee = netdev_priv(dev);
  20140. +#else
  20141. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  20142. +#endif
  20143. + struct ieee80211_txb *txb = NULL;
  20144. + struct ieee80211_hdr_3addr *frag_hdr;
  20145. + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
  20146. + int ether_type;
  20147. + int bytes, QOS_ctl;
  20148. + struct sk_buff *skb_frag;
  20149. +
  20150. + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
  20151. +
  20152. + /* Advance the SKB to the start of the payload */
  20153. + skb_pull(skb, sizeof(struct ethhdr));
  20154. +
  20155. + /* Determine total amount of storage required for TXB packets */
  20156. + bytes = skb->len + SNAP_SIZE + sizeof(u16);
  20157. +
  20158. + /* Determine fragmentation size based on destination (multicast
  20159. + * and broadcast are not fragmented) */
  20160. + // if (is_multicast_ether_addr(dest) ||
  20161. + // is_broadcast_ether_addr(dest)) {
  20162. + if (is_multicast_ether_addr(header->addr1) ||
  20163. + is_broadcast_ether_addr(header->addr1)) {
  20164. + frag_size = MAX_FRAG_THRESHOLD;
  20165. + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
  20166. + }
  20167. + else {
  20168. + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
  20169. + frag_size = ieee->fts;//default:392
  20170. + QOS_ctl = 0;
  20171. + }
  20172. +
  20173. + if(isQoS) {
  20174. + QOS_ctl |= skb->priority; //set in the ieee80211_classify
  20175. + *pQOS_ctl = cpu_to_le16(QOS_ctl);
  20176. + }
  20177. + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
  20178. + /* Determine amount of payload per fragment. Regardless of if
  20179. + * this stack is providing the full 802.11 header, one will
  20180. + * eventually be affixed to this fragment -- so we must account for
  20181. + * it when determining the amount of payload space. */
  20182. + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
  20183. + bytes_per_frag = frag_size - hdr_len;
  20184. + if (ieee->config &
  20185. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  20186. + bytes_per_frag -= IEEE80211_FCS_LEN;
  20187. +
  20188. + /* Each fragment may need to have room for encryptiong pre/postfix */
  20189. + if (isEncrypt)
  20190. + bytes_per_frag -= crypt->ops->extra_prefix_len +
  20191. + crypt->ops->extra_postfix_len;
  20192. +
  20193. + /* Number of fragments is the total bytes_per_frag /
  20194. + * payload_per_fragment */
  20195. + nr_frags = bytes / bytes_per_frag;
  20196. + bytes_last_frag = bytes % bytes_per_frag;
  20197. + if (bytes_last_frag)
  20198. + nr_frags++;
  20199. + else
  20200. + bytes_last_frag = bytes_per_frag;
  20201. +
  20202. + /* When we allocate the TXB we allocate enough space for the reserve
  20203. + * and full fragment bytes (bytes_per_frag doesn't include prefix,
  20204. + * postfix, header, FCS, etc.) */
  20205. + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
  20206. + if (unlikely(!txb)) {
  20207. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  20208. + ieee->dev->name);
  20209. + return NULL;
  20210. + }
  20211. + txb->encrypted = isEncrypt;
  20212. + txb->payload_size = bytes;
  20213. +
  20214. + for (i = 0; i < nr_frags; i++) {
  20215. + skb_frag = txb->fragments[i];
  20216. + skb_frag->priority = UP2AC(skb->priority);
  20217. + if (isEncrypt)
  20218. + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
  20219. +
  20220. + frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
  20221. + memcpy(frag_hdr, (void *)header, hdr_len);
  20222. +
  20223. + /* If this is not the last fragment, then add the MOREFRAGS
  20224. + * bit to the frame control */
  20225. + if (i != nr_frags - 1) {
  20226. + frag_hdr->frame_ctl = cpu_to_le16(
  20227. + header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
  20228. + bytes = bytes_per_frag;
  20229. +
  20230. + } else {
  20231. + /* The last fragment takes the remaining length */
  20232. + bytes = bytes_last_frag;
  20233. + }
  20234. +
  20235. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
  20236. + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
  20237. + //
  20238. +
  20239. + /* Put a SNAP header on the first fragment */
  20240. + if (i == 0) {
  20241. + ieee80211_put_snap(
  20242. + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
  20243. + bytes -= SNAP_SIZE + sizeof(u16);
  20244. + }
  20245. +
  20246. + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
  20247. +
  20248. + /* Advance the SKB... */
  20249. + skb_pull(skb, bytes);
  20250. +
  20251. + /* Encryption routine will move the header forward in order
  20252. + * to insert the IV between the header and the payload */
  20253. + if (isEncrypt)
  20254. + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
  20255. + if (ieee->config &
  20256. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  20257. + skb_put(skb_frag, 4);
  20258. + }
  20259. + // Advance sequence number in data frame.
  20260. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
  20261. + if (ieee->seq_ctrl[0] == 0xFFF)
  20262. + ieee->seq_ctrl[0] = 0;
  20263. + else
  20264. + ieee->seq_ctrl[0]++;
  20265. + // stanley, just for debug
  20266. +/*
  20267. +{
  20268. + int j=0;
  20269. + for(j=0;j<nr_frags;j++)
  20270. + {
  20271. + int i;
  20272. + struct sk_buff *skb = txb->fragments[j];
  20273. + printk("send(%d): ", j);
  20274. + for (i=0;i<skb->len;i++)
  20275. + printk("%02X ", skb->data[i]&0xff);
  20276. + printk("\n");
  20277. + }
  20278. +}
  20279. +*/
  20280. +
  20281. + return txb;
  20282. +}
  20283. +
  20284. +
  20285. +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
  20286. +// Assume no encryption, no FCS computing
  20287. +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)
  20288. +{
  20289. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  20290. + struct ieee80211_device *ieee = netdev_priv(dev);
  20291. +#else
  20292. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  20293. +#endif
  20294. + struct ieee80211_txb *txb = NULL;
  20295. + struct ieee80211_hdr_3addr *frag_hdr;
  20296. + int ether_type;
  20297. + int bytes, QOS_ctl;
  20298. +
  20299. + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
  20300. +
  20301. + /* Advance the SKB to the start of the payload */
  20302. + skb_pull(skb, sizeof(struct ethhdr));
  20303. +
  20304. + /* Determine total amount of storage required for TXB packets */
  20305. + bytes = skb->len + SNAP_SIZE + sizeof(u16);
  20306. +
  20307. + if (is_multicast_ether_addr(header->addr1) ||
  20308. + is_broadcast_ether_addr(header->addr1)) {
  20309. + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
  20310. + }
  20311. + else {
  20312. + QOS_ctl = 0;
  20313. + }
  20314. +
  20315. + if(isQoS) {
  20316. + QOS_ctl |= skb->priority; //set in the ieee80211_classify
  20317. + *pQOS_ctl = cpu_to_le16(QOS_ctl);
  20318. + }
  20319. +
  20320. + txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
  20321. + if (unlikely(!txb)) {
  20322. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  20323. + ieee->dev->name);
  20324. + return NULL;
  20325. + }
  20326. +
  20327. + txb->nr_frags = 1;
  20328. + txb->frag_size = bytes;
  20329. + txb->encrypted = isEncrypt;
  20330. + txb->payload_size = bytes;
  20331. +
  20332. + txb->fragments[0] = skb;
  20333. + ieee80211_put_snap(
  20334. + skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
  20335. + frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
  20336. + memcpy(frag_hdr, (void *)header, hdr_len);
  20337. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
  20338. + skb->priority = UP2AC(skb->priority);
  20339. + if(isEncrypt)
  20340. + ieee80211_encrypt_fragment(ieee,skb,hdr_len);
  20341. +
  20342. + // Advance sequence number in data frame.
  20343. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
  20344. + if (ieee->seq_ctrl[0] == 0xFFF)
  20345. + ieee->seq_ctrl[0] = 0;
  20346. + else
  20347. + ieee->seq_ctrl[0]++;
  20348. +
  20349. + return txb;
  20350. +}
  20351. +
  20352. +#endif // _RTL8187_EXT_PATCH_
  20353. +
  20354. +/* SKBs are added to the ieee->tx_queue. */
  20355. +int ieee80211_xmit(struct sk_buff *skb,
  20356. + struct net_device *dev)
  20357. +{
  20358. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  20359. + struct ieee80211_device *ieee = netdev_priv(dev);
  20360. +#else
  20361. + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
  20362. +#endif
  20363. + struct ieee80211_txb *txb = NULL;
  20364. + struct ieee80211_hdr_3addr_QOS *frag_hdr;
  20365. + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
  20366. + unsigned long flags;
  20367. + struct net_device_stats *stats = &ieee->stats;
  20368. + int ether_type, encrypt;
  20369. + int bytes, fc, QOS_ctl, hdr_len;
  20370. + struct sk_buff *skb_frag;
  20371. + //struct ieee80211_hdr header = { /* Ensure zero initialized */
  20372. + // .duration_id = 0,
  20373. + // .seq_ctl = 0
  20374. + //};
  20375. + struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
  20376. + .duration_id = 0,
  20377. + .seq_ctl = 0,
  20378. + .QOS_ctl = 0
  20379. + };
  20380. + u8 dest[ETH_ALEN], src[ETH_ALEN];
  20381. +
  20382. + struct ieee80211_crypt_data* crypt;
  20383. +
  20384. + //printk(KERN_WARNING "upper layer packet!\n");
  20385. + spin_lock_irqsave(&ieee->lock, flags);
  20386. +
  20387. + /* If there is no driver handler to take the TXB, dont' bother
  20388. + * creating it... */
  20389. + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
  20390. + ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
  20391. + printk(KERN_WARNING "%s: No xmit handler.\n",
  20392. + ieee->dev->name);
  20393. + goto success;
  20394. + }
  20395. +
  20396. + ieee80211_classify(skb,&ieee->current_network);
  20397. + if(likely(ieee->raw_tx == 0)){
  20398. +
  20399. + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
  20400. + printk(KERN_WARNING "%s: skb too small (%d).\n",
  20401. + ieee->dev->name, skb->len);
  20402. + goto success;
  20403. + }
  20404. +
  20405. +
  20406. +#ifdef _RTL8187_EXT_PATCH_
  20407. + // note, skb->priority which was set by ieee80211_classify, and used by physical tx
  20408. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
  20409. + {
  20410. + txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
  20411. + goto success;
  20412. + }
  20413. +#endif
  20414. +
  20415. + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
  20416. +#ifdef _RTL8187_EXT_PATCH_
  20417. + crypt = ieee->cryptlist[0]->crypt[ieee->tx_keyidx];
  20418. +#else
  20419. + crypt = ieee->crypt[ieee->tx_keyidx];
  20420. +#endif
  20421. + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
  20422. + ieee->host_encrypt && crypt && crypt->ops;
  20423. +
  20424. + if (!encrypt && ieee->ieee802_1x &&
  20425. + ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
  20426. + stats->tx_dropped++;
  20427. + goto success;
  20428. + }
  20429. +
  20430. + #ifdef CONFIG_IEEE80211_DEBUG
  20431. + if (crypt && !encrypt && ether_type == ETH_P_PAE) {
  20432. + struct eapol *eap = (struct eapol *)(skb->data +
  20433. + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
  20434. + IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
  20435. + eap_get_type(eap->type));
  20436. + }
  20437. + #endif
  20438. +
  20439. + /* Save source and destination addresses */
  20440. + memcpy(&dest, skb->data, ETH_ALEN);
  20441. + memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
  20442. +
  20443. + /* Advance the SKB to the start of the payload */
  20444. + skb_pull(skb, sizeof(struct ethhdr));
  20445. +
  20446. + /* Determine total amount of storage required for TXB packets */
  20447. + bytes = skb->len + SNAP_SIZE + sizeof(u16);
  20448. +
  20449. + if(ieee->current_network.QoS_Enable) {
  20450. + if (encrypt)
  20451. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
  20452. + IEEE80211_FCTL_WEP;
  20453. + else
  20454. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
  20455. +
  20456. + } else {
  20457. + if (encrypt)
  20458. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
  20459. + IEEE80211_FCTL_WEP;
  20460. + else
  20461. + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
  20462. + }
  20463. +
  20464. + if (ieee->iw_mode == IW_MODE_INFRA) {
  20465. + fc |= IEEE80211_FCTL_TODS;
  20466. + /* To DS: Addr1 = BSSID, Addr2 = SA,
  20467. + Addr3 = DA */
  20468. + memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
  20469. + memcpy(&header.addr2, &src, ETH_ALEN);
  20470. + memcpy(&header.addr3, &dest, ETH_ALEN);
  20471. + } else if (ieee->iw_mode == IW_MODE_ADHOC) {
  20472. + /* not From/To DS: Addr1 = DA, Addr2 = SA,
  20473. + Addr3 = BSSID */
  20474. + memcpy(&header.addr1, dest, ETH_ALEN);
  20475. + memcpy(&header.addr2, src, ETH_ALEN);
  20476. + memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
  20477. + }
  20478. + // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
  20479. + header.frame_ctl = cpu_to_le16(fc);
  20480. + //hdr_len = IEEE80211_3ADDR_LEN;
  20481. +
  20482. + /* Determine fragmentation size based on destination (multicast
  20483. + * and broadcast are not fragmented) */
  20484. +// if (is_multicast_ether_addr(dest) ||
  20485. +// is_broadcast_ether_addr(dest)) {
  20486. + if (is_multicast_ether_addr(header.addr1) ||
  20487. + is_broadcast_ether_addr(header.addr1)) {
  20488. + frag_size = MAX_FRAG_THRESHOLD;
  20489. + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
  20490. + }
  20491. + else {
  20492. + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
  20493. + frag_size = ieee->fts;//default:392
  20494. + QOS_ctl = 0;
  20495. + }
  20496. +
  20497. + if (ieee->current_network.QoS_Enable) {
  20498. + hdr_len = IEEE80211_3ADDR_LEN + 2;
  20499. + QOS_ctl |= skb->priority; //set in the ieee80211_classify
  20500. + header.QOS_ctl = cpu_to_le16(QOS_ctl);
  20501. + } else {
  20502. + hdr_len = IEEE80211_3ADDR_LEN;
  20503. + }
  20504. + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
  20505. + /* Determine amount of payload per fragment. Regardless of if
  20506. + * this stack is providing the full 802.11 header, one will
  20507. + * eventually be affixed to this fragment -- so we must account for
  20508. + * it when determining the amount of payload space. */
  20509. + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
  20510. + bytes_per_frag = frag_size - hdr_len;
  20511. + if (ieee->config &
  20512. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  20513. + bytes_per_frag -= IEEE80211_FCS_LEN;
  20514. +
  20515. + /* Each fragment may need to have room for encryptiong pre/postfix */
  20516. + if (encrypt)
  20517. + bytes_per_frag -= crypt->ops->extra_prefix_len +
  20518. + crypt->ops->extra_postfix_len;
  20519. +
  20520. + /* Number of fragments is the total bytes_per_frag /
  20521. + * payload_per_fragment */
  20522. + nr_frags = bytes / bytes_per_frag;
  20523. + bytes_last_frag = bytes % bytes_per_frag;
  20524. + if (bytes_last_frag)
  20525. + nr_frags++;
  20526. + else
  20527. + bytes_last_frag = bytes_per_frag;
  20528. +
  20529. + /* When we allocate the TXB we allocate enough space for the reserve
  20530. + * and full fragment bytes (bytes_per_frag doesn't include prefix,
  20531. + * postfix, header, FCS, etc.) */
  20532. + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
  20533. + if (unlikely(!txb)) {
  20534. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  20535. + ieee->dev->name);
  20536. + goto failed;
  20537. + }
  20538. + txb->encrypted = encrypt;
  20539. + txb->payload_size = bytes;
  20540. +
  20541. + for (i = 0; i < nr_frags; i++) {
  20542. + skb_frag = txb->fragments[i];
  20543. + skb_frag->priority = UP2AC(skb->priority);
  20544. + if (encrypt)
  20545. + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
  20546. +
  20547. + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
  20548. + memcpy(frag_hdr, &header, hdr_len);
  20549. +
  20550. + /* If this is not the last fragment, then add the MOREFRAGS
  20551. + * bit to the frame control */
  20552. + if (i != nr_frags - 1) {
  20553. + frag_hdr->frame_ctl = cpu_to_le16(
  20554. + fc | IEEE80211_FCTL_MOREFRAGS);
  20555. + bytes = bytes_per_frag;
  20556. +
  20557. + } else {
  20558. + /* The last fragment takes the remaining length */
  20559. + bytes = bytes_last_frag;
  20560. + }
  20561. + if(ieee->current_network.QoS_Enable) {
  20562. + // add 1 only indicate to corresponding seq number control 2006/7/12
  20563. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
  20564. + //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
  20565. + //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
  20566. + } else {
  20567. + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
  20568. + }
  20569. + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
  20570. + //
  20571. +
  20572. + /* Put a SNAP header on the first fragment */
  20573. + if (i == 0) {
  20574. + ieee80211_put_snap(
  20575. + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
  20576. + ether_type);
  20577. + bytes -= SNAP_SIZE + sizeof(u16);
  20578. + }
  20579. +
  20580. + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
  20581. +
  20582. + /* Advance the SKB... */
  20583. + skb_pull(skb, bytes);
  20584. +
  20585. + /* Encryption routine will move the header forward in order
  20586. + * to insert the IV between the header and the payload */
  20587. + if (encrypt)
  20588. + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
  20589. + if (ieee->config &
  20590. + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
  20591. + skb_put(skb_frag, 4);
  20592. + }
  20593. + // Advance sequence number in data frame.
  20594. + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
  20595. + if (ieee->current_network.QoS_Enable) {
  20596. + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
  20597. + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
  20598. + else
  20599. + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
  20600. + } else {
  20601. + if (ieee->seq_ctrl[0] == 0xFFF)
  20602. + ieee->seq_ctrl[0] = 0;
  20603. + else
  20604. + ieee->seq_ctrl[0]++;
  20605. + }
  20606. + //---
  20607. + }else{
  20608. + if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
  20609. + printk(KERN_WARNING "%s: skb too small (%d).\n",
  20610. + ieee->dev->name, skb->len);
  20611. + goto success;
  20612. + }
  20613. +
  20614. + txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
  20615. + if(!txb){
  20616. + printk(KERN_WARNING "%s: Could not allocate TXB\n",
  20617. + ieee->dev->name);
  20618. + goto failed;
  20619. + }
  20620. +
  20621. + txb->encrypted = 0;
  20622. + txb->payload_size = skb->len;
  20623. + memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
  20624. + }
  20625. +
  20626. + success:
  20627. + spin_unlock_irqrestore(&ieee->lock, flags);
  20628. +#ifdef _RTL8187_EXT_PATCH_
  20629. + // Sometimes, extension mode can reuse skb (by txb->fragments[0])
  20630. + if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
  20631. +#endif
  20632. + dev_kfree_skb_any(skb);
  20633. + if (txb) {
  20634. + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
  20635. + ieee80211_softmac_xmit(txb, ieee);
  20636. + }else{
  20637. + if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
  20638. + stats->tx_packets++;
  20639. + stats->tx_bytes += txb->payload_size;
  20640. + return 0;
  20641. + }
  20642. + ieee80211_txb_free(txb);
  20643. + }
  20644. + }
  20645. +
  20646. + return 0;
  20647. +
  20648. + failed:
  20649. + spin_unlock_irqrestore(&ieee->lock, flags);
  20650. + netif_stop_queue(dev);
  20651. + printk("netif_stop_queue in ieee80211_xmit \n");
  20652. + stats->tx_errors++;
  20653. + return 1;
  20654. +
  20655. +}
  20656. +
  20657. +
  20658. +
  20659. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  20660. +EXPORT_SYMBOL(ieee80211_txb_free);
  20661. +#ifdef _RTL8187_EXT_PATCH_
  20662. +EXPORT_SYMBOL(ieee80211_alloc_txb);
  20663. +EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
  20664. +EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
  20665. +
  20666. +EXPORT_SYMBOL(ieee80211_encrypt_fragment);
  20667. +#endif // _RTL8187_EXT_PATCH_
  20668. +#else
  20669. +EXPORT_SYMBOL_NOVERS(ieee80211_txb_free);
  20670. +#ifdef _RTL8187_EXT_PATCH_
  20671. +EXPORT_SYMBOL_NOVERS(ieee80211_alloc_txb);
  20672. +EXPORT_SYMBOL_NOVERS(ieee80211_ext_reuse_txb);
  20673. +
  20674. +EXPORT_SYMBOL_NOVERS(ieee80211_encrypt_fragment);
  20675. +#endif // _RTL8187_EXT_PATCH_
  20676. +#endif
  20677. +
  20678. 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
  20679. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 1970-01-01 01:00:00.000000000 +0100
  20680. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/ieee80211_wx.c 2010-05-27 18:12:39.532222207 +0200
  20681. @@ -0,0 +1,926 @@
  20682. +/******************************************************************************
  20683. +
  20684. + Copyright(c) 2004 Intel Corporation. All rights reserved.
  20685. +
  20686. + Portions of this file are based on the WEP enablement code provided by the
  20687. + Host AP project hostap-drivers v0.1.3
  20688. + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  20689. + <jkmaline@cc.hut.fi>
  20690. + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  20691. +
  20692. + This program is free software; you can redistribute it and/or modify it
  20693. + under the terms of version 2 of the GNU General Public License as
  20694. + published by the Free Software Foundation.
  20695. +
  20696. + This program is distributed in the hope that it will be useful, but WITHOUT
  20697. + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  20698. + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  20699. + more details.
  20700. +
  20701. + You should have received a copy of the GNU General Public License along with
  20702. + this program; if not, write to the Free Software Foundation, Inc., 59
  20703. + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20704. +
  20705. + The full GNU General Public License is included in this distribution in the
  20706. + file called LICENSE.
  20707. +
  20708. + Contact Information:
  20709. + James P. Ketrenos <ipw2100-admin@linux.intel.com>
  20710. + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  20711. +
  20712. +******************************************************************************/
  20713. +#include <linux/wireless.h>
  20714. +#include <linux/version.h>
  20715. +#include <linux/kmod.h>
  20716. +#include <linux/module.h>
  20717. +
  20718. +#include "ieee80211.h"
  20719. +static const char *ieee80211_modes[] = {
  20720. + "?", "a", "b", "ab", "g", "ag", "bg", "abg"
  20721. +};
  20722. +
  20723. +#define MAX_CUSTOM_LEN 64
  20724. +static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
  20725. + char *start, char *stop,
  20726. + struct ieee80211_network *network,
  20727. + struct iw_request_info *info)
  20728. +{
  20729. + char custom[MAX_CUSTOM_LEN];
  20730. + char *p;
  20731. + struct iw_event iwe;
  20732. + int i, j;
  20733. + u8 max_rate, rate;
  20734. +
  20735. + /* First entry *MUST* be the AP MAC address */
  20736. + iwe.cmd = SIOCGIWAP;
  20737. + iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
  20738. + memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
  20739. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20740. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
  20741. +#else
  20742. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
  20743. +#endif
  20744. + /* Remaining entries will be displayed in the order we provide them */
  20745. +
  20746. + /* Add the ESSID */
  20747. + iwe.cmd = SIOCGIWESSID;
  20748. + iwe.u.data.flags = 1;
  20749. + //YJ,modified,080903,for hidden ap
  20750. + //if (network->flags & NETWORK_EMPTY_ESSID) {
  20751. + if (network->ssid_len == 0) {
  20752. + iwe.u.data.length = sizeof("<hidden>");
  20753. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20754. + start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
  20755. +#else
  20756. + start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
  20757. +#endif
  20758. + } else {
  20759. + iwe.u.data.length = min(network->ssid_len, (u8)32);
  20760. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20761. + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
  20762. +#else
  20763. + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
  20764. +#endif
  20765. + }
  20766. +
  20767. + /* Add the protocol name */
  20768. + iwe.cmd = SIOCGIWNAME;
  20769. + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
  20770. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20771. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
  20772. +#else
  20773. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
  20774. +#endif
  20775. + /* Add mode */
  20776. + iwe.cmd = SIOCGIWMODE;
  20777. + if (network->capability &
  20778. + (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
  20779. + if (network->capability & WLAN_CAPABILITY_BSS)
  20780. + iwe.u.mode = IW_MODE_MASTER;
  20781. + else
  20782. + iwe.u.mode = IW_MODE_ADHOC;
  20783. +
  20784. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20785. + start = iwe_stream_add_event(info, start, stop, &iwe,
  20786. + IW_EV_UINT_LEN);
  20787. +#else
  20788. + start = iwe_stream_add_event(start, stop, &iwe,
  20789. + IW_EV_UINT_LEN);
  20790. +#endif
  20791. + }
  20792. +
  20793. + /* Add frequency/channel */
  20794. + iwe.cmd = SIOCGIWFREQ;
  20795. +/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
  20796. + iwe.u.freq.e = 3; */
  20797. + iwe.u.freq.m = network->channel;
  20798. + iwe.u.freq.e = 0;
  20799. + iwe.u.freq.i = 0;
  20800. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20801. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
  20802. +#else
  20803. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
  20804. +#endif
  20805. + /* Add encryption capability */
  20806. + iwe.cmd = SIOCGIWENCODE;
  20807. + if (network->capability & WLAN_CAPABILITY_PRIVACY)
  20808. + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
  20809. + else
  20810. + iwe.u.data.flags = IW_ENCODE_DISABLED;
  20811. + iwe.u.data.length = 0;
  20812. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20813. + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
  20814. +#else
  20815. + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
  20816. +#endif
  20817. + /* Add basic and extended rates */
  20818. + max_rate = 0;
  20819. + p = custom;
  20820. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
  20821. + for (i = 0, j = 0; i < network->rates_len; ) {
  20822. + if (j < network->rates_ex_len &&
  20823. + ((network->rates_ex[j] & 0x7F) <
  20824. + (network->rates[i] & 0x7F)))
  20825. + rate = network->rates_ex[j++] & 0x7F;
  20826. + else
  20827. + rate = network->rates[i++] & 0x7F;
  20828. + if (rate > max_rate)
  20829. + max_rate = rate;
  20830. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
  20831. + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
  20832. + }
  20833. + for (; j < network->rates_ex_len; j++) {
  20834. + rate = network->rates_ex[j] & 0x7F;
  20835. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
  20836. + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
  20837. + if (rate > max_rate)
  20838. + max_rate = rate;
  20839. + }
  20840. +
  20841. + iwe.cmd = SIOCGIWRATE;
  20842. + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
  20843. + iwe.u.bitrate.value = max_rate * 500000;
  20844. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20845. + start = iwe_stream_add_event(info, start, stop, &iwe,IW_EV_PARAM_LEN);
  20846. +#else
  20847. + start = iwe_stream_add_event(start, stop, &iwe,IW_EV_PARAM_LEN);
  20848. +#endif
  20849. + iwe.cmd = IWEVCUSTOM;
  20850. + iwe.u.data.length = p - custom;
  20851. + if (iwe.u.data.length)
  20852. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20853. + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
  20854. +#else
  20855. + start = iwe_stream_add_point(start, stop, &iwe, custom);
  20856. +#endif
  20857. + /* Add quality statistics */
  20858. + /* TODO: Fix these values... */
  20859. + iwe.cmd = IWEVQUAL;
  20860. + iwe.u.qual.qual = network->stats.signalstrength;//network->stats.signal;
  20861. + iwe.u.qual.level = network->stats.signal;//network->stats.rssi;
  20862. + iwe.u.qual.noise = network->stats.noise;
  20863. +#if 0
  20864. + iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
  20865. + if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
  20866. + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
  20867. + if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
  20868. + iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
  20869. + if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
  20870. + iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
  20871. +#endif
  20872. +
  20873. + iwe.u.qual.updated = 0x7;//network->stats.mask & IEEE80211_STATMASK_WEMASK;
  20874. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20875. + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
  20876. +#else
  20877. + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
  20878. +#endif
  20879. + iwe.cmd = IWEVCUSTOM;
  20880. + p = custom;
  20881. +
  20882. + iwe.u.data.length = p - custom;
  20883. + if (iwe.u.data.length)
  20884. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20885. + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
  20886. +#else
  20887. + start = iwe_stream_add_point(start, stop, &iwe, custom);
  20888. +#endif
  20889. +#if 0
  20890. + if (ieee->wpa_enabled && network->wpa_ie_len){
  20891. + char buf[MAX_WPA_IE_LEN * 2 + 30];
  20892. + // printk("WPA IE\n");
  20893. + u8 *p = buf;
  20894. + p += sprintf(p, "wpa_ie=");
  20895. + for (i = 0; i < network->wpa_ie_len; i++) {
  20896. + p += sprintf(p, "%02x", network->wpa_ie[i]);
  20897. + }
  20898. +
  20899. + memset(&iwe, 0, sizeof(iwe));
  20900. + iwe.cmd = IWEVCUSTOM;
  20901. + iwe.u.data.length = strlen(buf);
  20902. + start = iwe_stream_add_point(start, stop, &iwe, buf);
  20903. + }
  20904. +
  20905. + if (ieee->wpa_enabled && network->rsn_ie_len){
  20906. + char buf[MAX_WPA_IE_LEN * 2 + 30];
  20907. +
  20908. + u8 *p = buf;
  20909. + p += sprintf(p, "rsn_ie=");
  20910. + for (i = 0; i < network->rsn_ie_len; i++) {
  20911. + p += sprintf(p, "%02x", network->rsn_ie[i]);
  20912. + }
  20913. +
  20914. +
  20915. +#else
  20916. + memset(&iwe, 0, sizeof(iwe));
  20917. + if (network->wpa_ie_len) {
  20918. + //printk("wpa_ie_len:%d\n", network->wpa_ie_len);
  20919. + char buf[MAX_WPA_IE_LEN];
  20920. + memcpy(buf, network->wpa_ie, network->wpa_ie_len);
  20921. + iwe.cmd = IWEVGENIE;
  20922. + iwe.u.data.length = network->wpa_ie_len;
  20923. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20924. + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
  20925. +#else
  20926. + start = iwe_stream_add_point(start, stop, &iwe, buf);
  20927. +#endif
  20928. + }
  20929. +
  20930. + memset(&iwe, 0, sizeof(iwe));
  20931. + if (network->rsn_ie_len) {
  20932. + //printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
  20933. + #if 0
  20934. + {
  20935. + int i;
  20936. + for (i=0; i<network->rsn_ie_len; i++);
  20937. + printk("%2x ", network->rsn_ie[i]);
  20938. + printk("\n");
  20939. + }
  20940. + #endif
  20941. + char buf[MAX_WPA_IE_LEN];
  20942. + memcpy(buf, network->rsn_ie, network->rsn_ie_len);
  20943. + iwe.cmd = IWEVGENIE;
  20944. + iwe.u.data.length = network->rsn_ie_len;
  20945. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20946. + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
  20947. +#else
  20948. + start = iwe_stream_add_point(start, stop, &iwe, buf);
  20949. +#endif
  20950. + }
  20951. +
  20952. +#endif
  20953. +
  20954. + /* Add EXTRA: Age to display seconds since last beacon/probe response
  20955. + * for given network. */
  20956. + iwe.cmd = IWEVCUSTOM;
  20957. + p = custom;
  20958. + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
  20959. + " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
  20960. + iwe.u.data.length = p - custom;
  20961. + if (iwe.u.data.length)
  20962. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) || defined (QMI_26_6))
  20963. + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
  20964. +#else
  20965. + start = iwe_stream_add_point(start, stop, &iwe, custom);
  20966. +#endif
  20967. +
  20968. + return start;
  20969. +}
  20970. +
  20971. +int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
  20972. + struct iw_request_info *info,
  20973. + union iwreq_data *wrqu, char *extra)
  20974. +{
  20975. + struct ieee80211_network *network;
  20976. + unsigned long flags;
  20977. + int err = 0;
  20978. + char *ev = extra;
  20979. + char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
  20980. + //char *stop = ev + IW_SCAN_MAX_DATA;
  20981. + int i = 0;
  20982. +
  20983. + IEEE80211_DEBUG_WX("Getting scan\n");
  20984. + down(&ieee->wx_sem);
  20985. + spin_lock_irqsave(&ieee->lock, flags);
  20986. +
  20987. + if(!ieee->bHwRadioOff)
  20988. + {
  20989. + list_for_each_entry(network, &ieee->network_list, list) {
  20990. + i++;
  20991. +
  20992. + if((stop-ev)<200)
  20993. + {
  20994. + err = -E2BIG;
  20995. + break;
  20996. + }
  20997. +
  20998. + if (ieee->scan_age == 0 ||
  20999. + time_after(network->last_scanned + ieee->scan_age, jiffies))
  21000. + {
  21001. + ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
  21002. + }
  21003. + else
  21004. + IEEE80211_DEBUG_SCAN(
  21005. + "Not showing network '%s ("
  21006. + MAC_FMT ")' due to age (%lums).\n",
  21007. + escape_essid(network->ssid,
  21008. + network->ssid_len),
  21009. + MAC_ARG(network->bssid),
  21010. + (jiffies - network->last_scanned) / (HZ / 100));
  21011. + }
  21012. + }
  21013. + spin_unlock_irqrestore(&ieee->lock, flags);
  21014. + up(&ieee->wx_sem);
  21015. + wrqu->data.length = ev - extra;
  21016. + wrqu->data.flags = 0;
  21017. +
  21018. + IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
  21019. +
  21020. + return err;
  21021. +}
  21022. +
  21023. +int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
  21024. + struct iw_request_info *info,
  21025. + union iwreq_data *wrqu, char *keybuf)
  21026. +{
  21027. + struct iw_point *erq = &(wrqu->encoding);
  21028. + struct net_device *dev = ieee->dev;
  21029. + struct ieee80211_security sec = {
  21030. + .flags = 0
  21031. + };
  21032. + int i, key, key_provided, len;
  21033. + struct ieee80211_crypt_data **crypt;
  21034. +
  21035. + IEEE80211_DEBUG_WX("SET_ENCODE\n");
  21036. +
  21037. + key = erq->flags & IW_ENCODE_INDEX;
  21038. + if (key) {
  21039. + if (key > WEP_KEYS)
  21040. + return -EINVAL;
  21041. + key--;
  21042. + key_provided = 1;
  21043. + } else {
  21044. + key_provided = 0;
  21045. + key = ieee->tx_keyidx;
  21046. + }
  21047. +
  21048. + IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
  21049. + "provided" : "default");
  21050. +#ifdef _RTL8187_EXT_PATCH_
  21051. +#if 0
  21052. +{
  21053. + int j;
  21054. + for(j=0; j<MAX_MP; j++){
  21055. + crypt = &ieee->cryptlist[j]->crypt[key];
  21056. +#else
  21057. + crypt = &ieee->cryptlist[0]->crypt[key];
  21058. +#endif
  21059. +#else
  21060. + crypt = &ieee->crypt[key];
  21061. +#endif
  21062. + if (erq->flags & IW_ENCODE_DISABLED) {
  21063. + if (key_provided && *crypt) {
  21064. + IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
  21065. + key);
  21066. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  21067. + } else
  21068. + IEEE80211_DEBUG_WX("Disabling encryption.\n");
  21069. +
  21070. + /* Check all the keys to see if any are still configured,
  21071. + * and if no key index was provided, de-init them all */
  21072. + for (i = 0; i < WEP_KEYS; i++) {
  21073. +#ifdef _RTL8187_EXT_PATCH_
  21074. +
  21075. + if (ieee->cryptlist[0]->crypt[i] != NULL){
  21076. +#else
  21077. +
  21078. + if (ieee->crypt[i] != NULL) {
  21079. +#endif
  21080. + if (key_provided)
  21081. + break;
  21082. + ieee80211_crypt_delayed_deinit(
  21083. +#ifdef _RTL8187_EXT_PATCH_
  21084. + ieee, &ieee->cryptlist[0]->crypt[i]);
  21085. +#else
  21086. + ieee, &ieee->crypt[i]);
  21087. +#endif
  21088. + }
  21089. + }
  21090. +
  21091. + if (i == WEP_KEYS) {
  21092. + sec.enabled = 0;
  21093. + sec.level = SEC_LEVEL_0;
  21094. + sec.flags |= SEC_ENABLED | SEC_LEVEL;
  21095. + }
  21096. +
  21097. + goto done;
  21098. + }
  21099. +
  21100. +
  21101. +
  21102. + sec.enabled = 1;
  21103. + sec.flags |= SEC_ENABLED;
  21104. +
  21105. + if (*crypt != NULL && (*crypt)->ops != NULL &&
  21106. + strcmp((*crypt)->ops->name, "WEP") != 0) {
  21107. + /* changing to use WEP; deinit previously used algorithm
  21108. + * on this key */
  21109. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  21110. + }
  21111. +
  21112. + if (*crypt == NULL) {
  21113. + struct ieee80211_crypt_data *new_crypt;
  21114. +
  21115. + /* take WEP into use */
  21116. + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
  21117. + GFP_KERNEL);
  21118. + if (new_crypt == NULL)
  21119. + return -ENOMEM;
  21120. + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
  21121. + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
  21122. + if (!new_crypt->ops) {
  21123. + request_module("ieee80211_crypt_wep");
  21124. + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
  21125. + }
  21126. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
  21127. + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  21128. +#else
  21129. + if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
  21130. +#endif
  21131. + new_crypt->priv = new_crypt->ops->init(key);
  21132. +
  21133. + if (!new_crypt->ops || !new_crypt->priv) {
  21134. + kfree(new_crypt);
  21135. + new_crypt = NULL;
  21136. +
  21137. + printk(KERN_WARNING "%s: could not initialize WEP: "
  21138. + "load module ieee80211_crypt_wep\n",
  21139. + dev->name);
  21140. + return -EOPNOTSUPP;
  21141. + }
  21142. + *crypt = new_crypt;
  21143. + }
  21144. +
  21145. + /* If a new key was provided, set it up */
  21146. + if (erq->length > 0) {
  21147. + len = erq->length <= 5 ? 5 : 13;
  21148. + memcpy(sec.keys[key], keybuf, erq->length);
  21149. + if (len > erq->length)
  21150. + memset(sec.keys[key] + erq->length, 0,
  21151. + len - erq->length);
  21152. + IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
  21153. + key, escape_essid(sec.keys[key], len),
  21154. + erq->length, len);
  21155. + sec.key_sizes[key] = len;
  21156. + (*crypt)->ops->set_key(sec.keys[key], len, NULL,
  21157. + (*crypt)->priv);
  21158. + sec.flags |= (1 << key);
  21159. + /* This ensures a key will be activated if no key is
  21160. + * explicitely set */
  21161. + if (key == sec.active_key)
  21162. + sec.flags |= SEC_ACTIVE_KEY;
  21163. +
  21164. + ieee->tx_keyidx = key; //we need it to support multi_key setting. added by wb 2008_2_22
  21165. + } else {
  21166. + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
  21167. + NULL, (*crypt)->priv);
  21168. + if (len == 0) {
  21169. + /* Set a default key of all 0 */
  21170. + IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
  21171. + key);
  21172. + memset(sec.keys[key], 0, 13);
  21173. + (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
  21174. + (*crypt)->priv);
  21175. + sec.key_sizes[key] = 13;
  21176. + sec.flags |= (1 << key);
  21177. + }
  21178. +
  21179. + /* No key data - just set the default TX key index */
  21180. + if (key_provided) {
  21181. + IEEE80211_DEBUG_WX(
  21182. + "Setting key %d to default Tx key.\n", key);
  21183. + ieee->tx_keyidx = key;
  21184. + sec.active_key = key;
  21185. + sec.flags |= SEC_ACTIVE_KEY;
  21186. + }
  21187. + }
  21188. +#ifdef _RTL8187_EXT_PATCH_
  21189. +#if 0
  21190. +}
  21191. +}
  21192. +#endif
  21193. +#endif
  21194. + done:
  21195. + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
  21196. + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
  21197. + sec.flags |= SEC_AUTH_MODE;
  21198. + IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
  21199. + "OPEN" : "SHARED KEY");
  21200. +
  21201. + /* For now we just support WEP, so only set that security level...
  21202. + * TODO: When WPA is added this is one place that needs to change */
  21203. + sec.flags |= SEC_LEVEL;
  21204. + sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
  21205. +
  21206. + if (ieee->set_security)
  21207. + ieee->set_security(dev, &sec);
  21208. +
  21209. + /* Do not reset port if card is in Managed mode since resetting will
  21210. + * generate new IEEE 802.11 authentication which may end up in looping
  21211. + * with IEEE 802.1X. If your hardware requires a reset after WEP
  21212. + * configuration (for example... Prism2), implement the reset_port in
  21213. + * the callbacks structures used to initialize the 802.11 stack. */
  21214. + if (ieee->reset_on_keychange &&
  21215. + ieee->iw_mode != IW_MODE_INFRA &&
  21216. + ieee->reset_port && ieee->reset_port(dev)) {
  21217. + printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
  21218. + return -EINVAL;
  21219. + }
  21220. + return 0;
  21221. +}
  21222. +
  21223. +int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
  21224. + struct iw_request_info *info,
  21225. + union iwreq_data *wrqu, char *keybuf)
  21226. +{
  21227. + struct iw_point *erq = &(wrqu->encoding);
  21228. + int len, key;
  21229. + struct ieee80211_crypt_data *crypt;
  21230. +
  21231. + IEEE80211_DEBUG_WX("GET_ENCODE\n");
  21232. +
  21233. + if(ieee->iw_mode == IW_MODE_MONITOR)
  21234. + return -1;
  21235. +
  21236. + key = erq->flags & IW_ENCODE_INDEX;
  21237. + if (key) {
  21238. + if (key > WEP_KEYS)
  21239. + return -EINVAL;
  21240. + key--;
  21241. + } else
  21242. + key = ieee->tx_keyidx;
  21243. +#ifdef _RTL8187_EXT_PATCH_
  21244. + crypt = ieee->cryptlist[0]->crypt[key];
  21245. +#else
  21246. + crypt = ieee->crypt[key];
  21247. +#endif
  21248. + erq->flags = key + 1;
  21249. +
  21250. + if (crypt == NULL || crypt->ops == NULL) {
  21251. + erq->length = 0;
  21252. + erq->flags |= IW_ENCODE_DISABLED;
  21253. + return 0;
  21254. + }
  21255. +
  21256. + if (strcmp(crypt->ops->name, "WEP") != 0) {
  21257. + /* only WEP is supported with wireless extensions, so just
  21258. + * report that encryption is used */
  21259. + erq->length = 0;
  21260. + erq->flags |= IW_ENCODE_ENABLED;
  21261. + return 0;
  21262. + }
  21263. +
  21264. + len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
  21265. + erq->length = (len >= 0 ? len : 0);
  21266. +
  21267. + erq->flags |= IW_ENCODE_ENABLED;
  21268. +
  21269. + if (ieee->open_wep)
  21270. + erq->flags |= IW_ENCODE_OPEN;
  21271. + else
  21272. + erq->flags |= IW_ENCODE_RESTRICTED;
  21273. +
  21274. + return 0;
  21275. +}
  21276. +
  21277. +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
  21278. + struct iw_request_info *info,
  21279. + union iwreq_data *wrqu, char *extra)
  21280. +{
  21281. + struct net_device *dev = ieee->dev;
  21282. + struct iw_point *encoding = &wrqu->encoding;
  21283. + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
  21284. + int i, idx, ret = 0;
  21285. + int group_key = 0;
  21286. + const char *alg, *module;
  21287. + struct ieee80211_crypto_ops *ops;
  21288. + struct ieee80211_crypt_data **crypt;
  21289. +
  21290. + struct ieee80211_security sec = {
  21291. + .flags = 0,
  21292. + };
  21293. + //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
  21294. + idx = encoding->flags & IW_ENCODE_INDEX;
  21295. + if (idx) {
  21296. + if (idx < 1 || idx > WEP_KEYS)
  21297. + return -EINVAL;
  21298. + idx--;
  21299. + } else
  21300. + idx = ieee->tx_keyidx;
  21301. +
  21302. + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
  21303. +#ifdef _RTL8187_EXT_PATCH_
  21304. + crypt = &ieee->cryptlist[0]->crypt[idx];
  21305. +#else
  21306. + crypt = &ieee->crypt[idx];
  21307. +#endif
  21308. + group_key = 1;
  21309. + } else {
  21310. + /* some Cisco APs use idx>0 for unicast in dynamic WEP */
  21311. + //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
  21312. + if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
  21313. + return -EINVAL;
  21314. + if (ieee->iw_mode == IW_MODE_INFRA)
  21315. +#ifdef _RTL8187_EXT_PATCH_
  21316. + crypt = &ieee->cryptlist[0]->crypt[idx];
  21317. +#else
  21318. + crypt = &ieee->crypt[idx];
  21319. +#endif
  21320. + else
  21321. + return -EINVAL;
  21322. + }
  21323. +
  21324. + sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
  21325. + if ((encoding->flags & IW_ENCODE_DISABLED) ||
  21326. + ext->alg == IW_ENCODE_ALG_NONE) {
  21327. + if (*crypt)
  21328. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  21329. +
  21330. + for (i = 0; i < WEP_KEYS; i++)
  21331. +#ifdef _RTL8187_EXT_PATCH_
  21332. + if (ieee->cryptlist[0]->crypt[i] != NULL)
  21333. +#else
  21334. + if (ieee->crypt[i] != NULL)
  21335. +#endif
  21336. + break;
  21337. +
  21338. + if (i == WEP_KEYS) {
  21339. + sec.enabled = 0;
  21340. + // sec.encrypt = 0;
  21341. + sec.level = SEC_LEVEL_0;
  21342. + sec.flags |= SEC_LEVEL;
  21343. + }
  21344. + //printk("disabled: flag:%x\n", encoding->flags);
  21345. + goto done;
  21346. + }
  21347. +
  21348. + sec.enabled = 1;
  21349. + // sec.encrypt = 1;
  21350. +#if 0
  21351. + if (group_key ? !ieee->host_mc_decrypt :
  21352. + !(ieee->host_encrypt || ieee->host_decrypt ||
  21353. + ieee->host_encrypt_msdu))
  21354. + goto skip_host_crypt;
  21355. +#endif
  21356. + switch (ext->alg) {
  21357. + case IW_ENCODE_ALG_WEP:
  21358. + alg = "WEP";
  21359. + module = "ieee80211_crypt_wep";
  21360. + break;
  21361. + case IW_ENCODE_ALG_TKIP:
  21362. + alg = "TKIP";
  21363. + module = "ieee80211_crypt_tkip";
  21364. + break;
  21365. + case IW_ENCODE_ALG_CCMP:
  21366. + alg = "CCMP";
  21367. + module = "ieee80211_crypt_ccmp";
  21368. + break;
  21369. + default:
  21370. + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
  21371. + dev->name, ext->alg);
  21372. + ret = -EINVAL;
  21373. + goto done;
  21374. + }
  21375. + printk("alg name:%s\n",alg);
  21376. +
  21377. + ops = ieee80211_get_crypto_ops(alg);
  21378. + if (ops == NULL) {
  21379. + request_module(module);
  21380. + ops = ieee80211_get_crypto_ops(alg);
  21381. + }
  21382. + if (ops == NULL) {
  21383. + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
  21384. + dev->name, ext->alg);
  21385. + printk("========>unknown crypto alg %d\n", ext->alg);
  21386. + ret = -EINVAL;
  21387. + goto done;
  21388. + }
  21389. +
  21390. + if (*crypt == NULL || (*crypt)->ops != ops) {
  21391. + struct ieee80211_crypt_data *new_crypt;
  21392. +
  21393. + ieee80211_crypt_delayed_deinit(ieee, crypt);
  21394. +
  21395. + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
  21396. + if (new_crypt == NULL) {
  21397. + ret = -ENOMEM;
  21398. + goto done;
  21399. + }
  21400. + new_crypt->ops = ops;
  21401. + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
  21402. + new_crypt->priv = new_crypt->ops->init(idx);
  21403. + if (new_crypt->priv == NULL) {
  21404. + kfree(new_crypt);
  21405. + ret = -EINVAL;
  21406. + goto done;
  21407. + }
  21408. + *crypt = new_crypt;
  21409. +
  21410. + }
  21411. + //I need to deinit other crypt here in mesh mode instead deinit them while use them to tx&rx.
  21412. +#ifdef _RTL8187_EXT_PATCH_
  21413. + if (ieee->iw_mode == ieee->iw_ext_mode)
  21414. + {
  21415. + int j;
  21416. + for (j=1; j<MAX_MP; j++)
  21417. + {
  21418. + struct ieee80211_crypt_data ** crypttmp = &ieee->cryptlist[j]->crypt[idx];
  21419. + if (*crypttmp == NULL)
  21420. + break;
  21421. + if (*crypttmp && (*crypttmp)->ops != ops)
  21422. + ieee80211_crypt_delayed_deinit(ieee, crypttmp);
  21423. + }
  21424. + }
  21425. +#endif
  21426. + if (ext->key_len > 0 && (*crypt)->ops->set_key &&
  21427. + (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
  21428. + (*crypt)->priv) < 0) {
  21429. + IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
  21430. + printk("key setting failed\n");
  21431. + ret = -EINVAL;
  21432. + goto done;
  21433. + }
  21434. +#if 1
  21435. +// skip_host_crypt:
  21436. + //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
  21437. + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
  21438. + ieee->tx_keyidx = idx;
  21439. + sec.active_key = idx;
  21440. + sec.flags |= SEC_ACTIVE_KEY;
  21441. + }
  21442. +
  21443. + if (ext->alg != IW_ENCODE_ALG_NONE) {
  21444. + memcpy(sec.keys[idx], ext->key, ext->key_len);
  21445. + sec.key_sizes[idx] = ext->key_len;
  21446. + sec.flags |= (1 << idx);
  21447. + if (ext->alg == IW_ENCODE_ALG_WEP) {
  21448. + // sec.encode_alg[idx] = SEC_ALG_WEP;
  21449. + sec.flags |= SEC_LEVEL;
  21450. + sec.level = SEC_LEVEL_1;
  21451. + } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
  21452. + // sec.encode_alg[idx] = SEC_ALG_TKIP;
  21453. + sec.flags |= SEC_LEVEL;
  21454. + sec.level = SEC_LEVEL_2;
  21455. + } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
  21456. + // sec.encode_alg[idx] = SEC_ALG_CCMP;
  21457. + sec.flags |= SEC_LEVEL;
  21458. + sec.level = SEC_LEVEL_3;
  21459. + }
  21460. + /* Don't set sec level for group keys. */
  21461. + if (group_key)
  21462. + sec.flags &= ~SEC_LEVEL;
  21463. + }
  21464. +#endif
  21465. +done:
  21466. + if (ieee->set_security)
  21467. + ieee->set_security(ieee->dev, &sec);
  21468. +
  21469. + if (ieee->reset_on_keychange &&
  21470. + ieee->iw_mode != IW_MODE_INFRA &&
  21471. + ieee->reset_port && ieee->reset_port(dev)) {
  21472. + IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
  21473. + return -EINVAL;
  21474. + }
  21475. +
  21476. + return ret;
  21477. +}
  21478. +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
  21479. + struct iw_request_info *info,
  21480. + union iwreq_data *wrqu, char *extra)
  21481. +{
  21482. + struct iw_mlme *mlme = (struct iw_mlme *) extra;
  21483. +// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd);
  21484. +#if 1
  21485. + switch (mlme->cmd) {
  21486. + case IW_MLME_DEAUTH:
  21487. + case IW_MLME_DISASSOC:
  21488. + // printk("disassoc now\n");
  21489. + ieee80211_disassociate(ieee);
  21490. + break;
  21491. + default:
  21492. + return -EOPNOTSUPP;
  21493. + }
  21494. +#endif
  21495. + return 0;
  21496. +}
  21497. +
  21498. +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
  21499. + struct iw_request_info *info,
  21500. + struct iw_param *data, char *extra)
  21501. +{
  21502. +/*
  21503. + struct ieee80211_security sec = {
  21504. + .flags = SEC_AUTH_MODE,
  21505. + }
  21506. +*/
  21507. + //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
  21508. + switch (data->flags & IW_AUTH_INDEX) {
  21509. + case IW_AUTH_WPA_VERSION:
  21510. + /*need to support wpa2 here*/
  21511. + //printk("wpa version:%x\n", data->value);
  21512. + break;
  21513. + case IW_AUTH_CIPHER_PAIRWISE:
  21514. + case IW_AUTH_CIPHER_GROUP:
  21515. + case IW_AUTH_KEY_MGMT:
  21516. + /*
  21517. + * * Host AP driver does not use these parameters and allows
  21518. + * * wpa_supplicant to control them internally.
  21519. + * */
  21520. + break;
  21521. + case IW_AUTH_TKIP_COUNTERMEASURES:
  21522. + ieee->tkip_countermeasures = data->value;
  21523. + break;
  21524. + case IW_AUTH_DROP_UNENCRYPTED:
  21525. + ieee->drop_unencrypted = data->value;
  21526. + break;
  21527. +
  21528. + case IW_AUTH_80211_AUTH_ALG:
  21529. + ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
  21530. + //printk("open_wep:%d\n", ieee->open_wep);
  21531. + break;
  21532. +
  21533. +#if 1
  21534. + case IW_AUTH_WPA_ENABLED:
  21535. + ieee->wpa_enabled = (data->value)?1:0;
  21536. + //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
  21537. + break;
  21538. +
  21539. +#endif
  21540. + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
  21541. + ieee->ieee802_1x = data->value;
  21542. + break;
  21543. + case IW_AUTH_PRIVACY_INVOKED:
  21544. + ieee->privacy_invoked = data->value;
  21545. + break;
  21546. + default:
  21547. + return -EOPNOTSUPP;
  21548. + }
  21549. + return 0;
  21550. +}
  21551. +
  21552. +#if 1
  21553. +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
  21554. +{
  21555. +#if 0
  21556. + printk("====>%s()\n", __FUNCTION__);
  21557. + {
  21558. + int i;
  21559. + for (i=0; i<len; i++)
  21560. + printk("%2x ", ie[i]&0xff);
  21561. + printk("\n");
  21562. + }
  21563. +#endif
  21564. + u8 *buf = NULL;
  21565. +
  21566. + if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
  21567. + {
  21568. + // printk("return error out, len:%d\n", len);
  21569. + return -EINVAL;
  21570. + }
  21571. + if (len)
  21572. + {
  21573. +
  21574. + if (len != ie[1]+2) printk("len:%d, ie:%d\n", (int)len, ie[1]);
  21575. + buf = kmalloc(len, GFP_KERNEL);
  21576. + if (buf == NULL)
  21577. + return -ENOMEM;
  21578. + memcpy(buf, ie, len);
  21579. + kfree(ieee->wpa_ie);
  21580. + ieee->wpa_ie = buf;
  21581. + ieee->wpa_ie_len = len;
  21582. + }
  21583. + else{
  21584. + if (ieee->wpa_ie)
  21585. + kfree(ieee->wpa_ie);
  21586. + ieee->wpa_ie = NULL;
  21587. + ieee->wpa_ie_len = 0;
  21588. + }
  21589. +// printk("<=====out %s()\n", __FUNCTION__);
  21590. +
  21591. + return 0;
  21592. +
  21593. +}
  21594. +#endif
  21595. +
  21596. +EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
  21597. +EXPORT_SYMBOL(ieee80211_wx_set_mlme);
  21598. +EXPORT_SYMBOL(ieee80211_wx_set_auth);
  21599. +EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
  21600. +EXPORT_SYMBOL(ieee80211_wx_get_scan);
  21601. +EXPORT_SYMBOL(ieee80211_wx_set_encode);
  21602. +EXPORT_SYMBOL(ieee80211_wx_get_encode);
  21603. +#if 0
  21604. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan);
  21605. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode);
  21606. +EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode);
  21607. +#endif
  21608. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/internal.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/internal.h
  21609. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/internal.h 1970-01-01 01:00:00.000000000 +0100
  21610. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/internal.h 2010-05-27 18:12:39.532222207 +0200
  21611. @@ -0,0 +1,115 @@
  21612. +/*
  21613. + * Cryptographic API.
  21614. + *
  21615. + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  21616. + *
  21617. + * This program is free software; you can redistribute it and/or modify it
  21618. + * under the terms of the GNU General Public License as published by the Free
  21619. + * Software Foundation; either version 2 of the License, or (at your option)
  21620. + * any later version.
  21621. + *
  21622. + */
  21623. +#ifndef _CRYPTO_INTERNAL_H
  21624. +#define _CRYPTO_INTERNAL_H
  21625. +
  21626. +
  21627. +//#include <linux/crypto.h>
  21628. +#include "rtl_crypto.h"
  21629. +#include <linux/mm.h>
  21630. +#include <linux/highmem.h>
  21631. +#include <linux/init.h>
  21632. +#include <asm/hardirq.h>
  21633. +#include <asm/softirq.h>
  21634. +#include <asm/kmap_types.h>
  21635. +
  21636. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
  21637. +#define list_for_each_entry(pos, head, member) \
  21638. + for (pos = list_entry((head)->next, typeof(*pos), member), \
  21639. + prefetch(pos->member.next); \
  21640. + &pos->member != (head); \
  21641. + pos = list_entry(pos->member.next, typeof(*pos), member), \
  21642. + prefetch(pos->member.next))
  21643. +
  21644. +static inline void cond_resched(void)
  21645. +{
  21646. + if (need_resched()) {
  21647. + set_current_state(TASK_RUNNING);
  21648. + schedule();
  21649. + }
  21650. +}
  21651. +#endif
  21652. +
  21653. +extern enum km_type crypto_km_types[];
  21654. +
  21655. +static inline enum km_type crypto_kmap_type(int out)
  21656. +{
  21657. + return crypto_km_types[(in_softirq() ? 2 : 0) + out];
  21658. +}
  21659. +
  21660. +static inline void *crypto_kmap(struct page *page, int out)
  21661. +{
  21662. + return kmap_atomic(page, crypto_kmap_type(out));
  21663. +}
  21664. +
  21665. +static inline void crypto_kunmap(void *vaddr, int out)
  21666. +{
  21667. + kunmap_atomic(vaddr, crypto_kmap_type(out));
  21668. +}
  21669. +
  21670. +static inline void crypto_yield(struct crypto_tfm *tfm)
  21671. +{
  21672. + if (!in_softirq())
  21673. + cond_resched();
  21674. +}
  21675. +
  21676. +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
  21677. +{
  21678. + return (void *)&tfm[1];
  21679. +}
  21680. +
  21681. +struct crypto_alg *crypto_alg_lookup(const char *name);
  21682. +
  21683. +#ifdef CONFIG_KMOD
  21684. +void crypto_alg_autoload(const char *name);
  21685. +struct crypto_alg *crypto_alg_mod_lookup(const char *name);
  21686. +#else
  21687. +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
  21688. +{
  21689. + return crypto_alg_lookup(name);
  21690. +}
  21691. +#endif
  21692. +
  21693. +#ifdef CONFIG_CRYPTO_HMAC
  21694. +int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
  21695. +void crypto_free_hmac_block(struct crypto_tfm *tfm);
  21696. +#else
  21697. +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
  21698. +{
  21699. + return 0;
  21700. +}
  21701. +
  21702. +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
  21703. +{ }
  21704. +#endif
  21705. +
  21706. +#ifdef CONFIG_PROC_FS
  21707. +void __init crypto_init_proc(void);
  21708. +#else
  21709. +static inline void crypto_init_proc(void)
  21710. +{ }
  21711. +#endif
  21712. +
  21713. +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
  21714. +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
  21715. +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
  21716. +
  21717. +int crypto_init_digest_ops(struct crypto_tfm *tfm);
  21718. +int crypto_init_cipher_ops(struct crypto_tfm *tfm);
  21719. +int crypto_init_compress_ops(struct crypto_tfm *tfm);
  21720. +
  21721. +void crypto_exit_digest_ops(struct crypto_tfm *tfm);
  21722. +void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
  21723. +void crypto_exit_compress_ops(struct crypto_tfm *tfm);
  21724. +
  21725. +#endif /* _CRYPTO_INTERNAL_H */
  21726. +
  21727. 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
  21728. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 1970-01-01 01:00:00.000000000 +0100
  21729. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/kmap_types.h 2010-05-27 18:12:39.532222207 +0200
  21730. @@ -0,0 +1,20 @@
  21731. +#ifndef __KMAP_TYPES_H
  21732. +
  21733. +#define __KMAP_TYPES_H
  21734. +
  21735. +
  21736. +enum km_type {
  21737. + KM_BOUNCE_READ,
  21738. + KM_SKB_SUNRPC_DATA,
  21739. + KM_SKB_DATA_SOFTIRQ,
  21740. + KM_USER0,
  21741. + KM_USER1,
  21742. + KM_BH_IRQ,
  21743. + KM_SOFTIRQ0,
  21744. + KM_SOFTIRQ1,
  21745. + KM_TYPE_NR
  21746. +};
  21747. +
  21748. +#define _ASM_KMAP_TYPES_H
  21749. +
  21750. +#endif
  21751. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/readme linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/readme
  21752. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/readme 1970-01-01 01:00:00.000000000 +0100
  21753. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/readme 2010-05-27 18:12:39.532222207 +0200
  21754. @@ -0,0 +1,162 @@
  21755. +What this layer should do
  21756. +
  21757. +- It mantain the old mechanism as alternative, so the
  21758. + ipw2100 driver works with really few changes.
  21759. +- Encapsulate / Decapsulate ieee80211 packet
  21760. +- Handle fragmentation
  21761. +- Optionally provide an alterantive mechanism for netif queue stop/wake,
  21762. + so that the ieee80211 layer will pass one fragment per time instead of
  21763. + one txb struct per time. so the driver can stop the queue in the middle
  21764. + of a packet.
  21765. +- Provide two different TX interfaces for cards that can handle management
  21766. + frames on one HW queue, and data on another, and for cards that have only
  21767. + one HW queue (the latter untested and very, very rough).
  21768. +- Optionally provide the logic for handling IBSS/MASTER/MONITOR/BSS modes
  21769. + and for the channel, essid and wap get/set wireless extension requests.
  21770. + so that the driver has only to change channel when the ieee stack tell it.
  21771. +- Optionally provide a scanning mechanism so that the driver has not to
  21772. + worry about this, just implement the set channel calback and pass
  21773. + frames to the upper layer
  21774. +- Optionally provide the bss client protocol handshaking (just with open
  21775. + authentication)
  21776. +- Optionally provide the probe request send mechanism
  21777. +- Optionally provide the bss master mode logic to handle association
  21778. + protocol (only open authentication) and probe responses.
  21779. +- SW wep encryption (with open authentication)
  21780. +- It collects some stats
  21781. +- It provides beacons to the card when it ask for them
  21782. +
  21783. +What this layer doesn't do (yet)
  21784. +- Perform shared authentication
  21785. +- Have full support for master mode (the AP should loop back in the air
  21786. + frames from an associated client to another. This could be done easily
  21787. + with few lines of code, and it is done in my previous version of the
  21788. + stach, but a table of association must be keept and a disassociation
  21789. + policy must be decided and implemented.
  21790. +- Handle cleanly the full ieee 802.11 protocol. In AP mode it never
  21791. + disassociate clients, and it is really prone to always allow access.
  21792. + In bss client mode it is a bit rough with AP deauth and disassoc requests.
  21793. +- It has not any entry point to view the collected stats.
  21794. +- Altought it takes care of the card supported rates in the management frame
  21795. + it sends, support for rate changing on TXed packet is not complete.
  21796. +- Give up once associated in bss client mode (it never detect a
  21797. + signal loss condition to disassociate and restart scanning)
  21798. +- Provide a mechanism for enabling the TX in monitor mode, so
  21799. + userspace programs can TX raw packets.
  21800. +- Provide a mechanism for cards that need that the SW take care of beacon
  21801. + TX completely, in sense that the SW has to enqueue by itself beacons
  21802. + to the card so it TX them (if any...)
  21803. +APIs
  21804. +
  21805. +Callback functions in the original stack has been mantained.
  21806. +following has been added (from ieee80211.h)
  21807. +
  21808. + /* Softmac-generated frames (mamagement) are TXed via this
  21809. + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
  21810. + * not set. As some cards may have different HW queues that
  21811. + * one might want to use for data and management frames
  21812. + * the option to have two callbacks might be useful.
  21813. + * This fucntion can't sleep.
  21814. + */
  21815. + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
  21816. + struct net_device *dev);
  21817. +
  21818. + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
  21819. + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
  21820. + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
  21821. + * then also management frames are sent via this callback.
  21822. + * This function can't sleep.
  21823. + */
  21824. + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
  21825. + struct net_device *dev);
  21826. +
  21827. + /* stops the HW queue for DATA frames. Useful to avoid
  21828. + * waste time to TX data frame when we are reassociating
  21829. + * This function can sleep.
  21830. + */
  21831. + void (*data_hard_stop)(struct net_device *dev);
  21832. +
  21833. + /* OK this is complementar to data_poll_hard_stop */
  21834. + void (*data_hard_resume)(struct net_device *dev);
  21835. +
  21836. + /* ask to the driver to retune the radio .
  21837. + * This function can sleep. the driver should ensure
  21838. + * the radio has been swithced before return.
  21839. + */
  21840. + void (*set_chan)(struct net_device *dev,short ch);
  21841. +
  21842. + /* These are not used if the ieee stack takes care of
  21843. + * scanning (IEEE_SOFTMAC_SCAN feature set).
  21844. + * In this case only the set_chan is used.
  21845. + *
  21846. + * The syncro version is similar to the start_scan but
  21847. + * does not return until all channels has been scanned.
  21848. + * this is called in user context and should sleep,
  21849. + * it is called in a work_queue when swithcing to ad-hoc mode
  21850. + * or in behalf of iwlist scan when the card is associated
  21851. + * and root user ask for a scan.
  21852. + * the fucntion stop_scan should stop both the syncro and
  21853. + * background scanning and can sleep.
  21854. + * The fucntion start_scan should initiate the background
  21855. + * scanning and can't sleep.
  21856. + */
  21857. + void (*scan_syncro)(struct net_device *dev);
  21858. + void (*start_scan)(struct net_device *dev);
  21859. + void (*stop_scan)(struct net_device *dev);
  21860. +
  21861. + /* indicate the driver that the link state is changed
  21862. + * for example it may indicate the card is associated now.
  21863. + * Driver might be interested in this to apply RX filter
  21864. + * rules or simply light the LINK led
  21865. + */
  21866. + void (*link_change)(struct net_device *dev);
  21867. +
  21868. +Functions hard_data_[resume/stop] are optional and should not be used
  21869. +if the driver decides to uses data+management frames enqueue in a
  21870. +single HQ queue (thus using just the softmac_hard_data_start_xmit
  21871. +callback).
  21872. +
  21873. +Function that the driver can use are:
  21874. +
  21875. +ieee80211_get_beacon - this is called by the driver when
  21876. + the HW needs a beacon.
  21877. +ieee80211_softmac_start_protocol - this should normally be called in the
  21878. + driver open function
  21879. +ieee80211_softmac_stop_protocol - the opposite of the above
  21880. +ieee80211_wake_queue - this is similar to netif_wake_queue
  21881. +ieee80211_reset_queue - this throw away fragments pending(if any)
  21882. +ieee80211_stop_queue - this is similar to netif_stop_queue
  21883. +
  21884. +
  21885. +known BUGS:
  21886. +- When performing syncro scan (possiblily when swithcing to ad-hoc mode
  21887. + and when running iwlist scan when associated) there is still an odd
  21888. + behaviour.. I have not looked in this more accurately (yet).
  21889. +
  21890. +locking:
  21891. +locking is done by means of three structures.
  21892. +1- ieee->lock (by means of spin_[un]lock_irq[save/restore]
  21893. +2- ieee->wx_sem
  21894. +3- ieee->scan_sem
  21895. +
  21896. +the lock 1 is what protect most of the critical sections in the ieee stack.
  21897. +the lock 2 is used to avoid that more than one of the SET wireless extension
  21898. +handlers (as well as start/stop protocol function) are running at the same time.
  21899. +the lock 1 is used when we need to modify or read the shared data in the wx handlers.
  21900. +In other words the lock 2 will prevent one SET action will run across another SET
  21901. +action (by make sleep the 2nd one) but allow GET actions, while the lock 1
  21902. +make atomic those little shared data access in both GET and SET operation.
  21903. +So get operation will be never be delayed really: they will never sleep..
  21904. +Furthermore in the top of some SET operations a flag is set before acquiring
  21905. +the lock. This is an help to make the previous running SET operation to
  21906. +finish faster if needed (just in case the second one will totally undo the
  21907. +first, so there is not need to complete the 1st really.. ).
  21908. +The background scanning mechaninsm is protected by the lock 1 except for the
  21909. +workqueue. this wq is here just to let the set_chan callback sleep (I thinked it
  21910. +might be appreciated by USB network card driver developer). In this case the lock 3
  21911. +take its turn.
  21912. +Thus the stop function needs both the locks.
  21913. +Funny in the syncro scan the lock 2 play its role (as both the syncro_scan
  21914. +function and the stop scan function are called with this semaphore held).
  21915. +
  21916. +
  21917. 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
  21918. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 1970-01-01 01:00:00.000000000 +0100
  21919. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/rtl8187_mesh.h 2010-05-27 18:12:39.532222207 +0200
  21920. @@ -0,0 +1,282 @@
  21921. +#ifndef _RTL8187_MESH_H_
  21922. +#define _RTL8187_MESH_H_
  21923. +
  21924. +#include "msh_class.h" // struct mshclass
  21925. +#include "mesh.h" // struct MESH-Neighbor-Entry
  21926. +#include "ieee80211.h" // struct ieee80211-network
  21927. +#include "mesh_8185_util.h" // DOT11-QUEUE
  21928. +#include "hash_table.h" // hash-table
  21929. +#include "8185s_pathsel.h"
  21930. +#include <linux/list.h>
  21931. +
  21932. +#define GET_MESH_PRIV(x) ((struct mshclass_priv *)(x->priv))
  21933. +
  21934. +struct ieee80211_hdr_mesh {
  21935. + u16 frame_ctl;
  21936. + u16 duration_id;
  21937. + u8 addr1[ETH_ALEN];
  21938. + u8 addr2[ETH_ALEN];
  21939. + u8 addr3[ETH_ALEN];
  21940. + u16 seq_ctl;
  21941. + u8 addr4[ETH_ALEN];
  21942. + unsigned char mesh_flag;
  21943. + INT8 TTL;
  21944. + UINT16 segNum;
  21945. + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
  21946. + unsigned char SrcMACAddr[ETH_ALEN];
  21947. +} __attribute__ ((packed));
  21948. +
  21949. +struct myMeshIDNode {
  21950. + struct list_head list;
  21951. + char id[MESH_ID_LEN+1];
  21952. + short popEN;
  21953. + char tried;
  21954. + unsigned long expire;
  21955. + struct ieee80211_network mesh_network;
  21956. +};
  21957. +
  21958. +struct ieee80211_hdr_mesh_QOS {
  21959. + u16 frame_ctl;
  21960. + u16 duration_id;
  21961. + u8 addr1[ETH_ALEN];
  21962. + u8 addr2[ETH_ALEN];
  21963. + u8 addr3[ETH_ALEN];
  21964. + u16 seq_ctl;
  21965. + u8 addr4[ETH_ALEN];
  21966. + u16 QOS_ctl;
  21967. + unsigned char mesh_flag;
  21968. + INT8 TTL;
  21969. + UINT16 segNum;
  21970. + unsigned char DestMACAddr[ETH_ALEN]; // modify for 6 address
  21971. + unsigned char SrcMACAddr[ETH_ALEN];
  21972. +} __attribute__ ((packed));
  21973. +
  21974. +
  21975. +struct mesh_PeerEntry {
  21976. + // based on 8185ag.h
  21977. + struct list_head hash_list;
  21978. + unsigned int used; ///< used == TRUE => has been allocated, \n used == FALSE => can be allocated
  21979. + unsigned char hwaddr[MACADDRLEN]; ///< hardware address
  21980. +
  21981. + // struct list_head mesh_unEstablish_ptr; // 尚未(或從已連線 -> 未連線) 之 MP list
  21982. + struct list_head mesh_mp_ptr; // MP list
  21983. +
  21984. + /*mesh_neighbor:
  21985. + * Inited by "Neighbor Discovering"
  21986. + * cleaned by "Disassociation" or "Expired"
  21987. + */
  21988. + struct MESH_Neighbor_Entry mesh_neighbor_TBL;
  21989. +
  21990. + struct ieee80211_network * pstat; // a backward pointer
  21991. +
  21992. + // 802.11 seq checking
  21993. + u16 last_rxseq; /* rx seq previous per-tid */
  21994. + u16 last_rxfrag;/* tx frag previous per-tid */
  21995. + unsigned long last_time;
  21996. + //
  21997. +};
  21998. +
  21999. +
  22000. +struct mshclass_priv {
  22001. +
  22002. + struct mesh_PeerEntry *meshEntries; // 1-to-1 for priv->ieee80211->networks
  22003. +
  22004. + spinlock_t lock_stainfo; // lock for accessing the data structure of stat info
  22005. + spinlock_t lock_queue; // lock for DOT11_EnQueue2/DOT11_DeQueue2/enque/dequeue
  22006. + spinlock_t lock_Rreq; // lock for rreq_retry. Some function like aodv_expire/tx use lock_queue simultaneously
  22007. +// spinlock_t lock_meshlist;
  22008. +
  22009. + // struct _DOT11_QUEUE *pevent_queue; ///< 802.11 QUEUE結構
  22010. + // struct hash_table *pathsel_table; // GANTOE
  22011. + //tsananiu
  22012. + struct _DOT11_QUEUE *pathsel_queue; ///< 802.11 QUEUE結構
  22013. +
  22014. + //tsananiu end
  22015. +
  22016. + //add by shlu 20070518
  22017. + unsigned char RreqMAC[AODV_RREQ_TABLE_SIZE][6];
  22018. + unsigned int RreqBegin;
  22019. + unsigned int RreqEnd;
  22020. +
  22021. +#if defined(MESH_ROLE_ROOT) || defined(MESH_ROLE_PORTAL)
  22022. +#define MAX_SZ_BAD_MAC 3
  22023. + unsigned char BadMac[MAX_SZ_BAD_MAC][MACADDRLEN];
  22024. + int idx_BadMac;
  22025. +#endif // MESH_ROLE_ROOT || MESH_ROLE_PORTAL
  22026. +
  22027. + //-------------
  22028. + unsigned char root_mac[MACADDRLEN];
  22029. + struct mesh_info dot11MeshInfo; // extrated from wifi_mib (ieee802_mib.h)
  22030. + struct hash_table *proxy_table, *mesh_rreq_retry_queue; //GANTOE //GANTOE
  22031. + struct hash_table *pathsel_table; // add by chuangch 2007.09.13
  22032. + // add by Jason
  22033. + struct mpp_tb *pann_mpp_tb;
  22034. +
  22035. + struct timer_list expire_timer; // 1sec timer
  22036. +
  22037. + struct timer_list beacon_timer; // 1sec timer
  22038. + struct list_head stat_hash[MAX_NETWORK_COUNT]; // sta_info hash table (aid_obj)
  22039. +
  22040. + struct list_head meshList[MAX_CHANNEL_NUMBER];
  22041. + int scanMode;
  22042. +
  22043. + struct {
  22044. + struct ieee80211_network *pstat;
  22045. + unsigned char hwaddr[MACADDRLEN];
  22046. + } stainfo_cache;
  22047. +
  22048. + // The following elements are used by 802.11s.
  22049. + // For copyright-pretection, we use an independent (binary) module.
  22050. + // Note that it can also be put either under r8180_priv or ieee80211_device. The adv of put under
  22051. + // r8180_priv is to get "higher encapsulation". On the other hand, r8180_priv was originally designed
  22052. + // for "hardward specific."
  22053. + char mesh_mac_filter_allow[8][13];
  22054. + char mesh_mac_filter_deny[8][13];
  22055. +
  22056. + struct MESH_Share meshare; // mesh share data
  22057. +
  22058. + struct {
  22059. +
  22060. + int prev_iw_mode; // Save this->iw_mode for r8180_wx->r8180_wx_enable_mesh. No init requirement
  22061. +
  22062. + struct MESH_Profile mesh_profile; // contains MESHID
  22063. +
  22064. + struct mesh_info dot11MeshInfo; // contains meshMaxAssocNum
  22065. +
  22066. + struct net_device_stats mesh_stats;
  22067. +
  22068. + UINT8 mesh_Version; // 使用的版本
  22069. + // WLAN Mesh Capability
  22070. + INT16 mesh_PeerCAP_cap; // peer capability-Cap number (有號數)
  22071. + UINT8 mesh_PeerCAP_flags; // peer capability-flags
  22072. + UINT8 mesh_PowerSaveCAP; // Power Save capability
  22073. + UINT8 mesh_SyncCAP; // Synchronization capability
  22074. + UINT8 mesh_MDA_CAP; // MDA capability
  22075. + UINT32 mesh_ChannelPrecedence; // Channel Precedence
  22076. +
  22077. + // neighbor -> candidate neighbor, if mesh_available_peerlink > 0, page 56, D0.02
  22078. + UINT8 mesh_AvailablePeerLink; // 此是否有需要?(因它等同於 mesh_PeerCAP)=>暫 時保 留
  22079. +
  22080. + UINT8 mesh_HeaderFlags; // mesh header 內的 mesh flags field
  22081. +
  22082. + // MKD domain element [MKDDIE]
  22083. + UINT8 mesh_MKD_DomainID[6];
  22084. + UINT8 mesh_MKDDIE_SecurityConfiguration;
  22085. +
  22086. + // EMSA Handshake element [EMSAIE]
  22087. + UINT8 mesh_EMSAIE_ANonce[32];
  22088. + UINT8 mesh_EMSAIE_SNonce[32];
  22089. + UINT8 mesh_EMSAIE_MA_ID[6];
  22090. + UINT16 mesh_EMSAIE_MIC_Control;
  22091. + UINT8 mesh_EMSAIE_MIC[16];
  22092. +
  22093. + struct timer_list mesh_peer_link_timer; ///< 對尚未連 線(與連線退至未連線) MP mesh_unEstablish_hdr 作 peer link time out
  22094. +
  22095. +// struct timer_list mesh_beacon_timer;
  22096. + // mesh_unEstablish_hdr:
  22097. + // It is a list structure, only stores unEstablish (or Establish -> unEstablish [MP_HOLDING])MP entry
  22098. + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
  22099. + // and removed by successful "Peer link setup" or "Expired"
  22100. + struct list_head mesh_unEstablish_hdr;
  22101. +
  22102. + // mesh_mp_hdr:
  22103. + // It is a list of MP/MAP/MPP who has already passed "Peer link setup"
  22104. + // Each entry is a pointer pointing to an entry in "stat_info->mesh_mp_ptr"
  22105. + // Every entry is inserted by "successful peer link setup"
  22106. + // and removed by "Expired"
  22107. + struct list_head mesh_mp_hdr;
  22108. +
  22109. + } mesh;
  22110. +
  22111. + int iCurChannel; // remember the working channel
  22112. +};
  22113. +
  22114. +// Stanley, 04/23/07
  22115. +// The following mode is used by ieee80211_device->iw_mode
  22116. +// Although it is better to put the definition under linux/wireless.h (or wireless_copy.h), it is a system file
  22117. +// that we shouldn't modify directly.
  22118. +#define IW_MODE_MESH 11 /* 802.11s mesh mode */
  22119. +
  22120. +// Default MESHID
  22121. +#define IEEE80211S_DEFAULT_MESHID "802.11s"
  22122. +
  22123. +// callback for 802.11s
  22124. +extern short rtl8187_patch_ieee80211_probe_req_1 (struct ieee80211_device *ieee);
  22125. +extern u8* rtl8187_patch_ieee80211_probe_req_2 (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag);
  22126. +
  22127. +// wx
  22128. +extern int rtl8187_patch_r8180_wx_get_meshinfo(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22129. +extern int rtl8187_patch_r8180_wx_enable_mesh(struct net_device *dev);
  22130. +extern int rtl8187_patch_r8180_wx_disable_mesh(struct net_device *dev);
  22131. +extern int rtl8187_patch_r8180_wx_wx_set_meshID(struct net_device *dev, char *ext,unsigned char channel);
  22132. +extern void rtl8187_patch_r8180_wx_set_channel (struct ieee80211_device *ieee, int ch);
  22133. +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);
  22134. +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);
  22135. +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);
  22136. +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);
  22137. +extern int rtl8187_patch_r8180_wx_get_mac_allow(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22138. +extern int rtl8187_patch_r8180_wx_get_mac_deny(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22139. +
  22140. +extern int rtl8187_patch_r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22141. +extern int rtl8187_patch_r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22142. +extern int rtl8187_patch_r8180_wx_get_selected_mesh(struct net_device *dev, int en, char *cho, char* id);
  22143. +//by amy for networkmanager UI
  22144. +extern int rtl8187_patch_r8180_wx_get_selected_mesh_channel(struct net_device *dev, char *extmeshid, char *cho);
  22145. +//by amy for networkmanager UI
  22146. +// osdep
  22147. +extern int rtl8187_patch_ieee80211_start_protocol (struct ieee80211_device *ieee);
  22148. +extern u8 rtl8187_patch_rtl8180_up(struct mshclass *priv);
  22149. +extern void rtl8187_patch_ieee80211_stop_protocol(struct ieee80211_device *ieee);
  22150. +
  22151. +// issue_assocreq_MP
  22152. +extern void rtl8187_patch_ieee80211_association_req_1 (struct ieee80211_assoc_request_frame *hdr);
  22153. +extern u8* rtl8187_patch_ieee80211_association_req_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
  22154. +
  22155. +// OnAssocReq_MP
  22156. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_req (struct ieee80211_device *ieee, struct sk_buff *skb);
  22157. +
  22158. +// issue_assocrsp_MP
  22159. +extern void rtl8187_patch_ieee80211_assoc_resp_by_net_1 (struct ieee80211_assoc_response_frame *assoc);
  22160. +u8* rtl8187_patch_ieee80211_assoc_resp_by_net_2 (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
  22161. +
  22162. +// OnAssocRsp_MP
  22163. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_assoc_rsp (struct ieee80211_device *ieee, struct sk_buff *skb);
  22164. +
  22165. +
  22166. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_auth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  22167. +extern int rtl8187_patch_ieee80211_rx_frame_softmac_on_deauth(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  22168. +extern unsigned int rtl8187_patch_ieee80211_process_probe_response_1( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
  22169. +extern void rtl8187_patch_ieee80211_rx_mgt_on_probe_req( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
  22170. +extern void rtl8187_patch_ieee80211_rx_mgt_update_expire ( struct ieee80211_device *ieee, struct sk_buff *skb);
  22171. +
  22172. +// set channel
  22173. +extern int rtl8187_patch_ieee80211_ext_stop_scan_wq_set_channel (struct ieee80211_device *ieee);
  22174. +
  22175. +// on rx (rx isr)
  22176. +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);
  22177. +
  22178. +// r8187_core
  22179. +// handle ioctl
  22180. +extern int rtl8187_patch_rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
  22181. +// create proc
  22182. +extern void rtl8187_patch_create_proc(struct r8180_priv *priv);
  22183. +extern void rtl8187_patch_remove_proc(struct r8180_priv *priv);
  22184. +
  22185. +// tx, xmit
  22186. +// locked by ieee->lock. Call ieee80211_softmac_xmit afterward
  22187. +extern struct ieee80211_txb* rtl8187_patch_ieee80211_xmit (struct sk_buff *skb, struct net_device *dev);
  22188. +
  22189. +// given a skb, output header's length
  22190. +extern int rtl8187_patch_ieee80211_rx_frame_get_hdrlen (struct ieee80211_device *ieee, struct sk_buff *skb);
  22191. +
  22192. +// check the frame control field, return 0: not accept, 1: accept
  22193. +extern int rtl8187_patch_ieee80211_rx_is_valid_framectl (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
  22194. +
  22195. +// process_dataframe
  22196. +extern int rtl8187_patch_ieee80211_rx_process_dataframe (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  22197. +
  22198. +extern int rtl8187_patch_is_duplicate_packet (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
  22199. +
  22200. +extern int rtl8187_patch_ieee80211_softmac_xmit_get_rate (struct ieee80211_device *ieee, struct sk_buff *skb);
  22201. +extern void ieee80211_start_mesh(struct ieee80211_device *ieee);
  22202. +#endif // _RTL8187_MESH_H_
  22203. 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
  22204. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 1970-01-01 01:00:00.000000000 +0100
  22205. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/rtl_crypto.h 2010-05-27 18:12:39.532222207 +0200
  22206. @@ -0,0 +1,399 @@
  22207. +/*
  22208. + * Scatterlist Cryptographic API.
  22209. + *
  22210. + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  22211. + * Copyright (c) 2002 David S. Miller (davem@redhat.com)
  22212. + *
  22213. + * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
  22214. + * and Nettle, by Niels M敿ēer.
  22215. + *
  22216. + * This program is free software; you can redistribute it and/or modify it
  22217. + * under the terms of the GNU General Public License as published by the Free
  22218. + * Software Foundation; either version 2 of the License, or (at your option)
  22219. + * any later version.
  22220. + *
  22221. + */
  22222. +#ifndef _LINUX_CRYPTO_H
  22223. +#define _LINUX_CRYPTO_H
  22224. +
  22225. +#include <linux/module.h>
  22226. +#include <linux/kernel.h>
  22227. +#include <linux/types.h>
  22228. +#include <linux/list.h>
  22229. +#include <linux/string.h>
  22230. +#include <asm/page.h>
  22231. +#include <asm/errno.h>
  22232. +
  22233. +#define crypto_register_alg crypto_register_alg_rtl
  22234. +#define crypto_unregister_alg crypto_unregister_alg_rtl
  22235. +#define crypto_alloc_tfm crypto_alloc_tfm_rtl
  22236. +#define crypto_free_tfm crypto_free_tfm_rtl
  22237. +#define crypto_alg_available crypto_alg_available_rtl
  22238. +
  22239. +/*
  22240. + * Algorithm masks and types.
  22241. + */
  22242. +#define CRYPTO_ALG_TYPE_MASK 0x000000ff
  22243. +#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
  22244. +#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
  22245. +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
  22246. +
  22247. +/*
  22248. + * Transform masks and values (for crt_flags).
  22249. + */
  22250. +#define CRYPTO_TFM_MODE_MASK 0x000000ff
  22251. +#define CRYPTO_TFM_REQ_MASK 0x000fff00
  22252. +#define CRYPTO_TFM_RES_MASK 0xfff00000
  22253. +
  22254. +#define CRYPTO_TFM_MODE_ECB 0x00000001
  22255. +#define CRYPTO_TFM_MODE_CBC 0x00000002
  22256. +#define CRYPTO_TFM_MODE_CFB 0x00000004
  22257. +#define CRYPTO_TFM_MODE_CTR 0x00000008
  22258. +
  22259. +#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
  22260. +#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
  22261. +#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
  22262. +#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
  22263. +#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
  22264. +#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
  22265. +
  22266. +/*
  22267. + * Miscellaneous stuff.
  22268. + */
  22269. +#define CRYPTO_UNSPEC 0
  22270. +#define CRYPTO_MAX_ALG_NAME 64
  22271. +
  22272. +struct scatterlist;
  22273. +
  22274. +/*
  22275. + * Algorithms: modular crypto algorithm implementations, managed
  22276. + * via crypto_register_alg() and crypto_unregister_alg().
  22277. + */
  22278. +struct cipher_alg {
  22279. + unsigned int cia_min_keysize;
  22280. + unsigned int cia_max_keysize;
  22281. + int (*cia_setkey)(void *ctx, const u8 *key,
  22282. + unsigned int keylen, u32 *flags);
  22283. + void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
  22284. + void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
  22285. +};
  22286. +
  22287. +struct digest_alg {
  22288. + unsigned int dia_digestsize;
  22289. + void (*dia_init)(void *ctx);
  22290. + void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
  22291. + void (*dia_final)(void *ctx, u8 *out);
  22292. + int (*dia_setkey)(void *ctx, const u8 *key,
  22293. + unsigned int keylen, u32 *flags);
  22294. +};
  22295. +
  22296. +struct compress_alg {
  22297. + int (*coa_init)(void *ctx);
  22298. + void (*coa_exit)(void *ctx);
  22299. + int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
  22300. + u8 *dst, unsigned int *dlen);
  22301. + int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
  22302. + u8 *dst, unsigned int *dlen);
  22303. +};
  22304. +
  22305. +#define cra_cipher cra_u.cipher
  22306. +#define cra_digest cra_u.digest
  22307. +#define cra_compress cra_u.compress
  22308. +
  22309. +struct crypto_alg {
  22310. + struct list_head cra_list;
  22311. + u32 cra_flags;
  22312. + unsigned int cra_blocksize;
  22313. + unsigned int cra_ctxsize;
  22314. + const char cra_name[CRYPTO_MAX_ALG_NAME];
  22315. +
  22316. + union {
  22317. + struct cipher_alg cipher;
  22318. + struct digest_alg digest;
  22319. + struct compress_alg compress;
  22320. + } cra_u;
  22321. +
  22322. + struct module *cra_module;
  22323. +};
  22324. +
  22325. +/*
  22326. + * Algorithm registration interface.
  22327. + */
  22328. +int crypto_register_alg(struct crypto_alg *alg);
  22329. +int crypto_unregister_alg(struct crypto_alg *alg);
  22330. +
  22331. +/*
  22332. + * Algorithm query interface.
  22333. + */
  22334. +int crypto_alg_available(const char *name, u32 flags);
  22335. +
  22336. +/*
  22337. + * Transforms: user-instantiated objects which encapsulate algorithms
  22338. + * and core processing logic. Managed via crypto_alloc_tfm() and
  22339. + * crypto_free_tfm(), as well as the various helpers below.
  22340. + */
  22341. +struct crypto_tfm;
  22342. +
  22343. +struct cipher_tfm {
  22344. + void *cit_iv;
  22345. + unsigned int cit_ivsize;
  22346. + u32 cit_mode;
  22347. + int (*cit_setkey)(struct crypto_tfm *tfm,
  22348. + const u8 *key, unsigned int keylen);
  22349. + int (*cit_encrypt)(struct crypto_tfm *tfm,
  22350. + struct scatterlist *dst,
  22351. + struct scatterlist *src,
  22352. + unsigned int nbytes);
  22353. + int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
  22354. + struct scatterlist *dst,
  22355. + struct scatterlist *src,
  22356. + unsigned int nbytes, u8 *iv);
  22357. + int (*cit_decrypt)(struct crypto_tfm *tfm,
  22358. + struct scatterlist *dst,
  22359. + struct scatterlist *src,
  22360. + unsigned int nbytes);
  22361. + int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
  22362. + struct scatterlist *dst,
  22363. + struct scatterlist *src,
  22364. + unsigned int nbytes, u8 *iv);
  22365. + void (*cit_xor_block)(u8 *dst, const u8 *src);
  22366. +};
  22367. +
  22368. +struct digest_tfm {
  22369. + void (*dit_init)(struct crypto_tfm *tfm);
  22370. + void (*dit_update)(struct crypto_tfm *tfm,
  22371. + struct scatterlist *sg, unsigned int nsg);
  22372. + void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
  22373. + void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
  22374. + unsigned int nsg, u8 *out);
  22375. + int (*dit_setkey)(struct crypto_tfm *tfm,
  22376. + const u8 *key, unsigned int keylen);
  22377. +#ifdef CONFIG_CRYPTO_HMAC
  22378. + void *dit_hmac_block;
  22379. +#endif
  22380. +};
  22381. +
  22382. +struct compress_tfm {
  22383. + int (*cot_compress)(struct crypto_tfm *tfm,
  22384. + const u8 *src, unsigned int slen,
  22385. + u8 *dst, unsigned int *dlen);
  22386. + int (*cot_decompress)(struct crypto_tfm *tfm,
  22387. + const u8 *src, unsigned int slen,
  22388. + u8 *dst, unsigned int *dlen);
  22389. +};
  22390. +
  22391. +#define crt_cipher crt_u.cipher
  22392. +#define crt_digest crt_u.digest
  22393. +#define crt_compress crt_u.compress
  22394. +
  22395. +struct crypto_tfm {
  22396. +
  22397. + u32 crt_flags;
  22398. +
  22399. + union {
  22400. + struct cipher_tfm cipher;
  22401. + struct digest_tfm digest;
  22402. + struct compress_tfm compress;
  22403. + } crt_u;
  22404. +
  22405. + struct crypto_alg *__crt_alg;
  22406. +};
  22407. +
  22408. +/*
  22409. + * Transform user interface.
  22410. + */
  22411. +
  22412. +/*
  22413. + * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
  22414. + * If that fails and the kernel supports dynamically loadable modules, it
  22415. + * will then attempt to load a module of the same name or alias. A refcount
  22416. + * is grabbed on the algorithm which is then associated with the new transform.
  22417. + *
  22418. + * crypto_free_tfm() frees up the transform and any associated resources,
  22419. + * then drops the refcount on the associated algorithm.
  22420. + */
  22421. +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
  22422. +void crypto_free_tfm(struct crypto_tfm *tfm);
  22423. +
  22424. +/*
  22425. + * Transform helpers which query the underlying algorithm.
  22426. + */
  22427. +static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
  22428. +{
  22429. + return tfm->__crt_alg->cra_name;
  22430. +}
  22431. +
  22432. +static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
  22433. +{
  22434. + struct crypto_alg *alg = tfm->__crt_alg;
  22435. +
  22436. + if (alg->cra_module)
  22437. + return alg->cra_module->name;
  22438. + else
  22439. + return NULL;
  22440. +}
  22441. +
  22442. +static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
  22443. +{
  22444. + return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
  22445. +}
  22446. +
  22447. +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
  22448. +{
  22449. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22450. + return tfm->__crt_alg->cra_cipher.cia_min_keysize;
  22451. +}
  22452. +
  22453. +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
  22454. +{
  22455. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22456. + return tfm->__crt_alg->cra_cipher.cia_max_keysize;
  22457. +}
  22458. +
  22459. +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
  22460. +{
  22461. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22462. + return tfm->crt_cipher.cit_ivsize;
  22463. +}
  22464. +
  22465. +static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
  22466. +{
  22467. + return tfm->__crt_alg->cra_blocksize;
  22468. +}
  22469. +
  22470. +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
  22471. +{
  22472. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  22473. + return tfm->__crt_alg->cra_digest.dia_digestsize;
  22474. +}
  22475. +
  22476. +/*
  22477. + * API wrappers.
  22478. + */
  22479. +static inline void crypto_digest_init(struct crypto_tfm *tfm)
  22480. +{
  22481. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  22482. + tfm->crt_digest.dit_init(tfm);
  22483. +}
  22484. +
  22485. +static inline void crypto_digest_update(struct crypto_tfm *tfm,
  22486. + struct scatterlist *sg,
  22487. + unsigned int nsg)
  22488. +{
  22489. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  22490. + tfm->crt_digest.dit_update(tfm, sg, nsg);
  22491. +}
  22492. +
  22493. +static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
  22494. +{
  22495. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  22496. + tfm->crt_digest.dit_final(tfm, out);
  22497. +}
  22498. +
  22499. +static inline void crypto_digest_digest(struct crypto_tfm *tfm,
  22500. + struct scatterlist *sg,
  22501. + unsigned int nsg, u8 *out)
  22502. +{
  22503. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  22504. + tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
  22505. +}
  22506. +
  22507. +static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
  22508. + const u8 *key, unsigned int keylen)
  22509. +{
  22510. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
  22511. + if (tfm->crt_digest.dit_setkey == NULL)
  22512. + return -ENOSYS;
  22513. + return tfm->crt_digest.dit_setkey(tfm, key, keylen);
  22514. +}
  22515. +
  22516. +static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
  22517. + const u8 *key, unsigned int keylen)
  22518. +{
  22519. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22520. + return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
  22521. +}
  22522. +
  22523. +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
  22524. + struct scatterlist *dst,
  22525. + struct scatterlist *src,
  22526. + unsigned int nbytes)
  22527. +{
  22528. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22529. + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
  22530. +}
  22531. +
  22532. +static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
  22533. + struct scatterlist *dst,
  22534. + struct scatterlist *src,
  22535. + unsigned int nbytes, u8 *iv)
  22536. +{
  22537. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22538. + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
  22539. + return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
  22540. +}
  22541. +
  22542. +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
  22543. + struct scatterlist *dst,
  22544. + struct scatterlist *src,
  22545. + unsigned int nbytes)
  22546. +{
  22547. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22548. + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
  22549. +}
  22550. +
  22551. +static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
  22552. + struct scatterlist *dst,
  22553. + struct scatterlist *src,
  22554. + unsigned int nbytes, u8 *iv)
  22555. +{
  22556. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22557. + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
  22558. + return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
  22559. +}
  22560. +
  22561. +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
  22562. + const u8 *src, unsigned int len)
  22563. +{
  22564. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22565. + memcpy(tfm->crt_cipher.cit_iv, src, len);
  22566. +}
  22567. +
  22568. +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
  22569. + u8 *dst, unsigned int len)
  22570. +{
  22571. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
  22572. + memcpy(dst, tfm->crt_cipher.cit_iv, len);
  22573. +}
  22574. +
  22575. +static inline int crypto_comp_compress(struct crypto_tfm *tfm,
  22576. + const u8 *src, unsigned int slen,
  22577. + u8 *dst, unsigned int *dlen)
  22578. +{
  22579. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
  22580. + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
  22581. +}
  22582. +
  22583. +static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
  22584. + const u8 *src, unsigned int slen,
  22585. + u8 *dst, unsigned int *dlen)
  22586. +{
  22587. + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
  22588. + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
  22589. +}
  22590. +
  22591. +/*
  22592. + * HMAC support.
  22593. + */
  22594. +#ifdef CONFIG_CRYPTO_HMAC
  22595. +void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
  22596. +void crypto_hmac_update(struct crypto_tfm *tfm,
  22597. + struct scatterlist *sg, unsigned int nsg);
  22598. +void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
  22599. + unsigned int *keylen, u8 *out);
  22600. +void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
  22601. + struct scatterlist *sg, unsigned int nsg, u8 *out);
  22602. +#endif /* CONFIG_CRYPTO_HMAC */
  22603. +
  22604. +#endif /* _LINUX_CRYPTO_H */
  22605. +
  22606. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h
  22607. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 1970-01-01 01:00:00.000000000 +0100
  22608. +++ linux-loongson/drivers/net/wireless/rtl8187b/ieee80211/scatterwalk.h 2010-05-27 18:12:39.532222207 +0200
  22609. @@ -0,0 +1,51 @@
  22610. +/*
  22611. + * Cryptographic API.
  22612. + *
  22613. + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  22614. + * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
  22615. + * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.com>
  22616. + *
  22617. + * This program is free software; you can redistribute it and/or modify it
  22618. + * under the terms of the GNU General Public License as published by the Free
  22619. + * Software Foundation; either version 2 of the License, or (at your option)
  22620. + * any later version.
  22621. + *
  22622. + */
  22623. +
  22624. +#ifndef _CRYPTO_SCATTERWALK_H
  22625. +#define _CRYPTO_SCATTERWALK_H
  22626. +#include <linux/mm.h>
  22627. +#include <asm/scatterlist.h>
  22628. +
  22629. +struct scatter_walk {
  22630. + struct scatterlist *sg;
  22631. + struct page *page;
  22632. + void *data;
  22633. + unsigned int len_this_page;
  22634. + unsigned int len_this_segment;
  22635. + unsigned int offset;
  22636. +};
  22637. +
  22638. +/* Define sg_next is an inline routine now in case we want to change
  22639. + scatterlist to a linked list later. */
  22640. +static inline struct scatterlist *sg_next(struct scatterlist *sg)
  22641. +{
  22642. + return sg + 1;
  22643. +}
  22644. +
  22645. +static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
  22646. + struct scatter_walk *walk_out,
  22647. + void *src_p, void *dst_p)
  22648. +{
  22649. + return walk_in->page == walk_out->page &&
  22650. + walk_in->offset == walk_out->offset &&
  22651. + walk_in->data == src_p && walk_out->data == dst_p;
  22652. +}
  22653. +
  22654. +void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
  22655. +void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
  22656. +int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
  22657. +void scatterwalk_map(struct scatter_walk *walk, int out);
  22658. +void scatterwalk_done(struct scatter_walk *walk, int out, int more);
  22659. +
  22660. +#endif /* _CRYPTO_SCATTERWALK_H */
  22661. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/Makefile linux-loongson/drivers/net/wireless/rtl8187b/Makefile
  22662. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/Makefile 1970-01-01 01:00:00.000000000 +0100
  22663. +++ linux-loongson/drivers/net/wireless/rtl8187b/Makefile 2010-05-27 18:12:39.532222207 +0200
  22664. @@ -0,0 +1,41 @@
  22665. +obj-$(CONFIG_RTL8187B) += rtl8187b.o
  22666. +
  22667. +rtl8187b-objs := r8187_core.o \
  22668. + r8180_93cx6.o \
  22669. + r8180_wx.o \
  22670. + r8180_rtl8225.o \
  22671. + r8180_rtl8225z2.o \
  22672. + r8180_pm.o \
  22673. + r8180_dm.o \
  22674. + r8187_led.o \
  22675. + r8187_rfkill.o \
  22676. + ieee80211/dot11d.o \
  22677. + ieee80211/ieee80211_softmac.o \
  22678. + ieee80211/ieee80211_rx.o \
  22679. + ieee80211/ieee80211_tx.o \
  22680. + ieee80211/ieee80211_wx.o \
  22681. + ieee80211/ieee80211_module.o \
  22682. + ieee80211/ieee80211_softmac_wx.o \
  22683. + ieee80211/ieee80211_crypt.o \
  22684. + ieee80211/ieee80211_crypt_tkip.o \
  22685. + ieee80211/ieee80211_crypt_ccmp.o \
  22686. + ieee80211/ieee80211_crypt_wep.o
  22687. +
  22688. +EXTRA_CFLAGS += -DCONFIG_RTL8180_PM
  22689. +EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
  22690. +EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
  22691. +EXTRA_CFLAGS += -DJOHN_IOCTL
  22692. +EXTRA_CFLAGS += -DLED
  22693. +#EXTRA_CFLAGS += -DLED_SHIN
  22694. +#EXTRA_CFLAGS += -DSW_ANTE_DIVERSITY
  22695. +EXTRA_CFLAGS += -DCPU_64BIT
  22696. +EXTRA_CFLAGS += -DCONFIG_IPS
  22697. +#CFLAGS += -DJOHN_HWSEC -DJOHN_TKIP
  22698. +#CFLAGS += -DJOHN_DUMP_TX
  22699. +#EXTRA_CFLAGS += -DJOHN_DUMP_TXPKT
  22700. +
  22701. +#Radio On/Off debug
  22702. +#EXTRA_CFLAGS += -DCONFIG_RADIO_DEBUG
  22703. +
  22704. +#for dot11d
  22705. +EXTRA_CFLAGS += -DENABLE_DOT11D
  22706. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/msh_class.h linux-loongson/drivers/net/wireless/rtl8187b/msh_class.h
  22707. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/msh_class.h 1970-01-01 01:00:00.000000000 +0100
  22708. +++ linux-loongson/drivers/net/wireless/rtl8187b/msh_class.h 2010-05-27 18:12:39.532222207 +0200
  22709. @@ -0,0 +1,117 @@
  22710. +/*! \file msh_class.h
  22711. + \brief msh CLASS extension
  22712. +
  22713. + \date 2007/5/2
  22714. + \author Stanley Chang <chagnsl@cs.nctu.edu.tw>
  22715. +*/
  22716. +
  22717. +#ifndef _MESH_CLASS_HDR_H_
  22718. +#define _MESH_CLASS_HDR_H_
  22719. +
  22720. +#include <linux/if_ether.h> /* ETH_ALEN */
  22721. +#include <linux/kernel.h> /* ARRAY_SIZE */
  22722. +#include <linux/version.h>
  22723. +#include <linux/jiffies.h>
  22724. +#include <linux/timer.h>
  22725. +#include <linux/sched.h>
  22726. +
  22727. +#include "ieee80211/ieee80211.h" // for struct ieee80211-xxxx
  22728. +#include "r8187.h" // for struct r8180-priv
  22729. +
  22730. +#define MAC_TABLE_SIZE 8
  22731. +
  22732. +struct mshclass {
  22733. + struct r8180_priv * p8187;
  22734. +
  22735. + // callback functions
  22736. + // ieee80211_softmac.c
  22737. + int (*ext_patch_ieee80211_start_protocol) (struct ieee80211_device *ieee); // start special mode
  22738. +
  22739. + short (*ext_patch_ieee80211_probe_req_1) (struct ieee80211_device *ieee); // return = 0: no more phases, >0: another phase
  22740. + u8* (*ext_patch_ieee80211_probe_req_2) (struct ieee80211_device *ieee, struct sk_buff *skb, u8 *tag); // return tag
  22741. +
  22742. + void (*ext_patch_ieee80211_association_req_1) (struct ieee80211_assoc_request_frame *hdr);
  22743. + u8* (*ext_patch_ieee80211_association_req_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, struct sk_buff *skb);
  22744. +
  22745. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_req) (struct ieee80211_device *ieee, struct sk_buff *skb);
  22746. + int (*ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp) (struct ieee80211_device *ieee, struct sk_buff *skb);
  22747. +
  22748. + void (*ext_patch_ieee80211_stop_protocol) (struct ieee80211_device *ieee); // stop timer
  22749. +
  22750. + void (*ext_patch_ieee80211_assoc_resp_by_net_1) (struct ieee80211_assoc_response_frame *assoc);
  22751. + u8* (*ext_patch_ieee80211_assoc_resp_by_net_2) (struct ieee80211_device *ieee, struct ieee80211_network *pstat, int pkt_type, struct sk_buff *skb);
  22752. +
  22753. + int (*ext_patch_ieee80211_ext_stop_scan_wq_set_channel) (struct ieee80211_device *ieee);
  22754. +
  22755. + struct sk_buff* (*ext_patch_get_beacon_get_probersp)(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net);
  22756. +
  22757. + int (*ext_patch_ieee80211_softmac_xmit_get_rate) (struct ieee80211_device *ieee, struct sk_buff *skb);
  22758. + int (*ext_patch_ieee80211_rx_frame_softmac_on_auth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  22759. + int (*ext_patch_ieee80211_rx_frame_softmac_on_deauth)(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  22760. +//by amy for mesh
  22761. + void (*ext_patch_ieee80211_start_mesh)(struct ieee80211_device *ieee);
  22762. +//by amy for mesh
  22763. + /// r8180_wx.c
  22764. + int (*ext_patch_r8180_wx_get_meshinfo) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22765. + int (*ext_patch_r8180_wx_enable_mesh) (struct net_device *dev);
  22766. + int (*ext_patch_r8180_wx_disable_mesh) (struct net_device *dev);
  22767. + int (*ext_patch_r8180_wx_set_meshID) ( struct net_device *dev, char *ext);
  22768. +//by amy for mesh
  22769. + int (*ext_patch_r8180_wx_set_mesh_chan)(struct net_device *dev, unsigned char channel);
  22770. +//by amy for mesh
  22771. + void (*ext_patch_r8180_wx_set_channel) (struct ieee80211_device *ieee, int ch);
  22772. +
  22773. + int (*ext_patch_r8180_wx_set_add_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22774. + int (*ext_patch_r8180_wx_set_del_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22775. + int (*ext_patch_r8180_wx_set_add_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22776. + int (*ext_patch_r8180_wx_set_del_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22777. + int (*ext_patch_r8180_wx_get_mac_allow) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22778. + int (*ext_patch_r8180_wx_get_mac_deny) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22779. +
  22780. + int (*ext_patch_r8180_wx_get_mesh_list) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22781. + int (*ext_patch_r8180_wx_mesh_scan) (struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  22782. + int (*ext_patch_r8180_wx_get_selected_mesh)(struct net_device *dev, int en, char *cho, char* id);
  22783. +//by amy for networkmanager UI
  22784. + int (*ext_patch_r8180_wx_get_selected_mesh_channel)(struct net_device *dev, char* extmeshid, char *cho);
  22785. +//by amy for networkmanager UI
  22786. + /// r8187_core.c
  22787. + u8 (*ext_patch_rtl8180_up) (struct mshclass *priv);
  22788. +
  22789. + // ieee80211_rx.c
  22790. + unsigned int (*ext_patch_ieee80211_process_probe_response_1) ( struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats);
  22791. + void (*ext_patch_ieee80211_rx_mgt_on_probe_req) ( struct ieee80211_device *ieee, struct ieee80211_probe_request *beacon, struct ieee80211_rx_stats *stats);
  22792. +
  22793. + void (*ext_patch_ieee80211_rx_mgt_update_expire) ( struct ieee80211_device *ieee, struct sk_buff *skb);
  22794. +
  22795. + 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);
  22796. +
  22797. + int (*ext_patch_ieee80211_rx_frame_get_hdrlen) (struct ieee80211_device *ieee, struct sk_buff *skb);
  22798. +
  22799. + int (*ext_patch_ieee80211_rx_is_valid_framectl) (struct ieee80211_device *ieee, u16 fc, u16 type, u16 stype);
  22800. +
  22801. + // return > 0 is success. 0 when failed
  22802. + int (*ext_patch_ieee80211_rx_process_dataframe) (struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats);
  22803. +
  22804. + int (*ext_patch_is_duplicate_packet) (struct ieee80211_device *ieee, struct ieee80211_hdr *header, u16 type, u16 stype);
  22805. + /* added by david for setting acl dynamically */
  22806. + u8 (*ext_patch_ieee80211_acl_query) (struct ieee80211_device *ieee, u8 *sa);
  22807. +
  22808. + // r8187_core.c
  22809. + int (*ext_patch_rtl8180_ioctl) (struct net_device *dev, struct ifreq *rq, int cmd);
  22810. + void (*ext_patch_create_proc) (struct r8180_priv *priv);
  22811. + void (*ext_patch_remove_proc) (struct r8180_priv *priv);
  22812. +
  22813. + // ieee80211_tx.c
  22814. +
  22815. + // locked by ieee->lock. Call ieee80211_softmac_xmit afterward
  22816. + struct ieee80211_txb* (*ext_patch_ieee80211_xmit) (struct sk_buff *skb, struct net_device *dev);
  22817. +
  22818. + // DO NOT MODIFY ANY STRUCTURE BELOW THIS LINE
  22819. + u8 priv[0]; // mshclass_priv;
  22820. +};
  22821. +
  22822. +extern void free_mshobj(struct mshclass **pObj);
  22823. +extern struct mshclass *alloc_mshobj(struct r8180_priv *caller_priv);
  22824. +
  22825. +
  22826. +#endif // _MESH_CLASS_HDR_H_
  22827. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.c
  22828. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.c 1970-01-01 01:00:00.000000000 +0100
  22829. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.c 2010-05-27 18:12:39.532222207 +0200
  22830. @@ -0,0 +1,146 @@
  22831. +/*
  22832. + This files contains card eeprom (93c46 or 93c56) programming routines,
  22833. + memory is addressed by 16 bits words.
  22834. +
  22835. + This is part of rtl8180 OpenSource driver.
  22836. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  22837. + Released under the terms of GPL (General Public Licence)
  22838. +
  22839. + Parts of this driver are based on the GPL part of the
  22840. + official realtek driver.
  22841. +
  22842. + Parts of this driver are based on the rtl8180 driver skeleton
  22843. + from Patric Schenke & Andres Salomon.
  22844. +
  22845. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
  22846. +
  22847. + We want to tanks the Authors of those projects and the Ndiswrapper
  22848. + project Authors.
  22849. +*/
  22850. +
  22851. +#include "r8180_93cx6.h"
  22852. +
  22853. +void eprom_cs(struct net_device *dev, short bit)
  22854. +{
  22855. + if(bit)
  22856. + write_nic_byte(dev, EPROM_CMD,
  22857. + (1<<EPROM_CS_SHIFT) | \
  22858. + read_nic_byte(dev, EPROM_CMD)); //enable EPROM
  22859. + else
  22860. + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
  22861. + &~(1<<EPROM_CS_SHIFT)); //disable EPROM
  22862. +
  22863. + force_pci_posting(dev);
  22864. + udelay(EPROM_DELAY);
  22865. +}
  22866. +
  22867. +
  22868. +void eprom_ck_cycle(struct net_device *dev)
  22869. +{
  22870. + write_nic_byte(dev, EPROM_CMD,
  22871. + (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
  22872. + force_pci_posting(dev);
  22873. + udelay(EPROM_DELAY);
  22874. + write_nic_byte(dev, EPROM_CMD,
  22875. + read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
  22876. + force_pci_posting(dev);
  22877. + udelay(EPROM_DELAY);
  22878. +}
  22879. +
  22880. +
  22881. +void eprom_w(struct net_device *dev,short bit)
  22882. +{
  22883. + if(bit)
  22884. + write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
  22885. + read_nic_byte(dev,EPROM_CMD));
  22886. + else
  22887. + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
  22888. + &~(1<<EPROM_W_SHIFT));
  22889. +
  22890. + force_pci_posting(dev);
  22891. + udelay(EPROM_DELAY);
  22892. +}
  22893. +
  22894. +
  22895. +short eprom_r(struct net_device *dev)
  22896. +{
  22897. + short bit;
  22898. +
  22899. + bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
  22900. + udelay(EPROM_DELAY);
  22901. +
  22902. + if(bit) return 1;
  22903. + return 0;
  22904. +}
  22905. +
  22906. +
  22907. +void eprom_send_bits_string(struct net_device *dev, short b[], int len)
  22908. +{
  22909. + int i;
  22910. +
  22911. + for(i=0; i<len; i++){
  22912. + eprom_w(dev, b[i]);
  22913. + eprom_ck_cycle(dev);
  22914. + }
  22915. +}
  22916. +
  22917. +
  22918. +u32 eprom_read(struct net_device *dev, u32 addr)
  22919. +{
  22920. + struct r8180_priv *priv = ieee80211_priv(dev);
  22921. + short read_cmd[]={1,1,0};
  22922. + short addr_str[8];
  22923. + int i;
  22924. + int addr_len;
  22925. + u32 ret;
  22926. +
  22927. + ret=0;
  22928. + //enable EPROM programming
  22929. + write_nic_byte(dev, EPROM_CMD,
  22930. + (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
  22931. + force_pci_posting(dev);
  22932. + udelay(EPROM_DELAY);
  22933. +
  22934. + if (priv->epromtype==EPROM_93c56){
  22935. + addr_str[7]=addr & 1;
  22936. + addr_str[6]=addr & (1<<1);
  22937. + addr_str[5]=addr & (1<<2);
  22938. + addr_str[4]=addr & (1<<3);
  22939. + addr_str[3]=addr & (1<<4);
  22940. + addr_str[2]=addr & (1<<5);
  22941. + addr_str[1]=addr & (1<<6);
  22942. + addr_str[0]=addr & (1<<7);
  22943. + addr_len=8;
  22944. + }else{
  22945. + addr_str[5]=addr & 1;
  22946. + addr_str[4]=addr & (1<<1);
  22947. + addr_str[3]=addr & (1<<2);
  22948. + addr_str[2]=addr & (1<<3);
  22949. + addr_str[1]=addr & (1<<4);
  22950. + addr_str[0]=addr & (1<<5);
  22951. + addr_len=6;
  22952. + }
  22953. + eprom_cs(dev, 1);
  22954. + eprom_ck_cycle(dev);
  22955. + eprom_send_bits_string(dev, read_cmd, 3);
  22956. + eprom_send_bits_string(dev, addr_str, addr_len);
  22957. +
  22958. + //keep chip pin D to low state while reading.
  22959. + //I'm unsure if it is necessary, but anyway shouldn't hurt
  22960. + eprom_w(dev, 0);
  22961. +
  22962. + for(i=0;i<16;i++){
  22963. + //eeprom needs a clk cycle between writing opcode&adr
  22964. + //and reading data. (eeprom outs a dummy 0)
  22965. + eprom_ck_cycle(dev);
  22966. + ret |= (eprom_r(dev)<<(15-i));
  22967. + }
  22968. +
  22969. + eprom_cs(dev, 0);
  22970. + eprom_ck_cycle(dev);
  22971. +
  22972. + //disable EPROM programming
  22973. + write_nic_byte(dev, EPROM_CMD,
  22974. + (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
  22975. + return ret;
  22976. +}
  22977. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.h
  22978. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_93cx6.h 1970-01-01 01:00:00.000000000 +0100
  22979. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_93cx6.h 2010-05-27 18:12:39.532222207 +0200
  22980. @@ -0,0 +1,46 @@
  22981. +/*
  22982. + This is part of rtl8187 OpenSource driver
  22983. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  22984. + Released under the terms of GPL (General Public Licence)
  22985. +
  22986. + Parts of this driver are based on the GPL part of the official realtek driver
  22987. + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
  22988. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
  22989. +
  22990. + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
  22991. +*/
  22992. +
  22993. +/*This files contains card eeprom (93c46 or 93c56) programming routines*/
  22994. +/*memory is addressed by WORDS*/
  22995. +
  22996. +#include "r8187.h"
  22997. +#include "r8180_hw.h"
  22998. +
  22999. +#define EPROM_DELAY 10
  23000. +
  23001. +#define EPROM_ANAPARAM_ADDRLWORD 0xd
  23002. +#define EPROM_ANAPARAM_ADDRHWORD 0xe
  23003. +
  23004. +#define EPROM_CHANNEL_PLAN 0x3 //0x6>>1
  23005. +//0x77 BIT[0]0:use gpio 1 bit 1, 1:use gpio 1 bit 2.
  23006. +#define EPROM_SELECT_GPIO (0x77 >> 1)
  23007. +//#define EEPROM_COUNTRY_CODE 0x2E//87se channel plan is here
  23008. +
  23009. +#define EPROM_RFCHIPID 0x6
  23010. +#define EPROM_TXPW_BASE 0x05
  23011. +#define EPROM_RFCHIPID_RTL8225U 5
  23012. +#define EPROM_RFCHIPID_RTL8225U_VF 6
  23013. +#define EPROM_RF_PARAM 0x4
  23014. +#define EPROM_CONFIG2 0xc
  23015. +
  23016. +#define EPROM_VERSION 0x1E
  23017. +#define MAC_ADR 0x7
  23018. +
  23019. +#define CIS 0x18
  23020. +
  23021. +#define EPROM_TXPW0 0x16
  23022. +#define EPROM_TXPW2 0x1b
  23023. +#define EPROM_TXPW1 0x3d
  23024. +
  23025. +
  23026. +u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
  23027. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.c
  23028. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.c 1970-01-01 01:00:00.000000000 +0100
  23029. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.c 2010-05-27 18:12:39.532222207 +0200
  23030. @@ -0,0 +1,882 @@
  23031. +/*++
  23032. +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
  23033. +
  23034. +Module Name:
  23035. + r8180_dig.c
  23036. +
  23037. +Abstract:
  23038. + Hardware dynamic mechanism for RTL8187B
  23039. +
  23040. +Major Change History:
  23041. + When Who What
  23042. + ---------- --------------- -------------------------------
  23043. + 2006-11-15 david Created
  23044. +
  23045. +Notes:
  23046. + This file is ported from RTL8187B Windows driver.
  23047. +
  23048. +
  23049. +--*/
  23050. +#include "r8180_dm.h"
  23051. +#include "r8180_hw.h"
  23052. +#include "r8180_rtl8225.h"
  23053. +
  23054. +//================================================================================
  23055. +// Local Constant.
  23056. +//================================================================================
  23057. +#define Z1_HIPWR_UPPER_TH 99
  23058. +#define Z1_HIPWR_LOWER_TH 70
  23059. +#define Z2_HIPWR_UPPER_TH 99
  23060. +#define Z2_HIPWR_LOWER_TH 90
  23061. +
  23062. +bool CheckDig(struct net_device *dev)
  23063. +{
  23064. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23065. + struct ieee80211_device *ieee = priv->ieee80211;
  23066. +
  23067. + if(ieee->state != IEEE80211_LINKED)
  23068. + return false;
  23069. +
  23070. + if(priv->card_8187 == NIC_8187B) {
  23071. + //
  23072. + // We need to schedule dig workitem on either of the below mechanisms.
  23073. + // By Bruce, 2007-06-01.
  23074. + //
  23075. + if(!priv->bDigMechanism && !priv->bCCKThMechanism)
  23076. + return false;
  23077. +
  23078. + if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
  23079. + return false;
  23080. + } else {
  23081. + if(!priv->bDigMechanism)
  23082. + return false;
  23083. +
  23084. + if(priv->CurrentOperaRate < 48)
  23085. + return false;
  23086. + }
  23087. + return true;
  23088. +}
  23089. +
  23090. +
  23091. +//
  23092. +// Description:
  23093. +// Implementation of DIG for Zebra and Zebra2.
  23094. +//
  23095. +void DIG_Zebra(struct net_device *dev)
  23096. +{
  23097. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23098. + //PHAL_DATA_8187 pHalData = GetHalData8187(Adapter);
  23099. + u16 CCKFalseAlarm, OFDMFalseAlarm;
  23100. + u16 OfdmFA1, OfdmFA2;
  23101. + int InitialGainStep = 7; // The number of initial gain stages.
  23102. + int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
  23103. +
  23104. +// printk("---------> DIG_Zebra()\n");
  23105. +
  23106. + //Read only 1 byte because of HW bug. This is a temporal modification. Joseph
  23107. + // Modify by Isaiah 2006-06-27
  23108. + if(priv->card_8187_Bversion == VERSION_8187B_B)
  23109. + {
  23110. + CCKFalseAlarm = 0;
  23111. + OFDMFalseAlarm = (u16)(priv->FalseAlarmRegValue);
  23112. + OfdmFA1 = 0x01;
  23113. + OfdmFA2 = priv->RegDigOfdmFaUpTh;
  23114. + }
  23115. + else
  23116. + {
  23117. + CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
  23118. + OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
  23119. + OfdmFA1 = 0x15;
  23120. + //OfdmFA2 = 0xC00;
  23121. + OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
  23122. + }
  23123. +
  23124. +// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
  23125. +// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
  23126. +
  23127. +
  23128. +
  23129. + // The number of initial gain steps is different, by Bruce, 2007-04-13.
  23130. + if(priv->card_8187 == NIC_8187) {
  23131. + if (priv->InitialGain == 0 ) //autoDIG
  23132. + {
  23133. + switch( priv->rf_chip)
  23134. + {
  23135. + case RF_ZEBRA:
  23136. + priv->InitialGain = 5; // m74dBm;
  23137. + break;
  23138. + case RF_ZEBRA2:
  23139. + priv->InitialGain = 4; // m78dBm;
  23140. + break;
  23141. + default:
  23142. + priv->InitialGain = 5; // m74dBm;
  23143. + break;
  23144. + }
  23145. + }
  23146. + InitialGainStep = 7;
  23147. + if(priv->InitialGain > 7)
  23148. + priv->InitialGain = 5;
  23149. + LowestGainStage = 4;
  23150. + } else {
  23151. + if (priv->InitialGain == 0 ) //autoDIG
  23152. + { // Advised from SD3 DZ, by Bruce, 2007-06-05.
  23153. + priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
  23154. + }
  23155. + if(priv->card_8187_Bversion != VERSION_8187B_B)
  23156. + { // Advised from SD3 DZ, by Bruce, 2007-06-05.
  23157. + OfdmFA1 = 0x20;
  23158. + }
  23159. + InitialGainStep = 8;
  23160. + LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
  23161. + }
  23162. +
  23163. + if (OFDMFalseAlarm > OfdmFA1)
  23164. + {
  23165. + if (OFDMFalseAlarm > OfdmFA2)
  23166. + {
  23167. + priv->DIG_NumberFallbackVote++;
  23168. + if (priv->DIG_NumberFallbackVote >1)
  23169. + {
  23170. + //serious OFDM False Alarm, need fallback
  23171. + // By Bruce, 2007-03-29.
  23172. + // if (pHalData->InitialGain < 7) // In 87B, m66dBm means State 7 (m74dBm)
  23173. + if (priv->InitialGain < InitialGainStep)
  23174. + {
  23175. + priv->InitialGain = (priv->InitialGain + 1);
  23176. + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
  23177. + //printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
  23178. + UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
  23179. + }
  23180. + priv->DIG_NumberFallbackVote = 0;
  23181. + priv->DIG_NumberUpgradeVote=0;
  23182. + }
  23183. + }
  23184. + else
  23185. + {
  23186. + if (priv->DIG_NumberFallbackVote)
  23187. + priv->DIG_NumberFallbackVote--;
  23188. + }
  23189. + priv->DIG_NumberUpgradeVote=0;
  23190. + }
  23191. + else //OFDM False Alarm < 0x15
  23192. + {
  23193. + if (priv->DIG_NumberFallbackVote)
  23194. + priv->DIG_NumberFallbackVote--;
  23195. + priv->DIG_NumberUpgradeVote++;
  23196. +
  23197. + if (priv->DIG_NumberUpgradeVote>9)
  23198. + {
  23199. + if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
  23200. + {
  23201. + priv->InitialGain = (priv->InitialGain - 1);
  23202. + //printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
  23203. + //printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
  23204. + UpdateInitialGain(dev); // 2005.01.06, by rcnjko.
  23205. + }
  23206. + priv->DIG_NumberFallbackVote = 0;
  23207. + priv->DIG_NumberUpgradeVote=0;
  23208. + }
  23209. + }
  23210. +
  23211. +// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
  23212. +// printk("<--------- DIG_Zebra()\n");
  23213. +}
  23214. +
  23215. +//
  23216. +// Description:
  23217. +// Dispatch DIG implementation according to RF.
  23218. +//
  23219. +void DynamicInitGain(struct net_device *dev)
  23220. +{
  23221. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23222. +
  23223. + switch(priv->rf_chip)
  23224. + {
  23225. + case RF_ZEBRA:
  23226. + case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
  23227. + //case RF_ZEBRA4:
  23228. + DIG_Zebra(dev);
  23229. + break;
  23230. +
  23231. + default:
  23232. + printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
  23233. + break;
  23234. + }
  23235. +}
  23236. +
  23237. +// By Bruce, 2007-03-29.
  23238. +//
  23239. +// Description:
  23240. +// Dispatch CCK Power Detection implementation according to RF.
  23241. +//
  23242. +void DynamicCCKThreshold(struct net_device *dev)
  23243. +{
  23244. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23245. + u16 CCK_Up_Th;
  23246. + u16 CCK_Lw_Th;
  23247. + u16 CCKFalseAlarm;
  23248. +
  23249. + printk("=====>DynamicCCKThreshold()\n");
  23250. +
  23251. + CCK_Up_Th = priv->CCKUpperTh;
  23252. + CCK_Lw_Th = priv->CCKLowerTh;
  23253. + CCKFalseAlarm = (u16)((priv->FalseAlarmRegValue & 0x0000ffff) >> 8); // We only care about the higher byte.
  23254. + printk("DynamicCCKThreshold(): CCK Upper Threshold: 0x%02X, Lower Threshold: 0x%02X, CCKFalseAlarmHighByte: 0x%02X\n", CCK_Up_Th, CCK_Lw_Th, CCKFalseAlarm);
  23255. +
  23256. + if(priv->StageCCKTh < 3 && CCKFalseAlarm >= CCK_Up_Th)
  23257. + {
  23258. + priv->StageCCKTh ++;
  23259. + UpdateCCKThreshold(dev);
  23260. + }
  23261. + else if(priv->StageCCKTh > 0 && CCKFalseAlarm <= CCK_Lw_Th)
  23262. + {
  23263. + priv->StageCCKTh --;
  23264. + UpdateCCKThreshold(dev);
  23265. + }
  23266. +
  23267. + printk("<=====DynamicCCKThreshold()\n");
  23268. +}
  23269. +
  23270. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  23271. +void rtl8180_hw_dig_wq (struct work_struct *work)
  23272. +{
  23273. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  23274. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
  23275. + struct net_device *dev = ieee->dev;
  23276. +#else
  23277. +void rtl8180_hw_dig_wq(struct net_device *dev)
  23278. +{
  23279. + // struct r8180_priv *priv = ieee80211_priv(dev);
  23280. +#endif
  23281. + struct r8180_priv *priv = ieee80211_priv(dev);
  23282. +
  23283. + // Read CCK and OFDM False Alarm.
  23284. + if(priv->card_8187_Bversion == VERSION_8187B_B) {
  23285. + // Read only 1 byte because of HW bug. This is a temporal modification. Joseph
  23286. + // Modify by Isaiah 2006-06-27
  23287. + priv->FalseAlarmRegValue = (u32)read_nic_byte(dev, (OFDM_FALSE_ALARM+1));
  23288. + } else {
  23289. + priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
  23290. + }
  23291. +
  23292. + // Adjust Initial Gain dynamically.
  23293. + if(priv->bDigMechanism) {
  23294. + DynamicInitGain(dev);
  23295. + }
  23296. +
  23297. + //
  23298. + // Move from DynamicInitGain to be independent of the OFDM DIG mechanism, by Bruce, 2007-06-01.
  23299. + //
  23300. + if(priv->card_8187 == NIC_8187B) {
  23301. + // By Bruce, 2007-03-29.
  23302. + // Dynamically update CCK Power Detection Threshold.
  23303. + if(priv->bCCKThMechanism)
  23304. + {
  23305. + DynamicCCKThreshold(dev);
  23306. + }
  23307. + }
  23308. +}
  23309. +
  23310. +void SetTxPowerLevel8187(struct net_device *dev, short chan)
  23311. +{
  23312. + struct r8180_priv *priv = ieee80211_priv(dev);
  23313. +
  23314. + switch(priv->rf_chip)
  23315. + {
  23316. + case RF_ZEBRA:
  23317. + rtl8225_SetTXPowerLevel(dev,chan);
  23318. + break;
  23319. +
  23320. + case RF_ZEBRA2:
  23321. + //case RF_ZEBRA4:
  23322. + rtl8225z2_SetTXPowerLevel(dev,chan);
  23323. + break;
  23324. + }
  23325. +}
  23326. +
  23327. +//
  23328. +// Description:
  23329. +// Check if input power signal strength exceeds maximum input power threshold
  23330. +// of current HW.
  23331. +// If yes, we set our HW to high input power state:
  23332. +// RX: always force TR switch to SW Tx mode to reduce input power.
  23333. +// TX: turn off smaller Tx output power (see RtUsbCheckForHang).
  23334. +//
  23335. +// If no, we restore our HW to normal input power state:
  23336. +/// RX: restore TR switch to HW controled mode.
  23337. +// TX: restore TX output power (see RtUsbCheckForHang).
  23338. +//
  23339. +// TODO:
  23340. +// 1. Tx power control shall not be done in Platform-dependent timer (e.g. RtUsbCheckForHang).
  23341. +// 2. Allow these threshold adjustable by RF SD.
  23342. +//
  23343. +void DoRxHighPower(struct net_device *dev)
  23344. +{
  23345. + struct r8180_priv *priv = ieee80211_priv(dev);
  23346. + TR_SWITCH_STATE TrSwState;
  23347. + u16 HiPwrUpperTh = 0;
  23348. + u16 HiPwrLowerTh = 0;
  23349. + u16 RSSIHiPwrUpperTh = 0;
  23350. + u16 RSSIHiPwrLowerTh = 0;
  23351. +
  23352. + //87S remove TrSwitch mechanism
  23353. + if((priv->card_8187 == NIC_8187B)||(priv->card_8187 == NIC_8187)) {
  23354. +
  23355. + //printk("----> DoRxHighPower()\n");
  23356. +
  23357. + //
  23358. + // Get current TR switch setting.
  23359. + //
  23360. + //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_TR_SWITCH, (pu1Byte)(&TrSwState));
  23361. + TrSwState = priv->TrSwitchState;
  23362. +
  23363. + //
  23364. + // Determine threshold according to RF type.
  23365. + //
  23366. + switch(priv->rf_chip)
  23367. + {
  23368. + case RF_ZEBRA:
  23369. + HiPwrUpperTh = Z1_HIPWR_UPPER_TH;
  23370. + HiPwrLowerTh = Z1_HIPWR_LOWER_TH;
  23371. + printk("DoRxHighPower(): RF_ZEBRA, Upper Threshold: %d LOWER Threshold: %d\n",
  23372. + HiPwrUpperTh, HiPwrLowerTh);
  23373. + break;
  23374. +
  23375. + case RF_ZEBRA2:
  23376. + if((priv->card_8187 == NIC_8187)) {
  23377. + HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
  23378. + HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
  23379. + } else {
  23380. + // By Bruce, 2007-04-11.
  23381. + // HiPwrUpperTh = Z2_HIPWR_UPPER_TH;
  23382. + // HiPwrLowerTh = Z2_HIPWR_LOWER_TH;
  23383. +
  23384. + HiPwrUpperTh = priv->Z2HiPwrUpperTh;
  23385. + HiPwrLowerTh = priv->Z2HiPwrLowerTh;
  23386. + HiPwrUpperTh = HiPwrUpperTh * 10;
  23387. + HiPwrLowerTh = HiPwrLowerTh * 10;
  23388. +
  23389. + RSSIHiPwrUpperTh = priv->Z2RSSIHiPwrUpperTh;
  23390. + RSSIHiPwrLowerTh = priv->Z2RSSIHiPwrLowerTh;
  23391. + //printk("DoRxHighPower(): RF_ZEBRA2, Upper Threshold: %d LOWER Threshold: %d, RSSI Upper Th: %d, RSSI Lower Th: %d\n",HiPwrUpperTh, HiPwrLowerTh, RSSIHiPwrUpperTh, RSSIHiPwrLowerTh);
  23392. + }
  23393. + break;
  23394. +
  23395. + default:
  23396. + printk("DoRxHighPower(): Unknown RFChipID(%d), UndecoratedSmoothedSS(%d), TrSwState(%d)!!!\n",
  23397. + priv->rf_chip, priv->UndecoratedSmoothedSS, TrSwState);
  23398. + return;
  23399. + break;
  23400. + }
  23401. +
  23402. + /*printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",\
  23403. + priv->UndecoratedSmoothedSS, priv->CurCCKRSSI);
  23404. + */
  23405. + if((priv->card_8187 == NIC_8187)) {
  23406. + //
  23407. + // Perform Rx part High Power Mechanism by UndecoratedSmoothedSS.
  23408. + //
  23409. + if (priv->UndecoratedSmoothedSS > HiPwrUpperTh)
  23410. + { // High input power state.
  23411. + if( priv->TrSwitchState == TR_HW_CONTROLLED )
  23412. + {
  23413. + /* printk(">>>>>>>>>>Set TR switch to software control, UndecoratedSmoothedSS:%d \n", \
  23414. + priv->UndecoratedSmoothedSS);
  23415. + // printk(">>>>>>>>>> TR_SW_TX\n");
  23416. + */
  23417. + write_nic_byte(dev, RFPinsSelect,
  23418. + (u8)(priv->wMacRegRfPinsSelect | TR_SW_MASK_8187 ));
  23419. + write_nic_byte(dev, RFPinsOutput,
  23420. + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
  23421. + priv->TrSwitchState = TR_SW_TX;
  23422. + priv->bToUpdateTxPwr = true;
  23423. + }
  23424. + }
  23425. + else if (priv->UndecoratedSmoothedSS < HiPwrLowerTh)
  23426. + { // Normal input power state.
  23427. + if( priv->TrSwitchState == TR_SW_TX)
  23428. + {
  23429. + /* printk("<<<<<<<<<<<Set TR switch to hardware control UndecoratedSmoothedSS:%d \n", \
  23430. + priv->UndecoratedSmoothedSS);
  23431. + // printk("<<<<<<<<<< TR_HW_CONTROLLED\n");
  23432. + */
  23433. + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
  23434. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
  23435. + priv->TrSwitchState = TR_HW_CONTROLLED;
  23436. + priv->bToUpdateTxPwr = true;
  23437. + }
  23438. + }
  23439. + }else {
  23440. + /*printk("=====>TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
  23441. + //printk("UndecoratedSmoothedSS:%d, CurCCKRSSI = %d\n",priv->UndecoratedSmoothedSS, priv->CurCCKRSSI); */
  23442. + // Asked by SD3 DZ, by Bruce, 2007-04-12.
  23443. + if(TrSwState == TR_HW_CONTROLLED)
  23444. + {
  23445. + if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
  23446. + (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
  23447. + {
  23448. + //printk("===============================> high power!\n");
  23449. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect|TR_SW_MASK_8187 ));
  23450. + write_nic_byte(dev, RFPinsOutput,
  23451. + (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187));
  23452. + priv->TrSwitchState = TR_SW_TX;
  23453. + priv->bToUpdateTxPwr = true;
  23454. + }
  23455. + }
  23456. + else
  23457. + {
  23458. + if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
  23459. + (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
  23460. + {
  23461. + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
  23462. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
  23463. + priv->TrSwitchState = TR_HW_CONTROLLED;
  23464. + priv->bToUpdateTxPwr = true;
  23465. + }
  23466. + }
  23467. + //printk("<=======TrSwState = %s\n", (TrSwState==TR_HW_CONTROLLED)?"TR_HW_CONTROLLED":"TR_SW_TX");
  23468. + }
  23469. + //printk("<---- DoRxHighPower()\n");
  23470. + }
  23471. +}
  23472. +
  23473. +
  23474. +//
  23475. +// Description:
  23476. +// Callback function of UpdateTxPowerWorkItem.
  23477. +// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
  23478. +// We update Tx power of current channel again.
  23479. +//
  23480. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  23481. +void rtl8180_tx_pw_wq (struct work_struct *work)
  23482. +{
  23483. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  23484. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
  23485. + struct net_device *dev = ieee->dev;
  23486. +#else
  23487. +void rtl8180_tx_pw_wq(struct net_device *dev)
  23488. +{
  23489. + // struct r8180_priv *priv = ieee80211_priv(dev);
  23490. +#endif
  23491. +
  23492. + struct r8180_priv *priv = ieee80211_priv(dev);
  23493. +
  23494. + //printk("----> UpdateTxPowerWorkItemCallback()\n");
  23495. +
  23496. + if(priv->bToUpdateTxPwr)
  23497. + {
  23498. + //printk("DoTxHighPower(): schedule UpdateTxPowerWorkItem......\n");
  23499. + priv->bToUpdateTxPwr = false;
  23500. + SetTxPowerLevel8187(dev, priv->chan);
  23501. + }
  23502. +
  23503. + DoRxHighPower(dev);
  23504. + //printk("<---- UpdateTxPowerWorkItemCallback()\n");
  23505. +}
  23506. +
  23507. +//
  23508. +// Description:
  23509. +// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
  23510. +//
  23511. +bool CheckHighPower(struct net_device *dev)
  23512. +{
  23513. + struct r8180_priv *priv = ieee80211_priv(dev);
  23514. + struct ieee80211_device *ieee = priv->ieee80211;
  23515. +
  23516. + if(!priv->bRegHighPowerMechanism)
  23517. + {
  23518. + return false;
  23519. + }
  23520. +
  23521. + if((ieee->state == IEEE80211_LINKED_SCANNING)||(ieee->state == IEEE80211_MESH_SCANNING))
  23522. + {
  23523. + return false;
  23524. + }
  23525. +
  23526. + return true;
  23527. +}
  23528. +
  23529. +#ifdef SW_ANTE_DIVERSITY
  23530. +
  23531. +#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
  23532. +
  23533. +void
  23534. +SwAntennaDiversityRxOk8185(
  23535. + struct net_device *dev,
  23536. + u8 SignalStrength
  23537. + )
  23538. +{
  23539. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23540. +
  23541. + //printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
  23542. +
  23543. + priv->AdRxOkCnt++;
  23544. +
  23545. + if( priv->AdRxSignalStrength != -1)
  23546. + {
  23547. + priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
  23548. + }
  23549. + else
  23550. + { // Initialization case.
  23551. + priv->AdRxSignalStrength = SignalStrength;
  23552. + }
  23553. +
  23554. + //printk("====>pkt rcvd by %d\n", priv->LastRxPktAntenna);
  23555. + if( priv->LastRxPktAntenna ) //Main antenna.
  23556. + priv->AdMainAntennaRxOkCnt++;
  23557. + else // Aux antenna.
  23558. + priv->AdAuxAntennaRxOkCnt++;
  23559. + //printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
  23560. +}
  23561. +
  23562. +//
  23563. +// Description: Change Antenna Switch.
  23564. +//
  23565. +bool
  23566. +SetAntenna8185(
  23567. + struct net_device *dev,
  23568. + u8 u1bAntennaIndex
  23569. + )
  23570. +{
  23571. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23572. + bool bAntennaSwitched = false;
  23573. +
  23574. +// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
  23575. +
  23576. + switch(u1bAntennaIndex)
  23577. + {
  23578. + case 0://main antenna
  23579. + switch(priv->rf_chip)
  23580. + {
  23581. + case RF_ZEBRA:
  23582. + case RF_ZEBRA2:
  23583. + //case RF_ZEBRA4:
  23584. + // Tx Antenna.
  23585. + write_nic_byte(dev, ANTSEL, 0x03); // Config TX antenna.
  23586. +
  23587. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x01009b90); // Config CCK RX antenna.
  23588. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x5c8D); // Config OFDM RX antenna.
  23589. +
  23590. + // Rx CCK .
  23591. + write_nic_byte(dev, 0x7f, ((0x01009b90 & 0xff000000) >> 24));
  23592. + write_nic_byte(dev, 0x7e, ((0x01009b90 & 0x00ff0000) >> 16));
  23593. + write_nic_byte(dev, 0x7d, ((0x01009b90 & 0x0000ff00) >> 8));
  23594. + write_nic_byte(dev, 0x7c, ((0x01009b90 & 0x000000ff) >> 0));
  23595. +
  23596. + // Rx OFDM.
  23597. + write_nic_byte(dev, 0x7f, ((0x00005c8D & 0xff000000) >> 24));
  23598. + write_nic_byte(dev, 0x7e, ((0x00005c8D & 0x00ff0000) >> 16));
  23599. + write_nic_byte(dev, 0x7d, ((0x00005c8D & 0x0000ff00) >> 8));
  23600. + write_nic_byte(dev, 0x7c, ((0x00005c8D & 0x000000ff) >> 0));
  23601. +
  23602. + bAntennaSwitched = true;
  23603. + break;
  23604. +
  23605. + default:
  23606. + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
  23607. + break;
  23608. + }
  23609. + break;
  23610. +
  23611. + case 1:
  23612. + switch(priv->rf_chip)
  23613. + {
  23614. + case RF_ZEBRA:
  23615. + case RF_ZEBRA2:
  23616. + //case RF_ZEBRA4:
  23617. + // Tx Antenna.
  23618. + write_nic_byte(dev, ANTSEL, 0x00); // Config TX antenna.
  23619. +
  23620. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x0100bb90); // Config CCK RX antenna.
  23621. + //PlatformEFIOWrite4Byte(Adapter, BBAddr, 0x548D); // Config OFDM RX antenna.
  23622. +
  23623. + // Rx CCK.
  23624. + write_nic_byte(dev, 0x7f, ((0x0100bb90 & 0xff000000) >> 24));
  23625. + write_nic_byte(dev, 0x7e, ((0x0100bb90 & 0x00ff0000) >> 16));
  23626. + write_nic_byte(dev, 0x7d, ((0x0100bb90 & 0x0000ff00) >> 8));
  23627. + write_nic_byte(dev, 0x7c, ((0x0100bb90 & 0x000000ff) >> 0));
  23628. +
  23629. + // Rx OFDM.
  23630. + write_nic_byte(dev, 0x7f, ((0x0000548D & 0xff000000) >> 24));
  23631. + write_nic_byte(dev, 0x7e, ((0x0000548D & 0x00ff0000) >> 16));
  23632. + write_nic_byte(dev, 0x7d, ((0x0000548D & 0x0000ff00) >> 8));
  23633. + write_nic_byte(dev, 0x7c, ((0x0000548D & 0x000000ff) >> 0));
  23634. +
  23635. + bAntennaSwitched = true;
  23636. + break;
  23637. +
  23638. + default:
  23639. + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
  23640. + break;
  23641. + }
  23642. + break;
  23643. +
  23644. + default:
  23645. + printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
  23646. + break;
  23647. + }
  23648. +
  23649. + if(bAntennaSwitched)
  23650. + {
  23651. + priv->CurrAntennaIndex = u1bAntennaIndex;
  23652. + }
  23653. +
  23654. +// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
  23655. +
  23656. + return bAntennaSwitched;
  23657. +}
  23658. +
  23659. +//
  23660. +// Description: Toggle Antenna switch.
  23661. +//
  23662. +bool SwitchAntenna(struct net_device *dev)
  23663. +{
  23664. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23665. +
  23666. + bool bResult = false;
  23667. +
  23668. + if(priv->CurrAntennaIndex == 0)
  23669. + {
  23670. + bResult = SetAntenna8185(dev, 1);
  23671. + if(priv->ieee80211->state == IEEE80211_LINKED)
  23672. + printk("Switching to Aux antenna 1 \n");
  23673. + }
  23674. + else
  23675. + {
  23676. + bResult = SetAntenna8185(dev, 0);
  23677. + if(priv->ieee80211->state == IEEE80211_LINKED)
  23678. + printk("Switching to Main antenna 0 \n");
  23679. + }
  23680. +
  23681. + return bResult;
  23682. +}
  23683. +
  23684. +//
  23685. +// Description:
  23686. +// Engine of SW Antenna Diversity mechanism.
  23687. +// Since 8187 has no Tx part information,
  23688. +// this implementation is only dependend on Rx part information.
  23689. +//
  23690. +// 2006.04.17, by rcnjko.
  23691. +//
  23692. +void SwAntennaDiversity(struct net_device *dev)
  23693. +{
  23694. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23695. + //bool bSwCheckSS=false;
  23696. + bool bSwCheckSS=true;//open the SignalStrength check if not switched by rx ok pkt.
  23697. +
  23698. +// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
  23699. +
  23700. +//by amy 080312
  23701. + if(bSwCheckSS){
  23702. + priv->AdTickCount++;
  23703. +
  23704. + //printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod);
  23705. + //printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
  23706. + }
  23707. +// priv->AdTickCount++;//-by amy 080312
  23708. +
  23709. + // Case 1. No Link.
  23710. + if(priv->ieee80211->state != IEEE80211_LINKED){
  23711. + //printk("SwAntennaDiversity(): Case 1. No Link.\n");
  23712. +
  23713. + priv->bAdSwitchedChecking = false;
  23714. + // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
  23715. + SwitchAntenna(dev);
  23716. + }
  23717. + // Case 2. Linked but no packet received.
  23718. + else if(priv->AdRxOkCnt == 0){
  23719. + printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
  23720. +
  23721. + priv->bAdSwitchedChecking = false;
  23722. + SwitchAntenna(dev);
  23723. + }
  23724. + // Case 3. Evaluate last antenna switch action in case4. and undo it if necessary.
  23725. + else if(priv->bAdSwitchedChecking == true){
  23726. + //printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
  23727. +
  23728. + priv->bAdSwitchedChecking = false;
  23729. +
  23730. + // Adjust Rx signal strength threashold.
  23731. + priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
  23732. +
  23733. + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
  23734. + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
  23735. + if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched){
  23736. + // Rx signal strength is not improved after we swtiched antenna. => Swich back.
  23737. + printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
  23738. +
  23739. + //by amy 080312
  23740. + // Increase Antenna Diversity checking period due to bad decision.
  23741. + priv->AdCheckPeriod *= 2;
  23742. + //by amy 080312
  23743. + //
  23744. + // Increase Antenna Diversity checking period.
  23745. + if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
  23746. + priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
  23747. +
  23748. + // Wrong deceision => switch back.
  23749. + SwitchAntenna(dev);
  23750. + }else{ // Rx Signal Strength is improved.
  23751. + printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %ld, LastRxSs: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
  23752. +
  23753. + // Reset Antenna Diversity checking period to its min value.
  23754. + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
  23755. + }
  23756. +
  23757. + //printk("SwAntennaDiversity(): AdRxSsThreshold: %ld, AdCheckPeriod: %d\n",
  23758. + // priv->AdRxSsThreshold, priv->AdCheckPeriod);
  23759. + }
  23760. + // Case 4. Evaluate if we shall switch antenna now.
  23761. + // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
  23762. + else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
  23763. + {
  23764. + //printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
  23765. +
  23766. + priv->AdTickCount = 0;
  23767. +
  23768. + //
  23769. + // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
  23770. + // evaluate signal strength.
  23771. + // The following operation can overcome the disability of CCA on both two antennas
  23772. + // When signal strength was extremely low or high.
  23773. + // 2008.01.30.
  23774. + //
  23775. +
  23776. + //
  23777. + // Evaluate RxOk count from each antenna if we shall switch default antenna now.
  23778. + // Added by Roger, 2008.02.21.
  23779. +
  23780. + //{by amy 080312
  23781. + if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)){
  23782. + // We set Main antenna as default but RxOk count was less than Aux ones.
  23783. +
  23784. + printk("SwAntennaDiversity(): Main antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
  23785. +
  23786. + // Switch to Aux antenna.
  23787. + SwitchAntenna(dev);
  23788. + priv->bHWAdSwitched = true;
  23789. + }else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)){
  23790. + // We set Aux antenna as default but RxOk count was less than Main ones.
  23791. +
  23792. + printk("SwAntennaDiversity(): Aux antenna %d RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
  23793. +
  23794. + // Switch to Main antenna.
  23795. + SwitchAntenna(dev);
  23796. + priv->bHWAdSwitched = true;
  23797. + }else{// Default antenna is better.
  23798. +
  23799. + printk("SwAntennaDiversity(): Current Antenna %d is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",priv->CurrAntennaIndex, priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
  23800. +
  23801. + // Still need to check current signal strength.
  23802. + priv->bHWAdSwitched = false;
  23803. + }
  23804. + //
  23805. + // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
  23806. + // didn't changed by HW evaluation.
  23807. + // 2008.02.27.
  23808. + //
  23809. + // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
  23810. + // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
  23811. + // but AdRxSignalStrength is less than main.
  23812. + // Our guess is that main antenna have lower throughput and get many change
  23813. + // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
  23814. + //
  23815. + if( (!priv->bHWAdSwitched) && (bSwCheckSS)){
  23816. + //by amy 080312}
  23817. +
  23818. + // Evaluate Rx signal strength if we shall switch antenna now.
  23819. + if(priv->AdRxSignalStrength < priv->AdRxSsThreshold){
  23820. + // Rx signal strength is weak => Switch Antenna.
  23821. + printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
  23822. +
  23823. + priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
  23824. + priv->bAdSwitchedChecking = true;
  23825. +
  23826. + SwitchAntenna(dev);
  23827. + }else{ // Rx signal strength is OK.
  23828. + printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %ld, RxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold);
  23829. +
  23830. + priv->bAdSwitchedChecking = false;
  23831. + // Increase Rx signal strength threashold if necessary.
  23832. + if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
  23833. + priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
  23834. + {
  23835. + priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
  23836. + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
  23837. + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
  23838. + }
  23839. +
  23840. + // Reduce Antenna Diversity checking period if possible.
  23841. + if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
  23842. + {
  23843. + priv->AdCheckPeriod /= 2;
  23844. + }
  23845. + }
  23846. + }
  23847. + }
  23848. +//by amy 080312
  23849. + // Reset antenna diversity Rx related statistics.
  23850. + priv->AdRxOkCnt = 0;
  23851. + priv->AdMainAntennaRxOkCnt = 0;
  23852. + priv->AdAuxAntennaRxOkCnt = 0;
  23853. +//by amy 080312
  23854. +
  23855. +// priv->AdRxOkCnt = 0;//-by amy 080312
  23856. +
  23857. + //printk("-SwAntennaDiversity()\n");
  23858. +}
  23859. +
  23860. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  23861. +void SwAntennaWorkItemCallback(struct work_struct *work)
  23862. +{
  23863. + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, SwAntennaWorkItem.work);
  23864. + struct net_device *dev = ieee->dev;
  23865. +#else
  23866. +void SwAntennaWorkItemCallback(struct net_device *dev)
  23867. +{
  23868. +#endif
  23869. + //printk("==>%s \n", __func__);
  23870. + SwAntennaDiversity(dev);
  23871. +}
  23872. +
  23873. +//
  23874. +// Description: Timer callback function of SW Antenna Diversity.
  23875. +//
  23876. +void SwAntennaDiversityTimerCallback(struct net_device *dev)
  23877. +{
  23878. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  23879. + RT_RF_POWER_STATE rtState;
  23880. +
  23881. + //printk("+SwAntennaDiversityTimerCallback()\n");
  23882. +
  23883. + //
  23884. + // We do NOT need to switch antenna while RF is off.
  23885. + // 2007.05.09, added by Roger.
  23886. + //
  23887. + rtState = priv->eRFPowerState;
  23888. + do{
  23889. + if (rtState == eRfOff){
  23890. +// printk("SwAntennaDiversityTimer - RF is OFF.\n");
  23891. + break;
  23892. + }else if (rtState == eRfSleep){
  23893. + // Don't access BB/RF under Disable PLL situation.
  23894. + //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
  23895. + break;
  23896. + }
  23897. +
  23898. + queue_work(priv->ieee80211->wq,(void *)&priv->ieee80211->SwAntennaWorkItem);
  23899. +
  23900. + }while(false);
  23901. +
  23902. + if(priv->up){
  23903. + //priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
  23904. + //add_timer(&priv->SwAntennaDiversityTimer);
  23905. + mod_timer(&priv->SwAntennaDiversityTimer, jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD));
  23906. + }
  23907. +
  23908. +}
  23909. +#endif
  23910. +
  23911. +
  23912. +
  23913. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.h
  23914. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_dm.h 1970-01-01 01:00:00.000000000 +0100
  23915. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_dm.h 2010-05-27 18:12:39.532222207 +0200
  23916. @@ -0,0 +1,38 @@
  23917. +/*
  23918. + Hardware dynamic mechanism for RTL8187B.
  23919. +Notes:
  23920. + This file is ported from RTL8187B Windows driver
  23921. +*/
  23922. +
  23923. +#ifndef R8180_DM_H
  23924. +#define R8180_DM_H
  23925. +
  23926. +#include "r8187.h"
  23927. +
  23928. +bool CheckDig(struct net_device *dev);
  23929. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  23930. +void rtl8180_hw_dig_wq (struct work_struct *work);
  23931. +#else
  23932. +void rtl8180_hw_dig_wq(struct net_device *dev);
  23933. +#endif
  23934. +
  23935. +bool CheckHighPower(struct net_device *dev);
  23936. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  23937. +void rtl8180_tx_pw_wq (struct work_struct *work);
  23938. +#else
  23939. +void rtl8180_tx_pw_wq(struct net_device *dev);
  23940. +#endif
  23941. +
  23942. +//by lzm for antenna
  23943. +#ifdef SW_ANTE_DIVERSITY
  23944. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  23945. +void SwAntennaWorkItemCallback(struct work_struct *work);
  23946. +#else
  23947. +void SwAntennaWorkItemCallback(struct net_device *dev);
  23948. +#endif
  23949. +void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
  23950. +void SwAntennaDiversityTimerCallback(struct net_device *dev);
  23951. +#endif
  23952. +//by lzm for antenna
  23953. +
  23954. +#endif //R8180_PM_H
  23955. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_hw.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_hw.h
  23956. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_hw.h 1970-01-01 01:00:00.000000000 +0100
  23957. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_hw.h 2010-05-27 18:12:39.532222207 +0200
  23958. @@ -0,0 +1,788 @@
  23959. +/*
  23960. + This is part of rtl8187 OpenSource driver.
  23961. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  23962. + Released under the terms of GPL (General Public Licence)
  23963. +
  23964. + Parts of this driver are based on the GPL part of the
  23965. + official Realtek driver.
  23966. + Parts of this driver are based on the rtl8180 driver skeleton
  23967. + from Patric Schenke & Andres Salomon.
  23968. + Parts of this driver are based on the Intel Pro Wireless
  23969. + 2100 GPL driver.
  23970. +
  23971. + We want to tanks the Authors of those projects
  23972. + and the Ndiswrapper project Authors.
  23973. +*/
  23974. +
  23975. +/* Mariusz Matuszek added full registers definition with Realtek's name */
  23976. +
  23977. +/* this file contains register definitions for the rtl8187 MAC controller */
  23978. +#ifndef R8180_HW
  23979. +#define R8180_HW
  23980. +
  23981. +typedef enum _RF_TYPE_8187{
  23982. + RF_TYPE_MIN,
  23983. + RF_ZEBRA = 5,
  23984. + RF_ZEBRA2, // added by Annie, 2005-08-01.
  23985. + RF_TYPE_MAX,
  23986. +}RF_TYPE_8187,*PRF_TYPE_8187;
  23987. +
  23988. +typedef enum _VERSION_8187{
  23989. + // RTL8187
  23990. + VERSION_8187_B, // B-cut
  23991. + VERSION_8187_D, // D-cut
  23992. + // RTL8187B
  23993. + VERSION_8187B_B, // B-cut
  23994. + VERSION_8187B_D, //D-cut //added 2007-9-14
  23995. + VERSION_8187B_E, //E-cut //added 2007-9-14
  23996. +}VERSION_8187,*PVERSION_8187;
  23997. +
  23998. +//by lzm for antenna
  23999. +#ifdef SW_ANTE_DIVERSITY
  24000. +#define RF_PARAM 0x19
  24001. +#define RF_PARAM_DIGPHY_SHIFT 0
  24002. +#define RF_PARAM_ANTBDEFAULT_SHIFT 1
  24003. +#define EEPROM_VERSION 0x3c
  24004. +#define EEPROM_CONFIG2 0x18
  24005. +#define EEPROM_CS_THRESHOLD 0x2F
  24006. +#define EEPROM_RF_PARAM 0x08
  24007. +//// BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable.
  24008. +#define EEPROM_SW_AD_MASK 0x0300
  24009. +#define EEPROM_SW_AD_ENABLE 0x0100
  24010. +//// BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
  24011. +#define EEPROM_DEF_ANT_MASK 0x0C00
  24012. +#define EEPROM_DEF_ANT_1 0x0400
  24013. +
  24014. +#define RCR_EnCS1 BIT29 // enable carrier sense method 1
  24015. +#define RCR_EnCS2 BIT30 // enable carrier sense method 2
  24016. +#endif
  24017. +//by lzm for antenna
  24018. +
  24019. +#define RTL8187_RF_INDEX 0x8225
  24020. +#define RTL8187_REQT_READ 0xc0
  24021. +#define RTL8187_REQT_WRITE 0x40
  24022. +#define RTL8187_REQ_GET_REGS 0x05
  24023. +#define RTL8187_REQ_SET_REGS 0x05
  24024. +
  24025. +
  24026. +
  24027. +#define MAX_TX_URB 5
  24028. +#define MAX_RX_URB 16
  24029. +#define RX_URB_SIZE 0x9C4
  24030. +
  24031. +
  24032. +
  24033. +
  24034. +
  24035. +#define BB_ANTATTEN_CHAN14 0x0c
  24036. +#define BB_ANTENNA_B 0x40
  24037. +
  24038. +#define BB_HOST_BANG (1<<30)
  24039. +#define BB_HOST_BANG_EN (1<<2)
  24040. +#define BB_HOST_BANG_CLK (1<<1)
  24041. +#define BB_HOST_BANG_RW (1<<3)
  24042. +#define BB_HOST_BANG_DATA 1
  24043. +
  24044. +#define ANAPARAM_TXDACOFF_SHIFT 27
  24045. +#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28))
  24046. +#define ANAPARAM_PWR0_SHIFT 28
  24047. +#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20))
  24048. +#define ANAPARAM_PWR1_SHIFT 20
  24049. +
  24050. +#define MAC0 0
  24051. +#define MAC1 1
  24052. +#define MAC2 2
  24053. +#define MAC3 3
  24054. +#define MAC4 4
  24055. +#define MAC5 5
  24056. +
  24057. +#define RXFIFOCOUNT 0x10
  24058. +#define TXFIFOCOUNT 0x12
  24059. +#define BcnIntTime 0x74
  24060. +#define TALLY_SEL 0xfc
  24061. +#define BQREQ 0x13
  24062. +
  24063. +#define CMD 0x37
  24064. +#define CMD_RST_SHIFT 4
  24065. +#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
  24066. +#define CMD_RX_ENABLE_SHIFT 3
  24067. +#define CMD_TX_ENABLE_SHIFT 2
  24068. +
  24069. +#define EPROM_CMD 0x50
  24070. +#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
  24071. +#define EPROM_CMD_OPERATING_MODE_SHIFT 6
  24072. +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
  24073. +#define EPROM_CMD_CONFIG 0x3
  24074. +#define EPROM_CMD_NORMAL 0
  24075. +#define EPROM_CMD_LOAD 1
  24076. +#define EPROM_CMD_PROGRAM 2
  24077. +#define EPROM_CS_SHIFT 3
  24078. +#define EPROM_CK_SHIFT 2
  24079. +#define EPROM_W_SHIFT 1
  24080. +#define EPROM_R_SHIFT 0
  24081. +#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
  24082. +#define INTA 0x3e
  24083. +#define INTA_TXOVERFLOW (1<<15)
  24084. +#define INTA_TIMEOUT (1<<14)
  24085. +#define INTA_BEACONTIMEOUT (1<<13)
  24086. +#define INTA_ATIM (1<<12)
  24087. +#define INTA_BEACONDESCERR (1<<11)
  24088. +#define INTA_BEACONDESCOK (1<<10)
  24089. +#define INTA_HIPRIORITYDESCERR (1<<9)
  24090. +#define INTA_HIPRIORITYDESCOK (1<<8)
  24091. +#define INTA_NORMPRIORITYDESCERR (1<<7)
  24092. +#define INTA_NORMPRIORITYDESCOK (1<<6)
  24093. +#define INTA_RXOVERFLOW (1<<5)
  24094. +#define INTA_RXDESCERR (1<<4)
  24095. +#define INTA_LOWPRIORITYDESCERR (1<<3)
  24096. +#define INTA_LOWPRIORITYDESCOK (1<<2)
  24097. +#define INTA_RXCRCERR (1<<1)
  24098. +#define INTA_RXOK (1)
  24099. +#define INTA_MASK 0x3c
  24100. +#define RXRING_ADDR 0xe4 // page 0
  24101. +#define PGSELECT 0x5e
  24102. +#define PGSELECT_PG_SHIFT 0
  24103. +#define RX_CONF 0x44
  24104. +#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
  24105. +(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
  24106. +#define RX_CHECK_BSSID_SHIFT 23
  24107. +#define ACCEPT_PWR_FRAME_SHIFT 22
  24108. +#define ACCEPT_MNG_FRAME_SHIFT 20
  24109. +#define ACCEPT_CTL_FRAME_SHIFT 19
  24110. +#define ACCEPT_DATA_FRAME_SHIFT 18
  24111. +#define ACCEPT_ICVERR_FRAME_SHIFT 12
  24112. +#define ACCEPT_CRCERR_FRAME_SHIFT 5
  24113. +#define ACCEPT_BCAST_FRAME_SHIFT 3
  24114. +#define ACCEPT_MCAST_FRAME_SHIFT 2
  24115. +#define ACCEPT_ALLMAC_FRAME_SHIFT 0
  24116. +#define ACCEPT_NICMAC_FRAME_SHIFT 1
  24117. +#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
  24118. +#define RX_FIFO_THRESHOLD_SHIFT 13
  24119. +#define RX_FIFO_THRESHOLD_128 3
  24120. +#define RX_FIFO_THRESHOLD_256 4
  24121. +#define RX_FIFO_THRESHOLD_512 5
  24122. +#define RX_FIFO_THRESHOLD_1024 6
  24123. +#define RX_FIFO_THRESHOLD_NONE 7
  24124. +#define RX_AUTORESETPHY_SHIFT 28
  24125. +#define EPROM_TYPE_SHIFT 6
  24126. +#define TX_CONF 0x40
  24127. +#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
  24128. +#define TX_LOOPBACK_SHIFT 17
  24129. +#define TX_LOOPBACK_MAC 1
  24130. +#define TX_LOOPBACK_BASEBAND 2
  24131. +#define TX_LOOPBACK_NONE 0
  24132. +#define TX_LOOPBACK_CONTINUE 3
  24133. +#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
  24134. +#define TX_LRLRETRY_SHIFT 0
  24135. +#define R8180_MAX_RETRY 255
  24136. +#define TX_SRLRETRY_SHIFT 8
  24137. +#define TX_NOICV_SHIFT 19
  24138. +#define TX_NOCRC_SHIFT 16
  24139. +#define TX_DMA_POLLING 0xd9
  24140. +#define TX_DMA_POLLING_BEACON_SHIFT 7
  24141. +#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
  24142. +#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
  24143. +#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
  24144. +#define TX_DMA_STOP_BEACON_SHIFT 3
  24145. +#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
  24146. +#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
  24147. +#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
  24148. +#define TX_NORMPRIORITY_RING_ADDR 0x24
  24149. +#define TX_HIGHPRIORITY_RING_ADDR 0x28
  24150. +#define TX_LOWPRIORITY_RING_ADDR 0x20
  24151. +#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
  24152. +#define MAX_RX_DMA_2048 7
  24153. +#define MAX_RX_DMA_1024 6
  24154. +#define MAX_RX_DMA_SHIFT 10
  24155. +#define INT_TIMEOUT 0x48
  24156. +#define CONFIG3_CLKRUN_SHIFT 2
  24157. +#define CONFIG3_ANAPARAM_W_SHIFT 6
  24158. +#define ANAPARAM 0x54
  24159. +#define BEACON_INTERVAL 0x70
  24160. +#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
  24161. +(1<<6)|(1<<7)|(1<<8)|(1<<9))
  24162. +#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
  24163. +(1<<8)|(1<<9))
  24164. +#define ATIM 0x72
  24165. +#define EPROM_CS_SHIFT 3
  24166. +#define EPROM_CK_SHIFT 2
  24167. +#define PHY_DELAY 0x78
  24168. +#define PHY_CONFIG 0x80
  24169. +#define PHY_ADR 0x7c
  24170. +#define PHY_READ 0x7e
  24171. +#define CARRIER_SENSE_COUNTER 0x79 //byte
  24172. +#define SECURITY 0x5f
  24173. +#define SECURITY_WEP_TX_ENABLE_SHIFT 1
  24174. +#define SECURITY_WEP_RX_ENABLE_SHIFT 0
  24175. +#define SECURITY_ENCRYP_104 1
  24176. +#define SECURITY_ENCRYP_SHIFT 4
  24177. +#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
  24178. +#define KEY0 0x90
  24179. +#define CONFIG2_ANTENNA_SHIFT 6
  24180. +#define TX_BEACON_RING_ADDR 0x4c
  24181. +#define CONFIG0_WEP40_SHIFT 7
  24182. +#define CONFIG0_WEP104_SHIFT 6
  24183. +#define AGCRESET_SHIFT 5
  24184. +
  24185. +
  24186. +
  24187. +/*
  24188. + * Operational registers offsets in PCI (I/O) space.
  24189. + * RealTek names are used.
  24190. + */
  24191. +
  24192. +#define IDR0 0x0000
  24193. +#define IDR1 0x0001
  24194. +#define IDR2 0x0002
  24195. +#define IDR3 0x0003
  24196. +#define IDR4 0x0004
  24197. +#define IDR5 0x0005
  24198. +
  24199. +/* 0x0006 - 0x0007 - reserved */
  24200. +
  24201. +#define MAR0 0x0008
  24202. +#define MAR1 0x0009
  24203. +#define MAR2 0x000A
  24204. +#define MAR3 0x000B
  24205. +#define MAR4 0x000C
  24206. +#define MAR5 0x000D
  24207. +#define MAR6 0x000E
  24208. +#define MAR7 0x000F
  24209. +
  24210. +/* 0x0010 - 0x0017 - reserved */
  24211. +
  24212. +#define TSFTR 0x0018
  24213. +#define TSFTR_END 0x001F
  24214. +
  24215. +#define TLPDA 0x0020
  24216. +#define TLPDA_END 0x0023
  24217. +#define TNPDA 0x0024
  24218. +#define TNPDA_END 0x0027
  24219. +#define THPDA 0x0028
  24220. +#define THPDA_END 0x002B
  24221. +
  24222. +#define BRSR_8187 0x002C
  24223. +#define BRSR_8187_END 0x002D
  24224. +#define BRSR_8187B 0x0034
  24225. +#define BRSR_8187B_END 0x0035
  24226. +
  24227. +#define BSSID 0x002E
  24228. +#define BSSID_END 0x0033
  24229. +
  24230. +/* 0x0034 - 0x0034 - reserved */
  24231. +
  24232. +/* 0x0038 - 0x003B - reserved */
  24233. +
  24234. +#define IMR 0x003C
  24235. +#define IMR_END 0x003D
  24236. +
  24237. +#define ISR 0x003E
  24238. +#define ISR_END 0x003F
  24239. +
  24240. +#define TCR 0x0040
  24241. +#define TCR_END 0x0043
  24242. +
  24243. +#define RCR 0x0044
  24244. +#define RCR_END 0x0047
  24245. +
  24246. +#define TimerInt 0x0048
  24247. +#define TimerInt_END 0x004B
  24248. +
  24249. +#define TBDA 0x004C
  24250. +#define TBDA_END 0x004F
  24251. +
  24252. +#define CR9346 0x0050
  24253. +
  24254. +#define CONFIG0 0x0051
  24255. +#define CONFIG1 0x0052
  24256. +#define CONFIG2 0x0053
  24257. +
  24258. +#define ANA_PARAM 0x0054
  24259. +#define ANA_PARAM_END 0x0x0057
  24260. +
  24261. +#define MSR 0x0058
  24262. +
  24263. +#define CONFIG3 0x0059
  24264. +#define CONFIG4 0x005A
  24265. +
  24266. +#define TESTR 0x005B
  24267. +
  24268. +/* 0x005C - 0x005D - reserved */
  24269. +#define TFPC_AC 0x005C
  24270. +#define PSR 0x005E
  24271. +
  24272. +#define SCR 0x005F
  24273. +
  24274. +/* 0x0060 - 0x006F - reserved */
  24275. +#define ANA_PARAM2 0x0060
  24276. +#define ANA_PARAM2_END 0x0063
  24277. +
  24278. +#define BcnIntv 0x0070
  24279. +#define BcnItv_END 0x0071
  24280. +
  24281. +#define AtimWnd 0x0072
  24282. +#define AtimWnd_END 0x0073
  24283. +
  24284. +#define BintrItv 0x0074
  24285. +#define BintrItv_END 0x0075
  24286. +
  24287. +#define AtimtrItv 0x0076
  24288. +#define AtimtrItv_END 0x0077
  24289. +
  24290. +#define PhyDelay 0x0078
  24291. +
  24292. +//#define CRCount 0x0079
  24293. +
  24294. +#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us.
  24295. +/* 0x007A - 0x007B - reserved */
  24296. +#define BBAddr 0x007C
  24297. +
  24298. +
  24299. +#define PhyAddr 0x007C
  24300. +#define PhyDataW 0x007D
  24301. +#define PhyDataR 0x007E
  24302. +#define RF_Ready 0x007F
  24303. +
  24304. +#define PhyCFG 0x0080
  24305. +#define PhyCFG_END 0x0083
  24306. +
  24307. +/* following are for rtl8185 */
  24308. +#define RFPinsOutput 0x80
  24309. +#define RFPinsEnable 0x82
  24310. +#define RF_TIMING 0x8c
  24311. +#define RFPinsSelect 0x84
  24312. +#define ANAPARAM2 0x60
  24313. +#define RF_PARA 0x88
  24314. +#define RFPinsInput 0x86
  24315. +#define GP_ENABLE 0x90
  24316. +#define GPIO 0x91
  24317. +#define HSSI_PARA 0x94 // HSS Parameter
  24318. +#define SW_CONTROL_GPIO 0x400
  24319. +#define CCK_TXAGC 0x9d
  24320. +#define OFDM_TXAGC 0x9e
  24321. +#define ANTSEL 0x9f
  24322. +#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02
  24323. +#define WPA_CONFIG 0xb0
  24324. +#define TX_AGC_CTL 0x9c
  24325. +#define TX_AGC_CTL_PER_PACKET_TXAGC 0x01
  24326. +#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
  24327. +#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
  24328. +#define TX_AGC_CTL_FEEDBACK_ANT 2
  24329. +#define RESP_RATE 0x34
  24330. +#define SIFS 0xb4
  24331. +#define DIFS 0xb5
  24332. +#define EIFS_8187 0x35
  24333. +#define EIFS_8187B 0x2D
  24334. +#define SLOT 0xb6
  24335. +#define CW_VAL 0xbd
  24336. +#define CW_CONF 0xbc
  24337. +#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02
  24338. +#define CW_CONF_PERPACKET_CW 0x01
  24339. +#define CW_CONF_PERPACKET_RETRY_SHIFT 1
  24340. +#define CW_CONF_PERPACKET_CW_SHIFT 0
  24341. +#define MAX_RESP_RATE_SHIFT 4
  24342. +#define MIN_RESP_RATE_SHIFT 0
  24343. +#define RATE_FALLBACK 0xbe
  24344. +#define RATE_FALLBACK_CTL_ENABLE 0x80
  24345. +#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
  24346. +
  24347. +#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
  24348. +#define RMS 0x1EC // Rx Max Pacetk Size (0x1ec[0:12])
  24349. +
  24350. +/*
  24351. + * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
  24352. + * is set to 1
  24353. + */
  24354. +
  24355. +#define Wakeup0 0x0084
  24356. +#define Wakeup0_END 0x008B
  24357. +
  24358. +#define Wakeup1 0x008C
  24359. +#define Wakeup1_END 0x0093
  24360. +
  24361. +#define Wakeup2LD 0x0094
  24362. +#define Wakeup2LD_END 0x009B
  24363. +#define Wakeup2HD 0x009C
  24364. +#define Wakeup2HD_END 0x00A3
  24365. +
  24366. +#define Wakeup3LD 0x00A4
  24367. +#define Wakeup3LD_END 0x00AB
  24368. +#define Wakeup3HD 0x00AC
  24369. +#define Wakeup3HD_END 0x00B3
  24370. +
  24371. +#define Wakeup4LD 0x00B4
  24372. +#define Wakeup4LD_END 0x00BB
  24373. +#define Wakeup4HD 0x00BC
  24374. +#define Wakeup4HD_END 0x00C3
  24375. +
  24376. +#define CRC0 0x00C4
  24377. +#define CRC0_END 0x00C5
  24378. +#define CRC1 0x00C6
  24379. +#define CRC1_END 0x00C7
  24380. +#define CRC2 0x00C8
  24381. +#define CRC2_END 0x00C9
  24382. +#define CRC3 0x00CA
  24383. +#define CRC3_END 0x00CB
  24384. +#define CRC4 0x00CC
  24385. +#define CRC4_END 0x00CD
  24386. +
  24387. +/* 0x00CE - 0x00D3 - reserved */
  24388. +
  24389. +
  24390. +
  24391. +/*
  24392. + * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
  24393. + * is set to 0
  24394. + */
  24395. +
  24396. +/* 0x0084 - 0x008F - reserved */
  24397. +
  24398. +#define DK0 0x0090
  24399. +#define DK0_END 0x009F
  24400. +#define DK1 0x00A0
  24401. +#define DK1_END 0x00AF
  24402. +#define DK2 0x00B0
  24403. +#define DK2_END 0x00BF
  24404. +#define DK3 0x00C0
  24405. +#define DK3_END 0x00CF
  24406. +
  24407. +#define GPO 0x90
  24408. +#define GPE 0x91
  24409. +#define GPI 0x92
  24410. +
  24411. +#define RFTiming 0x008C
  24412. +#define ACM_CONTROL 0x00BF // ACM Control Registe
  24413. +#define INT_MIG 0x00E2 // Interrupt Migration (0xE2 ~ 0xE3)
  24414. +#define TID_AC_MAP 0x00E8 // TID to AC Mapping Register
  24415. +
  24416. +#define AC_VO_PARAM 0x00F0 // AC_VO Parameters Record
  24417. +#define AC_VI_PARAM 0x00F4 // AC_VI Parameters Record
  24418. +#define AC_BE_PARAM 0x00F8 // AC_BE Parameters Record
  24419. +#define AC_BK_PARAM 0x00FC // AC_BK Parameters Record
  24420. +
  24421. +/* 0x00D0 - 0x00D3 - reserved */
  24422. +#define CCK_FALSE_ALARM 0x00D0
  24423. +#define OFDM_FALSE_ALARM 0x00D2
  24424. +
  24425. +
  24426. +/* 0x00D4 - 0x00D7 - reserved */
  24427. +
  24428. +#define CONFIG5 0x00D8
  24429. +
  24430. +#define TPPoll 0x00D9
  24431. +
  24432. +/* 0x00DA - 0x00DB - reserved */
  24433. +
  24434. +#define CWR 0x00DC
  24435. +#define CWR_END 0x00DD
  24436. +
  24437. +#define RetryCTR 0x00DE
  24438. +
  24439. +/* 0x00DF - 0x00E3 - reserved */
  24440. +
  24441. +#define RDSAR 0x00E4
  24442. +#define RDSAR_END 0x00E7
  24443. +
  24444. +/* 0x00E8 - 0x00EF - reserved */
  24445. +#define ANA_PARAM3 0x00EE
  24446. +
  24447. +#define FER 0x00F0
  24448. +#define FER_END 0x00F3
  24449. +
  24450. +#define FEMR 0x1D4 // Function Event Mask register (0xf4 ~ 0xf7)
  24451. +//#define FEMR 0x00F4
  24452. +#define FEMR_END 0x00F7
  24453. +
  24454. +#define FPSR 0x00F8
  24455. +#define FPSR_END 0x00FB
  24456. +
  24457. +#define FFER 0x00FC
  24458. +#define FFER_END 0x00FF
  24459. +
  24460. +/*
  24461. + * 0x0000 - 0x00ff is selected to page 0 when PSEn bit (bit0, PSR)
  24462. + * is set to 2
  24463. + */
  24464. +#define RFSW_CTRL 0x272 // 0x272-0x273.
  24465. +
  24466. +
  24467. +
  24468. +//----------------------------------------------------------------------------
  24469. +// 8187B AC_XX_PARAM bits
  24470. +//----------------------------------------------------------------------------
  24471. +#define AC_PARAM_TXOP_LIMIT_OFFSET 16
  24472. +#define AC_PARAM_ECW_MAX_OFFSET 12
  24473. +#define AC_PARAM_ECW_MIN_OFFSET 8
  24474. +#define AC_PARAM_AIFS_OFFSET 0
  24475. +
  24476. +//----------------------------------------------------------------------------
  24477. +// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
  24478. +//----------------------------------------------------------------------------
  24479. +#define VOQ_ACM_EN (0x01 << 7) //BIT7
  24480. +#define VIQ_ACM_EN (0x01 << 6) //BIT6
  24481. +#define BEQ_ACM_EN (0x01 << 5) //BIT5
  24482. +#define ACM_HW_EN (0x01 << 4) //BIT4
  24483. +#define TXOPSEL (0x01 << 3) //BIT3
  24484. +#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
  24485. +#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
  24486. +#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
  24487. +
  24488. +//----------------------------------------------------------------------------
  24489. +// 8187B RF pins related setting (offset 0xFF80-0xFF87,)
  24490. +//----------------------------------------------------------------------------
  24491. +#define TR_SW_MASK_TX_8187 BIT5
  24492. +#define TR_SW_MASK_RX_8187 BIT6
  24493. +#define TR_SW_MASK_8187 (TR_SW_MASK_TX_8187 | TR_SW_MASK_RX_8187)
  24494. +
  24495. +/*
  24496. + * Bitmasks for specific register functions.
  24497. + * Names are derived from the register name and function name.
  24498. + *
  24499. + * <REGISTER>_<FUNCTION>[<bit>]
  24500. + *
  24501. + * this leads to some awkward names...
  24502. + */
  24503. +
  24504. +#define BRSR_BPLCP ((1<< 8))
  24505. +#define BRSR_MBR ((1<< 1)|(1<< 0))
  24506. +#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))
  24507. +#define BRSR_MBR0 ((1<< 0))
  24508. +#define BRSR_MBR1 ((1<< 1))
  24509. +
  24510. +#define CR_RST ((1<< 4))
  24511. +#define CR_RE ((1<< 3))
  24512. +#define CR_TE ((1<< 2))
  24513. +#define CR_MulRW ((1<< 0))
  24514. +
  24515. +#define IMR_TXFOVW ((1<<15))
  24516. +#define IMR_TimeOut ((1<<14))
  24517. +#define IMR_BcnInt ((1<<13))
  24518. +#define IMR_ATIMInt ((1<<12))
  24519. +#define IMR_TBDER ((1<<11))
  24520. +#define IMR_TBDOK ((1<<10))
  24521. +#define IMR_THPDER ((1<< 9))
  24522. +#define IMR_THPDOK ((1<< 8))
  24523. +#define IMR_TNPDER ((1<< 7))
  24524. +#define IMR_TNPDOK ((1<< 6))
  24525. +#define IMR_RXFOVW ((1<< 5))
  24526. +#define IMR_RDU ((1<< 4))
  24527. +#define IMR_TLPDER ((1<< 3))
  24528. +#define IMR_TLPDOK ((1<< 2))
  24529. +#define IMR_RER ((1<< 1))
  24530. +#define IMR_ROK ((1<< 0))
  24531. +
  24532. +#define ISR_TXFOVW ((1<<15))
  24533. +#define ISR_TimeOut ((1<<14))
  24534. +#define ISR_BcnInt ((1<<13))
  24535. +#define ISR_ATIMInt ((1<<12))
  24536. +#define ISR_TBDER ((1<<11))
  24537. +#define ISR_TBDOK ((1<<10))
  24538. +#define ISR_THPDER ((1<< 9))
  24539. +#define ISR_THPDOK ((1<< 8))
  24540. +#define ISR_TNPDER ((1<< 7))
  24541. +#define ISR_TNPDOK ((1<< 6))
  24542. +#define ISR_RXFOVW ((1<< 5))
  24543. +#define ISR_RDU ((1<< 4))
  24544. +#define ISR_TLPDER ((1<< 3))
  24545. +#define ISR_TLPDOK ((1<< 2))
  24546. +#define ISR_RER ((1<< 1))
  24547. +#define ISR_ROK ((1<< 0))
  24548. +
  24549. +#define HW_VERID_R8180_F 3
  24550. +#define HW_VERID_R8180_ABCD 2
  24551. +#define HW_VERID_R8185_ABC 4
  24552. +#define HW_VERID_R8185_D 5
  24553. +
  24554. +#define TCR_DurProcMode ((1<<30))
  24555. +#define TCR_DISReqQsize ((1<<28))
  24556. +#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
  24557. +#define TCR_HWVERID_SHIFT 25
  24558. +#define TCR_SWPLCPLEN ((1<<24))
  24559. +#define TCR_PLCP_LEN TCR_SAT // rtl8180
  24560. +#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21))
  24561. +#define TCR_MXDMA_1024 6
  24562. +#define TCR_MXDMA_2048 7
  24563. +#define TCR_MXDMA_SHIFT 21
  24564. +#define TCR_DISCW ((1<<20))
  24565. +#define TCR_ICV ((1<<19))
  24566. +#define TCR_LBK ((1<<18)|(1<<17))
  24567. +#define TCR_LBK1 ((1<<18))
  24568. +#define TCR_LBK0 ((1<<17))
  24569. +#define TCR_CRC ((1<<16))
  24570. +#define TCR_SRL_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
  24571. +#define TCR_LRL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
  24572. +#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
  24573. +
  24574. +#define RCR_ONLYERLPKT ((1<<31))
  24575. +#define RCR_CS_SHIFT 29
  24576. +#define RCR_CS_MASK ((1<<30) | (1<<29))
  24577. +#define RCR_ENMARP ((1<<28))
  24578. +#define RCR_CBSSID ((1<<23))
  24579. +#define RCR_APWRMGT ((1<<22))
  24580. +#define RCR_ADD3 ((1<<21))
  24581. +#define RCR_AMF ((1<<20))
  24582. +#define RCR_ACF ((1<<19))
  24583. +#define RCR_ADF ((1<<18))
  24584. +#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13))
  24585. +#define RCR_RXFTH2 ((1<<15))
  24586. +#define RCR_RXFTH1 ((1<<14))
  24587. +#define RCR_RXFTH0 ((1<<13))
  24588. +#define RCR_AICV ((1<<12))
  24589. +#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8))
  24590. +#define RCR_MXDMA2 ((1<<10))
  24591. +#define RCR_MXDMA1 ((1<< 9))
  24592. +#define RCR_MXDMA0 ((1<< 8))
  24593. +#define RCR_9356SEL ((1<< 6))
  24594. +#define RCR_ACRC32 ((1<< 5))
  24595. +#define RCR_AB ((1<< 3))
  24596. +#define RCR_AM ((1<< 2))
  24597. +#define RCR_APM ((1<< 1))
  24598. +#define RCR_AAP ((1<< 0))
  24599. +
  24600. +#define CR9346_EEM ((1<<7)|(1<<6))
  24601. +#define CR9346_EEM1 ((1<<7))
  24602. +#define CR9346_EEM0 ((1<<6))
  24603. +#define CR9346_EECS ((1<<3))
  24604. +#define CR9346_EESK ((1<<2))
  24605. +#define CR9346_EED1 ((1<<1))
  24606. +#define CR9346_EED0 ((1<<0))
  24607. +
  24608. +#define CONFIG0_WEP104 ((1<<6))
  24609. +#define CONFIG0_LEDGPO_En ((1<<4))
  24610. +#define CONFIG0_Aux_Status ((1<<3))
  24611. +#define CONFIG0_GL ((1<<1)|(1<<0))
  24612. +#define CONFIG0_GL1 ((1<<1))
  24613. +#define CONFIG0_GL0 ((1<<0))
  24614. +
  24615. +#define CONFIG1_LEDS ((1<<7)|(1<<6))
  24616. +#define CONFIG1_LEDS1 ((1<<7))
  24617. +#define CONFIG1_LEDS0 ((1<<6))
  24618. +#define CONFIG1_LWACT ((1<<4))
  24619. +#define CONFIG1_MEMMAP ((1<<3))
  24620. +#define CONFIG1_IOMAP ((1<<2))
  24621. +#define CONFIG1_VPD ((1<<1))
  24622. +#define CONFIG1_PMEn ((1<<0))
  24623. +
  24624. +#define CONFIG2_LCK ((1<<7))
  24625. +#define CONFIG2_ANT ((1<<6))
  24626. +#define CONFIG2_DPS ((1<<3))
  24627. +#define CONFIG2_PAPE_sign ((1<<2))
  24628. +#define CONFIG2_PAPE_time ((1<<1)|(1<<0))
  24629. +#define CONFIG2_PAPE_time1 ((1<<1))
  24630. +#define CONFIG2_PAPE_time0 ((1<<0))
  24631. +
  24632. +#define CONFIG3_GNTSel ((1<<7))
  24633. +#define CONFIG3_PARM_En ((1<<6))
  24634. +#define CONFIG3_Magic ((1<<5))
  24635. +#define CONFIG3_CardB_En ((1<<3))
  24636. +#define CONFIG3_CLKRUN_En ((1<<2))
  24637. +#define CONFIG3_FuncRegEn ((1<<1))
  24638. +#define CONFIG3_FBtbEn ((1<<0))
  24639. +
  24640. +#define CONFIG4_VCOPDN ((1<<7))
  24641. +#define CONFIG4_PWROFF ((1<<6))
  24642. +#define CONFIG4_PWRMGT ((1<<5))
  24643. +#define CONFIG4_LWPME ((1<<4))
  24644. +#define CONFIG4_LWPTN ((1<<2))
  24645. +#define CONFIG4_RFTYPE ((1<<1)|(1<<0))
  24646. +#define CONFIG4_RFTYPE1 ((1<<1))
  24647. +#define CONFIG4_RFTYPE0 ((1<<0))
  24648. +
  24649. +#define CONFIG5_TX_FIFO_OK ((1<<7))
  24650. +#define CONFIG5_RX_FIFO_OK ((1<<6))
  24651. +#define CONFIG5_CALON ((1<<5))
  24652. +#define CONFIG5_EACPI ((1<<2))
  24653. +#define CONFIG5_LANWake ((1<<1))
  24654. +#define CONFIG5_PME_STS ((1<<0))
  24655. +
  24656. +#define MSR_LINK_MASK ((1<<2)|(1<<3))
  24657. +#define MSR_LINK_MANAGED 2
  24658. +#define MSR_LINK_NONE 0
  24659. +#define MSR_LINK_SHIFT 2
  24660. +#define MSR_LINK_ADHOC 1
  24661. +#define MSR_LINK_MASTER 3
  24662. +#define MSR_LINK_ENEDCA (1<<4)
  24663. +
  24664. +#define PSR_GPO ((1<<7))
  24665. +#define PSR_GPI ((1<<6))
  24666. +#define PSR_LEDGPO1 ((1<<5))
  24667. +#define PSR_LEDGPO0 ((1<<4))
  24668. +#define PSR_UWF ((1<<1))
  24669. +#define PSR_PSEn ((1<<0))
  24670. +
  24671. +#define SCR_KM ((1<<5)|(1<<4))
  24672. +#define SCR_KM1 ((1<<5))
  24673. +#define SCR_KM0 ((1<<4))
  24674. +#define SCR_TXSECON ((1<<1))
  24675. +#define SCR_RXSECON ((1<<0))
  24676. +
  24677. +#define BcnItv_BcnItv (0x01FF)
  24678. +
  24679. +#define AtimWnd_AtimWnd (0x01FF)
  24680. +
  24681. +#define BintrItv_BintrItv (0x01FF)
  24682. +
  24683. +#define AtimtrItv_AtimtrItv (0x01FF)
  24684. +
  24685. +#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0))
  24686. +
  24687. +#define TPPoll_BQ ((1<<7))
  24688. +#define TPPoll_HPQ ((1<<6))
  24689. +#define TPPoll_NPQ ((1<<5))
  24690. +#define TPPoll_LPQ ((1<<4))
  24691. +#define TPPoll_SBQ ((1<<3))
  24692. +#define TPPoll_SHPQ ((1<<2))
  24693. +#define TPPoll_SNPQ ((1<<1))
  24694. +#define TPPoll_SLPQ ((1<<0))
  24695. +
  24696. +#define CWR_CW (0x01FF)
  24697. +
  24698. +#define FER_INTR ((1<<15))
  24699. +#define FER_GWAKE ((1<< 4))
  24700. +
  24701. +#define FEMR_INTR ((1<<15))
  24702. +#define FEMR_WKUP ((1<<14))
  24703. +#define FEMR_GWAKE ((1<< 4))
  24704. +
  24705. +#define FPSR_INTR ((1<<15))
  24706. +#define FPSR_GWAKE ((1<< 4))
  24707. +
  24708. +#define FFER_INTR ((1<<15))
  24709. +#define FFER_GWAKE ((1<< 4))
  24710. +
  24711. +
  24712. +//----------------------------------------------------------------------------
  24713. +// 818xB AnaParm & AnaParm2 Register
  24714. +//----------------------------------------------------------------------------
  24715. +/*
  24716. +#ifdef RTL8185B_FPGA
  24717. +#define ANAPARM_FPGA_ON 0xa0000b59
  24718. +//#define ANAPARM_FPGA_OFF
  24719. +#define ANAPARM2_FPGA_ON 0x860dec11
  24720. +//#define ANAPARM2_FPGA_OFF
  24721. +#else //ASIC
  24722. +*/
  24723. +#define ANAPARM_ASIC_ON 0x45090658
  24724. +//#define ANAPARM_ASIC_OFF
  24725. +#define ANAPARM2_ASIC_ON 0x727f3f52
  24726. +//#define ANAPARM2_ASIC_OFF
  24727. +//#endif
  24728. +//by amy for power save
  24729. +#define RF_CHANGE_BY_SW BIT31
  24730. +#define RF_CHANGE_BY_HW BIT30
  24731. +#define RF_CHANGE_BY_PS BIT29
  24732. +#define RF_CHANGE_BY_IPS BIT28
  24733. +#define ANAPARM_ASIC_ON 0x45090658
  24734. +#define ANAPARM2_ASIC_ON 0x727f3f52
  24735. +
  24736. +#define ANAPARM_ON ANAPARM_ASIC_ON
  24737. +#define ANAPARM2_ON ANAPARM2_ASIC_ON
  24738. +#define TFPC 0x5C // Tx FIFO Packet Count for BK, BE, VI, VO queues (2 bytes)
  24739. +#define Config4_PowerOff BIT6 // Turn ON/Off RF Power(RFMD)
  24740. +#define ANAPARM_OFF 0x51480658
  24741. +#define ANAPARM2_OFF 0x72003f70
  24742. +//by amy for power save
  24743. +
  24744. +#define MAX_DOZE_WAITING_TIMES_87B 500
  24745. +
  24746. +#endif
  24747. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.c
  24748. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.c 1970-01-01 01:00:00.000000000 +0100
  24749. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.c 2010-05-27 18:12:39.532222207 +0200
  24750. @@ -0,0 +1,97 @@
  24751. +/*
  24752. + Power management interface routines.
  24753. + Written by Mariusz Matuszek.
  24754. + This code is currently just a placeholder for later work and
  24755. + does not do anything useful.
  24756. +
  24757. + This is part of rtl8180 OpenSource driver.
  24758. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  24759. + Released under the terms of GPL (General Public Licence)
  24760. +*/
  24761. +
  24762. +#ifdef CONFIG_RTL8180_PM
  24763. +
  24764. +
  24765. +#include "r8180_hw.h"
  24766. +#include "r8180_pm.h"
  24767. +#include "r8187.h"
  24768. +int rtl8180_save_state (struct pci_dev *dev, u32 state)
  24769. +{
  24770. + printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
  24771. + return(-EAGAIN);
  24772. +}
  24773. +
  24774. +//netif_running is set to 0 before system call rtl8180_close,
  24775. +//netif_running is set to 1 before system call rtl8180_open,
  24776. +//if open success it will not change, or it change to 0;
  24777. +int rtl8187_suspend (struct usb_interface *intf, pm_message_t state)
  24778. +{
  24779. + struct r8180_priv *priv;
  24780. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  24781. + struct net_device *dev = usb_get_intfdata(intf);
  24782. +#else
  24783. + //struct net_device *dev = (struct net_device *)ptr;
  24784. +#endif
  24785. +
  24786. + printk("====>%s \n", __func__);
  24787. + priv=ieee80211_priv(dev);
  24788. +
  24789. + if(dev) {
  24790. + /* save the old rfkill state and then power off it */
  24791. + priv->eInactivePowerState = priv->eRFPowerState;
  24792. + /* power off the wifi by default */
  24793. + r8187b_wifi_change_rfkill_state(dev, eRfOff);
  24794. +
  24795. + if (!netif_running(dev)) {
  24796. + //printk(KERN_WARNING "UI or other close dev before suspend, go out suspend function\n");
  24797. + return 0;
  24798. + }
  24799. +
  24800. + dev->netdev_ops->ndo_stop(dev);
  24801. + netif_device_detach(dev);
  24802. + }
  24803. + return 0;
  24804. +}
  24805. +
  24806. +
  24807. +int rtl8187_resume (struct usb_interface *intf)
  24808. +{
  24809. + struct r8180_priv *priv;
  24810. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  24811. + struct net_device *dev = usb_get_intfdata(intf);
  24812. +#else
  24813. + //struct net_device *dev = (struct net_device *)ptr;
  24814. +#endif
  24815. +
  24816. + printk("====>%s \n", __func__);
  24817. + priv=ieee80211_priv(dev);
  24818. +
  24819. + if(dev) {
  24820. + /* resume the old rfkill state */
  24821. + r8187b_wifi_change_rfkill_state(dev, priv->eInactivePowerState);
  24822. +
  24823. + if (!netif_running(dev)){
  24824. + //printk(KERN_WARNING "UI or other close dev before suspend, go out resume function\n");
  24825. + return 0;
  24826. + }
  24827. +
  24828. + netif_device_attach(dev);
  24829. + dev->netdev_ops->ndo_open(dev);
  24830. + }
  24831. +
  24832. + return 0;
  24833. +}
  24834. +
  24835. +
  24836. +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
  24837. +{
  24838. +
  24839. + //printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
  24840. + // state, enable);
  24841. + return 0;
  24842. + //return(-EAGAIN);
  24843. +}
  24844. +
  24845. +
  24846. +
  24847. +#endif //CONFIG_RTL8180_PM
  24848. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.h
  24849. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_pm.h 1970-01-01 01:00:00.000000000 +0100
  24850. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_pm.h 2010-05-27 18:12:39.532222207 +0200
  24851. @@ -0,0 +1,28 @@
  24852. +/*
  24853. + Power management interface routines.
  24854. + Written by Mariusz Matuszek.
  24855. + This code is currently just a placeholder for later work and
  24856. + does not do anything useful.
  24857. +
  24858. + This is part of rtl8180 OpenSource driver.
  24859. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  24860. + Released under the terms of GPL (General Public Licence)
  24861. +
  24862. +*/
  24863. +
  24864. +#ifdef CONFIG_RTL8180_PM
  24865. +
  24866. +#ifndef R8180_PM_H
  24867. +#define R8180_PM_H
  24868. +
  24869. +#include <linux/types.h>
  24870. +#include <linux/usb.h>
  24871. +
  24872. +int rtl8180_save_state (struct pci_dev *dev, u32 state);
  24873. +int rtl8187_suspend (struct usb_interface *intf,pm_message_t state);
  24874. +int rtl8187_resume (struct usb_interface *intf);
  24875. +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
  24876. +
  24877. +#endif //R8180_PM_H
  24878. +
  24879. +#endif // CONFIG_RTL8180_PM
  24880. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.c
  24881. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 1970-01-01 01:00:00.000000000 +0100
  24882. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.c 2010-05-27 18:12:39.532222207 +0200
  24883. @@ -0,0 +1,1007 @@
  24884. +/*
  24885. + This is part of the rtl8180-sa2400 driver
  24886. + released under the GPL (See file COPYING for details).
  24887. + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  24888. +
  24889. + This files contains programming code for the rtl8225
  24890. + radio frontend.
  24891. +
  24892. + *Many* thanks to Realtek Corp. for their great support!
  24893. +
  24894. +*/
  24895. +
  24896. +
  24897. +
  24898. +#include "r8180_hw.h"
  24899. +#include "r8180_rtl8225.h"
  24900. +#ifdef ENABLE_DOT11D
  24901. +#include "dot11d.h"
  24902. +#endif
  24903. +
  24904. +#define USE_8051_3WIRE 1
  24905. +
  24906. +u8 rtl8225_threshold[]={
  24907. + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
  24908. +};
  24909. +
  24910. +u8 rtl8225_gain[]={
  24911. + 0x23,0x88,0x7c,0xa5,// -82dbm
  24912. + 0x23,0x88,0x7c,0xb5,// -82dbm
  24913. + 0x23,0x88,0x7c,0xc5,// -82dbm
  24914. + 0x33,0x80,0x79,0xc5,// -78dbm
  24915. + 0x43,0x78,0x76,0xc5,// -74dbm
  24916. + 0x53,0x60,0x73,0xc5,// -70dbm
  24917. + 0x63,0x58,0x70,0xc5,// -66dbm
  24918. +};
  24919. +
  24920. +u16 rtl8225bcd_rxgain[]={
  24921. + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
  24922. + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
  24923. + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
  24924. + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
  24925. + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
  24926. + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
  24927. + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
  24928. + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
  24929. + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
  24930. + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
  24931. + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
  24932. + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
  24933. +
  24934. +};
  24935. +
  24936. +
  24937. +
  24938. +u8 rtl8225_tx_gain_cck_ofdm[]={
  24939. + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
  24940. +};
  24941. +
  24942. +
  24943. +u8 rtl8225_tx_power_ofdm[]={
  24944. + 0x80,0x90,0xa2,0xb5,0xcb,0xe4
  24945. +};
  24946. +
  24947. +
  24948. +u8 rtl8225_tx_power_cck_ch14[]={
  24949. + 0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
  24950. + 0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
  24951. + 0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
  24952. + 0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
  24953. + 0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
  24954. + 0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00
  24955. +};
  24956. +
  24957. +
  24958. +u8 rtl8225_tx_power_cck[]={
  24959. + 0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,
  24960. + 0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,
  24961. + 0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,
  24962. + 0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,
  24963. + 0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,
  24964. + 0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03
  24965. +};
  24966. +
  24967. +u8 rtl8225_agc[]={
  24968. + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
  24969. + 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
  24970. + 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
  24971. + 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
  24972. + 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
  24973. + 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
  24974. + 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  24975. + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  24976. +};
  24977. +
  24978. +u32 rtl8225_chan[] = {
  24979. + 0, //dummy channel 0
  24980. + 0x085c, //1
  24981. + 0x08dc, //2
  24982. + 0x095c, //3
  24983. + 0x09dc, //4
  24984. + 0x0a5c, //5
  24985. + 0x0adc, //6
  24986. + 0x0b5c, //7
  24987. + 0x0bdc, //8
  24988. + 0x0c5c, //9
  24989. + 0x0cdc, //10
  24990. + 0x0d5c, //11
  24991. + 0x0ddc, //12
  24992. + 0x0e5c, //13
  24993. + //0x0f5c, //14
  24994. + 0x0f72, // 14
  24995. +};
  24996. +
  24997. +void rtl8225_set_gain(struct net_device *dev, short gain)
  24998. +{
  24999. + write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
  25000. + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
  25001. + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
  25002. + write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
  25003. +
  25004. +}
  25005. +
  25006. +
  25007. +void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
  25008. +{
  25009. +//in windows the delays in this function was del from 85 to 87,
  25010. +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  25011. +
  25012. +#ifdef USE_8051_3WIRE
  25013. +
  25014. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  25015. + struct usb_device *udev = priv->udev;
  25016. + //u8 bit;
  25017. + //u16 wReg80, wReg82, wReg84;
  25018. + u16 wReg80, wReg84;
  25019. +
  25020. + wReg80 = read_nic_word(dev, RFPinsOutput);
  25021. + wReg80 &= 0xfff3;
  25022. +// wReg82 = read_nic_word(dev, RFPinsEnable);
  25023. + wReg84 = read_nic_word(dev, RFPinsSelect);
  25024. + // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
  25025. + //wReg84 &= 0xfff0;
  25026. + wReg84 &= 0xfff8; //modified by david according to windows segment code.
  25027. +
  25028. + // We must set SW enabled before terminating HW 3-wire, 2005.07.29, by rcnjko.
  25029. +// write_nic_word(dev, RFPinsEnable, (wReg82|0x0007)); // Set To Output Enable
  25030. + write_nic_word(dev, RFPinsSelect, (wReg84|0x0007)); // Set To SW Switch
  25031. +// force_pci_posting(dev);
  25032. +// udelay(10); //
  25033. +
  25034. + write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80)); // Set SI_EN (RFLE)
  25035. +// force_pci_posting(dev);
  25036. +// udelay(2);
  25037. + //twreg.struc.enableB = 0;
  25038. + write_nic_word(dev, 0x80, (wReg80)); // Clear SI_EN (RFLE)
  25039. +// force_pci_posting(dev);
  25040. +// udelay(10);
  25041. +
  25042. + usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  25043. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  25044. + adr, 0x8225, &data, 2, HZ / 2);
  25045. +
  25046. + // write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80));
  25047. +// force_pci_posting(dev);
  25048. +// udelay(10);
  25049. +
  25050. + write_nic_word(dev, 0x80, (wReg80|0x0004));
  25051. + write_nic_word(dev, 0x84, (wReg84|0x0000));// Set To SW Switch
  25052. +
  25053. + if(priv->card_type == USB)
  25054. + ;// msleep(2);
  25055. + else
  25056. + ; // rtl8185_rf_pins_enable(dev);
  25057. +
  25058. +#else
  25059. + int i;
  25060. + u16 out,select;
  25061. + u8 bit;
  25062. + u32 bangdata = (data << 4) | (adr & 0xf);
  25063. + struct r8180_priv *priv = ieee80211_priv(dev);
  25064. +
  25065. + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
  25066. +
  25067. + write_nic_word(dev,RFPinsEnable,
  25068. + (read_nic_word(dev,RFPinsEnable) | 0x7));
  25069. +
  25070. + select = read_nic_word(dev, RFPinsSelect);
  25071. +
  25072. + write_nic_word(dev, RFPinsSelect, select | 0x7 |
  25073. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  25074. +
  25075. +// force_pci_posting(dev);
  25076. +// udelay(10);
  25077. +
  25078. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
  25079. +
  25080. +// force_pci_posting(dev);
  25081. +// udelay(2);
  25082. +
  25083. + write_nic_word(dev, RFPinsOutput, out);
  25084. +
  25085. +// force_pci_posting(dev);
  25086. +// udelay(10);
  25087. +
  25088. +
  25089. + for(i=15; i>=0;i--){
  25090. +
  25091. + bit = (bangdata & (1<<i)) >> i;
  25092. +
  25093. + write_nic_word(dev, RFPinsOutput, bit | out);
  25094. +
  25095. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25096. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25097. +
  25098. + i--;
  25099. + bit = (bangdata & (1<<i)) >> i;
  25100. +
  25101. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25102. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25103. +
  25104. + write_nic_word(dev, RFPinsOutput, bit | out);
  25105. +
  25106. + }
  25107. +
  25108. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
  25109. +
  25110. +// force_pci_posting(dev);
  25111. +// udelay(10);
  25112. +
  25113. + write_nic_word(dev, RFPinsOutput, out |
  25114. + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
  25115. +
  25116. + write_nic_word(dev, RFPinsSelect, select |
  25117. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  25118. +
  25119. + if(priv->card_type == USB)
  25120. + ;// msleep(2);
  25121. + else
  25122. +// rtl8185_rf_pins_enable(dev);
  25123. +#endif
  25124. +}
  25125. +
  25126. +
  25127. +void write_rtl8225_patch(struct net_device *dev, u8 adr, u16 data)
  25128. +{
  25129. +
  25130. + int i;
  25131. + u16 out,select;
  25132. + u8 bit;
  25133. + u32 bangdata = (data << 4) | (adr & 0xf);
  25134. + struct r8180_priv *priv = ieee80211_priv(dev);
  25135. +
  25136. + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
  25137. +
  25138. + write_nic_word(dev,RFPinsEnable,
  25139. + (read_nic_word(dev,RFPinsEnable) | 0x7));
  25140. +
  25141. + select = read_nic_word(dev, RFPinsSelect);
  25142. +
  25143. + write_nic_word(dev, RFPinsSelect, select | 0x7 |
  25144. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  25145. +
  25146. + force_pci_posting(dev);
  25147. + udelay(10);
  25148. +
  25149. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
  25150. +
  25151. + force_pci_posting(dev);
  25152. + udelay(2);
  25153. +
  25154. + write_nic_word(dev, RFPinsOutput, out);
  25155. +
  25156. + force_pci_posting(dev);
  25157. + udelay(10);
  25158. +
  25159. + for(i=15; i>=0;i--){
  25160. +
  25161. + bit = (bangdata & (1<<i)) >> i;
  25162. +
  25163. + write_nic_word(dev, RFPinsOutput, bit | out);
  25164. +
  25165. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25166. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25167. +
  25168. + i--;
  25169. + bit = (bangdata & (1<<i)) >> i;
  25170. +
  25171. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25172. + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
  25173. +
  25174. + write_nic_word(dev, RFPinsOutput, bit | out);
  25175. +
  25176. + }
  25177. +
  25178. + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
  25179. +
  25180. + force_pci_posting(dev);
  25181. + udelay(10);
  25182. +
  25183. + write_nic_word(dev, RFPinsOutput, out |
  25184. + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
  25185. +
  25186. + write_nic_word(dev, RFPinsSelect, select |
  25187. + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
  25188. +
  25189. + if(priv->card_type == USB)
  25190. + mdelay(2);
  25191. + else
  25192. + rtl8185_rf_pins_enable(dev);
  25193. +
  25194. +}
  25195. +
  25196. +void rtl8225_rf_close(struct net_device *dev)
  25197. +{
  25198. + write_rtl8225(dev, 0x4, 0x1f);
  25199. +
  25200. + force_pci_posting(dev);
  25201. + mdelay(1);
  25202. +
  25203. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
  25204. + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
  25205. +}
  25206. +
  25207. +#ifdef ENABLE_DOT11D
  25208. +//
  25209. +// Description:
  25210. +// Map dBm into Tx power index according to
  25211. +// current HW model, for example, RF and PA, and
  25212. +// current wireless mode.
  25213. +//
  25214. +s8
  25215. +DbmToTxPwrIdx(
  25216. + struct r8180_priv *priv,
  25217. + WIRELESS_MODE WirelessMode,
  25218. + s32 PowerInDbm
  25219. + )
  25220. +{
  25221. + bool bUseDefault = true;
  25222. + s8 TxPwrIdx = 0;
  25223. +
  25224. +#ifdef CONFIG_RTL818X_S
  25225. + //
  25226. + // 071011, SD3 SY:
  25227. + // OFDM Power in dBm = Index * 0.5 + 0
  25228. + // CCK Power in dBm = Index * 0.25 + 13
  25229. + //
  25230. + if(priv->card_8185 >= VERSION_8187S_B)
  25231. + {
  25232. + s32 tmp = 0;
  25233. +
  25234. + if(WirelessMode == WIRELESS_MODE_G)
  25235. + {
  25236. + bUseDefault = false;
  25237. + tmp = (2 * PowerInDbm);
  25238. +
  25239. + if(tmp < 0)
  25240. + TxPwrIdx = 0;
  25241. + else if(tmp > 40) // 40 means 20 dBm.
  25242. + TxPwrIdx = 40;
  25243. + else
  25244. + TxPwrIdx = (s8)tmp;
  25245. + }
  25246. + else if(WirelessMode == WIRELESS_MODE_B)
  25247. + {
  25248. + bUseDefault = false;
  25249. + tmp = (4 * PowerInDbm) - 52;
  25250. +
  25251. + if(tmp < 0)
  25252. + TxPwrIdx = 0;
  25253. + else if(tmp > 28) // 28 means 20 dBm.
  25254. + TxPwrIdx = 28;
  25255. + else
  25256. + TxPwrIdx = (s8)tmp;
  25257. + }
  25258. + }
  25259. +#endif
  25260. +
  25261. + //
  25262. + // TRUE if we want to use a default implementation.
  25263. + // We shall set it to FALSE when we have exact translation formular
  25264. + // for target IC. 070622, by rcnjko.
  25265. + //
  25266. + if(bUseDefault)
  25267. + {
  25268. + if(PowerInDbm < 0)
  25269. + TxPwrIdx = 0;
  25270. + else if(PowerInDbm > 35)
  25271. + TxPwrIdx = 35;
  25272. + else
  25273. + TxPwrIdx = (u8)PowerInDbm;
  25274. + }
  25275. +
  25276. + return TxPwrIdx;
  25277. +}
  25278. +#endif
  25279. +
  25280. +
  25281. +short rtl8225_rf_set_sens(struct net_device *dev, short sens)
  25282. +{
  25283. + if (sens <0 || sens > 6) return -1;
  25284. +
  25285. + if(sens > 4)
  25286. + write_rtl8225(dev, 0x0c, 0x850);
  25287. + else
  25288. + write_rtl8225(dev, 0x0c, 0x50);
  25289. +
  25290. + sens= 6-sens;
  25291. + rtl8225_set_gain(dev, sens);
  25292. +
  25293. + write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
  25294. + return 0;
  25295. +
  25296. +}
  25297. +
  25298. +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
  25299. +{
  25300. + struct r8180_priv *priv = ieee80211_priv(dev);
  25301. +
  25302. + int GainIdx;
  25303. + int GainSetting;
  25304. + int i;
  25305. + u8 power;
  25306. + u8 *cck_power_table;
  25307. + u8 max_cck_power_level;
  25308. + u8 max_ofdm_power_level;
  25309. + u8 min_ofdm_power_level;
  25310. + u8 cck_power_level = 0xff & priv->chtxpwr[ch];
  25311. + u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
  25312. +
  25313. +#ifdef ENABLE_DOT11D
  25314. + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
  25315. + IS_DOT11D_STATE_DONE(priv->ieee80211) )
  25316. + {
  25317. + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
  25318. + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
  25319. + u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
  25320. + u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
  25321. +
  25322. + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
  25323. +
  25324. + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
  25325. + // ch, cck_power_level, ofdm_power_level);
  25326. +
  25327. + if(cck_power_level > CckMaxPwrIdx)
  25328. + cck_power_level = CckMaxPwrIdx;
  25329. + if(ofdm_power_level > OfdmMaxPwrIdx)
  25330. + ofdm_power_level = OfdmMaxPwrIdx;
  25331. + }
  25332. +
  25333. + //priv->CurrentCckTxPwrIdx = cck_power_level;
  25334. + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
  25335. +#endif
  25336. +
  25337. +
  25338. + if(priv->card_type == USB){
  25339. + max_cck_power_level = 11;
  25340. + max_ofdm_power_level = 25; // 12 -> 25
  25341. + min_ofdm_power_level = 10;
  25342. + }else{
  25343. + max_cck_power_level = 35;
  25344. + max_ofdm_power_level = 35;
  25345. + min_ofdm_power_level = 0;
  25346. + }
  25347. + if( priv->TrSwitchState == TR_SW_TX )
  25348. + {
  25349. + printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d\n", ofdm_power_level);
  25350. + ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
  25351. + cck_power_level -= GetTxCckHighPowerBias(dev);
  25352. + printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
  25353. + ofdm_power_level);
  25354. + printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
  25355. + cck_power_level);
  25356. + }
  25357. +
  25358. +
  25359. +
  25360. + /* CCK power setting */
  25361. + if(cck_power_level > max_cck_power_level)
  25362. + cck_power_level = max_cck_power_level;
  25363. + GainIdx=cck_power_level % 6;
  25364. + GainSetting=cck_power_level / 6;
  25365. +
  25366. + if(ch == 14)
  25367. + cck_power_table = rtl8225_tx_power_cck_ch14;
  25368. + else
  25369. + cck_power_table = rtl8225_tx_power_cck;
  25370. +
  25371. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
  25372. + /*Ver B*/
  25373. +// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
  25374. +// }else{
  25375. + /*Ver C - D */
  25376. + write_nic_byte(dev, CCK_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
  25377. +// }
  25378. +
  25379. + for(i=0;i<8;i++){
  25380. +
  25381. + power = cck_power_table[GainIdx * 8 + i];
  25382. + write_phy_cck(dev, 0x44 + i, power);
  25383. + }
  25384. +
  25385. + /* FIXME Is this delay really needeed ? */
  25386. + force_pci_posting(dev);
  25387. + mdelay(1);
  25388. +
  25389. + /* OFDM power setting */
  25390. +// Old:
  25391. +// if(ofdm_power_level > max_ofdm_power_level)
  25392. +// ofdm_power_level = 35;
  25393. +// ofdm_power_level += min_ofdm_power_level;
  25394. +// Latest:
  25395. + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
  25396. + ofdm_power_level = max_ofdm_power_level;
  25397. + else
  25398. + ofdm_power_level += min_ofdm_power_level;
  25399. + if(ofdm_power_level > 35)
  25400. + ofdm_power_level = 35;
  25401. +//
  25402. +
  25403. + GainIdx=ofdm_power_level % 6;
  25404. + GainSetting=ofdm_power_level / 6;
  25405. +#if 1
  25406. +// if(priv->card_type == USB){
  25407. + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
  25408. +
  25409. + write_phy_ofdm(dev,2,0x42);
  25410. + write_phy_ofdm(dev,6,0);
  25411. + write_phy_ofdm(dev,8,0);
  25412. +// }
  25413. +#endif
  25414. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion){
  25415. +// /*Ver B*/
  25416. +// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
  25417. +// }else{
  25418. + /*Ver C - D */
  25419. + write_nic_byte(dev, OFDM_TXAGC, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
  25420. +// }
  25421. +
  25422. +
  25423. + power = rtl8225_tx_power_ofdm[GainIdx];
  25424. +
  25425. + write_phy_ofdm(dev, 0x5, power);
  25426. + write_phy_ofdm(dev, 0x7, power);
  25427. +
  25428. + force_pci_posting(dev);
  25429. + mdelay(1);
  25430. + //write_nic_byte(dev, TX_AGC_CONTROL,4);
  25431. +}
  25432. +
  25433. +void rtl8225_rf_set_chan(struct net_device *dev, short ch)
  25434. +{
  25435. + struct r8180_priv *priv = ieee80211_priv(dev);
  25436. + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
  25437. + ieee80211_is_54g(priv->ieee80211->current_network)) ||
  25438. + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
  25439. + int eifs_addr;
  25440. +
  25441. + if(NIC_8187 == priv->card_8187) {
  25442. + eifs_addr = EIFS_8187;
  25443. + } else {
  25444. + eifs_addr = EIFS_8187B;
  25445. + }
  25446. +
  25447. +#ifdef ENABLE_DOT11D
  25448. + if(!IsLegalChannel(priv->ieee80211, ch) )
  25449. + {
  25450. + printk("channel(%d). is invalide\n", ch);
  25451. + return;
  25452. + }
  25453. +#endif
  25454. +
  25455. + rtl8225_SetTXPowerLevel(dev, ch);
  25456. +
  25457. + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
  25458. +
  25459. + force_pci_posting(dev);
  25460. + mdelay(10);
  25461. +
  25462. + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
  25463. +
  25464. + if(gset)
  25465. + write_nic_byte(dev,DIFS,20); //DIFS: 20
  25466. + else
  25467. + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
  25468. +
  25469. + if(priv->ieee80211->state == IEEE80211_LINKED &&
  25470. + ieee80211_is_shortslot(priv->ieee80211->current_network))
  25471. + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
  25472. +
  25473. + else
  25474. + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
  25475. +
  25476. +
  25477. + if(gset){
  25478. + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
  25479. + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
  25480. + //DMESG("using G net params");
  25481. + }else{
  25482. + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
  25483. + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
  25484. + //DMESG("using B net params");
  25485. + }
  25486. +
  25487. +
  25488. +}
  25489. +
  25490. +void rtl8225_host_pci_init(struct net_device *dev)
  25491. +{
  25492. + write_nic_word(dev, RFPinsOutput, 0x480);
  25493. +
  25494. + rtl8185_rf_pins_enable(dev);
  25495. +
  25496. + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
  25497. + //write_nic_word(dev, RFPinsSelect, 0x88);
  25498. + //else
  25499. + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
  25500. +
  25501. + write_nic_byte(dev, GP_ENABLE, 0);
  25502. +
  25503. + force_pci_posting(dev);
  25504. + mdelay(200);
  25505. +
  25506. + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
  25507. +
  25508. +
  25509. +}
  25510. +
  25511. +void rtl8225_host_usb_init(struct net_device *dev)
  25512. +{
  25513. + write_nic_byte(dev,RFPinsSelect+1,0);
  25514. +
  25515. + write_nic_byte(dev,GPIO,0);
  25516. +
  25517. + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
  25518. +
  25519. + write_nic_byte(dev,RFPinsSelect+1,4);
  25520. +
  25521. + write_nic_byte(dev,GPIO,0x20);
  25522. +
  25523. + write_nic_byte(dev,GP_ENABLE,0);
  25524. +
  25525. +
  25526. + /* Config BB & RF */
  25527. + write_nic_word(dev, RFPinsOutput, 0x80);
  25528. +
  25529. + write_nic_word(dev, RFPinsSelect, 0x80);
  25530. +
  25531. + write_nic_word(dev, RFPinsEnable, 0x80);
  25532. +
  25533. +
  25534. + mdelay(100);
  25535. +
  25536. + mdelay(1000);
  25537. +
  25538. +}
  25539. +
  25540. +void rtl8225_rf_init(struct net_device *dev)
  25541. +{
  25542. + struct r8180_priv *priv = ieee80211_priv(dev);
  25543. + int i;
  25544. + short channel = 1;
  25545. + u16 brsr;
  25546. + int brsr_addr;
  25547. +
  25548. + if(NIC_8187 == priv->card_8187) {
  25549. + brsr_addr = BRSR_8187;
  25550. + } else {
  25551. + brsr_addr = BRSR_8187B;
  25552. + }
  25553. +
  25554. +
  25555. + priv->chan = channel;
  25556. +
  25557. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  25558. +
  25559. +
  25560. + if(priv->card_type == USB)
  25561. + rtl8225_host_usb_init(dev);
  25562. + else
  25563. + rtl8225_host_pci_init(dev);
  25564. +
  25565. + write_nic_dword(dev, RF_TIMING, 0x000a8008);
  25566. +
  25567. + //brsr = read_nic_word(dev, BRSR);
  25568. + brsr = read_nic_word(dev, brsr_addr);
  25569. +
  25570. + //write_nic_word(dev, BRSR, 0xffff);
  25571. + write_nic_word(dev, brsr_addr, 0xffff);
  25572. +
  25573. + write_nic_dword(dev, RF_PARA, 0x100044);
  25574. +
  25575. + #if 1 //0->1
  25576. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  25577. + write_nic_byte(dev, CONFIG3, 0x44);
  25578. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  25579. + #endif
  25580. +
  25581. + if(priv->card_type == USB){
  25582. + rtl8185_rf_pins_enable(dev);
  25583. +
  25584. + mdelay(1000);
  25585. + }
  25586. +
  25587. + write_rtl8225(dev, 0x0, 0x67); mdelay(1);
  25588. +
  25589. +
  25590. + write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
  25591. +
  25592. + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
  25593. +
  25594. + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
  25595. +
  25596. + if(priv->card_type == USB)
  25597. + write_rtl8225(dev, 0x4, 0x486);
  25598. + else
  25599. + write_rtl8225(dev, 0x4, 0x8be);
  25600. +
  25601. + mdelay(1);
  25602. +
  25603. +
  25604. + /* version B & C */
  25605. +
  25606. + if(priv->card_type == USB)
  25607. + write_rtl8225(dev, 0x5, 0xbc0);
  25608. + else if(priv->card_type == MINIPCI)
  25609. + write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3));
  25610. + else
  25611. + write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
  25612. +
  25613. + mdelay(1);
  25614. +// }
  25615. +
  25616. + write_rtl8225(dev, 0x6, 0xae6); mdelay(1);
  25617. +
  25618. + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
  25619. +
  25620. + write_rtl8225(dev, 0x8, 0x1f); mdelay(1);
  25621. +
  25622. + write_rtl8225(dev, 0x9, 0x334); mdelay(1);
  25623. +
  25624. + write_rtl8225(dev, 0xa, 0xfd4); mdelay(1);
  25625. +
  25626. + write_rtl8225(dev, 0xb, 0x391); mdelay(1);
  25627. +
  25628. + write_rtl8225(dev, 0xc, 0x50); mdelay(1);
  25629. +
  25630. +
  25631. + write_rtl8225(dev, 0xd, 0x6db); mdelay(1);
  25632. +
  25633. + write_rtl8225(dev, 0xe, 0x29); mdelay(1);
  25634. +
  25635. + write_rtl8225(dev, 0xf, 0x914);
  25636. +
  25637. + if(priv->card_type == USB){
  25638. + //force_pci_posting(dev);
  25639. + mdelay(100);
  25640. + }
  25641. +
  25642. + write_rtl8225(dev, 0x2, 0xc4d);
  25643. +
  25644. + if(priv->card_type == USB){
  25645. + // force_pci_posting(dev);
  25646. + mdelay(200);
  25647. +
  25648. + write_rtl8225(dev, 0x2, 0x44d);
  25649. +
  25650. + // force_pci_posting(dev);
  25651. + mdelay(100);
  25652. +
  25653. + }//End of if(priv->card_type == USB)
  25654. + /* FIXME!! rtl8187 we have to check if calibrarion
  25655. + * is successful and eventually cal. again (repeat
  25656. + * the two write on reg 2)
  25657. + */
  25658. + force_pci_posting(dev);
  25659. +
  25660. + mdelay(100); //200 for 8187
  25661. +
  25662. + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
  25663. +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  25664. +
  25665. + write_rtl8225(dev, 0x0, 0x127);
  25666. +
  25667. + for(i=0;i<95;i++){
  25668. + write_rtl8225(dev, 0x1, (u8)(i+1));
  25669. +
  25670. + /* version B & C & D*/
  25671. +
  25672. + write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
  25673. + }
  25674. +
  25675. + write_rtl8225(dev, 0x0, 0x27);
  25676. +
  25677. +
  25678. +// //if(priv->card_type != USB){
  25679. +// write_rtl8225(dev, 0x2, 0x44d);
  25680. +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  25681. +// write_rtl8225(dev, 0x2, 0x47d);
  25682. +//
  25683. +// force_pci_posting(dev);
  25684. +// mdelay(100);
  25685. +//
  25686. +// write_rtl8225(dev, 0x2, 0x44d);
  25687. +// //}
  25688. +
  25689. + write_rtl8225(dev, 0x0, 0x22f);
  25690. +
  25691. + if(priv->card_type != USB)
  25692. + rtl8185_rf_pins_enable(dev);
  25693. +
  25694. + for(i=0;i<128;i++){
  25695. + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
  25696. +
  25697. + mdelay(1);
  25698. + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
  25699. +
  25700. + mdelay(1);
  25701. + }
  25702. +
  25703. + force_pci_posting(dev);
  25704. + mdelay(1);
  25705. +
  25706. + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
  25707. + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
  25708. + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
  25709. + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
  25710. + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
  25711. + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
  25712. + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
  25713. + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
  25714. + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
  25715. + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
  25716. +
  25717. + /* ver C & D */
  25718. + write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
  25719. +
  25720. + //write_phy_ofdm(dev, 0x18, 0xef);
  25721. + // }
  25722. + //}
  25723. + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
  25724. +
  25725. + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
  25726. +
  25727. +
  25728. + //if(priv->card_type != USB)
  25729. + //write_phy_ofdm(dev, 0xd, 0x33); // <>
  25730. +
  25731. + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
  25732. +
  25733. + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
  25734. +/*ver D & 8187*/
  25735. +// }
  25736. +
  25737. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
  25738. +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
  25739. +// else
  25740. + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
  25741. +/*ver C & D & 8187*/
  25742. +
  25743. + write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
  25744. +/*agc resp time 700*/
  25745. +
  25746. +
  25747. +// if(priv->card_8185 == 2){
  25748. + /* Ver D & 8187*/
  25749. + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
  25750. +
  25751. + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
  25752. +
  25753. + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
  25754. + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
  25755. + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
  25756. + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
  25757. +
  25758. +// if (priv->card_type == USB)
  25759. +// write_phy_ofdm(dev, 0x18, 0xef);
  25760. +
  25761. + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
  25762. +
  25763. +
  25764. + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
  25765. + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
  25766. +
  25767. +// if (priv->card_type != USB){
  25768. +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
  25769. +// write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */
  25770. +// else
  25771. + write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
  25772. + /* Ver C & D */ //FIXME:MAYBE not needed
  25773. +// }
  25774. +
  25775. + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
  25776. +
  25777. + /*ver D & 8187*/
  25778. + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
  25779. +
  25780. + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
  25781. +
  25782. +// }
  25783. +
  25784. + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
  25785. +
  25786. + write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
  25787. +
  25788. + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
  25789. +
  25790. +// if(priv->card_type != USB)
  25791. + //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
  25792. +
  25793. + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
  25794. + write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
  25795. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
  25796. + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
  25797. +/* Ver C & D & 8187*/
  25798. +
  25799. + // <> Set init. gain to m74dBm.
  25800. +
  25801. + rtl8225_set_gain(dev,4);
  25802. + /*write_phy_ofdm(dev, 0x0d, 0x43); mdelay(1);
  25803. + write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1);
  25804. + write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
  25805. + write_phy_ofdm(dev, 0x23, 0x78); mdelay(1);
  25806. +*/
  25807. + //if(priv->card_type == USB);
  25808. + // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
  25809. +
  25810. + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
  25811. + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
  25812. + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
  25813. + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
  25814. + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
  25815. + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
  25816. + /* Ver C & D & 8187*/
  25817. +
  25818. + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
  25819. +
  25820. + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
  25821. + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
  25822. + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
  25823. + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
  25824. +
  25825. + write_phy_cck(dev, 0x19, 0x0);
  25826. + write_phy_cck(dev, 0x1a, 0xa0);
  25827. + write_phy_cck(dev, 0x1b, 0x8);
  25828. + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
  25829. +
  25830. + write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
  25831. +
  25832. +
  25833. + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
  25834. + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
  25835. + write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
  25836. + write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
  25837. + write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
  25838. + write_phy_cck(dev, 0x47, 0x15); mdelay(1);
  25839. + write_phy_cck(dev, 0x48, 0x10); mdelay(1);
  25840. + write_phy_cck(dev, 0x49, 0xa); mdelay(1);
  25841. + write_phy_cck(dev, 0x4a, 0x5); mdelay(1);
  25842. + write_phy_cck(dev, 0x4b, 0x2); mdelay(1);
  25843. + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
  25844. +
  25845. +
  25846. + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
  25847. +
  25848. +
  25849. +
  25850. +// <>
  25851. +// // TESTR 0xb 8187
  25852. +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
  25853. +//
  25854. +// //if(priv->card_type != USB){
  25855. +// write_phy_ofdm(dev, 0x2, 0x62);
  25856. +// write_phy_ofdm(dev, 0x6, 0x0);
  25857. +// write_phy_ofdm(dev, 0x8, 0x0);
  25858. +// //}
  25859. +
  25860. + rtl8225_SetTXPowerLevel(dev, channel);
  25861. +
  25862. + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
  25863. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
  25864. +
  25865. + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
  25866. +
  25867. + /* switch to high-speed 3-wire
  25868. + * last digit. 2 for both cck and ofdm
  25869. + */
  25870. + if(priv->card_type == USB)
  25871. + write_nic_dword(dev, 0x94, 0x3dc00002);
  25872. + else{
  25873. + write_nic_dword(dev, 0x94, 0x15c00002);
  25874. + rtl8185_rf_pins_enable(dev);
  25875. + }
  25876. +
  25877. +// if(priv->card_type != USB)
  25878. +// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
  25879. +// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
  25880. +//
  25881. +// /* make sure is waken up! */
  25882. +// write_rtl8225(dev,0x4, 0x9ff);
  25883. +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  25884. +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  25885. +
  25886. + rtl8225_rf_set_chan(dev, priv->chan);
  25887. +
  25888. + //write_nic_word(dev,BRSR,brsr);
  25889. +
  25890. +}
  25891. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.h
  25892. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 1970-01-01 01:00:00.000000000 +0100
  25893. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225.h 2010-05-27 18:12:39.532222207 +0200
  25894. @@ -0,0 +1,77 @@
  25895. +/*
  25896. + This is part of the rtl8180-sa2400 driver
  25897. + released under the GPL (See file COPYING for details).
  25898. + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  25899. +
  25900. + This files contains programming code for the rtl8225
  25901. + radio frontend.
  25902. +
  25903. + *Many* thanks to Realtek Corp. for their great support!
  25904. +
  25905. +*/
  25906. +
  25907. +#ifndef RTL8225H
  25908. +#define RTL8225H
  25909. +
  25910. +#include "r8187.h"
  25911. +
  25912. +#define RTL8225_ANAPARAM_ON 0xa0000a59
  25913. +
  25914. +// FIXME: OFF ANAPARAM MIGHT BE WRONG!
  25915. +#define RTL8225_ANAPARAM_OFF 0xa00beb59
  25916. +#define RTL8225_ANAPARAM2_OFF 0x840dec11
  25917. +
  25918. +#define RTL8225_ANAPARAM2_ON 0x860c7312
  25919. +
  25920. +void rtl8225_rf_init(struct net_device *dev);
  25921. +void rtl8225z2_rf_init(struct net_device *dev);
  25922. +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
  25923. +short rtl8225_is_V_z2(struct net_device *dev);
  25924. +void rtl8225_rf_set_chan(struct net_device *dev,short ch);
  25925. +void rtl8225_rf_close(struct net_device *dev);
  25926. +short rtl8225_rf_set_sens(struct net_device *dev, short sens);
  25927. +void rtl8225_host_pci_init(struct net_device *dev);
  25928. +void rtl8225_host_usb_init(struct net_device *dev);
  25929. +void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
  25930. +void rtl8225z2_rf_set_mode(struct net_device *dev) ;
  25931. +void rtl8185_rf_pins_enable(struct net_device *dev);
  25932. +void rtl8180_set_mode(struct net_device *dev,int mode);
  25933. +void UpdateInitialGain(struct net_device *dev);
  25934. +void UpdateCCKThreshold(struct net_device *dev);
  25935. +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch);
  25936. +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
  25937. +
  25938. +#define RTL8225_RF_MAX_SENS 6
  25939. +#define RTL8225_RF_DEF_SENS 4
  25940. +
  25941. +extern inline char GetTxOfdmHighPowerBias(struct net_device *dev)
  25942. +{
  25943. + //
  25944. + // We should always adjust our Tx Power for 8187 and 8187B.
  25945. + // It was ever recommended not to adjust Tx Power of 8187B with Atheros AP
  25946. + // for throughput by David, but now we found it is not the issue to impact
  25947. + // the Atheros's problem and also no adjustion for Tx Power will cause "low"
  25948. + // throughput. By Bruce, 2007-07-03.
  25949. + //
  25950. + return 10;
  25951. +}
  25952. +
  25953. +//
  25954. +// Description:
  25955. +// Return Tx power level to minus if we are in high power state.
  25956. +//
  25957. +// Note:
  25958. +// Adjust it according to RF if required.
  25959. +//
  25960. +extern inline char GetTxCckHighPowerBias(struct net_device *dev)
  25961. +{
  25962. + return 7;
  25963. +}
  25964. +
  25965. +
  25966. +
  25967. +extern u8 rtl8225_agc[];
  25968. +
  25969. +extern u32 rtl8225_chan[];
  25970. +
  25971. +#endif
  25972. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c
  25973. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 1970-01-01 01:00:00.000000000 +0100
  25974. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_rtl8225z2.c 2010-05-27 18:12:39.532222207 +0200
  25975. @@ -0,0 +1,2092 @@
  25976. +/*
  25977. + This is part of the rtl8180-sa2400 driver
  25978. + released under the GPL (See file COPYING for details).
  25979. + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  25980. +
  25981. + This files contains programming code for the rtl8225
  25982. + radio frontend.
  25983. +
  25984. + *Many* thanks to Realtek Corp. for their great support!
  25985. +
  25986. +*/
  25987. +
  25988. +
  25989. +
  25990. +#include "r8180_hw.h"
  25991. +#include "r8180_rtl8225.h"
  25992. +#ifdef ENABLE_DOT11D
  25993. +#include "dot11d.h"
  25994. +#endif
  25995. +
  25996. +//2005.11.16
  25997. +u8 rtl8225z2_threshold[]={
  25998. + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
  25999. +};
  26000. +
  26001. +// 0xd 0x19 0x1b 0x21
  26002. +u8 rtl8225z2_gain_bg[]={
  26003. + 0x23, 0x15, 0xa5, // -82-1dbm
  26004. + 0x23, 0x15, 0xb5, // -82-2dbm
  26005. + 0x23, 0x15, 0xc5, // -82-3dbm
  26006. + 0x33, 0x15, 0xc5, // -78dbm
  26007. + 0x43, 0x15, 0xc5, // -74dbm
  26008. + 0x53, 0x15, 0xc5, // -70dbm
  26009. + 0x63, 0x15, 0xc5, // -66dbm
  26010. +};
  26011. +
  26012. +u8 rtl8225z2_gain_a[]={
  26013. + 0x13,0x27,0x5a,//,0x37,// -82dbm
  26014. + 0x23,0x23,0x58,//,0x37,// -82dbm
  26015. + 0x33,0x1f,0x56,//,0x37,// -82dbm
  26016. + 0x43,0x1b,0x54,//,0x37,// -78dbm
  26017. + 0x53,0x17,0x51,//,0x37,// -74dbm
  26018. + 0x63,0x24,0x4f,//,0x37,// -70dbm
  26019. + 0x73,0x0f,0x4c,//,0x37,// -66dbm
  26020. +};
  26021. +static u32 MAC_REG_TABLE[][3]={
  26022. + {0xf0, 0x32, 0000}, {0xf1, 0x32, 0000}, {0xf2, 0x00, 0000}, {0xf3, 0x00, 0000},
  26023. + {0xf4, 0x32, 0000}, {0xf5, 0x43, 0000}, {0xf6, 0x00, 0000}, {0xf7, 0x00, 0000},
  26024. + {0xf8, 0x46, 0000}, {0xf9, 0xa4, 0000}, {0xfa, 0x00, 0000}, {0xfb, 0x00, 0000},
  26025. + {0xfc, 0x96, 0000}, {0xfd, 0xa4, 0000}, {0xfe, 0x00, 0000}, {0xff, 0x00, 0000},
  26026. +
  26027. + {0x58, 0x4b, 0001}, {0x59, 0x00, 0001}, {0x5a, 0x4b, 0001}, {0x5b, 0x00, 0001},
  26028. + {0x60, 0x4b, 0001}, {0x61, 0x09, 0001}, {0x62, 0x4b, 0001}, {0x63, 0x09, 0001},
  26029. + {0xce, 0x0f, 0001}, {0xcf, 0x00, 0001}, {0xe0, 0xff, 0001}, {0xe1, 0x0f, 0001},
  26030. + {0xe2, 0x00, 0001}, {0xf0, 0x4e, 0001}, {0xf1, 0x01, 0001}, {0xf2, 0x02, 0001},
  26031. + {0xf3, 0x03, 0001}, {0xf4, 0x04, 0001}, {0xf5, 0x05, 0001}, {0xf6, 0x06, 0001},
  26032. + {0xf7, 0x07, 0001}, {0xf8, 0x08, 0001},
  26033. +
  26034. + {0x4e, 0x00, 0002}, {0x0c, 0x04, 0002}, {0x21, 0x61, 0002}, {0x22, 0x68, 0002},
  26035. + {0x23, 0x6f, 0002}, {0x24, 0x76, 0002}, {0x25, 0x7d, 0002}, {0x26, 0x84, 0002},
  26036. + {0x27, 0x8d, 0002}, {0x4d, 0x08, 0002}, {0x50, 0x05, 0002}, {0x51, 0xf5, 0002},
  26037. + {0x52, 0x04, 0002}, {0x53, 0xa0, 0002}, {0x54, 0x1f, 0002}, {0x55, 0x23, 0002},
  26038. + {0x56, 0x45, 0002}, {0x57, 0x67, 0002}, {0x58, 0x08, 0002}, {0x59, 0x08, 0002},
  26039. + {0x5a, 0x08, 0002}, {0x5b, 0x08, 0002}, {0x60, 0x08, 0002}, {0x61, 0x08, 0002},
  26040. + {0x62, 0x08, 0002}, {0x63, 0x08, 0002}, {0x64, 0xcf, 0002}, {0x72, 0x56, 0002},
  26041. + {0x73, 0x9a, 0002},
  26042. +
  26043. + {0x34, 0xf0, 0000}, {0x35, 0x0f, 0000}, {0x5b, 0x40, 0000}, {0x84, 0x88, 0000},
  26044. + {0x85, 0x24, 0000}, {0x88, 0x54, 0000}, {0x8b, 0xb8, 0000}, {0x8c, 0x07, 0000},
  26045. + {0x8d, 0x00, 0000}, {0x94, 0x1b, 0000}, {0x95, 0x12, 0000}, {0x96, 0x00, 0000},
  26046. + {0x97, 0x06, 0000}, {0x9d, 0x1a, 0000}, {0x9f, 0x10, 0000}, {0xb4, 0x22, 0000},
  26047. + {0xbe, 0x80, 0000}, {0xdb, 0x00, 0000}, {0xee, 0x00, 0000}, {0x91, 0x01, 0000},
  26048. + //lzm mode 0x91 form 0x03->0x01 open GPIO BIT1,
  26049. + //because Polling methord will rurn off Radio
  26050. + //the first time when read GPI(0x92).
  26051. + //because after 0x91:bit1 form 1->0, there will
  26052. + //be time for 0x92:bit1 form 0->1
  26053. +
  26054. + {0x4c, 0x00, 0002}, {0x9f, 0x00, 0003}, {0x8c, 0x01, 0000}, {0x8d, 0x10, 0000},
  26055. + {0x8e, 0x08, 0000}, {0x8f, 0x00, 0000}
  26056. +};
  26057. +
  26058. +static u8 ZEBRA_AGC[]={
  26059. + 0,
  26060. + 0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,
  26061. + 0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,
  26062. + 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,
  26063. + 0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  26064. + 0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
  26065. + 0x26,0x27,0x27,0x28,0x28,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,
  26066. + 0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x31,0x31,0x31,0x31,
  26067. + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31
  26068. +};
  26069. +
  26070. +static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
  26071. + 0,
  26072. + 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409,
  26073. + 0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541,
  26074. + 0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583,
  26075. + 0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644,
  26076. + 0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688,
  26077. + 0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745,
  26078. + 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789,
  26079. + 0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793,
  26080. + 0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,
  26081. + 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9,
  26082. + 0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3,
  26083. + 0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb
  26084. +};
  26085. +
  26086. +// Use the new SD3 given param, by shien chang, 2006.07.14
  26087. +
  26088. +static u8 OFDM_CONFIG[]={
  26089. + // 0x00
  26090. + 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
  26091. + 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
  26092. +
  26093. + // 0x10
  26094. + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
  26095. + 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
  26096. +
  26097. + // 0x20
  26098. + 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
  26099. + 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
  26100. +
  26101. + // 0x30
  26102. + 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
  26103. + 0x6d, 0x3c, 0xfb, 0x07//0xc7
  26104. + };
  26105. +
  26106. +//2005.11.16,
  26107. +u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={
  26108. + 0x00,0x01,0x02,0x03,0x04,0x05,
  26109. + 0x06,0x07,0x08,0x09,0x0a,0x0b,
  26110. + 0x0c,0x0d,0x0e,0x0f,0x10,0x11,
  26111. + 0x12,0x13,0x14,0x15,0x16,0x17,
  26112. + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,
  26113. + 0x1e,0x1f,0x20,0x21,0x22,0x23,
  26114. +};
  26115. +//-
  26116. +u16 rtl8225z2_rxgain[]={
  26117. + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
  26118. + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
  26119. + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
  26120. + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
  26121. + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
  26122. + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
  26123. + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
  26124. + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
  26125. + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
  26126. + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
  26127. + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
  26128. + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
  26129. +
  26130. +};
  26131. +
  26132. +
  26133. +/*
  26134. + from 0 to 0x23
  26135. +u8 rtl8225_tx_gain_cck_ofdm[]={
  26136. + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
  26137. +};
  26138. +*/
  26139. +
  26140. +//-
  26141. +u8 rtl8225z2_tx_power_ofdm[]={
  26142. + 0x42,0x00,0x40,0x00,0x40
  26143. +};
  26144. +
  26145. +
  26146. +//-
  26147. +u8 rtl8225z2_tx_power_cck_ch14[]={
  26148. + 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00,
  26149. + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
  26150. + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
  26151. + 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
  26152. +};
  26153. +
  26154. +
  26155. +//-
  26156. +u8 rtl8225z2_tx_power_cck[]={
  26157. + 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04,
  26158. + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
  26159. + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
  26160. + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
  26161. +};
  26162. +
  26163. +#ifdef ENABLE_DOT11D
  26164. +//
  26165. +// Description:
  26166. +// Map dBm into Tx power index according to
  26167. +// current HW model, for example, RF and PA, and
  26168. +// current wireless mode.
  26169. +//
  26170. +s8
  26171. +rtl8187B_DbmToTxPwrIdx(
  26172. + struct r8180_priv *priv,
  26173. + WIRELESS_MODE WirelessMode,
  26174. + s32 PowerInDbm
  26175. + )
  26176. +{
  26177. + bool bUseDefault = true;
  26178. + s8 TxPwrIdx = 0;
  26179. +
  26180. +#ifdef CONFIG_RTL818X_S
  26181. + //
  26182. + // 071011, SD3 SY:
  26183. + // OFDM Power in dBm = Index * 0.5 + 0
  26184. + // CCK Power in dBm = Index * 0.25 + 13
  26185. + //
  26186. + if(priv->card_8185 >= VERSION_8187S_B)
  26187. + {
  26188. + s32 tmp = 0;
  26189. +
  26190. + if(WirelessMode == WIRELESS_MODE_G)
  26191. + {
  26192. + bUseDefault = false;
  26193. + tmp = (2 * PowerInDbm);
  26194. +
  26195. + if(tmp < 0)
  26196. + TxPwrIdx = 0;
  26197. + else if(tmp > 40) // 40 means 20 dBm.
  26198. + TxPwrIdx = 40;
  26199. + else
  26200. + TxPwrIdx = (s8)tmp;
  26201. + }
  26202. + else if(WirelessMode == WIRELESS_MODE_B)
  26203. + {
  26204. + bUseDefault = false;
  26205. + tmp = (4 * PowerInDbm) - 52;
  26206. +
  26207. + if(tmp < 0)
  26208. + TxPwrIdx = 0;
  26209. + else if(tmp > 28) // 28 means 20 dBm.
  26210. + TxPwrIdx = 28;
  26211. + else
  26212. + TxPwrIdx = (s8)tmp;
  26213. + }
  26214. + }
  26215. +#endif
  26216. +
  26217. + //
  26218. + // TRUE if we want to use a default implementation.
  26219. + // We shall set it to FALSE when we have exact translation formular
  26220. + // for target IC. 070622, by rcnjko.
  26221. + //
  26222. + if(bUseDefault)
  26223. + {
  26224. + if(PowerInDbm < 0)
  26225. + TxPwrIdx = 0;
  26226. + else if(PowerInDbm > 35)
  26227. + TxPwrIdx = 35;
  26228. + else
  26229. + TxPwrIdx = (u8)PowerInDbm;
  26230. + }
  26231. +
  26232. + return TxPwrIdx;
  26233. +}
  26234. +#endif
  26235. +
  26236. +
  26237. +void rtl8225z2_set_gain(struct net_device *dev, short gain)
  26238. +{
  26239. + u8* rtl8225_gain;
  26240. + struct r8180_priv *priv = ieee80211_priv(dev);
  26241. +
  26242. + u8 mode = priv->ieee80211->mode;
  26243. +
  26244. + if(mode == IEEE_B || mode == IEEE_G)
  26245. + rtl8225_gain = rtl8225z2_gain_bg;
  26246. + else
  26247. + rtl8225_gain = rtl8225z2_gain_a;
  26248. +
  26249. + //write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]);
  26250. + //write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]);
  26251. + //write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]);
  26252. + //2005.11.17, by ch-hsu
  26253. + write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
  26254. + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
  26255. + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
  26256. + write_phy_ofdm(dev, 0x21, 0x37);
  26257. +
  26258. +}
  26259. +
  26260. +u32 read_rtl8225(struct net_device *dev, u8 adr)
  26261. +{
  26262. + u32 data2Write = ((u32)(adr & 0x1f)) << 27;
  26263. + u32 dataRead;
  26264. + u32 mask;
  26265. + u16 oval,oval2,oval3,tmp;
  26266. +// ThreeWireReg twreg;
  26267. +// ThreeWireReg tdata;
  26268. + int i;
  26269. + short bit, rw;
  26270. +
  26271. + u8 wLength = 6;
  26272. + u8 rLength = 12;
  26273. + u8 low2high = 0;
  26274. +
  26275. + oval = read_nic_word(dev, RFPinsOutput);
  26276. + oval2 = read_nic_word(dev, RFPinsEnable);
  26277. + oval3 = read_nic_word(dev, RFPinsSelect);
  26278. + write_nic_word(dev, RFPinsEnable, (oval2|0xf));
  26279. + write_nic_word(dev, RFPinsSelect, (oval3|0xf));
  26280. +
  26281. + dataRead = 0;
  26282. +
  26283. + oval &= ~0xf;
  26284. +
  26285. + write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4);
  26286. +
  26287. + write_nic_word(dev, RFPinsOutput, oval ); udelay(5);
  26288. +
  26289. + rw = 0;
  26290. +
  26291. + mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
  26292. + for(i = 0; i < wLength/2; i++)
  26293. + {
  26294. + bit = ((data2Write&mask) != 0) ? 1 : 0;
  26295. + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
  26296. +
  26297. + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
  26298. + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
  26299. +
  26300. + mask = (low2high) ? (mask<<1): (mask>>1);
  26301. +
  26302. + if(i == 2)
  26303. + {
  26304. + rw = BB_HOST_BANG_RW;
  26305. + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
  26306. + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2);
  26307. + break;
  26308. + }
  26309. +
  26310. + bit = ((data2Write&mask) != 0) ? 1: 0;
  26311. +
  26312. + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
  26313. + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
  26314. +
  26315. + write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1);
  26316. +
  26317. + mask = (low2high) ? (mask<<1) : (mask>>1);
  26318. + }
  26319. +
  26320. + //twreg.struc.clk = 0;
  26321. + //twreg.struc.data = 0;
  26322. + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2);
  26323. + mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
  26324. +
  26325. + // We must set data pin to HW controled, otherwise RF can't driver it and
  26326. + // value RF register won't be able to read back properly. 2006.06.13, by rcnjko.
  26327. + write_nic_word(dev, RFPinsEnable,((oval2|0xe) & (~0x01)));
  26328. +
  26329. + for(i = 0; i < rLength; i++)
  26330. + {
  26331. + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
  26332. +
  26333. + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
  26334. + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
  26335. + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
  26336. + tmp = read_nic_word(dev, RFPinsInput);
  26337. +
  26338. + dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
  26339. +
  26340. + write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
  26341. +
  26342. + mask = (low2high) ? (mask<<1) : (mask>>1);
  26343. + }
  26344. +
  26345. + write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
  26346. +
  26347. + write_nic_word(dev, RFPinsEnable, oval2);
  26348. + write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
  26349. + write_nic_word(dev, RFPinsOutput, 0x3a0);
  26350. +
  26351. + return dataRead;
  26352. +
  26353. +}
  26354. +short rtl8225_is_V_z2(struct net_device *dev)
  26355. +{
  26356. + short vz2 = 1;
  26357. + //set VCO-PDN pin
  26358. +// printk("%s()\n", __FUNCTION__);
  26359. + write_nic_word(dev, RFPinsOutput, 0x0080);
  26360. + write_nic_word(dev, RFPinsSelect, 0x0080);
  26361. + write_nic_word(dev, RFPinsEnable, 0x0080);
  26362. +
  26363. + //lzm mod for up take too long time 20081201
  26364. + //mdelay(100);
  26365. + //mdelay(1000);
  26366. +
  26367. + /* sw to reg pg 1 */
  26368. + write_rtl8225(dev, 0, 0x1b7);
  26369. + /* reg 8 pg 1 = 23*/
  26370. + if( read_rtl8225(dev, 8) != 0x588)
  26371. + vz2 = 0;
  26372. +
  26373. + else /* reg 9 pg 1 = 24 */
  26374. + if( read_rtl8225(dev, 9) != 0x700)
  26375. + vz2 = 0;
  26376. +
  26377. + /* sw back to pg 0 */
  26378. + write_rtl8225(dev, 0, 0xb7);
  26379. +
  26380. + return vz2;
  26381. +
  26382. +}
  26383. +
  26384. +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
  26385. +{
  26386. + struct r8180_priv *priv = ieee80211_priv(dev);
  26387. +
  26388. +// int GainIdx;
  26389. +// int GainSetting;
  26390. + int i;
  26391. + u8 power;
  26392. + u8 *cck_power_table;
  26393. + u8 max_cck_power_level;
  26394. + u8 min_cck_power_level;
  26395. + u8 max_ofdm_power_level;
  26396. + u8 min_ofdm_power_level;
  26397. + s8 cck_power_level = 0xff & priv->chtxpwr[ch];
  26398. + s8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
  26399. + u8 hw_version = priv->card_8187_Bversion;
  26400. +
  26401. +#ifdef ENABLE_DOT11D
  26402. + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
  26403. + IS_DOT11D_STATE_DONE(priv->ieee80211) )
  26404. + {
  26405. + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
  26406. + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
  26407. + u8 CckMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
  26408. + u8 OfdmMaxPwrIdx = rtl8187B_DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
  26409. +
  26410. + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
  26411. +
  26412. + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
  26413. + // ch, cck_power_level, ofdm_power_level);
  26414. +
  26415. + if(cck_power_level > CckMaxPwrIdx)
  26416. + cck_power_level = CckMaxPwrIdx;
  26417. + if(ofdm_power_level > OfdmMaxPwrIdx)
  26418. + ofdm_power_level = OfdmMaxPwrIdx;
  26419. + }
  26420. +
  26421. + //priv->CurrentCckTxPwrIdx = cck_power_level;
  26422. + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
  26423. +#endif
  26424. +
  26425. + if (NIC_8187B == priv->card_8187)
  26426. + {
  26427. + if (hw_version == VERSION_8187B_B)
  26428. + {
  26429. + min_cck_power_level = 0;
  26430. + max_cck_power_level = 15;
  26431. + min_ofdm_power_level = 2;
  26432. + max_ofdm_power_level = 17;
  26433. + }else
  26434. + {
  26435. + min_cck_power_level = 7;
  26436. + max_cck_power_level = 22;
  26437. + min_ofdm_power_level = 10;
  26438. + max_ofdm_power_level = 25;
  26439. + }
  26440. +
  26441. + if( priv->TrSwitchState == TR_SW_TX )
  26442. + {
  26443. + //printk("SetTxPowerLevel8187(): Origianl OFDM Tx power level %d, adjust value = %d\n", ofdm_power_level,GetTxOfdmHighPowerBias(dev));
  26444. + ofdm_power_level -= GetTxOfdmHighPowerBias(dev);
  26445. + cck_power_level -= GetTxCckHighPowerBias(dev);
  26446. + //printk("SetTxPowerLevel8187(): Adjusted OFDM Tx power level %d for we are in High Power state\n",
  26447. + // ofdm_power_level);
  26448. + //printk("SetTxPowerLevel8187(): Adjusted CCK Tx power level %d for we are in High Power state\n",
  26449. + // cck_power_level);
  26450. + }
  26451. + /* CCK power setting */
  26452. + if(cck_power_level > (max_cck_power_level -min_cck_power_level))
  26453. + cck_power_level = max_cck_power_level;
  26454. + else
  26455. + cck_power_level += min_cck_power_level;
  26456. + cck_power_level += priv->cck_txpwr_base;
  26457. +
  26458. + if(cck_power_level > 35)
  26459. + cck_power_level = 35;
  26460. + if(cck_power_level < 0)
  26461. + cck_power_level = 0;
  26462. +
  26463. + if(ch == 14)
  26464. + cck_power_table = rtl8225z2_tx_power_cck_ch14;
  26465. + else
  26466. + cck_power_table = rtl8225z2_tx_power_cck;
  26467. + if (hw_version == VERSION_8187B_B)
  26468. + {
  26469. + if (cck_power_level <= 6){
  26470. + }
  26471. + else if (cck_power_level <=11){
  26472. + cck_power_table += 8;
  26473. + }
  26474. + else{
  26475. + cck_power_table += (8*2);
  26476. + }
  26477. + }else{
  26478. + if (cck_power_level<=5){
  26479. + }else if(cck_power_level<=11){
  26480. + cck_power_table += 8;
  26481. + }else if(cck_power_level <= 17){
  26482. + cck_power_table += 8*2;
  26483. + }else{
  26484. + cck_power_table += 8*3;
  26485. + }
  26486. + }
  26487. +
  26488. +
  26489. +
  26490. + for(i=0;i<8;i++){
  26491. +
  26492. + power = cck_power_table[i];
  26493. + write_phy_cck(dev, 0x44 + i, power);
  26494. + }
  26495. +
  26496. + //write_nic_byte(dev, TX_GAIN_CCK, power);
  26497. + //2005.11.17,
  26498. + write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]*2));
  26499. +
  26500. +// force_pci_posting(dev);
  26501. +// msleep(1);
  26502. +//in windows the delay was del from 85 to 87,
  26503. +//here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  26504. +
  26505. + /* OFDM power setting */
  26506. + // Old:
  26507. + // if(ofdm_power_level > max_ofdm_power_level)
  26508. + // ofdm_power_level = 35;
  26509. + // ofdm_power_level += min_ofdm_power_level;
  26510. + // Latest:
  26511. + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
  26512. + ofdm_power_level = max_ofdm_power_level;
  26513. + else
  26514. + ofdm_power_level += min_ofdm_power_level;
  26515. +
  26516. + ofdm_power_level += priv->ofdm_txpwr_base;
  26517. +
  26518. + if(ofdm_power_level > 35)
  26519. + ofdm_power_level = 35;
  26520. +
  26521. + if(ofdm_power_level < 0)
  26522. + ofdm_power_level = 0;
  26523. + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]*2);
  26524. +
  26525. + if (hw_version == VERSION_8187B_B)
  26526. + {
  26527. + if(ofdm_power_level<=11){
  26528. + write_phy_ofdm(dev, 0x87, 0x60);
  26529. + write_phy_ofdm(dev, 0x89, 0x60);
  26530. + }
  26531. + else{
  26532. + write_phy_ofdm(dev, 0x87, 0x5c);
  26533. + write_phy_ofdm(dev, 0x89, 0x5c);
  26534. + }
  26535. + }else{
  26536. + if(ofdm_power_level<=11){
  26537. + write_phy_ofdm(dev, 0x87, 0x5c);
  26538. + write_phy_ofdm(dev, 0x89, 0x5c);
  26539. + }
  26540. + if(ofdm_power_level<=17){
  26541. + write_phy_ofdm(dev, 0x87, 0x54);
  26542. + write_phy_ofdm(dev, 0x89, 0x54);
  26543. + }
  26544. + else{
  26545. + write_phy_ofdm(dev, 0x87, 0x50);
  26546. + write_phy_ofdm(dev, 0x89, 0x50);
  26547. + }
  26548. + }
  26549. +// force_pci_posting(dev);
  26550. +// msleep(1);
  26551. +//in windows the delay was del from 85 to 87,
  26552. +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  26553. + }else if(NIC_8187 == priv->card_8187) {
  26554. + min_cck_power_level = 0;
  26555. + max_cck_power_level = 15;
  26556. + min_ofdm_power_level = 10;
  26557. + max_ofdm_power_level = 25;
  26558. + if(cck_power_level > (max_cck_power_level -min_cck_power_level))
  26559. + cck_power_level = max_cck_power_level;
  26560. + else
  26561. + cck_power_level += min_cck_power_level;
  26562. + cck_power_level += priv->cck_txpwr_base;
  26563. +
  26564. + if(cck_power_level > 35)
  26565. + cck_power_level = 35;
  26566. +
  26567. + if(ch == 14)
  26568. + cck_power_table = rtl8225z2_tx_power_cck_ch14;
  26569. + else
  26570. + cck_power_table = rtl8225z2_tx_power_cck;
  26571. + for(i=0;i<8;i++){
  26572. + power = cck_power_table[i];
  26573. + write_phy_cck(dev, 0x44 + i, power);
  26574. + }
  26575. +
  26576. + //write_nic_byte(dev, TX_GAIN_CCK, power);
  26577. + //2005.11.17,
  26578. + write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]);
  26579. +
  26580. +// force_pci_posting(dev);
  26581. +// msleep(1);
  26582. +//in windows the delay was del from 85 to 87,
  26583. +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  26584. + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
  26585. + ofdm_power_level = max_ofdm_power_level;
  26586. + else
  26587. + ofdm_power_level += min_ofdm_power_level;
  26588. +
  26589. + ofdm_power_level += priv->ofdm_txpwr_base;
  26590. +
  26591. + if(ofdm_power_level > 35)
  26592. + ofdm_power_level = 35;
  26593. + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[ofdm_power_level]);
  26594. +
  26595. + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
  26596. +
  26597. + write_phy_ofdm(dev,2,0x42);
  26598. + write_phy_ofdm(dev,5,0);
  26599. + write_phy_ofdm(dev,6,0x40);
  26600. + write_phy_ofdm(dev,7,0);
  26601. + write_phy_ofdm(dev,8,0x40);
  26602. + }
  26603. +
  26604. +}
  26605. +
  26606. +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
  26607. +{
  26608. + struct r8180_priv *priv = ieee80211_priv(dev);
  26609. + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
  26610. + ieee80211_is_54g(priv->ieee80211->current_network)) ||
  26611. + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
  26612. + int eifs_addr;
  26613. +
  26614. + down(&priv->set_chan_sem);
  26615. +
  26616. + if(NIC_8187 == priv->card_8187) {
  26617. + eifs_addr = EIFS_8187;
  26618. + } else {
  26619. + eifs_addr = EIFS_8187B;
  26620. + }
  26621. +
  26622. +#ifdef ENABLE_DOT11D
  26623. + if(!IsLegalChannel(priv->ieee80211, ch) )
  26624. + {
  26625. + printk("channel(%d). is invalide\n", ch);
  26626. + up(&priv->set_chan_sem);
  26627. + return;
  26628. + }
  26629. +#endif
  26630. + //87B not do it FIXME
  26631. + rtl8225z2_SetTXPowerLevel(dev, ch);
  26632. +
  26633. + //write_nic_byte(dev,0x7,(u8)rtl8225_chan[ch]);
  26634. + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
  26635. +
  26636. + force_pci_posting(dev);
  26637. + //mdelay(10);
  26638. +//in windows the delay was del from 85 to 87,
  26639. +//and here we mod to sleep, or The CPU occupany is too hight. LZM 31/10/2008
  26640. + if(NIC_8187 == priv->card_8187){
  26641. + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
  26642. +
  26643. + if(gset)
  26644. + write_nic_byte(dev,DIFS,20); //DIFS: 20
  26645. + else
  26646. + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
  26647. +
  26648. + if(priv->ieee80211->state == IEEE80211_LINKED &&
  26649. + ieee80211_is_shortslot(priv->ieee80211->current_network))
  26650. + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
  26651. +
  26652. + else
  26653. + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
  26654. +
  26655. +
  26656. + if(gset){
  26657. + write_nic_byte(dev,eifs_addr,91 - 20); // EIFS: 91 (0x5B)
  26658. + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
  26659. + //DMESG("using G net params");
  26660. + }else{
  26661. + write_nic_byte(dev,eifs_addr,91 - 0x24); // EIFS: 91 (0x5B)
  26662. + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
  26663. + //DMESG("using B net params");
  26664. + }
  26665. + }
  26666. +
  26667. + else {
  26668. +#ifdef THOMAS_TURBO
  26669. + if(priv->ieee80211->current_network.Turbo_Enable && priv->ieee80211->iw_mode == IW_MODE_INFRA){
  26670. + write_nic_word(dev,AC_VO_PARAM,0x5114);
  26671. + write_nic_word(dev,AC_VI_PARAM,0x5114);
  26672. + write_nic_word(dev,AC_BE_PARAM,0x5114);
  26673. + write_nic_word(dev,AC_BK_PARAM,0x5114);
  26674. + } else {
  26675. + write_nic_word(dev,AC_VO_PARAM,0x731c);
  26676. + write_nic_word(dev,AC_VI_PARAM,0x731c);
  26677. + write_nic_word(dev,AC_BE_PARAM,0x731c);
  26678. + write_nic_word(dev,AC_BK_PARAM,0x731c);
  26679. + }
  26680. +#endif
  26681. + }
  26682. +
  26683. + up(&priv->set_chan_sem);
  26684. +}
  26685. +void
  26686. +MacConfig_87BASIC_HardCode(struct net_device *dev)
  26687. +{
  26688. + //============================================================================
  26689. + // MACREG.TXT
  26690. + //============================================================================
  26691. + int nLinesRead = 0;
  26692. + u32 u4bRegOffset, u4bRegValue, u4bPageIndex;
  26693. + int i;
  26694. +
  26695. + nLinesRead=(sizeof(MAC_REG_TABLE)/3)/4;
  26696. +
  26697. + for(i = 0; i < nLinesRead; i++)
  26698. + {
  26699. + u4bRegOffset=MAC_REG_TABLE[i][0];
  26700. + u4bRegValue=MAC_REG_TABLE[i][1];
  26701. + u4bPageIndex=MAC_REG_TABLE[i][2];
  26702. +
  26703. + u4bRegOffset|= (u4bPageIndex << 8);
  26704. +
  26705. + write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
  26706. + }
  26707. + //============================================================================
  26708. +}
  26709. +
  26710. +static void MacConfig_87BASIC(struct net_device *dev)
  26711. +{
  26712. + MacConfig_87BASIC_HardCode(dev);
  26713. +
  26714. + //============================================================================
  26715. +
  26716. + // Follow TID_AC_MAP of WMac.
  26717. + //PlatformEFIOWrite2Byte(dev, TID_AC_MAP, 0xfa50);
  26718. + write_nic_word(dev, TID_AC_MAP, 0xfa50);
  26719. +
  26720. + // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko.
  26721. + write_nic_word(dev, INT_MIG, 0x0000);
  26722. +
  26723. + // Prevent TPC to cause CRC error. Added by Annie, 2006-06-10.
  26724. + write_nic_dword(dev, 0x1F0, 0x00000000);
  26725. + write_nic_dword(dev, 0x1F4, 0x00000000);
  26726. + write_nic_byte(dev, 0x1F8, 0x00);
  26727. +
  26728. + // For WiFi 5.2.2.5 Atheros AP performance. Added by Annie, 2006-06-12.
  26729. + // PlatformIOWrite4Byte(dev, RFTiming, 0x0008e00f);
  26730. + // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
  26731. + write_nic_dword(dev, RFTiming, 0x00004001);
  26732. +
  26733. +#ifdef TODO
  26734. + // Asked for by Victor, for 87B B-cut Rx FIFO overflow bug, 2006.06.27, by rcnjko.
  26735. + if(dev->NdisUsbDev.CardInfo.USBIsHigh == FALSE)
  26736. + {
  26737. + PlatformEFIOWrite1Byte(dev, 0x24E, 0x01);
  26738. + }
  26739. +#endif
  26740. +}
  26741. +
  26742. +
  26743. +//
  26744. +// Description:
  26745. +// Initialize RFE and read Zebra2 version code.
  26746. +//
  26747. +// 2005-08-01, by Annie.
  26748. +//
  26749. +void
  26750. +SetupRFEInitialTiming(struct net_device* dev)
  26751. +{
  26752. + //u32 data8, data9;
  26753. + struct r8180_priv *priv = ieee80211_priv(dev);
  26754. +
  26755. + // setup initial timing for RFE
  26756. + // Set VCO-PDN pin.
  26757. + write_nic_word(dev, RFPinsOutput, 0x0480);
  26758. + write_nic_word(dev, RFPinsSelect, 0x2488);
  26759. + write_nic_word(dev, RFPinsEnable, 0x1FFF);
  26760. +
  26761. + mdelay(100);
  26762. + // Steven recommends: delay 1 sec for setting RF 1.8V. by Annie, 2005-04-28.
  26763. + mdelay(1000);
  26764. +
  26765. + //
  26766. + // TODO: Read Zebra version code if necessary.
  26767. + //
  26768. + priv->rf_chip = RF_ZEBRA2;
  26769. +}
  26770. +
  26771. +
  26772. +void ZEBRA_Config_87BASIC_HardCode(struct net_device* dev)
  26773. +{
  26774. + u32 i;
  26775. + u32 addr,data;
  26776. + u32 u4bRegOffset, u4bRegValue;
  26777. +
  26778. +
  26779. + //=============================================================================
  26780. + // RADIOCFG.TXT
  26781. + //=============================================================================
  26782. + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1);
  26783. + write_rtl8225(dev, 0x01, 0x0ee0); mdelay(1);
  26784. + write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
  26785. + write_rtl8225(dev, 0x03, 0x0441); mdelay(1);
  26786. + write_rtl8225(dev, 0x04, 0x08c3); mdelay(1);
  26787. + write_rtl8225(dev, 0x05, 0x0c72); mdelay(1);
  26788. + write_rtl8225(dev, 0x06, 0x00e6); mdelay(1);
  26789. + write_rtl8225(dev, 0x07, 0x082a); mdelay(1);
  26790. + write_rtl8225(dev, 0x08, 0x003f); mdelay(1);
  26791. + write_rtl8225(dev, 0x09, 0x0335); mdelay(1);
  26792. + write_rtl8225(dev, 0x0a, 0x09d4); mdelay(1);
  26793. + write_rtl8225(dev, 0x0b, 0x07bb); mdelay(1);
  26794. + write_rtl8225(dev, 0x0c, 0x0850); mdelay(1);
  26795. + write_rtl8225(dev, 0x0d, 0x0cdf); mdelay(1);
  26796. + write_rtl8225(dev, 0x0e, 0x002b); mdelay(1);
  26797. + write_rtl8225(dev, 0x0f, 0x0114); mdelay(1);
  26798. +
  26799. + write_rtl8225(dev, 0x00, 0x01b7); mdelay(1);
  26800. +
  26801. +
  26802. + for(i=1;i<=95;i++)
  26803. + {
  26804. + write_rtl8225(dev, 0x01, i);mdelay(1);
  26805. + write_rtl8225(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
  26806. + //DbgPrint("RF - 0x%x = 0x%x\n", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
  26807. + }
  26808. +
  26809. + write_rtl8225(dev, 0x03, 0x0080); mdelay(1); // write reg 18
  26810. + write_rtl8225(dev, 0x05, 0x0004); mdelay(1); // write reg 20
  26811. + write_rtl8225(dev, 0x00, 0x00b7); mdelay(1); // switch to reg0-reg15
  26812. + //lzm mod for up take too long time 20081201
  26813. +#ifdef THOMAS_BEACON
  26814. + msleep(1000);// Deay 1 sec. //0xfd
  26815. + //msleep(1000);// Deay 1 sec. //0xfd
  26816. + //msleep(1000);// Deay 1 sec. //0xfd
  26817. + msleep(400);// Deay 1 sec. //0xfd
  26818. +#else
  26819. +
  26820. + mdelay(1000);
  26821. + //mdelay(1000);
  26822. + //mdelay(1000);
  26823. + mdelay(400);
  26824. +#endif
  26825. + write_rtl8225(dev, 0x02, 0x0c4d); mdelay(1);
  26826. + //lzm mod for up take too long time 20081201
  26827. + //mdelay(1000);
  26828. + //mdelay(1000);
  26829. + msleep(100);// Deay 100 ms. //0xfe
  26830. + msleep(100);// Deay 100 ms. //0xfe
  26831. + write_rtl8225(dev, 0x02, 0x044d); mdelay(1);
  26832. + write_rtl8225(dev, 0x00, 0x02bf); mdelay(1); //0x002f disable 6us corner change, 06f--> enable
  26833. +
  26834. + //=============================================================================
  26835. +
  26836. + //=============================================================================
  26837. + // CCKCONF.TXT
  26838. + //=============================================================================
  26839. + /*
  26840. + u4bRegOffset=0x41;
  26841. + u4bRegValue=0xc8;
  26842. +
  26843. + //DbgPrint("\nCCK- 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
  26844. + WriteBB(dev, (0x01000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
  26845. + */
  26846. +
  26847. +
  26848. + //=============================================================================
  26849. +
  26850. + //=============================================================================
  26851. + // Follow WMAC RTL8225_Config()
  26852. + //=============================================================================
  26853. +// //
  26854. +// // enable EEM0 and EEM1 in 9346CR
  26855. +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)|0xc0);
  26856. +// // enable PARM_En in Config3
  26857. +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)|0x40);
  26858. +//
  26859. +// PlatformEFIOWrite4Byte(dev, AnaParm2, ANAPARM2_ASIC_ON); //0x727f3f52
  26860. +// PlatformEFIOWrite4Byte(dev, AnaParm, ANAPARM_ASIC_ON); //0x45090658
  26861. +
  26862. + // power control
  26863. + write_nic_byte(dev, CCK_TXAGC, 0x03);
  26864. + write_nic_byte(dev, OFDM_TXAGC, 0x07);
  26865. + write_nic_byte(dev, ANTSEL, 0x03);
  26866. +
  26867. +// // disable PARM_En in Config3
  26868. +// PlatformEFIOWrite1Byte(dev, CONFIG3, PlatformEFIORead1Byte(dev, CONFIG3)&0xbf);
  26869. +// // disable EEM0 and EEM1 in 9346CR
  26870. +// PlatformEFIOWrite1Byte(dev, CR9346, PlatformEFIORead1Byte(dev, CR9346)&0x3f);
  26871. + //=============================================================================
  26872. +
  26873. + //=============================================================================
  26874. + // AGC.txt
  26875. + //=============================================================================
  26876. + //write_nic_dword( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
  26877. + //write_phy_ofdm( dev, 0x00, 0x12); // David, 2006-08-01
  26878. + write_phy_ofdm( dev, 0x80, 0x12); // David, 2006-08-09
  26879. +
  26880. + for (i=0; i<128; i++)
  26881. + {
  26882. + //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
  26883. +
  26884. + data = ZEBRA_AGC[i+1];
  26885. + data = data << 8;
  26886. + data = data | 0x0000008F;
  26887. +
  26888. + addr = i + 0x80; //enable writing AGC table
  26889. + addr = addr << 8;
  26890. + addr = addr | 0x0000008E;
  26891. +
  26892. + write_phy_ofdm(dev,data&0x7f,(data>>8)&0xff);
  26893. + write_phy_ofdm(dev,addr&0x7f,(addr>>8)&0xff);
  26894. + write_phy_ofdm(dev,0x0E,0x00);
  26895. + }
  26896. +
  26897. + //write_nic_dword(dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
  26898. + //write_phy_ofdm( dev, 0x00, 0x10); // David, 2006-08-01
  26899. + write_phy_ofdm( dev, 0x80, 0x10); // David, 2006-08-09
  26900. +
  26901. + //=============================================================================
  26902. +
  26903. + //=============================================================================
  26904. + // OFDMCONF.TXT
  26905. + //=============================================================================
  26906. +
  26907. + for(i=0; i<60; i++)
  26908. + {
  26909. + u4bRegOffset=i;
  26910. + u4bRegValue=OFDM_CONFIG[i];
  26911. + //u4bRegValue=OFDM_CONFIG3m82[i];
  26912. +
  26913. + // write_nic_dword(dev,PhyAddr,(0x00000080 | (u4bRegOffset & 0x7f) | ((u4bRegValue & 0xff) << 8)));
  26914. + write_phy_ofdm(dev,i,u4bRegValue);
  26915. + }
  26916. +
  26917. +
  26918. + //=============================================================================
  26919. +}
  26920. +
  26921. +void ZEBRA_Config_87BASIC(struct net_device *dev)
  26922. +{
  26923. + ZEBRA_Config_87BASIC_HardCode(dev);
  26924. +}
  26925. +//by amy for DIG
  26926. +//
  26927. +// Description:
  26928. +// Update initial gain into PHY.
  26929. +//
  26930. +void
  26931. +UpdateCCKThreshold(
  26932. + struct net_device *dev
  26933. + )
  26934. +{
  26935. + struct r8180_priv *priv = ieee80211_priv(dev);
  26936. + // Update CCK Power Detection(0x41) value.
  26937. + switch(priv->StageCCKTh)
  26938. + {
  26939. + case 0:
  26940. +// printk("Update CCK Stage 0: 88 \n");
  26941. + write_phy_cck(dev, 0xc1, 0x88);mdelay(1);
  26942. + break;
  26943. +
  26944. + case 1:
  26945. +// printk("Update CCK Stage 1: 98 \n");
  26946. + write_phy_cck(dev, 0xc1, 0x98);mdelay(1);
  26947. + break;
  26948. +
  26949. + case 2:
  26950. +// printk("Update CCK Stage 2: C8 \n");
  26951. + write_phy_cck(dev, 0xc1, 0xC8);mdelay(1);
  26952. + break;
  26953. +
  26954. + case 3:
  26955. +// printk("Update CCK Stage 3: D8 \n");
  26956. + write_phy_cck(dev, 0xc1, 0xD8);mdelay(1);
  26957. + break;
  26958. +
  26959. + default:
  26960. +// printk("Update CCK Stage %d ERROR!\n", pHalData->StageCCKTh);
  26961. + break;
  26962. + }
  26963. +}
  26964. +//
  26965. +// Description:
  26966. +// Update initial gain into PHY.
  26967. +//
  26968. +void
  26969. +UpdateInitialGain(
  26970. + struct net_device *dev
  26971. + )
  26972. +{
  26973. + struct r8180_priv *priv = ieee80211_priv(dev);
  26974. + //u8 u1Tmp=0;
  26975. +
  26976. + //printk("UpdateInitialGain(): InitialGain: %d RFChipID: %d\n", priv->InitialGain, priv->rf_chip);
  26977. +
  26978. + switch(priv->rf_chip)
  26979. + {
  26980. + case RF_ZEBRA:
  26981. + case RF_ZEBRA2:
  26982. +
  26983. + //
  26984. + // Note:
  26985. + // Whenever we update this gain table, we should be careful about those who call it.
  26986. + // Functions which call UpdateInitialGain as follows are important:
  26987. + // (1)StaRateAdaptive87B
  26988. + // (2)DIG_Zebra
  26989. + // (3)ActSetWirelessMode8187 (when the wireless mode is "B" mode, we set the
  26990. + // OFDM[0x17] = 0x26 to improve the Rx sensitivity).
  26991. + // By Bruce, 2007-06-01.
  26992. + //
  26993. +
  26994. + //
  26995. + // SD3 C.M. Lin Initial Gain Table, by Bruce, 2007-06-01.
  26996. + //
  26997. + switch(priv->InitialGain)
  26998. + {
  26999. + case 1: //m861dBm
  27000. +// DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm ");
  27001. + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
  27002. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  27003. + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
  27004. + break;
  27005. +
  27006. + case 2: //m862dBm
  27007. +// DMESG("RTL8187 + 8225 Initial Gain State 2: -78 dBm ");
  27008. + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
  27009. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  27010. + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
  27011. + break;
  27012. +
  27013. + case 3: //m863dBm
  27014. +// DMESG("RTL8187 + 8225 Initial Gain State 3: -78 dBm ");
  27015. + write_phy_ofdm(dev, 0x97, 0x36); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
  27016. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  27017. + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
  27018. + break;
  27019. +
  27020. + case 4: //m864dBm
  27021. +// DMESG("RTL8187 + 8225 Initial Gain State 4: -74 dBm ");
  27022. + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);// Revise 0x26 to 0x36, by Roger, 2007.05.03.
  27023. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  27024. + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
  27025. + break;
  27026. +
  27027. + case 5: //m82dBm
  27028. +// DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm ");
  27029. + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
  27030. + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
  27031. + write_phy_ofdm(dev, 0x85, 0xfb); mdelay(1);
  27032. + break;
  27033. +
  27034. + case 6: //m78dBm
  27035. +// DMESG("RTL8187 + 8225 Initial Gain State 6: -70 dBm ");
  27036. + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
  27037. + write_phy_ofdm(dev, 0xa4, 0x96); mdelay(1);
  27038. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  27039. + break;
  27040. +
  27041. + case 7: //m74dBm
  27042. +// DMESG("RTL8187 + 8225 Initial Gain State 7: -70 dBm ");
  27043. + write_phy_ofdm(dev, 0x97, 0x56); mdelay(1);
  27044. + write_phy_ofdm(dev, 0xa4, 0xa6); mdelay(1);
  27045. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  27046. + break;
  27047. +
  27048. + // By Bruce, 2007-03-29.
  27049. + case 8:
  27050. + write_phy_ofdm(dev, 0x97, 0x66); mdelay(1);
  27051. + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
  27052. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  27053. + break;
  27054. +
  27055. + default: //MP
  27056. +// DMESG("RTL8187 + 8225 Initial Gain State: -82 dBm (default), InitialGain(%d)", priv->InitialGain);
  27057. + write_phy_ofdm(dev, 0x97, 0x26); mdelay(1);
  27058. + write_phy_ofdm(dev, 0xa4, 0x86); mdelay(1);
  27059. + write_phy_ofdm(dev, 0x85, 0xfa); mdelay(1);
  27060. + break;
  27061. + }
  27062. + break;
  27063. +
  27064. + default:
  27065. + break;
  27066. + }
  27067. +}
  27068. +//by amy for DIG
  27069. +void PhyConfig8187(struct net_device *dev)
  27070. +{
  27071. + struct r8180_priv *priv = ieee80211_priv(dev);
  27072. + u8 btConfig4;
  27073. +
  27074. + btConfig4 = read_nic_byte(dev, CONFIG4);
  27075. + priv->RFProgType = (btConfig4 & 0x03);
  27076. +
  27077. +
  27078. +
  27079. + switch(priv->rf_chip)
  27080. + {
  27081. + case RF_ZEBRA2:
  27082. + ZEBRA_Config_87BASIC(dev);
  27083. + break;
  27084. + }
  27085. + if(priv->bDigMechanism)
  27086. + {
  27087. + if(priv->InitialGain == 0)
  27088. + priv->InitialGain = 4;
  27089. + //DMESG("DIG is enabled, set default initial gain index to %d", priv->InitialGain);
  27090. + }
  27091. +
  27092. + // By Bruce, 2007-03-29.
  27093. + UpdateCCKThreshold(dev);
  27094. + // Update initial gain after PhyConfig comleted, asked for by SD3 CMLin.
  27095. + UpdateInitialGain(dev);
  27096. + return ;
  27097. +}
  27098. +
  27099. +u8 GetSupportedWirelessMode8187(struct net_device* dev)
  27100. +{
  27101. + u8 btSupportedWirelessMode;
  27102. + struct r8180_priv *priv = ieee80211_priv(dev);
  27103. +
  27104. + btSupportedWirelessMode = 0;
  27105. +
  27106. + switch(priv->rf_chip)
  27107. + {
  27108. + case RF_ZEBRA:
  27109. + case RF_ZEBRA2:
  27110. + btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
  27111. + break;
  27112. + default:
  27113. + btSupportedWirelessMode = WIRELESS_MODE_B;
  27114. + break;
  27115. + }
  27116. + return btSupportedWirelessMode;
  27117. +}
  27118. +
  27119. +void ActUpdateChannelAccessSetting(struct net_device *dev,
  27120. + int WirelessMode,
  27121. + PCHANNEL_ACCESS_SETTING ChnlAccessSetting)
  27122. +{
  27123. + AC_CODING eACI;
  27124. + AC_PARAM AcParam;
  27125. +#ifdef TODO
  27126. + PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
  27127. +#endif
  27128. + //bool bFollowLegacySetting = false;
  27129. +
  27130. +
  27131. + switch( WirelessMode )
  27132. + {
  27133. + case WIRELESS_MODE_A:
  27134. + ChnlAccessSetting->SIFS_Timer = 0x22;
  27135. + ChnlAccessSetting->DIFS_Timer = 34; // 34 = 16 + 2*9. 2006.06.07, by rcnjko.
  27136. + ChnlAccessSetting->SlotTimeTimer = 9;
  27137. + ChnlAccessSetting->EIFS_Timer = 23;
  27138. + ChnlAccessSetting->CWminIndex = 4;
  27139. + ChnlAccessSetting->CWmaxIndex = 10;
  27140. + break;
  27141. +
  27142. + case WIRELESS_MODE_B:
  27143. + ChnlAccessSetting->SIFS_Timer = 0x22;
  27144. + ChnlAccessSetting->DIFS_Timer = 50; // 50 = 10 + 2*20. 2006.06.07, by rcnjko.
  27145. + ChnlAccessSetting->SlotTimeTimer = 20;
  27146. + ChnlAccessSetting->EIFS_Timer = 91;
  27147. + ChnlAccessSetting->CWminIndex = 5;
  27148. + ChnlAccessSetting->CWmaxIndex = 10;
  27149. + break;
  27150. +
  27151. + case WIRELESS_MODE_G:
  27152. + //
  27153. + // <RJ_TODO_8185B>
  27154. + // TODO: We still don't know how to set up these registers, just follow WMAC to
  27155. + // verify 8185B FPAG.
  27156. + //
  27157. + // <RJ_TODO_8185B>
  27158. + // Jong said CWmin/CWmax register are not functional in 8185B,
  27159. + // so we shall fill channel access realted register into AC parameter registers,
  27160. + // even in nQBss.
  27161. + //
  27162. + ChnlAccessSetting->SIFS_Timer = 0x22; // Suggested by Jong, 2005.12.08.
  27163. + ChnlAccessSetting->SlotTimeTimer = 9; // 2006.06.07, by rcnjko.
  27164. + ChnlAccessSetting->DIFS_Timer = 28; // 28 = 10 + 2*9. 2006.06.07, by rcnjko.
  27165. + ChnlAccessSetting->EIFS_Timer = 0x5B; // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
  27166. +#ifdef TODO
  27167. + switch (Adapter->NdisUsbDev.CWinMaxMin)
  27168. +#else
  27169. + switch (2)
  27170. +#endif
  27171. + {
  27172. + case 0:// 0: [max:7 min:1 ]
  27173. + ChnlAccessSetting->CWminIndex = 1;
  27174. + ChnlAccessSetting->CWmaxIndex = 7;
  27175. + break;
  27176. + case 1:// 1: [max:7 min:2 ]
  27177. + ChnlAccessSetting->CWminIndex = 2;
  27178. + ChnlAccessSetting->CWmaxIndex = 7;
  27179. + break;
  27180. + case 2:// 2: [max:7 min:3 ]
  27181. + ChnlAccessSetting->CWminIndex = 3;
  27182. + ChnlAccessSetting->CWmaxIndex = 7;
  27183. + break;
  27184. + case 3:// 3: [max:9 min:1 ]
  27185. + ChnlAccessSetting->CWminIndex = 1;
  27186. + ChnlAccessSetting->CWmaxIndex = 9;
  27187. + break;
  27188. + case 4:// 4: [max:9 min:2 ]
  27189. + ChnlAccessSetting->CWminIndex = 2;
  27190. + ChnlAccessSetting->CWmaxIndex = 9;
  27191. + break;
  27192. + case 5:// 5: [max:9 min:3 ]
  27193. + ChnlAccessSetting->CWminIndex = 3;
  27194. + ChnlAccessSetting->CWmaxIndex = 9;
  27195. + break;
  27196. + case 6:// 6: [max:A min:5 ]
  27197. + ChnlAccessSetting->CWminIndex = 5;
  27198. + ChnlAccessSetting->CWmaxIndex = 10;
  27199. + break;
  27200. + case 7:// 7: [max:A min:4 ]
  27201. + ChnlAccessSetting->CWminIndex = 4;
  27202. + ChnlAccessSetting->CWmaxIndex = 10;
  27203. + break;
  27204. +
  27205. + default:
  27206. + ChnlAccessSetting->CWminIndex = 1;
  27207. + ChnlAccessSetting->CWmaxIndex = 7;
  27208. + break;
  27209. + }
  27210. +#ifdef TODO
  27211. + if( Adapter->MgntInfo.OpMode == RT_OP_MODE_IBSS)
  27212. + {
  27213. + ChnlAccessSetting->CWminIndex= 4;
  27214. + ChnlAccessSetting->CWmaxIndex= 10;
  27215. + }
  27216. +#endif
  27217. + break;
  27218. + }
  27219. +
  27220. +
  27221. + write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
  27222. +//{ update slot time related by david, 2006-7-21
  27223. + write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
  27224. +#ifdef TODO
  27225. + if(pStaQos->CurrentQosMode > QOS_DISABLE)
  27226. + {
  27227. + for(eACI = 0; eACI < AC_MAX; eACI++)
  27228. + {
  27229. + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, \
  27230. + (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
  27231. + }
  27232. + }
  27233. + else
  27234. +#endif
  27235. + {
  27236. + u8 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
  27237. +
  27238. + write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
  27239. + write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
  27240. + write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
  27241. + write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
  27242. + }
  27243. +//}
  27244. +
  27245. + write_nic_byte(dev, EIFS_8187B, ChnlAccessSetting->EIFS_Timer);
  27246. + write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
  27247. +#ifdef TODO
  27248. + // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
  27249. + if( pStaQos->CurrentQosMode > QOS_DISABLE )
  27250. + { // QoS mode.
  27251. + if(pStaQos->QBssWirelessMode == WirelessMode)
  27252. + {
  27253. + // Follow AC Parameters of the QBSS.
  27254. + for(eACI = 0; eACI < AC_MAX; eACI++)
  27255. + {
  27256. + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
  27257. + }
  27258. + }
  27259. + else
  27260. + {
  27261. + // Follow Default WMM AC Parameters.
  27262. + bFollowLegacySetting = TRUE;
  27263. + }
  27264. + }
  27265. + else
  27266. + { // Legacy 802.11.
  27267. + bFollowLegacySetting = TRUE;
  27268. + }
  27269. +
  27270. + if(bFollowLegacySetting)
  27271. +#endif
  27272. + if(true)
  27273. + {
  27274. + //
  27275. + // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
  27276. + // 2005.12.01, by rcnjko.
  27277. + //
  27278. + AcParam.longData = 0;
  27279. + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
  27280. + AcParam.f.AciAifsn.f.ACM = 0;
  27281. + AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; // Follow 802.11 CWmin.
  27282. + AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; // Follow 802.11 CWmax.
  27283. + AcParam.f.TXOPLimit = 0;
  27284. + for(eACI = 0; eACI < AC_MAX; eACI++)
  27285. + {
  27286. + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
  27287. + {
  27288. + PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
  27289. + AC_CODING eACI;
  27290. + u8 u1bAIFS;
  27291. + u32 u4bAcParam;
  27292. +
  27293. + // Retrive paramters to udpate.
  27294. + eACI = pAcParam->f.AciAifsn.f.ACI;
  27295. + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
  27296. + u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
  27297. + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
  27298. + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
  27299. + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
  27300. +
  27301. + switch(eACI)
  27302. + {
  27303. + case AC1_BK:
  27304. + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
  27305. + break;
  27306. +
  27307. + case AC0_BE:
  27308. + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
  27309. + break;
  27310. +
  27311. + case AC2_VI:
  27312. + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
  27313. + break;
  27314. +
  27315. + case AC3_VO:
  27316. + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
  27317. + break;
  27318. +
  27319. + default:
  27320. + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
  27321. + break;
  27322. + }
  27323. +
  27324. + // Cehck ACM bit.
  27325. + // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
  27326. + //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
  27327. + {
  27328. + PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
  27329. + AC_CODING eACI = pAciAifsn->f.ACI;
  27330. +
  27331. + //modified Joseph
  27332. + //for 8187B AsynIORead issue
  27333. +#ifdef TODO
  27334. + u8 AcmCtrl = pHalData->AcmControl;
  27335. +#else
  27336. + u8 AcmCtrl = 0;
  27337. +#endif
  27338. + if( pAciAifsn->f.ACM )
  27339. + { // ACM bit is 1.
  27340. + switch(eACI)
  27341. + {
  27342. + case AC0_BE:
  27343. + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21
  27344. + break;
  27345. +
  27346. + case AC2_VI:
  27347. + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42
  27348. + break;
  27349. +
  27350. + case AC3_VO:
  27351. + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84
  27352. + break;
  27353. +
  27354. + default:
  27355. + printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set\
  27356. + failed: eACI is %d\n", eACI );
  27357. + break;
  27358. + }
  27359. + }
  27360. + else
  27361. + { // ACM bit is 0.
  27362. + switch(eACI)
  27363. + {
  27364. + case AC0_BE:
  27365. + AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE
  27366. + break;
  27367. +
  27368. + case AC2_VI:
  27369. + AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD
  27370. + break;
  27371. +
  27372. + case AC3_VO:
  27373. + AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B
  27374. + break;
  27375. +
  27376. + default:
  27377. + break;
  27378. + }
  27379. + }
  27380. +
  27381. + //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
  27382. +
  27383. +#ifdef TO_DO
  27384. + pHalData->AcmControl = AcmCtrl;
  27385. +#endif
  27386. + write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
  27387. + }
  27388. + }
  27389. + }
  27390. + }
  27391. +}
  27392. +
  27393. +void ActSetWirelessMode8187(struct net_device* dev, u8 btWirelessMode)
  27394. +{
  27395. + struct r8180_priv *priv = ieee80211_priv(dev);
  27396. + struct ieee80211_device *ieee = priv->ieee80211;
  27397. + //PMGNT_INFO pMgntInfo = &(pAdapter->MgntInfo);
  27398. + u8 btSupportedWirelessMode = GetSupportedWirelessMode8187(dev);
  27399. +
  27400. + if( (btWirelessMode & btSupportedWirelessMode) == 0 )
  27401. + { // Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko.
  27402. + printk(KERN_WARNING "ActSetWirelessMode8187(): WirelessMode(%d) is not supported (%d)!\n",
  27403. + btWirelessMode, btSupportedWirelessMode);
  27404. + return;
  27405. + }
  27406. +
  27407. + // 1. Assign wireless mode to swtich if necessary.
  27408. + if( (btWirelessMode == WIRELESS_MODE_AUTO) ||
  27409. + (btWirelessMode & btSupportedWirelessMode) == 0 )
  27410. + {
  27411. + if((btSupportedWirelessMode & WIRELESS_MODE_A))
  27412. + {
  27413. + btWirelessMode = WIRELESS_MODE_A;
  27414. + }
  27415. + else if((btSupportedWirelessMode & WIRELESS_MODE_G))
  27416. + {
  27417. + btWirelessMode = WIRELESS_MODE_G;
  27418. + }
  27419. + else if((btSupportedWirelessMode & WIRELESS_MODE_B))
  27420. + {
  27421. + btWirelessMode = WIRELESS_MODE_B;
  27422. + }
  27423. + else
  27424. + {
  27425. + printk(KERN_WARNING "MptActSetWirelessMode8187(): No valid wireless mode supported, \
  27426. + btSupportedWirelessMode(%x)!!!\n", btSupportedWirelessMode);
  27427. + btWirelessMode = WIRELESS_MODE_B;
  27428. + }
  27429. + }
  27430. +
  27431. + // 2. Swtich band.
  27432. + switch(priv->rf_chip)
  27433. + {
  27434. + case RF_ZEBRA:
  27435. + case RF_ZEBRA2:
  27436. + {
  27437. + // Update current wireless mode if we swtich to specified band successfully.
  27438. + ieee->mode = (WIRELESS_MODE)btWirelessMode;
  27439. + }
  27440. + break;
  27441. +
  27442. + default:
  27443. + printk(KERN_WARNING "MptActSetWirelessMode8187(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
  27444. + break;
  27445. + }
  27446. +
  27447. + // 4. Change related setting.
  27448. +#if 0
  27449. + if( ieee->mode == WIRELESS_MODE_A ){
  27450. + DMESG("WIRELESS_MODE_A");
  27451. + }
  27452. + else if(ieee->mode == WIRELESS_MODE_B ){
  27453. + DMESG("WIRELESS_MODE_B");
  27454. + }
  27455. + else if( ieee->mode == WIRELESS_MODE_G ){
  27456. + DMESG("WIRELESS_MODE_G");
  27457. + }
  27458. +#endif
  27459. + ActUpdateChannelAccessSetting(dev, ieee->mode, &priv->ChannelAccessSetting );
  27460. +//by amy 0305
  27461. +#ifdef TODO
  27462. + if(ieee->mode == WIRELESS_MODE_B && priv->InitialGain > pHalData->RegBModeGainStage)
  27463. + {
  27464. + pHalData->InitialGain = pHalData->RegBModeGainStage; // B mode, OFDM[0x17] = 26.
  27465. + RT_TRACE(COMP_INIT | COMP_DIG, DBG_LOUD, ("ActSetWirelessMode8187(): update init_gain to index %d for B mode\n",pHalData->InitialGain));
  27466. + PlatformScheduleWorkItem( &(pHalData->UpdateDigWorkItem) );
  27467. + }
  27468. +// pAdapter->MgntInfo.dot11CurrentWirelessMode = pHalData->CurrentWirelessMode;
  27469. +// MgntSetRegdot11OperationalRateSet( pAdapter );
  27470. +#endif
  27471. +//by amy 0305
  27472. +}
  27473. +
  27474. +
  27475. +void
  27476. +InitializeExtraRegsOn8185(struct net_device *dev)
  27477. +{
  27478. + struct r8180_priv *priv = ieee80211_priv(dev);
  27479. + struct ieee80211_device *ieee = priv->ieee80211;
  27480. + //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
  27481. + bool bUNIVERSAL_CONTROL_RL = false; // Enable per-packet tx retry, 2005.03.31, by rcnjko.
  27482. + bool bUNIVERSAL_CONTROL_AGC = true;//false;
  27483. + bool bUNIVERSAL_CONTROL_ANT = true;//false;
  27484. + bool bAUTO_RATE_FALLBACK_CTL = true;
  27485. + u8 val8;
  27486. +
  27487. + // Set up ACK rate.
  27488. + // Suggested by wcchu, 2005.08.25, by rcnjko.
  27489. + // 1. Initialize (MinRR, MaxRR) to (6,24) for A/G.
  27490. + // 2. MUST Set RR before BRSR.
  27491. + // 3. CCK must be basic rate.
  27492. + if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
  27493. + {
  27494. + write_nic_word(dev, BRSR_8187B, 0x0fff);
  27495. + }
  27496. + else
  27497. + {
  27498. + write_nic_word(dev, BRSR_8187B, 0x000f);
  27499. + }
  27500. +
  27501. +
  27502. + // Retry limit
  27503. + val8 = read_nic_byte(dev, CW_CONF);
  27504. + if(bUNIVERSAL_CONTROL_RL)
  27505. + {
  27506. + val8 &= (~CW_CONF_PERPACKET_RETRY_LIMIT);
  27507. + }
  27508. + else
  27509. + {
  27510. + val8 |= CW_CONF_PERPACKET_RETRY_LIMIT;
  27511. + }
  27512. +
  27513. + write_nic_byte(dev, CW_CONF, val8);
  27514. +
  27515. + // Tx AGC
  27516. + val8 = read_nic_byte(dev, TX_AGC_CTL);
  27517. + if(bUNIVERSAL_CONTROL_AGC)
  27518. + {
  27519. + val8 &= (~TX_AGC_CTL_PER_PACKET_TXAGC);
  27520. + write_nic_byte(dev, CCK_TXAGC, 128);
  27521. + write_nic_byte(dev, OFDM_TXAGC, 128);
  27522. + }
  27523. + else
  27524. + {
  27525. + val8 |= TX_AGC_CTL_PER_PACKET_TXAGC;
  27526. + }
  27527. + write_nic_byte(dev, TX_AGC_CTL, val8);
  27528. +
  27529. + // Tx Antenna including Feedback control
  27530. + val8 = read_nic_byte(dev, TX_AGC_CTL);
  27531. +
  27532. + if(bUNIVERSAL_CONTROL_ANT)
  27533. + {
  27534. + write_nic_byte(dev, ANTSEL, 0x00);
  27535. + val8 &= (~TXAGC_CTL_PER_PACKET_ANT_SEL);
  27536. + }
  27537. + else
  27538. + {
  27539. + val8 |= TXAGC_CTL_PER_PACKET_ANT_SEL;
  27540. + }
  27541. + write_nic_byte(dev, TX_AGC_CTL, val8);
  27542. +
  27543. + // Auto Rate fallback control
  27544. + val8 = read_nic_byte(dev, RATE_FALLBACK);
  27545. + if( bAUTO_RATE_FALLBACK_CTL )
  27546. + {
  27547. + val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP0;
  27548. +
  27549. + // <RJ_TODO_8187B> We shall set up the ARFR according to user's setting.
  27550. + write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
  27551. + }
  27552. + else
  27553. + {
  27554. + val8 &= (~RATE_FALLBACK_CTL_ENABLE);
  27555. + }
  27556. + write_nic_byte(dev, RATE_FALLBACK, val8);
  27557. +
  27558. +}
  27559. +///////////////////////////
  27560. +void rtl8225z2_rf_init(struct net_device *dev)
  27561. +{
  27562. +
  27563. + struct r8180_priv *priv = ieee80211_priv(dev);
  27564. + if (NIC_8187B == priv->card_8187){
  27565. + struct ieee80211_device *ieee = priv->ieee80211;
  27566. + u8 InitWirelessMode;
  27567. + u8 SupportedWirelessMode;
  27568. + bool bInvalidWirelessMode = false;
  27569. + InitializeExtraRegsOn8185(dev);
  27570. +
  27571. + write_nic_byte(dev, MSR, read_nic_byte(dev,MSR) & 0xf3); // default network type to 'No Link'
  27572. + //{to avoid tx stall
  27573. + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR)|MSR_LINK_ENEDCA);//should always set ENDCA bit
  27574. + write_nic_byte(dev, ACM_CONTROL, priv->AcmControl);
  27575. +
  27576. + write_nic_word(dev, BcnIntv, 100);
  27577. + write_nic_word(dev, AtimWnd, 2);
  27578. + write_nic_word(dev, FEMR, 0xFFFF);
  27579. + //LED TYPE
  27580. + {
  27581. + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
  27582. + }
  27583. + write_nic_byte(dev, CR9346, 0x0); // disable config register write
  27584. +
  27585. + //{ add some info here
  27586. + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
  27587. + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
  27588. +
  27589. + write_nic_byte(dev, WPA_CONFIG, 0);
  27590. + //}
  27591. +
  27592. + MacConfig_87BASIC(dev);
  27593. +
  27594. + // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
  27595. + write_nic_word(dev, RFSW_CTRL, 0x569a);
  27596. +#ifdef JOHN_TKIP
  27597. + {
  27598. + void CamResetAllEntry(struct net_device *dev);
  27599. + void EnableHWSecurityConfig8187(struct net_device *dev);
  27600. + CamResetAllEntry(dev);
  27601. + EnableHWSecurityConfig8187(dev);
  27602. + write_nic_word(dev, AESMSK_FC, AESMSK_FC_DEFAULT); mdelay(1);
  27603. + write_nic_word(dev, AESMSK_SC, AESMSK_SC_DEFAULT); mdelay(1);
  27604. + write_nic_word(dev, AESMSK_QC, AESMSK_QC_DEFAULT); mdelay(1);
  27605. + }
  27606. +#endif
  27607. + //-----------------------------------------------------------------------------
  27608. + // Set up PHY related.
  27609. + //-----------------------------------------------------------------------------
  27610. + // Enable Config3.PARAM_En to revise AnaaParm.
  27611. + write_nic_byte(dev, CR9346, 0xC0);
  27612. + write_nic_byte(dev, CONFIG3, read_nic_byte(dev,CONFIG3)|CONFIG3_PARM_En);
  27613. + write_nic_byte(dev, CR9346, 0x0);
  27614. +
  27615. + // Initialize RFE and read Zebra2 version code. Added by Annie, 2005-08-01.
  27616. + SetupRFEInitialTiming(dev);
  27617. + // PHY config.
  27618. + PhyConfig8187(dev);
  27619. +
  27620. + // We assume RegWirelessMode has already been initialized before,
  27621. + // however, we has to validate the wireless mode here and provide a reasonble
  27622. + // initialized value if necessary. 2005.01.13, by rcnjko.
  27623. + SupportedWirelessMode = GetSupportedWirelessMode8187(dev);
  27624. +
  27625. + if((ieee->mode != WIRELESS_MODE_B) &&
  27626. + (ieee->mode != WIRELESS_MODE_G) &&
  27627. + (ieee->mode != WIRELESS_MODE_A) &&
  27628. + (ieee->mode != WIRELESS_MODE_AUTO))
  27629. + { // It should be one of B, G, A, or AUTO.
  27630. + bInvalidWirelessMode = true;
  27631. + }
  27632. + else
  27633. + { // One of B, G, A, or AUTO.
  27634. + // Check if the wireless mode is supported by RF.
  27635. + if( (ieee->mode != WIRELESS_MODE_AUTO) &&
  27636. + (ieee->mode & SupportedWirelessMode) == 0 )
  27637. + {
  27638. + bInvalidWirelessMode = true;
  27639. + }
  27640. + }
  27641. +
  27642. + if(bInvalidWirelessMode || ieee->mode==WIRELESS_MODE_AUTO)
  27643. + { // Auto or other invalid value.
  27644. + // Assigne a wireless mode to initialize.
  27645. + if((SupportedWirelessMode & WIRELESS_MODE_A))
  27646. + {
  27647. + InitWirelessMode = WIRELESS_MODE_A;
  27648. + }
  27649. + else if((SupportedWirelessMode & WIRELESS_MODE_G))
  27650. + {
  27651. +
  27652. + InitWirelessMode = WIRELESS_MODE_G;
  27653. + }
  27654. + else if((SupportedWirelessMode & WIRELESS_MODE_B))
  27655. + {
  27656. +
  27657. + InitWirelessMode = WIRELESS_MODE_B;
  27658. + }
  27659. + else
  27660. + {
  27661. + printk(KERN_WARNING
  27662. + "InitializeAdapter8187(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
  27663. + SupportedWirelessMode);
  27664. + InitWirelessMode = WIRELESS_MODE_B;
  27665. + }
  27666. +
  27667. + // Initialize RegWirelessMode if it is not a valid one.
  27668. + if(bInvalidWirelessMode)
  27669. + {
  27670. + ieee->mode = (WIRELESS_MODE)InitWirelessMode;
  27671. + }
  27672. + }
  27673. + else
  27674. + { // One of B, G, A.
  27675. + InitWirelessMode = ieee->mode;
  27676. + }
  27677. + ActSetWirelessMode8187(dev, (u8)(InitWirelessMode));
  27678. + {//added for init gain
  27679. + write_phy_ofdm(dev, 0x97, 0x46); mdelay(1);
  27680. + write_phy_ofdm(dev, 0xa4, 0xb6); mdelay(1);
  27681. + write_phy_ofdm(dev, 0x85, 0xfc); mdelay(1);
  27682. + write_phy_cck(dev, 0xc1, 0x88); mdelay(1);
  27683. + }
  27684. +
  27685. + }
  27686. + else{
  27687. + int i;
  27688. + short channel = 1;
  27689. + u16 brsr;
  27690. + u32 data,addr;
  27691. +
  27692. + priv->chan = channel;
  27693. +
  27694. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  27695. +
  27696. + if(priv->card_type == USB)
  27697. + rtl8225_host_usb_init(dev);
  27698. + else
  27699. + rtl8225_host_pci_init(dev);
  27700. +
  27701. + write_nic_dword(dev, RF_TIMING, 0x000a8008);
  27702. +
  27703. + brsr = read_nic_word(dev, BRSR_8187);
  27704. +
  27705. + write_nic_word(dev, BRSR_8187, 0xffff);
  27706. +
  27707. +
  27708. + write_nic_dword(dev, RF_PARA, 0x100044);
  27709. +
  27710. + #if 1 //0->1
  27711. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  27712. + write_nic_byte(dev, CONFIG3, 0x44);
  27713. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  27714. + #endif
  27715. +
  27716. +
  27717. + rtl8185_rf_pins_enable(dev);
  27718. +
  27719. + // mdelay(1000);
  27720. +
  27721. + write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
  27722. +
  27723. +
  27724. + write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
  27725. +
  27726. + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
  27727. +
  27728. + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
  27729. +
  27730. +
  27731. + write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
  27732. +
  27733. +
  27734. +
  27735. + write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
  27736. + // }
  27737. +
  27738. + write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
  27739. +
  27740. + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
  27741. +
  27742. + write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
  27743. +
  27744. + write_rtl8225(dev, 0x9, 0x335); mdelay(1);
  27745. +
  27746. + write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
  27747. +
  27748. + write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
  27749. +
  27750. + write_rtl8225(dev, 0xc, 0x850); mdelay(1);
  27751. +
  27752. +
  27753. + write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
  27754. +
  27755. + write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
  27756. +
  27757. + write_rtl8225(dev, 0xf, 0x114);
  27758. +
  27759. +
  27760. + mdelay(100);
  27761. +
  27762. +
  27763. + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
  27764. + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  27765. +
  27766. + write_rtl8225(dev, 0x0, 0x1b7);
  27767. +
  27768. + for(i=0;i<95;i++){
  27769. + write_rtl8225(dev, 0x1, (u8)(i+1));
  27770. + /* version B & C & D*/
  27771. + write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
  27772. + }
  27773. + //write_rtl8225(dev, 0x3, 0x80);
  27774. + write_rtl8225(dev, 0x3, 0x2);
  27775. + write_rtl8225(dev, 0x5, 0x4);
  27776. +
  27777. + write_rtl8225(dev, 0x0, 0xb7);
  27778. +
  27779. + write_rtl8225(dev, 0x2, 0xc4d);
  27780. +
  27781. + if(priv->card_type == USB){
  27782. + // force_pci_posting(dev);
  27783. + mdelay(200);
  27784. +
  27785. + write_rtl8225(dev, 0x2, 0x44d);
  27786. +
  27787. + // force_pci_posting(dev);
  27788. + mdelay(200);
  27789. +
  27790. + }//End of if(priv->card_type == USB)
  27791. + /* FIXME!! rtl8187 we have to check if calibrarion
  27792. + * is successful and eventually cal. again (repeat
  27793. + * the two write on reg 2)
  27794. + */
  27795. + // Check for calibration status, 2005.11.17,
  27796. + data = read_rtl8225(dev, 6);
  27797. + if (!(data&0x00000080))
  27798. + {
  27799. + write_rtl8225(dev, 0x02, 0x0c4d);
  27800. + force_pci_posting(dev); mdelay(200);
  27801. + write_rtl8225(dev, 0x02, 0x044d);
  27802. + force_pci_posting(dev); mdelay(100);
  27803. + data = read_rtl8225(dev, 6);
  27804. + if (!(data&0x00000080))
  27805. + {
  27806. + DMESGW("RF Calibration Failed!!!!\n");
  27807. + }
  27808. + }
  27809. + //force_pci_posting(dev);
  27810. +
  27811. + mdelay(200); //200 for 8187
  27812. +
  27813. +
  27814. + // //if(priv->card_type != USB){
  27815. + // write_rtl8225(dev, 0x2, 0x44d);
  27816. + // write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
  27817. + // write_rtl8225(dev, 0x2, 0x47d);
  27818. + //
  27819. + // force_pci_posting(dev);
  27820. + // mdelay(100);
  27821. + //
  27822. + // write_rtl8225(dev, 0x2, 0x44d);
  27823. + // //}
  27824. +
  27825. + write_rtl8225(dev, 0x0, 0x2bf);
  27826. +
  27827. + if(priv->card_type != USB)
  27828. + rtl8185_rf_pins_enable(dev);
  27829. + //set up ZEBRA AGC table, 2005.11.17,
  27830. + for(i=0;i<128;i++){
  27831. + data = rtl8225_agc[i];
  27832. +
  27833. + addr = i + 0x80; //enable writing AGC table
  27834. + write_phy_ofdm(dev, 0xb, data);
  27835. +
  27836. + mdelay(1);
  27837. + write_phy_ofdm(dev, 0xa, addr);
  27838. +
  27839. + mdelay(1);
  27840. + }
  27841. +
  27842. + force_pci_posting(dev);
  27843. + mdelay(1);
  27844. +
  27845. + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
  27846. + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
  27847. + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
  27848. + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
  27849. + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
  27850. + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
  27851. + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
  27852. + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
  27853. + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
  27854. + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
  27855. +
  27856. + write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
  27857. +
  27858. + //write_phy_ofdm(dev, 0x18, 0xef);
  27859. + // }
  27860. + //}
  27861. + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
  27862. +
  27863. + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
  27864. +
  27865. +
  27866. + //if(priv->card_type != USB)
  27867. + write_phy_ofdm(dev, 0xd, 0x43);
  27868. +
  27869. + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
  27870. +
  27871. + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
  27872. + /*ver D & 8187*/
  27873. + // }
  27874. +
  27875. + // if(priv->card_8185 == 1 && priv->card_8185_Bversion)
  27876. + // write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
  27877. + // else
  27878. + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
  27879. + /*ver C & D & 8187*/
  27880. +
  27881. + write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
  27882. + /*agc resp time 700*/
  27883. +
  27884. +
  27885. + // if(priv->card_8185 == 2){
  27886. + /* Ver D & 8187*/
  27887. + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
  27888. +
  27889. + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
  27890. +
  27891. + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
  27892. + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
  27893. + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
  27894. + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
  27895. +
  27896. + // if (priv->card_type == USB)
  27897. + // write_phy_ofdm(dev, 0x18, 0xef);
  27898. +
  27899. + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
  27900. +
  27901. +
  27902. + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
  27903. + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
  27904. + write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1);
  27905. +
  27906. + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
  27907. +
  27908. + write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
  27909. +
  27910. + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
  27911. +
  27912. + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
  27913. +
  27914. + // }
  27915. +
  27916. + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
  27917. +
  27918. + write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
  27919. +
  27920. + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
  27921. +
  27922. + // if(priv->card_type != USB)
  27923. + write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
  27924. +
  27925. + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
  27926. + write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
  27927. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
  27928. +
  27929. + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
  27930. +
  27931. +
  27932. + // <> Set init. gain to m74dBm.
  27933. +
  27934. + rtl8225z2_set_gain(dev,4);
  27935. + //rtl8225z2_set_gain(dev,2);
  27936. +
  27937. + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
  27938. + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
  27939. + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
  27940. + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
  27941. + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
  27942. + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
  27943. + /* Ver C & D & 8187*/
  27944. + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
  27945. +
  27946. + write_phy_cck(dev, 0x9, 0x11);mdelay(1);
  27947. + write_phy_cck(dev, 0xa, 0x17);mdelay(1);
  27948. + write_phy_cck(dev, 0xb, 0x11);mdelay(1);
  27949. +
  27950. + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
  27951. + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
  27952. + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
  27953. + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
  27954. +
  27955. + write_phy_cck(dev, 0x19, 0x0); mdelay(1);
  27956. + write_phy_cck(dev, 0x1a, 0xa0); mdelay(1);
  27957. + write_phy_cck(dev, 0x1b, 0x8); mdelay(1);
  27958. + write_phy_cck(dev, 0x1d, 0x0); mdelay(1);
  27959. +
  27960. + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */ mdelay(1);
  27961. +
  27962. + write_phy_cck(dev, 0x41, 0x9d);mdelay(1);
  27963. +
  27964. +
  27965. + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
  27966. + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
  27967. +
  27968. +
  27969. + write_phy_cck(dev, 0x44, 0x36); mdelay(1);
  27970. + write_phy_cck(dev, 0x45, 0x35); mdelay(1);
  27971. + write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
  27972. + write_phy_cck(dev, 0x47, 0x25); mdelay(1);
  27973. + write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
  27974. + write_phy_cck(dev, 0x49, 0x12); mdelay(1);
  27975. + write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
  27976. + write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
  27977. + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
  27978. +
  27979. +
  27980. + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
  27981. +
  27982. +
  27983. +
  27984. + // <>
  27985. + // // TESTR 0xb 8187
  27986. + // write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
  27987. + //
  27988. + // //if(priv->card_type != USB){
  27989. + // write_phy_ofdm(dev, 0x2, 0x62);
  27990. + // write_phy_ofdm(dev, 0x6, 0x0);
  27991. + // write_phy_ofdm(dev, 0x8, 0x0);
  27992. + // //}
  27993. +
  27994. + rtl8225z2_SetTXPowerLevel(dev, channel);
  27995. +
  27996. + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
  27997. + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
  27998. +
  27999. + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
  28000. +
  28001. + /* switch to high-speed 3-wire
  28002. + * last digit. 2 for both cck and ofdm
  28003. + */
  28004. + if(priv->card_type == USB)
  28005. + write_nic_dword(dev, 0x94, 0x3dc00002);
  28006. + else{
  28007. + write_nic_dword(dev, 0x94, 0x15c00002);
  28008. + rtl8185_rf_pins_enable(dev);
  28009. + }
  28010. +
  28011. + // if(priv->card_type != USB)
  28012. + // rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
  28013. + // rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
  28014. + //
  28015. + // /* make sure is waken up! */
  28016. + // write_rtl8225(dev,0x4, 0x9ff);
  28017. + // rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  28018. + // rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  28019. +
  28020. + rtl8225_rf_set_chan(dev, priv->chan);
  28021. +
  28022. + //write_nic_word(dev,BRSR,brsr);
  28023. +
  28024. + //rtl8225z2_rf_set_mode(dev);
  28025. + }
  28026. +}
  28027. +
  28028. +void rtl8225z2_rf_set_mode(struct net_device *dev)
  28029. +{
  28030. + struct r8180_priv *priv = ieee80211_priv(dev);
  28031. +
  28032. + if(priv->ieee80211->mode == IEEE_A)
  28033. + {
  28034. + write_rtl8225(dev, 0x5, 0x1865);
  28035. + write_nic_dword(dev, RF_PARA, 0x10084);
  28036. + write_nic_dword(dev, RF_TIMING, 0xa8008);
  28037. + write_phy_ofdm(dev, 0x0, 0x0);
  28038. + write_phy_ofdm(dev, 0xa, 0x6);
  28039. + write_phy_ofdm(dev, 0xb, 0x99);
  28040. + write_phy_ofdm(dev, 0xf, 0x20);
  28041. + write_phy_ofdm(dev, 0x11, 0x7);
  28042. +
  28043. + rtl8225z2_set_gain(dev,4);
  28044. +
  28045. + write_phy_ofdm(dev,0x15, 0x40);
  28046. + write_phy_ofdm(dev,0x17, 0x40);
  28047. +
  28048. + write_nic_dword(dev, 0x94,0x10000000);
  28049. + }else{
  28050. +
  28051. + write_rtl8225(dev, 0x5, 0x1864);
  28052. + write_nic_dword(dev, RF_PARA, 0x10044);
  28053. + write_nic_dword(dev, RF_TIMING, 0xa8008);
  28054. + write_phy_ofdm(dev, 0x0, 0x1);
  28055. + write_phy_ofdm(dev, 0xa, 0x6);
  28056. + write_phy_ofdm(dev, 0xb, 0x99);
  28057. + write_phy_ofdm(dev, 0xf, 0x20);
  28058. + write_phy_ofdm(dev, 0x11, 0x7);
  28059. +
  28060. + rtl8225z2_set_gain(dev,4);
  28061. +
  28062. + write_phy_ofdm(dev,0x15, 0x40);
  28063. + write_phy_ofdm(dev,0x17, 0x40);
  28064. +
  28065. + write_nic_dword(dev, 0x94,0x04000002);
  28066. + }
  28067. +}
  28068. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.c linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.c
  28069. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.c 1970-01-01 01:00:00.000000000 +0100
  28070. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.c 2010-05-27 18:12:39.532222207 +0200
  28071. @@ -0,0 +1,2067 @@
  28072. +/*
  28073. + This file contains wireless extension handlers.
  28074. +
  28075. + This is part of rtl8180 OpenSource driver.
  28076. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  28077. + Released under the terms of GPL (General Public Licence)
  28078. +
  28079. + Parts of this driver are based on the GPL part
  28080. + of the official realtek driver.
  28081. +
  28082. + Parts of this driver are based on the rtl8180 driver skeleton
  28083. + from Patric Schenke & Andres Salomon.
  28084. +
  28085. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
  28086. +
  28087. + We want to tanks the Authors of those projects and the Ndiswrapper
  28088. + project Authors.
  28089. +*/
  28090. +
  28091. +
  28092. +
  28093. +#include "r8187.h"
  28094. +#include "r8180_hw.h"
  28095. +//added 1117
  28096. +#include "ieee80211/ieee80211.h"
  28097. +#ifdef ENABLE_DOT11D
  28098. +#include "dot11d.h"
  28099. +#endif
  28100. +
  28101. +
  28102. +//#define RATE_COUNT 4
  28103. +u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
  28104. + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
  28105. +#define RATE_COUNT sizeof(rtl8180_rates)/(sizeof(rtl8180_rates[0]))
  28106. +
  28107. +#ifdef _RTL8187_EXT_PATCH_
  28108. +#define IW_MODE_MESH 11
  28109. +static int r8180_wx_join_mesh(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  28110. +int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  28111. +static int r8180_wx_mesh_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  28112. +static int r8180_wx_get_mesh_list(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  28113. +#endif
  28114. +
  28115. +static int r8180_wx_get_freq(struct net_device *dev,
  28116. + struct iw_request_info *a,
  28117. + union iwreq_data *wrqu, char *b)
  28118. +{
  28119. + struct r8180_priv *priv = ieee80211_priv(dev);
  28120. +
  28121. + return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
  28122. +}
  28123. +
  28124. +
  28125. +#if 0
  28126. +
  28127. +static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
  28128. + union iwreq_data *wrqu, char *b)
  28129. +{
  28130. + int *parms = (int *)b;
  28131. + int bi = parms[0];
  28132. +
  28133. + struct r8180_priv *priv = ieee80211_priv(dev);
  28134. + if(priv->ieee80211->bHwRadioOff)
  28135. + return 0;
  28136. + down(&priv->wx_sem);
  28137. + DMESG("setting beacon interval to %x",bi);
  28138. +
  28139. + priv->ieee80211->beacon_interval=bi;
  28140. + rtl8180_commit(dev);
  28141. + up(&priv->wx_sem);
  28142. +
  28143. + return 0;
  28144. +}
  28145. +
  28146. +
  28147. +static int r8180_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
  28148. + union iwreq_data *wrqu, char *extra)
  28149. +{
  28150. + struct r8180_priv *priv=ieee80211_priv(dev);
  28151. + int *parms = (int *)extra;
  28152. + if(priv->ieee80211->bHwRadioOff)
  28153. + return 0;
  28154. +
  28155. + priv->ieee80211->force_associate = (parms[0] > 0);
  28156. +
  28157. +
  28158. + return 0;
  28159. +}
  28160. +
  28161. +#endif
  28162. +static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
  28163. + union iwreq_data *wrqu, char *b)
  28164. +{
  28165. + struct r8180_priv *priv=ieee80211_priv(dev);
  28166. +
  28167. + return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
  28168. +}
  28169. +
  28170. +
  28171. +
  28172. +static int r8180_wx_get_rate(struct net_device *dev,
  28173. + struct iw_request_info *info,
  28174. + union iwreq_data *wrqu, char *extra)
  28175. +{
  28176. + struct r8180_priv *priv = ieee80211_priv(dev);
  28177. + return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
  28178. +}
  28179. +
  28180. +
  28181. +
  28182. +static int r8180_wx_set_rate(struct net_device *dev,
  28183. + struct iw_request_info *info,
  28184. + union iwreq_data *wrqu, char *extra)
  28185. +{
  28186. + int ret;
  28187. + struct r8180_priv *priv = ieee80211_priv(dev);
  28188. + if(priv->ieee80211->bHwRadioOff)
  28189. + return 0;
  28190. +
  28191. + down(&priv->wx_sem);
  28192. +
  28193. + ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
  28194. +
  28195. + up(&priv->wx_sem);
  28196. +
  28197. + return ret;
  28198. +}
  28199. +#ifdef JOHN_IOCTL
  28200. +u16 read_rtl8225(struct net_device *dev, u8 addr);
  28201. +void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
  28202. +u32 john_read_rtl8225(struct net_device *dev, u8 adr);
  28203. +void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
  28204. +
  28205. +static int r8180_wx_read_regs(struct net_device *dev,
  28206. + struct iw_request_info *info,
  28207. + union iwreq_data *wrqu, char *extra)
  28208. +{
  28209. + struct r8180_priv *priv = ieee80211_priv(dev);
  28210. + u8 addr = 0;
  28211. + u16 data1;
  28212. +
  28213. + down(&priv->wx_sem);
  28214. +
  28215. +
  28216. + get_user(addr,(u8*)wrqu->data.pointer);
  28217. + data1 = read_rtl8225(dev, addr);
  28218. + wrqu->data.length = data1;
  28219. +
  28220. + up(&priv->wx_sem);
  28221. + return 0;
  28222. +
  28223. +}
  28224. +
  28225. +static int r8180_wx_write_regs(struct net_device *dev,
  28226. + struct iw_request_info *info,
  28227. + union iwreq_data *wrqu, char *extra)
  28228. +{
  28229. + struct r8180_priv *priv = ieee80211_priv(dev);
  28230. + u8 addr = 0;
  28231. +
  28232. + down(&priv->wx_sem);
  28233. +
  28234. + get_user(addr, (u8*)wrqu->data.pointer);
  28235. + write_rtl8225(dev, addr, wrqu->data.length);
  28236. +
  28237. + up(&priv->wx_sem);
  28238. + return 0;
  28239. +
  28240. +}
  28241. +
  28242. +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
  28243. +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
  28244. +
  28245. +static int r8180_wx_read_bb(struct net_device *dev,
  28246. + struct iw_request_info *info,
  28247. + union iwreq_data *wrqu, char *extra)
  28248. +{
  28249. + struct r8180_priv *priv = ieee80211_priv(dev);
  28250. + u8 databb;
  28251. +#if 0
  28252. + int i;
  28253. + for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
  28254. +#endif
  28255. +
  28256. + down(&priv->wx_sem);
  28257. +
  28258. + databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
  28259. + wrqu->data.length = databb;
  28260. +
  28261. + up(&priv->wx_sem);
  28262. + return 0;
  28263. +}
  28264. +
  28265. +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
  28266. +static int r8180_wx_write_bb(struct net_device *dev,
  28267. + struct iw_request_info *info,
  28268. + union iwreq_data *wrqu, char *extra)
  28269. +{
  28270. + struct r8180_priv *priv = ieee80211_priv(dev);
  28271. + u8 databb = 0;
  28272. +
  28273. + down(&priv->wx_sem);
  28274. +
  28275. + get_user(databb, (u8*)wrqu->data.pointer);
  28276. + rtl8187_write_phy(dev, wrqu->data.length, databb);
  28277. +
  28278. + up(&priv->wx_sem);
  28279. + return 0;
  28280. +
  28281. +}
  28282. +
  28283. +
  28284. +static int r8180_wx_write_nicb(struct net_device *dev,
  28285. + struct iw_request_info *info,
  28286. + union iwreq_data *wrqu, char *extra)
  28287. +{
  28288. + struct r8180_priv *priv = ieee80211_priv(dev);
  28289. + u32 addr = 0;
  28290. +
  28291. + down(&priv->wx_sem);
  28292. +
  28293. + get_user(addr, (u32*)wrqu->data.pointer);
  28294. + write_nic_byte(dev, addr, wrqu->data.length);
  28295. +
  28296. + up(&priv->wx_sem);
  28297. + return 0;
  28298. +
  28299. +}
  28300. +static int r8180_wx_read_nicb(struct net_device *dev,
  28301. + struct iw_request_info *info,
  28302. + union iwreq_data *wrqu, char *extra)
  28303. +{
  28304. + struct r8180_priv *priv = ieee80211_priv(dev);
  28305. + u32 addr = 0;
  28306. + u16 data1;
  28307. +
  28308. + down(&priv->wx_sem);
  28309. +
  28310. + get_user(addr,(u32*)wrqu->data.pointer);
  28311. + data1 = read_nic_byte(dev, addr);
  28312. + wrqu->data.length = data1;
  28313. +
  28314. + up(&priv->wx_sem);
  28315. + return 0;
  28316. +}
  28317. +
  28318. +static inline int is_same_network(struct ieee80211_network *src,
  28319. + struct ieee80211_network *dst,
  28320. + struct ieee80211_device *ieee)
  28321. +{
  28322. + /* A network is only a duplicate if the channel, BSSID, ESSID
  28323. + * and the capability field (in particular IBSS and BSS) all match.
  28324. + * We treat all <hidden> with the same BSSID and channel
  28325. + * as one network */
  28326. + return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
  28327. + //((src->ssid_len == dst->ssid_len) &&
  28328. + (src->channel == dst->channel) &&
  28329. + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
  28330. + (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
  28331. + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
  28332. + ((src->capability & WLAN_CAPABILITY_IBSS) ==
  28333. + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
  28334. + ((src->capability & WLAN_CAPABILITY_BSS) ==
  28335. + (dst->capability & WLAN_CAPABILITY_BSS)));
  28336. +}
  28337. +
  28338. +static int r8180_wx_get_ap_status(struct net_device *dev,
  28339. + struct iw_request_info *info,
  28340. + union iwreq_data *wrqu, char *extra)
  28341. +{
  28342. + struct r8180_priv *priv = ieee80211_priv(dev);
  28343. + struct ieee80211_device *ieee = priv->ieee80211;
  28344. + struct ieee80211_network *target;
  28345. + int name_len;
  28346. +
  28347. + down(&priv->wx_sem);
  28348. +
  28349. + //count the length of input ssid
  28350. + for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
  28351. +
  28352. + //search for the correspoding info which is received
  28353. + list_for_each_entry(target, &ieee->network_list, list) {
  28354. + if ( (target->ssid_len == name_len) &&
  28355. + (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
  28356. + if( ((jiffies-target->last_scanned)/HZ > 1) && (ieee->state == IEEE80211_LINKED) && (is_same_network(&ieee->current_network,target, ieee)) )
  28357. + wrqu->data.length = 999;
  28358. + else
  28359. + wrqu->data.length = target->SignalStrength;
  28360. + if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
  28361. + //set flags=1 to indicate this ap is WPA
  28362. + wrqu->data.flags = 1;
  28363. + else wrqu->data.flags = 0;
  28364. +
  28365. +
  28366. + break;
  28367. + }
  28368. + }
  28369. +
  28370. + if (&target->list == &ieee->network_list){
  28371. + wrqu->data.flags = 3;
  28372. + }
  28373. + up(&priv->wx_sem);
  28374. + return 0;
  28375. +}
  28376. +
  28377. +
  28378. +
  28379. +#endif
  28380. +
  28381. +static int r8180_wx_set_rawtx(struct net_device *dev,
  28382. + struct iw_request_info *info,
  28383. + union iwreq_data *wrqu, char *extra)
  28384. +{
  28385. + struct r8180_priv *priv = ieee80211_priv(dev);
  28386. + int ret;
  28387. +
  28388. + if(priv->ieee80211->bHwRadioOff)
  28389. + return 0;
  28390. +
  28391. + down(&priv->wx_sem);
  28392. +
  28393. + ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
  28394. +
  28395. + up(&priv->wx_sem);
  28396. +
  28397. + return ret;
  28398. +
  28399. +}
  28400. +
  28401. +static int r8180_wx_set_crcmon(struct net_device *dev,
  28402. + struct iw_request_info *info,
  28403. + union iwreq_data *wrqu, char *extra)
  28404. +{
  28405. + struct r8180_priv *priv = ieee80211_priv(dev);
  28406. + int *parms = (int *)extra;
  28407. + int enable = (parms[0] > 0);
  28408. + short prev = priv->crcmon;
  28409. +
  28410. + if(priv->ieee80211->bHwRadioOff)
  28411. + return 0;
  28412. +
  28413. + down(&priv->wx_sem);
  28414. +
  28415. + if(enable)
  28416. + priv->crcmon=1;
  28417. + else
  28418. + priv->crcmon=0;
  28419. +
  28420. + DMESG("bad CRC in monitor mode are %s",
  28421. + priv->crcmon ? "accepted" : "rejected");
  28422. +
  28423. + if(prev != priv->crcmon && priv->up){
  28424. + rtl8180_down(dev);
  28425. + rtl8180_up(dev);
  28426. + }
  28427. +
  28428. + up(&priv->wx_sem);
  28429. +
  28430. + return 0;
  28431. +}
  28432. +
  28433. +static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
  28434. + union iwreq_data *wrqu, char *b)
  28435. +{
  28436. + struct r8180_priv *priv = ieee80211_priv(dev);
  28437. + int ret;
  28438. + if(priv->ieee80211->bHwRadioOff)
  28439. + return 0;
  28440. +
  28441. +#ifdef _RTL8187_EXT_PATCH_
  28442. + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)) return 0;
  28443. +#endif
  28444. + down(&priv->wx_sem);
  28445. +
  28446. +#ifdef CONFIG_IPS
  28447. + if(priv->bInactivePs){
  28448. + if(wrqu->mode != IW_MODE_INFRA){
  28449. + down(&priv->ieee80211->ips_sem);
  28450. + IPSLeave(dev);
  28451. + up(&priv->ieee80211->ips_sem);
  28452. + }
  28453. + }
  28454. +#endif
  28455. + ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
  28456. +
  28457. + rtl8187_set_rxconf(dev);
  28458. +
  28459. + up(&priv->wx_sem);
  28460. + return ret;
  28461. +}
  28462. +
  28463. +
  28464. +//YJ,add,080819,for hidden ap
  28465. +struct iw_range_with_scan_capa
  28466. +{
  28467. + /* Informative stuff (to choose between different interface) */
  28468. + __u32 throughput; /* To give an idea... */
  28469. + /* In theory this value should be the maximum benchmarked
  28470. + * TCP/IP throughput, because with most of these devices the
  28471. + * bit rate is meaningless (overhead an co) to estimate how
  28472. + * fast the connection will go and pick the fastest one.
  28473. + * I suggest people to play with Netperf or any benchmark...
  28474. + */
  28475. +
  28476. + /* NWID (or domain id) */
  28477. + __u32 min_nwid; /* Minimal NWID we are able to set */
  28478. + __u32 max_nwid; /* Maximal NWID we are able to set */
  28479. +
  28480. + /* Old Frequency (backward compat - moved lower ) */
  28481. + __u16 old_num_channels;
  28482. + __u8 old_num_frequency;
  28483. +
  28484. + /* Scan capabilities */
  28485. + __u8 scan_capa;
  28486. +};
  28487. +//YJ,add,080819,for hidden ap
  28488. +
  28489. +static int rtl8180_wx_get_range(struct net_device *dev,
  28490. + struct iw_request_info *info,
  28491. + union iwreq_data *wrqu, char *extra)
  28492. +{
  28493. + struct iw_range *range = (struct iw_range *)extra;
  28494. + struct r8180_priv *priv = ieee80211_priv(dev);
  28495. + u16 val;
  28496. + int i;
  28497. + struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
  28498. +
  28499. + wrqu->data.length = sizeof(*range);
  28500. + memset(range, 0, sizeof(*range));
  28501. +
  28502. + /* Let's try to keep this struct in the same order as in
  28503. + * linux/include/wireless.h
  28504. + */
  28505. +
  28506. + /* TODO: See what values we can set, and remove the ones we can't
  28507. + * set, or fill them with some default data.
  28508. + */
  28509. +
  28510. + /* ~5 Mb/s real (802.11b) */
  28511. + range->throughput = 5 * 1000 * 1000;
  28512. +
  28513. + // TODO: Not used in 802.11b?
  28514. +// range->min_nwid; /* Minimal NWID we are able to set */
  28515. + // TODO: Not used in 802.11b?
  28516. +// range->max_nwid; /* Maximal NWID we are able to set */
  28517. +
  28518. + /* Old Frequency (backward compat - moved lower ) */
  28519. +// range->old_num_channels;
  28520. +// range->old_num_frequency;
  28521. +// range->old_freq[6]; /* Filler to keep "version" at the same offset */
  28522. + if(priv->rf_set_sens != NULL)
  28523. + range->sensitivity = priv->max_sens; /* signal level threshold range */
  28524. +
  28525. + range->max_qual.qual = 100;
  28526. + /* TODO: Find real max RSSI and stick here */
  28527. + range->max_qual.level = 0;
  28528. + range->max_qual.noise = -98;
  28529. + range->max_qual.updated = 7; /* Updated all three */
  28530. +
  28531. + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
  28532. + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
  28533. + range->avg_qual.level = 20 + -98;
  28534. + range->avg_qual.noise = 0;
  28535. + range->avg_qual.updated = 7; /* Updated all three */
  28536. +
  28537. + range->num_bitrates = RATE_COUNT;
  28538. +
  28539. + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
  28540. + range->bitrate[i] = rtl8180_rates[i];
  28541. + }
  28542. +
  28543. + range->min_frag = MIN_FRAG_THRESHOLD;
  28544. + range->max_frag = MAX_FRAG_THRESHOLD;
  28545. +
  28546. + range->pm_capa = 0;
  28547. +
  28548. + range->we_version_compiled = WIRELESS_EXT;
  28549. + range->we_version_source = 16;
  28550. +
  28551. +// range->retry_capa; /* What retry options are supported */
  28552. +// range->retry_flags; /* How to decode max/min retry limit */
  28553. +// range->r_time_flags; /* How to decode max/min retry life */
  28554. +// range->min_retry; /* Minimal number of retries */
  28555. +// range->max_retry; /* Maximal number of retries */
  28556. +// range->min_r_time; /* Minimal retry lifetime */
  28557. +// range->max_r_time; /* Maximal retry lifetime */
  28558. +
  28559. + range->num_channels = 14;
  28560. +
  28561. + for (i = 0, val = 0; i < 14; i++) {
  28562. +
  28563. + // Include only legal frequencies for some countries
  28564. +#ifdef ENABLE_DOT11D
  28565. + if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
  28566. +#else
  28567. + if ((priv->ieee80211->channel_map)[i+1]) {
  28568. +#endif
  28569. + range->freq[val].i = i + 1;
  28570. + range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
  28571. + range->freq[val].e = 1;
  28572. + val++;
  28573. + } else {
  28574. + // FIXME: do we need to set anything for channels
  28575. + // we don't use ?
  28576. + }
  28577. +
  28578. + if (val == IW_MAX_FREQUENCIES)
  28579. + break;
  28580. + }
  28581. +
  28582. + range->num_frequency = val;
  28583. + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
  28584. + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
  28585. +
  28586. + tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
  28587. +
  28588. + return 0;
  28589. +}
  28590. +
  28591. +
  28592. +static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
  28593. + union iwreq_data *wrqu, char *b)
  28594. +{
  28595. + struct r8180_priv *priv = ieee80211_priv(dev);
  28596. + struct ieee80211_device* ieee = priv->ieee80211;
  28597. + int ret;
  28598. +
  28599. + if(priv->ieee80211->bHwRadioOff)
  28600. + return 0;
  28601. + //printk("==============>%s()\n",__FUNCTION__);
  28602. + if(!priv->up)
  28603. + return -1;
  28604. +
  28605. + if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
  28606. + {
  28607. + struct iw_scan_req* req = (struct iw_scan_req*)b;
  28608. + if (req->essid_len)
  28609. + {
  28610. + ieee->current_network.ssid_len = req->essid_len;
  28611. + memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
  28612. + }
  28613. + }
  28614. +
  28615. + //set Tr switch to hardware control to scan more bss
  28616. + if(priv->TrSwitchState == TR_SW_TX) {
  28617. + //YJ,add,080611
  28618. + write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect));
  28619. + write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput));
  28620. + //YJ,add,080611,end
  28621. + priv->TrSwitchState = TR_HW_CONTROLLED;
  28622. + }
  28623. +#ifdef _RTL8187_EXT_PATCH_
  28624. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  28625. + r8180_wx_mesh_scan(dev,a,wrqu,b);
  28626. + ret = 0;
  28627. + }
  28628. + else
  28629. +#endif
  28630. + {
  28631. + down(&priv->wx_sem);
  28632. + if(priv->ieee80211->state != IEEE80211_LINKED){
  28633. + //printk("===>start no link scan\n");
  28634. + //ieee80211_start_scan(priv->ieee80211);
  28635. + //lzm mod 090115 because wq can't scan complete once
  28636. + //because after start protocal wq scan is in doing
  28637. + //so we should stop it first.
  28638. + ieee80211_stop_scan(priv->ieee80211);
  28639. + ieee80211_start_scan_syncro(priv->ieee80211);
  28640. + ret = 0;
  28641. + } else {
  28642. + ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
  28643. + }
  28644. + up(&priv->wx_sem);
  28645. + }
  28646. + return ret;
  28647. +}
  28648. +
  28649. +
  28650. +static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
  28651. + union iwreq_data *wrqu, char *b)
  28652. +{
  28653. +
  28654. + int ret;
  28655. + struct r8180_priv *priv = ieee80211_priv(dev);
  28656. +
  28657. + if(!priv->up) return -1;
  28658. +#ifdef _RTL8187_EXT_PATCH_
  28659. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  28660. + ret = r8180_wx_get_mesh_list(dev, a, wrqu, b);
  28661. + }
  28662. + else
  28663. +#endif
  28664. + {
  28665. + down(&priv->wx_sem);
  28666. +
  28667. + ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
  28668. +
  28669. + up(&priv->wx_sem);
  28670. + }
  28671. + return ret;
  28672. +}
  28673. +
  28674. +
  28675. +static int r8180_wx_set_essid(struct net_device *dev,
  28676. + struct iw_request_info *a,
  28677. + union iwreq_data *wrqu, char *b)
  28678. +{
  28679. + struct r8180_priv *priv = ieee80211_priv(dev);
  28680. + int ret;
  28681. +#ifdef _RTL8187_EXT_PATCH_
  28682. + struct ieee80211_device *ieee = priv->ieee80211;
  28683. + char ch = 0;
  28684. + char tmpmeshid[32];
  28685. + char *p;
  28686. + int tmpmeshid_len=0;
  28687. + int i;
  28688. + short proto_started;
  28689. +#endif
  28690. + if(priv->ieee80211->bHwRadioOff)
  28691. + return 0;
  28692. + //printk("==========>%s()\n",__FUNCTION__);
  28693. + down(&priv->wx_sem);
  28694. +
  28695. +#ifdef _RTL8187_EXT_PATCH_
  28696. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  28697. + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
  28698. + ret= -E2BIG;
  28699. + goto out;
  28700. + }
  28701. + if (wrqu->essid.flags && (wrqu->essid.length > 1)) {
  28702. + memset(tmpmeshid,0,32);
  28703. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  28704. + tmpmeshid_len=wrqu->essid.length;
  28705. +#else
  28706. + tmpmeshid_len=wrqu->essid.length + 1;
  28707. +#endif
  28708. + p=b+tmpmeshid_len-2;
  28709. + for(i=tmpmeshid_len-1;i>0;i--)
  28710. + {
  28711. + if((*p)=='@')
  28712. + break;
  28713. + p--;
  28714. + }
  28715. + if((i == 0) || (i == 1)){
  28716. + printk("error:wrong meshid\n");
  28717. + ret = -1;
  28718. + goto out;
  28719. + }
  28720. +
  28721. + memcpy(tmpmeshid,b,(i-1));
  28722. + p++;
  28723. + if((tmpmeshid_len-1-i)==1)
  28724. + {
  28725. + if(*p > '9'|| *p <= '0'){
  28726. + goto out;
  28727. + } else {
  28728. + ch = *p - '0';
  28729. + }
  28730. + }
  28731. + else if((tmpmeshid_len-1-i)==2)
  28732. + {
  28733. + if((*p == '1') && (*(p+1) >= '0') && (*(p+1) <= '9'))
  28734. + ch = (*p - '0') * 10 + (*(p+1) - '0');
  28735. + else
  28736. + goto out;
  28737. + }
  28738. + else {
  28739. + ret = 0;
  28740. + goto out;
  28741. + }
  28742. + if(ch > 14)
  28743. + {
  28744. + ret = 0;
  28745. + printk("channel is invalid: %d\n",ch);
  28746. + goto out;
  28747. + }
  28748. + ieee->sync_scan_hurryup = 1;
  28749. +
  28750. + proto_started = ieee->proto_started;
  28751. + if(proto_started)
  28752. + ieee80211_stop_protocol(ieee);
  28753. +
  28754. + printk("==============>tmpmeshid is %s\n",tmpmeshid);
  28755. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, tmpmeshid);
  28756. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  28757. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  28758. + if (proto_started)
  28759. + ieee80211_start_protocol(ieee);
  28760. + }
  28761. + else{
  28762. + printk("BUG:meshid is null\n");
  28763. + ret=0;
  28764. + goto out;
  28765. + }
  28766. +
  28767. + ret = 0;
  28768. + }
  28769. + else
  28770. +#endif
  28771. + {
  28772. + ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
  28773. + }
  28774. +
  28775. +#ifdef _RTL8187_EXT_PATCH_
  28776. +out:
  28777. +#endif
  28778. + up(&priv->wx_sem);
  28779. + return ret;
  28780. +}
  28781. +
  28782. +
  28783. +static int r8180_wx_get_essid(struct net_device *dev,
  28784. + struct iw_request_info *a,
  28785. + union iwreq_data *wrqu, char *b)
  28786. +{
  28787. + int ret;
  28788. + struct r8180_priv *priv = ieee80211_priv(dev);
  28789. +
  28790. + down(&priv->wx_sem);
  28791. +
  28792. + ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
  28793. +
  28794. + up(&priv->wx_sem);
  28795. +
  28796. + return ret;
  28797. +}
  28798. +
  28799. +
  28800. +static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
  28801. + union iwreq_data *wrqu, char *b)
  28802. +{
  28803. + int ret;
  28804. + struct r8180_priv *priv = ieee80211_priv(dev);
  28805. +
  28806. + if(priv->ieee80211->bHwRadioOff)
  28807. + return 0;
  28808. +
  28809. + down(&priv->wx_sem);
  28810. +
  28811. + ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
  28812. +
  28813. + up(&priv->wx_sem);
  28814. + return ret;
  28815. +}
  28816. +
  28817. +static int r8180_wx_get_name(struct net_device *dev,
  28818. + struct iw_request_info *info,
  28819. + union iwreq_data *wrqu, char *extra)
  28820. +{
  28821. + struct r8180_priv *priv = ieee80211_priv(dev);
  28822. + return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
  28823. +}
  28824. +
  28825. +
  28826. +static int r8180_wx_set_frag(struct net_device *dev,
  28827. + struct iw_request_info *info,
  28828. + union iwreq_data *wrqu, char *extra)
  28829. +{
  28830. + struct r8180_priv *priv = ieee80211_priv(dev);
  28831. +
  28832. + if(priv->ieee80211->bHwRadioOff)
  28833. + return 0;
  28834. +
  28835. + if (wrqu->frag.disabled)
  28836. + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
  28837. + else {
  28838. + if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
  28839. + wrqu->frag.value > MAX_FRAG_THRESHOLD)
  28840. + return -EINVAL;
  28841. +
  28842. + priv->ieee80211->fts = wrqu->frag.value & ~0x1;
  28843. + }
  28844. +
  28845. + return 0;
  28846. +}
  28847. +
  28848. +
  28849. +static int r8180_wx_get_frag(struct net_device *dev,
  28850. + struct iw_request_info *info,
  28851. + union iwreq_data *wrqu, char *extra)
  28852. +{
  28853. + struct r8180_priv *priv = ieee80211_priv(dev);
  28854. +
  28855. + wrqu->frag.value = priv->ieee80211->fts;
  28856. + wrqu->frag.fixed = 0; /* no auto select */
  28857. + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
  28858. +
  28859. + return 0;
  28860. +}
  28861. +
  28862. +
  28863. +static int r8180_wx_set_wap(struct net_device *dev,
  28864. + struct iw_request_info *info,
  28865. + union iwreq_data *awrq,
  28866. + char *extra)
  28867. +{
  28868. + int ret;
  28869. + struct r8180_priv *priv = ieee80211_priv(dev);
  28870. + if(priv->ieee80211->bHwRadioOff)
  28871. + return 0;
  28872. +
  28873. + //printk("in function %s\n",__FUNCTION__);
  28874. +#ifdef _RTL8187_EXT_PATCH_
  28875. + if (priv->mshobj && (priv->ieee80211->iw_ext_mode==11)){
  28876. + return 0;
  28877. + }
  28878. +#endif
  28879. + down(&priv->wx_sem);
  28880. +
  28881. + ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
  28882. +
  28883. + up(&priv->wx_sem);
  28884. + return ret;
  28885. +
  28886. +}
  28887. +
  28888. +
  28889. +static int r8180_wx_get_wap(struct net_device *dev,
  28890. + struct iw_request_info *info,
  28891. + union iwreq_data *wrqu, char *extra)
  28892. +{
  28893. + struct r8180_priv *priv = ieee80211_priv(dev);
  28894. +
  28895. + return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
  28896. +}
  28897. +
  28898. +
  28899. +static int r8180_wx_get_enc(struct net_device *dev,
  28900. + struct iw_request_info *info,
  28901. + union iwreq_data *wrqu, char *key)
  28902. +{
  28903. + struct r8180_priv *priv = ieee80211_priv(dev);
  28904. +
  28905. + return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
  28906. +}
  28907. +
  28908. +static int r8180_wx_set_enc(struct net_device *dev,
  28909. + struct iw_request_info *info,
  28910. + union iwreq_data *wrqu, char *key)
  28911. +{
  28912. + struct r8180_priv *priv = ieee80211_priv(dev);
  28913. + int ret;
  28914. +#ifdef JOHN_HWSEC
  28915. +// struct ieee80211_device *ieee = priv->ieee80211;
  28916. +// u32 TargetContent;
  28917. + u32 hwkey[4]={0,0,0,0};
  28918. + u8 mask=0xff;
  28919. + u32 key_idx=0;
  28920. + u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
  28921. + u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
  28922. + {0x00,0x00,0x00,0x00,0x00,0x01},
  28923. + {0x00,0x00,0x00,0x00,0x00,0x02},
  28924. + {0x00,0x00,0x00,0x00,0x00,0x03} };
  28925. + int i;
  28926. +
  28927. +#endif
  28928. +
  28929. + if(priv->ieee80211->bHwRadioOff)
  28930. + return 0;
  28931. +
  28932. + down(&priv->wx_sem);
  28933. +
  28934. + DMESG("Setting SW wep key");
  28935. + ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
  28936. +
  28937. + up(&priv->wx_sem);
  28938. +
  28939. +#ifdef JOHN_HWSEC
  28940. +
  28941. + //sometimes, the length is zero while we do not type key value
  28942. + if(wrqu->encoding.length!=0){
  28943. +
  28944. + for(i=0 ; i<4 ; i++){
  28945. + hwkey[i] |= key[4*i+0]&mask;
  28946. + if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
  28947. + if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
  28948. + hwkey[i] |= (key[4*i+1]&mask)<<8;
  28949. + hwkey[i] |= (key[4*i+2]&mask)<<16;
  28950. + hwkey[i] |= (key[4*i+3]&mask)<<24;
  28951. + }
  28952. +
  28953. + #define CONF_WEP40 0x4
  28954. + #define CONF_WEP104 0x14
  28955. +
  28956. + switch(wrqu->encoding.flags){
  28957. + case 0:
  28958. + case 1: key_idx = 0; break;
  28959. + case 2: key_idx = 1; break;
  28960. + case 3: key_idx = 2; break;
  28961. + case 4: key_idx = 3; break;
  28962. + default: break;
  28963. + }
  28964. +
  28965. + if(wrqu->encoding.length==0x5){
  28966. + setKey( dev,
  28967. + key_idx, //EntryNo
  28968. + key_idx, //KeyIndex
  28969. + KEY_TYPE_WEP40, //KeyType
  28970. + zero_addr[key_idx],
  28971. + 0, //DefaultKey
  28972. + hwkey); //KeyContent
  28973. +
  28974. + if(key_idx == 0){
  28975. +
  28976. + write_nic_byte(dev, WPA_CONFIG, 7);
  28977. +
  28978. + setKey( dev,
  28979. + 4, //EntryNo
  28980. + key_idx, //KeyIndex
  28981. + KEY_TYPE_WEP40, //KeyType
  28982. + broadcast_addr, //addr
  28983. + 0, //DefaultKey
  28984. + hwkey); //KeyContent
  28985. + }
  28986. + }
  28987. +
  28988. + else if(wrqu->encoding.length==0xd){
  28989. + setKey( dev,
  28990. + key_idx, //EntryNo
  28991. + key_idx, //KeyIndex
  28992. + KEY_TYPE_WEP104, //KeyType
  28993. + zero_addr[key_idx],
  28994. + 0, //DefaultKey
  28995. + hwkey); //KeyContent
  28996. +
  28997. + if(key_idx == 0){
  28998. +
  28999. + write_nic_byte(dev, WPA_CONFIG, 7);
  29000. +
  29001. + setKey( dev,
  29002. + 4, //EntryNo
  29003. + key_idx, //KeyIndex
  29004. + KEY_TYPE_WEP104, //KeyType
  29005. + broadcast_addr, //addr
  29006. + 0, //DefaultKey
  29007. + hwkey); //KeyContent
  29008. + }
  29009. + }
  29010. + else printk("wrong type in WEP, not WEP40 and WEP104\n");
  29011. +
  29012. + }
  29013. +
  29014. + //consider the setting different key index situation
  29015. + //wrqu->encoding.flags = 801 means that we set key with index "1"
  29016. + if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
  29017. +
  29018. + write_nic_byte(dev, WPA_CONFIG, 7);
  29019. +
  29020. + //copy wpa config from default key(key0~key3) to broadcast key(key5)
  29021. + //
  29022. + key_idx = (wrqu->encoding.flags & 0xf)-1 ;
  29023. + write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
  29024. + write_cam(dev, (4*6)+1, 0xffffffff);
  29025. + write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
  29026. + write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
  29027. + write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
  29028. + write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
  29029. + }
  29030. +
  29031. +#endif /*JOHN_HWSEC*/
  29032. + return ret;
  29033. +}
  29034. +
  29035. +
  29036. +static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
  29037. + iwreq_data *wrqu, char *p){
  29038. +
  29039. + struct r8180_priv *priv = ieee80211_priv(dev);
  29040. + int *parms=(int*)p;
  29041. + int mode=parms[0];
  29042. +
  29043. + if(priv->ieee80211->bHwRadioOff)
  29044. + return 0;
  29045. +
  29046. + priv->ieee80211->active_scan = mode;
  29047. +
  29048. + return 1;
  29049. +}
  29050. +
  29051. +
  29052. +
  29053. +static int r8180_wx_set_retry(struct net_device *dev,
  29054. + struct iw_request_info *info,
  29055. + union iwreq_data *wrqu, char *extra)
  29056. +{
  29057. + struct r8180_priv *priv = ieee80211_priv(dev);
  29058. + int err = 0;
  29059. +
  29060. + if(priv->ieee80211->bHwRadioOff)
  29061. + return 0;
  29062. +
  29063. + down(&priv->wx_sem);
  29064. +
  29065. + if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
  29066. + wrqu->retry.disabled){
  29067. + err = -EINVAL;
  29068. + goto exit;
  29069. + }
  29070. + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
  29071. + err = -EINVAL;
  29072. + goto exit;
  29073. + }
  29074. +
  29075. + if(wrqu->retry.value > R8180_MAX_RETRY){
  29076. + err= -EINVAL;
  29077. + goto exit;
  29078. + }
  29079. + if (wrqu->retry.flags & IW_RETRY_MAX) {
  29080. + priv->retry_rts = wrqu->retry.value;
  29081. + DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
  29082. +
  29083. + }else {
  29084. + priv->retry_data = wrqu->retry.value;
  29085. + DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
  29086. + }
  29087. +
  29088. + /* FIXME !
  29089. + * We might try to write directly the TX config register
  29090. + * or to restart just the (R)TX process.
  29091. + * I'm unsure if whole reset is really needed
  29092. + */
  29093. +
  29094. + rtl8180_commit(dev);
  29095. + /*
  29096. + if(priv->up){
  29097. + rtl8180_rtx_disable(dev);
  29098. + rtl8180_rx_enable(dev);
  29099. + rtl8180_tx_enable(dev);
  29100. +
  29101. + }
  29102. + */
  29103. +exit:
  29104. + up(&priv->wx_sem);
  29105. +
  29106. + return err;
  29107. +}
  29108. +
  29109. +static int r8180_wx_get_retry(struct net_device *dev,
  29110. + struct iw_request_info *info,
  29111. + union iwreq_data *wrqu, char *extra)
  29112. +{
  29113. + struct r8180_priv *priv = ieee80211_priv(dev);
  29114. +
  29115. +
  29116. + wrqu->retry.disabled = 0; /* can't be disabled */
  29117. +
  29118. + if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
  29119. + IW_RETRY_LIFETIME)
  29120. + return -EINVAL;
  29121. +
  29122. + if (wrqu->retry.flags & IW_RETRY_MAX) {
  29123. + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
  29124. + wrqu->retry.value = priv->retry_rts;
  29125. + } else {
  29126. + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
  29127. + wrqu->retry.value = priv->retry_data;
  29128. + }
  29129. + //DMESG("returning %d",wrqu->retry.value);
  29130. +
  29131. +
  29132. + return 0;
  29133. +}
  29134. +
  29135. +static int r8180_wx_get_sens(struct net_device *dev,
  29136. + struct iw_request_info *info,
  29137. + union iwreq_data *wrqu, char *extra)
  29138. +{
  29139. + struct r8180_priv *priv = ieee80211_priv(dev);
  29140. + if(priv->rf_set_sens == NULL)
  29141. + return -1; /* we have not this support for this radio */
  29142. + wrqu->sens.value = priv->sens;
  29143. + return 0;
  29144. +}
  29145. +
  29146. +
  29147. +static int r8180_wx_set_sens(struct net_device *dev,
  29148. + struct iw_request_info *info,
  29149. + union iwreq_data *wrqu, char *extra)
  29150. +{
  29151. +
  29152. + struct r8180_priv *priv = ieee80211_priv(dev);
  29153. +
  29154. + short err = 0;
  29155. +
  29156. + if(priv->ieee80211->bHwRadioOff)
  29157. + return 0;
  29158. +
  29159. + down(&priv->wx_sem);
  29160. + //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
  29161. + if(priv->rf_set_sens == NULL) {
  29162. + err= -1; /* we have not this support for this radio */
  29163. + goto exit;
  29164. + }
  29165. + if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
  29166. + priv->sens = wrqu->sens.value;
  29167. + else
  29168. + err= -EINVAL;
  29169. +
  29170. +exit:
  29171. + up(&priv->wx_sem);
  29172. +
  29173. + return err;
  29174. +}
  29175. +
  29176. +
  29177. +static int dummy(struct net_device *dev, struct iw_request_info *a,
  29178. + union iwreq_data *wrqu,char *b)
  29179. +{
  29180. + return -1;
  29181. +}
  29182. +static int r8180_wx_set_enc_ext(struct net_device *dev,
  29183. + struct iw_request_info *info,
  29184. + union iwreq_data *wrqu, char *extra)
  29185. +{
  29186. +
  29187. + struct r8180_priv *priv = ieee80211_priv(dev);
  29188. + //printk("===>%s()\n", __FUNCTION__);
  29189. +
  29190. + int ret=0;
  29191. +
  29192. + if(priv->ieee80211->bHwRadioOff)
  29193. + return 0;
  29194. +
  29195. + down(&priv->wx_sem);
  29196. + ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
  29197. + up(&priv->wx_sem);
  29198. + return ret;
  29199. +
  29200. +}
  29201. +static int r8180_wx_set_auth(struct net_device *dev,
  29202. + struct iw_request_info *info,
  29203. + union iwreq_data* data, char *extra)
  29204. +{
  29205. + //printk("====>%s()\n", __FUNCTION__);
  29206. + struct r8180_priv *priv = ieee80211_priv(dev);
  29207. + int ret=0;
  29208. +
  29209. + if(priv->ieee80211->bHwRadioOff)
  29210. + return 0;
  29211. +
  29212. + down(&priv->wx_sem);
  29213. + ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
  29214. + up(&priv->wx_sem);
  29215. + return ret;
  29216. +}
  29217. +
  29218. +static int r8180_wx_set_mlme(struct net_device *dev,
  29219. + struct iw_request_info *info,
  29220. + union iwreq_data *wrqu, char *extra)
  29221. +{
  29222. + //printk("====>%s()\n", __FUNCTION__);
  29223. +
  29224. + int ret=0;
  29225. + struct r8180_priv *priv = ieee80211_priv(dev);
  29226. +
  29227. + if(priv->ieee80211->bHwRadioOff)
  29228. + return 0;
  29229. +
  29230. + down(&priv->wx_sem);
  29231. +#if 1
  29232. + ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
  29233. +#endif
  29234. + up(&priv->wx_sem);
  29235. + return ret;
  29236. +}
  29237. +
  29238. +static int r8180_wx_set_gen_ie(struct net_device *dev,
  29239. + struct iw_request_info *info,
  29240. + union iwreq_data* data, char *extra)
  29241. +{
  29242. + //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
  29243. + int ret=0;
  29244. + struct r8180_priv *priv = ieee80211_priv(dev);
  29245. +
  29246. + if(priv->ieee80211->bHwRadioOff)
  29247. + return 0;
  29248. +
  29249. + down(&priv->wx_sem);
  29250. +#if 1
  29251. + ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
  29252. +#endif
  29253. + up(&priv->wx_sem);
  29254. + //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
  29255. + return ret;
  29256. +
  29257. +
  29258. +}
  29259. +
  29260. +#ifdef _RTL8187_EXT_PATCH_
  29261. +/*
  29262. + Output:
  29263. + (case 1) Mesh: Enable. MESHID=[%s] (max length of %s is 32 bytes).
  29264. + (case 2) Mesh: Disable.
  29265. +*/
  29266. +static int r8180_wx_get_meshinfo(struct net_device *dev,
  29267. + struct iw_request_info *info,
  29268. + union iwreq_data *wrqu, char *extra)
  29269. +{
  29270. + struct r8180_priv *priv = ieee80211_priv(dev);
  29271. +
  29272. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_meshinfo )
  29273. + return 0;
  29274. + return priv->mshobj->ext_patch_r8180_wx_get_meshinfo(dev, info, wrqu, extra);
  29275. +}
  29276. +
  29277. +
  29278. +static int r8180_wx_enable_mesh(struct net_device *dev,
  29279. + struct iw_request_info *info,
  29280. + union iwreq_data *wrqu, char *extra)
  29281. +{
  29282. + struct r8180_priv *priv = ieee80211_priv(dev);
  29283. + struct ieee80211_device *ieee = priv->ieee80211;
  29284. +
  29285. + int ret = 0;
  29286. +
  29287. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_enable_mesh )
  29288. + return 0;
  29289. +
  29290. + down(&priv->wx_sem);
  29291. + if(priv->mshobj->ext_patch_r8180_wx_enable_mesh(dev))
  29292. + {
  29293. + union iwreq_data tmprqu;
  29294. + tmprqu.mode = ieee->iw_mode;
  29295. + ieee->iw_mode = 0;
  29296. + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
  29297. + rtl8187_set_rxconf(dev);
  29298. + }
  29299. +
  29300. + up(&priv->wx_sem);
  29301. +
  29302. + return ret;
  29303. +
  29304. +}
  29305. +
  29306. +static int r8180_wx_disable_mesh(struct net_device *dev,
  29307. + struct iw_request_info *info,
  29308. + union iwreq_data *wrqu, char *extra)
  29309. +{
  29310. + struct r8180_priv *priv = ieee80211_priv(dev);
  29311. + struct ieee80211_device *ieee = priv->ieee80211;
  29312. +
  29313. + int ret = 0;
  29314. +
  29315. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_disable_mesh )
  29316. + return 0;
  29317. +
  29318. + down(&priv->wx_sem);
  29319. + if(priv->mshobj->ext_patch_r8180_wx_disable_mesh(dev))
  29320. + {
  29321. + union iwreq_data tmprqu;
  29322. + tmprqu.mode = ieee->iw_mode;
  29323. + ieee->iw_mode = 999;
  29324. + ret = ieee80211_wx_set_mode(ieee, info, &tmprqu, extra);
  29325. + rtl8187_set_rxconf(dev);
  29326. + }
  29327. +
  29328. + up(&priv->wx_sem);
  29329. +
  29330. + return ret;
  29331. +}
  29332. +
  29333. +
  29334. +int r8180_wx_set_channel(struct net_device *dev,
  29335. + struct iw_request_info *info,
  29336. + union iwreq_data *wrqu, char *extra)
  29337. +{
  29338. + int ch = *extra;
  29339. + struct r8180_priv *priv = ieee80211_priv(dev);
  29340. + struct ieee80211_device *ieee = priv->ieee80211;
  29341. +
  29342. + if(priv->ieee80211->bHwRadioOff)
  29343. + return 0;
  29344. +
  29345. + // is 11s ?
  29346. + if (!priv->mshobj || (ieee->iw_mode != ieee->iw_ext_mode) || !priv->mshobj->ext_patch_r8180_wx_set_channel )
  29347. + return 0;
  29348. +
  29349. + printk("set channel = %d\n", ch);
  29350. + if ( ch < 0 )
  29351. + {
  29352. + ieee80211_start_scan(ieee); // auto
  29353. + ieee->meshScanMode =2;
  29354. + }
  29355. + else
  29356. + {
  29357. +//#ifdef NETWORKMANAGER_UI
  29358. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  29359. + }
  29360. +//#else
  29361. + else{
  29362. + down(&priv->wx_sem);}
  29363. +//#endif
  29364. + ieee->meshScanMode =0;
  29365. + // ieee->set_chan(dev, ch);
  29366. +//#ifdef _RTL8187_EXT_PATCH_
  29367. + if(priv->mshobj->ext_patch_r8180_wx_set_channel)
  29368. + {
  29369. + priv->mshobj->ext_patch_r8180_wx_set_channel(ieee, ch);
  29370. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  29371. + }
  29372. +//#endif
  29373. + ieee->set_chan(ieee->dev, ch);
  29374. + ieee->current_network.channel = ch;
  29375. + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
  29376. + ieee80211_ext_send_11s_beacon(ieee);
  29377. +//#ifdef NETWORKMANAGER_UI
  29378. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  29379. + }
  29380. +//#else
  29381. + else{
  29382. + up(&priv->wx_sem);}
  29383. +//#endif
  29384. + //up(&ieee->wx_sem);
  29385. +
  29386. + // ieee80211_stop_scan(ieee); // user set
  29387. + //
  29388. +
  29389. + /*
  29390. + netif_carrier_off(ieee->dev);
  29391. +
  29392. + if (ieee->data_hard_stop)
  29393. + ieee->data_hard_stop(ieee->dev);
  29394. +
  29395. + ieee->state = IEEE80211_NOLINK;
  29396. + ieee->link_change(ieee->dev);
  29397. +
  29398. + ieee->current_network.channel = fwrq->m;
  29399. + ieee->set_chan(ieee->dev, ieee->current_network.channel);
  29400. +
  29401. +
  29402. + if (ieee->data_hard_resume)
  29403. + ieee->data_hard_resume(ieee->dev);
  29404. +
  29405. + netif_carrier_on(ieee->dev);
  29406. + */
  29407. +
  29408. + }
  29409. +
  29410. + return 0;
  29411. +}
  29412. +
  29413. +static int r8180_wx_set_meshID(struct net_device *dev,
  29414. + struct iw_request_info *info,
  29415. + union iwreq_data *wrqu, char *extra)
  29416. +{
  29417. + struct r8180_priv *priv = ieee80211_priv(dev);
  29418. +
  29419. + if(priv->ieee80211->bHwRadioOff)
  29420. + return 0;
  29421. +
  29422. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_meshID )
  29423. + return 0;
  29424. +
  29425. + //printk("len=%d\n", wrqu->data.length);
  29426. + //printk("\nCall setMeshid.");
  29427. + return priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, wrqu->data.pointer);
  29428. +}
  29429. +
  29430. +
  29431. +/* reserved for future
  29432. +static int r8180_wx_add_mac_allow(struct net_device *dev,
  29433. + struct iw_request_info *info,
  29434. + union iwreq_data *wrqu, char *extra)
  29435. +{
  29436. + struct r8180_priv *priv = ieee80211_priv(dev);
  29437. +
  29438. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow )
  29439. + return 0;
  29440. +
  29441. + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_allow(dev, info, wrqu, extra);
  29442. +}
  29443. +
  29444. +static int r8180_wx_del_mac_allow(struct net_device *dev,
  29445. + struct iw_request_info *info,
  29446. + union iwreq_data *wrqu, char *extra)
  29447. +{
  29448. + struct r8180_priv *priv = ieee80211_priv(dev);
  29449. +
  29450. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow )
  29451. + return 0;
  29452. +
  29453. + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_allow(dev, info, wrqu, extra);
  29454. +}
  29455. +*/
  29456. +static int r8180_wx_add_mac_deny(struct net_device *dev,
  29457. + struct iw_request_info *info,
  29458. + union iwreq_data *wrqu, char *extra)
  29459. +{
  29460. + struct r8180_priv *priv = ieee80211_priv(dev);
  29461. +
  29462. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny )
  29463. + return 0;
  29464. +
  29465. + return priv->mshobj->ext_patch_r8180_wx_set_add_mac_deny(dev, info, wrqu, extra);
  29466. +}
  29467. +
  29468. +static int r8180_wx_del_mac_deny(struct net_device *dev,
  29469. + struct iw_request_info *info,
  29470. + union iwreq_data *wrqu, char *extra)
  29471. +{
  29472. + struct r8180_priv *priv = ieee80211_priv(dev);
  29473. +
  29474. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny )
  29475. + return 0;
  29476. +
  29477. + return priv->mshobj->ext_patch_r8180_wx_set_del_mac_deny(dev, info, wrqu, extra);
  29478. +}
  29479. +
  29480. +/* reserved for future
  29481. +static int r8180_wx_get_mac_allow(struct net_device *dev,
  29482. + struct iw_request_info *info,
  29483. + union iwreq_data *wrqu, char *extra)
  29484. +{
  29485. + struct r8180_priv *priv = ieee80211_priv(dev);
  29486. +
  29487. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_allow )
  29488. + return 0;
  29489. +
  29490. + return priv->mshobj->ext_patch_r8180_wx_get_mac_allow(dev, info, wrqu, extra);
  29491. +}
  29492. +*/
  29493. +
  29494. +static int r8180_wx_get_mac_deny(struct net_device *dev,
  29495. + struct iw_request_info *info,
  29496. + union iwreq_data *wrqu, char *extra)
  29497. +{
  29498. + struct r8180_priv *priv = ieee80211_priv(dev);
  29499. +
  29500. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mac_deny )
  29501. + return 0;
  29502. +
  29503. + return priv->mshobj->ext_patch_r8180_wx_get_mac_deny(dev, info, wrqu, extra);
  29504. +}
  29505. +
  29506. +
  29507. +static int r8180_wx_get_mesh_list(struct net_device *dev,
  29508. + struct iw_request_info *info,
  29509. + union iwreq_data *wrqu, char *extra)
  29510. +{
  29511. + struct r8180_priv *priv = ieee80211_priv(dev);
  29512. +
  29513. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_get_mesh_list )
  29514. + return 0;
  29515. +
  29516. + return priv->mshobj->ext_patch_r8180_wx_get_mesh_list(dev, info, wrqu, extra);
  29517. +}
  29518. +
  29519. +static int r8180_wx_mesh_scan(struct net_device *dev,
  29520. + struct iw_request_info *info,
  29521. + union iwreq_data *wrqu, char *extra)
  29522. +{
  29523. + struct r8180_priv *priv = ieee80211_priv(dev);
  29524. +
  29525. + if( ! priv->mshobj || !priv->mshobj->ext_patch_r8180_wx_mesh_scan )
  29526. + return 0;
  29527. +
  29528. + return priv->mshobj->ext_patch_r8180_wx_mesh_scan(dev, info, wrqu, extra);
  29529. +}
  29530. +
  29531. +static int r8180_wx_join_mesh(struct net_device *dev,
  29532. + struct iw_request_info *info,
  29533. + union iwreq_data *wrqu, char *extra)
  29534. +{
  29535. + struct r8180_priv *priv = ieee80211_priv(dev);
  29536. + int index;
  29537. + int ret=0;
  29538. + char extmeshid[32];
  29539. + int len=0;
  29540. + char id[50], ch;
  29541. +//#ifdef NETWORKMANAGER_UI
  29542. +
  29543. + if((priv->ieee80211->iw_mode == IW_MODE_MESH) && (priv->ieee80211->iw_ext_mode == IW_MODE_MESH)){
  29544. + printk("join mesh %s\n",extra);
  29545. + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
  29546. + ret= -E2BIG;
  29547. + goto out;
  29548. + }
  29549. + //printk("wrqu->essid.length is %d\n",wrqu->essid.length);
  29550. + //printk("wrqu->essid.flags is %d\n",wrqu->essid.flags);
  29551. + if((wrqu->essid.length == 1) && (wrqu->essid.flags == 1)){
  29552. + ret = 0;
  29553. + goto out;
  29554. + }
  29555. + if (wrqu->essid.flags && wrqu->essid.length) {
  29556. + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, extra, &ch))
  29557. + {
  29558. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
  29559. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  29560. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  29561. + }
  29562. + else
  29563. + printk("invalid mesh #\n");
  29564. +
  29565. + }
  29566. +#if 0
  29567. + else{
  29568. + if(priv->mshobj->ext_patch_r8180_wx_get_selected_mesh_channel(dev, 0, &ch))
  29569. + {
  29570. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, extra);
  29571. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  29572. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  29573. + }
  29574. + else
  29575. + printk("invalid mesh #\n");
  29576. +
  29577. + }
  29578. +#endif
  29579. + }
  29580. + else{
  29581. +//#else
  29582. + index = *(extra);
  29583. +// printk("index=%d\n", index);
  29584. +
  29585. + if( ! priv->mshobj
  29586. + || !priv->mshobj->ext_patch_r8180_wx_set_meshID
  29587. + || !priv->mshobj->ext_patch_r8180_wx_get_selected_mesh )
  29588. + return 0;
  29589. +
  29590. + if( priv->mshobj->ext_patch_r8180_wx_get_selected_mesh(dev, index, &ch, id) )
  29591. + {
  29592. + // printk("ch=%d, id=%s\n", ch, id);
  29593. + priv->mshobj->ext_patch_r8180_wx_set_meshID(dev, id);
  29594. + priv->mshobj->ext_patch_r8180_wx_set_mesh_chan(dev,ch);
  29595. + r8180_wx_set_channel(dev, NULL, NULL, &ch);
  29596. + }
  29597. + else
  29598. + printk("invalid mesh #\n");
  29599. + }
  29600. +//#endif
  29601. +out:
  29602. + return ret;
  29603. +}
  29604. +
  29605. +#endif // _RTL8187_EXT_PATCH_
  29606. +
  29607. +
  29608. +static int r8180_wx_get_radion(struct net_device *dev,
  29609. + struct iw_request_info *info,
  29610. + union iwreq_data *wrqu, char *extra)
  29611. +{
  29612. + struct r8180_priv *priv = ieee80211_priv(dev);
  29613. +// u8 addr;
  29614. +
  29615. + down(&priv->wx_sem);
  29616. + if(priv->radion == 1) {
  29617. + *(int *)extra = 1;
  29618. + } else {
  29619. +
  29620. + *(int *)extra = 0;
  29621. + }
  29622. + up(&priv->wx_sem);
  29623. + return 0;
  29624. +
  29625. +}
  29626. +
  29627. +static int r8180_wx_set_radion(struct net_device *dev,
  29628. + struct iw_request_info *info,
  29629. + union iwreq_data *wrqu, char *extra)
  29630. +{
  29631. + int radion = *extra;
  29632. + struct r8180_priv *priv = ieee80211_priv(dev);
  29633. +// struct ieee80211_device *ieee = priv->ieee80211;
  29634. + u8 btCR9346, btConfig3;
  29635. + int i;
  29636. + u16 u2bTFPC = 0;
  29637. + u8 u1bTmp;
  29638. +
  29639. + if(priv->ieee80211->bHwRadioOff)
  29640. + return 0;
  29641. +
  29642. + down(&priv->wx_sem);
  29643. + printk("set radion = %d\n", radion);
  29644. +
  29645. +#ifdef _RTL8187_EXT_PATCH_
  29646. + if(ieee->iw_mode == ieee->iw_ext_mode) {
  29647. + printk("mesh mode:: could not set radi on/off = %d\n", radion);
  29648. + up(&priv->wx_sem);
  29649. + return 0;
  29650. + }
  29651. +#endif
  29652. + // Set EEM0 and EEM1 in 9346CR.
  29653. + btCR9346 = read_nic_byte(dev, CR9346);
  29654. + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
  29655. + // Set PARM_En in Config3.
  29656. + btConfig3 = read_nic_byte(dev, CONFIG3);
  29657. + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
  29658. +
  29659. + if ( radion == 1) //radion off
  29660. + {
  29661. + printk("==================>RF on\n");
  29662. + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
  29663. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
  29664. + write_nic_byte(dev, CONFIG4, (priv->RFProgType));
  29665. +
  29666. + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
  29667. + write_rtl8225(dev, 0x4, 0x9FF);
  29668. +
  29669. + u1bTmp = read_nic_byte(dev, 0x24E);
  29670. + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
  29671. + priv->radion = 1; //radion on
  29672. + }
  29673. + else
  29674. + {
  29675. + printk("==================>RF off\n");
  29676. + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B; i++)
  29677. + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
  29678. + u2bTFPC = read_nic_word(dev, TFPC);
  29679. + if(u2bTFPC == 0)
  29680. + {
  29681. + break;
  29682. + }
  29683. + else
  29684. + {
  29685. + printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
  29686. + udelay(10);
  29687. + }
  29688. + }
  29689. + if( i == MAX_DOZE_WAITING_TIMES_87B )
  29690. + {
  29691. + printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n",\
  29692. + MAX_DOZE_WAITING_TIMES_87B, u2bTFPC);
  29693. + }
  29694. +
  29695. + u1bTmp = read_nic_byte(dev, 0x24E);
  29696. + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
  29697. +
  29698. + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
  29699. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
  29700. +
  29701. + write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
  29702. +
  29703. + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
  29704. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
  29705. + priv->radion = 0; //radion off
  29706. + }
  29707. + // Clear PARM_En in Config3.
  29708. + btConfig3 &= ~(CONFIG3_PARM_En);
  29709. + write_nic_byte(dev, CONFIG3, btConfig3);
  29710. + // Clear EEM0 and EEM1 in 9346CR.
  29711. + btCR9346 &= ~(0xC0);
  29712. + write_nic_byte(dev, CR9346, btCR9346);
  29713. +
  29714. + up(&priv->wx_sem);
  29715. +
  29716. + return 0;
  29717. +}
  29718. +
  29719. +static int r8180_wx_set_ratadpt (struct net_device *dev,
  29720. + struct iw_request_info *info,
  29721. + union iwreq_data *wrqu, char *extra)
  29722. +{
  29723. + int ratadapt = *extra;
  29724. + struct r8180_priv *priv = ieee80211_priv(dev);
  29725. + struct ieee80211_device *ieee = priv->ieee80211;
  29726. +
  29727. + if(priv->ieee80211->bHwRadioOff)
  29728. + return 0;
  29729. +
  29730. + down(&priv->wx_sem);
  29731. + printk("Set rate adaptive %s\n", (ratadapt==0)?"on":"off");
  29732. + if(ratadapt == 0) {
  29733. + del_timer_sync(&priv->rateadapter_timer);
  29734. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  29735. + priv->rateadapter_timer.function((unsigned long)dev);
  29736. + } else {
  29737. + del_timer_sync(&priv->rateadapter_timer);
  29738. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  29739. + printk("force rate to %d\n", ratadapt);
  29740. + ieee->rate = ratadapt;
  29741. + }
  29742. + up(&priv->wx_sem);
  29743. + return 0;
  29744. +}
  29745. +
  29746. +#ifdef ENABLE_TOSHIBA_CONFIG
  29747. +static int r8180_wx_get_tblidx(struct net_device *dev,
  29748. + struct iw_request_info *info,
  29749. + union iwreq_data *wrqu, char *extra)
  29750. +{
  29751. + struct r8180_priv *priv = ieee80211_priv(dev);
  29752. + //extern u8 chan_plan_index;
  29753. + //printk("=========>%s(), %x\n", __FUNCTION__, priv->channel_plan);
  29754. + down(&priv->wx_sem);
  29755. + put_user(priv->channel_plan, (u8*)wrqu->data.pointer);
  29756. + up(&priv->wx_sem);
  29757. + return 0;
  29758. +
  29759. +}
  29760. +
  29761. +//This func will be called after probe auto
  29762. +static int r8180_wx_set_tbl (struct net_device *dev,
  29763. + struct iw_request_info *info,
  29764. + union iwreq_data *wrqu, char *extra)
  29765. +{
  29766. + struct r8180_priv *priv = ieee80211_priv(dev);
  29767. + u8 len = 0;
  29768. + s8 err = -1;
  29769. + extern CHANNEL_LIST Current_tbl;
  29770. + down(&priv->wx_sem);
  29771. + if (!wrqu->data.pointer)
  29772. + {
  29773. + printk("user data pointer is null\n");
  29774. + goto exit;
  29775. + }
  29776. + len = wrqu->data.length;
  29777. + //printk("=========>%s(), len:%d\n", __FUNCTION__, len);
  29778. + //memset(&Current_tbl, 0, sizeof(CHANNEL_LIST));
  29779. + if (copy_from_user((u8*)&Current_tbl, (void*)wrqu->data.pointer, len))
  29780. + {
  29781. + printk("error copy from user\n");
  29782. + goto exit;
  29783. + }
  29784. + {
  29785. + int i;
  29786. + Current_tbl.Len = len;
  29787. + //printk("%d\n", Current_tbl.Len);
  29788. +
  29789. + Dot11d_Init(priv->ieee80211);
  29790. + priv->ieee80211->bGlobalDomain = false;
  29791. + priv->ieee80211->bWorldWide13 = false;
  29792. +
  29793. + //lzm add 081205
  29794. + priv->ieee80211->MinPassiveChnlNum=12;
  29795. + priv->ieee80211->IbssStartChnl= 10;
  29796. +
  29797. + for (i=0; i<Current_tbl.Len; i++){
  29798. + //printk("%2d ", Current_tbl.Channel[i]);
  29799. + if(priv->channel_plan == COUNTRY_CODE_ETSI)
  29800. + {
  29801. + if(Current_tbl.Channel[i] <= 11)
  29802. + {
  29803. +#ifdef ENABLE_DOT11D
  29804. + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
  29805. +#else
  29806. + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
  29807. +#endif
  29808. + }
  29809. + else if((Current_tbl.Channel[i] >= 11) && (Current_tbl.Channel[i] <= 13))
  29810. + {
  29811. +#ifdef ENABLE_DOT11D
  29812. + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 2;
  29813. +#else
  29814. + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 2;
  29815. +#endif
  29816. + }
  29817. + }
  29818. + else
  29819. + {
  29820. + if(Current_tbl.Channel[i] <= 14)
  29821. + {
  29822. +#ifdef ENABLE_DOT11D
  29823. + GET_DOT11D_INFO(priv->ieee80211)->channel_map[Current_tbl.Channel[i]] = 1;
  29824. +#else
  29825. + priv->ieee80211->channel_map[Current_tbl.Channel[i]] = 1;
  29826. +#endif
  29827. + }
  29828. + }
  29829. + }
  29830. +#if 0
  29831. + printk("\n");
  29832. + for(i=1; i<MAX_CHANNEL_NUMBER; i++)
  29833. + {
  29834. +#ifdef ENABLE_DOT11D
  29835. + printk("%2d ", GET_DOT11D_INFO(priv->ieee80211)->channel_map[i]);
  29836. +#else
  29837. + printk("%2d ", priv->ieee80211->channel_map[i]);
  29838. +#endif
  29839. + }
  29840. + printk("\n");
  29841. +
  29842. +#endif
  29843. + if(priv->ieee80211->proto_started)
  29844. + {//we need to restart protocol now if it was start before channel map
  29845. + ieee80211_softmac_stop_protocol(priv->ieee80211);
  29846. + //mdelay(1);
  29847. + ieee80211_softmac_start_protocol(priv->ieee80211);
  29848. + }
  29849. + }
  29850. + err = 0;
  29851. +exit:
  29852. + up(&priv->wx_sem);
  29853. + return err;
  29854. +
  29855. +
  29856. +}
  29857. +
  29858. +#endif
  29859. +
  29860. +
  29861. +static iw_handler r8180_wx_handlers[] =
  29862. +{
  29863. + NULL, /* SIOCSIWCOMMIT */
  29864. + r8180_wx_get_name, /* SIOCGIWNAME */
  29865. + dummy, /* SIOCSIWNWID */
  29866. + dummy, /* SIOCGIWNWID */
  29867. + r8180_wx_set_freq, /* SIOCSIWFREQ */
  29868. + r8180_wx_get_freq, /* SIOCGIWFREQ */
  29869. + r8180_wx_set_mode, /* SIOCSIWMODE */
  29870. + r8180_wx_get_mode, /* SIOCGIWMODE */
  29871. + r8180_wx_set_sens, /* SIOCSIWSENS */
  29872. + r8180_wx_get_sens, /* SIOCGIWSENS */
  29873. + NULL, /* SIOCSIWRANGE */
  29874. + rtl8180_wx_get_range, /* SIOCGIWRANGE */
  29875. + NULL, /* SIOCSIWPRIV */
  29876. + NULL, /* SIOCGIWPRIV */
  29877. + NULL, /* SIOCSIWSTATS */
  29878. + NULL, /* SIOCGIWSTATS */
  29879. + dummy, /* SIOCSIWSPY */
  29880. + dummy, /* SIOCGIWSPY */
  29881. + NULL, /* SIOCGIWTHRSPY */
  29882. + NULL, /* SIOCWIWTHRSPY */
  29883. + r8180_wx_set_wap, /* SIOCSIWAP */
  29884. + r8180_wx_get_wap, /* SIOCGIWAP */
  29885. + r8180_wx_set_mlme, //NULL, /* SIOCSIWMLME*/ /* -- hole -- */
  29886. + dummy, /* SIOCGIWAPLIST -- depricated */
  29887. + r8180_wx_set_scan, /* SIOCSIWSCAN */
  29888. + r8180_wx_get_scan, /* SIOCGIWSCAN */
  29889. + r8180_wx_set_essid, /* SIOCSIWESSID */
  29890. + r8180_wx_get_essid, /* SIOCGIWESSID */
  29891. + dummy, /* SIOCSIWNICKN */
  29892. + dummy, /* SIOCGIWNICKN */
  29893. + NULL, /* -- hole -- */
  29894. + NULL, /* -- hole -- */
  29895. + r8180_wx_set_rate, /* SIOCSIWRATE */
  29896. + r8180_wx_get_rate, /* SIOCGIWRATE */
  29897. + dummy, /* SIOCSIWRTS */
  29898. + dummy, /* SIOCGIWRTS */
  29899. + r8180_wx_set_frag, /* SIOCSIWFRAG */
  29900. + r8180_wx_get_frag, /* SIOCGIWFRAG */
  29901. + dummy, /* SIOCSIWTXPOW */
  29902. + dummy, /* SIOCGIWTXPOW */
  29903. + r8180_wx_set_retry, /* SIOCSIWRETRY */
  29904. + r8180_wx_get_retry, /* SIOCGIWRETRY */
  29905. + r8180_wx_set_enc, /* SIOCSIWENCODE */
  29906. + r8180_wx_get_enc, /* SIOCGIWENCODE */
  29907. + dummy, /* SIOCSIWPOWER */
  29908. + dummy, /* SIOCGIWPOWER */
  29909. + NULL, /*---hole---*/
  29910. + NULL, /*---hole---*/
  29911. + r8180_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
  29912. + NULL, /* SIOCSIWGENIE */
  29913. + r8180_wx_set_auth,//NULL, /* SIOCSIWAUTH */
  29914. + NULL,//r8180_wx_get_auth,//NULL, /* SIOCSIWAUTH */
  29915. + r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
  29916. + NULL,//r8180_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
  29917. + NULL, /* SIOCSIWPMKSA */
  29918. + NULL, /*---hole---*/
  29919. +};
  29920. +
  29921. +
  29922. +static const struct iw_priv_args r8180_private_args[] = {
  29923. + {
  29924. + SIOCIWFIRSTPRIV + 0x0,
  29925. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
  29926. + },
  29927. +
  29928. + {
  29929. + SIOCIWFIRSTPRIV + 0x1,
  29930. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
  29931. +
  29932. + },
  29933. + {
  29934. + SIOCIWFIRSTPRIV + 0x2,
  29935. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
  29936. + },
  29937. +#ifdef JOHN_IOCTL
  29938. + {
  29939. + SIOCIWFIRSTPRIV + 0x3,
  29940. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
  29941. + }
  29942. + ,
  29943. + {
  29944. + SIOCIWFIRSTPRIV + 0x4,
  29945. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
  29946. + }
  29947. + ,
  29948. + {
  29949. + SIOCIWFIRSTPRIV + 0x5,
  29950. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
  29951. + }
  29952. + ,
  29953. + {
  29954. + SIOCIWFIRSTPRIV + 0x6,
  29955. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
  29956. + }
  29957. + ,
  29958. + {
  29959. + SIOCIWFIRSTPRIV + 0x7,
  29960. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
  29961. + }
  29962. + ,
  29963. + {
  29964. + SIOCIWFIRSTPRIV + 0x8,
  29965. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
  29966. + }
  29967. + ,
  29968. + {
  29969. + SIOCIWFIRSTPRIV + 0x9,
  29970. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
  29971. + },
  29972. +#endif
  29973. + {
  29974. + SIOCIWFIRSTPRIV + 0xA,
  29975. + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED |1, "getradion"
  29976. + },
  29977. + {
  29978. + SIOCIWFIRSTPRIV + 0xB,
  29979. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setradion"
  29980. + },
  29981. + {
  29982. + SIOCIWFIRSTPRIV + 0xC,
  29983. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ratadpt"
  29984. + },
  29985. +#ifdef ENABLE_TOSHIBA_CONFIG
  29986. + {
  29987. + SIOCIWFIRSTPRIV + 0xD,
  29988. + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettblidx"
  29989. + },
  29990. + {
  29991. + SIOCIWFIRSTPRIV + 0xE,
  29992. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,0, "settblidx"
  29993. + },
  29994. +
  29995. +#endif
  29996. +
  29997. +};
  29998. +
  29999. +/*
  30000. + * Private ioctl interface information
  30001. +
  30002. +struct iw_priv_args
  30003. +{
  30004. +// __u32 cmd;
  30005. +// __u16 set_args;
  30006. +// __u16 get_args;
  30007. +// char name[IFNAMSIZ];
  30008. +//};
  30009. +*/
  30010. +//If get cmd's number is big,there may cause some problemes.
  30011. +//So modified by Lawrence,071120
  30012. +
  30013. +static iw_handler r8180_private_handler[] = {
  30014. +// r8180_wx_set_monitor, /* SIOCIWFIRSTPRIV */
  30015. + r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
  30016. +// r8180_wx_set_forceassociate,
  30017. +// r8180_wx_set_beaconinterval,
  30018. +// r8180_wx_set_monitor_type,
  30019. + r8180_wx_set_scan_type,
  30020. + r8180_wx_set_rawtx,
  30021. +
  30022. +#if 0
  30023. +#ifdef _RTL8187_EXT_PATCH_
  30024. + r8180_wx_get_meshinfo,
  30025. + r8180_wx_enable_mesh,
  30026. + r8180_wx_disable_mesh,
  30027. + r8180_wx_set_channel,
  30028. + r8180_wx_set_meshID,
  30029. +
  30030. +// r8180_wx_add_mac_allow,
  30031. +// r8180_wx_get_mac_allow,
  30032. +// r8180_wx_del_mac_allow,
  30033. + r8180_wx_add_mac_deny,
  30034. + r8180_wx_get_mac_deny,
  30035. + r8180_wx_del_mac_deny,
  30036. + r8180_wx_get_mesh_list,
  30037. + r8180_wx_mesh_scan,
  30038. + r8180_wx_join_mesh,
  30039. +#endif
  30040. +#endif
  30041. +
  30042. +#ifdef JOHN_IOCTL
  30043. + r8180_wx_read_regs,
  30044. + r8180_wx_write_regs,
  30045. + r8180_wx_read_bb,
  30046. + r8180_wx_write_bb,
  30047. + r8180_wx_read_nicb,
  30048. + r8180_wx_write_nicb,
  30049. + r8180_wx_get_ap_status,
  30050. +#endif
  30051. + r8180_wx_get_radion,
  30052. + r8180_wx_set_radion,
  30053. + r8180_wx_set_ratadpt,
  30054. +#ifdef ENABLE_TOSHIBA_CONFIG
  30055. + r8180_wx_get_tblidx,
  30056. + r8180_wx_set_tbl,
  30057. +#endif
  30058. +};
  30059. +
  30060. +#if WIRELESS_EXT >= 17
  30061. +//WB modefied to show signal to GUI on 18-01-2008
  30062. +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
  30063. +{
  30064. + struct r8180_priv *priv = ieee80211_priv(dev);
  30065. + struct ieee80211_device* ieee = priv->ieee80211;
  30066. + struct iw_statistics* wstats = &priv->wstats;
  30067. +// struct ieee80211_network* target = NULL;
  30068. + int tmp_level = 0;
  30069. + int tmp_qual = 0;
  30070. + int tmp_noise = 0;
  30071. +// unsigned long flag;
  30072. +
  30073. + if (ieee->state < IEEE80211_LINKED)
  30074. + {
  30075. + wstats->qual.qual = 0;
  30076. + wstats->qual.level = 0;
  30077. + wstats->qual.noise = 0;
  30078. + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
  30079. + return wstats;
  30080. + }
  30081. +#if 0
  30082. + spin_lock_irqsave(&ieee->lock, flag);
  30083. + list_for_each_entry(target, &ieee->network_list, list)
  30084. + {
  30085. + if (is_same_network(target, &ieee->current_network))
  30086. + {
  30087. + printk("it's same network:%s\n", target->ssid);
  30088. +#if 0
  30089. + if (!tmp_level)
  30090. + {
  30091. + tmp_level = target->stats.signalstrength;
  30092. + tmp_qual = target->stats.signal;
  30093. + }
  30094. + else
  30095. + {
  30096. +
  30097. + tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
  30098. + tmp_qual = (15*tmp_qual + target->stats.signal)/16;
  30099. + }
  30100. +#else
  30101. + tmp_level = target->stats.signal;
  30102. + tmp_qual = target->stats.signalstrength;
  30103. + tmp_noise = target->stats.noise;
  30104. + printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
  30105. +#endif
  30106. + break;
  30107. + }
  30108. + }
  30109. + spin_unlock_irqrestore(&ieee->lock, flag);
  30110. +#endif
  30111. + tmp_level = (&ieee->current_network)->stats.signal;
  30112. + tmp_qual = (&ieee->current_network)->stats.signalstrength;
  30113. + tmp_noise = (&ieee->current_network)->stats.noise;
  30114. + //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
  30115. +
  30116. + wstats->qual.level = tmp_level;
  30117. + wstats->qual.qual = tmp_qual;
  30118. + wstats->qual.noise = tmp_noise;
  30119. + wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
  30120. + return wstats;
  30121. +}
  30122. +#endif
  30123. +
  30124. +
  30125. +struct iw_handler_def r8180_wx_handlers_def={
  30126. + .standard = r8180_wx_handlers,
  30127. + .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
  30128. + .private = r8180_private_handler,
  30129. + .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
  30130. + .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
  30131. +#if WIRELESS_EXT >= 17
  30132. + .get_wireless_stats = r8180_get_wireless_stats,
  30133. +#endif
  30134. + .private_args = (struct iw_priv_args *)r8180_private_args,
  30135. +};
  30136. +#ifdef _RTL8187_EXT_PATCH_
  30137. +EXPORT_SYMBOL(r8180_wx_set_channel);
  30138. +#endif
  30139. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.h linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.h
  30140. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8180_wx.h 1970-01-01 01:00:00.000000000 +0100
  30141. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8180_wx.h 2010-05-27 18:12:39.532222207 +0200
  30142. @@ -0,0 +1,21 @@
  30143. +/*
  30144. + This is part of rtl8180 OpenSource driver - v 0.3
  30145. + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
  30146. + Released under the terms of GPL (General Public Licence)
  30147. +
  30148. + Parts of this driver are based on the GPL part of the official realtek driver
  30149. + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
  30150. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
  30151. +
  30152. + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
  30153. +*/
  30154. +
  30155. +/* this file (will) contains wireless extension handlers*/
  30156. +
  30157. +#ifndef R8180_WX_H
  30158. +#define R8180_WX_H
  30159. +#include <linux/wireless.h>
  30160. +#include "ieee80211/ieee80211.h"
  30161. +extern struct iw_handler_def r8180_wx_handlers_def;
  30162. +
  30163. +#endif
  30164. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_core.c linux-loongson/drivers/net/wireless/rtl8187b/r8187_core.c
  30165. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_core.c 1970-01-01 01:00:00.000000000 +0100
  30166. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_core.c 2010-05-27 18:12:39.532222207 +0200
  30167. @@ -0,0 +1,7042 @@
  30168. +/*
  30169. + This is part of rtl8187 OpenSource driver - v 0.1
  30170. + Copyright (C) Andrea Merello 2005 <andreamrl@tiscali.it>
  30171. + Released under the terms of GPL (General Public License)
  30172. +
  30173. +
  30174. + Parts of this driver are based on the rtl8180 driver skeleton
  30175. + from Patric Schenke & Andres Salomon.
  30176. +
  30177. + Parts of this driver are based on the Intel Pro Wireless 2*00 GPL drivers.
  30178. +
  30179. + some ideas might be derived from David Young rtl8180 netbsd driver.
  30180. +
  30181. + Parts of the usb code are from the r8150.c driver in linux kernel
  30182. +
  30183. + Some ideas borrowed from the 8139too.c driver included in linux kernel.
  30184. +
  30185. + We (I?) want to thanks the Authors of those projecs and also the
  30186. + Ndiswrapper's project Authors.
  30187. +
  30188. + A special big thanks goes also to Realtek corp. for their help in my
  30189. + attempt to add RTL8187 and RTL8225 support, and to David Young also.
  30190. +
  30191. + - Please note that this file is a modified version from rtl8180-sa2400
  30192. + drv. So some other people have contributed to this project, and they are
  30193. + thanked in the rtl8180-sa2400 CHANGELOG.
  30194. +*/
  30195. +
  30196. +#undef LOOP_TEST
  30197. +#undef DUMP_RX
  30198. +#undef DUMP_TX
  30199. +#undef DEBUG_TX_DESC2
  30200. +#undef RX_DONT_PASS_UL
  30201. +#undef DEBUG_EPROM
  30202. +#undef DEBUG_RX_VERBOSE
  30203. +#undef DUMMY_RX
  30204. +#undef DEBUG_ZERO_RX
  30205. +#undef DEBUG_RX_SKB
  30206. +#undef DEBUG_TX_FRAG
  30207. +#undef DEBUG_RX_FRAG
  30208. +#undef DEBUG_TX_FILLDESC
  30209. +#undef DEBUG_TX
  30210. +#undef DEBUG_IRQ
  30211. +#undef DEBUG_RX
  30212. +#undef DEBUG_RXALLOC
  30213. +#undef DEBUG_REGISTERS
  30214. +#undef DEBUG_RING
  30215. +#undef DEBUG_IRQ_TASKLET
  30216. +#undef DEBUG_TX_ALLOC
  30217. +#undef DEBUG_TX_DESC
  30218. +#undef CONFIG_SOFT_BEACON
  30219. +#undef DEBUG_RW_REGISTER
  30220. +
  30221. +#define CONFIG_RTL8180_IO_MAP
  30222. +//#define CONFIG_SOFT_BEACON
  30223. +//#define DEBUG_RW_REGISTER
  30224. +
  30225. +#include "r8180_hw.h"
  30226. +#include "r8187.h"
  30227. +#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
  30228. +#include "r8180_93cx6.h" /* Card EEPROM */
  30229. +#include "r8180_wx.h"
  30230. +#include "r8180_dm.h"
  30231. +
  30232. +#include <linux/dmapool.h>
  30233. +
  30234. +#include <linux/usb.h>
  30235. +// FIXME: check if 2.6.7 is ok
  30236. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
  30237. +#define usb_kill_urb usb_unlink_urb
  30238. +#endif
  30239. +
  30240. +#ifdef CONFIG_RTL8180_PM
  30241. +#include "r8180_pm.h"
  30242. +#endif
  30243. +
  30244. +#ifdef ENABLE_DOT11D
  30245. +#include "dot11d.h"
  30246. +#endif
  30247. +
  30248. +#ifndef USB_VENDOR_ID_REALTEK
  30249. +#define USB_VENDOR_ID_REALTEK 0x0bda
  30250. +#endif
  30251. +#ifndef USB_VENDOR_ID_NETGEAR
  30252. +#define USB_VENDOR_ID_NETGEAR 0x0846
  30253. +#endif
  30254. +
  30255. +#define TXISR_SELECT(priority) ((priority == MANAGE_PRIORITY)?rtl8187_managetx_isr:\
  30256. + (priority == BEACON_PRIORITY)?rtl8187_beacontx_isr: \
  30257. + (priority == VO_PRIORITY)?rtl8187_votx_isr: \
  30258. + (priority == VI_PRIORITY)?rtl8187_vitx_isr:\
  30259. + (priority == BE_PRIORITY)?rtl8187_betx_isr:rtl8187_bktx_isr)
  30260. +
  30261. +static struct usb_device_id rtl8187_usb_id_tbl[] = {
  30262. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8187)},
  30263. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8189)},
  30264. +// {USB_DEVICE_VER(USB_VENDOR_ID_REALTEK, 0x8187,0x0200,0x0200)},
  30265. + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6100)},
  30266. + {USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6a00)},
  30267. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8197)},
  30268. + {USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8198)},
  30269. + {}
  30270. +};
  30271. +
  30272. +static char* ifname = "wlan%d";
  30273. +#if 0
  30274. +static int hwseqnum = 0;
  30275. +static int hwwep = 0;
  30276. +#endif
  30277. +static int channels = 0x3fff;
  30278. +//static int channels = 0x7ff;// change by thomas, use 1 - 11 channel 0907-2007
  30279. +#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 )
  30280. +//by amy for rate adaptive
  30281. +#define DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD 300
  30282. +//by amy for rate adaptive
  30283. +//by amy for ps
  30284. +#define IEEE80211_WATCH_DOG_TIME 2000
  30285. +//by amy for ps
  30286. +MODULE_LICENSE("GPL");
  30287. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  30288. +MODULE_VERSION("V 1.1");
  30289. +#endif
  30290. +MODULE_DEVICE_TABLE(usb, rtl8187_usb_id_tbl);
  30291. +MODULE_AUTHOR("Realsil Wlan");
  30292. +MODULE_DESCRIPTION("Linux driver for Realtek RTL8187 WiFi cards");
  30293. +
  30294. +#if 0
  30295. +MODULE_PARM(ifname,"s");
  30296. +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
  30297. +
  30298. +MODULE_PARM(hwseqnum,"i");
  30299. +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
  30300. +
  30301. +MODULE_PARM(hwwep,"i");
  30302. +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
  30303. +
  30304. +MODULE_PARM(channels,"i");
  30305. +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
  30306. +#endif
  30307. +
  30308. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
  30309. +module_param(ifname, charp, S_IRUGO|S_IWUSR );
  30310. +//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
  30311. +//module_param(hwwep,int, S_IRUGO|S_IWUSR);
  30312. +module_param(channels,int, S_IRUGO|S_IWUSR);
  30313. +#else
  30314. +MODULE_PARM(ifname, "s");
  30315. +//MODULE_PARM(hwseqnum,"i");
  30316. +//MODULE_PARM(hwwep,"i");
  30317. +MODULE_PARM(channels,"i");
  30318. +#endif
  30319. +
  30320. +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
  30321. +//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
  30322. +//MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
  30323. +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
  30324. +
  30325. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  30326. +static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
  30327. + const struct usb_device_id *id);
  30328. +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf);
  30329. +#else
  30330. +static void *__devinit rtl8187_usb_probe(struct usb_device *udev,unsigned int ifnum,
  30331. + const struct usb_device_id *id);
  30332. +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr);
  30333. +#endif
  30334. +
  30335. +
  30336. +static struct usb_driver rtl8187_usb_driver = {
  30337. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
  30338. + .owner = THIS_MODULE,
  30339. +#endif
  30340. + .name = RTL8187_MODULE_NAME, /* Driver name */
  30341. + .id_table = rtl8187_usb_id_tbl, /* PCI_ID table */
  30342. + .probe = rtl8187_usb_probe, /* probe fn */
  30343. + .disconnect = rtl8187_usb_disconnect, /* remove fn */
  30344. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
  30345. +#ifdef CONFIG_RTL8180_PM
  30346. + .suspend = rtl8187_suspend, /* PM suspend fn */
  30347. + .resume = rtl8187_resume, /* PM resume fn */
  30348. +#else
  30349. + .suspend = NULL, /* PM suspend fn */
  30350. + .resume = NULL, /* PM resume fn */
  30351. +#endif
  30352. +#endif
  30353. +};
  30354. +
  30355. +#ifdef JOHN_HWSEC
  30356. +void CAM_mark_invalid(struct net_device *dev, u8 ucIndex)
  30357. +{
  30358. + u32 ulContent=0;
  30359. + u32 ulCommand=0;
  30360. + u32 ulEncAlgo=CAM_AES;
  30361. +
  30362. + // keyid must be set in config field
  30363. + ulContent |= (ucIndex&3) | ((u16)(ulEncAlgo)<<2);
  30364. +
  30365. + ulContent |= BIT15;
  30366. + // polling bit, and No Write enable, and address
  30367. + ulCommand= CAM_CONTENT_COUNT*ucIndex;
  30368. + ulCommand= ulCommand | BIT31|BIT16;
  30369. + // write content 0 is equall to mark invalid
  30370. +
  30371. + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
  30372. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A4: %x \n",ulContent));
  30373. + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
  30374. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_mark_invalid(): WRITE A0: %x \n",ulCommand));
  30375. +}
  30376. +
  30377. +void CAM_empty_entry(struct net_device *dev, u8 ucIndex)
  30378. +{
  30379. + u32 ulCommand=0;
  30380. + u32 ulContent=0;
  30381. + u8 i;
  30382. + u32 ulEncAlgo=CAM_AES;
  30383. +
  30384. + for(i=0;i<6;i++)
  30385. + {
  30386. +
  30387. + // filled id in CAM config 2 byte
  30388. + if( i == 0)
  30389. + {
  30390. + ulContent |=(ucIndex & 0x03) | (ulEncAlgo<<2);
  30391. + ulContent |= BIT15;
  30392. +
  30393. + }
  30394. + else
  30395. + {
  30396. + ulContent = 0;
  30397. + }
  30398. + // polling bit, and No Write enable, and address
  30399. + ulCommand= CAM_CONTENT_COUNT*ucIndex+i;
  30400. + ulCommand= ulCommand | BIT31|BIT16;
  30401. + // write content 0 is equall to mark invalid
  30402. + write_nic_dword(dev, WCAMI, ulContent); //delay_ms(40);
  30403. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %x \n",ulContent));
  30404. + write_nic_dword(dev, RWCAM, ulCommand); //delay_ms(40);
  30405. + //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %x \n",ulCommand));
  30406. + }
  30407. +}
  30408. +
  30409. +void CamResetAllEntry(struct net_device *dev)
  30410. +{
  30411. + u8 ucIndex;
  30412. +
  30413. + //2004/02/11 In static WEP, OID_ADD_KEY or OID_ADD_WEP are set before STA associate to AP.
  30414. + // However, ResetKey is called on OID_802_11_INFRASTRUCTURE_MODE and MlmeAssociateRequest
  30415. + // In this condition, Cam can not be reset because upper layer will not set this static key again.
  30416. + //if(Adapter->EncAlgorithm == WEP_Encryption)
  30417. + // return;
  30418. + //debug
  30419. + //DbgPrint("========================================\n");
  30420. + //DbgPrint(" Call ResetAllEntry \n");
  30421. + //DbgPrint("========================================\n\n");
  30422. +
  30423. + for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
  30424. + CAM_mark_invalid(dev, ucIndex);
  30425. + for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
  30426. + CAM_empty_entry(dev, ucIndex);
  30427. +
  30428. +}
  30429. +
  30430. +
  30431. +void write_cam(struct net_device *dev, u8 addr, u32 data)
  30432. +{
  30433. + write_nic_dword(dev, WCAMI, data);
  30434. + write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
  30435. +}
  30436. +u32 read_cam(struct net_device *dev, u8 addr)
  30437. +{
  30438. + write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
  30439. + return read_nic_dword(dev, 0xa8);
  30440. +}
  30441. +#endif /*JOHN_HWSEC*/
  30442. +
  30443. +#ifdef DEBUG_RW_REGISTER
  30444. +//lzm add for write time out test
  30445. +void add_into_rw_registers(struct net_device *dev, u32 addr, u32 cont, u8 flag)
  30446. +{
  30447. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30448. + int reg_index = (priv->write_read_register_index % 200) ;
  30449. +
  30450. + priv->write_read_registers[reg_index].address = 0;
  30451. + priv->write_read_registers[reg_index].content = 0;
  30452. + priv->write_read_registers[reg_index].flag = 0;
  30453. +
  30454. + priv->write_read_registers[reg_index].address = addr;
  30455. + priv->write_read_registers[reg_index].content = cont;
  30456. + priv->write_read_registers[reg_index].flag = flag;
  30457. +
  30458. + priv->write_read_register_index = (priv->write_read_register_index + 1) % 200;
  30459. +}
  30460. +
  30461. +bool print_once = 0;
  30462. +
  30463. +void print_rw_registers(struct net_device *dev)
  30464. +{
  30465. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30466. + int reg_index = 0;
  30467. + int watchdog = 0;
  30468. + if(print_once == false)
  30469. + {
  30470. + print_once = true;
  30471. + for(reg_index = ((priv->write_read_register_index + 1) % 200); watchdog <= 199; reg_index++)
  30472. + {
  30473. + watchdog++;
  30474. + printk("====>reg_addr:0x%x, reg_cont:0x%x, read_or_write:0x%d\n",
  30475. + priv->write_read_registers[reg_index].address,
  30476. + priv->write_read_registers[reg_index].content,
  30477. + priv->write_read_registers[reg_index].flag);
  30478. + }
  30479. + }
  30480. +}
  30481. +//lzm add for write time out test
  30482. +#endif
  30483. +
  30484. +#ifdef CPU_64BIT
  30485. +void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
  30486. +{
  30487. + int status;
  30488. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30489. + struct usb_device *udev = priv->udev;
  30490. +
  30491. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30492. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30493. + indx|0xfe00, 0, &data, 1, HZ / 2);
  30494. +
  30495. +//lzm add for write time out test
  30496. +#ifdef DEBUG_RW_REGISTER
  30497. + add_into_rw_registers(dev, indx, data, 2);
  30498. +#endif
  30499. +
  30500. + if (status < 0)
  30501. + {
  30502. + printk("write_nic_byte_E TimeOut!addr:%x, status:%x\n", indx, status);
  30503. +#ifdef DEBUG_RW_REGISTER
  30504. + print_rw_registers(dev);
  30505. +#endif
  30506. + }
  30507. +}
  30508. +
  30509. +u8 read_nic_byte_E(struct net_device *dev, int indx)
  30510. +{
  30511. + int status;
  30512. + u8 data, *buf;
  30513. + dma_addr_t dma_handle;
  30514. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30515. + struct usb_device *udev = priv->udev;
  30516. +
  30517. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  30518. + if (!buf) {
  30519. + printk("read_nic_byte_E out of memory\n");
  30520. + return -ENOMEM;
  30521. + }
  30522. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30523. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30524. + indx|0xfe00, 0, buf, 1, HZ / 2);
  30525. +//lzm add for write time out test
  30526. +#ifdef DEBUG_RW_REGISTER
  30527. + add_into_rw_registers(dev, indx, buf[0], 1);
  30528. +#endif
  30529. +
  30530. + if (status < 0)
  30531. + {
  30532. + printk("read_nic_byte_E TimeOut!addr:%x, status:%x\n",indx, status);
  30533. +#ifdef DEBUG_RW_REGISTER
  30534. + print_rw_registers(dev);
  30535. +#endif
  30536. + }
  30537. +
  30538. + data = buf[0];
  30539. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  30540. + return data;
  30541. +}
  30542. +
  30543. +void write_nic_byte(struct net_device *dev, int indx, u8 data)
  30544. +{
  30545. + int status;
  30546. +
  30547. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30548. + struct usb_device *udev = priv->udev;
  30549. +
  30550. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30551. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30552. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
  30553. +
  30554. +//lzm add for write time out test
  30555. +#ifdef DEBUG_RW_REGISTER
  30556. + add_into_rw_registers(dev, indx, data, 2);
  30557. +#endif
  30558. + if (status < 0)
  30559. + {
  30560. + printk("write_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
  30561. +#ifdef DEBUG_RW_REGISTER
  30562. + print_rw_registers(dev);
  30563. +#endif
  30564. + }
  30565. +
  30566. +
  30567. +}
  30568. +
  30569. +void write_nic_word(struct net_device *dev, int indx, u16 data)
  30570. +{
  30571. +
  30572. + int status;
  30573. +
  30574. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30575. + struct usb_device *udev = priv->udev;
  30576. +
  30577. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30578. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30579. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
  30580. +
  30581. +//lzm add for write time out test
  30582. +#ifdef DEBUG_RW_REGISTER
  30583. + add_into_rw_registers(dev, indx, data, 2);
  30584. +
  30585. + if(priv->write_read_register_index == 199)
  30586. + {
  30587. + //print_rw_registers(dev);
  30588. + }
  30589. +#endif
  30590. + if (status < 0)
  30591. + {
  30592. + printk("write_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
  30593. +#ifdef DEBUG_RW_REGISTER
  30594. + print_rw_registers(dev);
  30595. +#endif
  30596. + }
  30597. +
  30598. +}
  30599. +
  30600. +void write_nic_dword(struct net_device *dev, int indx, u32 data)
  30601. +{
  30602. +
  30603. + int status;
  30604. +
  30605. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30606. + struct usb_device *udev = priv->udev;
  30607. +
  30608. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30609. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30610. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
  30611. +//lzm add for write time out test
  30612. +#ifdef DEBUG_RW_REGISTER
  30613. + add_into_rw_registers(dev, indx, data, 2);
  30614. +#endif
  30615. +
  30616. +
  30617. + if (status < 0)
  30618. + {
  30619. + printk("write_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
  30620. +#ifdef DEBUG_RW_REGISTER
  30621. + print_rw_registers(dev);
  30622. +#endif
  30623. + }
  30624. +
  30625. +}
  30626. +
  30627. + u8 read_nic_byte(struct net_device *dev, int indx)
  30628. +{
  30629. + u8 data, *buf;
  30630. + int status;
  30631. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30632. + struct usb_device *udev = priv->udev;
  30633. + dma_addr_t dma_handle;
  30634. +
  30635. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  30636. + if (!buf) {
  30637. + printk("read_nic_byte: out of memory\n");
  30638. + return -ENOMEM;
  30639. + }
  30640. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30641. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30642. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
  30643. +//lzm add for write time out test
  30644. +#ifdef DEBUG_RW_REGISTER
  30645. + add_into_rw_registers(dev, indx, buf[0], 1);
  30646. +#endif
  30647. +
  30648. + if (status < 0)
  30649. + {
  30650. + printk("read_nic_byte TimeOut!addr:%x, status:%x\n",indx, status);
  30651. +#ifdef DEBUG_RW_REGISTER
  30652. + print_rw_registers(dev);
  30653. +#endif
  30654. + }
  30655. +
  30656. + data = buf[0];
  30657. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  30658. + return data;
  30659. +}
  30660. +
  30661. +u16 read_nic_word(struct net_device *dev, int indx)
  30662. +{
  30663. + u16 data, *buf;
  30664. + int status;
  30665. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30666. + struct usb_device *udev = priv->udev;
  30667. + dma_addr_t dma_handle;
  30668. +
  30669. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  30670. + if (!buf) {
  30671. + printk("read_nic_word: out of memory\n");
  30672. + return -ENOMEM;
  30673. + }
  30674. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30675. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30676. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
  30677. +//lzm add for write time out test
  30678. +#ifdef DEBUG_RW_REGISTER
  30679. + add_into_rw_registers(dev, indx, buf[0], 1);
  30680. +#endif
  30681. +
  30682. + if (status < 0)
  30683. + {
  30684. + printk("read_nic_word TimeOut!addr:%x, status:%x\n",indx, status);
  30685. +#ifdef DEBUG_RW_REGISTER
  30686. + print_rw_registers(dev);
  30687. +#endif
  30688. + }
  30689. +
  30690. +
  30691. + data = buf[0];
  30692. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  30693. + return data;
  30694. +}
  30695. +
  30696. +u32 read_nic_dword(struct net_device *dev, int indx)
  30697. +{
  30698. + u32 data, *buf;
  30699. + int status;
  30700. + dma_addr_t dma_handle;
  30701. +// int result;
  30702. +
  30703. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30704. + struct usb_device *udev = priv->udev;
  30705. +
  30706. + buf = dma_pool_alloc(priv->usb_pool, GFP_ATOMIC, &dma_handle);
  30707. + if (!buf){
  30708. + printk("read_nic_dword: out of memory\n");
  30709. + return -ENOMEM;
  30710. + }
  30711. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30712. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30713. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
  30714. +//lzm add for write time out test
  30715. +#ifdef DEBUG_RW_REGISTER
  30716. + add_into_rw_registers(dev, indx, buf[0], 1);
  30717. +#endif
  30718. +
  30719. + if (status < 0)
  30720. + {
  30721. + printk("read_nic_dword TimeOut!addr:%x, status:%x\n",indx, status);
  30722. +#ifdef DEBUG_RW_REGISTER
  30723. + print_rw_registers(dev);
  30724. +#endif
  30725. + }
  30726. +
  30727. +
  30728. +
  30729. + data = buf[0];
  30730. + dma_pool_free(priv->usb_pool, buf, dma_handle);
  30731. + return data;
  30732. +}
  30733. +#else
  30734. +void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
  30735. +{
  30736. + int status;
  30737. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30738. + struct usb_device *udev = priv->udev;
  30739. +
  30740. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30741. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30742. + indx|0xfe00, 0, &data, 1, HZ / 2);
  30743. +
  30744. + if (status < 0)
  30745. + {
  30746. + printk("write_nic_byte_E TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data,status);
  30747. + }
  30748. +}
  30749. +
  30750. +u8 read_nic_byte_E(struct net_device *dev, int indx)
  30751. +{
  30752. + int status;
  30753. + u8 data = 0;
  30754. + u8 buf[64];
  30755. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30756. + struct usb_device *udev = priv->udev;
  30757. +
  30758. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30759. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30760. + indx|0xfe00, 0, buf, 1, HZ / 2);
  30761. +
  30762. + if (status < 0)
  30763. + {
  30764. + printk("read_nic_byte_E TimeOut!addr:0x%x, status:%x\n", indx, status);
  30765. + }
  30766. +
  30767. + data = *(u8*)buf;
  30768. + return data;
  30769. +}
  30770. +
  30771. +void write_nic_byte(struct net_device *dev, int indx, u8 data)
  30772. +{
  30773. + int status;
  30774. +
  30775. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30776. + struct usb_device *udev = priv->udev;
  30777. +
  30778. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30779. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30780. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 1, HZ / 2);
  30781. +
  30782. + if (status < 0)
  30783. + {
  30784. + printk("write_nic_byte TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
  30785. + }
  30786. +
  30787. +
  30788. +}
  30789. +
  30790. +void write_nic_word(struct net_device *dev, int indx, u16 data)
  30791. +{
  30792. +
  30793. + int status;
  30794. +
  30795. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30796. + struct usb_device *udev = priv->udev;
  30797. +
  30798. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30799. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30800. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 2, HZ / 2);
  30801. +
  30802. + if (status < 0)
  30803. + {
  30804. + printk("write_nic_word TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
  30805. + }
  30806. +
  30807. +}
  30808. +
  30809. +void write_nic_dword(struct net_device *dev, int indx, u32 data)
  30810. +{
  30811. +
  30812. + int status;
  30813. +
  30814. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30815. + struct usb_device *udev = priv->udev;
  30816. +
  30817. + status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
  30818. + RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
  30819. + (indx&0xff)|0xff00, (indx>>8)&0x03, &data, 4, HZ / 2);
  30820. +
  30821. +
  30822. + if (status < 0)
  30823. + {
  30824. + printk("write_nic_dword TimeOut!addr:0x%x,val:0x%x, status:%x\n", indx,data, status);
  30825. + }
  30826. +
  30827. +}
  30828. +
  30829. +u8 read_nic_byte(struct net_device *dev, int indx)
  30830. +{
  30831. + u8 data = 0;
  30832. + u8 buf[64];
  30833. + int status;
  30834. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30835. + struct usb_device *udev = priv->udev;
  30836. +
  30837. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30838. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30839. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 1, HZ / 2);
  30840. +
  30841. + if (status < 0)
  30842. + {
  30843. + printk("read_nic_byte TimeOut!addr:0x%x,status:%x\n", indx,status);
  30844. + }
  30845. +
  30846. +
  30847. + data = *(u8*)buf;
  30848. + return data;
  30849. +}
  30850. +
  30851. +u16 read_nic_word(struct net_device *dev, int indx)
  30852. +{
  30853. + u16 data = 0;
  30854. + u8 buf[64];
  30855. + int status;
  30856. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30857. + struct usb_device *udev = priv->udev;
  30858. +
  30859. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30860. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30861. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 2, HZ / 2);
  30862. +
  30863. + if (status < 0)
  30864. + {
  30865. + printk("read_nic_word TimeOut!addr:0x%x,status:%x\n", indx,status);
  30866. + }
  30867. +
  30868. + data = *(u16*)buf;
  30869. + return data;
  30870. +}
  30871. +
  30872. +u32 read_nic_dword(struct net_device *dev, int indx)
  30873. +{
  30874. + u32 data = 0;
  30875. + u8 buf[64];
  30876. + int status;
  30877. +
  30878. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30879. + struct usb_device *udev = priv->udev;
  30880. +
  30881. + status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  30882. + RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
  30883. + (indx&0xff)|0xff00, (indx>>8)&0x03, buf, 4, HZ / 2);
  30884. +
  30885. + if (status < 0)
  30886. + {
  30887. + printk("read_nic_dword TimeOut!addr:0x%x,status:%x\n", indx, status);
  30888. + }
  30889. +
  30890. +
  30891. + data = *(u32*)buf;
  30892. + return data;
  30893. +}
  30894. +#endif
  30895. +
  30896. +
  30897. +u8 read_phy_cck(struct net_device *dev, u8 adr);
  30898. +u8 read_phy_ofdm(struct net_device *dev, u8 adr);
  30899. +/* this might still called in what was the PHY rtl8185/rtl8187 common code
  30900. + * plans are to possibilty turn it again in one common code...
  30901. + */
  30902. +inline void force_pci_posting(struct net_device *dev)
  30903. +{
  30904. +}
  30905. +
  30906. +
  30907. +static struct net_device_stats *rtl8180_stats(struct net_device *dev);
  30908. +void rtl8180_commit(struct net_device *dev);
  30909. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  30910. +void rtl8180_restart(struct work_struct *work);
  30911. +#else
  30912. +void rtl8180_restart(struct net_device *dev);
  30913. +#endif
  30914. +/****************************************************************************
  30915. + -----------------------------PROCFS STUFF-------------------------
  30916. +*****************************************************************************/
  30917. +
  30918. +static struct proc_dir_entry *rtl8180_proc = NULL;
  30919. +static int proc_get_stats_ap(char *page, char **start,
  30920. + off_t offset, int count,
  30921. + int *eof, void *data)
  30922. +{
  30923. + struct net_device *dev = data;
  30924. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  30925. + struct ieee80211_device *ieee = priv->ieee80211;
  30926. + struct ieee80211_network *target;
  30927. +
  30928. + int len = 0;
  30929. +
  30930. + list_for_each_entry(target, &ieee->network_list, list) {
  30931. +
  30932. + len += snprintf(page + len, count - len,
  30933. + "%s ", target->ssid);
  30934. + len += snprintf(page + len, count - len,
  30935. + "%ld ", (jiffies-target->last_scanned)/HZ);
  30936. +
  30937. +
  30938. +
  30939. + if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
  30940. + len += snprintf(page + len, count - len,
  30941. + "WPA\n");
  30942. + }
  30943. + else{
  30944. + len += snprintf(page + len, count - len,
  30945. + "non_WPA\n");
  30946. + }
  30947. +
  30948. + }
  30949. +
  30950. + *eof = 1;
  30951. + return len;
  30952. +}
  30953. +
  30954. +static int proc_get_registers(char *page, char **start,
  30955. + off_t offset, int count,
  30956. + int *eof, void *data)
  30957. +{
  30958. + struct net_device *dev = data;
  30959. +
  30960. + int len = 0;
  30961. + int i,n;
  30962. +
  30963. + int max=0xff;
  30964. +
  30965. + /* This dump the current register page */
  30966. +len += snprintf(page + len, count - len,
  30967. + "\n####################page 0##################\n ");
  30968. +
  30969. + for(n=0;n<=max;)
  30970. + {
  30971. + //printk( "\nD: %2x> ", n);
  30972. + len += snprintf(page + len, count - len,
  30973. + "\nD: %2x > ",n);
  30974. +
  30975. + for(i=0;i<16 && n<=max;i++,n++)
  30976. + len += snprintf(page + len, count - len,
  30977. + "%2x ",read_nic_byte(dev,n));
  30978. +
  30979. + // printk("%2x ",read_nic_byte(dev,n));
  30980. + }
  30981. + len += snprintf(page + len, count - len,"\n");
  30982. +len += snprintf(page + len, count - len,
  30983. + "\n####################page 1##################\n ");
  30984. + for(n=0;n<=max;)
  30985. + {
  30986. + //printk( "\nD: %2x> ", n);
  30987. + len += snprintf(page + len, count - len,
  30988. + "\nD: %2x > ",n);
  30989. +
  30990. + for(i=0;i<16 && n<=max;i++,n++)
  30991. + len += snprintf(page + len, count - len,
  30992. + "%2x ",read_nic_byte(dev,0x100|n));
  30993. +
  30994. + // printk("%2x ",read_nic_byte(dev,n));
  30995. + }
  30996. +len += snprintf(page + len, count - len,
  30997. + "\n####################page 2##################\n ");
  30998. + for(n=0;n<=max;)
  30999. + {
  31000. + //printk( "\nD: %2x> ", n);
  31001. + len += snprintf(page + len, count - len,
  31002. + "\nD: %2x > ",n);
  31003. +
  31004. + for(i=0;i<16 && n<=max;i++,n++)
  31005. + len += snprintf(page + len, count - len,
  31006. + "%2x ",read_nic_byte(dev,0x200|n));
  31007. +
  31008. + // printk("%2x ",read_nic_byte(dev,n));
  31009. + }
  31010. +
  31011. +
  31012. +
  31013. + *eof = 1;
  31014. + return len;
  31015. +
  31016. +}
  31017. +
  31018. +
  31019. +static int proc_get_cck_reg(char *page, char **start,
  31020. + off_t offset, int count,
  31021. + int *eof, void *data)
  31022. +{
  31023. + struct net_device *dev = data;
  31024. +
  31025. + int len = 0;
  31026. + int i,n;
  31027. +
  31028. + int max = 0x5F;
  31029. +
  31030. + /* This dump the current register page */
  31031. + for(n=0;n<=max;)
  31032. + {
  31033. + //printk( "\nD: %2x> ", n);
  31034. + len += snprintf(page + len, count - len,
  31035. + "\nD: %2x > ",n);
  31036. +
  31037. + for(i=0;i<16 && n<=max;i++,n++)
  31038. + len += snprintf(page + len, count - len,
  31039. + "%2x ",read_phy_cck(dev,n));
  31040. +
  31041. + // printk("%2x ",read_nic_byte(dev,n));
  31042. + }
  31043. + len += snprintf(page + len, count - len,"\n");
  31044. +
  31045. +
  31046. + *eof = 1;
  31047. + return len;
  31048. +
  31049. +}
  31050. +
  31051. +
  31052. +static int proc_get_ofdm_reg(char *page, char **start,
  31053. + off_t offset, int count,
  31054. + int *eof, void *data)
  31055. +{
  31056. + struct net_device *dev = data;
  31057. +
  31058. + int len = 0;
  31059. + int i,n;
  31060. +
  31061. + //int max=0xff;
  31062. + int max = 0x40;
  31063. +
  31064. + /* This dump the current register page */
  31065. + for(n=0;n<=max;)
  31066. + {
  31067. + //printk( "\nD: %2x> ", n);
  31068. + len += snprintf(page + len, count - len,
  31069. + "\nD: %2x > ",n);
  31070. +
  31071. + for(i=0;i<16 && n<=max;i++,n++)
  31072. + len += snprintf(page + len, count - len,
  31073. + "%2x ",read_phy_ofdm(dev,n));
  31074. +
  31075. + // printk("%2x ",read_nic_byte(dev,n));
  31076. + }
  31077. + len += snprintf(page + len, count - len,"\n");
  31078. +
  31079. +
  31080. +
  31081. + *eof = 1;
  31082. + return len;
  31083. +
  31084. +}
  31085. +
  31086. +
  31087. +#if 0
  31088. +static int proc_get_stats_hw(char *page, char **start,
  31089. + off_t offset, int count,
  31090. + int *eof, void *data)
  31091. +{
  31092. + struct net_device *dev = data;
  31093. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31094. +
  31095. + int len = 0;
  31096. +
  31097. + len += snprintf(page + len, count - len,
  31098. + "NIC int: %lu\n"
  31099. + "Total int: %lu\n",
  31100. + priv->stats.ints,
  31101. + priv->stats.shints);
  31102. +
  31103. + *eof = 1;
  31104. + return len;
  31105. +}
  31106. +#endif
  31107. +
  31108. +static int proc_get_stats_tx(char *page, char **start,
  31109. + off_t offset, int count,
  31110. + int *eof, void *data)
  31111. +{
  31112. + struct net_device *dev = data;
  31113. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31114. +
  31115. + int len = 0;
  31116. +
  31117. + len += snprintf(page + len, count - len,
  31118. + "TX VI priority ok int: %lu\n"
  31119. + "TX VI priority error int: %lu\n"
  31120. + "TX VO priority ok int: %lu\n"
  31121. + "TX VO priority error int: %lu\n"
  31122. + "TX BE priority ok int: %lu\n"
  31123. + "TX BE priority error int: %lu\n"
  31124. + "TX BK priority ok int: %lu\n"
  31125. + "TX BK priority error int: %lu\n"
  31126. + "TX MANAGE priority ok int: %lu\n"
  31127. + "TX MANAGE priority error int: %lu\n"
  31128. + "TX BEACON priority ok int: %lu\n"
  31129. + "TX BEACON priority error int: %lu\n"
  31130. +// "TX high priority ok int: %lu\n"
  31131. +// "TX high priority failed error int: %lu\n"
  31132. + "TX queue resume: %lu\n"
  31133. + "TX queue stopped?: %d\n"
  31134. + "TX fifo overflow: %lu\n"
  31135. +// "TX beacon: %lu\n"
  31136. + "TX VI queue: %d\n"
  31137. + "TX VO queue: %d\n"
  31138. + "TX BE queue: %d\n"
  31139. + "TX BK queue: %d\n"
  31140. + "TX BEACON queue: %d\n"
  31141. + "TX MANAGE queue: %d\n"
  31142. +// "TX HW queue: %d\n"
  31143. + "TX VI dropped: %lu\n"
  31144. + "TX VO dropped: %lu\n"
  31145. + "TX BE dropped: %lu\n"
  31146. + "TX BK dropped: %lu\n"
  31147. + "TX total data packets %lu\n",
  31148. +// "TX beacon aborted: %lu\n",
  31149. + priv->stats.txviokint,
  31150. + priv->stats.txvierr,
  31151. + priv->stats.txvookint,
  31152. + priv->stats.txvoerr,
  31153. + priv->stats.txbeokint,
  31154. + priv->stats.txbeerr,
  31155. + priv->stats.txbkokint,
  31156. + priv->stats.txbkerr,
  31157. + priv->stats.txmanageokint,
  31158. + priv->stats.txmanageerr,
  31159. + priv->stats.txbeaconokint,
  31160. + priv->stats.txbeaconerr,
  31161. +// priv->stats.txhpokint,
  31162. +// priv->stats.txhperr,
  31163. + priv->stats.txresumed,
  31164. + netif_queue_stopped(dev),
  31165. + priv->stats.txoverflow,
  31166. +// priv->stats.txbeacon,
  31167. + atomic_read(&(priv->tx_pending[VI_PRIORITY])),
  31168. + atomic_read(&(priv->tx_pending[VO_PRIORITY])),
  31169. + atomic_read(&(priv->tx_pending[BE_PRIORITY])),
  31170. + atomic_read(&(priv->tx_pending[BK_PRIORITY])),
  31171. + atomic_read(&(priv->tx_pending[BEACON_PRIORITY])),
  31172. + atomic_read(&(priv->tx_pending[MANAGE_PRIORITY])),
  31173. +// read_nic_byte(dev, TXFIFOCOUNT),
  31174. + priv->stats.txvidrop,
  31175. + priv->stats.txvodrop,
  31176. + priv->stats.txbedrop,
  31177. + priv->stats.txbkdrop,
  31178. + priv->stats.txdatapkt
  31179. +// priv->stats.txbeaconerr
  31180. + );
  31181. +
  31182. + *eof = 1;
  31183. + return len;
  31184. +}
  31185. +
  31186. +
  31187. +
  31188. +static int proc_get_stats_rx(char *page, char **start,
  31189. + off_t offset, int count,
  31190. + int *eof, void *data)
  31191. +{
  31192. + struct net_device *dev = data;
  31193. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31194. +
  31195. + int len = 0;
  31196. +
  31197. + len += snprintf(page + len, count - len,
  31198. + "RX packets: %lu\n"
  31199. + "RX urb status error: %lu\n"
  31200. + "RX invalid urb error: %lu\n",
  31201. + priv->stats.rxok,
  31202. + priv->stats.rxstaterr,
  31203. + priv->stats.rxurberr);
  31204. +
  31205. + *eof = 1;
  31206. + return len;
  31207. +}
  31208. +
  31209. +#if WIRELESS_EXT < 17
  31210. +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
  31211. +{
  31212. + struct r8180_priv *priv = ieee80211_priv(dev);
  31213. +
  31214. + return &priv->wstats;
  31215. +}
  31216. +#endif
  31217. +
  31218. +void rtl8180_proc_module_init(void)
  31219. +{
  31220. + DMESG("Initializing proc filesystem");
  31221. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  31222. + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, proc_net);
  31223. +#else
  31224. + rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
  31225. +#endif
  31226. +}
  31227. +
  31228. +
  31229. +void rtl8180_proc_module_remove(void)
  31230. +{
  31231. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
  31232. + remove_proc_entry(RTL8187_MODULE_NAME, proc_net);
  31233. +#else
  31234. + remove_proc_entry(RTL8187_MODULE_NAME, init_net.proc_net);
  31235. +#endif
  31236. +}
  31237. +
  31238. +
  31239. +void rtl8180_proc_remove_one(struct net_device *dev)
  31240. +{
  31241. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31242. + if (priv->dir_dev) {
  31243. + // remove_proc_entry("stats-hw", priv->dir_dev);
  31244. + remove_proc_entry("stats-tx", priv->dir_dev);
  31245. + remove_proc_entry("stats-rx", priv->dir_dev);
  31246. + // remove_proc_entry("stats-ieee", priv->dir_dev);
  31247. + remove_proc_entry("stats-ap", priv->dir_dev);
  31248. + remove_proc_entry("registers", priv->dir_dev);
  31249. + remove_proc_entry("cck-registers",priv->dir_dev);
  31250. + remove_proc_entry("ofdm-registers",priv->dir_dev);
  31251. + remove_proc_entry(dev->name, rtl8180_proc);
  31252. + priv->dir_dev = NULL;
  31253. + }
  31254. +}
  31255. +
  31256. +
  31257. +void rtl8180_proc_init_one(struct net_device *dev)
  31258. +{
  31259. + struct proc_dir_entry *e;
  31260. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31261. + priv->dir_dev = create_proc_entry(dev->name,
  31262. + S_IFDIR | S_IRUGO | S_IXUGO,
  31263. + rtl8180_proc);
  31264. + if (!priv->dir_dev) {
  31265. + DMESGE("Unable to initialize /proc/net/rtl8187/%s\n",
  31266. + dev->name);
  31267. + return;
  31268. + }
  31269. + #if 0
  31270. + e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
  31271. + priv->dir_dev, proc_get_stats_hw, dev);
  31272. +
  31273. + if (!e) {
  31274. + DMESGE("Unable to initialize "
  31275. + "/proc/net/rtl8187/%s/stats-hw\n",
  31276. + dev->name);
  31277. + }
  31278. + #endif
  31279. + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
  31280. + priv->dir_dev, proc_get_stats_rx, dev);
  31281. +
  31282. + if (!e) {
  31283. + DMESGE("Unable to initialize "
  31284. + "/proc/net/rtl8187/%s/stats-rx\n",
  31285. + dev->name);
  31286. + }
  31287. +
  31288. +
  31289. + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
  31290. + priv->dir_dev, proc_get_stats_tx, dev);
  31291. +
  31292. + if (!e) {
  31293. + DMESGE("Unable to initialize "
  31294. + "/proc/net/rtl8187/%s/stats-tx\n",
  31295. + dev->name);
  31296. + }
  31297. + #if 0
  31298. + e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
  31299. + priv->dir_dev, proc_get_stats_ieee, dev);
  31300. +
  31301. + if (!e) {
  31302. + DMESGE("Unable to initialize "
  31303. + "/proc/net/rtl8187/%s/stats-ieee\n",
  31304. + dev->name);
  31305. + }
  31306. +
  31307. + #endif
  31308. +
  31309. + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
  31310. + priv->dir_dev, proc_get_stats_ap, dev);
  31311. +
  31312. + if (!e) {
  31313. + DMESGE("Unable to initialize "
  31314. + "/proc/net/rtl8187/%s/stats-ap\n",
  31315. + dev->name);
  31316. + }
  31317. +
  31318. + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
  31319. + priv->dir_dev, proc_get_registers, dev);
  31320. + if (!e) {
  31321. + DMESGE("Unable to initialize "
  31322. + "/proc/net/rtl8187/%s/registers\n",
  31323. + dev->name);
  31324. + }
  31325. +
  31326. + e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
  31327. + priv->dir_dev, proc_get_cck_reg, dev);
  31328. + if (!e) {
  31329. + DMESGE("Unable to initialize "
  31330. + "/proc/net/rtl8187/%s/cck-registers\n",
  31331. + dev->name);
  31332. + }
  31333. +
  31334. + e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
  31335. + priv->dir_dev, proc_get_ofdm_reg, dev);
  31336. + if (!e) {
  31337. + DMESGE("Unable to initialize "
  31338. + "/proc/net/rtl8187/%s/ofdm-registers\n",
  31339. + dev->name);
  31340. + }
  31341. +
  31342. +#ifdef _RTL8187_EXT_PATCH_
  31343. + if( priv->mshobj && priv->mshobj->ext_patch_create_proc )
  31344. + priv->mshobj->ext_patch_create_proc(priv);
  31345. +#endif
  31346. +
  31347. +}
  31348. +/****************************************************************************
  31349. + -----------------------------MISC STUFF-------------------------
  31350. +*****************************************************************************/
  31351. +
  31352. +/* this is only for debugging */
  31353. +void print_buffer(u32 *buffer, int len)
  31354. +{
  31355. + int i;
  31356. + u8 *buf =(u8*)buffer;
  31357. +
  31358. + printk("ASCII BUFFER DUMP (len: %x):\n",len);
  31359. +
  31360. + for(i=0;i<len;i++)
  31361. + printk("%c",buf[i]);
  31362. +
  31363. + printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
  31364. +
  31365. + for(i=0;i<len;i++)
  31366. + printk("%x",buf[i]);
  31367. +
  31368. + printk("\n");
  31369. +}
  31370. +
  31371. +short check_nic_enought_desc(struct net_device *dev, priority_t priority)
  31372. +{
  31373. + struct r8180_priv *priv = ieee80211_priv(dev);
  31374. + //int used = atomic_read((priority == NORM_PRIORITY) ?
  31375. + // &priv->tx_np_pending : &priv->tx_lp_pending);
  31376. + int used = atomic_read(&priv->tx_pending[priority]);
  31377. +
  31378. + return (used < MAX_TX_URB);
  31379. +}
  31380. +
  31381. +void tx_timeout(struct net_device *dev)
  31382. +{
  31383. + struct r8180_priv *priv = ieee80211_priv(dev);
  31384. + //rtl8180_commit(dev);
  31385. + printk("@@@@ Transmit timeout at %ld, latency %ld\n", jiffies,
  31386. + jiffies - dev->trans_start);
  31387. +
  31388. + printk("@@@@ netif_queue_stopped = %d\n", netif_queue_stopped(dev));
  31389. +
  31390. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  31391. + schedule_work(&priv->reset_wq);
  31392. +#else
  31393. + schedule_task(&priv->reset_wq);
  31394. +#endif
  31395. + //DMESG("TXTIMEOUT");
  31396. +}
  31397. +
  31398. +
  31399. +/* this is only for debug */
  31400. +void dump_eprom(struct net_device *dev)
  31401. +{
  31402. + int i;
  31403. + for(i=0; i<63; i++)
  31404. + DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
  31405. +}
  31406. +
  31407. +/* this is only for debug */
  31408. +void rtl8180_dump_reg(struct net_device *dev)
  31409. +{
  31410. + int i;
  31411. + int n;
  31412. + int max=0xff;
  31413. +
  31414. + DMESG("Dumping NIC register map");
  31415. +
  31416. + for(n=0;n<=max;)
  31417. + {
  31418. + printk( "\nD: %2x> ", n);
  31419. + for(i=0;i<16 && n<=max;i++,n++)
  31420. + printk("%2x ",read_nic_byte(dev,n));
  31421. + }
  31422. + printk("\n");
  31423. +}
  31424. +
  31425. +/****************************************************************************
  31426. + ------------------------------HW STUFF---------------------------
  31427. +*****************************************************************************/
  31428. +
  31429. +
  31430. +void rtl8180_irq_enable(struct net_device *dev)
  31431. +{
  31432. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31433. + //priv->irq_enabled = 1;
  31434. +
  31435. + //write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |
  31436. + // INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |
  31437. + // INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |
  31438. + // INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
  31439. +
  31440. + write_nic_word(dev,INTA_MASK, priv->irq_mask);
  31441. +}
  31442. +
  31443. +
  31444. +void rtl8180_irq_disable(struct net_device *dev)
  31445. +{
  31446. + write_nic_word(dev,INTA_MASK,0);
  31447. + force_pci_posting(dev);
  31448. +// priv->irq_enabled = 0;
  31449. +}
  31450. +
  31451. +
  31452. +void rtl8180_set_mode(struct net_device *dev,int mode)
  31453. +{
  31454. + u8 ecmd;
  31455. + ecmd=read_nic_byte(dev, EPROM_CMD);
  31456. + ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
  31457. + ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
  31458. + ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
  31459. + ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
  31460. + write_nic_byte(dev, EPROM_CMD, ecmd);
  31461. +}
  31462. +
  31463. +
  31464. +void rtl8180_update_msr(struct net_device *dev)
  31465. +{
  31466. + struct r8180_priv *priv = ieee80211_priv(dev);
  31467. + u8 msr;
  31468. +
  31469. + msr = read_nic_byte(dev, MSR);
  31470. + msr &= ~ MSR_LINK_MASK;
  31471. +
  31472. + /* do not change in link_state != WLAN_LINK_ASSOCIATED.
  31473. + * msr must be updated if the state is ASSOCIATING.
  31474. + * this is intentional and make sense for ad-hoc and
  31475. + * master (see the create BSS/IBSS func)
  31476. + */
  31477. + if (priv->ieee80211->state == IEEE80211_LINKED){
  31478. +
  31479. + if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
  31480. + msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
  31481. + else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
  31482. + msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
  31483. + else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
  31484. + msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
  31485. +
  31486. + }else
  31487. + msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
  31488. +
  31489. + write_nic_byte(dev, MSR, msr);
  31490. +}
  31491. +
  31492. +void rtl8180_set_chan(struct net_device *dev,short ch)
  31493. +{
  31494. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31495. + u32 tx;
  31496. +
  31497. + priv->chan=ch;
  31498. + #if 0
  31499. + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
  31500. + priv->ieee80211->iw_mode == IW_MODE_MASTER){
  31501. +
  31502. + priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
  31503. + priv->ieee80211->master_chan = ch;
  31504. + rtl8180_update_beacon_ch(dev);
  31505. + }
  31506. + #endif
  31507. +
  31508. + /* this hack should avoid frame TX during channel setting*/
  31509. + tx = read_nic_dword(dev,TX_CONF);
  31510. + tx &= ~TX_LOOPBACK_MASK;
  31511. +
  31512. +#ifndef LOOP_TEST
  31513. + write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
  31514. + priv->rf_set_chan(dev,priv->chan);
  31515. + //mdelay(10); //CPU occupany is too high. LZM 31/10/2008
  31516. + write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
  31517. +#endif
  31518. +}
  31519. +
  31520. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  31521. +void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs);
  31522. +#else
  31523. +void rtl8187_rx_isr(struct urb* rx_urb);
  31524. +#endif
  31525. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  31526. +void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs);
  31527. +#else
  31528. +void rtl8187_rx_manage_isr(struct urb* rx_urb);
  31529. +#endif
  31530. +
  31531. +
  31532. +
  31533. +void rtl8187_rx_urbsubmit(struct net_device *dev, struct urb* rx_urb)
  31534. +{
  31535. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31536. + int err;
  31537. +
  31538. + usb_fill_bulk_urb(rx_urb,priv->udev,
  31539. + usb_rcvbulkpipe(priv->udev,(NIC_8187 == priv->card_8187)?0x81:0x83),
  31540. + rx_urb->transfer_buffer,
  31541. + RX_URB_SIZE,
  31542. + rtl8187_rx_isr,
  31543. + dev);
  31544. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  31545. + err = usb_submit_urb(rx_urb, GFP_ATOMIC);
  31546. +#else
  31547. + err = usb_submit_urb(rx_urb);
  31548. +#endif
  31549. + if(err && err != -EPERM){
  31550. + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
  31551. + }
  31552. +}
  31553. +
  31554. +
  31555. +void rtl8187_rx_manage_urbsubmit(struct net_device *dev, struct urb* rx_urb)
  31556. +{
  31557. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31558. + int err;
  31559. +#ifdef THOMAS_BEACON
  31560. + usb_fill_bulk_urb(rx_urb,priv->udev,
  31561. + usb_rcvbulkpipe(priv->udev,0x09),
  31562. + rx_urb->transfer_buffer,
  31563. + rx_urb->transfer_buffer_length,
  31564. + rtl8187_rx_manage_isr, dev);
  31565. +#endif
  31566. +
  31567. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  31568. + err = usb_submit_urb(rx_urb, GFP_ATOMIC);
  31569. +#else
  31570. + err = usb_submit_urb(rx_urb);
  31571. +#endif
  31572. + if(err && err != -EPERM){
  31573. + DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
  31574. + }
  31575. +}
  31576. +
  31577. +
  31578. +
  31579. +void rtl8187_rx_initiate(struct net_device *dev)
  31580. +{
  31581. + int i;
  31582. + unsigned long flags;
  31583. + struct urb *purb;
  31584. +
  31585. + struct sk_buff *pskb;
  31586. +
  31587. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31588. +
  31589. + priv->tx_urb_index = 0;
  31590. +
  31591. + if ((!priv->rx_urb) || (!priv->pp_rxskb)) {
  31592. +
  31593. + DMESGE("Cannot intiate RX urb mechanism");
  31594. + return;
  31595. +
  31596. + }
  31597. +
  31598. + priv->rx_inx = 0;
  31599. +#ifdef THOMAS_TASKLET
  31600. + atomic_set(&priv->irt_counter,0);
  31601. +#endif
  31602. + for(i = 0;i < MAX_RX_URB; i++){
  31603. +
  31604. + purb = priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
  31605. +
  31606. + if(!priv->rx_urb[i])
  31607. + goto destroy;
  31608. +
  31609. + pskb = priv->pp_rxskb[i] = dev_alloc_skb (RX_URB_SIZE);
  31610. +
  31611. + if (pskb == NULL)
  31612. + goto destroy;
  31613. +
  31614. + purb->transfer_buffer_length = RX_URB_SIZE;
  31615. + purb->transfer_buffer = pskb->data;
  31616. + }
  31617. +
  31618. + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
  31619. +
  31620. + for(i=0;i<MAX_RX_URB;i++)
  31621. + rtl8187_rx_urbsubmit(dev,priv->rx_urb[i]);
  31622. +
  31623. + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
  31624. +
  31625. + return;
  31626. +
  31627. +destroy:
  31628. +
  31629. + for(i = 0; i < MAX_RX_URB; i++) {
  31630. +
  31631. + purb = priv->rx_urb[i];
  31632. +
  31633. + if (purb)
  31634. + usb_free_urb(purb);
  31635. +
  31636. + pskb = priv->pp_rxskb[i];
  31637. +
  31638. + if (pskb)
  31639. + dev_kfree_skb_any(pskb);
  31640. +
  31641. + }
  31642. +
  31643. + return;
  31644. +}
  31645. +
  31646. +
  31647. +void rtl8187_rx_manage_initiate(struct net_device *dev)
  31648. +{
  31649. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31650. + if(!priv->rx_urb)
  31651. + DMESGE("Cannot intiate RX urb mechanism");
  31652. +
  31653. + rtl8187_rx_manage_urbsubmit(dev,priv->rx_urb[MAX_RX_URB]);
  31654. +
  31655. +}
  31656. +
  31657. +
  31658. +void rtl8187_set_rxconf(struct net_device *dev)
  31659. +{
  31660. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31661. + u32 rxconf;
  31662. +
  31663. + rxconf=read_nic_dword(dev,RX_CONF);
  31664. + rxconf = rxconf &~ MAC_FILTER_MASK;
  31665. + rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
  31666. + rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
  31667. + rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
  31668. + rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
  31669. + //rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
  31670. +#ifdef SW_ANTE_DIVERSITY
  31671. + rxconf = rxconf | priv->EEPROMCSMethod;//for antenna
  31672. +#endif
  31673. +
  31674. + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
  31675. +
  31676. + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
  31677. + dev->flags & IFF_PROMISC){
  31678. + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
  31679. + } /*else if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
  31680. + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
  31681. + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
  31682. + }*/else{
  31683. + rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
  31684. + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
  31685. + }
  31686. +
  31687. +
  31688. + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
  31689. + rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
  31690. + rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
  31691. + }
  31692. +
  31693. + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
  31694. + rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
  31695. +
  31696. +
  31697. + rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
  31698. + rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
  31699. + rxconf = rxconf &~ MAX_RX_DMA_MASK;
  31700. + rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
  31701. +
  31702. + rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
  31703. + rxconf = rxconf | RCR_ONLYERLPKT;
  31704. +
  31705. + //rxconf = rxconf &~ RCR_CS_MASK;
  31706. + //rxconf = rxconf | (1<<RCR_CS_SHIFT);
  31707. +
  31708. + write_nic_dword(dev, RX_CONF, rxconf);
  31709. +
  31710. + #ifdef DEBUG_RX
  31711. + DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
  31712. + #endif
  31713. +}
  31714. +
  31715. +void rtl8180_rx_enable(struct net_device *dev)
  31716. +{
  31717. + u8 cmd;
  31718. +
  31719. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31720. +
  31721. + rtl8187_rx_initiate(dev);
  31722. + rtl8187_set_rxconf(dev);
  31723. +
  31724. + if(NIC_8187 == priv->card_8187) {
  31725. + cmd=read_nic_byte(dev,CMD);
  31726. + write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
  31727. + } else {
  31728. + //write_nic_dword(dev, RCR, priv->ReceiveConfig);
  31729. + }
  31730. +}
  31731. +
  31732. +
  31733. +void rtl8180_tx_enable(struct net_device *dev)
  31734. +{
  31735. + u8 cmd;
  31736. + u8 byte;
  31737. + u32 txconf = 0;
  31738. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31739. +
  31740. + if(NIC_8187B == priv->card_8187){
  31741. + write_nic_dword(dev, TCR, priv->TransmitConfig);
  31742. + byte = read_nic_byte(dev, MSR);
  31743. + byte |= MSR_LINK_ENEDCA;
  31744. + write_nic_byte(dev, MSR, byte);
  31745. +#ifdef LOOP_TEST
  31746. + txconf= read_nic_dword(dev,TX_CONF);
  31747. + txconf = txconf | (TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT);
  31748. + write_nic_dword(dev,TX_CONF,txconf);
  31749. +#endif
  31750. + } else {
  31751. + byte = read_nic_byte(dev,CW_CONF);
  31752. + byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
  31753. + byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
  31754. + write_nic_byte(dev, CW_CONF, byte);
  31755. +
  31756. + byte = read_nic_byte(dev, TX_AGC_CTL);
  31757. + byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
  31758. + byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
  31759. + byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
  31760. + write_nic_byte(dev, TX_AGC_CTL, byte);
  31761. +
  31762. + txconf= read_nic_dword(dev,TX_CONF);
  31763. +
  31764. +
  31765. + txconf = txconf &~ TX_LOOPBACK_MASK;
  31766. +
  31767. +#ifndef LOOP_TEST
  31768. + txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
  31769. +#else
  31770. + txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
  31771. +#endif
  31772. + txconf = txconf &~ TCR_SRL_MASK;
  31773. + txconf = txconf &~ TCR_LRL_MASK;
  31774. +
  31775. + txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
  31776. + txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
  31777. +
  31778. + txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
  31779. +
  31780. + txconf = txconf &~ TCR_MXDMA_MASK;
  31781. + txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
  31782. +
  31783. + txconf = txconf | TCR_DISReqQsize;
  31784. + txconf = txconf | TCR_DISCW;
  31785. + txconf = txconf &~ TCR_SWPLCPLEN;
  31786. +
  31787. + txconf=txconf | (1<<TX_NOICV_SHIFT);
  31788. +
  31789. + write_nic_dword(dev,TX_CONF,txconf);
  31790. +
  31791. +#ifdef DEBUG_TX
  31792. + DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
  31793. +#endif
  31794. +
  31795. + cmd=read_nic_byte(dev,CMD);
  31796. + write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
  31797. + }
  31798. +}
  31799. +
  31800. +#if 0
  31801. +void rtl8180_beacon_tx_enable(struct net_device *dev)
  31802. +{
  31803. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31804. + priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
  31805. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  31806. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  31807. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  31808. +}
  31809. +
  31810. +
  31811. +void rtl8180_
  31812. +_disable(struct net_device *dev)
  31813. +{
  31814. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31815. + priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
  31816. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  31817. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  31818. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  31819. +}
  31820. +
  31821. +#endif
  31822. +
  31823. +
  31824. +void rtl8180_rtx_disable(struct net_device *dev)
  31825. +{
  31826. + u8 cmd;
  31827. + int i;
  31828. + struct r8180_priv *priv = ieee80211_priv(dev);
  31829. +
  31830. + cmd=read_nic_byte(dev,CMD);
  31831. + write_nic_byte(dev, CMD, cmd &~ \
  31832. + ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
  31833. + force_pci_posting(dev);
  31834. + mdelay(10);
  31835. +
  31836. +#ifdef THOMAS_BEACON
  31837. + {
  31838. + int index = priv->rx_inx;//0
  31839. + i=0;
  31840. + if(priv->rx_urb){
  31841. + while(i<MAX_RX_URB){
  31842. + if(priv->rx_urb[index]){
  31843. + usb_kill_urb(priv->rx_urb[index]);
  31844. + }
  31845. + if( index == (MAX_RX_URB-1) )
  31846. + index=0;
  31847. + else
  31848. + index=index+1;
  31849. + i++;
  31850. + }
  31851. + if(priv->rx_urb[MAX_RX_URB])
  31852. + usb_kill_urb(priv->rx_urb[MAX_RX_URB]);
  31853. + }
  31854. + }
  31855. +#endif
  31856. +}
  31857. +
  31858. +
  31859. +int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
  31860. +{
  31861. + #if 0
  31862. + int i;
  31863. + u32 *tmp;
  31864. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  31865. +
  31866. + priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
  31867. + sizeof(u32)*8*count,
  31868. + &priv->txbeaconringdma);
  31869. + if (!priv->txbeaconring) return -1;
  31870. + for (tmp=priv->txbeaconring,i=0;i<count;i++){
  31871. + *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
  31872. + /*
  31873. + *(tmp+2) = (u32)dma_tmp;
  31874. + *(tmp+3) = bufsize;
  31875. + */
  31876. + if(i+1<count)
  31877. + *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
  31878. + else
  31879. + *(tmp+4) = (u32)priv->txbeaconringdma;
  31880. +
  31881. + tmp=tmp+8;
  31882. + }
  31883. + #endif
  31884. + return 0;
  31885. +}
  31886. +
  31887. +long NetgearSignalStrengthTranslate(long LastSS,long CurrSS)
  31888. +{
  31889. + long RetSS;
  31890. +
  31891. + // Step 1. Scale mapping.
  31892. + if(CurrSS >= 71 && CurrSS <= 100){
  31893. + RetSS = 90 + ((CurrSS - 70) / 3);
  31894. + }else if(CurrSS >= 41 && CurrSS <= 70){
  31895. + RetSS = 78 + ((CurrSS - 40) / 3);
  31896. + }else if(CurrSS >= 31 && CurrSS <= 40){
  31897. + RetSS = 66 + (CurrSS - 30);
  31898. + }else if(CurrSS >= 21 && CurrSS <= 30){
  31899. + RetSS = 54 + (CurrSS - 20);
  31900. + }else if(CurrSS >= 5 && CurrSS <= 20){
  31901. + RetSS = 42 + (((CurrSS - 5) * 2) / 3);
  31902. + }else if(CurrSS == 4){
  31903. + RetSS = 36;
  31904. + }else if(CurrSS == 3){
  31905. + RetSS = 27;
  31906. + }else if(CurrSS == 2){
  31907. + RetSS = 18;
  31908. + }else if(CurrSS == 1){
  31909. + RetSS = 9;
  31910. + }else{
  31911. + RetSS = CurrSS;
  31912. + }
  31913. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  31914. +
  31915. + // Step 2. Smoothing.
  31916. + if(LastSS > 0){
  31917. + RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
  31918. + }
  31919. + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  31920. +
  31921. + return RetSS;
  31922. +}
  31923. +
  31924. +extern long TranslateToDbm8187(u8 SignalStrengthIndex); // 0-100 index.
  31925. +//long TranslateToDbm8187(u8 SignalStrengthIndex) // 0-100 index.
  31926. +//{
  31927. + // long SignalPower; // in dBm.
  31928. +
  31929. + // Translate to dBm (x=0.5y-95).
  31930. + // SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
  31931. + // SignalPower -= 95;
  31932. +
  31933. + // return SignalPower;
  31934. +//}
  31935. +
  31936. +
  31937. +void rtl8180_reset(struct net_device *dev)
  31938. +{
  31939. +
  31940. + struct r8180_priv *priv = ieee80211_priv(dev);
  31941. + u8 cr;
  31942. + int i;
  31943. +
  31944. +
  31945. + /* make sure the analog power is on before
  31946. + * reset, otherwise reset may fail
  31947. + */
  31948. + if(NIC_8187 == priv->card_8187) {
  31949. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  31950. + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  31951. + rtl8180_irq_disable(dev);
  31952. + mdelay(200);
  31953. + write_nic_byte_E(dev,0x18,0x10);
  31954. + write_nic_byte_E(dev,0x18,0x11);
  31955. + write_nic_byte_E(dev,0x18,0x00);
  31956. + mdelay(200);
  31957. + }
  31958. +
  31959. +
  31960. + cr=read_nic_byte(dev,CMD);
  31961. + cr = cr & 2;
  31962. + cr = cr | (1<<CMD_RST_SHIFT);
  31963. + write_nic_byte(dev,CMD,cr);
  31964. +
  31965. + //lzm mod for up take too long time 20081201
  31966. + //force_pci_posting(dev);
  31967. + //mdelay(200);
  31968. + udelay(20);
  31969. +
  31970. + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
  31971. + DMESGW("Card reset timeout!");
  31972. +
  31973. + if(NIC_8187 == priv->card_8187) {
  31974. +
  31975. + //printk("This is RTL8187 Reset procedure\n");
  31976. + rtl8180_set_mode(dev,EPROM_CMD_LOAD);
  31977. + force_pci_posting(dev);
  31978. + mdelay(200);
  31979. +
  31980. + /* after the eeprom load cycle, make sure we have
  31981. + * correct anaparams
  31982. + */
  31983. + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
  31984. + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
  31985. + }
  31986. + else {
  31987. + //printk("This is RTL8187B Reset procedure\n");
  31988. + //test pending bug, john 20070815
  31989. + //initialize tx_pending
  31990. + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
  31991. +
  31992. + }
  31993. +
  31994. +}
  31995. +
  31996. +inline u16 ieeerate2rtlrate(int rate)
  31997. +{
  31998. + switch(rate){
  31999. + case 10:
  32000. + return 0;
  32001. + case 20:
  32002. + return 1;
  32003. + case 55:
  32004. + return 2;
  32005. + case 110:
  32006. + return 3;
  32007. + case 60:
  32008. + return 4;
  32009. + case 90:
  32010. + return 5;
  32011. + case 120:
  32012. + return 6;
  32013. + case 180:
  32014. + return 7;
  32015. + case 240:
  32016. + return 8;
  32017. + case 360:
  32018. + return 9;
  32019. + case 480:
  32020. + return 10;
  32021. + case 540:
  32022. + return 11;
  32023. + default:
  32024. + return 3;
  32025. +
  32026. + }
  32027. +}
  32028. +static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720};
  32029. +inline u16 rtl8180_rate2rate(short rate)
  32030. +{
  32031. + if (rate >12) return 10;
  32032. + return rtl_rate[rate];
  32033. +}
  32034. +
  32035. +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
  32036. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32037. +void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs)
  32038. +#else
  32039. +void rtl8187_rx_isr(struct urb* rx_urb)
  32040. +#endif
  32041. +{
  32042. + struct net_device *dev = (struct net_device*)rx_urb->context;
  32043. + struct r8180_priv *priv = ieee80211_priv(dev);
  32044. + priv->rxurb_task = rx_urb;
  32045. +
  32046. +
  32047. + //DMESGW("David: Rx tasklet start!");
  32048. +
  32049. +#ifdef THOMAS_TASKLET
  32050. + atomic_inc( &priv->irt_counter );
  32051. +
  32052. + //if( likely(priv->irt_counter_head+1 != priv->irt_counter_tail) ){
  32053. + // priv->irt_counter_head = (priv->irt_counter_head+1)&0xffff ;
  32054. + tasklet_schedule(&priv->irq_rx_tasklet);
  32055. + //} else{
  32056. + //DMESG("error: priv->irt_counter_head is going to pass through priv->irt_counter_tail\n");
  32057. + /*
  32058. + skb = priv->pp_rxskb[priv->rx_inx];
  32059. + dev_kfree_skb_any(skb);
  32060. +
  32061. + skb = dev_alloc_skb(RX_URB_SIZE);
  32062. + if (skb == NULL)
  32063. + panic("No Skb For RX!/n");
  32064. +
  32065. + rx_urb->transfer_buffer = skb->data;
  32066. +
  32067. + priv->pp_rxskb[priv->rx_inx] = skb;
  32068. + if(status == 0)
  32069. + rtl8187_rx_urbsubmit(dev,rx_urb);
  32070. + else {
  32071. + priv->pp_rxskb[priv->rx_inx] = NULL;
  32072. + dev_kfree_skb_any(skb);
  32073. + printk("RX process aborted due to explicit shutdown (%x) ", status);
  32074. + }
  32075. +
  32076. + if (*prx_inx == (MAX_RX_URB -1))
  32077. + *prx_inx = 0;
  32078. + else
  32079. + *prx_inx = *prx_inx + 1;
  32080. +
  32081. + */
  32082. + //}
  32083. +#endif
  32084. +
  32085. +}
  32086. +
  32087. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32088. +void rtl8187_rx_manage_isr(struct urb *rx_urb, struct pt_regs *regs)
  32089. +#else
  32090. +void rtl8187_rx_manage_isr(struct urb* rx_urb)
  32091. +#endif
  32092. +{
  32093. + struct net_device *dev = (struct net_device*)rx_urb->context;
  32094. + struct r8180_priv *priv = ieee80211_priv(dev);
  32095. + int status,cmd;
  32096. + struct sk_buff *skb;
  32097. + u32 *desc;
  32098. + int ret;
  32099. + unsigned long flag;
  32100. +
  32101. + //DMESG("RX %d ",rx_urb->status);
  32102. + status = rx_urb->status;
  32103. + if(status == 0){
  32104. +
  32105. + desc = (u32*)(rx_urb->transfer_buffer);
  32106. + cmd = (desc[0] >> 30) & 0x03;
  32107. + //printk(KERN_ALERT "buffersize = %d, length = %d, pipe = %p\n",
  32108. + //rx_urb->transfer_buffer_length, rx_urb->actual_length, rx_urb->pipe>>15);
  32109. +
  32110. + if(cmd == 0x00) {//beacon interrupt
  32111. + //send beacon packet
  32112. +
  32113. + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
  32114. + if(priv->flag_beacon == true){
  32115. + //printk("rtl8187_rx_manage_isr(): CMD_TYPE0_BCN_INTR\n");
  32116. +
  32117. + skb = ieee80211_get_beacon(priv->ieee80211);
  32118. + if(!skb){
  32119. + DMESG("not enought memory for allocating beacon");
  32120. + return;
  32121. + }
  32122. + //printk(KERN_WARNING "to send beacon packet through beacon endpoint!\n");
  32123. + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, BEACON_PRIORITY,
  32124. + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
  32125. +
  32126. + if( ret != 0 ){
  32127. + printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
  32128. + }
  32129. + dev_kfree_skb_any(skb);
  32130. +
  32131. + //} else {//0x00
  32132. + //{ log the device information
  32133. + // At present, It is not implemented just now.
  32134. + //}
  32135. + //}
  32136. +
  32137. + }
  32138. + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
  32139. + }
  32140. + else if(cmd == 0x01){
  32141. + //printk("rtl8187_rx_manage_isr(): CMD_TYPE1_TX_CLOSE\n");
  32142. + priv->CurrRetryCnt += (u16)desc[0]&0x000000ff;
  32143. + //printk("priv->CurrRetryCnt is %d\n",priv->CurrRetryCnt);
  32144. + }
  32145. + else
  32146. + printk("HalUsbInCommandComplete8187B(): unknown Type(%#X) !!!\n", cmd);
  32147. +
  32148. + }else{
  32149. + priv->stats.rxstaterr++;
  32150. + priv->ieee80211->stats.rx_errors++;
  32151. + }
  32152. +
  32153. +
  32154. + if( status == 0 )
  32155. + //if(status != -ENOENT)
  32156. + rtl8187_rx_manage_urbsubmit(dev, rx_urb);
  32157. + else
  32158. + ;//DMESG("Mangement RX process aborted due to explicit shutdown");
  32159. +}
  32160. +
  32161. +#if 0
  32162. +void rtl8180_tx_queues_stop(struct net_device *dev)
  32163. +{
  32164. + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  32165. + u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
  32166. + dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
  32167. + dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
  32168. + dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
  32169. +
  32170. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  32171. + write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
  32172. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  32173. +}
  32174. +#endif
  32175. +
  32176. +void rtl8180_data_hard_stop(struct net_device *dev)
  32177. +{
  32178. + //FIXME !!
  32179. + #if 0
  32180. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  32181. + priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
  32182. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  32183. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  32184. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  32185. + #endif
  32186. +}
  32187. +
  32188. +
  32189. +void rtl8180_data_hard_resume(struct net_device *dev)
  32190. +{
  32191. + // FIXME !!
  32192. + #if 0
  32193. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  32194. + priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
  32195. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  32196. + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
  32197. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  32198. + #endif
  32199. +}
  32200. +
  32201. +unsigned int PRI2EP[4] = {0x06,0x07,0x05,0x04};
  32202. +// this function TX data frames when the ieee80211 stack requires this.
  32203. +// It checks also if we need to stop the ieee tx queue, eventually do it
  32204. +void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
  32205. +{
  32206. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  32207. +
  32208. + short morefrag = 0;
  32209. + unsigned long flags;
  32210. + struct ieee80211_hdr *h = (struct ieee80211_hdr *) skb->data;
  32211. +
  32212. + unsigned char ep;
  32213. + short ret; //john
  32214. +
  32215. + if (le16_to_cpu(h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS)
  32216. + morefrag = 1;
  32217. + //DMESG("%x %x", h->frame_ctl, h->seq_ctl);
  32218. + /*
  32219. + * This function doesn't require lock because we make
  32220. + * sure it's called with the tx_lock already acquired.
  32221. + * this come from the kernel's hard_xmit callback (trought
  32222. + * the ieee stack, or from the try_wake_queue (again trought
  32223. + * the ieee stack.
  32224. + */
  32225. + spin_lock_irqsave(&priv->tx_lock,flags);
  32226. +
  32227. + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
  32228. + if((priv->ieee80211->bHwRadioOff)||(!priv->up))
  32229. + {
  32230. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  32231. +
  32232. + return;
  32233. + }
  32234. +
  32235. + if(NIC_8187B == priv->card_8187){
  32236. + ep = PRI2EP[skb->priority];
  32237. + } else {
  32238. + ep = LOW_PRIORITY;
  32239. + }
  32240. + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
  32241. + if (!check_nic_enought_desc(dev, ep)){
  32242. + DMESG("Error: no TX slot ");
  32243. + ieee80211_stop_queue(priv->ieee80211);
  32244. + }
  32245. +
  32246. +#ifdef LED_SHIN
  32247. + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_TX);
  32248. +#endif
  32249. +
  32250. + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, ep, morefrag,ieeerate2rtlrate(rate));
  32251. + if(ret!=0) DMESG("Error: rtl8180_tx failed in rtl8180_hard_data_xmit\n");//john
  32252. +
  32253. + priv->stats.txdatapkt++;
  32254. +
  32255. + //if (!check_nic_enought_desc(dev, PRI2EP[skb->priority])){
  32256. + if (!check_nic_enought_desc(dev, ep)){
  32257. + ieee80211_stop_queue(priv->ieee80211);
  32258. + }
  32259. +
  32260. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  32261. +
  32262. +}
  32263. +
  32264. +//This is a rough attempt to TX a frame
  32265. +//This is called by the ieee 80211 stack to TX management frames.
  32266. +//If the ring is full packet are dropped (for data frame the queue
  32267. +//is stopped before this can happen).
  32268. +
  32269. +int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
  32270. +{
  32271. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  32272. + struct ieee80211_device *ieee = priv->ieee80211;
  32273. + int ret;
  32274. + unsigned long flags;
  32275. + spin_lock_irqsave(&priv->tx_lock,flags);
  32276. +
  32277. + //lzm mod 20081128 for sometimes wlan down but it still have some pkt to tx
  32278. + if((priv->ieee80211->bHwRadioOff)||(!priv->up))
  32279. + {
  32280. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  32281. + return 0;
  32282. + }
  32283. +
  32284. + ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, MANAGE_PRIORITY, 0, ieeerate2rtlrate(ieee->basic_rate));
  32285. +
  32286. + priv->ieee80211->stats.tx_bytes+=skb->len;
  32287. + priv->ieee80211->stats.tx_packets++;
  32288. +
  32289. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  32290. +
  32291. + return ret;
  32292. +}
  32293. +
  32294. +
  32295. +#if 0
  32296. +// longpre 144+48 shortpre 72+24
  32297. +u16 rtl8180_len2duration(u32 len, short rate,short* ext)
  32298. +{
  32299. + u16 duration;
  32300. + u16 drift;
  32301. + *ext=0;
  32302. +
  32303. + switch(rate){
  32304. + case 0://1mbps
  32305. + *ext=0;
  32306. + duration = ((len+4)<<4) /0x2;
  32307. + drift = ((len+4)<<4) % 0x2;
  32308. + if(drift ==0 ) break;
  32309. + duration++;
  32310. + break;
  32311. +
  32312. + case 1://2mbps
  32313. + *ext=0;
  32314. + duration = ((len+4)<<4) /0x4;
  32315. + drift = ((len+4)<<4) % 0x4;
  32316. + if(drift ==0 ) break;
  32317. + duration++;
  32318. + break;
  32319. +
  32320. + case 2: //5.5mbps
  32321. + *ext=0;
  32322. + duration = ((len+4)<<4) /0xb;
  32323. + drift = ((len+4)<<4) % 0xb;
  32324. + if(drift ==0 )
  32325. + break;
  32326. + duration++;
  32327. + break;
  32328. +
  32329. + default:
  32330. + case 3://11mbps
  32331. + *ext=0;
  32332. + duration = ((len+4)<<4) /0x16;
  32333. + drift = ((len+4)<<4) % 0x16;
  32334. + if(drift ==0 )
  32335. + break;
  32336. + duration++;
  32337. + if(drift > 6)
  32338. + break;
  32339. + *ext=1;
  32340. + break;
  32341. + }
  32342. +
  32343. + return duration;
  32344. +}
  32345. +#endif
  32346. +
  32347. +void rtl8180_try_wake_queue(struct net_device *dev, int pri);
  32348. +
  32349. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32350. +void rtl8187_lptx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32351. +#else
  32352. +void rtl8187_lptx_isr(struct urb* tx_urb)
  32353. +#endif
  32354. +{
  32355. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32356. + struct r8180_priv *priv = ieee80211_priv(dev);
  32357. +
  32358. + if(tx_urb->status == 0){
  32359. + dev->trans_start = jiffies; //john
  32360. + priv->stats.txlpokint++;
  32361. + priv->txokbytestotal+=tx_urb->actual_length;
  32362. + }else{
  32363. + priv->stats.txlperr++;
  32364. + }
  32365. +
  32366. + kfree(tx_urb->transfer_buffer);
  32367. + usb_free_urb(tx_urb);
  32368. +
  32369. + if(atomic_read(&priv->tx_pending[LOW_PRIORITY]) >= 1)
  32370. + atomic_dec(&priv->tx_pending[LOW_PRIORITY]);
  32371. +
  32372. + rtl8180_try_wake_queue(dev,LOW_PRIORITY);
  32373. +}
  32374. +
  32375. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32376. +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32377. +#else
  32378. +void rtl8187_nptx_isr(struct urb* tx_urb)
  32379. +#endif
  32380. +{
  32381. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32382. + struct r8180_priv *priv = ieee80211_priv(dev);
  32383. +
  32384. + if(tx_urb->status == 0){
  32385. + dev->trans_start = jiffies; //john
  32386. + priv->stats.txnpokint++;
  32387. + }else{
  32388. + priv->stats.txnperr++;
  32389. + }
  32390. +
  32391. + kfree(tx_urb->transfer_buffer);
  32392. + usb_free_urb(tx_urb);
  32393. +
  32394. + if(atomic_read(&priv->tx_pending[NORM_PRIORITY]) >= 1)
  32395. + atomic_dec(&priv->tx_pending[NORM_PRIORITY]);
  32396. + //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
  32397. +}
  32398. +
  32399. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32400. +void rtl8187_votx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32401. +#else
  32402. +void rtl8187_votx_isr(struct urb* tx_urb)
  32403. +#endif
  32404. +{
  32405. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32406. + struct r8180_priv *priv = ieee80211_priv(dev);
  32407. +
  32408. + if(tx_urb->status == 0){
  32409. + dev->trans_start = jiffies; //john
  32410. + priv->stats.txvookint++;
  32411. + priv->txokbytestotal+=tx_urb->actual_length;
  32412. + }else{
  32413. + priv->stats.txvoerr++;
  32414. + }
  32415. +
  32416. + kfree(tx_urb->transfer_buffer);
  32417. + usb_free_urb(tx_urb);
  32418. +
  32419. + if(atomic_read(&priv->tx_pending[VO_PRIORITY]) >= 1)
  32420. + atomic_dec(&priv->tx_pending[VO_PRIORITY]);
  32421. + rtl8180_try_wake_queue(dev,VO_PRIORITY);
  32422. +}
  32423. +
  32424. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32425. +void rtl8187_vitx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32426. +#else
  32427. +void rtl8187_vitx_isr(struct urb* tx_urb)
  32428. +#endif
  32429. +{
  32430. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32431. + struct r8180_priv *priv = ieee80211_priv(dev);
  32432. +
  32433. + if(tx_urb->status == 0){
  32434. + dev->trans_start = jiffies; //john
  32435. + priv->stats.txviokint++;
  32436. + priv->txokbytestotal+=tx_urb->actual_length;
  32437. + }else{
  32438. + priv->stats.txvierr++;
  32439. + }
  32440. +
  32441. + kfree(tx_urb->transfer_buffer);
  32442. + usb_free_urb(tx_urb);
  32443. +
  32444. + if(atomic_read(&priv->tx_pending[VI_PRIORITY]) >= 1)
  32445. + atomic_dec(&priv->tx_pending[VI_PRIORITY]);
  32446. + rtl8180_try_wake_queue(dev,VI_PRIORITY);
  32447. +}
  32448. +
  32449. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32450. +void rtl8187_betx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32451. +#else
  32452. +void rtl8187_betx_isr(struct urb* tx_urb)
  32453. +#endif
  32454. +{
  32455. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32456. + struct r8180_priv *priv = ieee80211_priv(dev);
  32457. +
  32458. + if(tx_urb->status == 0){
  32459. + dev->trans_start = jiffies; //john
  32460. + priv->stats.txbeokint++;
  32461. + priv->txokbytestotal+=tx_urb->actual_length;
  32462. + }else{
  32463. + priv->stats.txbeerr++;
  32464. + }
  32465. +
  32466. + kfree(tx_urb->transfer_buffer);
  32467. + usb_free_urb(tx_urb);
  32468. +
  32469. + if(atomic_read(&priv->tx_pending[BE_PRIORITY]) >= 1)
  32470. + atomic_dec(&priv->tx_pending[BE_PRIORITY]);
  32471. + rtl8180_try_wake_queue(dev, BE_PRIORITY);
  32472. +}
  32473. +
  32474. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32475. +void rtl8187_bktx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32476. +#else
  32477. +void rtl8187_bktx_isr(struct urb* tx_urb)
  32478. +#endif
  32479. +{
  32480. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32481. + struct r8180_priv *priv = ieee80211_priv(dev);
  32482. +
  32483. + if(tx_urb->status == 0){
  32484. + dev->trans_start = jiffies; //john
  32485. + priv->stats.txbkokint++;
  32486. + }else{
  32487. + priv->stats.txbkerr++;
  32488. + }
  32489. +
  32490. + kfree(tx_urb->transfer_buffer);
  32491. + usb_free_urb(tx_urb);
  32492. +
  32493. + if(atomic_read(&priv->tx_pending[BK_PRIORITY]) >= 1)
  32494. + atomic_dec(&priv->tx_pending[BK_PRIORITY]);
  32495. + rtl8180_try_wake_queue(dev,BK_PRIORITY);
  32496. +}
  32497. +
  32498. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32499. +void rtl8187_beacontx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32500. +#else
  32501. +void rtl8187_beacontx_isr(struct urb* tx_urb)
  32502. +#endif
  32503. +{
  32504. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32505. + struct r8180_priv *priv = ieee80211_priv(dev);
  32506. +
  32507. + if(tx_urb->status == 0){
  32508. + dev->trans_start = jiffies; //john
  32509. + priv->stats.txbeaconokint++;
  32510. + priv->txokbytestotal+=tx_urb->actual_length;
  32511. + }else{
  32512. + priv->stats.txbeaconerr++;
  32513. + }
  32514. +
  32515. + kfree(tx_urb->transfer_buffer);
  32516. + usb_free_urb(tx_urb);
  32517. +
  32518. + if(atomic_read(&priv->tx_pending[BEACON_PRIORITY]) >= 1)
  32519. + atomic_dec(&priv->tx_pending[BEACON_PRIORITY]);
  32520. + //rtl8180_try_wake_queue(dev,BEACON_PRIORITY);
  32521. +}
  32522. +
  32523. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  32524. +void rtl8187_managetx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32525. +#else
  32526. +void rtl8187_managetx_isr(struct urb* tx_urb)
  32527. +#endif
  32528. +{
  32529. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32530. + struct r8180_priv *priv = ieee80211_priv(dev);
  32531. +
  32532. + if(tx_urb->status == 0){
  32533. + dev->trans_start = jiffies; //john
  32534. + priv->stats.txmanageokint++;
  32535. + priv->txokbytestotal+=tx_urb->actual_length;
  32536. + }else{
  32537. + priv->stats.txmanageerr++;
  32538. + }
  32539. +
  32540. + kfree(tx_urb->transfer_buffer);
  32541. + usb_free_urb(tx_urb);
  32542. +
  32543. + if(atomic_read(&priv->tx_pending[MANAGE_PRIORITY]) >= 1)
  32544. + atomic_dec(&priv->tx_pending[MANAGE_PRIORITY]);
  32545. +// rtl8180_try_wake_queue(dev,MANAGE_PRIORITY);
  32546. +}
  32547. +
  32548. +void rtl8187_beacon_stop(struct net_device *dev)
  32549. +{
  32550. + u8 msr, msrm, msr2;
  32551. + struct r8180_priv *priv = ieee80211_priv(dev);
  32552. + unsigned long flag;
  32553. + msr = read_nic_byte(dev, MSR);
  32554. + msrm = msr & MSR_LINK_MASK;
  32555. + msr2 = msr & ~MSR_LINK_MASK;
  32556. + if(NIC_8187B == priv->card_8187) {
  32557. + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
  32558. + priv->flag_beacon = false;
  32559. + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
  32560. + }
  32561. + if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
  32562. + (msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
  32563. + write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
  32564. + write_nic_byte(dev, MSR, msr);
  32565. + }
  32566. +}
  32567. +
  32568. +
  32569. +void rtl8187_net_update(struct net_device *dev)
  32570. +{
  32571. +
  32572. + struct r8180_priv *priv = ieee80211_priv(dev);
  32573. + struct ieee80211_network *net;
  32574. + net = & priv->ieee80211->current_network;
  32575. +
  32576. +
  32577. + write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
  32578. + write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
  32579. +
  32580. + rtl8180_update_msr(dev);
  32581. +
  32582. + //rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  32583. + write_nic_word(dev, AtimWnd, 2);
  32584. + write_nic_word(dev, AtimtrItv, 100);
  32585. + write_nic_word(dev, BEACON_INTERVAL, net->beacon_interval);
  32586. + //write_nic_word(dev, BcnIntTime, 100);
  32587. + write_nic_word(dev, BcnIntTime, 0x3FF);
  32588. +
  32589. +
  32590. +}
  32591. +
  32592. +void rtl8187_beacon_tx(struct net_device *dev)
  32593. +{
  32594. + struct r8180_priv *priv = ieee80211_priv(dev);
  32595. + struct sk_buff *skb;
  32596. + int i = 0;
  32597. + u8 cr;
  32598. + unsigned long flag;
  32599. + rtl8187_net_update(dev);
  32600. +
  32601. + if(NIC_8187B == priv->card_8187) {
  32602. + //Cause TSF timer of MAC reset to 0
  32603. + cr=read_nic_byte(dev,CMD);
  32604. + cr = cr | (1<<CMD_RST_SHIFT);
  32605. + write_nic_byte(dev,CMD,cr);
  32606. +
  32607. + //lzm mod 20081201
  32608. + //mdelay(200);
  32609. + mdelay(20);
  32610. +
  32611. + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
  32612. + DMESGW("Card reset timeout for ad-hoc!");
  32613. + else
  32614. + DMESG("Card successfully reset for ad-hoc");
  32615. +
  32616. + write_nic_byte(dev,CMD, (read_nic_byte(dev,CMD)|CR_RE|CR_TE));
  32617. + spin_lock_irqsave(&priv->ieee80211->beaconflag_lock,flag);
  32618. + priv->flag_beacon = true;
  32619. + spin_unlock_irqrestore(&priv->ieee80211->beaconflag_lock,flag);
  32620. +
  32621. + //rtl8187_rx_manage_initiate(dev);
  32622. + } else {
  32623. + printk(KERN_WARNING "get the beacon!\n");
  32624. + skb = ieee80211_get_beacon(priv->ieee80211);
  32625. + if(!skb){
  32626. + DMESG("not enought memory for allocating beacon");
  32627. + return;
  32628. + }
  32629. +
  32630. + write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
  32631. +
  32632. + i=0;
  32633. + //while(!read_nic_byte(dev,BQREQ & (1<<7)))
  32634. + while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
  32635. + {
  32636. + msleep_interruptible_rtl(HZ/2);
  32637. + if(i++ > 10){
  32638. + DMESGW("get stuck to wait HW beacon to be ready");
  32639. + return ;
  32640. + }
  32641. + }
  32642. + //tx
  32643. + rtl8180_tx(dev, (u32*)skb->data, skb->len, NORM_PRIORITY,
  32644. + 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
  32645. + if(skb)
  32646. + dev_kfree_skb_any(skb);
  32647. + }
  32648. +}
  32649. +
  32650. +#if 0
  32651. +void rtl8187_nptx_isr(struct urb *tx_urb, struct pt_regs *regs)
  32652. +{
  32653. + struct net_device *dev = (struct net_device*)tx_urb->context;
  32654. + struct r8180_priv *priv = ieee80211_priv(dev);
  32655. +
  32656. + if(tx_urb->status == 0)
  32657. + priv->stats.txnpokint++;
  32658. + else
  32659. + priv->stats.txnperr++;
  32660. + kfree(tx_urb->transfer_buffer);
  32661. + usb_free_urb(tx_urb);
  32662. + atomic_dec(&priv->tx_np_pending);
  32663. + //rtl8180_try_wake_queue(dev,NORM_PRIORITY);
  32664. +}
  32665. +#endif
  32666. +inline u8 rtl8180_IsWirelessBMode(u16 rate)
  32667. +{
  32668. + if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
  32669. + return 1;
  32670. + else return 0;
  32671. +}
  32672. +
  32673. +u16 N_DBPSOfRate(u16 DataRate);
  32674. +
  32675. +u16 ComputeTxTime(
  32676. + u16 FrameLength,
  32677. + u16 DataRate,
  32678. + u8 bManagementFrame,
  32679. + u8 bShortPreamble
  32680. + )
  32681. +{
  32682. + u16 FrameTime;
  32683. + u16 N_DBPS;
  32684. + u16 Ceiling;
  32685. +
  32686. + if( rtl8180_IsWirelessBMode(DataRate) )
  32687. + {
  32688. + if( bManagementFrame || !bShortPreamble || DataRate == 10 ){ // long preamble
  32689. + FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
  32690. + }else{ // Short preamble
  32691. + FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
  32692. + }
  32693. + if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
  32694. + FrameTime ++;
  32695. + } else { //802.11g DSSS-OFDM PLCP length field calculation.
  32696. + N_DBPS = N_DBPSOfRate(DataRate);
  32697. + Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
  32698. + + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
  32699. + FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
  32700. + }
  32701. + return FrameTime;
  32702. +}
  32703. +
  32704. +u16 N_DBPSOfRate(u16 DataRate)
  32705. +{
  32706. + u16 N_DBPS = 24;
  32707. +
  32708. + switch(DataRate)
  32709. + {
  32710. + case 60:
  32711. + N_DBPS = 24;
  32712. + break;
  32713. +
  32714. + case 90:
  32715. + N_DBPS = 36;
  32716. + break;
  32717. +
  32718. + case 120:
  32719. + N_DBPS = 48;
  32720. + break;
  32721. +
  32722. + case 180:
  32723. + N_DBPS = 72;
  32724. + break;
  32725. +
  32726. + case 240:
  32727. + N_DBPS = 96;
  32728. + break;
  32729. +
  32730. + case 360:
  32731. + N_DBPS = 144;
  32732. + break;
  32733. +
  32734. + case 480:
  32735. + N_DBPS = 192;
  32736. + break;
  32737. +
  32738. + case 540:
  32739. + N_DBPS = 216;
  32740. + break;
  32741. +
  32742. + default:
  32743. + break;
  32744. + }
  32745. +
  32746. + return N_DBPS;
  32747. +}
  32748. +// NOte!!!
  32749. +// the rate filled in is the rtl_rate.
  32750. +// while the priv->ieee80211->basic_rate,used in the following code is ieee80211 rate.
  32751. +
  32752. +#ifdef JUST_FOR_87SEMESH
  32753. +#define ActionHeadLen 30
  32754. +#endif
  32755. +#define sCrcLng 4
  32756. +#define sAckCtsLng 112 // bits in ACK and CTS frames
  32757. +short rtl8180_tx(struct net_device *dev, u32* txbuf, int len, priority_t priority,
  32758. + short morefrag, short rate)
  32759. +{
  32760. + u32 *tx;
  32761. + int pend ;
  32762. + int status;
  32763. + struct urb *tx_urb;
  32764. + int urb_len;
  32765. + struct r8180_priv *priv = ieee80211_priv(dev);
  32766. + struct ieee80211_hdr_3addr_QOS *frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
  32767. + struct ieee80211_device *ieee;//added for descriptor
  32768. + u8 dest[ETH_ALEN];
  32769. +
  32770. + bool bUseShortPreamble = false;
  32771. + bool bCTSEnable = false;
  32772. + bool bRTSEnable = false;
  32773. + u16 Duration = 0;
  32774. + u16 RtsDur = 0;
  32775. + u16 ThisFrameTime = 0;
  32776. + u16 TxDescDuration = 0;
  32777. +
  32778. + ieee = priv->ieee80211;
  32779. +#if 0
  32780. +//{added by david for filter the packet listed in the filter table
  32781. +#ifdef _RTL8187_EXT_PATCH_
  32782. + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_acl_query))
  32783. + {
  32784. + if(!ieee->ext_patch_ieee80211_acl_query(ieee, frag_hdr->addr1)) {
  32785. + return 0;
  32786. + }
  32787. + }
  32788. +#endif
  32789. +//}
  32790. +#endif
  32791. +
  32792. +#ifdef JUST_FOR_87SEMESH
  32793. +//#ifdef Lawrence_Mesh
  32794. + u8* meshtype = (u8*)txbuf;
  32795. + if(*meshtype == 0xA8)
  32796. + {
  32797. + //overflow??
  32798. + //memcpy(meshtype+ActionHeadLen+2,meshtype+ActionHeadLen,Len-ActionHeadLen);
  32799. + //memcpy(meshtype+ActionHeadLen,0,2);
  32800. + u8 actionframe[256];
  32801. + memset(actionframe,0,256);
  32802. + memcpy(actionframe,meshtype,ActionHeadLen);
  32803. + memcpy(actionframe+ActionHeadLen+2,meshtype+ActionHeadLen,len-ActionHeadLen);
  32804. + txbuf = (u32*)actionframe;
  32805. + len=len+2;
  32806. + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)txbuf;
  32807. + }
  32808. +#endif
  32809. +
  32810. + //pend = atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
  32811. + pend = atomic_read(&priv->tx_pending[priority]);
  32812. + /* we are locked here so the two atomic_read and inc are executed without interleaves */
  32813. + if( pend > MAX_TX_URB){
  32814. + if(NIC_8187 == priv->card_8187) {
  32815. + if(priority == NORM_PRIORITY)
  32816. + priv->stats.txnpdrop++;
  32817. + else
  32818. + priv->stats.txlpdrop++;
  32819. +
  32820. + } else {
  32821. + switch (priority) {
  32822. + case VO_PRIORITY:
  32823. + priv->stats.txvodrop++;
  32824. + break;
  32825. + case VI_PRIORITY:
  32826. + priv->stats.txvidrop++;
  32827. + break;
  32828. + case BE_PRIORITY:
  32829. + priv->stats.txbedrop++;
  32830. + break;
  32831. + case MANAGE_PRIORITY: //lzm for MANAGE_PRIORITY pending
  32832. + if(priv->commit == 0)
  32833. + {
  32834. + priv->commit = 1;
  32835. + printk(KERN_INFO "manage pkt pending will commit now....\n");
  32836. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  32837. + schedule_work(&priv->reset_wq);
  32838. +#else
  32839. + schedule_task(&priv->reset_wq);
  32840. +#endif
  32841. + }
  32842. + break;
  32843. + default://BK_PRIORITY
  32844. + priv->stats.txbkdrop++;
  32845. + break;
  32846. + }
  32847. + }
  32848. + //printk(KERN_INFO "tx_pending: %d > MAX_TX_URB\n", priority);
  32849. + return -1;
  32850. + }
  32851. +
  32852. + urb_len = len + ((NIC_8187 == priv->card_8187)?(4*3):(4*8));
  32853. + if((0 == (urb_len&63))||(0 == (urb_len&511))) {
  32854. + urb_len += 1;
  32855. + }
  32856. +
  32857. + tx = kmalloc(urb_len, GFP_ATOMIC);
  32858. + if(!tx) return -ENOMEM;
  32859. + memset(tx, 0, sizeof(u32) * 8);
  32860. +
  32861. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  32862. + tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
  32863. +#else
  32864. + tx_urb = usb_alloc_urb(0);
  32865. +#endif
  32866. +
  32867. + if(!tx_urb){
  32868. + kfree(tx);
  32869. + return -ENOMEM;
  32870. + }
  32871. +
  32872. + // Check multicast/broadcast
  32873. + if (ieee->iw_mode == IW_MODE_INFRA) {
  32874. + /* To DS: Addr1 = BSSID, Addr2 = SA,
  32875. + Addr3 = DA */
  32876. + //memcpy(&dest, frag_hdr->addr3, ETH_ALEN);
  32877. + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
  32878. + } else if (ieee->iw_mode == IW_MODE_ADHOC) {
  32879. + /* not From/To DS: Addr1 = DA, Addr2 = SA,
  32880. + Addr3 = BSSID */
  32881. + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
  32882. + }
  32883. +
  32884. + if (is_multicast_ether_addr(dest) ||is_broadcast_ether_addr(dest))
  32885. + {
  32886. + Duration = 0;
  32887. + RtsDur = 0;
  32888. + bRTSEnable = false;
  32889. + bCTSEnable = false;
  32890. +
  32891. + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
  32892. + TxDescDuration = ThisFrameTime;
  32893. + } else {// Unicast packet
  32894. + //u8 AckRate;
  32895. + u16 AckTime;
  32896. +
  32897. + // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
  32898. + //AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) );
  32899. + // Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko.
  32900. + //AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE);
  32901. + //For simplicity, just use the 1M basic rate
  32902. + AckTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
  32903. + //AckTime = ComputeTxTime(14, 2,false, false); // AckCTSLng = 14 use 1M bps send
  32904. +
  32905. + if ( ((len + sCrcLng) > priv->rts) && priv->rts ){ // RTS/CTS.
  32906. + u16 RtsTime, CtsTime;
  32907. + //u16 CtsRate;
  32908. + bRTSEnable = true;
  32909. + bCTSEnable = false;
  32910. +
  32911. + // Rate and time required for RTS.
  32912. + RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, false, false);
  32913. + // Rate and time required for CTS.
  32914. + CtsTime = ComputeTxTime(14, 10,false, false); // AckCTSLng = 14 use 1M bps send
  32915. +
  32916. + // Figure out time required to transmit this frame.
  32917. + ThisFrameTime = ComputeTxTime(len + sCrcLng,
  32918. + rtl8180_rate2rate(rate),
  32919. + false,
  32920. + bUseShortPreamble);
  32921. +
  32922. + // RTS-CTS-ThisFrame-ACK.
  32923. + RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime;
  32924. +
  32925. + TxDescDuration = RtsTime + RtsDur;
  32926. + }else {// Normal case.
  32927. + bCTSEnable = false;
  32928. + bRTSEnable = false;
  32929. + RtsDur = 0;
  32930. +
  32931. + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), false, bUseShortPreamble);
  32932. + TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
  32933. + }
  32934. +
  32935. + if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment
  32936. + // ThisFrame-ACK.
  32937. + Duration = aSifsTime + AckTime;
  32938. + } else { // One or more fragments remained.
  32939. + u16 NextFragTime;
  32940. + NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet
  32941. + rtl8180_rate2rate(rate),
  32942. + false, bUseShortPreamble );
  32943. +
  32944. + //ThisFrag-ACk-NextFrag-ACK.
  32945. + Duration = NextFragTime + 3*aSifsTime + 2*AckTime;
  32946. + }
  32947. +
  32948. + } // End of Unicast packet
  32949. +
  32950. +
  32951. + //fill the tx desriptor
  32952. + tx[0] |= len & 0xfff;
  32953. +#ifdef JOHN_HWSEC
  32954. + if(frag_hdr->frame_ctl & IEEE80211_FCTL_WEP ){
  32955. + tx[0] &= 0xffff7fff;
  32956. + //group key may be different from pairwise key
  32957. + if( frag_hdr->addr1[0]==0xff &&
  32958. + frag_hdr->addr1[0]==0xff &&
  32959. + frag_hdr->addr1[0]==0xff &&
  32960. + frag_hdr->addr1[0]==0xff &&
  32961. + frag_hdr->addr1[0]==0xff &&
  32962. + frag_hdr->addr1[0]==0xff ){
  32963. + if(ieee->broadcast_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//ccmp
  32964. + else tx[7] |= 0x1;//wep and tkip
  32965. + }
  32966. + else {
  32967. + if(ieee->pairwise_key_type == KEY_TYPE_CCMP) tx[7] |= 0x2;//CCMP
  32968. + else tx[7] |= 0x1;//WEP and TKIP
  32969. + }
  32970. + }
  32971. + else
  32972. +#endif /*JOHN_HWSEC*/
  32973. +
  32974. + tx[0] |= (1<<15);
  32975. +
  32976. + if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE){
  32977. + if (priv->plcp_preamble_mode==1 && rate!=0) { // short mode now, not long!
  32978. + tx[0] |= (1<<16);
  32979. + } // enable short preamble mode.
  32980. + }
  32981. +
  32982. + if(morefrag) tx[0] |= (1<<17);
  32983. + //printk(KERN_WARNING "rtl_rate = %d\n", rate);
  32984. + tx[0] |= (rate << 24); //TX rate
  32985. + frag_hdr->duration_id = Duration;
  32986. +
  32987. + if(NIC_8187B == priv->card_8187) {
  32988. + if(bCTSEnable) {
  32989. + tx[0] |= (1<<18);
  32990. + }
  32991. +
  32992. + if(bRTSEnable) //rts enable
  32993. + {
  32994. + tx[0] |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE
  32995. + tx[0] |= (1<<23);//rts enable
  32996. + tx[1] |= RtsDur;//RTS Duration
  32997. + }
  32998. + tx[3] |= (TxDescDuration<<16); //DURATION
  32999. + if( WLAN_FC_GET_STYPE(le16_to_cpu(frag_hdr->frame_ctl)) == IEEE80211_STYPE_PROBE_RESP )
  33000. + tx[5] |= (1<<8);//(priv->retry_data<<8); //retry lim ;
  33001. + else
  33002. + tx[5] |= (11<<8);//(priv->retry_data<<8); //retry lim ;
  33003. +
  33004. + //frag_hdr->duration_id = Duration;
  33005. + memcpy(tx+8,txbuf,len);
  33006. + } else {
  33007. + if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
  33008. + tx[0] |= (1<<23); //enalbe RTS function
  33009. + tx[1] |= RtsDur; //Need to edit here! ----hikaru
  33010. + }
  33011. + else {
  33012. + tx[1]=0;
  33013. + }
  33014. + tx[0] |= (ieeerate2rtlrate(priv->ieee80211->basic_rate) << 19); /* RTS RATE - should be basic rate */
  33015. +
  33016. + tx[2] = 3; // CW min
  33017. + tx[2] |= (7<<4); //CW max
  33018. + tx[2] |= (11<<8);//(priv->retry_data<<8); //retry lim
  33019. +
  33020. + // printk("%x\n%x\n",tx[0],tx[1]);
  33021. +
  33022. +#ifdef DUMP_TX
  33023. + int i;
  33024. + printk("<Tx pkt>--rate %x---",rate);
  33025. + for (i = 0; i < (len + 3); i++)
  33026. + printk("%2x", ((u8*)tx)[i]);
  33027. + printk("---------------\n");
  33028. +#endif
  33029. + memcpy(tx+3,txbuf,len);
  33030. + }
  33031. +
  33032. +#ifdef JOHN_DUMP_TXDESC
  33033. + int i;
  33034. + printk("<Tx descriptor>--rate %x---",rate);
  33035. + for (i = 0; i < 8; i++)
  33036. + printk("%8x ", tx[i]);
  33037. + printk("\n");
  33038. +#endif
  33039. +#ifdef JOHN_DUMP_TXPKT
  33040. + {
  33041. + int j;
  33042. + printk("\n---------------------------------------------------------------------\n");
  33043. + printk("<Tx packet>--rate %x--urb_len in decimal %d",rate, urb_len);
  33044. + for (j = 32; j < (urb_len); j++){
  33045. + if( ( (j-32)%24 )==0 ) printk("\n");
  33046. + printk("%2x ", ((u8*)tx)[j]);
  33047. + }
  33048. + printk("\n---------------------------------------------------------------------\n");
  33049. +
  33050. + }
  33051. +#endif
  33052. +
  33053. + if(NIC_8187 == priv->card_8187) {
  33054. + usb_fill_bulk_urb(tx_urb,priv->udev,
  33055. + usb_sndbulkpipe(priv->udev,priority), tx,
  33056. + urb_len, (priority == LOW_PRIORITY)?rtl8187_lptx_isr:rtl8187_nptx_isr, dev);
  33057. +
  33058. + } else {
  33059. + //printk(KERN_WARNING "Tx packet use by submit urb!\n");
  33060. + /* FIXME check what EP is for low/norm PRI */
  33061. + usb_fill_bulk_urb(tx_urb,priv->udev,
  33062. + usb_sndbulkpipe(priv->udev,priority), tx,
  33063. + urb_len, TXISR_SELECT(priority), dev);
  33064. + }
  33065. +
  33066. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  33067. + status = usb_submit_urb(tx_urb, GFP_ATOMIC);
  33068. +#else
  33069. + status = usb_submit_urb(tx_urb);
  33070. +#endif
  33071. +
  33072. + if (!status){
  33073. + //atomic_inc((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending);
  33074. + atomic_inc(&priv->tx_pending[priority]);
  33075. + dev->trans_start = jiffies;
  33076. + //printk("=====> tx_pending[%d]=%d\n", priority, atomic_read(&priv->tx_pending[priority]));
  33077. + return 0;
  33078. + }else{
  33079. + DMESGE("Error TX URB %d, error pending %d",
  33080. + //atomic_read((priority == NORM_PRIORITY)? &priv->tx_np_pending : &priv->tx_lp_pending),
  33081. + atomic_read(&priv->tx_pending[priority]),
  33082. + status);
  33083. + return -1;
  33084. + }
  33085. +}
  33086. +
  33087. + short rtl8187_usb_initendpoints(struct net_device *dev)
  33088. +{
  33089. + struct r8180_priv *priv = ieee80211_priv(dev);
  33090. +
  33091. + priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL);
  33092. +
  33093. + memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB);
  33094. +
  33095. +#ifdef JACKSON_NEW_RX
  33096. + priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL);
  33097. + if (priv->pp_rxskb == NULL)
  33098. + goto destroy;
  33099. +
  33100. + memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB);
  33101. +#endif
  33102. +#ifdef THOMAS_BEACON
  33103. + {
  33104. + int align;
  33105. + unsigned long oldaddr,newaddr; //lzm mod for 64bit cpu crash 20081107
  33106. + priv->rx_urb[MAX_RX_URB] = usb_alloc_urb(0, GFP_KERNEL);
  33107. + priv->oldaddr = kmalloc(16, GFP_KERNEL);
  33108. + oldaddr = (unsigned long)priv->oldaddr;
  33109. + align = oldaddr&3;
  33110. + if(align != 0 ){
  33111. + newaddr = oldaddr + 4 - align;
  33112. + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16-4+align;
  33113. + }
  33114. + else{
  33115. + newaddr = oldaddr;
  33116. + priv->rx_urb[MAX_RX_URB]->transfer_buffer_length = 16;
  33117. + }
  33118. + priv->rx_urb[MAX_RX_URB]->transfer_buffer = (u32*)newaddr;
  33119. + }
  33120. +#endif
  33121. +
  33122. +
  33123. + goto _middle;
  33124. +
  33125. +
  33126. +destroy:
  33127. +
  33128. +#ifdef JACKSON_NEW_RX
  33129. + if (priv->pp_rxskb) {
  33130. + kfree(priv->pp_rxskb);
  33131. + priv->pp_rxskb = NULL;
  33132. +
  33133. + }
  33134. +#endif
  33135. + if (priv->rx_urb) {
  33136. + kfree(priv->rx_urb);
  33137. + }
  33138. + priv->rx_urb = NULL;
  33139. +
  33140. + DMESGE("Endpoint Alloc Failure");
  33141. + return -ENOMEM;
  33142. +
  33143. +
  33144. +_middle:
  33145. +
  33146. + return 0;
  33147. +
  33148. +}
  33149. +#ifdef THOMAS_BEACON
  33150. +void rtl8187_usb_deleteendpoints(struct net_device *dev)
  33151. +{
  33152. + int i;
  33153. + struct r8180_priv *priv = ieee80211_priv(dev);
  33154. +
  33155. + if( in_interrupt() )
  33156. + printk(KERN_ALERT " %ld in interrupt \n",in_interrupt() );
  33157. + if(priv->rx_urb){
  33158. + for(i=0;i<(MAX_RX_URB+1);i++){
  33159. + if(priv->rx_urb[i]) {
  33160. + usb_kill_urb(priv->rx_urb[i]);
  33161. + usb_free_urb(priv->rx_urb[i]);
  33162. + }
  33163. + }
  33164. + kfree(priv->rx_urb);
  33165. + priv->rx_urb = NULL;
  33166. + }
  33167. + if(priv->oldaddr){
  33168. + kfree(priv->oldaddr);
  33169. + priv->oldaddr = NULL;
  33170. + }
  33171. + if (priv->pp_rxskb) {
  33172. + kfree(priv->pp_rxskb);
  33173. + priv->pp_rxskb = 0;
  33174. + }
  33175. +}
  33176. +#endif
  33177. +
  33178. +void rtl8187_set_rate(struct net_device *dev)
  33179. +{
  33180. + int i;
  33181. + u16 word;
  33182. + int basic_rate,min_rr_rate,max_rr_rate;
  33183. +
  33184. + //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
  33185. + // priv->ieee80211->state == IEEE80211_LINKED){
  33186. + basic_rate = ieeerate2rtlrate(240);
  33187. + min_rr_rate = ieeerate2rtlrate(60);
  33188. + max_rr_rate = ieeerate2rtlrate(240);
  33189. +
  33190. + /*
  33191. + }else{
  33192. + basic_rate = ieeerate2rtlrate(20);
  33193. + min_rr_rate = ieeerate2rtlrate(10);
  33194. + max_rr_rate = ieeerate2rtlrate(110);
  33195. + }
  33196. + */
  33197. +
  33198. + write_nic_byte(dev, RESP_RATE,
  33199. + max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
  33200. +
  33201. + //word = read_nic_word(dev, BRSR);
  33202. + word = read_nic_word(dev, BRSR_8187);
  33203. + word &= ~BRSR_MBR_8185;
  33204. +
  33205. +
  33206. + for(i=0;i<=basic_rate;i++)
  33207. + word |= (1<<i);
  33208. +
  33209. + //write_nic_word(dev, BRSR, word);
  33210. + write_nic_word(dev, BRSR_8187, word);
  33211. +}
  33212. +
  33213. +
  33214. +void rtl8187_link_change(struct net_device *dev)
  33215. +{
  33216. + struct r8180_priv *priv = ieee80211_priv(dev);
  33217. + //write_nic_word(dev, BintrItv, net->beacon_interval);
  33218. + rtl8187_net_update(dev);
  33219. + /*update timing params*/
  33220. + rtl8180_set_chan(dev, priv->chan);
  33221. + rtl8187_set_rxconf(dev);
  33222. +}
  33223. +
  33224. +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
  33225. +void rtl8180_wmm_param_update(struct work_struct* work)
  33226. +{
  33227. + struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq);
  33228. + struct net_device *dev = ieee->dev;
  33229. + struct r8180_priv *priv = ieee80211_priv(dev);
  33230. +#else
  33231. +void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
  33232. +{
  33233. + struct net_device *dev = ieee->dev;
  33234. + struct r8180_priv *priv = ieee80211_priv(dev);
  33235. +#endif
  33236. + u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
  33237. + u8 mode = ieee->current_network.mode;
  33238. + AC_CODING eACI;
  33239. + AC_PARAM AcParam;
  33240. + PAC_PARAM pAcParam;
  33241. + u8 i;
  33242. +
  33243. + //8187 need not to update wmm param, added by David, 2006.9.8
  33244. + if(NIC_8187 == priv->card_8187) {
  33245. + return;
  33246. + }
  33247. +
  33248. + if(!ieee->current_network.QoS_Enable)
  33249. + {
  33250. + //legacy ac_xx_param update
  33251. +
  33252. + AcParam.longData = 0;
  33253. + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
  33254. + AcParam.f.AciAifsn.f.ACM = 0;
  33255. + AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin.
  33256. + AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax.
  33257. + AcParam.f.TXOPLimit = 0;
  33258. + for(eACI = 0; eACI < AC_MAX; eACI++)
  33259. + {
  33260. + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
  33261. + {
  33262. + u8 u1bAIFS;
  33263. + u32 u4bAcParam;
  33264. +
  33265. +
  33266. + pAcParam = (PAC_PARAM)(&AcParam);
  33267. + // Retrive paramters to udpate.
  33268. + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
  33269. + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
  33270. + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
  33271. + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
  33272. + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
  33273. +
  33274. + switch(eACI)
  33275. + {
  33276. + case AC1_BK:
  33277. + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
  33278. + break;
  33279. +
  33280. + case AC0_BE:
  33281. + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
  33282. + break;
  33283. +
  33284. + case AC2_VI:
  33285. + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
  33286. + break;
  33287. +
  33288. + case AC3_VO:
  33289. + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
  33290. + break;
  33291. +
  33292. + default:
  33293. + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
  33294. + break;
  33295. + }
  33296. + }
  33297. + }
  33298. +
  33299. + return;
  33300. + }
  33301. + //
  33302. + for(i = 0; i < AC_MAX; i++){
  33303. + pAcParam = (AC_PARAM * )ac_param;
  33304. + {
  33305. + AC_CODING eACI;
  33306. + u8 u1bAIFS;
  33307. + u32 u4bAcParam;
  33308. +
  33309. + // Retrive paramters to udpate.
  33310. + eACI = pAcParam->f.AciAifsn.f.ACI;
  33311. + //Mode G/A: slotTimeTimer = 9; Mode B: 20
  33312. + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
  33313. + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
  33314. + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
  33315. + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
  33316. + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
  33317. +
  33318. + switch(eACI)
  33319. + {
  33320. + case AC1_BK:
  33321. + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
  33322. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BK_PARAM,read_nic_dword(dev, AC_BK_PARAM));
  33323. + break;
  33324. +
  33325. + case AC0_BE:
  33326. + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
  33327. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_BE_PARAM,read_nic_dword(dev, AC_BE_PARAM));
  33328. + break;
  33329. +
  33330. + case AC2_VI:
  33331. + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
  33332. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VI_PARAM,read_nic_dword(dev, AC_VI_PARAM));
  33333. + break;
  33334. +
  33335. + case AC3_VO:
  33336. + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
  33337. + //printk(KERN_WARNING "[%04x]:0x%08x\n",AC_VO_PARAM,read_nic_dword(dev, AC_VO_PARAM));
  33338. + break;
  33339. +
  33340. + default:
  33341. + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
  33342. + break;
  33343. + }
  33344. + }
  33345. + ac_param += (sizeof(AC_PARAM));
  33346. + }
  33347. +}
  33348. +
  33349. +int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate )
  33350. +{
  33351. + u8 rate_len;
  33352. + u8 rate_ex_len;
  33353. + u8 RateMask = 0x7F;
  33354. + u8 idx;
  33355. + unsigned short Found = 0;
  33356. + u8 NaiveTxRate = TxRate&RateMask;
  33357. +
  33358. + rate_len = priv->ieee80211->current_network.rates_len;
  33359. + rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
  33360. +
  33361. + for( idx=0; idx< rate_len; idx++ ){
  33362. + if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate ) {
  33363. + Found = 1;
  33364. + goto found_rate;
  33365. + }
  33366. + }
  33367. +
  33368. + for( idx=0; idx< rate_ex_len; idx++ ) {
  33369. + if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate ) {
  33370. + Found = 1;
  33371. + goto found_rate;
  33372. + }
  33373. + }
  33374. +
  33375. + return Found;
  33376. + found_rate:
  33377. + return Found;
  33378. +}
  33379. +//
  33380. +// Description:
  33381. +// Get the Tx rate one degree up form the input rate in the supported rates.
  33382. +// Return the upgrade rate if it is successed, otherwise return the input rate.
  33383. +// By Bruce, 2007-06-05.
  33384. +//
  33385. +u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
  33386. +{
  33387. + struct r8180_priv *priv = ieee80211_priv(dev);
  33388. + u8 UpRate;
  33389. +
  33390. + // Upgrade 1 degree.
  33391. + switch(rate)
  33392. + {
  33393. + case 108: // Up to 54Mbps.
  33394. + UpRate = 108;
  33395. + break;
  33396. +
  33397. + case 96: // Up to 54Mbps.
  33398. + UpRate = 108;
  33399. + break;
  33400. +
  33401. + case 72: // Up to 48Mbps.
  33402. + UpRate = 96;
  33403. + break;
  33404. +
  33405. + case 48: // Up to 36Mbps.
  33406. + UpRate = 72;
  33407. + break;
  33408. +
  33409. + case 36: // Up to 24Mbps.
  33410. + UpRate = 48;
  33411. + break;
  33412. +
  33413. + case 22: // Up to 18Mbps.
  33414. + UpRate = 36;
  33415. + break;
  33416. +
  33417. + case 11: // Up to 11Mbps.
  33418. + UpRate = 22;
  33419. + break;
  33420. +
  33421. + case 4: // Up to 5.5Mbps.
  33422. + UpRate = 11;
  33423. + break;
  33424. +
  33425. + case 2: // Up to 2Mbps.
  33426. + UpRate = 4;
  33427. + break;
  33428. +
  33429. + default:
  33430. + printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
  33431. + return rate;
  33432. + }
  33433. + // Check if the rate is valid.
  33434. + if(IncludedInSupportedRates(priv, UpRate))
  33435. + {
  33436. +// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
  33437. + return UpRate;
  33438. + }
  33439. + else
  33440. + {
  33441. + printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
  33442. + return rate;
  33443. + }
  33444. + return rate;
  33445. +}
  33446. +//
  33447. +// Description:
  33448. +// Get the Tx rate one degree down form the input rate in the supported rates.
  33449. +// Return the degrade rate if it is successed, otherwise return the input rate.
  33450. +// By Bruce, 2007-06-05.
  33451. +//
  33452. +u8 GetDegradeTxRate( struct net_device *dev, u8 rate)
  33453. +{
  33454. + struct r8180_priv *priv = ieee80211_priv(dev);
  33455. + u8 DownRate;
  33456. +
  33457. + // Upgrade 1 degree.
  33458. + switch(rate)
  33459. + {
  33460. + case 108: // Down to 48Mbps.
  33461. + DownRate = 96;
  33462. + break;
  33463. +
  33464. + case 96: // Down to 36Mbps.
  33465. + DownRate = 72;
  33466. + break;
  33467. +
  33468. + case 72: // Down to 24Mbps.
  33469. + DownRate = 48;
  33470. + break;
  33471. +
  33472. + case 48: // Down to 18Mbps.
  33473. + DownRate = 36;
  33474. + break;
  33475. +
  33476. + case 36: // Down to 11Mbps.
  33477. + DownRate = 22;
  33478. + break;
  33479. +
  33480. + case 22: // Down to 5.5Mbps.
  33481. + DownRate = 11;
  33482. + break;
  33483. +
  33484. + case 11: // Down to 2Mbps.
  33485. + DownRate = 4;
  33486. + break;
  33487. +
  33488. + case 4: // Down to 1Mbps.
  33489. + DownRate = 2;
  33490. + break;
  33491. +
  33492. + case 2: // Down to 1Mbps.
  33493. + DownRate = 2;
  33494. + break;
  33495. +
  33496. + default:
  33497. + printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
  33498. + return rate;
  33499. + }
  33500. + // Check if the rate is valid.
  33501. + if(IncludedInSupportedRates(priv, DownRate)){
  33502. +// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
  33503. + return DownRate;
  33504. + }else{
  33505. + printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
  33506. + return rate;
  33507. + }
  33508. + return rate;
  33509. +}
  33510. +
  33511. +//
  33512. +// Helper function to determine if specified data rate is
  33513. +// CCK rate.
  33514. +// 2005.01.25, by rcnjko.
  33515. +//
  33516. +bool MgntIsCckRate(u16 rate )
  33517. +{
  33518. + bool bReturn = false;
  33519. +
  33520. + if((rate <= 22) && (rate != 12) && (rate != 18)){
  33521. + bReturn = true;
  33522. + }
  33523. +
  33524. + return bReturn;
  33525. +}
  33526. +//by amy for rate adaptive
  33527. +//
  33528. +// Description:
  33529. +// Core logic to adjust Tx data rate in STA mode according to
  33530. +// OFDM retry count ratio.
  33531. +//
  33532. +// Note:
  33533. +// RTL8187 : pHalData->CurrRetryCnt = TallyCnt
  33534. +// RTL8187B : pHalData->CurrRetryCnt = PktRetryCnt in TxClosedCommand
  33535. +//
  33536. +void sta_rateadaptive8187B(struct net_device *dev)
  33537. +{
  33538. + struct r8180_priv *priv = ieee80211_priv(dev);
  33539. + unsigned long CurrTxokCnt;
  33540. + u16 CurrRetryCnt;
  33541. + u16 CurrRetryRate;
  33542. + unsigned long CurrRxokCnt;
  33543. + bool bTryUp = false;
  33544. + bool bTryDown = false;
  33545. + u8 TryUpTh = 1;
  33546. + u8 TryDownTh = 2;
  33547. + u32 TxThroughput;
  33548. + long CurrSignalStrength;
  33549. + bool bUpdateInitialGain = false;
  33550. + CurrRetryCnt = priv->CurrRetryCnt;
  33551. + CurrTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
  33552. + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint)- priv->LastTxokCnt;
  33553. + CurrRxokCnt = priv->stats.rxok - priv->LastRxokCnt;
  33554. + CurrSignalStrength = priv->RecvSignalPower;
  33555. + TxThroughput = (u32)(priv->txokbytestotal - priv->LastTxOKBytes);
  33556. + priv->LastTxOKBytes = priv->txokbytestotal;
  33557. + priv->CurrentOperaRate = priv->ieee80211->rate / 5;
  33558. + //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
  33559. +
  33560. +#if 1
  33561. + //2 Compute retry ratio.
  33562. + if (CurrTxokCnt>0)
  33563. + {
  33564. + CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
  33565. + }
  33566. + else
  33567. + { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
  33568. + CurrRetryRate = (u16)(CurrRetryCnt*100/1);
  33569. + }
  33570. +#endif
  33571. +
  33572. +
  33573. + //printk("\n(1) priv->LastRetryRate: %d \n",priv->LastRetryRate);
  33574. + //printk("(2) CurrRetryCnt = %d \n", CurrRetryCnt);
  33575. + //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
  33576. + //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
  33577. + //printk("(5) SignalStrength = %d \n",priv->RecvSignalPower);
  33578. +
  33579. + priv->LastRetryCnt = priv->CurrRetryCnt;
  33580. + priv->LastTxokCnt = (priv->stats.txbeaconokint + priv->stats.txmanageokint +
  33581. + priv->stats.txvookint + priv->stats.txviokint + priv->stats.txbeokint);
  33582. + priv->LastRxokCnt = priv->stats.rxok;
  33583. + priv->CurrRetryCnt = 0;
  33584. + //2No Tx packets, return to init_rate or not?
  33585. + if (CurrRetryRate==0 && CurrTxokCnt == 0)
  33586. + {
  33587. + //
  33588. + // 2007.04.09, by Roger. after 4.5 seconds in this condition, we try to raise rate.
  33589. + //
  33590. + priv->TryupingCountNoData++;
  33591. +
  33592. + //printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
  33593. + //printk("(6) priv->CurrentOperaRate =%d\n", priv->CurrentOperaRate);
  33594. +
  33595. + if (priv->TryupingCountNoData>15)
  33596. + {
  33597. + priv->TryupingCountNoData = 0;
  33598. + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
  33599. + // Reset Fail Record
  33600. + priv->LastFailTxRate = 0;
  33601. + priv->LastFailTxRateSS = -200;
  33602. + priv->FailTxRateCount = 0;
  33603. + }
  33604. + goto SetInitialGain;
  33605. + }
  33606. + else
  33607. + {
  33608. + priv->TryupingCountNoData=0; //Reset trying up times.
  33609. + }
  33610. +
  33611. + //
  33612. + // For Netgear case, I comment out the following signal strength estimation,
  33613. + // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
  33614. + // 2007.04.09, by Roger.
  33615. + //
  33616. +#if 1
  33617. + // If sample is not enough, we use signalstrength.
  33618. + if ( CurrTxokCnt<10|| CurrRetryCnt<10)
  33619. + {
  33620. + //printk("Sample is not enough, we use signalstrength for rate adaptive\n");
  33621. + //After 3 sec, and trying up.
  33622. + priv->TryupingCountNoData++;
  33623. + if (priv->TryupingCountNoData>10)
  33624. + {
  33625. + //printk("Sample is not enough and After 3 sec try up\n");
  33626. + priv->TryupingCountNoData=0;
  33627. +
  33628. + //
  33629. + // Added by Roger, 2007.01.04.
  33630. + // Signal strength plus 3 for air link.
  33631. + //
  33632. +
  33633. + if ( CurrSignalStrength>-68 )//&& IncludedInSupportedRates(Adapter, 108) )
  33634. + {
  33635. + priv->ieee80211->rate = 540;
  33636. + //pMgntInfo->CurrentOperaRate = 108;
  33637. + }
  33638. + else if (CurrSignalStrength>-70)// && IncludedInSupportedRates(Adapter, 96) )
  33639. + {
  33640. + priv->ieee80211->rate = 480;
  33641. + //pMgntInfo->CurrentOperaRate = 96;
  33642. + }
  33643. + else if (CurrSignalStrength>-73)// && IncludedInSupportedRates(Adapter, 72) )
  33644. + {
  33645. + priv->ieee80211->rate = 360;
  33646. + //pMgntInfo->CurrentOperaRate = 72;
  33647. + }
  33648. + else if (CurrSignalStrength>-79)// && IncludedInSupportedRates(Adapter, 48) )
  33649. + {
  33650. + priv->ieee80211->rate = 240;
  33651. + //pMgntInfo->CurrentOperaRate = 48;
  33652. + }
  33653. + else if (CurrSignalStrength>-81)// && IncludedInSupportedRates(Adapter, 36) )
  33654. + {
  33655. + priv->ieee80211->rate = 180;
  33656. + //pMgntInfo->CurrentOperaRate = 36;
  33657. + }
  33658. + else if (CurrSignalStrength>-83)// && IncludedInSupportedRates(Adapter, 22) )
  33659. + {
  33660. + priv->ieee80211->rate = 110;
  33661. + //pMgntInfo->CurrentOperaRate = 22;
  33662. + }
  33663. + else if (CurrSignalStrength>-85)// && IncludedInSupportedRates(Adapter, 11) )
  33664. + {
  33665. + priv->ieee80211->rate = 55;
  33666. + //pMgntInfo->CurrentOperaRate = 11;
  33667. + }
  33668. + else if (CurrSignalStrength>-89)// && IncludedInSupportedRates(Adapter, 4) )
  33669. + {
  33670. + priv->ieee80211->rate = 20;
  33671. + //pMgntInfo->CurrentOperaRate = 4;
  33672. + }
  33673. +
  33674. +
  33675. + }
  33676. +
  33677. + //2004.12.23 skip record for 0
  33678. + //pHalData->LastRetryRate = CurrRetryRate;
  33679. + //printk("pMgntInfo->CurrentOperaRate =%d\n",priv->ieee80211->rate);
  33680. + return;
  33681. + }
  33682. + else
  33683. + {
  33684. + priv->TryupingCountNoData=0;
  33685. + }
  33686. +#endif
  33687. + //
  33688. + // Restructure rate adaptive as the following main stages:
  33689. + // (1) Add retry threshold in 54M upgrading condition with signal strength.
  33690. + // (2) Add the mechanism to degrade to CCK rate according to signal strength
  33691. + // and retry rate.
  33692. + // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
  33693. + // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
  33694. + // (4) Add the mehanism of trying to upgrade tx rate.
  33695. + // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
  33696. + // By Bruce, 2007-06-05.
  33697. + //
  33698. + //
  33699. +
  33700. + // 11Mbps or 36Mbps
  33701. + // Check more times in these rate(key rates).
  33702. + //
  33703. + if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
  33704. + {
  33705. + TryUpTh += 9;
  33706. + }
  33707. + //
  33708. + // Let these rates down more difficult.
  33709. + //
  33710. + if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
  33711. + {
  33712. + TryDownTh += 1;
  33713. + }
  33714. +
  33715. + //1 Adjust Rate.
  33716. + if (priv->bTryuping == true)
  33717. + {
  33718. + //2 For Test Upgrading mechanism
  33719. + // Note:
  33720. + // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
  33721. + // thus the low data rate does not improve the performance.
  33722. + // We randomly upgrade the data rate and check if the retry rate is improved.
  33723. +
  33724. + // Upgrading rate did not improve the retry rate, fallback to the original rate.
  33725. + if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
  33726. + {
  33727. + //Not necessary raising rate, fall back rate.
  33728. + bTryDown = true;
  33729. + //printk("Not necessary raising rate, fall back rate....\n");
  33730. + //printk("(7) priv->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
  33731. + // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
  33732. + }
  33733. + else
  33734. + {
  33735. + priv->bTryuping = false;
  33736. + }
  33737. + }
  33738. + else if (CurrSignalStrength > -51 && (CurrRetryRate < 100))
  33739. + {
  33740. + //2For High Power
  33741. + //
  33742. + // Added by Roger, 2007.04.09.
  33743. + // Return to highest data rate, if signal strength is good enough.
  33744. + // SignalStrength threshold(-50dbm) is for RTL8186.
  33745. + // Revise SignalStrength threshold to -51dbm.
  33746. + //
  33747. + // Also need to check retry rate for safety, by Bruce, 2007-06-05.
  33748. + if(priv->CurrentOperaRate != 108)
  33749. + {
  33750. + bTryUp = true;
  33751. + // Upgrade Tx Rate directly.
  33752. + priv->TryupingCount += TryUpTh;
  33753. + //printk("StaRateAdaptive87B: Power(%d) is high enough!!. \n", CurrSignalStrength);
  33754. + }
  33755. + }
  33756. + // To avoid unstable rate jumping, comment out this condition, by Bruce, 2007-06-26.
  33757. + /*
  33758. + else if(CurrSignalStrength < -86 && CurrRetryRate >= 100)
  33759. + {
  33760. + //2 For Low Power
  33761. + //
  33762. + // Low signal strength and high current tx rate may cause Tx rate to degrade too slowly.
  33763. + // Update Tx rate to CCK rate directly.
  33764. + // By Bruce, 2007-06-05.
  33765. + //
  33766. + if(!MgntIsCckRate(pMgntInfo->CurrentOperaRate))
  33767. + {
  33768. + if(CurrSignalStrength > -88 && IncludedInSupportedRates(Adapter, 22)) // 11M
  33769. + pMgntInfo->CurrentOperaRate = 22;
  33770. + else if(CurrSignalStrength > -90 && IncludedInSupportedRates(Adapter, 11)) // 5.5M
  33771. + pMgntInfo->CurrentOperaRate = 11;
  33772. + else if(CurrSignalStrength > -92 && IncludedInSupportedRates(Adapter, 4)) // 2M
  33773. + pMgntInfo->CurrentOperaRate = 4;
  33774. + else // 1M
  33775. + pMgntInfo->CurrentOperaRate = 2;
  33776. + }
  33777. + else if(CurrRetryRate >= 200)
  33778. + {
  33779. + pMgntInfo->CurrentOperaRate = GetDegradeTxRate(Adapter, pMgntInfo->CurrentOperaRate);
  33780. + }
  33781. + RT_TRACE(COMP_RATE, DBG_LOUD, ("RA: Low Power(%d), or High Retry Rate(%d), set rate to CCK rate (%d). \n",
  33782. + CurrSignalStrength, CurrRetryRate, pMgntInfo->CurrentOperaRate));
  33783. + bUpdateInitialGain = TRUE;
  33784. + // Reset Fail Record
  33785. + pHalData->LastFailTxRate = 0;
  33786. + pHalData->LastFailTxRateSS = -200;
  33787. + pHalData->FailTxRateCount = 0;
  33788. + goto SetInitialGain;
  33789. + }
  33790. + */
  33791. + else if(CurrTxokCnt< 100 && CurrRetryRate >= 600)
  33792. + {
  33793. + //2 For Serious Retry
  33794. + //
  33795. + // Traffic is not busy but our Tx retry is serious.
  33796. + //
  33797. + bTryDown = true;
  33798. + // Let Rate Mechanism to degrade tx rate directly.
  33799. + priv->TryDownCountLowData += TryDownTh;
  33800. + //printk("RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
  33801. + }
  33802. + else if ( priv->CurrentOperaRate == 108 )
  33803. + {
  33804. + //2For 54Mbps
  33805. + // if ( (CurrRetryRate>38)&&(pHalData->LastRetryRate>35))
  33806. + if ( (CurrRetryRate>33)&&(priv->LastRetryRate>32))
  33807. + {
  33808. + //(30,25) for cable link threshold. (38,35) for air link.
  33809. + //Down to rate 48Mbps.
  33810. + bTryDown = true;
  33811. + }
  33812. + }
  33813. + else if ( priv->CurrentOperaRate == 96 )
  33814. + {
  33815. + //2For 48Mbps
  33816. + // if ( ((CurrRetryRate>73) && (pHalData->LastRetryRate>72)) && IncludedInSupportedRates(Adapter, 72) )
  33817. + if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
  33818. + {
  33819. + //(73, 72) for temp used.
  33820. + //(25, 23) for cable link, (60,59) for air link.
  33821. + //CurrRetryRate plus 25 and 26 respectively for air link.
  33822. + //Down to rate 36Mbps.
  33823. + bTryDown = true;
  33824. + }
  33825. + else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
  33826. + {
  33827. + bTryUp = true;
  33828. + }
  33829. + }
  33830. + else if ( priv->CurrentOperaRate == 72 )
  33831. + {
  33832. + //2For 36Mbps
  33833. + //if ( (CurrRetryRate>97) && (pHalData->LastRetryRate>97))
  33834. + if ( (CurrRetryRate>55) && (priv->LastRetryRate>54))
  33835. + {
  33836. + //(30,25) for cable link threshold respectively. (103,10) for air link respectively.
  33837. + //CurrRetryRate plus 65 and 69 respectively for air link threshold.
  33838. + //Down to rate 24Mbps.
  33839. + bTryDown = true;
  33840. + }
  33841. + // else if ( (CurrRetryRate<20) && (pHalData->LastRetryRate<20) && IncludedInSupportedRates(Adapter, 96) )//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
  33842. + else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16))//&& (device->LastRetryRate<15) ) //TO DO: need to consider (RSSI)
  33843. + {
  33844. + bTryUp = true;
  33845. + }
  33846. + }
  33847. + else if ( priv->CurrentOperaRate == 48 )
  33848. + {
  33849. + //2For 24Mbps
  33850. + // if ( ((CurrRetryRate>119) && (pHalData->LastRetryRate>119) && IncludedInSupportedRates(Adapter, 36)))
  33851. + if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
  33852. + {
  33853. + //(15,15) for cable link threshold respectively. (119, 119) for air link threshold.
  33854. + //Plus 84 for air link threshold.
  33855. + //Down to rate 18Mbps.
  33856. + bTryDown = true;
  33857. + }
  33858. + // else if ( (CurrRetryRate<14) && (pHalData->LastRetryRate<15) && IncludedInSupportedRates(Adapter, 72)) //TO DO: need to consider (RSSI)
  33859. + else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
  33860. + {
  33861. + bTryUp = true;
  33862. + }
  33863. + }
  33864. + else if ( priv->CurrentOperaRate == 36 )
  33865. + {
  33866. + //2For 18Mbps
  33867. + if ( ((CurrRetryRate>109) && (priv->LastRetryRate>109)))
  33868. + {
  33869. + //(99,99) for cable link, (109,109) for air link.
  33870. + //Down to rate 11Mbps.
  33871. + bTryDown = true;
  33872. + }
  33873. + // else if ( (CurrRetryRate<15) && (pHalData->LastRetryRate<16) && IncludedInSupportedRates(Adapter, 48)) //TO DO: need to consider (RSSI)
  33874. + else if ( (CurrRetryRate<25) && (priv->LastRetryRate<26)) //TO DO: need to consider (RSSI)
  33875. + {
  33876. + bTryUp = true;
  33877. + }
  33878. + }
  33879. + else if ( priv->CurrentOperaRate == 22 )
  33880. + {
  33881. + //2For 11Mbps
  33882. + // if (CurrRetryRate>299 && IncludedInSupportedRates(Adapter, 11))
  33883. + if (CurrRetryRate>95)
  33884. + {
  33885. + bTryDown = true;
  33886. + }
  33887. + else if (CurrRetryRate<55)//&& (device->LastRetryRate<55) ) //TO DO: need to consider (RSSI)
  33888. + {
  33889. + bTryUp = true;
  33890. + }
  33891. + }
  33892. + else if ( priv->CurrentOperaRate == 11 )
  33893. + {
  33894. + //2For 5.5Mbps
  33895. + // if (CurrRetryRate>159 && IncludedInSupportedRates(Adapter, 4) )
  33896. + if (CurrRetryRate>149)
  33897. + {
  33898. + bTryDown = true;
  33899. + }
  33900. + // else if ( (CurrRetryRate<30) && (pHalData->LastRetryRate<30) && IncludedInSupportedRates(Adapter, 22) )
  33901. + else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
  33902. + {
  33903. + bTryUp = true;
  33904. + }
  33905. + }
  33906. + else if ( priv->CurrentOperaRate == 4 )
  33907. + {
  33908. + //2For 2 Mbps
  33909. + if((CurrRetryRate>99) && (priv->LastRetryRate>99))
  33910. + {
  33911. + bTryDown = true;
  33912. + }
  33913. + // else if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 11) )
  33914. + else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
  33915. + {
  33916. + bTryUp = true;
  33917. + }
  33918. + }
  33919. + else if ( priv->CurrentOperaRate == 2 )
  33920. + {
  33921. + //2For 1 Mbps
  33922. + // if ( (CurrRetryRate<50) && (pHalData->LastRetryRate<65) && IncludedInSupportedRates(Adapter, 4))
  33923. + if ( (CurrRetryRate<70) && (priv->LastRetryRate<75))
  33924. + {
  33925. + bTryUp = true;
  33926. + }
  33927. + }
  33928. + if(bTryUp && bTryDown)
  33929. + printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
  33930. +
  33931. + //1 Test Upgrading Tx Rate
  33932. + // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
  33933. + // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
  33934. + if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
  33935. + && priv->CurrentOperaRate != 108 && priv->FailTxRateCount < 2)
  33936. + {
  33937. +#if 1
  33938. + if(jiffies% (CurrRetryRate + 101) == 0)
  33939. + {
  33940. + bTryUp = true;
  33941. + priv->bTryuping = true;
  33942. + printk("======================================================>StaRateAdaptive87B(): Randomly try upgrading...\n");
  33943. + }
  33944. +#endif
  33945. + }
  33946. + //1 Rate Mechanism
  33947. + if(bTryUp)
  33948. + {
  33949. + priv->TryupingCount++;
  33950. + priv->TryDownCountLowData = 0;
  33951. +
  33952. + //
  33953. + // Check more times if we need to upgrade indeed.
  33954. + // Because the largest value of pHalData->TryupingCount is 0xFFFF and
  33955. + // the largest value of pHalData->FailTxRateCount is 0x14,
  33956. + // this condition will be satisfied at most every 2 min.
  33957. + //
  33958. + if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
  33959. + (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
  33960. + {
  33961. + priv->TryupingCount = 0;
  33962. + //
  33963. + // When transfering from CCK to OFDM, DIG is an important issue.
  33964. + //
  33965. + if(priv->CurrentOperaRate == 22)
  33966. + bUpdateInitialGain = true;
  33967. + // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
  33968. + // (2)If the signal strength is increased, it may be able to upgrade.
  33969. + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
  33970. + //printk("StaRateAdaptive87B(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
  33971. +
  33972. + // Update Fail Tx rate and count.
  33973. + if(priv->LastFailTxRate != priv->CurrentOperaRate)
  33974. + {
  33975. + priv->LastFailTxRate = priv->CurrentOperaRate;
  33976. + priv->FailTxRateCount = 0;
  33977. + priv->LastFailTxRateSS = -200; // Set lowest power.
  33978. + }
  33979. + }
  33980. + }
  33981. + else
  33982. + {
  33983. + if(priv->TryupingCount > 0)
  33984. + priv->TryupingCount --;
  33985. + }
  33986. +
  33987. + if(bTryDown)
  33988. + {
  33989. + priv->TryDownCountLowData++;
  33990. + priv->TryupingCount = 0;
  33991. +
  33992. +
  33993. + //Check if Tx rate can be degraded or Test trying upgrading should fallback.
  33994. + if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
  33995. + {
  33996. + priv->TryDownCountLowData = 0;
  33997. + priv->bTryuping = false;
  33998. + // Update fail information.
  33999. + if(priv->LastFailTxRate == priv->CurrentOperaRate)
  34000. + {
  34001. + priv->FailTxRateCount ++;
  34002. + // Record the Tx fail rate signal strength.
  34003. + if(CurrSignalStrength > priv->LastFailTxRateSS)
  34004. + {
  34005. + priv->LastFailTxRateSS = CurrSignalStrength;
  34006. + }
  34007. + }
  34008. + else
  34009. + {
  34010. + priv->LastFailTxRate = priv->CurrentOperaRate;
  34011. + priv->FailTxRateCount = 1;
  34012. + priv->LastFailTxRateSS = CurrSignalStrength;
  34013. + }
  34014. + priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
  34015. + //
  34016. + // When it is CCK rate, it may need to update initial gain to receive lower power packets.
  34017. + //
  34018. + if(MgntIsCckRate(priv->CurrentOperaRate))
  34019. + {
  34020. + bUpdateInitialGain = true;
  34021. + }
  34022. + //printk("StaRateAdaptive87B(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
  34023. + }
  34024. + }
  34025. + else
  34026. + {
  34027. + if(priv->TryDownCountLowData > 0)
  34028. + priv->TryDownCountLowData --;
  34029. + }
  34030. + // Keep the Tx fail rate count to equal to 0x15 at most.
  34031. + // Reduce the fail count at least to 10 sec if tx rate is tending stable.
  34032. + if(priv->FailTxRateCount >= 0x15 ||
  34033. + (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
  34034. + {
  34035. + priv->FailTxRateCount --;
  34036. + }
  34037. +
  34038. + //
  34039. + // We need update initial gain when we set tx rate "from OFDM to CCK" or
  34040. + // "from CCK to OFDM".
  34041. + //
  34042. +SetInitialGain:
  34043. +#if 1 //to be done
  34044. + if(bUpdateInitialGain)
  34045. + {
  34046. + if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
  34047. + {
  34048. + if(priv->InitialGain > priv->RegBModeGainStage)
  34049. + {
  34050. + if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
  34051. + {
  34052. + priv->InitialGain = priv->RegBModeGainStage;
  34053. + }
  34054. + else if(priv->InitialGain > priv->RegBModeGainStage + 1)
  34055. + {
  34056. + priv->InitialGain -= 2;
  34057. + }
  34058. + else
  34059. + {
  34060. + priv->InitialGain --;
  34061. + }
  34062. + UpdateInitialGain(dev);
  34063. + }
  34064. + }
  34065. + else // OFDM
  34066. + {
  34067. + if(priv->InitialGain < 4)
  34068. + {
  34069. + priv->InitialGain ++;
  34070. + UpdateInitialGain(dev);
  34071. + }
  34072. + }
  34073. + }
  34074. +#endif
  34075. + //Record the related info
  34076. + priv->LastRetryRate = CurrRetryRate;
  34077. + priv->LastTxThroughput = TxThroughput;
  34078. + priv->ieee80211->rate = priv->CurrentOperaRate * 5;
  34079. +}
  34080. +
  34081. +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
  34082. +void rtl8180_rate_adapter(struct work_struct * work)
  34083. +{
  34084. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  34085. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
  34086. + struct net_device *dev = ieee->dev;
  34087. +#else
  34088. +void rtl8180_rate_adapter(struct net_device *dev)
  34089. +{
  34090. +
  34091. +#endif
  34092. + sta_rateadaptive8187B(dev);
  34093. +}
  34094. +
  34095. +void timer_rate_adaptive(unsigned long data)
  34096. +{
  34097. + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
  34098. + //DMESG("---->timer_rate_adaptive()\n");
  34099. + if(!priv->up)
  34100. + {
  34101. + //DMESG("<----timer_rate_adaptive():driver is not up!\n");
  34102. + return;
  34103. + }
  34104. + if( (priv->ieee80211->mode != IEEE_B) &&
  34105. + (priv->ieee80211->iw_mode != IW_MODE_MASTER)
  34106. + && ((priv->ieee80211->state == IEEE80211_LINKED)||(priv->ieee80211->state == IEEE80211_MESH_LINKED)))
  34107. + {
  34108. + //DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
  34109. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  34110. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq, 0);
  34111. +#else
  34112. + queue_work(priv->ieee80211->wq,&priv->ieee80211->rate_adapter_wq);
  34113. +#endif
  34114. + }
  34115. +
  34116. + mod_timer(&priv->rateadapter_timer, jiffies + MSECS(DEFAULT_RATE_ADAPTIVE_TIMER_PERIOD));
  34117. + //DMESG("<----timer_rate_adaptive()\n");
  34118. +}
  34119. +//by amy for rate adaptive
  34120. +
  34121. +
  34122. +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv);
  34123. +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
  34124. +
  34125. +//YJ,add,080828,for KeepAlive
  34126. +#if 0
  34127. +static void MgntLinkKeepAlive(struct r8180_priv *priv )
  34128. +{
  34129. + if (priv->keepAliveLevel == 0)
  34130. + return;
  34131. +
  34132. + if(priv->ieee80211->state == IEEE80211_LINKED)
  34133. + {
  34134. + //
  34135. + // Keep-Alive.
  34136. + //
  34137. + //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);
  34138. +
  34139. + if ( (priv->keepAliveLevel== 2) ||
  34140. + (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
  34141. + priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast )
  34142. + )
  34143. + {
  34144. + priv->link_detect.IdleCount++;
  34145. +
  34146. + //
  34147. + // Send a Keep-Alive packet packet to AP if we had been idle for a while.
  34148. + //
  34149. + if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) )
  34150. + {
  34151. + priv->link_detect.IdleCount = 0;
  34152. + ieee80211_sta_ps_send_null_frame(priv->ieee80211, false);
  34153. + }
  34154. + }
  34155. + else
  34156. + {
  34157. + priv->link_detect.IdleCount = 0;
  34158. + }
  34159. + priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast;
  34160. + priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
  34161. + }
  34162. +}
  34163. +//YJ,add,080828,for KeepAlive,end
  34164. +#endif
  34165. +void InactivePowerSave(struct net_device *dev)
  34166. +{
  34167. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  34168. +
  34169. + //
  34170. + // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
  34171. + // is really scheduled.
  34172. + // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
  34173. + // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
  34174. + // blocks the IPS procedure of switching RF.
  34175. + // By Bruce, 2007-12-25.
  34176. + //
  34177. + priv->bSwRfProcessing = true;
  34178. + MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
  34179. +
  34180. + //
  34181. + // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
  34182. + //
  34183. +#if 0
  34184. + while( index < 4 )
  34185. + {
  34186. + if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
  34187. + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
  34188. + {
  34189. + if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
  34190. + pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
  34191. +
  34192. + }
  34193. + index++;
  34194. + }
  34195. +#endif
  34196. + priv->bSwRfProcessing = false;
  34197. +}
  34198. +
  34199. +//
  34200. +// Description:
  34201. +// Enter the inactive power save mode. RF will be off
  34202. +// 2007.08.17, by shien chang.
  34203. +//
  34204. +void IPSEnter(struct net_device *dev)
  34205. +{
  34206. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  34207. + RT_RF_POWER_STATE rtState;
  34208. +
  34209. + if (priv->bInactivePs)
  34210. + {
  34211. + rtState = priv->eRFPowerState;
  34212. +
  34213. + //
  34214. + // Added by Bruce, 2007-12-25.
  34215. + // Do not enter IPS in the following conditions:
  34216. + // (1) RF is already OFF or Sleep
  34217. + // (2) bSwRfProcessing (indicates the IPS is still under going)
  34218. + // (3) Connectted (only disconnected can trigger IPS)
  34219. + // (4) IBSS (send Beacon)
  34220. + // (5) AP mode (send Beacon)
  34221. + //
  34222. + if (rtState == eRfOn && !priv->bSwRfProcessing && (priv->ieee80211->iw_mode != IW_MODE_ADHOC)
  34223. + && (priv->ieee80211->state != IEEE80211_LINKED ))
  34224. + {
  34225. +#ifdef CONFIG_RADIO_DEBUG
  34226. + DMESG("IPSEnter(): Turn off RF.");
  34227. +#endif
  34228. + priv->eInactivePowerState = eRfOff;
  34229. + InactivePowerSave(dev);
  34230. + //SetRFPowerState(dev, priv->eInactivePowerState);
  34231. + //MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
  34232. + }
  34233. + }
  34234. + //printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
  34235. +}
  34236. +
  34237. +void IPSLeave(struct net_device *dev)
  34238. +{
  34239. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  34240. + RT_RF_POWER_STATE rtState;
  34241. + if (priv->bInactivePs)
  34242. + {
  34243. + rtState = priv->eRFPowerState;
  34244. + if (rtState == eRfOff && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
  34245. + {
  34246. +#ifdef CONFIG_RADIO_DEBUG
  34247. + DMESG("ISLeave(): Turn on RF.");
  34248. +#endif
  34249. + priv->eInactivePowerState = eRfOn;
  34250. + InactivePowerSave(dev);
  34251. + }
  34252. + }
  34253. +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
  34254. +}
  34255. +//by amy for power save
  34256. +
  34257. +//YJ,add,081230
  34258. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  34259. +void IPSLeave_wq (struct work_struct *work)
  34260. +{
  34261. + struct ieee80211_device *ieee = container_of(work,struct ieee80211_device,ips_leave_wq);
  34262. + struct net_device *dev = ieee->dev;
  34263. +#else
  34264. +void IPSLeave_wq(struct net_device *dev)
  34265. +{
  34266. +#endif
  34267. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  34268. + down(&priv->ieee80211->ips_sem);
  34269. + IPSLeave(dev);
  34270. + up(&priv->ieee80211->ips_sem);
  34271. +}
  34272. +
  34273. +void ieee80211_ips_leave(struct net_device *dev)
  34274. +{
  34275. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  34276. + if(priv->bInactivePs){
  34277. + if(priv->eRFPowerState == eRfOff)
  34278. + {
  34279. + //DMESG("%s", __FUNCTION__);
  34280. + queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
  34281. + }
  34282. + }
  34283. +}
  34284. +//YJ,add,081230,end
  34285. +
  34286. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  34287. +void rtl8180_watch_dog_wq (struct work_struct *work)
  34288. +{
  34289. + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
  34290. + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,watch_dog_wq);
  34291. + struct net_device *dev = ieee->dev;
  34292. +#else
  34293. +void rtl8180_watch_dog_wq(struct net_device *dev)
  34294. +{
  34295. +#endif
  34296. + struct r8180_priv *priv = ieee80211_priv(dev);
  34297. + //bool bEnterPS = false;
  34298. + //bool bBusyTraffic = false;
  34299. + u32 TotalRxNum = 0;
  34300. + u16 SlotIndex = 0, i=0;
  34301. + //YJ,add,080828,for link state check
  34302. + if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){
  34303. + SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum;
  34304. + priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod;
  34305. + for( i=0; i<priv->link_detect.SlotNum; i++ )
  34306. + TotalRxNum+= priv->link_detect.RxFrameNum[i];
  34307. +#if 0 //for roaming temp del
  34308. + if(TotalRxNum == 0){
  34309. + priv->ieee80211->state = IEEE80211_ASSOCIATING;
  34310. + printk("=========>turn to another AP\n");
  34311. + queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
  34312. + }
  34313. +#endif
  34314. + }
  34315. + priv->link_detect.NumRxOkInPeriod = 0;
  34316. + priv->link_detect.NumTxOkInPeriod = 0;
  34317. + priv->ieee80211->NumRxDataInPeriod = 0;
  34318. + priv->ieee80211->NumRxBcnInPeriod = 0;
  34319. +
  34320. +#ifdef CONFIG_IPS
  34321. + if(priv->ieee80211->actscanning == false){
  34322. + if((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
  34323. + (priv->ieee80211->state == IEEE80211_NOLINK) &&
  34324. + (priv->eRFPowerState == eRfOn))
  34325. + {
  34326. + //printk("actscanning:%d, state:%d, eRFPowerState:%d\n",
  34327. + // priv->ieee80211->actscanning,
  34328. + // priv->ieee80211->state,
  34329. + // priv->eRFPowerState);
  34330. +
  34331. + down(&priv->ieee80211->ips_sem);
  34332. + IPSEnter(dev);
  34333. + up(&priv->ieee80211->ips_sem);
  34334. + }
  34335. + }
  34336. + //queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,IEEE80211_WATCH_DOG_TIME);
  34337. +#endif
  34338. +
  34339. + //printk("========================>leave rtl8180_watch_dog_wq()\n");
  34340. +}
  34341. +
  34342. +void watch_dog_adaptive(unsigned long data)
  34343. +{
  34344. + struct net_device* dev = (struct net_device*)data;
  34345. + struct r8180_priv* priv = ieee80211_priv(dev);
  34346. + //DMESG("---->watch_dog_adaptive()\n");
  34347. + if(!priv->up){
  34348. + //DMESG("<----watch_dog_adaptive():driver is not up!\n");
  34349. + return;
  34350. + }
  34351. + // Tx and Rx High Power Mechanism.
  34352. + if(CheckHighPower(dev)){
  34353. + //printk("===============================> high power!\n");
  34354. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  34355. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq, 0);
  34356. +#else
  34357. + queue_work(priv->ieee80211->wq,&priv->ieee80211->tx_pw_wq);
  34358. +#endif
  34359. + }
  34360. +
  34361. + // Schedule an workitem to perform DIG
  34362. + if(CheckDig(dev) == true){
  34363. +
  34364. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  34365. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq,0);
  34366. +#else
  34367. + queue_work(priv->ieee80211->wq,&priv->ieee80211->hw_dig_wq);
  34368. +#endif
  34369. + }
  34370. +
  34371. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  34372. + queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq,0);
  34373. +#else
  34374. + queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
  34375. +#endif
  34376. +
  34377. + mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
  34378. + //DMESG("<----watch_dog_adaptive()\n");
  34379. +}
  34380. +
  34381. +#ifdef ENABLE_DOT11D
  34382. +
  34383. +CHANNEL_LIST Current_tbl;
  34384. +
  34385. +static CHANNEL_LIST ChannelPlan[] = {
  34386. + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
  34387. + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
  34388. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
  34389. + {{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.
  34390. + {{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.
  34391. + {{14,36,40,44,48,52,56,60,64},9}, //MKK
  34392. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
  34393. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
  34394. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
  34395. + {{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
  34396. + {{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
  34397. +};
  34398. +
  34399. +static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
  34400. +{
  34401. + int i;
  34402. +
  34403. + //lzm add 081205
  34404. + ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1;
  34405. + ieee->IbssStartChnl=0;
  34406. +
  34407. + switch (channel_plan)
  34408. + {
  34409. + case COUNTRY_CODE_FCC:
  34410. + case COUNTRY_CODE_IC:
  34411. + case COUNTRY_CODE_ETSI:
  34412. + case COUNTRY_CODE_SPAIN:
  34413. + case COUNTRY_CODE_FRANCE:
  34414. + case COUNTRY_CODE_MKK:
  34415. + case COUNTRY_CODE_MKK1:
  34416. + case COUNTRY_CODE_ISRAEL:
  34417. + case COUNTRY_CODE_TELEC:
  34418. + {
  34419. + Dot11d_Init(ieee);
  34420. + ieee->bGlobalDomain = false;
  34421. + ieee->bWorldWide13 = false;
  34422. + if (ChannelPlan[channel_plan].Len != 0){
  34423. + // Clear old channel map
  34424. + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
  34425. + // Set new channel map
  34426. + for (i=0;i<ChannelPlan[channel_plan].Len;i++)
  34427. + {
  34428. + if(ChannelPlan[channel_plan].Channel[i] <= 14)
  34429. + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
  34430. + }
  34431. + }
  34432. + break;
  34433. + }
  34434. + case COUNTRY_CODE_GLOBAL_DOMAIN:
  34435. + {
  34436. + GET_DOT11D_INFO(ieee)->bEnabled = 0;
  34437. + Dot11d_Reset(ieee);
  34438. + ieee->bGlobalDomain = true;
  34439. + ieee->bWorldWide13 = false;
  34440. +
  34441. + //lzm add 081205
  34442. + ieee->MinPassiveChnlNum=12;
  34443. + ieee->IbssStartChnl= 10;
  34444. +
  34445. + break;
  34446. + }
  34447. + case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 081205
  34448. + {
  34449. + Dot11d_Init(ieee);
  34450. + ieee->bGlobalDomain = false;
  34451. + ieee->bWorldWide13 = true;
  34452. +
  34453. + //lzm add 081205
  34454. + ieee->MinPassiveChnlNum=12;
  34455. + ieee->IbssStartChnl= 10;
  34456. +
  34457. + if (ChannelPlan[channel_plan].Len != 0){
  34458. + // Clear old channel map
  34459. + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
  34460. + // Set new channel map
  34461. + for (i=0;i<ChannelPlan[channel_plan].Len;i++)
  34462. + {
  34463. + if(ChannelPlan[channel_plan].Channel[i] <= 11)//ch1~ch11 active scan
  34464. + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
  34465. + else//ch12~13 passive scan
  34466. + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 2;
  34467. + }
  34468. + }
  34469. +
  34470. + break;
  34471. + }
  34472. + default:
  34473. + {
  34474. + Dot11d_Init(ieee);
  34475. + ieee->bGlobalDomain = false;
  34476. + ieee->bWorldWide13 = false;
  34477. + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
  34478. + for (i=1;i<=14;i++)
  34479. + {
  34480. + GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
  34481. + }
  34482. + break;
  34483. + }
  34484. + }
  34485. +}
  34486. +#endif
  34487. +
  34488. +
  34489. +static void rtl8180_link_detect_init(plink_detect_t plink_detect)
  34490. +{
  34491. + memset(plink_detect, 0, sizeof(link_detect_t));
  34492. + plink_detect->SlotNum = DEFAULT_SLOT_NUM;
  34493. +}
  34494. +
  34495. +#ifdef SW_ANTE_DIVERSITY
  34496. +static void rtl8187_antenna_diversity_read(struct net_device *dev)
  34497. +{
  34498. + struct r8180_priv *priv = ieee80211_priv(dev);
  34499. + u16 usValue;
  34500. +
  34501. + //2 Read CustomerID
  34502. + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET>>1);
  34503. + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
  34504. + //DMESG("EEPROM Customer ID: %02X\n", priv->EEPROMCustomerID);
  34505. +
  34506. + //2 Read AntennaDiversity
  34507. + // SW Antenna Diversity.
  34508. + if( (usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE ){
  34509. + priv->EEPROMSwAntennaDiversity = false;
  34510. + DMESG("EEPROM Disable SW Antenna Diversity");
  34511. + }else{
  34512. + priv->EEPROMSwAntennaDiversity = true;
  34513. + DMESG("EEPROM Enable SW Antenna Diversity");
  34514. + }
  34515. + // Default Antenna to use.
  34516. + if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 ) {
  34517. + priv->EEPROMDefaultAntenna1 = false;
  34518. + DMESG("EEPROM Default Main Antenna 0");
  34519. + }else{
  34520. + priv->EEPROMDefaultAntenna1 = false;
  34521. + DMESG( "EEPROM Default Aux Antenna 1");
  34522. + }
  34523. +
  34524. + //
  34525. + // Antenna diversity mechanism. Added by Roger, 2007.11.05.
  34526. + //
  34527. + if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto //set it to 0 when init
  34528. + {// 0: default from EEPROM.
  34529. + priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
  34530. + }else{// 1:disable antenna diversity, 2: enable antenna diversity.
  34531. + priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
  34532. + }
  34533. + //DMESG("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
  34534. +
  34535. +
  34536. + //
  34537. + // Default antenna settings. Added by Roger, 2007.11.05.
  34538. + //
  34539. + if( priv->RegDefaultAntenna == 0)//set it to 0 when init
  34540. + { // 0: default from EEPROM.
  34541. + priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
  34542. + }else{// 1: main, 2: aux.
  34543. + priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
  34544. + }
  34545. + //DMESG("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
  34546. +
  34547. +//by amy for antenna
  34548. +}
  34549. +#endif
  34550. +
  34551. +short rtl8180_init(struct net_device *dev)
  34552. +{
  34553. + struct r8180_priv *priv = ieee80211_priv(dev);
  34554. + int i, j;
  34555. + u16 word;
  34556. + //int ch;
  34557. + //u16 version;
  34558. + u8 hw_version;
  34559. + //u8 config3;
  34560. + struct usb_device *udev;
  34561. + u16 idProduct;
  34562. + u16 bcdDevice;
  34563. + //u8 chan_plan_index;
  34564. +
  34565. + //FIXME: these constants are placed in a bad pleace.
  34566. +
  34567. + //priv->txbuffsize = 1024;
  34568. + //priv->txringcount = 32;
  34569. + //priv->rxbuffersize = 1024;
  34570. + //priv->rxringcount = 32;
  34571. + //priv->txbeaconcount = 3;
  34572. + //priv->rx_skb_complete = 1;
  34573. + //priv->txnp_pending.ispending=0;
  34574. + /* ^^ the SKB does not containt a partial RXed packet (is empty) */
  34575. +
  34576. + //memcpy(priv->stats,0,sizeof(struct Stats));
  34577. +
  34578. + //priv->irq_enabled=0;
  34579. + priv->driver_upping = 0;
  34580. + priv->commit = 0;
  34581. +
  34582. + //priv->stats.rxdmafail=0;
  34583. + priv->stats.txrdu=0;
  34584. + //priv->stats.rxrdu=0;
  34585. + //priv->stats.rxnolast=0;
  34586. + //priv->stats.rxnodata=0;
  34587. + //priv->stats.rxreset=0;
  34588. + //priv->stats.rxwrkaround=0;
  34589. + //priv->stats.rxnopointer=0;
  34590. + priv->stats.txbeerr=0;
  34591. + priv->stats.txbkerr=0;
  34592. + priv->stats.txvierr=0;
  34593. + priv->stats.txvoerr=0;
  34594. + priv->stats.txmanageerr=0;
  34595. + priv->stats.txbeaconerr=0;
  34596. + priv->stats.txresumed=0;
  34597. + //priv->stats.rxerr=0;
  34598. + //priv->stats.rxoverflow=0;
  34599. + //priv->stats.rxint=0;
  34600. + priv->stats.txbeokint=0;
  34601. + priv->stats.txbkokint=0;
  34602. + priv->stats.txviokint=0;
  34603. + priv->stats.txvookint=0;
  34604. + priv->stats.txmanageokint=0;
  34605. + priv->stats.txbeaconokint=0;
  34606. + /*priv->stats.txhpokint=0;
  34607. + priv->stats.txhperr=0;*/
  34608. + priv->stats.rxurberr=0;
  34609. + priv->stats.rxstaterr=0;
  34610. + priv->stats.txoverflow=0;
  34611. + priv->stats.rxok=0;
  34612. + //priv->stats.txbeaconerr=0;
  34613. + //priv->stats.txlperr=0;
  34614. + //priv->stats.txlpokint=0;
  34615. +//john
  34616. + priv->stats.txnpdrop=0;
  34617. + priv->stats.txlpdrop =0;
  34618. + priv->stats.txbedrop =0;
  34619. + priv->stats.txbkdrop =0;
  34620. + priv->stats.txvidrop =0;
  34621. + priv->stats.txvodrop =0;
  34622. + priv->stats.txbeacondrop =0;
  34623. + priv->stats.txmanagedrop =0;
  34624. +
  34625. + // priv->stats.txokbytestotal =0;
  34626. +//by amy
  34627. + priv->LastSignalStrengthInPercent=0;
  34628. + priv->SignalStrength=0;
  34629. + priv->SignalQuality=0;
  34630. + priv->antenna_flag=0;
  34631. + priv->flag_beacon = false;
  34632. +//by amy
  34633. +//david
  34634. + //radion on defaultly
  34635. + priv->radion = 1;
  34636. +//david
  34637. +//by amy for rate adaptive
  34638. + priv->CurrRetryCnt=0;
  34639. + priv->LastRetryCnt=0;
  34640. + priv->LastTxokCnt=0;
  34641. + priv->LastRxokCnt=0;
  34642. + priv->LastRetryRate=0;
  34643. + priv->bTryuping=0;
  34644. + priv->CurrTxRate=0;
  34645. + priv->CurrRetryRate=0;
  34646. + priv->TryupingCount=0;
  34647. + priv->TryupingCountNoData=0;
  34648. + priv->TryDownCountLowData=0;
  34649. + priv->RecvSignalPower=0;
  34650. + priv->LastTxOKBytes=0;
  34651. + priv->LastFailTxRate=0;
  34652. + priv->LastFailTxRateSS=0;
  34653. + priv->FailTxRateCount=0;
  34654. + priv->LastTxThroughput=0;
  34655. + priv->txokbytestotal=0;
  34656. +//by amy for rate adaptive
  34657. +//by amy for ps
  34658. + priv->RFChangeInProgress = false;
  34659. + priv->SetRFPowerStateInProgress = false;
  34660. + priv->RFProgType = 0;
  34661. + priv->bInHctTest = false;
  34662. + priv->bInactivePs = true;//false;
  34663. + priv->ieee80211->bInactivePs = priv->bInactivePs;
  34664. + priv->eInactivePowerState = eRfOn;//lzm add for IPS and Polling methord
  34665. + priv->bSwRfProcessing = false;
  34666. + priv->eRFPowerState = eRfOff;
  34667. + priv->RfOffReason = 0;
  34668. + priv->NumRxOkInPeriod = 0;
  34669. + priv->NumTxOkInPeriod = 0;
  34670. + priv->bLeisurePs = true;
  34671. + priv->dot11PowerSaveMode = eActive;
  34672. + priv->RegThreeWireMode=HW_THREE_WIRE_BY_8051;
  34673. + priv->ps_mode = false;
  34674. +//by amy for ps
  34675. +//by amy for DIG
  34676. + priv->bDigMechanism = 1;
  34677. + priv->bCCKThMechanism = 0;
  34678. + priv->InitialGain = 0;
  34679. + priv->StageCCKTh = 0;
  34680. + priv->RegBModeGainStage = 2;
  34681. +//by amy for DIG
  34682. +// {by david for DIG, 2008.3.6
  34683. + priv->RegDigOfdmFaUpTh = 0x0c;
  34684. + priv->RegBModeGainStage = 0x02;
  34685. + priv->DIG_NumberFallbackVote = 0;
  34686. + priv->DIG_NumberUpgradeVote = 0;
  34687. + priv->CCKUpperTh = 0x100;
  34688. + priv->CCKLowerTh = 0x20;
  34689. +//}
  34690. +//{added by david for High tx power, 2008.3.11
  34691. + priv->bRegHighPowerMechanism = true;
  34692. + priv->bToUpdateTxPwr = false;
  34693. +
  34694. + priv->Z2HiPwrUpperTh = 77;
  34695. + priv->Z2HiPwrLowerTh = 75;
  34696. + priv->Z2RSSIHiPwrUpperTh = 70;
  34697. + priv->Z2RSSIHiPwrLowerTh = 20;
  34698. + //specify for rtl8187B
  34699. + priv->wMacRegRfPinsOutput = 0x0480;
  34700. + priv->wMacRegRfPinsSelect = 0x2488;
  34701. + //
  34702. + // Note that, we just set TrSwState to TR_HW_CONTROLLED here instead of changing
  34703. + // HW setting because we assume it should be inialized as HW controlled. 061010, by rcnjko.
  34704. + //
  34705. + priv->TrSwitchState = TR_HW_CONTROLLED;
  34706. +//}
  34707. + priv->ieee80211->iw_mode = IW_MODE_INFRA;
  34708. +//test pending bug, john 20070815
  34709. + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
  34710. +//by lizhaoming for LED
  34711. +#ifdef LED
  34712. + priv->ieee80211->ieee80211_led_contorl = LedControl8187;
  34713. +#endif
  34714. +#ifdef CONFIG_IPS
  34715. + priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;//IPSLeave;
  34716. +#endif
  34717. +
  34718. +#ifdef SW_ANTE_DIVERSITY
  34719. + priv->antb=0;
  34720. + priv->diversity=1;
  34721. + priv->LastRxPktAntenna = 0;
  34722. + priv->AdMinCheckPeriod = 5;
  34723. + priv->AdMaxCheckPeriod = 10;
  34724. + // Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
  34725. + priv->AdMaxRxSsThreshold = 30;//60->30
  34726. + priv->AdRxSsThreshold = 20;//50->20
  34727. + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
  34728. + priv->AdTickCount = 0;
  34729. + priv->AdRxSignalStrength = -1;
  34730. + priv->RegSwAntennaDiversityMechanism = 0;
  34731. + priv->RegDefaultAntenna = 0;
  34732. + priv->SignalStrength = 0;
  34733. + priv->AdRxOkCnt = 0;
  34734. + priv->CurrAntennaIndex = 0;
  34735. + priv->AdRxSsBeforeSwitched = 0;
  34736. + init_timer(&priv->SwAntennaDiversityTimer);
  34737. + priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
  34738. + priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
  34739. +#endif
  34740. +
  34741. + priv->retry_rts = DEFAULT_RETRY_RTS;
  34742. + priv->retry_data = DEFAULT_RETRY_DATA;
  34743. + priv->ieee80211->rate = 110; //11 mbps
  34744. + priv->CurrentOperaRate=priv->ieee80211->rate/5;
  34745. + priv->ieee80211->short_slot = 1;
  34746. + priv->ieee80211->mode = IEEE_G;
  34747. + priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
  34748. +
  34749. + rtl8180_link_detect_init(&priv->link_detect);
  34750. +
  34751. + spin_lock_init(&priv->tx_lock);
  34752. + spin_lock_init(&priv->irq_lock);//added by thomas
  34753. + spin_lock_init(&priv->rf_ps_lock);
  34754. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  34755. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  34756. + INIT_WORK(&priv->reset_wq, (void*)rtl8180_restart);
  34757. + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); //YJ,add,081230,for IPS
  34758. + INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);
  34759. + INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);
  34760. + INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq);
  34761. + INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);
  34762. +
  34763. +#ifdef SW_ANTE_DIVERSITY
  34764. + INIT_DELAYED_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback);
  34765. +#endif
  34766. +
  34767. +#else
  34768. + INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart,dev);
  34769. + INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq,dev); //YJ,add,081230,for IPS
  34770. + INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev);
  34771. + INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev);
  34772. + INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*)rtl8180_watch_dog_wq,dev);
  34773. + INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev);
  34774. +
  34775. +#ifdef SW_ANTE_DIVERSITY
  34776. + INIT_WORK(&priv->ieee80211->SwAntennaWorkItem,(void*) SwAntennaWorkItemCallback, dev);
  34777. +#endif
  34778. +
  34779. +#endif
  34780. +#else
  34781. + tq_init(&priv->reset_wq,(void*) rtl8180_restart,dev);
  34782. +#endif
  34783. + sema_init(&priv->wx_sem,1);
  34784. + sema_init(&priv->set_chan_sem,1);
  34785. +#ifdef THOMAS_TASKLET
  34786. + tasklet_init(&priv->irq_rx_tasklet,
  34787. + (void(*)(unsigned long))rtl8180_irq_rx_tasklet_new,
  34788. + (unsigned long)priv);
  34789. +#else
  34790. + tasklet_init(&priv->irq_rx_tasklet,
  34791. + (void(*)(unsigned long))rtl8180_irq_rx_tasklet,
  34792. + (unsigned long)priv);
  34793. +#endif
  34794. +//by amy for rate adaptive
  34795. + init_timer(&priv->rateadapter_timer);
  34796. + priv->rateadapter_timer.data = (unsigned long)dev;
  34797. + priv->rateadapter_timer.function = timer_rate_adaptive;
  34798. +//by amy for rate adaptive
  34799. +//by amy for ps
  34800. + init_timer(&priv->watch_dog_timer);
  34801. + priv->watch_dog_timer.data = (unsigned long)dev;
  34802. + priv->watch_dog_timer.function = watch_dog_adaptive;
  34803. +//by amy
  34804. +//by amy for ps
  34805. + priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
  34806. + priv->ieee80211->iw_mode = IW_MODE_INFRA;
  34807. + priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
  34808. + IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
  34809. +#ifdef CONFIG_SOFT_BEACON
  34810. + IEEE_SOFTMAC_BEACONS | //IEEE_SOFTMAC_SINGLE_QUEUE;
  34811. +#endif
  34812. + IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
  34813. +
  34814. + priv->ieee80211->active_scan = 1;
  34815. + //priv->ieee80211->ch_lock = 0;
  34816. + priv->ieee80211->rate = 110; //11 mbps
  34817. + priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
  34818. + priv->ieee80211->host_encrypt = 1;
  34819. + priv->ieee80211->host_decrypt = 1;
  34820. +#ifdef CONFIG_SOFT_BEACON
  34821. + priv->ieee80211->start_send_beacons = NULL;
  34822. + priv->ieee80211->stop_send_beacons = NULL;
  34823. +#else
  34824. + priv->ieee80211->start_send_beacons = rtl8187_beacon_tx;
  34825. + priv->ieee80211->stop_send_beacons = rtl8187_beacon_stop;
  34826. +#endif
  34827. + priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
  34828. + priv->ieee80211->set_chan = rtl8180_set_chan;
  34829. + priv->ieee80211->link_change = rtl8187_link_change;
  34830. + priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
  34831. + priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
  34832. + priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
  34833. +
  34834. +#ifdef _RTL8187_EXT_PATCH_
  34835. + priv->ieee80211->meshScanMode = 0;
  34836. + priv->mshobj = alloc_mshobj(priv);
  34837. + if(priv->mshobj)
  34838. + {
  34839. + priv->ieee80211->ext_patch_ieee80211_start_protocol = priv->mshobj->ext_patch_ieee80211_start_protocol;
  34840. + priv->ieee80211->ext_patch_ieee80211_stop_protocol = priv->mshobj->ext_patch_ieee80211_stop_protocol;
  34841. +//by amy for mesh
  34842. + priv->ieee80211->ext_patch_ieee80211_start_mesh = priv->mshobj->ext_patch_ieee80211_start_mesh;
  34843. +//by amy for mesh
  34844. + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = priv->mshobj->ext_patch_ieee80211_probe_req_1;
  34845. + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = priv->mshobj->ext_patch_ieee80211_probe_req_2;
  34846. + priv->ieee80211->ext_patch_ieee80211_association_req_1 = priv->mshobj->ext_patch_ieee80211_association_req_1;
  34847. + priv->ieee80211->ext_patch_ieee80211_association_req_2 = priv->mshobj->ext_patch_ieee80211_association_req_2;
  34848. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_1;
  34849. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = priv->mshobj->ext_patch_ieee80211_assoc_resp_by_net_2;
  34850. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_auth;
  34851. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_deauth;
  34852. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req;
  34853. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = priv->mshobj->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp;
  34854. + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = priv->mshobj->ext_patch_ieee80211_ext_stop_scan_wq_set_channel;
  34855. + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = priv->mshobj->ext_patch_ieee80211_process_probe_response_1;
  34856. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = priv->mshobj->ext_patch_ieee80211_rx_mgt_on_probe_req;
  34857. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = priv->mshobj->ext_patch_ieee80211_rx_mgt_update_expire;
  34858. + priv->ieee80211->ext_patch_get_beacon_get_probersp = priv->mshobj->ext_patch_get_beacon_get_probersp;
  34859. + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = priv->mshobj->ext_patch_ieee80211_rx_on_rx;
  34860. + priv->ieee80211->ext_patch_ieee80211_xmit = priv->mshobj->ext_patch_ieee80211_xmit;
  34861. + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = priv->mshobj->ext_patch_ieee80211_rx_frame_get_hdrlen;
  34862. + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = priv->mshobj->ext_patch_ieee80211_rx_is_valid_framectl;
  34863. + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = priv->mshobj->ext_patch_ieee80211_rx_process_dataframe;
  34864. + // priv->ieee80211->ext_patch_is_duplicate_packet = priv->mshobj->ext_patch_is_duplicate_packet;
  34865. + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = priv->mshobj->ext_patch_ieee80211_softmac_xmit_get_rate;
  34866. + /* added by david for setting acl dynamically */
  34867. + priv->ieee80211->ext_patch_ieee80211_acl_query = priv->mshobj->ext_patch_ieee80211_acl_query;
  34868. + }
  34869. +
  34870. +#endif // _RTL8187_EXT_PATCH_
  34871. +
  34872. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  34873. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  34874. + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
  34875. + (void(*)(void*)) rtl8180_wmm_param_update,\
  34876. + priv->ieee80211);
  34877. +#else
  34878. + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,\
  34879. + rtl8180_wmm_param_update);
  34880. +#endif
  34881. +#else
  34882. + tq_init(&priv->ieee80211->wmm_param_update_wq,\
  34883. + (void(*)(void*)) rtl8180_wmm_param_update,\
  34884. + priv->ieee80211);
  34885. +#endif
  34886. + priv->ieee80211->init_wmmparam_flag = 0;
  34887. + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
  34888. +
  34889. + //priv->card_8185 = 2;
  34890. + priv->phy_ver = 2;
  34891. + priv->card_type = USB;
  34892. +//{add for 87B
  34893. + priv->ShortRetryLimit = 7;
  34894. + priv->LongRetryLimit = 7;
  34895. + priv->EarlyRxThreshold = 7;
  34896. +
  34897. + priv->TransmitConfig =
  34898. + TCR_DurProcMode | //for RTL8185B, duration setting by HW
  34899. + TCR_DISReqQsize |
  34900. + (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
  34901. + (priv->ShortRetryLimit<<TX_SRLRETRY_SHIFT)| // Short retry limit
  34902. + (priv->LongRetryLimit<<TX_LRLRETRY_SHIFT) | // Long retry limit
  34903. + (false ? TCR_SWPLCPLEN : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
  34904. +
  34905. + priv->ReceiveConfig =
  34906. + RCR_AMF | RCR_ADF | //accept management/data
  34907. + RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
  34908. + RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
  34909. + //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
  34910. + RCR_MXDMA | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
  34911. + (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
  34912. + (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
  34913. +
  34914. + priv->AcmControl = 0;
  34915. +//}
  34916. + priv->rf_chip = 0xff & eprom_read(dev,EPROM_RFCHIPID);
  34917. + //DMESG("rf_chip:%x\n", priv->rf_chip);
  34918. + if (!priv->rf_chip)
  34919. + {
  34920. + DMESG("Can't get rf chip ID from EEPROM");
  34921. + DMESGW("So set rf chip ID to defalut EPROM_RFCHIPID_RTL8225U");
  34922. + DMESGW("use it with care and at your own risk and");
  34923. + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
  34924. + priv->rf_chip = EPROM_RFCHIPID_RTL8225U;
  34925. +
  34926. + }
  34927. +
  34928. +
  34929. +//{put the card to detect different card here, mainly I/O processing
  34930. + udev = priv->udev;
  34931. + idProduct = le16_to_cpu(udev->descriptor.idProduct);
  34932. + //idProduct = 0x8197;
  34933. + bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
  34934. + DMESG("idProduct:0x%x, bcdDevice:0x%x", idProduct,bcdDevice);
  34935. + switch (idProduct) {
  34936. + case 0x8189:
  34937. + case 0x8197:
  34938. + case 0x8198:
  34939. + /* check RF frontend chipset */
  34940. + priv->card_8187 = NIC_8187B;
  34941. + priv->rf_init = rtl8225z2_rf_init;
  34942. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  34943. + priv->rf_set_sens = NULL;
  34944. + break;
  34945. +
  34946. + case 0x8187:
  34947. + if(bcdDevice == 0x0200){
  34948. + priv->card_8187 = NIC_8187B;
  34949. + priv->rf_init = rtl8225z2_rf_init;
  34950. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  34951. + priv->rf_set_sens = NULL;
  34952. + break;
  34953. + }else{
  34954. + //0x0100 is for 8187
  34955. + //legacy 8187 NIC
  34956. + //delet
  34957. + ;
  34958. + }
  34959. + default:
  34960. + /* check RF frontend chipset */
  34961. + priv->ieee80211->softmac_features |= IEEE_SOFTMAC_SINGLE_QUEUE;
  34962. + priv->card_8187 = NIC_8187;
  34963. + switch (priv->rf_chip) {
  34964. + case EPROM_RFCHIPID_RTL8225U:
  34965. + DMESG("Card reports RF frontend Realtek 8225");
  34966. + DMESGW("This driver has EXPERIMENTAL support for this chipset.");
  34967. + DMESGW("use it with care and at your own risk and");
  34968. + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO Realtek");
  34969. + if(rtl8225_is_V_z2(dev)){
  34970. + priv->rf_init = rtl8225z2_rf_init;
  34971. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  34972. + priv->rf_set_sens = NULL;
  34973. + DMESG("This seems a new V2 radio");
  34974. + }else{
  34975. + priv->rf_init = rtl8225_rf_init;
  34976. + priv->rf_set_chan = rtl8225_rf_set_chan;
  34977. + priv->rf_set_sens = rtl8225_rf_set_sens;
  34978. + DMESG("This seems a legacy 1st version radio");
  34979. + }
  34980. + break;
  34981. +
  34982. + case EPROM_RFCHIPID_RTL8225U_VF:
  34983. + priv->rf_init = rtl8225z2_rf_init;
  34984. + priv->rf_set_chan = rtl8225z2_rf_set_chan;
  34985. + priv->rf_set_sens = NULL;
  34986. + DMESG("This seems a new V2 radio");
  34987. + break;
  34988. +
  34989. + default:
  34990. + DMESGW("Unknown RF module %x",priv->rf_chip);
  34991. + DMESGW("Exiting...");
  34992. + return -1;
  34993. + }
  34994. + break;
  34995. + }
  34996. +
  34997. + priv->rf_close = rtl8225_rf_close;
  34998. + priv->max_sens = RTL8225_RF_MAX_SENS;
  34999. + priv->sens = RTL8225_RF_DEF_SENS;
  35000. +
  35001. +#ifdef ENABLE_DOT11D
  35002. +#if 0
  35003. + for(i=0;i<0xFF;i++) {
  35004. + if(i%16 == 0)
  35005. + printk("\n[%x]: ", i/16);
  35006. + printk("\t%4.4x", eprom_read(dev,i));
  35007. + }
  35008. +#endif
  35009. + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xFF;
  35010. + //DMESG("EPROM_CHANNEL_PLAN is %x", priv->channel_plan);
  35011. +
  35012. + // lzm add 081205 for Toshiba:
  35013. + // For Toshiba,reading the value from EEPROM 0x6h bit[7] to determine the priority of
  35014. + // channel plan to be defined.
  35015. + // -If bit[7] is true, then the channel plan is defined by EEPROM but no user defined.
  35016. + // -If bit[7] is false, then the channel plan is defined by user first.
  35017. + //
  35018. + if(priv->channel_plan & 0x80) {
  35019. + DMESG("Toshiba channel plan is defined by EEPROM");
  35020. + priv->channel_plan &= 0xf;
  35021. + }
  35022. + else
  35023. + priv->channel_plan = 0;
  35024. +
  35025. + //if(priv->channel_plan > COUNTRY_CODE_WORLD_WIDE_13_INDEX){
  35026. + if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
  35027. + DMESG("rtl8180_init:Error channel plan! Set to default.\n");
  35028. + priv->channel_plan = 0;
  35029. + }
  35030. +
  35031. + //priv->channel_plan = 9; //Global Domain
  35032. + //priv->channel_plan = 2; //ETSI
  35033. +
  35034. +
  35035. + DMESG("Channel plan is %d ",priv->channel_plan);
  35036. +
  35037. + //for Toshiba card we read channel plan from ChanPlanBin
  35038. + if((idProduct != 0x8197) && (idProduct != 0x8198))
  35039. + rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
  35040. +#else
  35041. + int ch;
  35042. + priv->channel_plan = eprom_read(dev,EPROM_CHANNEL_PLAN) & 0xff;
  35043. + if(priv->channel_plan & 0x80) {
  35044. + priv->channel_plan &= 0x7f;
  35045. + if (ChannelPlan[priv->channel_plan].Len != 0){
  35046. + // force channel plan map
  35047. + for (i=0;i<ChannelPlan[priv->channel_plan].Len;i++)
  35048. + priv->ieee80211->channel_map[ChannelPlan[priv->channel_plan].Channel[i]] = 1;
  35049. + } else {
  35050. + DMESG("No channels, aborting");
  35051. + return -1;
  35052. + }
  35053. + } else {
  35054. + //default channel plan setting
  35055. + if(!channels){
  35056. + DMESG("No channels, aborting");
  35057. + return -1;
  35058. + }
  35059. + ch=channels;
  35060. + // set channels 1..14 allowed in given locale
  35061. + for (i=1; i<=14; i++) {
  35062. + (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
  35063. + ch >>= 1;
  35064. + }
  35065. + }
  35066. +#endif
  35067. +
  35068. + if((idProduct == 0x8197) || (idProduct == 0x8198)) {
  35069. + // lzm add 081205 for Toshiba:
  35070. + // 0x77h bit[0]=1: use GPIO bit[2], bit[0]=0: use GPIO bit[1]
  35071. + priv->EEPROMSelectNewGPIO =((u8)((eprom_read(dev,EPROM_SELECT_GPIO) & 0xff00) >> 8)) ? true : false;
  35072. + DMESG("EPROM_SELECT_GPIO:%d", priv->EEPROMSelectNewGPIO);
  35073. + } else {
  35074. + priv->EEPROMSelectNewGPIO = false;
  35075. + }
  35076. +
  35077. +
  35078. + if (NIC_8187 == priv->card_8187){
  35079. + hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
  35080. + switch (hw_version) {
  35081. + case 0x06:
  35082. + //priv->card_8187_Bversion = VERSION_8187B_B;
  35083. + break;
  35084. + case 0x05:
  35085. + priv->card_8187_Bversion = VERSION_8187_D;
  35086. + break;
  35087. + default:
  35088. + priv->card_8187_Bversion = VERSION_8187_B;
  35089. + break;
  35090. + }
  35091. + }else{
  35092. + hw_version = read_nic_byte(dev, 0xe1); //87B hw version reg
  35093. + switch (hw_version){
  35094. + case 0x00:
  35095. + priv->card_8187_Bversion = VERSION_8187B_B;
  35096. + break;
  35097. + case 0x01:
  35098. + priv->card_8187_Bversion = VERSION_8187B_D;
  35099. + break;
  35100. + case 0x02:
  35101. + priv->card_8187_Bversion = VERSION_8187B_E;
  35102. + break;
  35103. + default:
  35104. + priv->card_8187_Bversion = VERSION_8187B_B; //defalt
  35105. + break;
  35106. + }
  35107. + }
  35108. +
  35109. + //printk("=====hw_version:%x\n", priv->card_8187_Bversion);
  35110. + priv->enable_gpio0 = 0;
  35111. +
  35112. + /*the eeprom type is stored in RCR register bit #6 */
  35113. + if (RCR_9356SEL & read_nic_dword(dev, RCR)){
  35114. + priv->epromtype=EPROM_93c56;
  35115. + DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
  35116. + }else{
  35117. + priv->epromtype=EPROM_93c46;
  35118. + DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
  35119. + }
  35120. +
  35121. + dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
  35122. + dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
  35123. + dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
  35124. + dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
  35125. + dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
  35126. + dev->dev_addr[5]=((eprom_read(dev,MAC_ADR+2) & 0xff00)>>8)+1;
  35127. +
  35128. + DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
  35129. +
  35130. + for(i=1,j=0; i<6; i+=2,j++){
  35131. +
  35132. + word = eprom_read(dev,EPROM_TXPW0 + j);
  35133. + priv->chtxpwr[i]=word & 0xf;
  35134. + priv->chtxpwr_ofdm[i]=(word & 0xf0)>>4;
  35135. + priv->chtxpwr[i+1]=(word & 0xf00)>>8;
  35136. + priv->chtxpwr_ofdm[i+1]=(word & 0xf000)>>12;
  35137. + }
  35138. +
  35139. + for(i=1,j=0; i<4; i+=2,j++){
  35140. +
  35141. + word = eprom_read(dev,EPROM_TXPW1 + j);
  35142. + priv->chtxpwr[i+6]=word & 0xf;
  35143. + priv->chtxpwr_ofdm[i+6]=(word & 0xf0)>>4;
  35144. + priv->chtxpwr[i+6+1]=(word & 0xf00)>>8;
  35145. + priv->chtxpwr_ofdm[i+6+1]=(word & 0xf000)>>12;
  35146. + }
  35147. + if (priv->card_8187 == NIC_8187){
  35148. + for(i=1,j=0; i<4; i+=2,j++){
  35149. + word = eprom_read(dev,EPROM_TXPW2 + j);
  35150. + priv->chtxpwr[i+6+4]=word & 0xf;
  35151. + priv->chtxpwr_ofdm[i+6+4]=(word & 0xf0)>>4;
  35152. + priv->chtxpwr[i+6+4+1]=(word & 0xf00)>>8;
  35153. + priv->chtxpwr_ofdm[i+6+4+1]=(word & 0xf000)>>12;
  35154. + }
  35155. + } else{
  35156. + word = eprom_read(dev, 0x1B) & 0xff; //channel 11;
  35157. + priv->chtxpwr[11]=word & 0xf;
  35158. + priv->chtxpwr_ofdm[11] = (word & 0xf0)>>4;
  35159. +
  35160. + word = eprom_read(dev, 0xA) & 0xff; //channel 12;
  35161. + priv->chtxpwr[12]=word & 0xf;
  35162. + priv->chtxpwr_ofdm[12] = (word & 0xf0)>>4;
  35163. +
  35164. + word = eprom_read(dev, 0x1c) ; //channel 13 ,14;
  35165. + priv->chtxpwr[13]=word & 0xf;
  35166. + priv->chtxpwr_ofdm[13] = (word & 0xf0)>>4;
  35167. + priv->chtxpwr[14]=(word & 0xf00)>>8;
  35168. + priv->chtxpwr_ofdm[14] = (word & 0xf000)>>12;
  35169. + }
  35170. +
  35171. + word = eprom_read(dev,EPROM_TXPW_BASE);
  35172. + priv->cck_txpwr_base = word & 0xf;
  35173. + priv->ofdm_txpwr_base = (word>>4) & 0xf;
  35174. +
  35175. + //DMESG("PAPE from CONFIG2: %x",read_nic_byte(dev,CONFIG2)&0x7);
  35176. +
  35177. +#ifdef SW_ANTE_DIVERSITY
  35178. + rtl8187_antenna_diversity_read(dev);
  35179. +#endif
  35180. +
  35181. + if(rtl8187_usb_initendpoints(dev)!=0){
  35182. + DMESG("Endopoints initialization failed");
  35183. + return -ENOMEM;
  35184. + }
  35185. +#ifdef LED
  35186. + InitSwLeds(dev);
  35187. +#endif
  35188. +#ifdef DEBUG_EPROM
  35189. + dump_eprom(dev);
  35190. +#endif
  35191. + return 0;
  35192. +
  35193. +}
  35194. +
  35195. +void rtl8185_rf_pins_enable(struct net_device *dev)
  35196. +{
  35197. +/* u16 tmp;
  35198. + tmp = read_nic_word(dev, RFPinsEnable);*/
  35199. + write_nic_word(dev, RFPinsEnable, 0x1ff7);// | tmp);
  35200. +}
  35201. +
  35202. +
  35203. +void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
  35204. +{
  35205. + u8 conf3;
  35206. +
  35207. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  35208. +
  35209. + conf3 = read_nic_byte(dev, CONFIG3);
  35210. + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
  35211. +
  35212. + write_nic_dword(dev, ANAPARAM2, a);
  35213. +
  35214. + conf3 = read_nic_byte(dev, CONFIG3);
  35215. + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
  35216. +
  35217. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  35218. +
  35219. +}
  35220. +
  35221. +
  35222. +void rtl8180_set_anaparam(struct net_device *dev, u32 a)
  35223. +{
  35224. + u8 conf3;
  35225. +
  35226. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  35227. +
  35228. + conf3 = read_nic_byte(dev, CONFIG3);
  35229. + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
  35230. +
  35231. + write_nic_dword(dev, ANAPARAM, a);
  35232. +
  35233. + conf3 = read_nic_byte(dev, CONFIG3);
  35234. + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
  35235. +
  35236. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  35237. +
  35238. +}
  35239. +
  35240. +
  35241. +void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
  35242. +{
  35243. + write_nic_byte(dev, ANTSEL, ant);
  35244. + //lzm mod for up take too long time 20081201
  35245. + //mdelay(1);
  35246. +}
  35247. +
  35248. +
  35249. +void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data)
  35250. +{
  35251. + u32 phyw;
  35252. +
  35253. + adr |= 0x80;
  35254. +
  35255. + phyw= ((data<<8) | adr);
  35256. +
  35257. +
  35258. +
  35259. + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
  35260. + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
  35261. + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
  35262. + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
  35263. + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
  35264. +
  35265. + //read_nic_dword(dev, PHY_ADR);
  35266. +#if 0
  35267. + for(i=0;i<10;i++){
  35268. + write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
  35269. + phyr = read_nic_byte(dev, PHY_READ);
  35270. + if(phyr == (data&0xff)) break;
  35271. +
  35272. + }
  35273. +#endif
  35274. + /* this is ok to fail when we write AGC table. check for AGC table might be
  35275. + * done by masking with 0x7f instead of 0xff */
  35276. + //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data, adr);
  35277. + //msdelay(1);//CPU occupany is too high. LZM 31/10/2008
  35278. +}
  35279. +
  35280. +u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data)
  35281. +{
  35282. + u32 phyw;
  35283. +
  35284. + adr &= ~0x80;
  35285. + phyw= ((data<<8) | adr);
  35286. +
  35287. +
  35288. + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
  35289. + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
  35290. + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
  35291. + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
  35292. + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
  35293. +
  35294. + return(read_nic_byte(dev,0x7e));
  35295. +
  35296. +}
  35297. +
  35298. +u8 read_phy_ofdm(struct net_device *dev, u8 adr)
  35299. +{
  35300. + return(rtl8187_read_phy(dev, adr, 0x000000));
  35301. +}
  35302. +
  35303. +u8 read_phy_cck(struct net_device *dev, u8 adr)
  35304. +{
  35305. + return(rtl8187_read_phy(dev, adr, 0x10000));
  35306. +}
  35307. +
  35308. +inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
  35309. +{
  35310. + data = data & 0xff;
  35311. + rtl8187_write_phy(dev, adr, data);
  35312. +}
  35313. +
  35314. +
  35315. +void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
  35316. +{
  35317. + data = data & 0xff;
  35318. + rtl8187_write_phy(dev, adr, data | 0x10000);
  35319. +}
  35320. +//
  35321. +// Description: Change ZEBRA's power state.
  35322. +//
  35323. +// Assumption: This function must be executed in PASSIVE_LEVEL.
  35324. +//
  35325. +// 061214, by rcnjko.
  35326. +//
  35327. +//#define MAX_DOZE_WAITING_TIMES_87B 1000//500
  35328. +#define MAX_DOZE_WAITING_TIMES_87B_MOD 500
  35329. +
  35330. +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
  35331. +{
  35332. + struct r8180_priv *priv = ieee80211_priv(dev);
  35333. + u8 btCR9346, btConfig3;
  35334. + bool bResult = true;
  35335. + int i;
  35336. + u16 u2bTFPC = 0;
  35337. + u8 u1bTmp;
  35338. +
  35339. + // Set EEM0 and EEM1 in 9346CR.
  35340. + btCR9346 = read_nic_byte(dev, CR9346);
  35341. + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
  35342. + // Set PARM_En in Config3.
  35343. + btConfig3 = read_nic_byte(dev, CONFIG3);
  35344. + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
  35345. + // BB and RF related operations:
  35346. + switch(eRFPowerState)
  35347. + {
  35348. + case eRfOn:
  35349. +#ifdef CONFIG_RADIO_DEBUG
  35350. + DMESG("Now Radio ON!");
  35351. +#endif
  35352. + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
  35353. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
  35354. + //write_nic_byte(dev, CONFIG4, (priv->RFProgType));
  35355. +
  35356. + write_nic_byte(dev, 0x085, 0x24); // 061219, SD3 ED: for minicard CCK power leakage issue.
  35357. + write_rtl8225(dev, 0x4, 0x9FF);
  35358. + mdelay(1);
  35359. + //
  35360. + // <Roger_Notes> We reset PLL to reduce power consumption about 30 mA. 2008.01.16.
  35361. + //
  35362. + {
  35363. + u8 Reg62;
  35364. +
  35365. + write_nic_byte(dev, 0x61, 0x10);
  35366. + Reg62 = read_nic_byte(dev, 0x62);
  35367. + write_nic_byte(dev, 0x62, (Reg62 & (~BIT5)) );
  35368. + write_nic_byte(dev, 0x62, (Reg62 | BIT5) ); // Enable PLL.
  35369. + }
  35370. +
  35371. + u1bTmp = read_nic_byte(dev, 0x24E);
  35372. + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
  35373. + break;
  35374. +
  35375. + case eRfSleep:
  35376. +#ifdef CONFIG_RADIO_DEBUG
  35377. + DMESG("Now Radio Sleep!");
  35378. +#endif
  35379. + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
  35380. + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
  35381. + u2bTFPC = read_nic_word(dev, TFPC);
  35382. + if(u2bTFPC == 0){
  35383. + //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
  35384. + break;
  35385. + }else{
  35386. + //printk("%d times TFPC: %d != 0 before doze!\n", (i+1), u2bTFPC);
  35387. + udelay(10);
  35388. + }
  35389. + }
  35390. +
  35391. + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD ){
  35392. + //printk("\n\n\n SetZebraRFPowerState8187B(): %d times TFPC: %d != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
  35393. + }
  35394. +
  35395. + u1bTmp = read_nic_byte(dev, 0x24E);
  35396. + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
  35397. +
  35398. + write_rtl8225(dev, 0x4, 0xDFF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
  35399. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
  35400. +
  35401. + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
  35402. +
  35403. + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
  35404. + write_nic_dword(dev, ANAPARAM2, 0x72303f70); // 070126, by SD1 William.
  35405. + break;
  35406. +
  35407. + case eRfOff:
  35408. +#ifdef CONFIG_RADIO_DEBUG
  35409. + DMESG("Now Radio OFF!");
  35410. +#endif
  35411. + for(i = 0; i < MAX_DOZE_WAITING_TIMES_87B_MOD; i++)
  35412. + { // Make sure TX FIFO is empty befor turn off RFE pwoer.
  35413. + u2bTFPC = read_nic_word(dev, TFPC);
  35414. + if(u2bTFPC == 0) {
  35415. + //printk("%d times TFPC: %d == 0 before doze...\n", (i+1), u2bTFPC);
  35416. + break;
  35417. + }else{
  35418. + //printk("%d times TFPC: 0x%x != 0 before doze!\n", (i+1), u2bTFPC);
  35419. + udelay(10);
  35420. + }
  35421. + }
  35422. +
  35423. + if( i == MAX_DOZE_WAITING_TIMES_87B_MOD){
  35424. + //printk("\n\n\nSetZebraRFPowerState8187B(): %d times TFPC: 0x%x != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_87B_MOD, u2bTFPC);
  35425. + }
  35426. +
  35427. + u1bTmp = read_nic_byte(dev, 0x24E);
  35428. + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));// 070124 SD1 Alex: turn off CCK and OFDM.
  35429. +
  35430. + write_rtl8225(dev, 0x4,0x1FF); // Turn off RF first to prevent BB lock up, suggested by PJ, 2006.03.03.
  35431. + write_nic_byte(dev, 0x085, 0x04); // 061219, SD3 ED: for minicard CCK power leakage issue.
  35432. +
  35433. + //write_nic_byte(dev, CONFIG4, (priv->RFProgType|Config4_PowerOff));
  35434. +
  35435. + write_nic_dword(dev, ANAPARAM, ANAPARM_OFF);
  35436. + write_nic_dword(dev, ANAPARAM2, ANAPARM2_OFF); // 070301, SD1 William: to reduce RF off power consumption to 80 mA.
  35437. + break;
  35438. +
  35439. + default:
  35440. + bResult = false;
  35441. + //printk("SetZebraRFPowerState8187B(): unknow state to set: 0x%X!!!\n", eRFPowerState);
  35442. + break;
  35443. + }
  35444. +
  35445. + // Clear PARM_En in Config3.
  35446. + btConfig3 &= ~(CONFIG3_PARM_En);
  35447. + write_nic_byte(dev, CONFIG3, btConfig3);
  35448. + // Clear EEM0 and EEM1 in 9346CR.
  35449. + btCR9346 &= ~(0xC0);
  35450. + write_nic_byte(dev, CR9346, btCR9346);
  35451. +
  35452. + if(bResult){
  35453. + // Update current RF state variable.
  35454. + priv->eRFPowerState = eRFPowerState;
  35455. + }
  35456. +
  35457. + return bResult;
  35458. +}
  35459. +//by amy for ps
  35460. +//
  35461. +// Description: Chang RF Power State.
  35462. +// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
  35463. +//
  35464. +// Assumption:PASSIVE LEVEL.
  35465. +//
  35466. +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState)
  35467. +{
  35468. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  35469. + bool bResult = false;
  35470. +
  35471. + //printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
  35472. + if(eRFPowerState == priv->eRFPowerState)
  35473. + {
  35474. + //printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
  35475. + return bResult;
  35476. + }
  35477. +
  35478. + switch(priv->rf_chip)
  35479. + {
  35480. + case RF_ZEBRA2:
  35481. + bResult = SetZebraRFPowerState8187B(dev, eRFPowerState);
  35482. + break;
  35483. +
  35484. + default:
  35485. + printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
  35486. + break;;
  35487. + }
  35488. + //printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
  35489. +
  35490. + return bResult;
  35491. +}
  35492. +
  35493. +bool
  35494. +MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource)
  35495. +{
  35496. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  35497. + bool bActionAllowed = false;
  35498. + bool bConnectBySSID = false;
  35499. + RT_RF_POWER_STATE rtState;
  35500. + u16 RFWaitCounter = 0;
  35501. + unsigned long flag;
  35502. + // printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
  35503. + //
  35504. + // Prevent the race condition of RF state change. By Bruce, 2007-11-28.
  35505. + // Only one thread can change the RF state at one time, and others should wait to be executed.
  35506. + //
  35507. +#if 1
  35508. + while(true)
  35509. + {
  35510. + //down(&priv->rf_state);
  35511. + spin_lock_irqsave(&priv->rf_ps_lock,flag);
  35512. + if(priv->RFChangeInProgress)
  35513. + {
  35514. + //up(&priv->rf_state);
  35515. + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
  35516. + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
  35517. + // Set RF after the previous action is done.
  35518. + while(priv->RFChangeInProgress)
  35519. + {
  35520. + RFWaitCounter ++;
  35521. + //RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
  35522. + udelay(1000); // 1 ms
  35523. +
  35524. + // Wait too long, return FALSE to avoid to be stuck here.
  35525. + if(RFWaitCounter > 1000) // 1sec
  35526. + {
  35527. + // DMESG("MgntActSet_RF_State(): Wait too long to set RF");
  35528. + // TODO: Reset RF state?
  35529. + return false;
  35530. + }
  35531. + }
  35532. + }
  35533. + else
  35534. + {
  35535. + priv->RFChangeInProgress = true;
  35536. +// up(&priv->rf_state);
  35537. + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
  35538. + break;
  35539. + }
  35540. + }
  35541. +#endif
  35542. + rtState = priv->eRFPowerState;
  35543. +
  35544. + switch(StateToSet)
  35545. + {
  35546. + case eRfOn:
  35547. + //
  35548. + // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
  35549. + // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
  35550. + //
  35551. + // leave last reasons and kick this reason till priv->RfOffReason = 0;
  35552. + // if one reason turn radio off check if off->on reason is the same.if so turn, or reject it.
  35553. + // if more than 1 reasons turn radio off we only turn on radio when all reasons turn on radio,
  35554. + // so first turn on trys will reject till priv->RfOffReason = 0;
  35555. + priv->RfOffReason &= (~ChangeSource);
  35556. +
  35557. + if(! priv->RfOffReason)
  35558. + {
  35559. + priv->RfOffReason = 0;
  35560. + bActionAllowed = true;
  35561. +
  35562. + if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest)
  35563. + {
  35564. + bConnectBySSID = true;
  35565. + }
  35566. + } else {
  35567. + ;//lzm must or TX_PENDING 12>MAX_TX_URB
  35568. + //printk("Turn Radio On Reject because RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
  35569. + }
  35570. + break;
  35571. +
  35572. + case eRfOff:
  35573. + // 070125, rcnjko: we always keep connected in AP mode.
  35574. + if (priv->RfOffReason > RF_CHANGE_BY_IPS)
  35575. + {
  35576. + //
  35577. + // 060808, Annie:
  35578. + // Disconnect to current BSS when radio off. Asked by QuanTa.
  35579. + //
  35580. +
  35581. + //
  35582. + // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
  35583. + // because we do NOT need to set ssid to dummy ones.
  35584. + // Revised by Roger, 2007.12.04.
  35585. + //
  35586. +//by amy not supported
  35587. + //MgntDisconnect( dev, disas_lv_ss );
  35588. +
  35589. + // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
  35590. + // 2007.05.28, by shien chang.
  35591. + //PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
  35592. + //pMgntInfo->NumBssDesc = 0;
  35593. + //PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
  35594. + //pMgntInfo->NumBssDesc4Query = 0;
  35595. + }
  35596. +
  35597. +
  35598. +
  35599. + priv->RfOffReason |= ChangeSource;
  35600. + bActionAllowed = true;
  35601. + //printk("Turn Radio Off RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource);
  35602. + break;
  35603. +
  35604. + case eRfSleep:
  35605. + priv->RfOffReason |= ChangeSource;
  35606. + bActionAllowed = true;
  35607. + break;
  35608. +
  35609. + default:
  35610. + break;
  35611. + }
  35612. +
  35613. + if(bActionAllowed)
  35614. + {
  35615. + // Config HW to the specified mode.
  35616. + //printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
  35617. + SetRFPowerState(dev, StateToSet);
  35618. + // Turn on RF.
  35619. + if(StateToSet == eRfOn)
  35620. + {
  35621. + //HalEnableRx8185Dummy(dev);
  35622. + if(bConnectBySSID)
  35623. + {
  35624. + // by amy not supported
  35625. + //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
  35626. + }
  35627. + }
  35628. + // Turn off RF.
  35629. + else if(StateToSet == eRfOff)
  35630. + {
  35631. + //HalDisableRx8185Dummy(dev);
  35632. + }
  35633. + }
  35634. + else
  35635. + {
  35636. + //printk("Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n",
  35637. + // StateToSet, ChangeSource, priv->RfOffReason);
  35638. + }
  35639. +
  35640. + // Release RF spinlock
  35641. + //down(&priv->rf_state);
  35642. + spin_lock_irqsave(&priv->rf_ps_lock,flag);
  35643. + priv->RFChangeInProgress = false;
  35644. + //up(&priv->rf_state);
  35645. + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
  35646. + return bActionAllowed;
  35647. +}
  35648. +//by amy for ps
  35649. +
  35650. +void rtl8180_adapter_start(struct net_device *dev)
  35651. +{
  35652. + struct r8180_priv *priv = ieee80211_priv(dev);
  35653. +// struct ieee80211_device *ieee = priv->ieee80211;
  35654. +// u8 InitWirelessMode;
  35655. +// u8 SupportedWirelessMode;
  35656. +// bool bInvalidWirelessMode = false;
  35657. +
  35658. +
  35659. + if(NIC_8187 == priv->card_8187) {
  35660. + //rtl8180_rtx_disable(dev);
  35661. + rtl8180_reset(dev);
  35662. +
  35663. + write_nic_byte(dev,0x85,0);
  35664. + write_nic_byte(dev,0x91,0);
  35665. +
  35666. + /* light blink! */
  35667. + write_nic_byte(dev,0x85,4);
  35668. + write_nic_byte(dev,0x91,1);
  35669. + write_nic_byte(dev,0x90,0);
  35670. +
  35671. + //by lizhaoming for LED POWR ON
  35672. + //LedControl8187(dev, LED_CTL_POWER_ON);
  35673. +
  35674. + /*
  35675. + write_nic_byte(dev, CR9346, 0xC0);
  35676. + //LED TYPE
  35677. + write_nic_byte(dev, CONFIG1,((read_nic_byte(dev, CONFIG1)&0x3f)|0x80)); //turn on bit 5:Clkrun_mode
  35678. + write_nic_byte(dev, CR9346, 0x0); // disable config register write
  35679. + */
  35680. + priv->irq_mask = 0xffff;
  35681. + /*
  35682. + priv->dma_poll_mask = 0;
  35683. + priv->dma_poll_mask|= (1<<TX_DMA_STOP_BEACON_SHIFT);
  35684. + */
  35685. + // rtl8180_beacon_tx_disable(dev);
  35686. +
  35687. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  35688. + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
  35689. + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
  35690. +
  35691. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  35692. + rtl8180_update_msr(dev);
  35693. +
  35694. + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
  35695. +
  35696. + write_nic_word(dev,0xf4,0xffff);
  35697. + write_nic_byte(dev,
  35698. + CONFIG1, (read_nic_byte(dev,CONFIG1) & 0x3f) | 0x80);
  35699. +
  35700. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  35701. +
  35702. + write_nic_dword(dev,INT_TIMEOUT,0);
  35703. +
  35704. +#ifdef DEBUG_REGISTERS
  35705. + rtl8180_dump_reg(dev);
  35706. +#endif
  35707. +
  35708. +
  35709. + write_nic_byte(dev, WPA_CONFIG, 0);
  35710. +
  35711. + write_nic_byte(dev, RATE_FALLBACK, 0x81);
  35712. + rtl8187_set_rate(dev);
  35713. +
  35714. + priv->rf_init(dev);
  35715. +
  35716. + if(priv->rf_set_sens != NULL) {
  35717. + priv->rf_set_sens(dev,priv->sens);
  35718. + }
  35719. +
  35720. + write_nic_word(dev,0x5e,1);
  35721. + //mdelay(1);
  35722. + write_nic_word(dev,0xfe,0x10);
  35723. + // mdelay(1);
  35724. + write_nic_byte(dev, TALLY_SEL, 0x80);//Set NQ retry count
  35725. + write_nic_byte(dev, 0xff, 0x60);
  35726. + write_nic_word(dev,0x5e,0);
  35727. +
  35728. + rtl8180_irq_enable(dev);
  35729. + } else {
  35730. + /**
  35731. + * IO part migrated from Windows Driver.
  35732. + */
  35733. + priv->irq_mask = 0xffff;
  35734. + // Enable Config3.PARAM_En.
  35735. + write_nic_byte(dev, CR9346, 0xC0);
  35736. +
  35737. + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)| CONFIG3_PARM_En|CONFIG3_GNTSel));
  35738. + // Turn on Analog power.
  35739. + // setup A/D D/A parameter for 8185 b2
  35740. + // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
  35741. + write_nic_dword(dev, ANA_PARAM2, ANAPARM2_ASIC_ON);
  35742. + write_nic_dword(dev, ANA_PARAM, ANAPARM_ASIC_ON);
  35743. + write_nic_byte(dev, ANA_PARAM3, 0x00);
  35744. +
  35745. + //by lizhaoming for LED POWR ON
  35746. + //LedControl8187(dev, LED_CTL_POWER_ON);
  35747. +
  35748. + {//added for reset PLL
  35749. + u8 bReg62;
  35750. + write_nic_byte(dev, 0x61, 0x10);
  35751. + bReg62 = read_nic_byte(dev, 0x62);
  35752. + write_nic_byte(dev, 0x62, bReg62&(~(0x1<<5)));
  35753. + write_nic_byte(dev, 0x62, bReg62|(0x1<<5));
  35754. + }
  35755. + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
  35756. + write_nic_byte(dev, CR9346, 0x00);
  35757. +
  35758. + //rtl8180_rtx_disable(dev);
  35759. + rtl8180_reset(dev);
  35760. + write_nic_byte(dev, CR9346, 0xc0); // enable config register write
  35761. + priv->rf_init(dev);
  35762. + // Enable tx/rx
  35763. +
  35764. + write_nic_byte(dev, CMD, (CR_RE|CR_TE));// Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
  35765. +
  35766. + //add this is for 8187B Rx stall problem
  35767. +
  35768. + rtl8180_irq_enable(dev);
  35769. +
  35770. + write_nic_byte_E(dev, 0x41, 0xF4);
  35771. + write_nic_byte_E(dev, 0x40, 0x00);
  35772. + write_nic_byte_E(dev, 0x42, 0x00);
  35773. + write_nic_byte_E(dev, 0x42, 0x01);
  35774. + write_nic_byte_E(dev, 0x40, 0x0F);
  35775. + write_nic_byte_E(dev, 0x42, 0x00);
  35776. + write_nic_byte_E(dev, 0x42, 0x01);
  35777. +
  35778. + // 8187B demo board MAC and AFE power saving parameters from SD1 William, 2006.07.20.
  35779. + // Parameter revised by SD1 William, 2006.08.21:
  35780. + // 373h -> 0x4F // Original: 0x0F
  35781. + // 377h -> 0x59 // Original: 0x4F
  35782. + // Victor 2006/8/21: 竅�繒q簞�翹�竄��糧繕瞼SD3 簞穠禮C繚� and cable link test OK瞻~瞼聶礎癒 release,瞻瞿竄��糧瞻�禮�
  35783. + // 2006/9/5, Victor & ED: it is OK to use.
  35784. + //if(pHalData->RegBoardType == BT_DEMO_BOARD)
  35785. + //{
  35786. + // AFE.
  35787. + //
  35788. + // Revise the content of Reg0x372, 0x374, 0x378 and 0x37a to fix unusual electronic current
  35789. + // while CTS-To-Self occurs, by DZ's request.
  35790. + // Modified by Roger, 2007.06.22.
  35791. + //
  35792. + write_nic_byte(dev, 0x0DB, (read_nic_byte(dev, 0x0DB)|(BIT2)));
  35793. + write_nic_word(dev, 0x372, 0x59FA); // 0x4FFA-> 0x59FA.
  35794. + write_nic_word(dev, 0x374, 0x59D2); // 0x4FD2-> 0x59D2.
  35795. + write_nic_word(dev, 0x376, 0x59D2);
  35796. + write_nic_word(dev, 0x378, 0x19FA); // 0x0FFA-> 0x19FA.
  35797. + write_nic_word(dev, 0x37A, 0x19FA); // 0x0FFA-> 0x19FA.
  35798. + write_nic_word(dev, 0x37C, 0x00D0);
  35799. +
  35800. + write_nic_byte(dev, 0x061, 0x00);
  35801. +
  35802. + // MAC.
  35803. + write_nic_byte(dev, 0x180, 0x0F);
  35804. + write_nic_byte(dev, 0x183, 0x03);
  35805. + // 061218, lanhsin: for victorh request
  35806. + write_nic_byte(dev, 0x0DA, 0x10);
  35807. + //}
  35808. +
  35809. + //
  35810. + // 061213, rcnjko:
  35811. + // Set MAC.0x24D to 0x00 to prevent cts-to-self Tx/Rx stall symptom.
  35812. + // If we set MAC 0x24D to 0x08, OFDM and CCK will turn off
  35813. + // if not in use, and there is a bug about this action when
  35814. + // we try to send CCK CTS and OFDM data together.
  35815. + //
  35816. + //PlatformEFIOWrite1Byte(Adapter, 0x24D, 0x00);
  35817. + // 061218, lanhsin: for victorh request
  35818. + write_nic_byte(dev, 0x24D, 0x08);
  35819. +
  35820. + //
  35821. + // 061215, rcnjko:
  35822. + // Follow SD3 RTL8185B_87B_MacPhy_Register.doc v0.4.
  35823. + //
  35824. + write_nic_dword(dev, HSSI_PARA, 0x0600321B);
  35825. + //
  35826. + // 061226, rcnjko:
  35827. + // Babble found in HCT 2c_simultaneous test, server with 87B might
  35828. + // receive a packet size about 2xxx bytes.
  35829. + // So, we restrict RMS to 2048 (0x800), while as IC default value is 0xC00.
  35830. + //
  35831. + write_nic_word(dev, RMS, 0x0800);
  35832. +
  35833. + /*****20070321 Resolve HW page bug on system logo test
  35834. + u8 faketemp=read_nic_byte(dev, 0x50);*/
  35835. + }
  35836. +}
  35837. +
  35838. +/* this configures registers for beacon tx and enables it via
  35839. + * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
  35840. + * be used to stop beacon transmission
  35841. + */
  35842. +#if 0
  35843. +void rtl8180_start_tx_beacon(struct net_device *dev)
  35844. +{
  35845. + int i;
  35846. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  35847. + u16 word;
  35848. + DMESG("Enabling beacon TX");
  35849. + //write_nic_byte(dev, 0x42,0xe6);// TCR
  35850. + //rtl8180_init_beacon(dev);
  35851. + //set_nic_txring(dev);
  35852. +// rtl8180_prepare_beacon(dev);
  35853. + rtl8180_irq_disable(dev);
  35854. +// rtl8180_beacon_tx_enable(dev);
  35855. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  35856. + //write_nic_byte(dev,0x9d,0x20); //DMA Poll
  35857. + //write_nic_word(dev,0x7a,0);
  35858. + //write_nic_word(dev,0x7a,0x8000);
  35859. +
  35860. +
  35861. + word = read_nic_word(dev, BcnItv);
  35862. + word &= ~BcnItv_BcnItv; // clear Bcn_Itv
  35863. + write_nic_word(dev, BcnItv, word);
  35864. +
  35865. + write_nic_word(dev, AtimWnd,
  35866. + read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
  35867. +
  35868. + word = read_nic_word(dev, BintrItv);
  35869. + word &= ~BintrItv_BintrItv;
  35870. +
  35871. + //word |= priv->ieee80211->beacon_interval *
  35872. + // ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
  35873. + // FIXME:FIXME check if correct ^^ worked with 0x3e8;
  35874. +
  35875. + write_nic_word(dev, BintrItv, word);
  35876. +
  35877. + //write_nic_word(dev,0x2e,0xe002);
  35878. + //write_nic_dword(dev,0x30,0xb8c7832e);
  35879. + for(i=0; i<ETH_ALEN; i++)
  35880. + write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
  35881. +
  35882. +// rtl8180_update_msr(dev);
  35883. +
  35884. +
  35885. + //write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
  35886. +
  35887. + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
  35888. +
  35889. + rtl8180_irq_enable(dev);
  35890. +
  35891. + /* VV !!!!!!!!!! VV*/
  35892. + /*
  35893. + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
  35894. + write_nic_byte(dev,0x9d,0x00);
  35895. + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
  35896. +*/
  35897. +}
  35898. +#endif
  35899. +/***************************************************************************
  35900. + -------------------------------NET STUFF---------------------------
  35901. +***************************************************************************/
  35902. +static struct net_device_stats *rtl8180_stats(struct net_device *dev)
  35903. +{
  35904. + struct r8180_priv *priv = ieee80211_priv(dev);
  35905. +
  35906. + return &priv->ieee80211->stats;
  35907. +}
  35908. +
  35909. +int _rtl8180_up(struct net_device *dev)
  35910. +{
  35911. + struct r8180_priv *priv = ieee80211_priv(dev);
  35912. + //int i;
  35913. +
  35914. + priv->driver_upping = 1;
  35915. + priv->up=1;
  35916. +
  35917. +#ifdef LED
  35918. + if(priv->ieee80211->bHwRadioOff == false)
  35919. + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_ON);
  35920. +#endif
  35921. + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_SW);
  35922. +
  35923. + rtl8180_adapter_start(dev);
  35924. + rtl8180_rx_enable(dev);
  35925. + rtl8180_tx_enable(dev);
  35926. +//by amy for rate adaptive
  35927. + timer_rate_adaptive((unsigned long)dev);
  35928. +//by amy for rate adaptive
  35929. +
  35930. +#ifdef SW_ANTE_DIVERSITY
  35931. + if(priv->bSwAntennaDiverity){
  35932. + //DMESG("SW Antenna Diversity Enable!");
  35933. + SwAntennaDiversityTimerCallback(dev);
  35934. + }
  35935. +#endif
  35936. +
  35937. + ieee80211_softmac_start_protocol(priv->ieee80211);
  35938. +
  35939. +//by amy for ps
  35940. + watch_dog_adaptive((unsigned long)dev);
  35941. +//by amy for ps
  35942. +
  35943. + ieee80211_reset_queue(priv->ieee80211);
  35944. + if(!netif_queue_stopped(dev))
  35945. + netif_start_queue(dev);
  35946. + else
  35947. + netif_wake_queue(dev);
  35948. +
  35949. +#ifndef CONFIG_SOFT_BEACON
  35950. + if(NIC_8187B == priv->card_8187)
  35951. + rtl8187_rx_manage_initiate(dev);
  35952. +#endif
  35953. +
  35954. +#ifdef _RTL8187_EXT_PATCH_
  35955. + if(priv->mshobj && priv->mshobj->ext_patch_rtl8180_up )
  35956. + priv->mshobj->ext_patch_rtl8180_up(priv->mshobj);
  35957. +#endif
  35958. +
  35959. +
  35960. + priv->driver_upping = 0;
  35961. + //DMESG("rtl8187_open process complete");
  35962. + return 0;
  35963. +}
  35964. +
  35965. +
  35966. +int rtl8180_open(struct net_device *dev)
  35967. +{
  35968. + struct r8180_priv *priv = ieee80211_priv(dev);
  35969. + int ret;
  35970. +//changed by lizhaoming for power on/off
  35971. + if(priv->ieee80211->bHwRadioOff == false){
  35972. + //DMESG("rtl8187_open process ");
  35973. + down(&priv->wx_sem);
  35974. + ret = rtl8180_up(dev);
  35975. + up(&priv->wx_sem);
  35976. + return ret;
  35977. + }else{
  35978. + DMESG("rtl8187_open process failed because radio off");
  35979. + return -1;
  35980. + }
  35981. +
  35982. +}
  35983. +
  35984. +
  35985. +int rtl8180_up(struct net_device *dev)
  35986. +{
  35987. + struct r8180_priv *priv = ieee80211_priv(dev);
  35988. +
  35989. + if (priv->up == 1) return -1;
  35990. +
  35991. + return _rtl8180_up(dev);
  35992. +}
  35993. +
  35994. +
  35995. +int rtl8180_close(struct net_device *dev)
  35996. +{
  35997. + struct r8180_priv *priv = ieee80211_priv(dev);
  35998. + int ret;
  35999. +
  36000. + if (priv->up == 0) return -1;
  36001. +
  36002. + down(&priv->wx_sem);
  36003. +
  36004. + //DMESG("rtl8187_close process");
  36005. + ret = rtl8180_down(dev);
  36006. +#ifdef LED
  36007. + priv->ieee80211->ieee80211_led_contorl(dev,LED_CTL_POWER_OFF);
  36008. +#endif
  36009. + up(&priv->wx_sem);
  36010. +
  36011. + return ret;
  36012. +
  36013. +}
  36014. +
  36015. +int rtl8180_down(struct net_device *dev)
  36016. +{
  36017. + struct r8180_priv *priv = ieee80211_priv(dev);
  36018. +
  36019. + if (priv->up == 0) return -1;
  36020. +
  36021. + priv->up=0;
  36022. +
  36023. +/* FIXME */
  36024. + if (!netif_queue_stopped(dev))
  36025. + netif_stop_queue(dev);
  36026. +
  36027. + //DMESG("rtl8180_down process");
  36028. + rtl8180_rtx_disable(dev);
  36029. + rtl8180_irq_disable(dev);
  36030. +//by amy for rate adaptive
  36031. + del_timer_sync(&priv->rateadapter_timer);
  36032. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  36033. +//by amy for rate adaptive
  36034. + del_timer_sync(&priv->watch_dog_timer);
  36035. + cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
  36036. + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
  36037. + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
  36038. +
  36039. +#ifdef SW_ANTE_DIVERSITY
  36040. + del_timer_sync(&priv->SwAntennaDiversityTimer);
  36041. + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
  36042. +#endif
  36043. +
  36044. + ieee80211_softmac_stop_protocol(priv->ieee80211);
  36045. + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
  36046. + //amy,081212
  36047. + memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network));
  36048. + return 0;
  36049. +}
  36050. +
  36051. +bool SetZebraRFPowerState8187B(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
  36052. +
  36053. +void rtl8180_commit(struct net_device *dev)
  36054. +{
  36055. + struct r8180_priv *priv = ieee80211_priv(dev);
  36056. + int i;
  36057. +
  36058. + if (priv->up == 0) return ;
  36059. + printk("==========>%s()\n", __FUNCTION__);
  36060. +
  36061. + /* FIXME */
  36062. + if (!netif_queue_stopped(dev))
  36063. + netif_stop_queue(dev);
  36064. +
  36065. +//by amy for rate adaptive
  36066. + del_timer_sync(&priv->rateadapter_timer);
  36067. + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
  36068. +//by amy for rate adaptive
  36069. + del_timer_sync(&priv->watch_dog_timer);
  36070. + cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
  36071. + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
  36072. + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
  36073. +
  36074. +#ifdef SW_ANTE_DIVERSITY
  36075. + del_timer_sync(&priv->SwAntennaDiversityTimer);
  36076. + cancel_delayed_work(&priv->ieee80211->SwAntennaWorkItem);
  36077. +#endif
  36078. + ieee80211_softmac_stop_protocol(priv->ieee80211);
  36079. +
  36080. +#if 0
  36081. + if(priv->ieee80211->bHwRadioOff == false){
  36082. + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_HW);
  36083. + mdelay(10);
  36084. + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_HW);
  36085. + }
  36086. +#endif
  36087. +
  36088. + rtl8180_irq_disable(dev);
  36089. + rtl8180_rtx_disable(dev);
  36090. +
  36091. + //test pending bug, john 20070815
  36092. + //initialize tx_pending
  36093. + for(i=0;i<0x10;i++) atomic_set(&(priv->tx_pending[i]), 0);
  36094. +
  36095. + _rtl8180_up(dev);
  36096. + priv->commit = 0;
  36097. +}
  36098. +
  36099. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
  36100. +void rtl8180_restart(struct work_struct *work)
  36101. +{
  36102. + struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
  36103. + struct ieee80211_device* ieee = priv->ieee80211;//for commit crash
  36104. + struct net_device *dev = ieee->dev;//for commit crash
  36105. +#else
  36106. +void rtl8180_restart(struct net_device *dev)
  36107. +{
  36108. +
  36109. + struct r8180_priv *priv = ieee80211_priv(dev);
  36110. +#endif
  36111. +
  36112. + down(&priv->wx_sem);
  36113. +
  36114. + rtl8180_commit(dev);
  36115. +
  36116. + up(&priv->wx_sem);
  36117. +}
  36118. +
  36119. +static void r8180_set_multicast(struct net_device *dev)
  36120. +{
  36121. + struct r8180_priv *priv = ieee80211_priv(dev);
  36122. + short promisc;
  36123. +
  36124. + //down(&priv->wx_sem);
  36125. +
  36126. + /* FIXME FIXME */
  36127. +
  36128. + promisc = (dev->flags & IFF_PROMISC) ? 1:0;
  36129. +
  36130. + if (promisc != priv->promisc)
  36131. + // rtl8180_commit(dev);
  36132. +
  36133. + priv->promisc = promisc;
  36134. +
  36135. + //schedule_work(&priv->reset_wq);
  36136. + //up(&priv->wx_sem);
  36137. +}
  36138. +
  36139. +
  36140. +int r8180_set_mac_adr(struct net_device *dev, void *mac)
  36141. +{
  36142. + struct r8180_priv *priv = ieee80211_priv(dev);
  36143. + struct sockaddr *addr = mac;
  36144. +
  36145. + down(&priv->wx_sem);
  36146. +
  36147. + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
  36148. +
  36149. +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
  36150. + schedule_work(&priv->reset_wq);
  36151. +#else
  36152. + schedule_task(&priv->reset_wq);
  36153. +#endif
  36154. + up(&priv->wx_sem);
  36155. +
  36156. + return 0;
  36157. +}
  36158. +
  36159. +struct ipw_param {
  36160. + u32 cmd;
  36161. + u8 sta_addr[ETH_ALEN];
  36162. + union {
  36163. + struct {
  36164. + u8 name;
  36165. + u32 value;
  36166. + } wpa_param;
  36167. + struct {
  36168. + u32 len;
  36169. + u8 reserved[32];
  36170. + u8 data[0];
  36171. + } wpa_ie;
  36172. + struct{
  36173. + u32 command;
  36174. + u32 reason_code;
  36175. + } mlme;
  36176. + struct {
  36177. + u8 alg[16];
  36178. + u8 set_tx;
  36179. + u32 err;
  36180. + u8 idx;
  36181. + u8 seq[8];
  36182. + u16 key_len;
  36183. + u8 key[0];
  36184. + } crypt;
  36185. +
  36186. + } u;
  36187. +};
  36188. +
  36189. +
  36190. +/* based on ipw2200 driver */
  36191. +int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  36192. +{
  36193. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  36194. + struct iwreq *wrq = (struct iwreq *)rq;
  36195. + int ret=-1;
  36196. +
  36197. +#ifdef JOHN_TKIP
  36198. + u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
  36199. +
  36200. + struct ieee80211_device *ieee = priv->ieee80211;
  36201. + struct ipw_param *ipw = (struct ipw_param *)wrq->u.data.pointer;
  36202. + u32 key[4];
  36203. +
  36204. +#endif
  36205. +
  36206. +#ifdef _RTL8187_EXT_PATCH_
  36207. + if(priv->mshobj && (priv->ieee80211->iw_mode == priv->ieee80211->iw_ext_mode) && priv->mshobj->ext_patch_rtl8180_ioctl)
  36208. + {
  36209. + // DO NOT put the belowing function in critical section, due to it uses "spin lock"
  36210. + if((ret = priv->mshobj->ext_patch_rtl8180_ioctl(dev, rq, cmd)) != -EOPNOTSUPP)
  36211. + return ret;
  36212. + }
  36213. +#endif
  36214. +
  36215. + down(&priv->wx_sem);
  36216. +
  36217. + switch (cmd) {
  36218. + case RTL_IOCTL_WPA_SUPPLICANT:
  36219. +#ifdef JOHN_TKIP
  36220. +
  36221. +//the following code is specified for ipw driver in wpa_supplicant
  36222. + if( ((u32*)wrq->u.data.pointer)[0]==3 ){
  36223. +
  36224. +
  36225. + if( ((u32*)wrq->u.data.pointer)[7] &&
  36226. + ( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ||
  36227. + ((u32*)wrq->u.data.pointer)[3]==0x50494b54 )) {//50494b54 tkip and 504d4343 ccmp
  36228. +
  36229. + //enable HW security of TKIP and CCMP
  36230. + write_nic_byte(dev, WPA_CONFIG, SCR_TxSecEnable | SCR_RxSecEnable );
  36231. +
  36232. + //copy key from wpa_supplicant ioctl info
  36233. + key[0] = ((u32*)wrq->u.data.pointer)[12];
  36234. + key[1] = ((u32*)wrq->u.data.pointer)[13];
  36235. + key[2] = ((u32*)wrq->u.data.pointer)[14];
  36236. + key[3] = ((u32*)wrq->u.data.pointer)[15];
  36237. + switch (ieee->pairwise_key_type){
  36238. + case KEY_TYPE_TKIP:
  36239. + setKey( dev,
  36240. + 0, //EntryNo
  36241. + ipw->u.crypt.idx, //KeyIndex
  36242. + KEY_TYPE_TKIP, //KeyType
  36243. + (u8*)ieee->ap_mac_addr, //MacAddr
  36244. + 0, //DefaultKey
  36245. + key); //KeyContent
  36246. + break;
  36247. +
  36248. + case KEY_TYPE_CCMP:
  36249. + setKey( dev,
  36250. + 0, //EntryNo
  36251. + ipw->u.crypt.idx, //KeyIndex
  36252. + KEY_TYPE_CCMP, //KeyType
  36253. + (u8*)ieee->ap_mac_addr, //MacAddr
  36254. + 0, //DefaultKey
  36255. + key); //KeyContent
  36256. + break
  36257. +;
  36258. + default:
  36259. + printk("error on key_type: %d\n", ieee->pairwise_key_type);
  36260. + break;
  36261. + }
  36262. + }
  36263. +
  36264. + //group key for broadcast
  36265. + if( ((u32*)wrq->u.data.pointer)[9] ) {
  36266. +
  36267. + key[0] = ((u32*)wrq->u.data.pointer)[12];
  36268. + key[1] = ((u32*)wrq->u.data.pointer)[13];
  36269. + key[2] = ((u32*)wrq->u.data.pointer)[14];
  36270. + key[3] = ((u32*)wrq->u.data.pointer)[15];
  36271. +
  36272. + if( ((u32*)wrq->u.data.pointer)[3]==0x50494b54 ){//50494b54 is the ASCII code of TKIP in reversed order
  36273. + setKey( dev,
  36274. + 1, //EntryNo
  36275. + ipw->u.crypt.idx,//KeyIndex
  36276. + KEY_TYPE_TKIP, //KeyType
  36277. + broadcast_addr, //MacAddr
  36278. + 0, //DefaultKey
  36279. + key); //KeyContent
  36280. + }
  36281. + else if( ((u32*)wrq->u.data.pointer)[3]==0x504d4343 ){//CCMP
  36282. + setKey( dev,
  36283. + 1, //EntryNo
  36284. + ipw->u.crypt.idx,//KeyIndex
  36285. + KEY_TYPE_CCMP, //KeyType
  36286. + broadcast_addr, //MacAddr
  36287. + 0, //DefaultKey
  36288. + key); //KeyContent
  36289. + }
  36290. + else if( ((u32*)wrq->u.data.pointer)[3]==0x656e6f6e ){//none
  36291. + //do nothing
  36292. + }
  36293. + else if( ((u32*)wrq->u.data.pointer)[3]==0x504557 ){//WEP
  36294. + setKey( dev,
  36295. + 1, //EntryNo
  36296. + ipw->u.crypt.idx,//KeyIndex
  36297. + KEY_TYPE_WEP40, //KeyType
  36298. + broadcast_addr, //MacAddr
  36299. + 0, //DefaultKey
  36300. + key); //KeyContent
  36301. + }
  36302. + else printk("undefine group key type: %8x\n", ((u32*)wrq->u.data.pointer)[3]);
  36303. + }
  36304. +
  36305. + }
  36306. +#endif /*JOHN_TKIP*/
  36307. +
  36308. +
  36309. +#ifdef JOHN_HWSEC_DEBUG
  36310. + {
  36311. + int i;
  36312. + //john's test 0711
  36313. + printk("@@ wrq->u pointer = ");
  36314. + for(i=0;i<wrq->u.data.length;i++){
  36315. + if(i%10==0) printk("\n");
  36316. + printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
  36317. + }
  36318. + printk("\n");
  36319. + }
  36320. +#endif /*JOHN_HWSEC_DEBUG*/
  36321. + ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
  36322. + break;
  36323. +
  36324. + default:
  36325. + ret = -EOPNOTSUPP;
  36326. + break;
  36327. + }
  36328. +
  36329. + up(&priv->wx_sem);
  36330. +
  36331. + return ret;
  36332. +}
  36333. +
  36334. +
  36335. +struct tx_desc {
  36336. +
  36337. +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  36338. +
  36339. +
  36340. +//dword 0
  36341. +unsigned int tpktsize:12;
  36342. +unsigned int rsvd0:3;
  36343. +unsigned int no_encrypt:1;
  36344. +unsigned int splcp:1;
  36345. +unsigned int morefrag:1;
  36346. +unsigned int ctsen:1;
  36347. +unsigned int rtsrate:4;
  36348. +unsigned int rtsen:1;
  36349. +unsigned int txrate:4;
  36350. +unsigned int last:1;
  36351. +unsigned int first:1;
  36352. +unsigned int dmaok:1;
  36353. +unsigned int own:1;
  36354. +
  36355. +//dword 1
  36356. +unsigned short rtsdur;
  36357. +unsigned short length:15;
  36358. +unsigned short l_ext:1;
  36359. +
  36360. +//dword 2
  36361. +unsigned int bufaddr;
  36362. +
  36363. +
  36364. +//dword 3
  36365. +unsigned short rxlen:12;
  36366. +unsigned short rsvd1:3;
  36367. +unsigned short miccal:1;
  36368. +unsigned short dur;
  36369. +
  36370. +//dword 4
  36371. +unsigned int nextdescaddr;
  36372. +
  36373. +//dword 5
  36374. +unsigned char rtsagc;
  36375. +unsigned char retrylimit;
  36376. +unsigned short rtdb:1;
  36377. +unsigned short noacm:1;
  36378. +unsigned short pifs:1;
  36379. +unsigned short rsvd2:4;
  36380. +unsigned short rtsratefallback:4;
  36381. +unsigned short ratefallback:5;
  36382. +
  36383. +//dword 6
  36384. +unsigned short delaybound;
  36385. +unsigned short rsvd3:4;
  36386. +unsigned short agc:8;
  36387. +unsigned short antenna:1;
  36388. +unsigned short spc:2;
  36389. +unsigned short rsvd4:1;
  36390. +
  36391. +//dword 7
  36392. +unsigned char len_adjust:2;
  36393. +unsigned char rsvd5:1;
  36394. +unsigned char tpcdesen:1;
  36395. +unsigned char tpcpolarity:2;
  36396. +unsigned char tpcen:1;
  36397. +unsigned char pten:1;
  36398. +
  36399. +unsigned char bckey:6;
  36400. +unsigned char enbckey:1;
  36401. +unsigned char enpmpd:1;
  36402. +unsigned short fragqsz;
  36403. +
  36404. +
  36405. +#else
  36406. +
  36407. +#error "please modify tx_desc to your own\n"
  36408. +
  36409. +#endif
  36410. +
  36411. +
  36412. +} __attribute__((packed));
  36413. +
  36414. +struct rx_desc_rtl8187b {
  36415. +
  36416. +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  36417. +
  36418. +//dword 0
  36419. +unsigned int rxlen:12;
  36420. +unsigned int icv:1;
  36421. +unsigned int crc32:1;
  36422. +unsigned int pwrmgt:1;
  36423. +unsigned int res:1;
  36424. +unsigned int bar:1;
  36425. +unsigned int pam:1;
  36426. +unsigned int mar:1;
  36427. +unsigned int qos:1;
  36428. +unsigned int rxrate:4;
  36429. +unsigned int trsw:1;
  36430. +unsigned int splcp:1;
  36431. +unsigned int fovf:1;
  36432. +unsigned int dmafail:1;
  36433. +unsigned int last:1;
  36434. +unsigned int first:1;
  36435. +unsigned int eor:1;
  36436. +unsigned int own:1;
  36437. +
  36438. +
  36439. +//dword 1
  36440. +unsigned int tsftl;
  36441. +
  36442. +
  36443. +//dword 2
  36444. +unsigned int tsfth;
  36445. +
  36446. +
  36447. +//dword 3
  36448. +unsigned char sq;
  36449. +unsigned char rssi:7;
  36450. +unsigned char antenna:1;
  36451. +
  36452. +unsigned char agc;
  36453. +unsigned char decrypted:1;
  36454. +unsigned char wakeup:1;
  36455. +unsigned char shift:1;
  36456. +unsigned char rsvd0:5;
  36457. +
  36458. +//dword 4
  36459. +unsigned int num_mcsi:4;
  36460. +unsigned int snr_long2end:6;
  36461. +unsigned int cfo_bias:6;
  36462. +
  36463. +int pwdb_g12:8;
  36464. +unsigned int fot:8;
  36465. +
  36466. +
  36467. +
  36468. +
  36469. +#else
  36470. +
  36471. +#error "please modify tx_desc to your own\n"
  36472. +
  36473. +#endif
  36474. +
  36475. +}__attribute__((packed));
  36476. +
  36477. +
  36478. +
  36479. +struct rx_desc_rtl8187 {
  36480. +
  36481. +#ifdef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
  36482. +
  36483. +//dword 0
  36484. +unsigned int rxlen:12;
  36485. +unsigned int icv:1;
  36486. +unsigned int crc32:1;
  36487. +unsigned int pwrmgt:1;
  36488. +unsigned int res:1;
  36489. +unsigned int bar:1;
  36490. +unsigned int pam:1;
  36491. +unsigned int mar:1;
  36492. +unsigned int qos:1;
  36493. +unsigned int rxrate:4;
  36494. +unsigned int trsw:1;
  36495. +unsigned int splcp:1;
  36496. +unsigned int fovf:1;
  36497. +unsigned int dmafail:1;
  36498. +unsigned int last:1;
  36499. +unsigned int first:1;
  36500. +unsigned int eor:1;
  36501. +unsigned int own:1;
  36502. +
  36503. +//dword 1
  36504. +unsigned char sq;
  36505. +unsigned char rssi:7;
  36506. +unsigned char antenna:1;
  36507. +
  36508. +unsigned char agc;
  36509. +unsigned char decrypted:1;
  36510. +unsigned char wakeup:1;
  36511. +unsigned char shift:1;
  36512. +unsigned char rsvd0:5;
  36513. +
  36514. +//dword 2
  36515. +unsigned int tsftl;
  36516. +
  36517. +//dword 3
  36518. +unsigned int tsfth;
  36519. +
  36520. +
  36521. +
  36522. +#else
  36523. +
  36524. +#error "please modify tx_desc to your own\n"
  36525. +
  36526. +#endif
  36527. +
  36528. +
  36529. +}__attribute__((packed));
  36530. +
  36531. +
  36532. +
  36533. +union rx_desc {
  36534. +
  36535. +struct rx_desc_rtl8187b desc_87b;
  36536. +struct rx_desc_rtl8187 desc_87;
  36537. +
  36538. +}__attribute__((packed));
  36539. +
  36540. +//
  36541. +// Description:
  36542. +// Perform signal smoothing for dynamic mechanism.
  36543. +// This is different with PerformSignalSmoothing8187 in smoothing fomula.
  36544. +// No dramatic adjustion is apply because dynamic mechanism need some degree
  36545. +// of correctness.
  36546. +// 2007.01.23, by shien chang.
  36547. +//
  36548. +void PerformUndecoratedSignalSmoothing8187(struct net_device *dev, struct ieee80211_rx_stats *stats)
  36549. +{
  36550. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  36551. + bool bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats->rate));
  36552. +
  36553. + if(NIC_8187 == priv->card_8187) {
  36554. + if(priv->UndecoratedSmoothedSS >= 0) {
  36555. + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 50) + (stats->signalstrength * 11)) / 60;
  36556. + }else{
  36557. + priv->UndecoratedSmoothedSS = stats->signalstrength;
  36558. + }
  36559. + } else {
  36560. + // Determin the current packet is CCK rate, by Bruce, 2007-04-12.
  36561. + priv->bCurCCKPkt = bCckRate;
  36562. +
  36563. + // Tesing for SD3 DZ, by Bruce, 2007-04-11.
  36564. + if(priv->UndecoratedSmoothedSS >= 0) {
  36565. + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 5) + (stats->signalstrength * 10)) / 6;
  36566. + }else{
  36567. + priv->UndecoratedSmoothedSS = stats->signalstrength * 10;
  36568. + }
  36569. +
  36570. + //
  36571. + // Bacause the AGC parameter is not exactly correct under high power (AGC saturation), we need to record the RSSI value to be
  36572. + // referenced by DoRxHighPower. It is not necessary to record this value when this packet is sent by OFDM rate.
  36573. + // Advised by SD3 DZ, by Bruce, 2007-04-12.
  36574. + //
  36575. + if(bCckRate){
  36576. + priv->CurCCKRSSI = stats->signal;
  36577. + }else{
  36578. + priv->CurCCKRSSI = 0;
  36579. + }
  36580. + }
  36581. + //printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", stats->signalstrength, priv->UndecoratedSmoothedSS);
  36582. +}
  36583. +
  36584. +#ifdef THOMAS_SKB
  36585. +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv)
  36586. +{
  36587. + int status,len,flen;
  36588. +
  36589. +#ifdef SW_ANTE_DIVERSITY
  36590. + u8 Antenna = 0;
  36591. +#endif
  36592. + u32 SignalStrength = 0;
  36593. + u32 quality = 0;
  36594. + bool bCckRate = false;
  36595. + char RX_PWDB = 0;
  36596. + long RecvSignalPower=0;
  36597. + struct sk_buff *skb;
  36598. + struct sk_buff *skb2;//skb for check out of memory
  36599. + union rx_desc *desc;
  36600. + //struct urb *rx_urb = priv->rxurb_task;
  36601. + struct ieee80211_hdr *hdr;//by amy
  36602. + u16 fc,type;
  36603. + u8 bHwError=0,bCRC=0,bICV=0;
  36604. + long SignalStrengthIndex = 0;
  36605. + struct ieee80211_rx_stats stats = {
  36606. + .signal = 0,
  36607. + .noise = -98,
  36608. + .rate = 0,
  36609. + //.mac_time = jiffies,
  36610. + .freq = IEEE80211_24GHZ_BAND,
  36611. + };
  36612. +
  36613. + int *prx_inx=&priv->rx_inx;
  36614. + struct urb *rx_urb=priv->rx_urb[*prx_inx]; //changed by jackson
  36615. + struct net_device *dev = (struct net_device*)rx_urb->context;
  36616. + //DMESG("=====>RX %x ",rx_urb->status);
  36617. +
  36618. + skb = priv->pp_rxskb[*prx_inx];
  36619. + status = rx_urb->status;
  36620. + skb2 = dev_alloc_skb(RX_URB_SIZE);
  36621. +
  36622. + if (skb2 == NULL){
  36623. + printk(KERN_ALERT "No Skb For RX!/n");
  36624. + //rx_urb->transfer_buffer = skb->data;
  36625. + //priv->pp_rxskb[*prx_inx] = skb;
  36626. + } else {
  36627. +
  36628. + if(status == 0)
  36629. + {
  36630. + if(NIC_8187B == priv->card_8187)
  36631. + {
  36632. + stats.nic_type = NIC_8187B;
  36633. + len = rx_urb->actual_length;
  36634. + len -= sizeof (struct rx_desc_rtl8187b);
  36635. + desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
  36636. + flen = desc->desc_87b.rxlen ;
  36637. +
  36638. + if( flen <= rx_urb->actual_length){
  36639. +#if 1
  36640. +#ifdef SW_ANTE_DIVERSITY
  36641. + Antenna = desc->desc_87b.antenna;
  36642. +#endif
  36643. + stats.mac_time[0] = desc->desc_87b.tsftl;
  36644. + stats.mac_time[1] = desc->desc_87b.tsfth;
  36645. +
  36646. + stats.signal = desc->desc_87b.rssi;
  36647. + //stats.noise = desc->desc_87b.sq;
  36648. + quality = desc->desc_87b.sq;
  36649. + stats.rate = desc->desc_87b.rxrate;
  36650. + bCckRate = rtl8180_IsWirelessBMode(rtl8180_rate2rate(stats.rate));
  36651. +
  36652. + if(!bCckRate) { // OFDM rate.
  36653. + if(desc->desc_87b.pwdb_g12 < -106)
  36654. + SignalStrength = 0;
  36655. + else
  36656. + SignalStrength = desc->desc_87b.pwdb_g12 + 106;
  36657. + RX_PWDB = (desc->desc_87b.pwdb_g12)/2 -42;
  36658. + } else { // CCK rate.
  36659. + if(desc->desc_87b.agc> 174)
  36660. + SignalStrength = 0;
  36661. + else
  36662. + SignalStrength = 174 - desc->desc_87b.agc;
  36663. + RX_PWDB = ((desc->desc_87b.agc)/2)*(-1) - 8;
  36664. + }
  36665. +
  36666. + //lzm mod 081028 based on windows driver
  36667. + //compensate SignalStrength when switch TR to SW controled
  36668. + if(priv->TrSwitchState == TR_SW_TX) {
  36669. + SignalStrength = SignalStrength + 54;
  36670. + RX_PWDB = RX_PWDB + 27;
  36671. + }
  36672. +
  36673. + if(SignalStrength > 100)
  36674. + SignalStrength = 100;
  36675. + SignalStrength = (SignalStrength * 70) / 100 + 30;
  36676. +
  36677. + if(SignalStrength > 50)
  36678. + SignalStrength = SignalStrength + 10;
  36679. + if(SignalStrength > 100)
  36680. + SignalStrength = 100;
  36681. +
  36682. + RecvSignalPower = RX_PWDB;
  36683. + //printk("SignalStrength = %d \n",SignalStrength);
  36684. + bHwError = (desc->desc_87b.fovf | desc->desc_87b.icv | desc->desc_87b.crc32);
  36685. + bCRC = desc->desc_87b.crc32;
  36686. + bICV = desc->desc_87b.icv;
  36687. + priv->wstats.qual.level = (u8)SignalStrength;
  36688. +
  36689. + if(!bCckRate){
  36690. + if (quality > 127)
  36691. + quality = 0;
  36692. + else if (quality <27)
  36693. + quality = 100;
  36694. + else
  36695. + quality = 127 - quality;
  36696. + } else {
  36697. + if(quality > 64)
  36698. + quality = 0;
  36699. + else
  36700. + quality = ((64-quality)*100)/64;
  36701. + }
  36702. +
  36703. +
  36704. + priv ->wstats.qual.qual = quality;
  36705. + priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
  36706. +
  36707. + stats.signalstrength = (u8)SignalStrength;
  36708. + stats.signal = (u8)quality;
  36709. + stats.noise = desc->desc_87b.snr_long2end;
  36710. +
  36711. + skb_put(skb,flen-4);
  36712. +
  36713. + priv->stats.rxok++;
  36714. + //by amy
  36715. + hdr = (struct ieee80211_hdr *)skb->data;
  36716. + fc = le16_to_cpu(hdr->frame_ctl);
  36717. + type = WLAN_FC_GET_TYPE(fc);
  36718. +
  36719. + if((IEEE80211_FTYPE_CTL != type) &&
  36720. + (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!bHwError) && (!bCRC)&& (!bICV))
  36721. + {
  36722. + // Perform signal smoothing for dynamic mechanism on demand.
  36723. + // This is different with PerformSignalSmoothing8187 in smoothing fomula.
  36724. + // No dramatic adjustion is apply because dynamic mechanism need some degree
  36725. + // of correctness. 2007.01.23, by shien chang.
  36726. + PerformUndecoratedSignalSmoothing8187(dev, &stats);
  36727. +
  36728. + //Update signal strength and realted into private RxStats for UI query.
  36729. + SignalStrengthIndex = NetgearSignalStrengthTranslate(priv->LastSignalStrengthInPercent, priv->wstats.qual.level);
  36730. + priv->LastSignalStrengthInPercent = SignalStrengthIndex;
  36731. + priv->SignalStrength = TranslateToDbm8187((u8)SignalStrengthIndex);
  36732. + priv->SignalQuality = (priv->SignalQuality*5+quality+5)/6;
  36733. + priv->RecvSignalPower = (priv->RecvSignalPower * 5 + RecvSignalPower - 1) / 6;
  36734. +#ifdef SW_ANTE_DIVERSITY
  36735. + priv->LastRxPktAntenna = Antenna ? 1:0;
  36736. + SwAntennaDiversityRxOk8185(dev, SignalStrength);
  36737. +#endif
  36738. + }
  36739. + //by amy
  36740. +#endif
  36741. + if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
  36742. + dev_kfree_skb_any(skb);
  36743. + }
  36744. + }else {
  36745. + priv->stats.rxurberr++;
  36746. + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
  36747. + dev_kfree_skb_any(skb);
  36748. + }
  36749. + } else {
  36750. + stats.nic_type = NIC_8187;
  36751. + len = rx_urb->actual_length;
  36752. + len -= sizeof (struct rx_desc_rtl8187);
  36753. + desc = (union rx_desc *)(rx_urb->transfer_buffer + len);
  36754. + flen = desc->desc_87.rxlen ;
  36755. +
  36756. + if(flen <= rx_urb->actual_length){
  36757. + stats.signal = desc->desc_87.rssi;
  36758. + stats.noise = desc->desc_87.sq;
  36759. + stats.rate = desc->desc_87.rxrate;
  36760. + stats.mac_time[0] = desc->desc_87.tsftl;
  36761. + stats.mac_time[1] = desc->desc_87.tsfth;
  36762. + SignalStrength = (desc->desc_87.agc&0xfe) >> 1;
  36763. + if( ((stats.rate <= 22) && (stats.rate != 12) && (stats.rate != 18)) || (stats.rate == 44) )//need to translate to real rate here
  36764. + bCckRate= TRUE;
  36765. + if (!bCckRate)
  36766. + {
  36767. + if (SignalStrength > 90) SignalStrength = 90;
  36768. + else if (SignalStrength < 25) SignalStrength = 25;
  36769. + SignalStrength = ((90 - SignalStrength)*100)/65;
  36770. + }
  36771. + else
  36772. + {
  36773. + if (SignalStrength >95) SignalStrength = 95;
  36774. + else if (SignalStrength < 30) SignalStrength = 30;
  36775. + SignalStrength = ((95 - SignalStrength)*100)/65;
  36776. + }
  36777. + stats.signalstrength = (u8)SignalStrength;
  36778. +
  36779. + skb_put(skb,flen-4);
  36780. +
  36781. + priv->stats.rxok++;
  36782. +
  36783. + if(!ieee80211_rx(priv->ieee80211,skb, &stats))
  36784. + dev_kfree_skb_any(skb);
  36785. +
  36786. +
  36787. + }else {
  36788. + priv->stats.rxurberr++;
  36789. + printk("URB Error flen:%d actual_length:%d\n", flen , rx_urb->actual_length);
  36790. + dev_kfree_skb_any(skb);
  36791. + }
  36792. + }
  36793. + }else{
  36794. +
  36795. + //printk("RX Status Error!\n");
  36796. + priv->stats.rxstaterr++;
  36797. + priv->ieee80211->stats.rx_errors++;
  36798. + dev_kfree_skb_any(skb);
  36799. +
  36800. + }
  36801. +
  36802. + rx_urb->transfer_buffer = skb2->data;
  36803. +
  36804. + priv->pp_rxskb[*prx_inx] = skb2;
  36805. + }
  36806. +
  36807. + if(status != -ENOENT ){
  36808. + rtl8187_rx_urbsubmit(dev,rx_urb);
  36809. + } else {
  36810. + priv->pp_rxskb[*prx_inx] = NULL;
  36811. + dev_kfree_skb_any(skb2);
  36812. + //printk("RX process %d aborted due to explicit shutdown (%x)(%d)\n ", *prx_inx, status, status);
  36813. + }
  36814. +
  36815. + if (*prx_inx == (MAX_RX_URB -1))
  36816. + *prx_inx = 0;
  36817. + else
  36818. + *prx_inx = *prx_inx + 1;
  36819. +}
  36820. +#endif
  36821. +
  36822. +#ifdef THOMAS_TASKLET
  36823. +void rtl8180_irq_rx_tasklet_new(struct r8180_priv *priv){
  36824. + unsigned long flags;
  36825. + while( atomic_read( &priv->irt_counter ) ){
  36826. + spin_lock_irqsave(&priv->irq_lock,flags);//added by thomas
  36827. + rtl8180_irq_rx_tasklet(priv);
  36828. + spin_unlock_irqrestore(&priv->irq_lock,flags);//added by thomas
  36829. + if(atomic_read(&priv->irt_counter) >= 1)
  36830. + atomic_dec( &priv->irt_counter );
  36831. + }
  36832. +}
  36833. +#endif
  36834. +/****************************************************************************
  36835. + ---------------------------- USB_STUFF---------------------------
  36836. +*****************************************************************************/
  36837. +
  36838. +static const struct net_device_ops rtl8187_netdev_ops = {
  36839. + .ndo_open = rtl8180_open,
  36840. + .ndo_stop = rtl8180_close,
  36841. + .ndo_tx_timeout = tx_timeout,
  36842. + .ndo_do_ioctl = rtl8180_ioctl,
  36843. + .ndo_set_multicast_list = r8180_set_multicast,
  36844. + .ndo_set_mac_address = r8180_set_mac_adr,
  36845. + .ndo_validate_addr = eth_validate_addr,
  36846. + .ndo_change_mtu = eth_change_mtu,
  36847. + .ndo_start_xmit = ieee80211_xmit,
  36848. + .ndo_get_stats = rtl8180_stats,
  36849. +};
  36850. +
  36851. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  36852. +static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
  36853. + const struct usb_device_id *id)
  36854. +#else
  36855. +static void * __devinit rtl8187_usb_probe(struct usb_device *udev,
  36856. + unsigned int ifnum,
  36857. + const struct usb_device_id *id)
  36858. +#endif
  36859. +{
  36860. + struct net_device *dev = NULL;
  36861. + struct r8180_priv *priv= NULL;
  36862. +
  36863. +
  36864. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  36865. + struct usb_device *udev = interface_to_usbdev(intf);
  36866. +#endif
  36867. +
  36868. + dev = alloc_ieee80211(sizeof(struct r8180_priv));
  36869. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  36870. + SET_MODULE_OWNER(dev);
  36871. +#endif
  36872. +
  36873. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  36874. + usb_set_intfdata(intf, dev);
  36875. + SET_NETDEV_DEV(dev, &intf->dev);
  36876. +#endif
  36877. + priv = ieee80211_priv(dev);
  36878. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  36879. + priv->ieee80211 = netdev_priv(dev);
  36880. +#else
  36881. + priv->ieee80211 = (struct net_device *)dev->priv;
  36882. +#endif
  36883. + priv->udev=udev;
  36884. +#ifdef CPU_64BIT
  36885. + priv->usb_buf = kmalloc(0x200, GFP_KERNEL);
  36886. + priv->usb_pool = dma_pool_create("rtl8187b", NULL, 64, 64, 0);
  36887. +#endif
  36888. +//lzm add for write time out test
  36889. +#ifdef DEBUG_RW_REGISTER
  36890. + {
  36891. + int reg_index = 0;
  36892. + for(reg_index = 0; reg_index <= 199; reg_index++)
  36893. + {
  36894. + priv->write_read_registers[reg_index].address = 0;
  36895. + priv->write_read_registers[reg_index].content = 0;
  36896. + priv->write_read_registers[reg_index].flag = 0;
  36897. + }
  36898. + priv->write_read_register_index = 0;
  36899. + }
  36900. +#endif
  36901. + //init netdev_ops, added by falcon....
  36902. + dev->netdev_ops = &rtl8187_netdev_ops;
  36903. +
  36904. + dev->wireless_handlers = &r8180_wx_handlers_def;
  36905. +#if WIRELESS_EXT >= 12
  36906. +#if WIRELESS_EXT < 17
  36907. + dev->get_wireless_stats = r8180_get_wireless_stats;
  36908. +#endif
  36909. + dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
  36910. +#endif
  36911. +
  36912. + dev->type=ARPHRD_ETHER;
  36913. + dev->watchdog_timeo = HZ*3; //modified by john, 0805
  36914. +
  36915. + if (dev_alloc_name(dev, ifname) < 0){
  36916. + DMESG("Oops: devname already taken! Trying wlan%%d...\n");
  36917. + ifname = "wlan%d";
  36918. + dev_alloc_name(dev, ifname);
  36919. + }
  36920. +
  36921. + if(rtl8180_init(dev)!=0){
  36922. + DMESG("Initialization failed");
  36923. + goto fail;
  36924. + }
  36925. +
  36926. + netif_carrier_off(dev);
  36927. + netif_stop_queue(dev);
  36928. +
  36929. + register_netdev(dev);
  36930. +
  36931. + rtl8180_proc_init_one(dev);
  36932. +
  36933. + /* init rfkill */
  36934. + r8187b_rfkill_init(dev);
  36935. +
  36936. + DMESG("Driver probe completed");
  36937. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  36938. + return dev;
  36939. +#else
  36940. + return 0;
  36941. +#endif
  36942. +
  36943. +
  36944. +fail:
  36945. + free_ieee80211(dev);
  36946. +
  36947. + DMESG("wlan driver load failed\n");
  36948. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  36949. + return NULL;
  36950. +#else
  36951. + return -ENODEV;
  36952. +#endif
  36953. +
  36954. +}
  36955. +
  36956. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  36957. +static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf)
  36958. +#else
  36959. +static void __devexit rtl8187_usb_disconnect(struct usb_device *udev, void *ptr)
  36960. +#endif
  36961. +{
  36962. + struct r8180_priv *priv = NULL;
  36963. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  36964. + struct net_device *dev = usb_get_intfdata(intf);
  36965. +#else
  36966. + struct net_device *dev = (struct net_device *)ptr;
  36967. +#endif
  36968. + if(dev){
  36969. + unregister_netdev(dev);
  36970. +
  36971. + priv=ieee80211_priv(dev);
  36972. +
  36973. + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
  36974. +
  36975. +#ifdef _RTL8187_EXT_PATCH_
  36976. + if(priv && priv->mshobj)
  36977. + {
  36978. + if(priv->mshobj->ext_patch_remove_proc)
  36979. + priv->mshobj->ext_patch_remove_proc(priv);
  36980. + priv->ieee80211->ext_patch_ieee80211_start_protocol = 0;
  36981. + priv->ieee80211->ext_patch_ieee80211_stop_protocol = 0;
  36982. + priv->ieee80211->ext_patch_ieee80211_probe_req_1 = 0;
  36983. + priv->ieee80211->ext_patch_ieee80211_probe_req_2 = 0;
  36984. + priv->ieee80211->ext_patch_ieee80211_association_req_1 = 0;
  36985. + priv->ieee80211->ext_patch_ieee80211_association_req_2 = 0;
  36986. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_1 = 0;
  36987. + priv->ieee80211->ext_patch_ieee80211_assoc_resp_by_net_2 = 0;
  36988. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_auth =0;
  36989. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_deauth =0;
  36990. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req = 0;
  36991. + priv->ieee80211->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp = 0;
  36992. + priv->ieee80211->ext_patch_ieee80211_ext_stop_scan_wq_set_channel = 0;
  36993. + priv->ieee80211->ext_patch_ieee80211_process_probe_response_1 = 0;
  36994. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_on_probe_req = 0;
  36995. + priv->ieee80211->ext_patch_ieee80211_rx_mgt_update_expire = 0;
  36996. + priv->ieee80211->ext_patch_ieee80211_rx_on_rx = 0;
  36997. + priv->ieee80211->ext_patch_get_beacon_get_probersp = 0;
  36998. + priv->ieee80211->ext_patch_ieee80211_xmit = 0;
  36999. + priv->ieee80211->ext_patch_ieee80211_rx_frame_get_hdrlen = 0;
  37000. + priv->ieee80211->ext_patch_ieee80211_rx_is_valid_framectl = 0;
  37001. + priv->ieee80211->ext_patch_ieee80211_rx_process_dataframe = 0;
  37002. + // priv->ieee80211->ext_patch_is_duplicate_packet = 0;
  37003. + priv->ieee80211->ext_patch_ieee80211_softmac_xmit_get_rate = 0;
  37004. + free_mshobj(&priv->mshobj);
  37005. + }
  37006. +#endif // _RTL8187_EXT_PATCH_
  37007. +
  37008. + rtl8180_proc_remove_one(dev);
  37009. +
  37010. + rtl8180_down(dev);
  37011. + priv->rf_close(dev);
  37012. +
  37013. + //rtl8180_rtx_disable(dev);
  37014. + rtl8187_usb_deleteendpoints(dev);
  37015. +#ifdef LED
  37016. + DeInitSwLeds(dev);
  37017. +#endif
  37018. + rtl8180_irq_disable(dev);
  37019. + rtl8180_reset(dev);
  37020. + mdelay(10);
  37021. +
  37022. + }
  37023. +
  37024. +#ifdef CPU_64BIT
  37025. + if(priv->usb_buf)
  37026. + kfree(priv->usb_buf);
  37027. + if(priv->usb_pool) {
  37028. + dma_pool_destroy(priv->usb_pool);
  37029. + priv->usb_pool = NULL;
  37030. + }
  37031. +#endif
  37032. + free_ieee80211(dev);
  37033. + DMESG("wlan driver removed");
  37034. +}
  37035. +
  37036. +/* fun with the built-in ieee80211 stack... */
  37037. +extern int ieee80211_crypto_init(void);
  37038. +extern void ieee80211_crypto_deinit(void);
  37039. +extern int ieee80211_crypto_tkip_init(void);
  37040. +extern void ieee80211_crypto_tkip_exit(void);
  37041. +extern int ieee80211_crypto_ccmp_init(void);
  37042. +extern void ieee80211_crypto_ccmp_exit(void);
  37043. +extern int ieee80211_crypto_wep_init(void);
  37044. +extern void ieee80211_crypto_wep_exit(void);
  37045. +
  37046. +static int __init rtl8187_usb_module_init(void)
  37047. +{
  37048. + int ret;
  37049. +
  37050. + ret = ieee80211_crypto_init();
  37051. + if (ret) {
  37052. + printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
  37053. + return ret;
  37054. + }
  37055. + ret = ieee80211_crypto_tkip_init();
  37056. + if (ret) {
  37057. + printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
  37058. + return ret;
  37059. + }
  37060. + ret = ieee80211_crypto_ccmp_init();
  37061. + if (ret) {
  37062. + printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
  37063. + return ret;
  37064. + }
  37065. + ret = ieee80211_crypto_wep_init();
  37066. + if (ret) {
  37067. + printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
  37068. + return ret;
  37069. + }
  37070. +
  37071. + printk("\nLinux kernel driver for RTL8187/RTL8187B based WLAN cards\n");
  37072. + printk("Copyright (c) 2004-2008, Realsil Wlan\n");
  37073. + DMESG("Initializing module");
  37074. + DMESG("Wireless extensions version %d", WIRELESS_EXT);
  37075. + rtl8180_proc_module_init();
  37076. + return usb_register(&rtl8187_usb_driver);
  37077. +}
  37078. +
  37079. +static void __exit rtl8187_usb_module_exit(void)
  37080. +{
  37081. + r8187b_rfkill_exit();
  37082. + usb_deregister(&rtl8187_usb_driver);
  37083. + rtl8180_proc_module_remove();
  37084. + ieee80211_crypto_tkip_exit();
  37085. + ieee80211_crypto_ccmp_exit();
  37086. + ieee80211_crypto_wep_exit();
  37087. + ieee80211_crypto_deinit();
  37088. +
  37089. + DMESG("Exiting\n");
  37090. +}
  37091. +
  37092. +
  37093. +void rtl8180_try_wake_queue(struct net_device *dev, int pri)
  37094. +{
  37095. + unsigned long flags;
  37096. + short enough_desc;
  37097. + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  37098. +
  37099. + spin_lock_irqsave(&priv->tx_lock,flags);
  37100. + enough_desc = check_nic_enought_desc(dev,pri);
  37101. + spin_unlock_irqrestore(&priv->tx_lock,flags);
  37102. +
  37103. + if(enough_desc)
  37104. + ieee80211_wake_queue(priv->ieee80211);
  37105. +}
  37106. +
  37107. +#ifdef JOHN_HWSEC
  37108. +void EnableHWSecurityConfig8187(struct net_device *dev)
  37109. +{
  37110. + u8 SECR_value = 0x0;
  37111. + SECR_value = SCR_TxSecEnable | SCR_RxSecEnable;
  37112. + {
  37113. + write_nic_byte(dev, WPA_CONFIG, 0x7);//SECR_value | SCR_UseDK );
  37114. + }
  37115. +}
  37116. +
  37117. +void setKey(struct net_device *dev,
  37118. + u8 EntryNo,
  37119. + u8 KeyIndex,
  37120. + u16 KeyType,
  37121. + u8 *MacAddr,
  37122. + u8 DefaultKey,
  37123. + u32 *KeyContent )
  37124. +{
  37125. + u32 TargetCommand = 0;
  37126. + u32 TargetContent = 0;
  37127. + u16 usConfig = 0;
  37128. + int i;
  37129. + usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
  37130. +
  37131. +
  37132. + for(i=0 ; i<6 ; i++){
  37133. + TargetCommand = i+6*EntryNo;
  37134. + TargetCommand |= BIT31|BIT16;
  37135. +
  37136. + if(i==0){//MAC|Config
  37137. + TargetContent = (u32)(*(MacAddr+0)) << 16|
  37138. + (u32)(*(MacAddr+1)) << 24|
  37139. + (u32)usConfig;
  37140. +
  37141. + write_nic_dword(dev, WCAMI, TargetContent);
  37142. + write_nic_dword(dev, RWCAM, TargetCommand);
  37143. + //printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
  37144. + } else if(i==1){//MAC
  37145. + TargetContent = (u32)(*(MacAddr+2)) |
  37146. + (u32)(*(MacAddr+3)) << 8|
  37147. + (u32)(*(MacAddr+4)) << 16|
  37148. + (u32)(*(MacAddr+5)) << 24;
  37149. + write_nic_dword(dev, WCAMI, TargetContent);
  37150. + write_nic_dword(dev, RWCAM, TargetCommand);
  37151. + } else { //Key Material
  37152. + write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
  37153. + write_nic_dword(dev, RWCAM, TargetCommand);
  37154. + }
  37155. + }
  37156. +
  37157. +}
  37158. +#endif
  37159. +
  37160. +/****************************************************************************
  37161. + --------------------------- RF power on/power off -----------------
  37162. +*****************************************************************************/
  37163. +
  37164. +/*
  37165. + * the interface for changing the rfkill state
  37166. + * @dev: the device of r8187b
  37167. + * @eRfPowerStateToSet: the state we need to change,
  37168. + * eRfOn: power on
  37169. + * eRfOff: power off
  37170. + *
  37171. + * This function should be called by the SCI interrupt handler when the
  37172. + * KEY_WLAN event happen(or install to the notify function of the SCI
  37173. + * interrupt) or called in the wifi_set function of the rfkill interface for
  37174. + * user-space, and also, it can be called to initialize the wifi state, and
  37175. + * called when suspend/resume.
  37176. + */
  37177. +
  37178. +void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet)
  37179. +{
  37180. + struct r8180_priv *priv = ieee80211_priv(dev);
  37181. +
  37182. + if (eRfPowerStateToSet == eRfOn)
  37183. + priv->ieee80211->bHwRadioOff = false;
  37184. + else
  37185. + priv->ieee80211->bHwRadioOff = true;
  37186. +
  37187. +#ifdef CONFIG_RADIO_DEBUG
  37188. + DMESG("SCI interrupt Methord Will Turn Radio %s",
  37189. + (priv->ieee80211->bHwRadioOff == true) ? "Off" : "On");
  37190. +#endif
  37191. +
  37192. +#ifdef LED //by lizhaoming
  37193. + if (priv->ieee80211->bHwRadioOff)
  37194. + priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_OFF);
  37195. + else
  37196. + priv->ieee80211->ieee80211_led_contorl(dev, LED_CTL_POWER_ON);
  37197. +#endif
  37198. +
  37199. + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
  37200. +
  37201. + /* report the rfkill state to the user-space via uevent interface */
  37202. + r8187b_wifi_report_state(priv);
  37203. +}
  37204. +
  37205. +/***************************************************************************
  37206. + ------------------- module init / exit stubs ----------------
  37207. +****************************************************************************/
  37208. +module_init(rtl8187_usb_module_init);
  37209. +module_exit(rtl8187_usb_module_exit);
  37210. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187.h linux-loongson/drivers/net/wireless/rtl8187b/r8187.h
  37211. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187.h 1970-01-01 01:00:00.000000000 +0100
  37212. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187.h 2010-05-27 18:12:39.532222207 +0200
  37213. @@ -0,0 +1,811 @@
  37214. +/*
  37215. + This is part of rtl8187 OpenSource driver.
  37216. + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
  37217. + Released under the terms of GPL (General Public Licence)
  37218. +
  37219. + Parts of this driver are based on the GPL part of the
  37220. + official realtek driver
  37221. +
  37222. + Parts of this driver are based on the rtl8180 driver skeleton
  37223. + from Patric Schenke & Andres Salomon
  37224. +
  37225. + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
  37226. +
  37227. + We want to tanks the Authors of those projects and the Ndiswrapper
  37228. + project Authors.
  37229. +*/
  37230. +
  37231. +#ifndef R8180H
  37232. +#define R8180H
  37233. +
  37234. +
  37235. +#define RTL8187_MODULE_NAME "rtl8187"
  37236. +#define DMESG(x,a...) printk(KERN_INFO RTL8187_MODULE_NAME ": " x "\n", ## a)
  37237. +#define DMESGW(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": WW:" x "\n", ## a)
  37238. +#define DMESGE(x,a...) printk(KERN_WARNING RTL8187_MODULE_NAME ": EE:" x "\n", ## a)
  37239. +
  37240. +#include <linux/module.h>
  37241. +#include <linux/kernel.h>
  37242. +//#include <linux/config.h>
  37243. +#include <linux/init.h>
  37244. +#include <linux/ioport.h>
  37245. +#include <linux/sched.h>
  37246. +#include <linux/types.h>
  37247. +#include <linux/slab.h>
  37248. +#include <linux/netdevice.h>
  37249. +//#include <linux/pci.h>
  37250. +#include <linux/usb.h>
  37251. +#include <linux/etherdevice.h>
  37252. +#include <linux/delay.h>
  37253. +#include <linux/rtnetlink.h> //for rtnl_lock()
  37254. +#include <linux/wireless.h>
  37255. +#include <linux/timer.h>
  37256. +#include <linux/proc_fs.h> // Necessary because we use the proc fs
  37257. +#include <linux/if_arp.h>
  37258. +#include <linux/random.h>
  37259. +#include <linux/version.h>
  37260. +#include <asm/io.h>
  37261. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
  37262. +#include <asm/semaphore.h>
  37263. +#endif
  37264. +#include "ieee80211/ieee80211.h"
  37265. +#ifdef _RTL8187_EXT_PATCH_
  37266. +#include "msh_class.h"
  37267. +#endif
  37268. +#ifdef LED
  37269. +#include "r8187_led.h"
  37270. +#endif
  37271. +
  37272. +//added for HW security, john.0629
  37273. +#define FALSE 0
  37274. +#define TRUE 1
  37275. +#define MAX_KEY_LEN 61
  37276. +#define KEY_BUF_SIZE 5
  37277. +
  37278. +#define BIT0 0x00000001
  37279. +#define BIT1 0x00000002
  37280. +#define BIT2 0x00000004
  37281. +#define BIT3 0x00000008
  37282. +#define BIT4 0x00000010
  37283. +#define BIT5 0x00000020
  37284. +#define BIT6 0x00000040
  37285. +#define BIT7 0x00000080
  37286. +#define BIT8 0x00000100
  37287. +#define BIT9 0x00000200
  37288. +#define BIT10 0x00000400
  37289. +#define BIT11 0x00000800
  37290. +#define BIT12 0x00001000
  37291. +#define BIT13 0x00002000
  37292. +#define BIT14 0x00004000
  37293. +#define BIT15 0x00008000
  37294. +#define BIT16 0x00010000
  37295. +#define BIT17 0x00020000
  37296. +#define BIT18 0x00040000
  37297. +#define BIT19 0x00080000
  37298. +#define BIT20 0x00100000
  37299. +#define BIT21 0x00200000
  37300. +#define BIT22 0x00400000
  37301. +#define BIT23 0x00800000
  37302. +#define BIT24 0x01000000
  37303. +#define BIT25 0x02000000
  37304. +#define BIT26 0x04000000
  37305. +#define BIT27 0x08000000
  37306. +#define BIT28 0x10000000
  37307. +#define BIT29 0x20000000
  37308. +#define BIT30 0x40000000
  37309. +#define BIT31 0x80000000
  37310. +
  37311. +//8187B Security
  37312. +#define RWCAM 0xA0 // Software read/write CAM config
  37313. +#define WCAMI 0xA4 // Software write CAM input content
  37314. +#define RCAMO 0xA8 // Output value from CAM according to 0xa0 setting
  37315. +#define DCAM 0xAC // Debug CAM Interface
  37316. +#define SECR 0xB0 // Security configuration register
  37317. +#define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06.
  37318. +#define AESMSK_SC 0x1FC // AES Mask for Sequence Control (0x1FC~0X1FD). Added by Annie, 2006-03-06.
  37319. +#define AESMSK_QC 0x1CE // AES Mask register for QoS Control when computing AES MIC, default = 0x000F. (2 bytes)
  37320. +
  37321. +#define AESMSK_FC_DEFAULT 0xC78F // default value of AES MASK for Frame Control Field. (2 bytes)
  37322. +#define AESMSK_SC_DEFAULT 0x000F // default value of AES MASK for Sequence Control Field. (2 bytes)
  37323. +#define AESMSK_QC_DEFAULT 0x000F // default value of AES MASK for QoS Control Field. (2 bytes)
  37324. +
  37325. +#define CAM_CONTENT_COUNT 6
  37326. +#define CFG_DEFAULT_KEY BIT5
  37327. +#define CFG_VALID BIT15
  37328. +
  37329. +//----------------------------------------------------------------------------
  37330. +// 8187B WPA Config Register (offset 0xb0, 1 byte)
  37331. +//----------------------------------------------------------------------------
  37332. +#define SCR_UseDK 0x01
  37333. +#define SCR_TxSecEnable 0x02
  37334. +#define SCR_RxSecEnable 0x04
  37335. +
  37336. +//----------------------------------------------------------------------------
  37337. +// 8187B CAM Config Setting (offset 0xb0, 1 byte)
  37338. +//----------------------------------------------------------------------------
  37339. +#define CAM_VALID 0x8000
  37340. +#define CAM_NOTVALID 0x0000
  37341. +#define CAM_USEDK 0x0020
  37342. +
  37343. +
  37344. +#define CAM_NONE 0x0
  37345. +#define CAM_WEP40 0x01
  37346. +#define CAM_TKIP 0x02
  37347. +#define CAM_AES 0x04
  37348. +#define CAM_WEP104 0x05
  37349. +
  37350. +
  37351. +//#define CAM_SIZE 16
  37352. +#define TOTAL_CAM_ENTRY 16
  37353. +#define CAM_ENTRY_LEN_IN_DW 6 // 6, unit: in u4byte. Added by Annie, 2006-05-25.
  37354. +#define CAM_ENTRY_LEN_IN_BYTE (CAM_ENTRY_LEN_IN_DW*sizeof(u4Byte)) // 24, unit: in u1byte. Added by Annie, 2006-05-25.
  37355. +
  37356. +#define CAM_CONFIG_USEDK 1
  37357. +#define CAM_CONFIG_NO_USEDK 0
  37358. +
  37359. +#define CAM_WRITE 0x00010000
  37360. +#define CAM_READ 0x00000000
  37361. +#define CAM_POLLINIG 0x80000000
  37362. +
  37363. +//=================================================================
  37364. +//=================================================================
  37365. +
  37366. +#define EPROM_93c46 0
  37367. +#define EPROM_93c56 1
  37368. +
  37369. +#define DEFAULT_FRAG_THRESHOLD 2342U
  37370. +#define MIN_FRAG_THRESHOLD 256U
  37371. +#define DEFAULT_BEACONINTERVAL 0x64U
  37372. +#define DEFAULT_BEACON_ESSID "Rtl8187"
  37373. +
  37374. +#define DEFAULT_SSID ""
  37375. +#define DEFAULT_RETRY_RTS 7
  37376. +#define DEFAULT_RETRY_DATA 7
  37377. +#define PRISM_HDR_SIZE 64
  37378. +
  37379. +typedef enum _WIRELESS_MODE {
  37380. + WIRELESS_MODE_UNKNOWN = 0x00,
  37381. + WIRELESS_MODE_A = 0x01,
  37382. + WIRELESS_MODE_B = 0x02,
  37383. + WIRELESS_MODE_G = 0x04,
  37384. + WIRELESS_MODE_AUTO = 0x08,
  37385. +} WIRELESS_MODE;
  37386. +
  37387. +typedef enum _TR_SWITCH_STATE{
  37388. + TR_HW_CONTROLLED = 0,
  37389. + TR_SW_TX = 1,
  37390. +}TR_SWITCH_STATE, *PTR_SWITCH_STATE;
  37391. +
  37392. +
  37393. +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
  37394. +
  37395. +typedef struct buffer
  37396. +{
  37397. + struct buffer *next;
  37398. + u32 *buf;
  37399. +
  37400. +} buffer;
  37401. +
  37402. +typedef struct rtl_reg_debug{
  37403. + unsigned int cmd;
  37404. + struct {
  37405. + unsigned char type;
  37406. + unsigned char addr;
  37407. + unsigned char page;
  37408. + unsigned char length;
  37409. + } head;
  37410. + unsigned char buf[0xff];
  37411. +}rtl_reg_debug;
  37412. +typedef struct _CHANNEL_LIST{
  37413. + u8 Channel[MAX_CHANNEL_NUMBER + 1];
  37414. + u8 Len;
  37415. +}CHANNEL_LIST, *PCHANNEL_LIST;
  37416. +
  37417. +#define MAX_LD_SLOT_NUM 10
  37418. +#define DEFAULT_SLOT_NUM 2
  37419. +#define KEEP_ALIVE_INTERVAL 20 // in seconds.
  37420. +#define CHECK_FOR_HANG_PERIOD 2 //be equal to watchdog check time
  37421. +#define DEFAULT_KEEP_ALIVE_LEVEL 1
  37422. +
  37423. +typedef struct _link_detect_t
  37424. +{
  37425. + u32 RxFrameNum[MAX_LD_SLOT_NUM]; // number of Rx Frame / CheckForHang_period to determine link status
  37426. + u16 SlotNum; // number of CheckForHang period to determine link status, default is 2
  37427. + u16 SlotIndex;
  37428. +
  37429. + u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang
  37430. + u32 NumRxOkInPeriod; //number of packet received during CheckForHang
  37431. +
  37432. + u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)
  37433. + u32 LastNumTxUnicast;
  37434. + u32 LastNumRxUnicast;
  37435. +
  37436. + bool bBusyTraffic; //when it is set to 1, UI cann't scan at will.
  37437. +}link_detect_t, *plink_detect_t;
  37438. +
  37439. +#if 0
  37440. +
  37441. +typedef struct tx_pendingbuf
  37442. +{
  37443. + struct ieee80211_txb *txb;
  37444. + short ispending;
  37445. + short descfrag;
  37446. +} tx_pendigbuf;
  37447. +
  37448. +#endif
  37449. +
  37450. +typedef struct Stats
  37451. +{
  37452. + unsigned long txrdu;
  37453. +// unsigned long rxrdu;
  37454. + //unsigned long rxnolast;
  37455. + //unsigned long rxnodata;
  37456. +// unsigned long rxreset;
  37457. +// unsigned long rxwrkaround;
  37458. +// unsigned long rxnopointer;
  37459. + unsigned long rxok;
  37460. + unsigned long rxurberr;
  37461. + unsigned long rxstaterr;
  37462. + unsigned long txnperr;
  37463. + unsigned long txnpdrop;
  37464. + unsigned long txresumed;
  37465. +// unsigned long rxerr;
  37466. +// unsigned long rxoverflow;
  37467. +// unsigned long rxint;
  37468. + unsigned long txnpokint;
  37469. +// unsigned long txhpokint;
  37470. +// unsigned long txhperr;
  37471. +// unsigned long ints;
  37472. +// unsigned long shints;
  37473. + unsigned long txoverflow;
  37474. +// unsigned long rxdmafail;
  37475. +// unsigned long txbeacon;
  37476. +// unsigned long txbeaconerr;
  37477. + unsigned long txlpokint;
  37478. + unsigned long txlpdrop;
  37479. + unsigned long txlperr;
  37480. + unsigned long txbeokint;
  37481. + unsigned long txbedrop;
  37482. + unsigned long txbeerr;
  37483. + unsigned long txbkokint;
  37484. + unsigned long txbkdrop;
  37485. + unsigned long txbkerr;
  37486. + unsigned long txviokint;
  37487. + unsigned long txvidrop;
  37488. + unsigned long txvierr;
  37489. + unsigned long txvookint;
  37490. + unsigned long txvodrop;
  37491. + unsigned long txvoerr;
  37492. + unsigned long txbeaconokint;
  37493. + unsigned long txbeacondrop;
  37494. + unsigned long txbeaconerr;
  37495. + unsigned long txmanageokint;
  37496. + unsigned long txmanagedrop;
  37497. + unsigned long txmanageerr;
  37498. + unsigned long txdatapkt;
  37499. +} Stats;
  37500. +
  37501. +typedef struct ChnlAccessSetting {
  37502. + u16 SIFS_Timer;
  37503. + u16 DIFS_Timer;
  37504. + u16 SlotTimeTimer;
  37505. + u16 EIFS_Timer;
  37506. + u16 CWminIndex;
  37507. + u16 CWmaxIndex;
  37508. +}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
  37509. +
  37510. +
  37511. +typedef enum _RT_RF_POWER_STATE
  37512. +{
  37513. + eRfOn,
  37514. + eRfSleep,
  37515. + eRfOff
  37516. +}RT_RF_POWER_STATE;
  37517. +typedef enum _RT_PS_MODE
  37518. +{
  37519. + eActive, // Active/Continuous access.
  37520. + eMaxPs, // Max power save mode.
  37521. + eFastPs // Fast power save mode.
  37522. +}RT_PS_MODE;
  37523. +//
  37524. +// Three wire mode.
  37525. +//
  37526. +#define IC_DEFAULT_THREE_WIRE 0
  37527. +#define SW_THREE_WIRE 1
  37528. +//RTL818xB
  37529. +#define SW_THREE_WIRE_BY_8051 2
  37530. +#define HW_THREE_WIRE 3
  37531. +#define HW_THREE_WIRE_BY_8051 4
  37532. +//lzm add for write time out test
  37533. +typedef struct write_read_register
  37534. +{
  37535. + u32 address;
  37536. + u32 content;
  37537. + u32 flag;
  37538. +} write_read_register;
  37539. +//lzm add for write time out test
  37540. +typedef struct r8180_priv
  37541. +{
  37542. +//lzm add for write time out test
  37543. + struct write_read_register write_read_registers[200];
  37544. + u8 write_read_register_index;
  37545. +//lzm add for write time out test
  37546. +
  37547. + struct usb_device *udev;
  37548. + short epromtype;
  37549. + int irq;
  37550. + struct ieee80211_device *ieee80211;
  37551. +
  37552. + short card_8187; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D */
  37553. + short card_8187_Bversion; /* if TCR reports card V B/C this discriminates */
  37554. + short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
  37555. + short enable_gpio0;
  37556. + enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
  37557. + short hw_plcp_len;
  37558. + short plcp_preamble_mode;
  37559. +
  37560. + spinlock_t irq_lock;
  37561. +// spinlock_t irq_th_lock;
  37562. + spinlock_t tx_lock;
  37563. +//by amy for ps
  37564. + spinlock_t rf_ps_lock;
  37565. +//by amy for ps
  37566. +
  37567. + u16 irq_mask;
  37568. +// short irq_enabled;
  37569. + struct net_device *dev;
  37570. + short chan;
  37571. + short sens;
  37572. + short max_sens;
  37573. + u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
  37574. + u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
  37575. + u8 cck_txpwr_base;
  37576. + u8 ofdm_txpwr_base;
  37577. + u8 challow[15]; //channels from 1 to 14, 0 not used
  37578. + short up;
  37579. + short crcmon; //if 1 allow bad crc frame reception in monitor mode
  37580. +// short prism_hdr;
  37581. +
  37582. +// struct timer_list scan_timer;
  37583. + /*short scanpending;
  37584. + short stopscan;*/
  37585. +// spinlock_t scan_lock;
  37586. +// u8 active_probe;
  37587. + //u8 active_scan_num;
  37588. + struct semaphore wx_sem;
  37589. + struct semaphore set_chan_sem;
  37590. +// short hw_wep;
  37591. +
  37592. +// short digphy;
  37593. +// short antb;
  37594. +// short diversity;
  37595. +// u8 cs_treshold;
  37596. +// short rcr_csense;
  37597. + short rf_chip;
  37598. +// u32 key0[4];
  37599. + short (*rf_set_sens)(struct net_device *dev,short sens);
  37600. + void (*rf_set_chan)(struct net_device *dev,short ch);
  37601. + void (*rf_close)(struct net_device *dev);
  37602. + void (*rf_init)(struct net_device *dev);
  37603. + //short rate;
  37604. + short promisc;
  37605. + /*stats*/
  37606. + struct Stats stats;
  37607. + struct _link_detect_t link_detect; //added on 1016.2008
  37608. + struct iw_statistics wstats;
  37609. + struct proc_dir_entry *dir_dev;
  37610. +
  37611. + /*RX stuff*/
  37612. +// u32 *rxring;
  37613. +// u32 *rxringtail;
  37614. +// dma_addr_t rxringdma;
  37615. + struct urb **rx_urb;
  37616. +#ifdef THOMAS_BEACON
  37617. + unsigned long *oldaddr; //lzm for 64bit CPU crash
  37618. +#endif
  37619. +
  37620. +#ifdef THOMAS_TASKLET
  37621. + atomic_t irt_counter;//count for irq_rx_tasklet
  37622. +#endif
  37623. +#ifdef JACKSON_NEW_RX
  37624. + struct sk_buff **pp_rxskb;
  37625. + int rx_inx;
  37626. +#endif
  37627. +
  37628. + short tx_urb_index;
  37629. +
  37630. + //struct buffer *rxbuffer;
  37631. + //struct buffer *rxbufferhead;
  37632. + //int rxringcount;
  37633. + //u16 rxbuffersize;
  37634. +
  37635. + //struct sk_buff *rx_skb;
  37636. +
  37637. + //short rx_skb_complete;
  37638. +
  37639. + //u32 rx_prevlen;
  37640. + //atomic_t tx_lp_pending;
  37641. + //atomic_t tx_np_pending;
  37642. + atomic_t tx_pending[0x10];//UART_PRIORITY+1
  37643. +
  37644. +#if 0
  37645. + /*TX stuff*/
  37646. + u32 *txlpring;
  37647. + u32 *txhpring;
  37648. + u32 *txnpring;
  37649. + dma_addr_t txlpringdma;
  37650. + dma_addr_t txhpringdma;
  37651. + dma_addr_t txnpringdma;
  37652. + u32 *txlpringtail;
  37653. + u32 *txhpringtail;
  37654. + u32 *txnpringtail;
  37655. + u32 *txlpringhead;
  37656. + u32 *txhpringhead;
  37657. + u32 *txnpringhead;
  37658. + struct buffer *txlpbufs;
  37659. + struct buffer *txhpbufs;
  37660. + struct buffer *txnpbufs;
  37661. + struct buffer *txlpbufstail;
  37662. + struct buffer *txhpbufstail;
  37663. + struct buffer *txnpbufstail;
  37664. + int txringcount;
  37665. + int txbuffsize;
  37666. +
  37667. + //struct tx_pendingbuf txnp_pending;
  37668. + struct tasklet_struct irq_tx_tasklet;
  37669. +#endif
  37670. + struct tasklet_struct irq_rx_tasklet;
  37671. + struct urb *rxurb_task;
  37672. +// u8 dma_poll_mask;
  37673. + //short tx_suspend;
  37674. +
  37675. + /* adhoc/master mode stuff */
  37676. +#if 0
  37677. + u32 *txbeacontail;
  37678. + dma_addr_t txbeaconringdma;
  37679. + u32 *txbeaconring;
  37680. + int txbeaconcount;
  37681. +#endif
  37682. +// struct ieee_tx_beacon *beacon_buf;
  37683. + //char *master_essid;
  37684. +// dma_addr_t beacondmabuf;
  37685. + //u16 master_beaconinterval;
  37686. +// u32 master_beaconsize;
  37687. + //u16 beacon_interval;
  37688. +
  37689. + //2 Tx Related variables
  37690. + u16 ShortRetryLimit;
  37691. + u16 LongRetryLimit;
  37692. + u32 TransmitConfig;
  37693. + u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27.
  37694. +
  37695. + //2 Rx Related variables
  37696. + u16 EarlyRxThreshold;
  37697. + u32 ReceiveConfig;
  37698. + u8 AcmControl;
  37699. +
  37700. + u8 RFProgType;
  37701. +
  37702. + u8 retry_data;
  37703. + u8 retry_rts;
  37704. + u16 rts;
  37705. +
  37706. +//by amy
  37707. + long LastSignalStrengthInPercent;
  37708. + long SignalStrength;
  37709. + long SignalQuality;
  37710. + u8 antenna_flag;
  37711. + bool flag_beacon;
  37712. +//by amy
  37713. +//by amy for rate adaptive
  37714. + struct timer_list rateadapter_timer;
  37715. + u16 LastRetryCnt;
  37716. + u16 LastRetryRate;
  37717. + unsigned long LastTxokCnt;
  37718. + unsigned long LastRxokCnt;
  37719. + u16 CurrRetryCnt;
  37720. + long RecvSignalPower;
  37721. + unsigned long LastTxOKBytes;
  37722. + u8 LastFailTxRate;
  37723. + long LastFailTxRateSS;
  37724. + u8 FailTxRateCount;
  37725. + u32 LastTxThroughput;
  37726. + unsigned long txokbytestotal;
  37727. + //for up rate
  37728. + unsigned short bTryuping;
  37729. + u8 CurrTxRate; //the rate before up
  37730. + u16 CurrRetryRate;
  37731. + u16 TryupingCount;
  37732. + u8 TryDownCountLowData;
  37733. + u8 TryupingCountNoData;
  37734. +
  37735. + u8 CurrentOperaRate;
  37736. +//by amy for rate adaptive
  37737. +//by amy for power save
  37738. + struct timer_list watch_dog_timer;
  37739. + bool bInactivePs;
  37740. + bool bSwRfProcessing;
  37741. + RT_RF_POWER_STATE eInactivePowerState;
  37742. + RT_RF_POWER_STATE eRFPowerState;
  37743. + u32 RfOffReason;
  37744. + bool RFChangeInProgress;
  37745. + bool bInHctTest;
  37746. + bool SetRFPowerStateInProgress;
  37747. + //u8 RFProgType;
  37748. + bool bLeisurePs;
  37749. + RT_PS_MODE dot11PowerSaveMode;
  37750. + u32 NumRxOkInPeriod;
  37751. + u32 NumTxOkInPeriod;
  37752. + u8 RegThreeWireMode;
  37753. + bool ps_mode;
  37754. +//by amy for power save
  37755. +//by amy for DIG
  37756. + bool bDigMechanism;
  37757. + bool bCCKThMechanism;
  37758. + u8 InitialGain;
  37759. + u8 StageCCKTh;
  37760. + u8 RegBModeGainStage;
  37761. + u8 RegDigOfdmFaUpTh; //added by david, 2008.3.6
  37762. + u8 DIG_NumberFallbackVote;
  37763. + u8 DIG_NumberUpgradeVote;
  37764. + u16 CCKUpperTh;
  37765. + u16 CCKLowerTh;
  37766. + u32 FalseAlarmRegValue; //added by david, 2008.3.6
  37767. +//by amy for DIG
  37768. +//{ added by david for high power, 2008.3.11
  37769. + int UndecoratedSmoothedSS;
  37770. + bool bRegHighPowerMechanism;
  37771. + bool bToUpdateTxPwr;
  37772. + u8 Z2HiPwrUpperTh;
  37773. + u8 Z2HiPwrLowerTh;
  37774. + u8 Z2RSSIHiPwrUpperTh;
  37775. + u8 Z2RSSIHiPwrLowerTh;
  37776. + // Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, by Bruce, 2007-04-12.
  37777. + u8 CurCCKRSSI;
  37778. + bool bCurCCKPkt;
  37779. + u32 wMacRegRfPinsOutput;
  37780. + u32 wMacRegRfPinsSelect;
  37781. + TR_SWITCH_STATE TrSwitchState;
  37782. +//}
  37783. +//{added by david for radio on/off
  37784. + u8 radion;
  37785. +//}
  37786. + struct ChnlAccessSetting ChannelAccessSetting;
  37787. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
  37788. + struct work_struct reset_wq;
  37789. +#else
  37790. + struct tq_struct reset_wq;
  37791. +#endif
  37792. +
  37793. +#ifdef _RTL8187_EXT_PATCH_
  37794. + struct mshclass *mshobj;
  37795. +#endif
  37796. +
  37797. +#ifdef LED
  37798. + /* add for led controll */
  37799. + u8 EEPROMCustomerID;
  37800. + RT_CID_TYPE CustomerID;
  37801. + LED_8187 Gpio0Led;
  37802. + LED_8187 SwLed0;
  37803. + LED_8187 SwLed1;
  37804. + u8 bEnableLedCtrl;
  37805. + LED_STRATEGY_8187 LedStrategy;
  37806. + u8 PsrValue;
  37807. + struct work_struct Gpio0LedWorkItem;
  37808. + struct work_struct SwLed0WorkItem;
  37809. + struct work_struct SwLed1WorkItem;
  37810. +#endif
  37811. + u8 driver_upping;
  37812. +#ifdef CPU_64BIT
  37813. + u8 *usb_buf;
  37814. + struct dma_pool *usb_pool;
  37815. +#endif
  37816. +
  37817. +
  37818. +#ifdef SW_ANTE_DIVERSITY
  37819. +
  37820. +//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  37821. +// struct delayed_work SwAntennaWorkItem;
  37822. +//#else
  37823. +// struct work_struct SwAntennaWorkItem;
  37824. +//#endif
  37825. +
  37826. + bool bAntennaDiversityTimerIssued;
  37827. + short antb;
  37828. + short diversity;
  37829. + bool AutoloadFailFlag;
  37830. + u16 EEPROMVersion;
  37831. + u8 EEPROMAntennaDiversity;
  37832. + u16 EEPROMCSThreshold;
  37833. + u8 EEPROMDefaultAntennaB;
  37834. + u8 EEPROMDigitalPhy;
  37835. + u32 EEPROMCSMethod;
  37836. + u8 EEPROMGEPRFOffState;
  37837. + // For HW antenna diversity, added by Roger, 2008.01.30.
  37838. + u32 AdMainAntennaRxOkCnt; // Main antenna Rx OK count.
  37839. + u32 AdAuxAntennaRxOkCnt; // Aux antenna Rx OK count.
  37840. + bool bHWAdSwitched; // TRUE if we has switched default antenna by HW evaluation.
  37841. + u8 EEPROMSwAntennaDiversity;
  37842. + bool EEPROMDefaultAntenna1;
  37843. + u8 RegSwAntennaDiversityMechanism;// 0:default from EEPROM, 1: disable, 2: enable.
  37844. + bool bSwAntennaDiverity;
  37845. + u8 RegDefaultAntenna;// 0: default from EEPROM, 1: main, 2: aux. Added by Roger, 2007.11.05.
  37846. + bool bDefaultAntenna1;
  37847. + //long SignalStrength;
  37848. + long Stats_SignalStrength;
  37849. + //long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average.
  37850. + //long SignalQuality; // in 0-100 index.
  37851. + long Stats_SignalQuality;
  37852. + //long RecvSignalPower; // in dBm.
  37853. + long Stats_RecvSignalPower;
  37854. + u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25.
  37855. + u32 AdRxOkCnt;
  37856. + long AdRxSignalStrength; // Rx signal strength for Antenna Diversity, which had been smoothing, its valid range is [0,100].
  37857. + u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx).
  37858. + u8 AdTickCount; // Times of SwAntennaDiversityTimer happened.
  37859. + u8 AdCheckPeriod; // # of period SwAntennaDiversityTimer to check Rx signal strength for SW Antenna Diversity.
  37860. + u8 AdMinCheckPeriod; // Min value of AdCheckPeriod.
  37861. + u8 AdMaxCheckPeriod; // Max value of AdCheckPeriod.
  37862. + long AdRxSsThreshold; // Signal strength threshold to switch antenna.
  37863. + long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold.
  37864. + bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna.
  37865. + long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna.
  37866. + struct timer_list SwAntennaDiversityTimer;
  37867. +#endif
  37868. + u8 commit;
  37869. +
  37870. +//#ifdef ENABLE_DOT11D
  37871. + u8 channel_plan;
  37872. +//#endif
  37873. + u8 EEPROMSelectNewGPIO;
  37874. +}r8180_priv;
  37875. +
  37876. +// for rtl8187
  37877. +// now mirging to rtl8187B
  37878. +/*
  37879. +typedef enum{
  37880. + LOW_PRIORITY = 0x02,
  37881. + NORM_PRIORITY
  37882. + } priority_t;
  37883. +*/
  37884. +//for rtl8187B
  37885. +typedef enum{
  37886. + BULK_PRIORITY = 0x01,
  37887. + //RSVD0,
  37888. + //RSVD1,
  37889. + LOW_PRIORITY,
  37890. + NORM_PRIORITY,
  37891. + VO_PRIORITY,
  37892. + VI_PRIORITY, //0x05
  37893. + BE_PRIORITY,
  37894. + BK_PRIORITY,
  37895. + RSVD2,
  37896. + RSVD3,
  37897. + BEACON_PRIORITY, //0x0A
  37898. + HIGH_PRIORITY,
  37899. + MANAGE_PRIORITY,
  37900. + RSVD4,
  37901. + RSVD5,
  37902. + UART_PRIORITY //0x0F
  37903. +} priority_t;
  37904. +
  37905. +typedef enum{
  37906. + NIC_8187 = 1,
  37907. + NIC_8187B
  37908. + } nic_t;
  37909. +
  37910. +
  37911. +typedef u32 AC_CODING;
  37912. +#define AC0_BE 0 // ACI: 0x00 // Best Effort
  37913. +#define AC1_BK 1 // ACI: 0x01 // Background
  37914. +#define AC2_VI 2 // ACI: 0x10 // Video
  37915. +#define AC3_VO 3 // ACI: 0x11 // Voice
  37916. +#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
  37917. +
  37918. +//
  37919. +// ECWmin/ECWmax field.
  37920. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
  37921. +//
  37922. +typedef union _ECW{
  37923. + u8 charData;
  37924. + struct
  37925. + {
  37926. + u8 ECWmin:4;
  37927. + u8 ECWmax:4;
  37928. + }f; // Field
  37929. +}ECW, *PECW;
  37930. +
  37931. +//
  37932. +// ACI/AIFSN Field.
  37933. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
  37934. +//
  37935. +typedef union _ACI_AIFSN{
  37936. + u8 charData;
  37937. +
  37938. + struct
  37939. + {
  37940. + u8 AIFSN:4;
  37941. + u8 ACM:1;
  37942. + u8 ACI:2;
  37943. + u8 Reserved:1;
  37944. + }f; // Field
  37945. +}ACI_AIFSN, *PACI_AIFSN;
  37946. +
  37947. +//
  37948. +// AC Parameters Record Format.
  37949. +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
  37950. +//
  37951. +typedef union _AC_PARAM{
  37952. + u32 longData;
  37953. + u8 charData[4];
  37954. +
  37955. + struct
  37956. + {
  37957. + ACI_AIFSN AciAifsn;
  37958. + ECW Ecw;
  37959. + u16 TXOPLimit;
  37960. + }f; // Field
  37961. +}AC_PARAM, *PAC_PARAM;
  37962. +
  37963. +#ifdef JOHN_HWSEC
  37964. +struct ssid_thread {
  37965. + struct net_device *dev;
  37966. + u8 name[IW_ESSID_MAX_SIZE + 1];
  37967. +};
  37968. +#endif
  37969. +
  37970. +short rtl8180_tx(struct net_device *dev,u32* skbuf, int len,priority_t priority,short morefrag,short rate);
  37971. +
  37972. +#ifdef JOHN_TKIP
  37973. +u32 read_cam(struct net_device *dev, u8 addr);
  37974. +void write_cam(struct net_device *dev, u8 addr, u32 data);
  37975. +#endif
  37976. +u8 read_nic_byte(struct net_device *dev, int x);
  37977. +u8 read_nic_byte_E(struct net_device *dev, int x);
  37978. +u32 read_nic_dword(struct net_device *dev, int x);
  37979. +u16 read_nic_word(struct net_device *dev, int x) ;
  37980. +void write_nic_byte(struct net_device *dev, int x,u8 y);
  37981. +void write_nic_byte_E(struct net_device *dev, int x,u8 y);
  37982. +void write_nic_word(struct net_device *dev, int x,u16 y);
  37983. +void write_nic_dword(struct net_device *dev, int x,u32 y);
  37984. +void force_pci_posting(struct net_device *dev);
  37985. +
  37986. +void rtl8180_rtx_disable(struct net_device *);
  37987. +void rtl8180_rx_enable(struct net_device *);
  37988. +void rtl8180_tx_enable(struct net_device *);
  37989. +
  37990. +void rtl8180_disassociate(struct net_device *dev);
  37991. +//void fix_rx_fifo(struct net_device *dev);
  37992. +void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
  37993. +
  37994. +void rtl8180_set_anaparam(struct net_device *dev,u32 a);
  37995. +void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
  37996. +void rtl8180_update_msr(struct net_device *dev);
  37997. +int rtl8180_down(struct net_device *dev);
  37998. +int rtl8180_up(struct net_device *dev);
  37999. +void rtl8180_commit(struct net_device *dev);
  38000. +void rtl8180_set_chan(struct net_device *dev,short ch);
  38001. +void write_phy(struct net_device *dev, u8 adr, u8 data);
  38002. +void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
  38003. +void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
  38004. +void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
  38005. +void rtl8187_set_rxconf(struct net_device *dev);
  38006. +bool MgntActSet_RF_State(struct net_device *dev,RT_RF_POWER_STATE StateToSet,u32 ChangeSource);
  38007. +void IPSEnter(struct net_device *dev);
  38008. +void IPSLeave(struct net_device *dev);
  38009. +int r8187b_rfkill_init(struct net_device *dev);
  38010. +void r8187b_rfkill_exit(void);
  38011. +int r8187b_wifi_report_state(r8180_priv *priv);
  38012. +void r8187b_wifi_change_rfkill_state(struct net_device *dev, RT_RF_POWER_STATE eRfPowerStateToSet);
  38013. +bool SetRFPowerState(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
  38014. +void rtl8180_patch_ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
  38015. +#ifdef _RTL8187_EXT_PATCH_
  38016. +extern int r8180_wx_set_channel(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra);
  38017. +#endif
  38018. +#ifdef JOHN_TKIP
  38019. +void EnableHWSecurityConfig8187(struct net_device *dev);
  38020. +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
  38021. +
  38022. +#endif
  38023. +
  38024. +#endif
  38025. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_led.c linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.c
  38026. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_led.c 1970-01-01 01:00:00.000000000 +0100
  38027. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.c 2010-05-27 18:12:39.532222207 +0200
  38028. @@ -0,0 +1,1629 @@
  38029. +/*++
  38030. +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
  38031. +
  38032. +Module Name:
  38033. + r8187_led.c
  38034. +
  38035. +Abstract:
  38036. + RTL8187 LED control functions
  38037. +
  38038. +Major Change History:
  38039. + When Who What
  38040. + ---------- --------------- -------------------------------
  38041. + 2006-09-07 Xiong Created
  38042. +
  38043. +Notes:
  38044. +
  38045. +--*/
  38046. +
  38047. +/*--------------------------Include File------------------------------------*/
  38048. +#include "ieee80211/ieee80211.h"
  38049. +#include "r8180_hw.h"
  38050. +#include "r8187.h"
  38051. +#include "r8180_93cx6.h"
  38052. +#include "r8187_led.h"
  38053. +
  38054. +/**
  38055. +*
  38056. +* Initialization function for Sw Leds controll.
  38057. +*
  38058. +* \param dev The net device for this driver.
  38059. +* \return void.
  38060. +*
  38061. +* Note:
  38062. +*
  38063. +*/
  38064. +
  38065. +void
  38066. +InitSwLeds(
  38067. + struct net_device *dev
  38068. + )
  38069. +{
  38070. +
  38071. + struct r8180_priv *priv = ieee80211_priv(dev);
  38072. + u16 usValue;
  38073. +// printk("========>%s()\n", __FUNCTION__);
  38074. +
  38075. +// priv->CustomerID = RT_CID_87B_DELL; //by lizhaoming for DELL 2008.6.3
  38076. + priv->CustomerID = RT_CID_DEFAULT; //just set to default now
  38077. + priv->bEnableLedCtrl = 1;
  38078. + priv->PsrValue = read_nic_byte(dev, PSR);
  38079. + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET >> 1);
  38080. + priv->EEPROMCustomerID = (u8)( usValue & EEPROM_CID_MASK );
  38081. + DMESG("EEPROM Customer ID: %02X", priv->EEPROMCustomerID);
  38082. +
  38083. + if(priv->CustomerID == RT_CID_DEFAULT)
  38084. + { // If we have not yet change priv->CustomerID in register,
  38085. + // we initialzie it from that of EEPROM with proper translation, 2006.07.03, by rcnjko.
  38086. + switch(priv->EEPROMCustomerID)
  38087. + {
  38088. + case EEPROM_CID_RSVD0:
  38089. + case EEPROM_CID_RSVD1:
  38090. + priv->CustomerID = RT_CID_DEFAULT;
  38091. + break;
  38092. +
  38093. + case EEPROM_CID_ALPHA0:
  38094. + priv->CustomerID = RT_CID_8187_ALPHA0;
  38095. + break;
  38096. +
  38097. + case EEPROM_CID_SERCOMM_PS:
  38098. + priv->CustomerID = RT_CID_8187_SERCOMM_PS;
  38099. + break;
  38100. +
  38101. + case EEPROM_CID_HW_LED:
  38102. + priv->CustomerID = RT_CID_8187_HW_LED;
  38103. + break;
  38104. +
  38105. + case EEPROM_CID_QMI:
  38106. + priv->CustomerID = RT_CID_87B_QMI;
  38107. + break;
  38108. +
  38109. + case EEPROM_CID_DELL:
  38110. + priv->CustomerID = RT_CID_87B_DELL;
  38111. + break;
  38112. +
  38113. + default:
  38114. + // Invalid value, so, we use default value instead.
  38115. + priv->CustomerID = RT_CID_DEFAULT;
  38116. + break;
  38117. + }
  38118. + }
  38119. + switch(priv->CustomerID)
  38120. + {
  38121. + case RT_CID_DEFAULT:
  38122. + priv->LedStrategy = SW_LED_MODE0;
  38123. + break;
  38124. +
  38125. + case RT_CID_8187_ALPHA0:
  38126. + priv->LedStrategy = SW_LED_MODE1;
  38127. + break;
  38128. +
  38129. + case RT_CID_8187_SERCOMM_PS:
  38130. + priv->LedStrategy = SW_LED_MODE3;
  38131. + break;
  38132. +
  38133. + case RT_CID_87B_QMI:
  38134. + priv->LedStrategy = SW_LED_MODE4;
  38135. + break;
  38136. +
  38137. + case RT_CID_87B_DELL:
  38138. + priv->LedStrategy = SW_LED_MODE5;
  38139. + break;
  38140. +
  38141. + case RT_CID_8187_HW_LED:
  38142. + priv->LedStrategy = HW_LED;
  38143. + break;
  38144. +
  38145. + default:
  38146. + priv->LedStrategy = SW_LED_MODE0;
  38147. + break;
  38148. + }
  38149. +
  38150. + InitLed8187(dev,
  38151. + &(priv->Gpio0Led),
  38152. + LED_PIN_GPIO0,
  38153. + Gpio0LedBlinkTimerCallback);
  38154. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  38155. + INIT_WORK(&priv->Gpio0LedWorkItem,
  38156. + (void(*)(void*))Gpio0LedWorkItemCallback, dev);
  38157. +
  38158. + InitLed8187(dev,
  38159. + &(priv->SwLed0),
  38160. + LED_PIN_LED0,
  38161. + SwLed0BlinkTimerCallback);
  38162. + INIT_WORK(&priv->SwLed0WorkItem,
  38163. + (void(*)(void*))SwLed0WorkItemCallback, dev);
  38164. +
  38165. + InitLed8187(dev,
  38166. + &(priv->SwLed1),
  38167. + LED_PIN_LED1,
  38168. + SwLed1BlinkTimerCallback);
  38169. + INIT_WORK(&priv->SwLed1WorkItem,
  38170. + (void(*)(void*))SwLed1WorkItemCallback, dev);
  38171. +#else
  38172. +INIT_WORK(&priv->Gpio0LedWorkItem,
  38173. + Gpio0LedWorkItemCallback);
  38174. +
  38175. + InitLed8187(dev,
  38176. + &(priv->SwLed0),
  38177. + LED_PIN_LED0,
  38178. + SwLed0BlinkTimerCallback);
  38179. + INIT_WORK(&priv->SwLed0WorkItem,
  38180. + SwLed0WorkItemCallback);
  38181. +
  38182. + InitLed8187(dev,
  38183. + &(priv->SwLed1),
  38184. + LED_PIN_LED1,
  38185. + SwLed1BlinkTimerCallback);
  38186. + INIT_WORK(&priv->SwLed1WorkItem,
  38187. + SwLed1WorkItemCallback);
  38188. +#endif
  38189. +}
  38190. +
  38191. +void
  38192. +DeInitSwLeds(
  38193. + struct net_device *dev
  38194. + )
  38195. +{
  38196. + struct r8180_priv *priv = ieee80211_priv(dev);
  38197. +
  38198. +// printk("=========>%s In\n", __FUNCTION__);
  38199. + DeInitLed8187(dev, &(priv->Gpio0Led));
  38200. + DeInitLed8187(dev, &(priv->SwLed0));
  38201. + DeInitLed8187(dev, &(priv->SwLed1));
  38202. +}
  38203. +
  38204. +void
  38205. +InitLed8187(
  38206. + struct net_device *dev,
  38207. + PLED_8187 pLed,
  38208. + LED_PIN_8187 LedPin,
  38209. + void * BlinkCallBackFunc)
  38210. +{
  38211. +// printk("=========>%s In\n", __FUNCTION__);
  38212. + pLed->LedPin = LedPin;
  38213. +
  38214. + pLed->bLedOn = 0;
  38215. + pLed->CurrLedState = LED_OFF;
  38216. +
  38217. + pLed->bLedBlinkInProgress = 0;
  38218. + pLed->BlinkTimes = 0;
  38219. + pLed->BlinkingLedState = LED_OFF;
  38220. +
  38221. + init_timer(&(pLed->BlinkTimer));
  38222. + pLed->BlinkTimer.data = (unsigned long)dev;
  38223. + pLed->BlinkTimer.function = BlinkCallBackFunc;
  38224. + //PlatformInitializeTimer(dev, &(pLed->BlinkTimer), BlinkCallBackFunc);
  38225. +}
  38226. +
  38227. +void
  38228. +DeInitLed8187(
  38229. + struct net_device *dev,
  38230. + PLED_8187 pLed)
  38231. +{
  38232. + //printk("=========>%s In\n", __FUNCTION__);
  38233. + //PlatformCancelTimer(dev, &(pLed->BlinkTimer));
  38234. + del_timer_sync(&(pLed->BlinkTimer));
  38235. + // We should reset bLedBlinkInProgress if we cancel the LedControlTimer, 2005.03.10, by rcnjko.
  38236. + pLed->bLedBlinkInProgress = 0;
  38237. +}
  38238. +
  38239. +void
  38240. +LedControl8187(
  38241. + struct net_device *dev,
  38242. + LED_CTL_MODE LedAction
  38243. +)
  38244. +{
  38245. + struct r8180_priv *priv = ieee80211_priv(dev);
  38246. +// printk("=========>%s In\n", __FUNCTION__);
  38247. + if( priv->bEnableLedCtrl == 0)
  38248. + return;
  38249. +
  38250. +
  38251. + if( priv->eRFPowerState != eRfOn &&
  38252. + (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
  38253. + LedAction == LED_CTL_SITE_SURVEY ||
  38254. + LedAction == LED_CTL_LINK ||
  38255. + LedAction == LED_CTL_NO_LINK) )
  38256. + {
  38257. + return;
  38258. + }
  38259. +
  38260. +
  38261. + switch(priv->LedStrategy)
  38262. + {
  38263. + case SW_LED_MODE0:
  38264. + SwLedControlMode0(dev, LedAction);
  38265. + break;
  38266. +
  38267. + case SW_LED_MODE1:
  38268. + SwLedControlMode1(dev, LedAction);
  38269. + break;
  38270. +
  38271. + case SW_LED_MODE2:
  38272. + SwLedControlMode2(dev, LedAction);
  38273. + break;
  38274. +
  38275. + case SW_LED_MODE3:
  38276. + SwLedControlMode3(dev, LedAction);
  38277. + break;
  38278. + case SW_LED_MODE4:
  38279. + SwLedControlMode4(dev, LedAction);
  38280. + break;
  38281. +
  38282. + case SW_LED_MODE5:
  38283. + SwLedControlMode5(dev, LedAction);
  38284. + break;
  38285. +
  38286. + default:
  38287. + break;
  38288. + }
  38289. +}
  38290. +
  38291. +
  38292. +//
  38293. +// Description:
  38294. +// Implement each led action for SW_LED_MODE0.
  38295. +// This is default strategy.
  38296. +//
  38297. +void
  38298. +SwLedControlMode0(
  38299. + struct net_device *dev,
  38300. + LED_CTL_MODE LedAction
  38301. +)
  38302. +{
  38303. + struct r8180_priv *priv = ieee80211_priv(dev);
  38304. + PLED_8187 pLed = &(priv->Gpio0Led);
  38305. +
  38306. +// printk("===+++++++++++++++======>%s In\n", __FUNCTION__);
  38307. + // Decide led state
  38308. + switch(LedAction)
  38309. + {
  38310. + case LED_CTL_TX:
  38311. + case LED_CTL_RX:
  38312. + if( pLed->bLedBlinkInProgress == 0 )
  38313. + {
  38314. + pLed->CurrLedState = LED_BLINK_NORMAL;
  38315. + pLed->BlinkTimes = 2;
  38316. + // printk("===========>LED_CTL_TX/RX \n");
  38317. + }
  38318. + else
  38319. + {
  38320. + return;
  38321. + }
  38322. + break;
  38323. +
  38324. + case LED_CTL_SITE_SURVEY:
  38325. + if( pLed->bLedBlinkInProgress == 0 )
  38326. + {
  38327. + pLed->CurrLedState = LED_BLINK_SLOWLY;
  38328. + // pLed->BlinkTimes = 10;
  38329. + //printk("===========>LED_CTL_SURVEY \n");
  38330. + }
  38331. + else
  38332. + {
  38333. + return;
  38334. + }
  38335. + break;
  38336. +
  38337. + case LED_CTL_LINK:
  38338. + // printk("===========>associate commplite LED_CTL_LINK\n");
  38339. + pLed->CurrLedState = LED_ON;
  38340. + break;
  38341. +
  38342. + case LED_CTL_NO_LINK:
  38343. + pLed->CurrLedState = LED_OFF;
  38344. + break;
  38345. +
  38346. + case LED_CTL_POWER_ON:
  38347. + // printk("===========>LED_CTL_POWER_ON\n");
  38348. + pLed->CurrLedState = LED_POWER_ON_BLINK;
  38349. + break;
  38350. +
  38351. + case LED_CTL_POWER_OFF:
  38352. + pLed->CurrLedState = LED_OFF;
  38353. + break;
  38354. +
  38355. + default:
  38356. + return;
  38357. + break;
  38358. + }
  38359. +
  38360. + // Change led state.
  38361. + switch(pLed->CurrLedState)
  38362. + {
  38363. + case LED_ON:
  38364. + if( pLed->bLedBlinkInProgress == 0 )
  38365. + {
  38366. + SwLedOn(dev, pLed);
  38367. + }
  38368. + break;
  38369. +
  38370. + case LED_OFF://modified by lizhaoming 2008.6.23
  38371. + // if( pLed->bLedBlinkInProgress == 0 )
  38372. + // {
  38373. + // SwLedOff(dev, pLed);
  38374. + // }
  38375. +
  38376. + if(pLed->bLedBlinkInProgress )/////////lizhaoming
  38377. + {
  38378. + del_timer_sync(&(pLed->BlinkTimer));
  38379. + pLed->bLedBlinkInProgress = FALSE;
  38380. + }
  38381. + SwLedOff(dev, pLed);
  38382. + break;
  38383. +
  38384. + case LED_BLINK_NORMAL:
  38385. + if( pLed->bLedBlinkInProgress == 0 )
  38386. + {
  38387. + pLed->bLedBlinkInProgress = 1;
  38388. + if( pLed->bLedOn )
  38389. + pLed->BlinkingLedState = LED_OFF;
  38390. + else
  38391. + pLed->BlinkingLedState = LED_ON;
  38392. +
  38393. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  38394. + //add_timer(&(pLed->BlinkTimer));
  38395. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  38396. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  38397. + }
  38398. + break;
  38399. +
  38400. + case LED_BLINK_SLOWLY:
  38401. + if( pLed->bLedBlinkInProgress == 0 )
  38402. + {
  38403. + //printk("=======>%s SLOWLY\n", __func__);
  38404. + pLed->bLedBlinkInProgress = 1;
  38405. + // if( pLed->bLedOn )
  38406. + pLed->BlinkingLedState = LED_OFF;//for LED_SHIN is LED on
  38407. + // else
  38408. + // pLed->BlinkingLedState = LED_ON;
  38409. +
  38410. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  38411. + }
  38412. + break;
  38413. +
  38414. + case LED_POWER_ON_BLINK:
  38415. + SwLedOn(dev, pLed);
  38416. +#ifdef LED_SHIN
  38417. + mdelay(100);
  38418. + SwLedOff(dev, pLed);
  38419. +#endif
  38420. + break;
  38421. +
  38422. + default:
  38423. + break;
  38424. + }
  38425. +}
  38426. +
  38427. +//
  38428. +// Description:
  38429. +// Implement each led action for SW_LED_MODE1.
  38430. +// For example, this is applied by ALPHA.
  38431. +//
  38432. +void
  38433. +SwLedControlMode1(
  38434. + struct net_device *dev,
  38435. + LED_CTL_MODE LedAction
  38436. +)
  38437. +{
  38438. + struct r8180_priv *priv = ieee80211_priv(dev);
  38439. + PLED_8187 pLed0 = &(priv->SwLed0);
  38440. + PLED_8187 pLed1 = &(priv->SwLed1);
  38441. +// printk("=====++++++++++++++++++++++====>%s In\n", __FUNCTION__);
  38442. +
  38443. + switch(LedAction)
  38444. + {
  38445. + case LED_CTL_TX:
  38446. + if( pLed0->bLedBlinkInProgress == 0 )
  38447. + {
  38448. + pLed0->CurrLedState = LED_BLINK_NORMAL;
  38449. + pLed0->BlinkTimes = 2;
  38450. + pLed0->bLedBlinkInProgress = 1;
  38451. + if( pLed0->bLedOn )
  38452. + pLed0->BlinkingLedState = LED_OFF;
  38453. + else
  38454. + pLed0->BlinkingLedState = LED_ON;
  38455. +
  38456. + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  38457. + //add_timer(&(pLed0->BlinkTimer));
  38458. + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  38459. + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  38460. + }
  38461. + break;
  38462. +
  38463. + case LED_CTL_LINK:
  38464. + pLed0->CurrLedState = LED_ON;
  38465. + if( pLed0->bLedBlinkInProgress == 0 )
  38466. + {
  38467. + SwLedOn(dev, pLed0);
  38468. + }
  38469. + break;
  38470. +
  38471. + case LED_CTL_NO_LINK:
  38472. + pLed0->CurrLedState = LED_OFF;
  38473. + if( pLed0->bLedBlinkInProgress == 0 )
  38474. + {
  38475. + SwLedOff(dev, pLed0);
  38476. + }
  38477. + break;
  38478. +
  38479. + case LED_CTL_POWER_ON:
  38480. + pLed0->CurrLedState = LED_OFF;
  38481. + SwLedOff(dev, pLed0);
  38482. +
  38483. + pLed1->CurrLedState = LED_ON;
  38484. + SwLedOn(dev, pLed1);
  38485. +
  38486. + break;
  38487. +
  38488. + case LED_CTL_POWER_OFF:
  38489. + pLed0->CurrLedState = LED_OFF;
  38490. + SwLedOff(dev, pLed0);
  38491. +
  38492. + pLed1->CurrLedState = LED_OFF;
  38493. + SwLedOff(dev, pLed1);
  38494. + break;
  38495. +
  38496. + case LED_CTL_SITE_SURVEY:
  38497. + if( pLed0->bLedBlinkInProgress == 0 )
  38498. + {
  38499. + pLed0->CurrLedState = LED_BLINK_SLOWLY;;
  38500. + pLed0->BlinkTimes = 10;
  38501. + pLed0->bLedBlinkInProgress = 1;
  38502. + if( pLed0->bLedOn )
  38503. + pLed0->BlinkingLedState = LED_OFF;
  38504. + else
  38505. + pLed0->BlinkingLedState = LED_ON;
  38506. +
  38507. + //pLed0->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  38508. + //add_timer(&(pLed0->BlinkTimer));
  38509. + mod_timer(&pLed0->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  38510. + //PlatformSetTimer(dev, &(pLed0->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  38511. + }
  38512. + break;
  38513. +
  38514. + default:
  38515. + break;
  38516. + }
  38517. +}
  38518. +
  38519. +//
  38520. +// Description:
  38521. +// Implement each led action for SW_LED_MODE2,
  38522. +// which is customized for AzWave 8187 minicard.
  38523. +// 2006.04.03, by rcnjko.
  38524. +//
  38525. +void
  38526. +SwLedControlMode2(
  38527. + struct net_device *dev,
  38528. + LED_CTL_MODE LedAction
  38529. +)
  38530. +{
  38531. + struct r8180_priv *priv = ieee80211_priv(dev);
  38532. + PLED_8187 pLed = &(priv->Gpio0Led);
  38533. +
  38534. +// printk("====+++++++++++++++++++++=====>%s In\n", __FUNCTION__);
  38535. + // Decide led state
  38536. + switch(LedAction)
  38537. + {
  38538. + case LED_CTL_TX:
  38539. + case LED_CTL_RX:
  38540. + if( pLed->bLedBlinkInProgress == 0 )
  38541. + {
  38542. + pLed->bLedBlinkInProgress = 1;
  38543. +
  38544. + pLed->CurrLedState = LED_BLINK_NORMAL;
  38545. + pLed->BlinkTimes = 2;
  38546. +
  38547. + if( pLed->bLedOn )
  38548. + pLed->BlinkingLedState = LED_OFF;
  38549. + else
  38550. + pLed->BlinkingLedState = LED_ON;
  38551. +
  38552. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  38553. + //add_timer(&(pLed->BlinkTimer));
  38554. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  38555. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  38556. + }
  38557. + break;
  38558. +
  38559. + case LED_CTL_SITE_SURVEY:
  38560. + if( pLed->bLedBlinkInProgress == 0 )
  38561. + {
  38562. + pLed->bLedBlinkInProgress = 1;
  38563. +
  38564. + //if( dev->MgntInfo.mAssoc ||
  38565. + // dev->MgntInfo.mIbss )
  38566. + //{
  38567. + pLed->CurrLedState = LED_SCAN_BLINK;
  38568. + pLed->BlinkTimes = 4;
  38569. + //}
  38570. + //else
  38571. + //{
  38572. + // pLed->CurrLedState = LED_NO_LINK_BLINK;
  38573. + // pLed->BlinkTimes = 24;
  38574. + //}
  38575. +
  38576. + if( pLed->bLedOn )
  38577. + {
  38578. + pLed->BlinkingLedState = LED_OFF;
  38579. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  38580. + //add_timer(&(pLed->BlinkTimer));
  38581. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  38582. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  38583. + }
  38584. + else
  38585. + {
  38586. + pLed->BlinkingLedState = LED_ON;
  38587. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
  38588. + //add_timer(&(pLed->BlinkTimer));
  38589. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
  38590. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
  38591. + }
  38592. + }
  38593. + else
  38594. + {
  38595. + if(pLed->CurrLedState != LED_NO_LINK_BLINK)
  38596. + {
  38597. + pLed->CurrLedState = LED_SCAN_BLINK;
  38598. + /*
  38599. + if( dev->MgntInfo.mAssoc ||
  38600. + dev->MgntInfo.mIbss )
  38601. + {
  38602. + pLed->CurrLedState = LED_SCAN_BLINK;
  38603. + }
  38604. + else
  38605. + {
  38606. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  38607. + }
  38608. + */
  38609. + }
  38610. + }
  38611. + break;
  38612. +
  38613. + case LED_CTL_NO_LINK:
  38614. + if( pLed->bLedBlinkInProgress == 0 )
  38615. + {
  38616. + pLed->bLedBlinkInProgress = 1;
  38617. +
  38618. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  38619. + pLed->BlinkTimes = 24;
  38620. +
  38621. + if( pLed->bLedOn )
  38622. + {
  38623. + pLed->BlinkingLedState = LED_OFF;
  38624. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  38625. + //add_timer(&(pLed->BlinkTimer));
  38626. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  38627. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  38628. + }
  38629. + else
  38630. + {
  38631. + pLed->BlinkingLedState = LED_ON;
  38632. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
  38633. + //add_timer(&(pLed->BlinkTimer));
  38634. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
  38635. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
  38636. + }
  38637. + }
  38638. + else
  38639. + {
  38640. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  38641. + }
  38642. + break;
  38643. +
  38644. + case LED_CTL_LINK:
  38645. + pLed->CurrLedState = LED_ON;
  38646. + if( pLed->bLedBlinkInProgress == 0 )
  38647. + {
  38648. + SwLedOn(dev, pLed);
  38649. + }
  38650. + break;
  38651. +
  38652. + case LED_CTL_POWER_OFF:
  38653. + pLed->CurrLedState = LED_OFF;
  38654. + if( pLed->bLedBlinkInProgress == 0 )
  38655. + {
  38656. + SwLedOff(dev, pLed);
  38657. + }
  38658. + break;
  38659. +
  38660. + default:
  38661. + break;
  38662. + }
  38663. +}
  38664. +
  38665. +
  38666. +//
  38667. +// Description:
  38668. +// Implement each led action for SW_LED_MODE3,
  38669. +// which is customized for Sercomm Printer Server case.
  38670. +// 2006.04.21, by rcnjko.
  38671. +//
  38672. +void
  38673. +SwLedControlMode3(
  38674. + struct net_device *dev,
  38675. + LED_CTL_MODE LedAction
  38676. +)
  38677. +{
  38678. + struct r8180_priv *priv = ieee80211_priv(dev);
  38679. + PLED_8187 pLed = &(priv->Gpio0Led);
  38680. +
  38681. +// printk("=====+++++++++++++++++++====>%s In\n", __FUNCTION__);
  38682. + // Decide led state
  38683. + switch(LedAction)
  38684. + {
  38685. + case LED_CTL_TX:
  38686. + case LED_CTL_RX:
  38687. + if( pLed->bLedBlinkInProgress == 0 )
  38688. + {
  38689. + pLed->bLedBlinkInProgress = 1;
  38690. +
  38691. + pLed->CurrLedState = LED_BLINK_CM3;
  38692. + pLed->BlinkTimes = 2;
  38693. +
  38694. + if( pLed->bLedOn )
  38695. + pLed->BlinkingLedState = LED_OFF;
  38696. + else
  38697. + pLed->BlinkingLedState = LED_ON;
  38698. +
  38699. + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
  38700. + //add_timer(&(pLed->BlinkTimer));
  38701. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
  38702. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
  38703. + }
  38704. + break;
  38705. +
  38706. + case LED_CTL_SITE_SURVEY:
  38707. + if( pLed->bLedBlinkInProgress == 0 )
  38708. + {
  38709. + pLed->bLedBlinkInProgress = 1;
  38710. +
  38711. + pLed->CurrLedState = LED_BLINK_CM3;
  38712. + pLed->BlinkTimes = 10;
  38713. +
  38714. + if( pLed->bLedOn )
  38715. + pLed->BlinkingLedState = LED_OFF;
  38716. + else
  38717. + pLed->BlinkingLedState = LED_ON;
  38718. +
  38719. + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
  38720. + //add_timer(&(pLed->BlinkTimer));
  38721. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
  38722. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
  38723. + }
  38724. + break;
  38725. +
  38726. + case LED_CTL_LINK:
  38727. + pLed->CurrLedState = LED_ON;
  38728. + if( pLed->bLedBlinkInProgress == 0 )
  38729. + {
  38730. + SwLedOn(dev, pLed);
  38731. + }
  38732. + break;
  38733. +
  38734. + case LED_CTL_NO_LINK:
  38735. + pLed->CurrLedState = LED_OFF;
  38736. + if( pLed->bLedBlinkInProgress == 0 )
  38737. + {
  38738. + SwLedOff(dev, pLed);
  38739. + }
  38740. + break;
  38741. +
  38742. + case LED_CTL_POWER_ON:
  38743. + pLed->CurrLedState = LED_POWER_ON_BLINK;
  38744. + SwLedOn(dev, pLed);
  38745. + mdelay(100);
  38746. + SwLedOff(dev, pLed);
  38747. + break;
  38748. +
  38749. + case LED_CTL_POWER_OFF:
  38750. + pLed->CurrLedState = LED_OFF;
  38751. + if( pLed->bLedBlinkInProgress == 0 )
  38752. + {
  38753. + SwLedOff(dev, pLed);
  38754. + }
  38755. + break;
  38756. +
  38757. + default:
  38758. + break;
  38759. + }
  38760. +}
  38761. +
  38762. +// added by lizhaoming 2008.6.2
  38763. +//
  38764. +// Description:
  38765. +// Implement each led action for SW_LED_MODE4,
  38766. +// which is customized for QMI 8187B minicard.
  38767. +// 2008.04.21, by chiyokolin.
  38768. +//
  38769. +void
  38770. +SwLedControlMode4(
  38771. + struct net_device *dev,
  38772. + LED_CTL_MODE LedAction
  38773. + )
  38774. +{
  38775. + struct r8180_priv *priv = ieee80211_priv(dev);
  38776. + PLED_8187 pLed = &(priv->Gpio0Led);
  38777. +
  38778. + //printk("=====+++++++++++++++++++++====>%s In\n", __FUNCTION__);
  38779. + // Decide led state
  38780. + switch(LedAction)
  38781. + {
  38782. + case LED_CTL_TX:
  38783. + case LED_CTL_RX:
  38784. + //if( pLed->bLedBlinkInProgress == false && !priv->bScanInProgress)//?????
  38785. + if( pLed->bLedBlinkInProgress == 0)
  38786. + {
  38787. + pLed->bLedBlinkInProgress = 1;
  38788. +
  38789. + pLed->CurrLedState = LED_BLINK_NORMAL;
  38790. + pLed->BlinkTimes = 2;
  38791. +
  38792. + if( pLed->bLedOn )
  38793. + pLed->BlinkingLedState = LED_OFF;
  38794. + else
  38795. + pLed->BlinkingLedState = LED_ON;
  38796. +
  38797. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  38798. + //add_timer(&(pLed->BlinkTimer));
  38799. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  38800. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  38801. + }
  38802. + else
  38803. + //printk("----->LED_CTL_RX/TX bLedBlinkInProgress\n");
  38804. +
  38805. + break;
  38806. +
  38807. + case LED_CTL_SITE_SURVEY:
  38808. + if( pLed->bLedBlinkInProgress == 0 )
  38809. + {
  38810. +
  38811. + pLed->bLedBlinkInProgress = 1;
  38812. + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//////////??????
  38813. + //{
  38814. + pLed->CurrLedState = LED_SCAN_BLINK;
  38815. + pLed->BlinkTimes = 10;
  38816. +
  38817. + pLed->BlinkingLedState = LED_ON;
  38818. +
  38819. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  38820. + //add_timer(&(pLed->BlinkTimer));
  38821. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  38822. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  38823. + //}
  38824. + //else
  38825. + //{
  38826. + // pLed->CurrLedState = LED_NO_LINK_BLINK;
  38827. + // pLed->BlinkTimes = 24;
  38828. + //
  38829. + // if( pLed->bLedOn )
  38830. + // {
  38831. + // pLed->BlinkingLedState = LED_OFF;
  38832. + //
  38833. + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  38834. + // add_timer(&(pLed->BlinkTimer));
  38835. + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  38836. + // }
  38837. + // else
  38838. + // {
  38839. + // pLed->BlinkingLedState = LED_ON;
  38840. +
  38841. + // pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
  38842. + // add_timer(&(pLed->BlinkTimer));
  38843. + // //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
  38844. + // }
  38845. + //}
  38846. + }
  38847. + else
  38848. + {
  38849. + if(pLed->CurrLedState != LED_NO_LINK_BLINK)
  38850. + {
  38851. + //if( priv->MgntInfo.mAssoc || priv->MgntInfo.mIbss )//???????????
  38852. + //{
  38853. + //}
  38854. + //else
  38855. + //{
  38856. + // pLed->CurrLedState = LED_NO_LINK_BLINK;
  38857. + //}
  38858. + }
  38859. +
  38860. + //printk("----->LED_CTL_SITE_SURVEY bLedBlinkInProgress\n");
  38861. + }
  38862. + break;
  38863. +
  38864. + case LED_CTL_NO_LINK:
  38865. + if( pLed->bLedBlinkInProgress == 0 )
  38866. + {
  38867. + pLed->bLedBlinkInProgress = 1;
  38868. +
  38869. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  38870. + pLed->BlinkTimes = 24;
  38871. +
  38872. + if( pLed->bLedOn )
  38873. + {
  38874. + pLed->BlinkingLedState = LED_OFF;
  38875. +
  38876. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  38877. + //add_timer(&(pLed->BlinkTimer));
  38878. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
  38879. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  38880. + }
  38881. + else
  38882. + {
  38883. + pLed->BlinkingLedState = LED_ON;
  38884. +
  38885. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
  38886. + //add_timer(&(pLed->BlinkTimer));
  38887. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
  38888. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
  38889. + }
  38890. + }
  38891. + else
  38892. + {
  38893. + pLed->CurrLedState = LED_NO_LINK_BLINK;
  38894. + //printk("----->LED_CTL_NO_LINK bLedBlinkInProgress\n");
  38895. + }
  38896. + break;
  38897. +
  38898. + case LED_CTL_LINK:
  38899. + pLed->CurrLedState = LED_ON;
  38900. + if( pLed->bLedBlinkInProgress == 0)
  38901. + {
  38902. + SwLedOn(dev, pLed);
  38903. + }
  38904. + else
  38905. + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
  38906. +
  38907. + break;
  38908. +
  38909. + case LED_CTL_POWER_OFF:
  38910. + pLed->CurrLedState = LED_OFF;
  38911. + if(pLed->bLedBlinkInProgress)
  38912. + {
  38913. + printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
  38914. +
  38915. + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
  38916. + del_timer_sync(&(pLed->BlinkTimer));
  38917. + pLed->bLedBlinkInProgress = 0;
  38918. + }
  38919. + SwLedOff(dev, pLed);
  38920. + break;
  38921. +
  38922. + default:
  38923. + break;
  38924. + }
  38925. +}
  38926. +
  38927. +
  38928. +
  38929. +//added by lizhaoming 2008.6.3
  38930. +//
  38931. +// Description:
  38932. +// Implement each led action for SW_LED_MODE5,
  38933. +// which is customized for DELL 8187B minicard.
  38934. +// 2008.04.24, by chiyokolin.
  38935. +//
  38936. +void
  38937. +SwLedControlMode5(
  38938. + struct net_device *dev,
  38939. + LED_CTL_MODE LedAction
  38940. + )
  38941. +{
  38942. + struct r8180_priv *priv = ieee80211_priv(dev);
  38943. + PLED_8187 pLed = &(priv->Gpio0Led);
  38944. +
  38945. + // Decide led state
  38946. + //printk("====++++++++++++++++++++++=====>%s In\n", __FUNCTION__);
  38947. + switch(LedAction)
  38948. + {
  38949. + case LED_CTL_TX:
  38950. + case LED_CTL_RX:
  38951. + case LED_CTL_SITE_SURVEY:
  38952. + case LED_CTL_POWER_ON:
  38953. + case LED_CTL_NO_LINK:
  38954. + case LED_CTL_LINK:
  38955. + pLed->CurrLedState = LED_ON;
  38956. + if( pLed->bLedBlinkInProgress == 0 )
  38957. + {
  38958. + pLed->bLedBlinkInProgress = 1;
  38959. + if(! pLed->bLedOn )
  38960. + pLed->BlinkingLedState = LED_ON;
  38961. + else
  38962. + break;
  38963. +
  38964. + //printk("====++++++++++++++++++++++=====>%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
  38965. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  38966. + //add_timer(&(pLed->BlinkTimer));
  38967. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  38968. + // SwLedOn(dev, pLed);
  38969. + }
  38970. + else
  38971. + ;//printk("----->LED_CTL_LINK bLedBlinkInProgress\n");
  38972. +
  38973. + break;
  38974. +
  38975. + case LED_CTL_POWER_OFF:
  38976. + pLed->CurrLedState = LED_OFF;
  38977. + // printk("<====++++++++++++++++++++++=====%s In LED:%d\n", __FUNCTION__, pLed->bLedOn);
  38978. + if(pLed->bLedBlinkInProgress)
  38979. + {
  38980. + // printk("----->LED_CTL_POWER_OFF bLedBlinkInProgress\n");
  38981. +
  38982. + //PlatformCancelTimer(Adapter, &(pLed->BlinkTimer));
  38983. + del_timer_sync(&(pLed->BlinkTimer));
  38984. + pLed->bLedBlinkInProgress = 0;
  38985. + }
  38986. + SwLedOff(dev, pLed);
  38987. + break;
  38988. +
  38989. + default:
  38990. + break;
  38991. + }
  38992. +}
  38993. +
  38994. +//
  38995. +// Callback fuction of the timer, Gpio0Led.BlinkTimer.
  38996. +//
  38997. +void
  38998. +Gpio0LedBlinkTimerCallback(
  38999. + unsigned long data
  39000. + )
  39001. +{
  39002. + struct net_device *dev = (struct net_device *)data;
  39003. + struct r8180_priv *priv = ieee80211_priv(dev);
  39004. +
  39005. +// printk("=========>%s In\n", __FUNCTION__);
  39006. + PlatformSwLedBlink(dev, &(priv->Gpio0Led));
  39007. +}
  39008. +
  39009. +
  39010. +
  39011. +//
  39012. +// Callback fuction of the timer, SwLed0.BlinkTimer.
  39013. +//
  39014. +void
  39015. +SwLed0BlinkTimerCallback(
  39016. + unsigned long data
  39017. + )
  39018. +{
  39019. + struct net_device *dev = (struct net_device *)data;
  39020. + struct r8180_priv *priv = ieee80211_priv(dev);
  39021. +
  39022. +// printk("=========>%s In\n", __FUNCTION__);
  39023. + PlatformSwLedBlink(dev, &(priv->SwLed0));
  39024. +}
  39025. +
  39026. +
  39027. +
  39028. +//
  39029. +// Callback fuction of the timer, SwLed1.BlinkTimer.
  39030. +//
  39031. +void
  39032. +SwLed1BlinkTimerCallback(
  39033. + unsigned long data
  39034. + )
  39035. +{
  39036. + struct net_device *dev = (struct net_device *)data;
  39037. + struct r8180_priv *priv = ieee80211_priv(dev);
  39038. +
  39039. +// printk("=========>%s In\n", __FUNCTION__);
  39040. + PlatformSwLedBlink(dev, &(priv->SwLed1));
  39041. +}
  39042. +
  39043. +void
  39044. +PlatformSwLedBlink(
  39045. + struct net_device *dev,
  39046. + PLED_8187 pLed
  39047. + )
  39048. +{
  39049. + struct r8180_priv *priv = ieee80211_priv(dev);
  39050. +
  39051. +// printk("=========>%s In\n", __FUNCTION__);
  39052. + switch(pLed->LedPin)
  39053. + {
  39054. + case LED_PIN_GPIO0:
  39055. + schedule_work(&(priv->Gpio0LedWorkItem));
  39056. + break;
  39057. +
  39058. + case LED_PIN_LED0:
  39059. + schedule_work(&(priv->SwLed0WorkItem));
  39060. + break;
  39061. +
  39062. + case LED_PIN_LED1:
  39063. + schedule_work(&(priv->SwLed1WorkItem));
  39064. + break;
  39065. +
  39066. + default:
  39067. + break;
  39068. + }
  39069. +}
  39070. +
  39071. +//
  39072. +// Callback fucntion of the workitem for SW LEDs.
  39073. +// 2006.03.01, by rcnjko.
  39074. +//
  39075. +
  39076. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  39077. +void Gpio0LedWorkItemCallback(struct work_struct *work)
  39078. +{
  39079. + struct r8180_priv *priv = container_of(work, struct r8180_priv,Gpio0LedWorkItem);
  39080. + struct net_device *dev = priv->ieee80211->dev;
  39081. +#else
  39082. +void
  39083. +Gpio0LedWorkItemCallback(
  39084. + void * Context
  39085. + )
  39086. +{
  39087. + struct net_device *dev = (struct net_device *)Context;
  39088. + struct r8180_priv *priv = ieee80211_priv(dev);
  39089. +#endif
  39090. + PLED_8187 pLed = &(priv->Gpio0Led);
  39091. + if (priv == NULL || dev == NULL){
  39092. +// printk("=========>%s In\n", __FUNCTION__);
  39093. + //printk("ft=====================>%s()\n", __FUNCTION__);
  39094. + }
  39095. +
  39096. +#if 0 // by lizahoming 2008.6.3
  39097. + if(priv->LedStrategy == SW_LED_MODE2)
  39098. + SwLedCm2Blink(dev, pLed);
  39099. + else
  39100. + SwLedBlink(dev, pLed);
  39101. +#endif
  39102. +
  39103. +#if 1 // by lizahoming 2008.6.3
  39104. + switch(priv->LedStrategy)
  39105. + {
  39106. + case SW_LED_MODE2:
  39107. + SwLedCm2Blink(dev, pLed);
  39108. + break;
  39109. + case SW_LED_MODE4:
  39110. + SwLedCm4Blink(dev, pLed);
  39111. + break;
  39112. + default:
  39113. + SwLedBlink(dev, pLed);
  39114. + break;
  39115. + }
  39116. +#endif
  39117. +
  39118. + //LeaveCallbackOfRtWorkItem( &(usbdevice->Gpio0LedWorkItem) );
  39119. +}
  39120. +
  39121. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  39122. +void SwLed0WorkItemCallback(struct work_struct *work)
  39123. +{
  39124. + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed0WorkItem);
  39125. + //struct net_device *dev = priv->dev;
  39126. +#else
  39127. +void SwLed0WorkItemCallback(void * Context)
  39128. +{
  39129. + //struct net_device *dev = (struct net_device *)Context;
  39130. + //struct r8180_priv *priv = ieee80211_priv(dev);
  39131. +#endif
  39132. + //SwLedBlink(dev, &(priv->SwLed0));
  39133. +// printk("=========>%s In\n", __FUNCTION__);
  39134. +
  39135. + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed0WorkItem) );
  39136. +}
  39137. +
  39138. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  39139. +void SwLed1WorkItemCallback(struct work_struct *work)
  39140. +{
  39141. + //struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed1WorkItem);
  39142. +// struct net_device *dev = priv->dev;
  39143. +#else
  39144. +void
  39145. +SwLed1WorkItemCallback(
  39146. + void * Context
  39147. + )
  39148. +{
  39149. + //struct net_device *dev = (struct net_device *)Context;
  39150. + //struct r8180_priv *priv = ieee80211_priv(dev);
  39151. +#endif
  39152. +// printk("=========>%s In\n", __FUNCTION__);
  39153. + //SwLedBlink(dev, &(priv->SwLed1));
  39154. +
  39155. + //LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed1WorkItem) );
  39156. +}
  39157. +
  39158. +//
  39159. +// Implementation of LED blinking behavior.
  39160. +// It toggle off LED and schedule corresponding timer if necessary.
  39161. +//
  39162. +void
  39163. +SwLedBlink(
  39164. + struct net_device *dev,
  39165. + PLED_8187 pLed
  39166. + )
  39167. +{
  39168. + u8 bStopBlinking = 0;
  39169. +
  39170. + //printk("=========>%s In state:%d\n", __FUNCTION__, pLed->CurrLedState);
  39171. + // Change LED according to BlinkingLedState specified.
  39172. + if( pLed->BlinkingLedState == LED_ON )
  39173. + {
  39174. + SwLedOn(dev, pLed);
  39175. +// printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
  39176. + }
  39177. + else
  39178. + {
  39179. + SwLedOff(dev, pLed);
  39180. +// printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
  39181. + }
  39182. +
  39183. + // Determine if we shall change LED state again.
  39184. +//by lizhaoming for LED BLINK SLOWLY
  39185. + if(pLed->CurrLedState == LED_BLINK_SLOWLY)
  39186. + {
  39187. + bStopBlinking = 0;
  39188. + } else {
  39189. + pLed->BlinkTimes--;
  39190. + if( pLed->BlinkTimes == 0 )
  39191. + {
  39192. + bStopBlinking = 1;
  39193. + }
  39194. + else
  39195. + {
  39196. + if( pLed->CurrLedState != LED_BLINK_NORMAL &&
  39197. + pLed->CurrLedState != LED_BLINK_SLOWLY &&
  39198. + pLed->CurrLedState != LED_BLINK_CM3 )
  39199. + {
  39200. + bStopBlinking = 1;
  39201. + }
  39202. + }
  39203. + }
  39204. +
  39205. + if(bStopBlinking)
  39206. + {
  39207. + if( pLed->CurrLedState == LED_ON && pLed->bLedOn == 0)
  39208. + {
  39209. + SwLedOn(dev, pLed);
  39210. + }
  39211. + else if(pLed->CurrLedState == LED_OFF && pLed->bLedOn == 1)
  39212. + {
  39213. + SwLedOff(dev, pLed);
  39214. + }
  39215. +
  39216. + pLed->BlinkTimes = 0;
  39217. + pLed->bLedBlinkInProgress = 0;
  39218. + }
  39219. + else
  39220. + {
  39221. + // Assign LED state to toggle.
  39222. + if( pLed->BlinkingLedState == LED_ON )
  39223. + pLed->BlinkingLedState = LED_OFF;
  39224. + else
  39225. + pLed->BlinkingLedState = LED_ON;
  39226. +
  39227. + // Schedule a timer to toggle LED state.
  39228. + switch( pLed->CurrLedState )
  39229. + {
  39230. + case LED_BLINK_NORMAL:
  39231. + //printk("LED_BLINK_NORMAL:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
  39232. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  39233. + //add_timer(&(pLed->BlinkTimer));
  39234. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  39235. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  39236. + break;
  39237. +
  39238. + case LED_BLINK_SLOWLY:
  39239. + if( pLed->bLedOn == 1 )
  39240. + {
  39241. + //printk("LED_BLINK_SLOWLY:turn off\n");
  39242. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL+50;//for pcie mini card spec page 33, 250ms
  39243. + //add_timer(&(pLed->BlinkTimer));
  39244. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL+50));
  39245. + pLed->BlinkingLedState = LED_OFF;
  39246. + } else {
  39247. + //printk("LED_BLINK_SLOWLY:turn on\n");
  39248. + //pLed->BlinkTimer.expires = jiffies + 5000;//for pcie mini card spec page 33, 5s
  39249. + //add_timer(&(pLed->BlinkTimer));
  39250. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(5000));
  39251. + pLed->BlinkingLedState = LED_ON;
  39252. + }
  39253. + break;
  39254. +
  39255. + case LED_BLINK_CM3:
  39256. + //printk("LED_BLINK_CM3:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
  39257. + //pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
  39258. + //add_timer(&(pLed->BlinkTimer));
  39259. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM3_BLINK_INTERVAL));
  39260. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
  39261. + break;
  39262. +
  39263. + default:
  39264. + //printk("LED_BLINK_default:Blinktimes (%d): turn off\n", pLed->BlinkTimes+1);
  39265. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  39266. + //add_timer(&(pLed->BlinkTimer));
  39267. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  39268. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  39269. + break;
  39270. + }
  39271. + }
  39272. +}
  39273. +
  39274. +
  39275. +
  39276. +//
  39277. +// Implementation of LED blinking behavior for SwLedControlMode2.
  39278. +//
  39279. +void
  39280. +SwLedCm2Blink(
  39281. + struct net_device *dev,
  39282. + PLED_8187 pLed
  39283. + )
  39284. +{
  39285. + struct r8180_priv *priv = ieee80211_priv(dev);
  39286. + //PMGNT_INFO priv = &(dev->MgntInfo);
  39287. + u8 bStopBlinking = 0;
  39288. +
  39289. + //printk("========+++++++++++++=>%s In\n", __FUNCTION__);
  39290. + //To avoid LED blinking when rf is off, add by lizhaoming 2008.6.2
  39291. + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
  39292. + {
  39293. + SwLedOff(dev, pLed);
  39294. +
  39295. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  39296. + //add_timer(&(pLed->BlinkTimer));
  39297. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  39298. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  39299. + //printk(" Hw/Soft Radio Off, turn off Led\n");
  39300. + return;
  39301. + }
  39302. +
  39303. + // Change LED according to BlinkingLedState specified.
  39304. + if( pLed->BlinkingLedState == LED_ON )
  39305. + {
  39306. + SwLedOn(dev, pLed);
  39307. + //DMESG("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
  39308. + }
  39309. + else
  39310. + {
  39311. + SwLedOff(dev, pLed);
  39312. + //DMESG("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
  39313. + }
  39314. +
  39315. + //Add by lizhaoming for avoid BlinkTimers <0, 2008.6.2
  39316. + if(pLed->BlinkTimes > 0)
  39317. + {//by lizhaoming 2008.6.2
  39318. + // Determine if we shall change LED state again.
  39319. + pLed->BlinkTimes--;
  39320. + }//by lizhaoming 2008.6.2
  39321. +
  39322. + switch(pLed->CurrLedState)
  39323. + {
  39324. + case LED_BLINK_NORMAL:
  39325. + if(pLed->BlinkTimes == 0)
  39326. + {
  39327. + bStopBlinking = 1;
  39328. + }
  39329. + break;
  39330. +/* CM2 scan blink and no link blind now not be supported
  39331. + case LED_SCAN_BLINK:
  39332. + if( (priv->mAssoc || priv->mIbss) && // Linked.
  39333. + (!priv->bScanInProgress) && // Not in scan stage.
  39334. + (pLed->BlinkTimes % 2 == 0)) // Even
  39335. + {
  39336. + bStopBlinking = 1;
  39337. + }
  39338. + break;
  39339. +
  39340. + case LED_NO_LINK_BLINK:
  39341. + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
  39342. + //if( (priv->mAssoc || priv->mIbss) ) // Linked.
  39343. + if( priv->mAssoc)
  39344. + {
  39345. + bStopBlinking = 1;
  39346. + }
  39347. + else if(priv->mIbss && priv->bMediaConnect )
  39348. + {
  39349. + bStopBlinking = 1;
  39350. + }
  39351. + break;
  39352. +*/
  39353. + default:
  39354. + bStopBlinking = 1;
  39355. + break;
  39356. + }
  39357. +
  39358. + if(bStopBlinking)
  39359. + {
  39360. +/*
  39361. + if( priv->eRFPowerState != eRfOn )
  39362. + {
  39363. + SwLedOff(dev, pLed);
  39364. + }
  39365. + else if( priv->bMediaConnect == 1 && pLed->bLedOn == 0)
  39366. + {
  39367. + SwLedOn(dev, pLed);
  39368. + }
  39369. + else if( priv->bMediaConnect == 0 && pLed->bLedOn == 1)
  39370. + {
  39371. + SwLedOff(dev, pLed);
  39372. + }
  39373. +*/
  39374. + pLed->BlinkTimes = 0;
  39375. + pLed->bLedBlinkInProgress = 0;
  39376. + }
  39377. + else
  39378. + {
  39379. + // Assign LED state to toggle.
  39380. + if( pLed->BlinkingLedState == LED_ON )
  39381. + pLed->BlinkingLedState = LED_OFF;
  39382. + else
  39383. + pLed->BlinkingLedState = LED_ON;
  39384. +
  39385. + // Schedule a timer to toggle LED state.
  39386. + switch( pLed->CurrLedState )
  39387. + {
  39388. + case LED_BLINK_NORMAL:
  39389. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  39390. + //add_timer(&(pLed->BlinkTimer));
  39391. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  39392. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  39393. + break;
  39394. +
  39395. + case LED_BLINK_SLOWLY:
  39396. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  39397. + //add_timer(&(pLed->BlinkTimer));
  39398. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  39399. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  39400. + break;
  39401. +
  39402. + case LED_SCAN_BLINK:
  39403. + case LED_NO_LINK_BLINK:
  39404. + if( pLed->bLedOn ) {
  39405. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
  39406. + //add_timer(&(pLed->BlinkTimer));
  39407. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
  39408. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
  39409. + } else {
  39410. + //pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
  39411. + //add_timer(&(pLed->BlinkTimer));
  39412. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
  39413. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
  39414. + }
  39415. + break;
  39416. +
  39417. + default:
  39418. + //RT_ASSERT(0, ("SwLedCm2Blink(): unexpected state!\n"));
  39419. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  39420. + //add_timer(&(pLed->BlinkTimer));
  39421. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  39422. + //PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  39423. + break;
  39424. + }
  39425. + }
  39426. +}
  39427. +
  39428. +// added by lizhaoming 2008.6.2
  39429. +//
  39430. +// Description:
  39431. +// Implement LED blinking behavior for SW_LED_MODE4.
  39432. +//
  39433. +void
  39434. +SwLedCm4Blink(
  39435. + struct net_device *dev,
  39436. + PLED_8187 pLed
  39437. + )
  39438. +{
  39439. + struct r8180_priv *priv = ieee80211_priv(dev);
  39440. + u8 bStopBlinking = 0;
  39441. +
  39442. + printk("======++++++++++++++++++======>%s In\n", __FUNCTION__);
  39443. + //To avoid LED blinking when rf is off, add by Maddest 20080307
  39444. + if((priv->eRFPowerState == eRfOff) && (priv->RfOffReason>RF_CHANGE_BY_IPS))
  39445. + {
  39446. + SwLedOff(dev, pLed);
  39447. +
  39448. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  39449. + //add_timer(&(pLed->BlinkTimer));
  39450. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
  39451. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  39452. + printk(" Hw/Soft Radio Off, turn off Led\n");
  39453. + return;
  39454. + }
  39455. + // Change LED according to BlinkingLedState specified.
  39456. + if( pLed->BlinkingLedState == LED_ON )
  39457. + {
  39458. + if(!pLed->bLedOn)
  39459. + {
  39460. + SwLedOn(dev, pLed);
  39461. + }
  39462. + printk("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
  39463. + }
  39464. + else
  39465. + {
  39466. + SwLedOff(dev, pLed);
  39467. + printk("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
  39468. + }
  39469. +
  39470. + //Add by Maddest for avoid BlinkTimers <0, 20080307;
  39471. + if(pLed->BlinkTimes > 0)
  39472. + {
  39473. + // Determine if we shall change LED state again.
  39474. + pLed->BlinkTimes--;
  39475. + }
  39476. + printk("pLed->CurrLedState %d pLed->BlinkTimes %d\n", pLed->CurrLedState,pLed->BlinkTimes);
  39477. + switch(pLed->CurrLedState)
  39478. + {
  39479. + case LED_BLINK_NORMAL:
  39480. + if(pLed->BlinkTimes == 0)
  39481. + {
  39482. + bStopBlinking = 1;
  39483. + }
  39484. + break;
  39485. +
  39486. +/* CM2 scan blink and no link blind now not be supported
  39487. + case LED_SCAN_BLINK:
  39488. + if( (priv->mAssoc || priv->mIbss) && // Linked.//????????????
  39489. + (!priv->bScanInProgress) && // Not in scan stage.//????????????
  39490. + (pLed->BlinkTimes % 2 == 0)) // Even
  39491. + {
  39492. + bStopBlinking = 1;
  39493. + }
  39494. + break;
  39495. +
  39496. + case LED_NO_LINK_BLINK:
  39497. + //Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
  39498. + //if( (pMgntInfo->mAssoc || pMgntInfo->mIbss) ) // Linked.
  39499. + if( priv->mAssoc) //????????????
  39500. + {
  39501. + bStopBlinking = 1;
  39502. + }
  39503. + else if(priv->mIbss && priv->bMediaConnect )//????????????
  39504. + {
  39505. + bStopBlinking = 1;
  39506. + }
  39507. + break;
  39508. +*/
  39509. +
  39510. + default:
  39511. + bStopBlinking = 1;
  39512. + break;
  39513. + }
  39514. +
  39515. + if(bStopBlinking)
  39516. + {
  39517. + /*
  39518. + if( priv->eRFPowerState != eRfOn )
  39519. + {
  39520. + SwLedOff(dev, pLed);
  39521. + }
  39522. + else if( priv->bMediaConnect == true && pLed->bLedOn == false)//????????????
  39523. + {
  39524. + SwLedOn(dev, pLed);
  39525. + }
  39526. + else if( priv->bMediaConnect == false && pLed->bLedOn == true)//????????????
  39527. + {
  39528. + SwLedOff(dev, pLed);
  39529. + }
  39530. + */
  39531. +
  39532. + pLed->BlinkTimes = 0;
  39533. + pLed->bLedBlinkInProgress = 0;
  39534. + }
  39535. + else
  39536. + {
  39537. + // Assign LED state to toggle.
  39538. + if( pLed->BlinkingLedState == LED_ON )
  39539. + pLed->BlinkingLedState = LED_OFF;
  39540. + else
  39541. + pLed->BlinkingLedState = LED_ON;
  39542. +
  39543. + // Schedule a timer to toggle LED state.
  39544. + switch( pLed->CurrLedState )
  39545. + {
  39546. + case LED_BLINK_NORMAL:
  39547. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  39548. + //add_timer(&(pLed->BlinkTimer));
  39549. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  39550. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  39551. + break;
  39552. +
  39553. + case LED_BLINK_SLOWLY:
  39554. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  39555. + //add_timer(&(pLed->BlinkTimer));
  39556. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  39557. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  39558. + break;
  39559. +
  39560. + case LED_SCAN_BLINK:
  39561. + pLed->BlinkingLedState = LED_ON;
  39562. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
  39563. + //add_timer(&(pLed->BlinkTimer));
  39564. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
  39565. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
  39566. +
  39567. + case LED_NO_LINK_BLINK:
  39568. + if( pLed->bLedOn ){
  39569. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_ON_INTERVAL;
  39570. + //add_timer(&(pLed->BlinkTimer));
  39571. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_ON_INTERVAL));
  39572. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_ON_INTERVAL);
  39573. + }else{
  39574. + //pLed->BlinkTimer.expires = jiffies + LED_CM4_BLINK_OFF_INTERVAL;
  39575. + //add_timer(&(pLed->BlinkTimer));
  39576. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_CM4_BLINK_OFF_INTERVAL));
  39577. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_CM4_BLINK_OFF_INTERVAL);
  39578. + }
  39579. + break;
  39580. +
  39581. + default:
  39582. + printk("SwLedCm2Blink(): unexpected state!\n");
  39583. + //pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
  39584. + //add_timer(&(pLed->BlinkTimer));
  39585. + mod_timer(&pLed->BlinkTimer, jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
  39586. + //PlatformSetTimer(Adapter, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
  39587. + break;
  39588. + }
  39589. + }
  39590. +}
  39591. +
  39592. +void
  39593. +SwLedOn(
  39594. + struct net_device *dev,
  39595. + PLED_8187 pLed
  39596. +)
  39597. +{
  39598. + struct r8180_priv *priv = ieee80211_priv(dev);
  39599. +// printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
  39600. + switch(pLed->LedPin)
  39601. + {
  39602. + case LED_PIN_GPIO0:
  39603. + write_nic_byte(dev,0x0091,0x01);
  39604. + write_nic_byte(dev,0x0090,0x00); // write 0 : LED on
  39605. + break;
  39606. +
  39607. + case LED_PIN_LED0:
  39608. + priv->PsrValue &= ~(0x01 << 4);
  39609. + write_nic_byte(dev, PSR, priv->PsrValue);
  39610. + break;
  39611. +
  39612. + case LED_PIN_LED1:
  39613. + priv->PsrValue &= ~(0x01 << 5);
  39614. + write_nic_byte(dev, PSR, priv->PsrValue);
  39615. + break;
  39616. +
  39617. + default:
  39618. + break;
  39619. + }
  39620. +
  39621. + pLed->bLedOn = 1;
  39622. +}
  39623. +
  39624. +void
  39625. +SwLedOff(
  39626. + struct net_device *dev,
  39627. + PLED_8187 pLed
  39628. +)
  39629. +{
  39630. + struct r8180_priv *priv = ieee80211_priv(dev);
  39631. +
  39632. +
  39633. + //printk("=========>%s(), pin:%d\n", __FUNCTION__, pLed->LedPin);
  39634. + switch(pLed->LedPin)
  39635. + {
  39636. + case LED_PIN_GPIO0:
  39637. + write_nic_byte(dev,0x0091,0x01);
  39638. + write_nic_byte(dev,0x0090,0x01); // write 1 : LED off
  39639. + break;
  39640. +
  39641. + case LED_PIN_LED0:
  39642. + priv->PsrValue |= (0x01 << 4);
  39643. + write_nic_byte(dev, PSR, priv->PsrValue);
  39644. + break;
  39645. +
  39646. + case LED_PIN_LED1:
  39647. + priv->PsrValue |= (0x01 << 5);
  39648. + write_nic_byte(dev, PSR, priv->PsrValue);
  39649. + break;
  39650. +
  39651. + default:
  39652. + break;
  39653. + }
  39654. +
  39655. + pLed->bLedOn = 0;
  39656. +}
  39657. +
  39658. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_led.h linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.h
  39659. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_led.h 1970-01-01 01:00:00.000000000 +0100
  39660. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_led.h 2010-05-27 18:12:39.532222207 +0200
  39661. @@ -0,0 +1,276 @@
  39662. +/*++
  39663. +
  39664. +Copyright (c) Microsoft Corporation. All rights reserved.
  39665. +
  39666. +Module Name:
  39667. + r8187_led.h
  39668. +
  39669. +Abstract:
  39670. + definitions and stuctures for rtl8187 led control.
  39671. +
  39672. +Major Change History:
  39673. + When Who What
  39674. + ---------- ------ ----------------------------------------------
  39675. + 2006-09-07 Xiong Created
  39676. +
  39677. +Notes:
  39678. +
  39679. +--*/
  39680. +
  39681. +#ifndef R8187_LED_H
  39682. +#define R8187_LED_H
  39683. +
  39684. +#include <linux/types.h>
  39685. +#include <linux/timer.h>
  39686. +
  39687. +
  39688. +/*--------------------------Define -------------------------------------------*/
  39689. +//
  39690. +// 0x7E-0x7F is reserved for SW customization. 2006.04.21, by rcnjko.
  39691. +//
  39692. +// BIT[0-7] is for CustomerID where value 0x00 and 0xFF is reserved for Realtek.
  39693. +#define EEPROM_SW_REVD_OFFSET 0x7E
  39694. +
  39695. +#define EEPROM_CID_MASK 0x00FF
  39696. +#define EEPROM_CID_RSVD0 0x00
  39697. +#define EEPROM_CID_RSVD1 0xFF
  39698. +#define EEPROM_CID_ALPHA0 0x01
  39699. +#define EEPROM_CID_SERCOMM_PS 0x02
  39700. +#define EEPROM_CID_HW_LED 0x03
  39701. +
  39702. +#define EEPROM_CID_QMI 0x07 //Added by lizhaoming 2008.6.3
  39703. +#define EEPROM_CID_DELL 0x08 //Added by lizhaoming 2008.6.3
  39704. +
  39705. +#define LED_BLINK_NORMAL_INTERVAL 100 //by lizhaoming 50 -> 100
  39706. +#define LED_BLINK_SLOWLY_INTERVAL 200
  39707. +
  39708. +// Customized for AzWave, 2006.04.03, by rcnjko.
  39709. +#define LED_CM2_BLINK_ON_INTERVAL 250
  39710. +#define LED_CM2_BLINK_OFF_INTERVAL 4750
  39711. +//
  39712. +
  39713. +// Customized for Sercomm Printer Server case, 2006.04.21, by rcnjko.
  39714. +#define LED_CM3_BLINK_INTERVAL 1500
  39715. +
  39716. +// by lizhaoming 2008.6.3: Customized for QMI.
  39717. +//
  39718. +#define LED_CM4_BLINK_ON_INTERVAL 500
  39719. +#define LED_CM4_BLINK_OFF_INTERVAL 4500
  39720. +
  39721. +
  39722. +/*--------------------------Define MACRO--------------------------------------*/
  39723. +
  39724. +
  39725. +/*------------------------------Define Struct---------------------------------*/
  39726. +typedef enum _LED_STATE_8187{
  39727. + LED_UNKNOWN = 0,
  39728. + LED_ON = 1,
  39729. + LED_OFF = 2,
  39730. + LED_BLINK_NORMAL = 3,
  39731. + LED_BLINK_SLOWLY = 4,
  39732. + LED_POWER_ON_BLINK = 5,
  39733. + LED_SCAN_BLINK = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning.
  39734. + LED_NO_LINK_BLINK = 7, // LED is blinking during no link state.
  39735. + LED_BLINK_CM3 = 8, // Customzied for Sercomm Printer Server case
  39736. +}LED_STATE_8187;
  39737. +
  39738. +typedef enum _RT_CID_TYPE {
  39739. + RT_CID_DEFAULT,
  39740. + RT_CID_8187_ALPHA0,
  39741. + RT_CID_8187_SERCOMM_PS,
  39742. + RT_CID_8187_HW_LED,
  39743. +
  39744. + RT_CID_87B_QMI , //Added by lizhaoming 2008.6.3
  39745. + RT_CID_87B_DELL, //Added by lizhaoming 2008.6.3
  39746. +
  39747. +} RT_CID_TYPE;
  39748. +
  39749. +typedef enum _LED_STRATEGY_8187{
  39750. + SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option.
  39751. + SW_LED_MODE1, // 2 LEDs, through LED0 and LED1. For ALPHA.
  39752. + SW_LED_MODE2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard.
  39753. + SW_LED_MODE3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case.
  39754. + SW_LED_MODE4, //added by lizhaoming for bluetooth 2008.6.3
  39755. + SW_LED_MODE5, //added by lizhaoming for bluetooth 2008.6.3
  39756. + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.)
  39757. +}LED_STRATEGY_8187, *PLED_STRATEGY_8187;
  39758. +
  39759. +typedef enum _LED_PIN_8187{
  39760. + LED_PIN_GPIO0,
  39761. + LED_PIN_LED0,
  39762. + LED_PIN_LED1
  39763. +}LED_PIN_8187;
  39764. +
  39765. +//by lizhaoming for LED 2008.6.23 into ieee80211.h
  39766. +//typedef enum _LED_CTL_MODE {
  39767. +// LED_CTL_POWER_ON,
  39768. +// LED_CTL_POWER_OFF,
  39769. +// LED_CTL_LINK,
  39770. +// LED_CTL_NO_LINK,
  39771. +// LED_CTL_TX,
  39772. +// LED_CTL_RX,
  39773. +// LED_CTL_SITE_SURVEY,
  39774. +//} LED_CTL_MODE;
  39775. +
  39776. +typedef struct _LED_8187{
  39777. + LED_PIN_8187 LedPin; // Identify how to implement this SW led.
  39778. +
  39779. + LED_STATE_8187 CurrLedState; // Current LED state.
  39780. + u8 bLedOn; // TRUE if LED is ON, FALSE if LED is OFF.
  39781. +
  39782. + u8 bLedBlinkInProgress; // TRUE if it is blinking, FALSE o.w..
  39783. + u32 BlinkTimes; // Number of times to toggle led state for blinking.
  39784. + LED_STATE_8187 BlinkingLedState; // Next state for blinking, either LED_ON or LED_OFF are.
  39785. + struct timer_list BlinkTimer; // Timer object for led blinking.
  39786. +} LED_8187, *PLED_8187;
  39787. +
  39788. +
  39789. +
  39790. +/*------------------------Export global variable------------------------------*/
  39791. +
  39792. +
  39793. +/*------------------------------Funciton declaration--------------------------*/
  39794. +void
  39795. +InitSwLeds(
  39796. + struct net_device *dev
  39797. + );
  39798. +
  39799. +void
  39800. +DeInitSwLeds(
  39801. + struct net_device *dev
  39802. + );
  39803. +
  39804. +void
  39805. +InitLed8187(
  39806. + struct net_device *dev,
  39807. + PLED_8187 pLed,
  39808. + LED_PIN_8187 LedPin,
  39809. + void * BlinkCallBackFunc);
  39810. +
  39811. +void
  39812. +DeInitLed8187(
  39813. + struct net_device *dev,
  39814. + PLED_8187 pLed);
  39815. +
  39816. +void
  39817. +LedControl8187(
  39818. + struct net_device *dev,
  39819. + LED_CTL_MODE LedAction
  39820. +);
  39821. +
  39822. +void
  39823. +SwLedControlMode0(
  39824. + struct net_device *dev,
  39825. + LED_CTL_MODE LedAction
  39826. +);
  39827. +
  39828. +void
  39829. +SwLedControlMode1(
  39830. + struct net_device *dev,
  39831. + LED_CTL_MODE LedAction
  39832. +);
  39833. +
  39834. +void
  39835. +SwLedControlMode2(
  39836. + struct net_device *dev,
  39837. + LED_CTL_MODE LedAction
  39838. +);
  39839. +
  39840. +void
  39841. +SwLedControlMode3(
  39842. + struct net_device *dev,
  39843. + LED_CTL_MODE LedAction
  39844. +);
  39845. +
  39846. +
  39847. +void
  39848. +SwLedControlMode4(
  39849. + struct net_device *dev,
  39850. + LED_CTL_MODE LedAction
  39851. +);
  39852. +
  39853. +
  39854. +void
  39855. +SwLedControlMode5(
  39856. + struct net_device *dev,
  39857. + LED_CTL_MODE LedAction
  39858. +);
  39859. +
  39860. +void
  39861. +Gpio0LedBlinkTimerCallback(
  39862. + unsigned long data
  39863. + );
  39864. +
  39865. +void
  39866. +SwLed0BlinkTimerCallback(
  39867. + unsigned long data
  39868. + );
  39869. +
  39870. +void
  39871. +SwLed1BlinkTimerCallback(
  39872. + unsigned long data
  39873. + );
  39874. +
  39875. +void
  39876. +PlatformSwLedBlink(
  39877. + struct net_device *dev,
  39878. + PLED_8187 pLed
  39879. + );
  39880. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  39881. +void
  39882. +Gpio0LedWorkItemCallback(
  39883. + void * Context
  39884. + );
  39885. +
  39886. +void
  39887. +SwLed0WorkItemCallback(
  39888. + void * Context
  39889. + );
  39890. +
  39891. +void
  39892. +SwLed1WorkItemCallback(
  39893. + void * Context
  39894. + );
  39895. +#else
  39896. +void
  39897. +Gpio0LedWorkItemCallback(struct work_struct *work);
  39898. +
  39899. +void
  39900. +SwLed0WorkItemCallback(struct work_struct *work);
  39901. +
  39902. +void
  39903. +SwLed1WorkItemCallback(struct work_struct *work);
  39904. +
  39905. +#endif
  39906. +void
  39907. +SwLedBlink(
  39908. + struct net_device *dev,
  39909. + PLED_8187 pLed
  39910. + );
  39911. +
  39912. +void
  39913. +SwLedCm2Blink(
  39914. + struct net_device *dev,
  39915. + PLED_8187 pLed
  39916. + );
  39917. +
  39918. +void
  39919. +SwLedCm4Blink(
  39920. + struct net_device *dev,
  39921. + PLED_8187 pLed
  39922. + );
  39923. +
  39924. +void
  39925. +SwLedOn(
  39926. + struct net_device *dev,
  39927. + PLED_8187 pLed
  39928. +);
  39929. +
  39930. +void
  39931. +SwLedOff(
  39932. + struct net_device *dev,
  39933. + PLED_8187 pLed
  39934. +);
  39935. +
  39936. +
  39937. +#endif
  39938. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_rfkill.c linux-loongson/drivers/net/wireless/rtl8187b/r8187_rfkill.c
  39939. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/r8187_rfkill.c 1970-01-01 01:00:00.000000000 +0100
  39940. +++ linux-loongson/drivers/net/wireless/rtl8187b/r8187_rfkill.c 2010-05-27 18:12:39.532222207 +0200
  39941. @@ -0,0 +1,157 @@
  39942. +/*
  39943. + * rtl8187b specific rfkill support
  39944. + *
  39945. + * NOTE: we only concern about two states
  39946. + * eRfOff: RFKILL_STATE_SOFT_BLOCKED
  39947. + * eRfOn: RFKILL_STATE_UNBLOCKED
  39948. + * TODO: move led controlling source code to rfkill framework
  39949. + *
  39950. + * Copyright (C) 2009 Lemote Inc.
  39951. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  39952. + */
  39953. +
  39954. +#include <linux/module.h>
  39955. +#include <linux/rfkill.h>
  39956. +#include <linux/device.h>
  39957. +
  39958. +/* LED macros are defined in r8187.h and rfkill.h, we not use any of them here
  39959. + * just avoid compiling erros here.
  39960. + */
  39961. +#undef LED
  39962. +
  39963. +#include "r8187.h"
  39964. +#include "ieee80211/ieee80211.h"
  39965. +#include "linux/netdevice.h"
  39966. +
  39967. +static struct rfkill *r8187b_rfkill;
  39968. +static struct work_struct r8187b_rfkill_task;
  39969. +static int initialized;
  39970. +/* turn off by default */
  39971. +int r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
  39972. +struct net_device *r8187b_dev = NULL;
  39973. +RT_RF_POWER_STATE eRfPowerStateToSet;
  39974. +
  39975. +/* These two mutexes are used to ensure the relative rfkill status are accessed
  39976. + * by different tasks exclusively */
  39977. +DEFINE_MUTEX(statetoset_lock);
  39978. +DEFINE_MUTEX(state_lock);
  39979. +
  39980. +static void r8187b_wifi_rfkill_task(struct work_struct *work)
  39981. +{
  39982. + if (r8187b_dev) {
  39983. + mutex_lock(&statetoset_lock);
  39984. + r8187b_wifi_change_rfkill_state(r8187b_dev, eRfPowerStateToSet);
  39985. + mutex_unlock(&statetoset_lock);
  39986. + }
  39987. +}
  39988. +
  39989. +static int r8187b_wifi_update_rfkill_state(int status)
  39990. +{
  39991. + /* ensure r8187b_rfkill is initialized if dev is not initialized, means
  39992. + * wifi driver is not start, the status is eRfOff be default.
  39993. + */
  39994. + if (!r8187b_dev)
  39995. + return eRfOff;
  39996. +
  39997. + if (initialized == 0) {
  39998. + /* init the rfkill work task */
  39999. + INIT_WORK(&r8187b_rfkill_task, r8187b_wifi_rfkill_task);
  40000. + initialized = 1;
  40001. + }
  40002. +
  40003. + mutex_lock(&statetoset_lock);
  40004. + if (status == 1)
  40005. + eRfPowerStateToSet = eRfOn;
  40006. + else if (status == 0)
  40007. + eRfPowerStateToSet = eRfOff;
  40008. + else if (status == 2) {
  40009. + /* if the KEY_WLAN is pressed, just switch it! */
  40010. + mutex_lock(&state_lock);
  40011. + if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
  40012. + eRfPowerStateToSet = eRfOff;
  40013. + else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
  40014. + eRfPowerStateToSet = eRfOn;
  40015. + mutex_unlock(&state_lock);
  40016. + }
  40017. + mutex_unlock(&statetoset_lock);
  40018. +
  40019. + schedule_work(&r8187b_rfkill_task);
  40020. +
  40021. + return eRfPowerStateToSet;
  40022. +}
  40023. +
  40024. +static int r8187b_rfkill_set(void *data, bool blocked)
  40025. +{
  40026. + r8187b_wifi_update_rfkill_state(!blocked);
  40027. +
  40028. + return 0;
  40029. +}
  40030. +
  40031. +static void r8187b_rfkill_query(struct rfkill *rfkill, void *data)
  40032. +{
  40033. + static bool blocked;
  40034. +
  40035. + mutex_lock(&state_lock);
  40036. + if (r8187b_rfkill_state == RFKILL_USER_STATE_UNBLOCKED)
  40037. + blocked = 0;
  40038. + else if (r8187b_rfkill_state == RFKILL_USER_STATE_SOFT_BLOCKED)
  40039. + blocked = 1;
  40040. + mutex_unlock(&state_lock);
  40041. +
  40042. + rfkill_set_hw_state(rfkill, blocked);
  40043. +}
  40044. +
  40045. +int r8187b_wifi_report_state(r8180_priv *priv)
  40046. +{
  40047. + mutex_lock(&state_lock);
  40048. + r8187b_rfkill_state = RFKILL_USER_STATE_UNBLOCKED;
  40049. + if (priv->ieee80211->bHwRadioOff && priv->eRFPowerState == eRfOff)
  40050. + r8187b_rfkill_state = RFKILL_USER_STATE_SOFT_BLOCKED;
  40051. + mutex_unlock(&state_lock);
  40052. +
  40053. + r8187b_rfkill_query(r8187b_rfkill, NULL);
  40054. +
  40055. + return 0;
  40056. +}
  40057. +
  40058. +static const struct rfkill_ops r8187b_rfkill_ops = {
  40059. + .set_block = r8187b_rfkill_set,
  40060. + .query = r8187b_rfkill_query,
  40061. +};
  40062. +
  40063. +int r8187b_rfkill_init(struct net_device *dev)
  40064. +{
  40065. + int ret;
  40066. +
  40067. + /* init the r8187b device */
  40068. + r8187b_dev = dev;
  40069. +
  40070. + /* init the rfkill struct */
  40071. + r8187b_rfkill = rfkill_alloc("r8187b-wifi", &dev->dev,
  40072. + RFKILL_TYPE_WLAN, &r8187b_rfkill_ops,
  40073. + (void *)1);
  40074. +
  40075. + if (!r8187b_rfkill) {
  40076. + rfkill_destroy(r8187b_rfkill);
  40077. + printk(KERN_WARNING "r8187b: Unable to allocate rfkill\n");
  40078. + return -ENOMEM;
  40079. + }
  40080. + ret = rfkill_register(r8187b_rfkill);
  40081. + if (ret) {
  40082. + rfkill_destroy(r8187b_rfkill);
  40083. + return ret;
  40084. + }
  40085. +
  40086. + /* The default status is passed to the rfkill module */
  40087. +
  40088. + return 0;
  40089. +}
  40090. +
  40091. +void r8187b_rfkill_exit(void)
  40092. +{
  40093. + if (r8187b_rfkill) {
  40094. + rfkill_unregister(r8187b_rfkill);
  40095. + rfkill_destroy(r8187b_rfkill);
  40096. + }
  40097. + r8187b_rfkill = NULL;
  40098. +}
  40099. diff -Nur linux-2.6.34.orig/drivers/net/wireless/rtl8187b/readme linux-loongson/drivers/net/wireless/rtl8187b/readme
  40100. --- linux-2.6.34.orig/drivers/net/wireless/rtl8187b/readme 1970-01-01 01:00:00.000000000 +0100
  40101. +++ linux-loongson/drivers/net/wireless/rtl8187b/readme 2010-05-27 18:12:39.532222207 +0200
  40102. @@ -0,0 +1,124 @@
  40103. +rtl8187 Linux kernel driver
  40104. +Released under the terms of GNU General Public Licence (GPL)
  40105. +Copyright(c) Andrea Merello - 2004,2005
  40106. +
  40107. +Portions of this driver are based on other projects, please see the notes
  40108. +in the source files for detail.
  40109. +A special thanks go to Realtek corp for their support and to David Young
  40110. +------------------------------------------------------------------------------
  40111. +
  40112. +This is an attempt to write somethig that can make rtl8187 usb dongle wifi card
  40113. +on Linux using only opensource stuff.
  40114. +The rtl8225 radio is supported.
  40115. +
  40116. +It's in early development stage so don't expect too much from it
  40117. +(also use it at your own risk!)
  40118. +This should be considered just a fragment of code.. using it on your(any)
  40119. +system is at your own risk! Please note that I never supported the idea to
  40120. +use it in any way, so i cannot be considered responsible in any way for
  40121. +anything deriving by it usage.
  40122. +
  40123. +Anyway for now we have monitor mode and managed mode
  40124. +basically working! This isn't necessary stable, but seems to work..
  40125. +
  40126. +This driver is still under development and very far from perfect. It should work on x86,
  40127. +Other archs are untested..
  40128. +
  40129. +To compile the driver simply run make.
  40130. +
  40131. +The driver contains also the ieee80211.h and ieee80211_crypt.h from the ieee stack.
  40132. +Note that for some reasons this stack is NOT the same that will be included in newer
  40133. +2.6 kernel. I will try to port to this stack as soon as it will have enought features
  40134. +to support 8187 cards.
  40135. +Please note that you will have to make sure the two .h files are the same of the ieee
  40136. +stack.
  40137. +In other words when you download from the CVS this driver and the ieee80211 stack a good
  40138. +idea is to copy the ieee80211.h and ieee80211_crypt.h from the ieee directory to the drv
  40139. +directory
  40140. +
  40141. +Warning during compile are OK
  40142. +
  40143. +To wake up the nic run:
  40144. +
  40145. + ifconfig <ifacename> up
  40146. +
  40147. +(where <ifacename> is your network device for wlan card).
  40148. +
  40149. +Please note that the default interface name is wlanX.
  40150. +
  40151. +Please note thet this will take several seconds..
  40152. +
  40153. +If you would like to set the interface name to something else you may use the
  40154. +'devname=' module parameter. For example:
  40155. +
  40156. + insmod r8187.ko ifname=eth%d
  40157. +
  40158. +will set the interface name of this device to something like eth0.
  40159. +
  40160. +Once the nic is up it can be put in a monitor mode by running:
  40161. +
  40162. + iwconfig <ifacename> mode monitor
  40163. +
  40164. +and channel number may be changed by running:
  40165. +
  40166. + iwconfig <ifacename> channel XX
  40167. +
  40168. +
  40169. +In monitor mode a choice may be made via iwpriv if the nic should pass packets
  40170. +with bad crc or drop them.
  40171. +
  40172. +To put the nic in managed mode run:
  40173. +
  40174. + iwconfig <ifacename> mode managed
  40175. +
  40176. +In managed mode there is support for
  40177. +
  40178. + iwlist scan
  40179. +
  40180. +that should report the currently available networks.
  40181. +Please note that in managed mode channels cannot be changed manually.
  40182. +
  40183. +To associate with a network
  40184. +
  40185. + iwconfig <ifacename> essid XXXXX
  40186. +
  40187. +where XXXXX is the network essid (name) reported by 'iwlist scan'. Please
  40188. +note that essid is case sensitive.
  40189. +
  40190. +If your network is not broadcasting the ESSID, then you need to specify *also*
  40191. +the AP MAC address
  40192. +
  40193. + iwconfig <ifacename> ap XX:XX:XX:XX:XX:XX
  40194. +
  40195. +The driver accepts another boolean parameter: hwseqnum
  40196. +If set to 1 it lets the card HW take care of the sequence number of the TXed
  40197. +frames. Altought in managed mode I can't see an important reason to use HW to
  40198. +do that, when we'll start to TX beacons in master (AP) and ad-hoc modes most
  40199. +probably it will be extremely useful (since most probably we will use two HW
  40200. +queues).
  40201. +
  40202. +I'm unsure if it will work correctly on all NICs.. reports are *VERY, VERY* apreciated..
  40203. +
  40204. +
  40205. + WEP
  40206. + ===
  40207. +
  40208. +WEP encryption should work. For now it's done by host, not by the nic. Key can be set with:
  40209. +Key can be set with
  40210. +
  40211. + iwconfig <ifacename> key 12345...
  40212. +
  40213. +WEP is supported via software thanks to the ipw stack.
  40214. +
  40215. +Shared and open authentication are supported
  40216. +
  40217. + IWPRIV
  40218. + ======
  40219. +
  40220. +This driver supports some private handlers:
  40221. +-badcrc: let you choose to kill or to pass to the upper layer frames with bad crc in monitor mode
  40222. +-activescan: if 0 the driver will avoid to send probe requests, sanning will be only on beacon basis
  40223. +
  40224. +
  40225. +If you have some question/comments please feel free to write me.
  40226. +
  40227. diff -Nur linux-2.6.34.orig/drivers/platform/Kconfig linux-loongson/drivers/platform/Kconfig
  40228. --- linux-2.6.34.orig/drivers/platform/Kconfig 2010-05-16 23:17:36.000000000 +0200
  40229. +++ linux-loongson/drivers/platform/Kconfig 2010-05-27 18:12:39.983464277 +0200
  40230. @@ -1,3 +1,7 @@
  40231. if X86
  40232. source "drivers/platform/x86/Kconfig"
  40233. endif
  40234. +
  40235. +if MIPS
  40236. +source "drivers/platform/mips/Kconfig"
  40237. +endif
  40238. diff -Nur linux-2.6.34.orig/drivers/platform/Makefile linux-loongson/drivers/platform/Makefile
  40239. --- linux-2.6.34.orig/drivers/platform/Makefile 2010-05-16 23:17:36.000000000 +0200
  40240. +++ linux-loongson/drivers/platform/Makefile 2010-05-27 18:12:39.983464277 +0200
  40241. @@ -3,3 +3,4 @@
  40242. #
  40243. obj-$(CONFIG_X86) += x86/
  40244. +obj-$(CONFIG_MIPS) += mips/
  40245. diff -Nur linux-2.6.34.orig/drivers/platform/mips/Kconfig linux-loongson/drivers/platform/mips/Kconfig
  40246. --- linux-2.6.34.orig/drivers/platform/mips/Kconfig 1970-01-01 01:00:00.000000000 +0100
  40247. +++ linux-loongson/drivers/platform/mips/Kconfig 2010-05-27 18:12:39.983464277 +0200
  40248. @@ -0,0 +1,43 @@
  40249. +#
  40250. +# MIPS Platform Specific Drivers
  40251. +#
  40252. +
  40253. +menuconfig MIPS_PLATFORM_DEVICES
  40254. + bool "MIPS Platform Specific Device Drivers"
  40255. + default y
  40256. + help
  40257. + Say Y here to get to see options for device drivers of various
  40258. + MIPS platforms, including vendor-specific netbook/laptop/pc extension
  40259. + drivers. This option alone does not add any kernel code.
  40260. +
  40261. + If you say N, all options in this submenu will be skipped and disabled.
  40262. +
  40263. +if MIPS_PLATFORM_DEVICES
  40264. +
  40265. +config LEMOTE_YEELOONG2F
  40266. + tristate "Lemote YeeLoong Laptop"
  40267. + depends on LEMOTE_MACH2F
  40268. + select BACKLIGHT_CLASS_DEVICE
  40269. + select POWER_SUPPLY
  40270. + select HWMON
  40271. + select VIDEO_OUTPUT_CONTROL
  40272. + select INPUT_SPARSEKMAP
  40273. + depends on INPUT
  40274. + help
  40275. + YeeLoong netbook is a mini laptop made by Lemote, which is basically
  40276. + compatible to FuLoong2F mini PC, but it has an extra Embedded
  40277. + Controller(kb3310b) for battery, hotkey, backlight, temperature and
  40278. + fan management.
  40279. +
  40280. +config LEMOTE_LYNLOONG2F
  40281. + tristate "Lemote LynLoong PC"
  40282. + depends on LEMOTE_MACH2F
  40283. + select BACKLIGHT_CLASS_DEVICE
  40284. + select VIDEO_OUTPUT_CONTROL
  40285. + help
  40286. + LynLoong PC is an AllINONE machine made by Lemote, which is basically
  40287. + compatible to FuLoong2F Mini PC, the only difference is that it has a
  40288. + size-fixed screen: 1360x768 with sisfb video driver. and also, it has
  40289. + its own specific suspend support.
  40290. +
  40291. +endif # MIPS_PLATFORM_DEVICES
  40292. diff -Nur linux-2.6.34.orig/drivers/platform/mips/lynloong_pc.c linux-loongson/drivers/platform/mips/lynloong_pc.c
  40293. --- linux-2.6.34.orig/drivers/platform/mips/lynloong_pc.c 1970-01-01 01:00:00.000000000 +0100
  40294. +++ linux-loongson/drivers/platform/mips/lynloong_pc.c 2010-05-27 18:12:39.993464274 +0200
  40295. @@ -0,0 +1,513 @@
  40296. +/*
  40297. + * Driver for LynLoong PC extras
  40298. + *
  40299. + * Copyright (C) 2009 Lemote Inc.
  40300. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Xiang Yu <xiangy@lemote.com>
  40301. + *
  40302. + * This program is free software; you can redistribute it and/or modify
  40303. + * it under the terms of the GNU General Public License version 2 as
  40304. + * published by the Free Software Foundation.
  40305. + */
  40306. +
  40307. +#include <linux/err.h>
  40308. +#include <linux/platform_device.h>
  40309. +#include <linux/backlight.h> /* for backlight subdriver */
  40310. +#include <linux/fb.h>
  40311. +#include <linux/video_output.h> /* for video output subdriver */
  40312. +#include <linux/delay.h> /* for suspend support */
  40313. +
  40314. +#include <cs5536/cs5536.h>
  40315. +#include <cs5536/cs5536_mfgpt.h>
  40316. +
  40317. +#include <loongson.h>
  40318. +
  40319. +static u32 gpio_base, mfgpt_base;
  40320. +
  40321. +static void set_gpio_reg_high(int gpio, int reg)
  40322. +{
  40323. + u32 val;
  40324. +
  40325. + val = inl(gpio_base + reg);
  40326. + val |= (1 << gpio);
  40327. + val &= ~(1 << (16 + gpio));
  40328. + outl(val, gpio_base + reg);
  40329. + mmiowb();
  40330. +}
  40331. +
  40332. +static void set_gpio_reg_low(int gpio, int reg)
  40333. +{
  40334. + u32 val;
  40335. +
  40336. + val = inl(gpio_base + reg);
  40337. + val |= (1 << (16 + gpio));
  40338. + val &= ~(1 << gpio);
  40339. + outl(val, gpio_base + reg);
  40340. + mmiowb();
  40341. +}
  40342. +
  40343. +static void set_gpio_output_low(int gpio)
  40344. +{
  40345. + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
  40346. + set_gpio_reg_low(gpio, GPIOL_OUT_VAL);
  40347. +}
  40348. +
  40349. +static void set_gpio_output_high(int gpio)
  40350. +{
  40351. + set_gpio_reg_high(gpio, GPIOL_OUT_EN);
  40352. + set_gpio_reg_high(gpio, GPIOL_OUT_VAL);
  40353. +}
  40354. +
  40355. +/* backlight subdriver */
  40356. +
  40357. +#define MAX_BRIGHTNESS 100
  40358. +#define DEFAULT_BRIGHTNESS 50
  40359. +#define MIN_BRIGHTNESS 0
  40360. +static unsigned int level;
  40361. +
  40362. +DEFINE_SPINLOCK(backlight_lock);
  40363. +/* Tune the brightness */
  40364. +static void setup_mfgpt2(void)
  40365. +{
  40366. + unsigned long flags;
  40367. +
  40368. + spin_lock_irqsave(&backlight_lock, flags);
  40369. +
  40370. + /* Set MFGPT2 comparator 1,2 */
  40371. + outw(MAX_BRIGHTNESS-level, MFGPT2_CMP1);
  40372. + outw(MAX_BRIGHTNESS, MFGPT2_CMP2);
  40373. + /* Clear MFGPT2 UP COUNTER */
  40374. + outw(0, MFGPT2_CNT);
  40375. + /* Enable counter, compare mode, 32k */
  40376. + outw(0x8280, MFGPT2_SETUP);
  40377. +
  40378. + spin_unlock_irqrestore(&backlight_lock, flags);
  40379. +}
  40380. +
  40381. +static int lynloong_set_brightness(struct backlight_device *bd)
  40382. +{
  40383. + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
  40384. + bd->props.power == FB_BLANK_UNBLANK) ?
  40385. + bd->props.brightness : 0;
  40386. +
  40387. + if (level > MAX_BRIGHTNESS)
  40388. + level = MAX_BRIGHTNESS;
  40389. + else if (level < MIN_BRIGHTNESS)
  40390. + level = MIN_BRIGHTNESS;
  40391. +
  40392. + setup_mfgpt2();
  40393. +
  40394. + return 0;
  40395. +}
  40396. +
  40397. +static int lynloong_get_brightness(struct backlight_device *bd)
  40398. +{
  40399. + return level;
  40400. +}
  40401. +
  40402. +static struct backlight_ops backlight_ops = {
  40403. + .get_brightness = lynloong_get_brightness,
  40404. + .update_status = lynloong_set_brightness,
  40405. +};
  40406. +
  40407. +static struct backlight_device *lynloong_backlight_dev;
  40408. +
  40409. +static int lynloong_backlight_init(void)
  40410. +{
  40411. + int ret;
  40412. + u32 hi;
  40413. + struct backlight_properties props;
  40414. +
  40415. + /* Get gpio_base */
  40416. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
  40417. + /* Get mfgpt_base */
  40418. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base);
  40419. + /* Get gpio_base */
  40420. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);
  40421. +
  40422. + /* Select for mfgpt */
  40423. + set_gpio_reg_high(7, GPIOL_OUT_AUX1_SEL);
  40424. + /* Enable brightness controlling */
  40425. + set_gpio_output_high(7);
  40426. +
  40427. + memset(&props, 0, sizeof(struct backlight_properties));
  40428. + props.max_brightness = MAX_BRIGHTNESS;
  40429. + lynloong_backlight_dev = backlight_device_register("backlight0", NULL,
  40430. + NULL, &backlight_ops, &props);
  40431. +
  40432. + if (IS_ERR(lynloong_backlight_dev)) {
  40433. + ret = PTR_ERR(lynloong_backlight_dev);
  40434. + return ret;
  40435. + }
  40436. +
  40437. + lynloong_backlight_dev->props.brightness = DEFAULT_BRIGHTNESS;
  40438. + backlight_update_status(lynloong_backlight_dev);
  40439. +
  40440. + return 0;
  40441. +}
  40442. +
  40443. +static void lynloong_backlight_exit(void)
  40444. +{
  40445. + if (lynloong_backlight_dev) {
  40446. + backlight_device_unregister(lynloong_backlight_dev);
  40447. + lynloong_backlight_dev = NULL;
  40448. + }
  40449. + /* Disable brightness controlling */
  40450. + set_gpio_output_low(7);
  40451. +}
  40452. +
  40453. +/* video output driver */
  40454. +static int vo_status = 1;
  40455. +
  40456. +static int lcd_video_output_get(struct output_device *od)
  40457. +{
  40458. + return vo_status;
  40459. +}
  40460. +
  40461. +static int lcd_video_output_set(struct output_device *od)
  40462. +{
  40463. + int i;
  40464. + unsigned long status;
  40465. +
  40466. + status = !!od->request_state;
  40467. +
  40468. + if (status == 0) {
  40469. + /* Set the current status as off */
  40470. + vo_status = 0;
  40471. + /* Turn off the backlight */
  40472. + set_gpio_output_low(11);
  40473. + for (i = 0; i < 0x500; i++)
  40474. + delay();
  40475. + /* Turn off the LCD */
  40476. + set_gpio_output_high(8);
  40477. + } else {
  40478. + /* Turn on the LCD */
  40479. + set_gpio_output_low(8);
  40480. + for (i = 0; i < 0x500; i++)
  40481. + delay();
  40482. + /* Turn on the backlight */
  40483. + set_gpio_output_high(11);
  40484. + /* Set the current status as on */
  40485. + vo_status = 1;
  40486. + }
  40487. +
  40488. + return 0;
  40489. +}
  40490. +
  40491. +static struct output_properties lcd_output_properties = {
  40492. + .set_state = lcd_video_output_set,
  40493. + .get_status = lcd_video_output_get,
  40494. +};
  40495. +
  40496. +static struct output_device *lcd_output_dev;
  40497. +
  40498. +static void lynloong_lcd_vo_set(int status)
  40499. +{
  40500. + lcd_output_dev->request_state = status;
  40501. + lcd_video_output_set(lcd_output_dev);
  40502. +}
  40503. +
  40504. +static int lynloong_vo_init(void)
  40505. +{
  40506. + int ret;
  40507. +
  40508. + /* Register video output device: lcd */
  40509. + lcd_output_dev = video_output_register("LCD", NULL, NULL,
  40510. + &lcd_output_properties);
  40511. +
  40512. + if (IS_ERR(lcd_output_dev)) {
  40513. + ret = PTR_ERR(lcd_output_dev);
  40514. + lcd_output_dev = NULL;
  40515. + return ret;
  40516. + }
  40517. + /* Ensure LCD is on by default */
  40518. + lynloong_lcd_vo_set(1);
  40519. +
  40520. + return 0;
  40521. +}
  40522. +
  40523. +static void lynloong_vo_exit(void)
  40524. +{
  40525. + if (lcd_output_dev) {
  40526. + video_output_unregister(lcd_output_dev);
  40527. + lcd_output_dev = NULL;
  40528. + }
  40529. +}
  40530. +
  40531. +/* suspend support */
  40532. +
  40533. +#ifdef CONFIG_PM
  40534. +
  40535. +static u32 smb_base;
  40536. +
  40537. +/* I2C operations */
  40538. +
  40539. +static int i2c_wait(void)
  40540. +{
  40541. + char c;
  40542. + int i;
  40543. +
  40544. + udelay(1000);
  40545. + for (i = 0; i < 20; i++) {
  40546. + c = inb(smb_base | SMB_STS);
  40547. + if (c & (SMB_STS_BER | SMB_STS_NEGACK))
  40548. + return -1;
  40549. + if (c & SMB_STS_SDAST)
  40550. + return 0;
  40551. + udelay(100);
  40552. + }
  40553. + return -2;
  40554. +}
  40555. +
  40556. +static void i2c_read_single(int addr, int regNo, char *value)
  40557. +{
  40558. + unsigned char c;
  40559. +
  40560. + /* Start condition */
  40561. + c = inb(smb_base | SMB_CTRL1);
  40562. + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
  40563. + i2c_wait();
  40564. +
  40565. + /* Send slave address */
  40566. + outb(addr & 0xfe, smb_base | SMB_SDA);
  40567. + i2c_wait();
  40568. +
  40569. + /* Acknowledge smbus */
  40570. + c = inb(smb_base | SMB_CTRL1);
  40571. + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
  40572. +
  40573. + /* Send register index */
  40574. + outb(regNo, smb_base | SMB_SDA);
  40575. + i2c_wait();
  40576. +
  40577. + /* Acknowledge smbus */
  40578. + c = inb(smb_base | SMB_CTRL1);
  40579. + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
  40580. +
  40581. + /* Start condition again */
  40582. + c = inb(smb_base | SMB_CTRL1);
  40583. + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
  40584. + i2c_wait();
  40585. +
  40586. + /* Send salve address again */
  40587. + outb(1 | addr, smb_base | SMB_SDA);
  40588. + i2c_wait();
  40589. +
  40590. + /* Acknowledge smbus */
  40591. + c = inb(smb_base | SMB_CTRL1);
  40592. + outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);
  40593. +
  40594. + /* Read data */
  40595. + *value = inb(smb_base | SMB_SDA);
  40596. +
  40597. + /* Stop condition */
  40598. + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
  40599. + i2c_wait();
  40600. +}
  40601. +
  40602. +static void i2c_write_single(int addr, int regNo, char value)
  40603. +{
  40604. + unsigned char c;
  40605. +
  40606. + /* Start condition */
  40607. + c = inb(smb_base | SMB_CTRL1);
  40608. + outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);
  40609. + i2c_wait();
  40610. + /* Send slave address */
  40611. + outb(addr & 0xfe, smb_base | SMB_SDA);
  40612. + i2c_wait();;
  40613. +
  40614. + /* Send register index */
  40615. + outb(regNo, smb_base | SMB_SDA);
  40616. + i2c_wait();
  40617. +
  40618. + /* Write data */
  40619. + outb(value, smb_base | SMB_SDA);
  40620. + i2c_wait();
  40621. + /* Stop condition */
  40622. + outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);
  40623. + i2c_wait();
  40624. +}
  40625. +
  40626. +static void stop_clock(int clk_reg, int clk_sel)
  40627. +{
  40628. + u8 value;
  40629. +
  40630. + i2c_read_single(0xd3, clk_reg, &value);
  40631. + value &= ~(1 << clk_sel);
  40632. + i2c_write_single(0xd2, clk_reg, value);
  40633. +}
  40634. +
  40635. +static void enable_clock(int clk_reg, int clk_sel)
  40636. +{
  40637. + u8 value;
  40638. +
  40639. + i2c_read_single(0xd3, clk_reg, &value);
  40640. + value |= (1 << clk_sel);
  40641. + i2c_write_single(0xd2, clk_reg, value);
  40642. +}
  40643. +
  40644. +static char cached_clk_freq;
  40645. +static char cached_pci_fixed_freq;
  40646. +
  40647. +static void decrease_clk_freq(void)
  40648. +{
  40649. + char value;
  40650. +
  40651. + i2c_read_single(0xd3, 1, &value);
  40652. + cached_clk_freq = value;
  40653. +
  40654. + /* Select frequency by software */
  40655. + value |= (1 << 1);
  40656. + /* CPU, 3V66, PCI : 100, 66, 33(1) */
  40657. + value |= (1 << 2);
  40658. + i2c_write_single(0xd2, 1, value);
  40659. +
  40660. + /* Cache the pci frequency */
  40661. + i2c_read_single(0xd3, 14, &value);
  40662. + cached_pci_fixed_freq = value;
  40663. +
  40664. + /* Enable PCI fix mode */
  40665. + value |= (1 << 5);
  40666. + /* 3V66, PCI : 64MHz, 32MHz */
  40667. + value |= (1 << 3);
  40668. + i2c_write_single(0xd2, 14, value);
  40669. +
  40670. +}
  40671. +
  40672. +static void resume_clk_freq(void)
  40673. +{
  40674. + i2c_write_single(0xd2, 1, cached_clk_freq);
  40675. + i2c_write_single(0xd2, 14, cached_pci_fixed_freq);
  40676. +}
  40677. +
  40678. +static void stop_clocks(void)
  40679. +{
  40680. + /* CPU Clock Register */
  40681. + stop_clock(2, 5); /* not used */
  40682. + stop_clock(2, 6); /* not used */
  40683. + stop_clock(2, 7); /* not used */
  40684. +
  40685. + /* PCI Clock Register */
  40686. + stop_clock(3, 1); /* 8100 */
  40687. + stop_clock(3, 5); /* SIS */
  40688. + stop_clock(3, 0); /* not used */
  40689. + stop_clock(3, 6); /* not used */
  40690. +
  40691. + /* PCI 48M Clock Register */
  40692. + stop_clock(4, 6); /* USB grounding */
  40693. + stop_clock(4, 5); /* REF(5536_14M) */
  40694. +
  40695. + /* 3V66 Control Register */
  40696. + stop_clock(5, 0); /* VCH_CLK..., grounding */
  40697. +}
  40698. +
  40699. +static void enable_clocks(void)
  40700. +{
  40701. + enable_clock(3, 1); /* 8100 */
  40702. + enable_clock(3, 5); /* SIS */
  40703. +
  40704. + enable_clock(4, 6);
  40705. + enable_clock(4, 5); /* REF(5536_14M) */
  40706. +
  40707. + enable_clock(5, 0); /* VCH_CLOCK, grounding */
  40708. +}
  40709. +
  40710. +static int lynloong_suspend(struct device *dev)
  40711. +{
  40712. + /* Disable AMP */
  40713. + set_gpio_output_high(6);
  40714. + /* Turn off LCD */
  40715. + lynloong_lcd_vo_set(0);
  40716. +
  40717. + /* Stop the clocks of some devices */
  40718. + stop_clocks();
  40719. +
  40720. + /* Decrease the external clock frequency */
  40721. + decrease_clk_freq();
  40722. +
  40723. + return 0;
  40724. +}
  40725. +
  40726. +static int lynloong_resume(struct device *dev)
  40727. +{
  40728. + /* Turn on the LCD */
  40729. + lynloong_lcd_vo_set(1);
  40730. +
  40731. + /* Resume clock frequency, enable the relative clocks */
  40732. + resume_clk_freq();
  40733. + enable_clocks();
  40734. +
  40735. + /* Enable AMP */
  40736. + set_gpio_output_low(6);
  40737. +
  40738. + return 0;
  40739. +}
  40740. +
  40741. +static const SIMPLE_DEV_PM_OPS(lynloong_pm_ops, lynloong_suspend,
  40742. + lynloong_resume);
  40743. +#endif /* !CONFIG_PM */
  40744. +
  40745. +static struct platform_device_id platform_device_ids[] = {
  40746. + {
  40747. + .name = "lynloong_pc",
  40748. + },
  40749. + {}
  40750. +};
  40751. +
  40752. +MODULE_DEVICE_TABLE(platform, platform_device_ids);
  40753. +
  40754. +static struct platform_driver platform_driver = {
  40755. + .driver = {
  40756. + .name = "lynloong_pc",
  40757. + .owner = THIS_MODULE,
  40758. +#ifdef CONFIG_PM
  40759. + .pm = &lynloong_pm_ops,
  40760. +#endif
  40761. + },
  40762. + .id_table = platform_device_ids,
  40763. +};
  40764. +
  40765. +static int __init lynloong_init(void)
  40766. +{
  40767. + int ret;
  40768. +
  40769. + pr_info("Load LynLoong Platform Specific Driver.\n");
  40770. +
  40771. + /* Register platform stuff */
  40772. + ret = platform_driver_register(&platform_driver);
  40773. + if (ret) {
  40774. + pr_err("Fail to register lynloong platform driver.\n");
  40775. + return ret;
  40776. + }
  40777. +
  40778. + ret = lynloong_backlight_init();
  40779. + if (ret) {
  40780. + pr_err("Fail to register lynloong backlight driver.\n");
  40781. + return ret;
  40782. + }
  40783. +
  40784. + ret = lynloong_vo_init();
  40785. + if (ret) {
  40786. + pr_err("Fail to register lynloong backlight driver.\n");
  40787. + lynloong_vo_exit();
  40788. + return ret;
  40789. + }
  40790. +
  40791. + return 0;
  40792. +}
  40793. +
  40794. +static void __exit lynloong_exit(void)
  40795. +{
  40796. + lynloong_vo_exit();
  40797. + lynloong_backlight_exit();
  40798. + platform_driver_unregister(&platform_driver);
  40799. +
  40800. + pr_info("Unload LynLoong Platform Specific Driver.\n");
  40801. +}
  40802. +
  40803. +module_init(lynloong_init);
  40804. +module_exit(lynloong_exit);
  40805. +
  40806. +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Xiang Yu <xiangy@lemote.com>");
  40807. +MODULE_DESCRIPTION("LynLoong PC driver");
  40808. +MODULE_LICENSE("GPL");
  40809. diff -Nur linux-2.6.34.orig/drivers/platform/mips/Makefile linux-loongson/drivers/platform/mips/Makefile
  40810. --- linux-2.6.34.orig/drivers/platform/mips/Makefile 1970-01-01 01:00:00.000000000 +0100
  40811. +++ linux-loongson/drivers/platform/mips/Makefile 2010-05-27 18:12:39.993464274 +0200
  40812. @@ -0,0 +1,7 @@
  40813. +#
  40814. +# Makefile for MIPS Platform-Specific Drivers
  40815. +#
  40816. +
  40817. +obj-$(CONFIG_LEMOTE_YEELOONG2F) += yeeloong_laptop.o
  40818. +
  40819. +obj-$(CONFIG_LEMOTE_LYNLOONG2F) += lynloong_pc.o
  40820. diff -Nur linux-2.6.34.orig/drivers/platform/mips/yeeloong_ecrom.c linux-loongson/drivers/platform/mips/yeeloong_ecrom.c
  40821. --- linux-2.6.34.orig/drivers/platform/mips/yeeloong_ecrom.c 1970-01-01 01:00:00.000000000 +0100
  40822. +++ linux-loongson/drivers/platform/mips/yeeloong_ecrom.c 2010-05-27 18:12:39.993464274 +0200
  40823. @@ -0,0 +1,943 @@
  40824. +/*
  40825. + * Driver for flushing/dumping ROM of EC on YeeLoong laptop
  40826. + *
  40827. + * Copyright (C) 2009 Lemote Inc.
  40828. + * Author: liujl <liujl@lemote.com>
  40829. + *
  40830. + * NOTE :
  40831. + * The EC resources accessing and programming are supported.
  40832. + */
  40833. +
  40834. +#include <linux/proc_fs.h>
  40835. +#include <linux/miscdevice.h>
  40836. +#include <linux/init.h>
  40837. +#include <linux/delay.h>
  40838. +
  40839. +#include <ec_kb3310b.h>
  40840. +
  40841. +#define EC_MISC_DEV "ec_misc"
  40842. +#define EC_IOC_MAGIC 'E'
  40843. +
  40844. +/* ec registers range */
  40845. +#define EC_MAX_REGADDR 0xFFFF
  40846. +#define EC_MIN_REGADDR 0xF000
  40847. +#define EC_RAM_ADDR 0xF800
  40848. +
  40849. +/* version burned address */
  40850. +#define VER_ADDR 0xf7a1
  40851. +#define VER_MAX_SIZE 7
  40852. +#define EC_ROM_MAX_SIZE 0x10000
  40853. +
  40854. +/* ec internal register */
  40855. +#define REG_POWER_MODE 0xF710
  40856. +#define FLAG_NORMAL_MODE 0x00
  40857. +#define FLAG_IDLE_MODE 0x01
  40858. +#define FLAG_RESET_MODE 0x02
  40859. +
  40860. +/* ec update program flag */
  40861. +#define PROGRAM_FLAG_NONE 0x00
  40862. +#define PROGRAM_FLAG_IE 0x01
  40863. +#define PROGRAM_FLAG_ROM 0x02
  40864. +
  40865. +/* XBI relative registers */
  40866. +#define REG_XBISEG0 0xFEA0
  40867. +#define REG_XBISEG1 0xFEA1
  40868. +#define REG_XBIRSV2 0xFEA2
  40869. +#define REG_XBIRSV3 0xFEA3
  40870. +#define REG_XBIRSV4 0xFEA4
  40871. +#define REG_XBICFG 0xFEA5
  40872. +#define REG_XBICS 0xFEA6
  40873. +#define REG_XBIWE 0xFEA7
  40874. +#define REG_XBISPIA0 0xFEA8
  40875. +#define REG_XBISPIA1 0xFEA9
  40876. +#define REG_XBISPIA2 0xFEAA
  40877. +#define REG_XBISPIDAT 0xFEAB
  40878. +#define REG_XBISPICMD 0xFEAC
  40879. +#define REG_XBISPICFG 0xFEAD
  40880. +#define REG_XBISPIDATR 0xFEAE
  40881. +#define REG_XBISPICFG2 0xFEAF
  40882. +
  40883. +/* commands definition for REG_XBISPICMD */
  40884. +#define SPICMD_WRITE_STATUS 0x01
  40885. +#define SPICMD_BYTE_PROGRAM 0x02
  40886. +#define SPICMD_READ_BYTE 0x03
  40887. +#define SPICMD_WRITE_DISABLE 0x04
  40888. +#define SPICMD_READ_STATUS 0x05
  40889. +#define SPICMD_WRITE_ENABLE 0x06
  40890. +#define SPICMD_HIGH_SPEED_READ 0x0B
  40891. +#define SPICMD_POWER_DOWN 0xB9
  40892. +#define SPICMD_SST_EWSR 0x50
  40893. +#define SPICMD_SST_SEC_ERASE 0x20
  40894. +#define SPICMD_SST_BLK_ERASE 0x52
  40895. +#define SPICMD_SST_CHIP_ERASE 0x60
  40896. +#define SPICMD_FRDO 0x3B
  40897. +#define SPICMD_SEC_ERASE 0xD7
  40898. +#define SPICMD_BLK_ERASE 0xD8
  40899. +#define SPICMD_CHIP_ERASE 0xC7
  40900. +
  40901. +/* bits definition for REG_XBISPICFG */
  40902. +#define SPICFG_AUTO_CHECK 0x01
  40903. +#define SPICFG_SPI_BUSY 0x02
  40904. +#define SPICFG_DUMMY_READ 0x04
  40905. +#define SPICFG_EN_SPICMD 0x08
  40906. +#define SPICFG_LOW_SPICS 0x10
  40907. +#define SPICFG_EN_SHORT_READ 0x20
  40908. +#define SPICFG_EN_OFFSET_READ 0x40
  40909. +#define SPICFG_EN_FAST_READ 0x80
  40910. +
  40911. +/* watchdog timer registers */
  40912. +#define REG_WDTCFG 0xfe80
  40913. +#define REG_WDTPF 0xfe81
  40914. +#define REG_WDT 0xfe82
  40915. +
  40916. +/* lpc configure register */
  40917. +#define REG_LPCCFG 0xfe95
  40918. +
  40919. +/* 8051 reg */
  40920. +#define REG_PXCFG 0xff14
  40921. +
  40922. +/* Fan register in KB3310 */
  40923. +#define REG_ECFAN_SPEED_LEVEL 0xf4e4
  40924. +#define REG_ECFAN_SWITCH 0xf4d2
  40925. +
  40926. +/* the ec flash rom id number */
  40927. +#define EC_ROM_PRODUCT_ID_SPANSION 0x01
  40928. +#define EC_ROM_PRODUCT_ID_MXIC 0xC2
  40929. +#define EC_ROM_PRODUCT_ID_AMIC 0x37
  40930. +#define EC_ROM_PRODUCT_ID_EONIC 0x1C
  40931. +
  40932. +/* misc ioctl operations */
  40933. +#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int)
  40934. +#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int)
  40935. +#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int)
  40936. +#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int)
  40937. +#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int)
  40938. +
  40939. +/* start address for programming of EC content or IE */
  40940. +/* ec running code start address */
  40941. +#define EC_START_ADDR 0x00000000
  40942. +/* ec information element storing address */
  40943. +#define IE_START_ADDR 0x00020000
  40944. +
  40945. +/* EC state */
  40946. +#define EC_STATE_IDLE 0x00 /* ec in idle state */
  40947. +#define EC_STATE_BUSY 0x01 /* ec in busy state */
  40948. +
  40949. +/* timeout value for programming */
  40950. +#define EC_FLASH_TIMEOUT 0x1000 /* ec program timeout */
  40951. +/* command checkout timeout including cmd to port or state flag check */
  40952. +#define EC_CMD_TIMEOUT 0x1000
  40953. +#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) /* unit : us */
  40954. +#define EC_MAX_DELAY_UNIT (10) /* every time for polling */
  40955. +#define SPI_FINISH_WAIT_TIME 10
  40956. +/* EC content max size */
  40957. +#define EC_CONTENT_MAX_SIZE (64 * 1024)
  40958. +#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR)
  40959. +
  40960. +/* the register operation access struct */
  40961. +struct ec_reg {
  40962. + u32 addr; /* the address of kb3310 registers */
  40963. + u8 val; /* the register value */
  40964. +};
  40965. +
  40966. +struct ec_info {
  40967. + u32 start_addr;
  40968. + u32 size;
  40969. + u8 *buf;
  40970. +};
  40971. +
  40972. +/* open for using rom protection action */
  40973. +#define EC_ROM_PROTECTION
  40974. +
  40975. +/* enable the chip reset mode */
  40976. +static int ec_init_reset_mode(void)
  40977. +{
  40978. + int timeout;
  40979. + unsigned char status = 0;
  40980. + int ret = 0;
  40981. +
  40982. + /* make chip goto reset mode */
  40983. + ret = ec_query_seq(CMD_INIT_RESET_MODE);
  40984. + if (ret < 0) {
  40985. + printk(KERN_ERR "ec init reset mode failed.\n");
  40986. + goto out;
  40987. + }
  40988. +
  40989. + /* make the action take active */
  40990. + timeout = EC_CMD_TIMEOUT;
  40991. + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
  40992. + while (timeout--) {
  40993. + if (status) {
  40994. + udelay(EC_REG_DELAY);
  40995. + break;
  40996. + }
  40997. + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;
  40998. + udelay(EC_REG_DELAY);
  40999. + }
  41000. + if (timeout <= 0) {
  41001. + printk(KERN_ERR "ec rom fixup : can't check reset status.\n");
  41002. + ret = -EINVAL;
  41003. + } else
  41004. + printk(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout,
  41005. + EC_CMD_TIMEOUT - timeout, status);
  41006. +
  41007. + /* set MCU to reset mode */
  41008. + udelay(EC_REG_DELAY);
  41009. + status = ec_read(REG_PXCFG);
  41010. + status |= (1 << 0);
  41011. + ec_write(REG_PXCFG, status);
  41012. + udelay(EC_REG_DELAY);
  41013. +
  41014. + /* disable FWH/LPC */
  41015. + udelay(EC_REG_DELAY);
  41016. + status = ec_read(REG_LPCCFG);
  41017. + status &= ~(1 << 7);
  41018. + ec_write(REG_LPCCFG, status);
  41019. + udelay(EC_REG_DELAY);
  41020. +
  41021. + printk(KERN_INFO "entering reset mode ok..............\n");
  41022. +
  41023. + out:
  41024. + return ret;
  41025. +}
  41026. +
  41027. +/* make ec exit from reset mode */
  41028. +static void ec_exit_reset_mode(void)
  41029. +{
  41030. + unsigned char regval;
  41031. +
  41032. + udelay(EC_REG_DELAY);
  41033. + regval = ec_read(REG_LPCCFG);
  41034. + regval |= (1 << 7);
  41035. + ec_write(REG_LPCCFG, regval);
  41036. + regval = ec_read(REG_PXCFG);
  41037. + regval &= ~(1 << 0);
  41038. + ec_write(REG_PXCFG, regval);
  41039. + printk(KERN_INFO "exit reset mode ok..................\n");
  41040. +
  41041. + return;
  41042. +}
  41043. +
  41044. +/* make ec disable WDD */
  41045. +static void ec_disable_WDD(void)
  41046. +{
  41047. + unsigned char status;
  41048. +
  41049. + udelay(EC_REG_DELAY);
  41050. + status = ec_read(REG_WDTCFG);
  41051. + ec_write(REG_WDTPF, 0x03);
  41052. + ec_write(REG_WDTCFG, (status & 0x80) | 0x48);
  41053. + printk(KERN_INFO "Disable WDD ok..................\n");
  41054. +
  41055. + return;
  41056. +}
  41057. +
  41058. +/* make ec enable WDD */
  41059. +static void ec_enable_WDD(void)
  41060. +{
  41061. + unsigned char status;
  41062. +
  41063. + udelay(EC_REG_DELAY);
  41064. + status = ec_read(REG_WDTCFG);
  41065. + ec_write(REG_WDT, 0x28); /* set WDT 5sec(0x28) */
  41066. + ec_write(REG_WDTCFG, (status & 0x80) | 0x03);
  41067. + printk(KERN_INFO "Enable WDD ok..................\n");
  41068. +
  41069. + return;
  41070. +}
  41071. +
  41072. +/* make ec goto idle mode */
  41073. +static int ec_init_idle_mode(void)
  41074. +{
  41075. + int timeout;
  41076. + unsigned char status = 0;
  41077. + int ret = 0;
  41078. +
  41079. + ec_query_seq(CMD_INIT_IDLE_MODE);
  41080. +
  41081. + /* make the action take active */
  41082. + timeout = EC_CMD_TIMEOUT;
  41083. + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
  41084. + while (timeout--) {
  41085. + if (status) {
  41086. + udelay(EC_REG_DELAY);
  41087. + break;
  41088. + }
  41089. + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;
  41090. + udelay(EC_REG_DELAY);
  41091. + }
  41092. + if (timeout <= 0) {
  41093. + printk(KERN_ERR "ec rom fixup : can't check out the status.\n");
  41094. + ret = -EINVAL;
  41095. + } else
  41096. + printk(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout,
  41097. + EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE));
  41098. +
  41099. + printk(KERN_INFO "entering idle mode ok...................\n");
  41100. +
  41101. + return ret;
  41102. +}
  41103. +
  41104. +/* make ec exit from idle mode */
  41105. +static int ec_exit_idle_mode(void)
  41106. +{
  41107. +
  41108. + ec_query_seq(CMD_EXIT_IDLE_MODE);
  41109. +
  41110. + printk(KERN_INFO "exit idle mode ok...................\n");
  41111. +
  41112. + return 0;
  41113. +}
  41114. +
  41115. +static int ec_instruction_cycle(void)
  41116. +{
  41117. + unsigned long timeout;
  41118. + int ret = 0;
  41119. +
  41120. + timeout = EC_FLASH_TIMEOUT;
  41121. + while (timeout-- >= 0) {
  41122. + if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY))
  41123. + break;
  41124. + }
  41125. + if (timeout <= 0) {
  41126. + printk(KERN_ERR
  41127. + "EC_INSTRUCTION_CYCLE : timeout for check flag.\n");
  41128. + ret = -EINVAL;
  41129. + goto out;
  41130. + }
  41131. +
  41132. + out:
  41133. + return ret;
  41134. +}
  41135. +
  41136. +/* To see if the ec is in busy state or not. */
  41137. +static inline int ec_flash_busy(unsigned long timeout)
  41138. +{
  41139. + /* assurance the first command be going to rom */
  41140. + if (ec_instruction_cycle() < 0)
  41141. + return EC_STATE_BUSY;
  41142. +#if 1
  41143. + timeout = timeout / EC_MAX_DELAY_UNIT;
  41144. + while (timeout-- > 0) {
  41145. + /* check the rom's status of busy flag */
  41146. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  41147. + if (ec_instruction_cycle() < 0)
  41148. + return EC_STATE_BUSY;
  41149. + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
  41150. + return EC_STATE_IDLE;
  41151. + udelay(EC_MAX_DELAY_UNIT);
  41152. + }
  41153. + if (timeout <= 0) {
  41154. + printk(KERN_ERR
  41155. + "EC_FLASH_BUSY : timeout for check rom flag.\n");
  41156. + return EC_STATE_BUSY;
  41157. + }
  41158. +#else
  41159. + /* check the rom's status of busy flag */
  41160. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  41161. + if (ec_instruction_cycle() < 0)
  41162. + return EC_STATE_BUSY;
  41163. +
  41164. + timeout = timeout / EC_MAX_DELAY_UNIT;
  41165. + while (timeout-- > 0) {
  41166. + if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)
  41167. + return EC_STATE_IDLE;
  41168. + udelay(EC_MAX_DELAY_UNIT);
  41169. + }
  41170. + if (timeout <= 0) {
  41171. + printk(KERN_ERR
  41172. + "EC_FLASH_BUSY : timeout for check rom flag.\n");
  41173. + return EC_STATE_BUSY;
  41174. + }
  41175. +#endif
  41176. +
  41177. + return EC_STATE_IDLE;
  41178. +}
  41179. +
  41180. +static int rom_instruction_cycle(unsigned char cmd)
  41181. +{
  41182. + unsigned long timeout = 0;
  41183. +
  41184. + switch (cmd) {
  41185. + case SPICMD_READ_STATUS:
  41186. + case SPICMD_WRITE_ENABLE:
  41187. + case SPICMD_WRITE_DISABLE:
  41188. + case SPICMD_READ_BYTE:
  41189. + case SPICMD_HIGH_SPEED_READ:
  41190. + timeout = 0;
  41191. + break;
  41192. + case SPICMD_WRITE_STATUS:
  41193. + timeout = 300 * 1000;
  41194. + break;
  41195. + case SPICMD_BYTE_PROGRAM:
  41196. + timeout = 5 * 1000;
  41197. + break;
  41198. + case SPICMD_SST_SEC_ERASE:
  41199. + case SPICMD_SEC_ERASE:
  41200. + timeout = 1000 * 1000;
  41201. + break;
  41202. + case SPICMD_SST_BLK_ERASE:
  41203. + case SPICMD_BLK_ERASE:
  41204. + timeout = 3 * 1000 * 1000;
  41205. + break;
  41206. + case SPICMD_SST_CHIP_ERASE:
  41207. + case SPICMD_CHIP_ERASE:
  41208. + timeout = 20 * 1000 * 1000;
  41209. + break;
  41210. + default:
  41211. + timeout = EC_SPICMD_STANDARD_TIMEOUT;
  41212. + }
  41213. + if (timeout == 0)
  41214. + return ec_instruction_cycle();
  41215. + if (timeout < EC_SPICMD_STANDARD_TIMEOUT)
  41216. + timeout = EC_SPICMD_STANDARD_TIMEOUT;
  41217. +
  41218. + return ec_flash_busy(timeout);
  41219. +}
  41220. +
  41221. +/* delay for start/stop action */
  41222. +static void delay_spi(int n)
  41223. +{
  41224. + while (n--)
  41225. + inb(EC_IO_PORT_HIGH);
  41226. +}
  41227. +
  41228. +/* start the action to spi rom function */
  41229. +static void ec_start_spi(void)
  41230. +{
  41231. + unsigned char val;
  41232. +
  41233. + delay_spi(SPI_FINISH_WAIT_TIME);
  41234. + val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK;
  41235. + ec_write(REG_XBISPICFG, val);
  41236. + delay_spi(SPI_FINISH_WAIT_TIME);
  41237. +}
  41238. +
  41239. +/* stop the action to spi rom function */
  41240. +static void ec_stop_spi(void)
  41241. +{
  41242. + unsigned char val;
  41243. +
  41244. + delay_spi(SPI_FINISH_WAIT_TIME);
  41245. + val =
  41246. + ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK));
  41247. + ec_write(REG_XBISPICFG, val);
  41248. + delay_spi(SPI_FINISH_WAIT_TIME);
  41249. +}
  41250. +
  41251. +/* read one byte from xbi interface */
  41252. +static int ec_read_byte(unsigned int addr, unsigned char *byte)
  41253. +{
  41254. + int ret = 0;
  41255. +
  41256. + /* enable spicmd writing. */
  41257. + ec_start_spi();
  41258. +
  41259. + /* enable write spi flash */
  41260. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  41261. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  41262. + printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n");
  41263. + ret = -EINVAL;
  41264. + goto out;
  41265. + }
  41266. +
  41267. + /* write the address */
  41268. + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
  41269. + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
  41270. + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
  41271. + /* start action */
  41272. + ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ);
  41273. + if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) {
  41274. + printk(KERN_ERR
  41275. + "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n");
  41276. + ret = -EINVAL;
  41277. + goto out;
  41278. + }
  41279. +
  41280. + *byte = ec_read(REG_XBISPIDAT);
  41281. +
  41282. + out:
  41283. + /* disable spicmd writing. */
  41284. + ec_stop_spi();
  41285. +
  41286. + return ret;
  41287. +}
  41288. +
  41289. +/* write one byte to ec rom */
  41290. +static int ec_write_byte(unsigned int addr, unsigned char byte)
  41291. +{
  41292. + int ret = 0;
  41293. +
  41294. + /* enable spicmd writing. */
  41295. + ec_start_spi();
  41296. +
  41297. + /* enable write spi flash */
  41298. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  41299. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  41300. + printk(KERN_ERR
  41301. + "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n");
  41302. + ret = -EINVAL;
  41303. + goto out;
  41304. + }
  41305. +
  41306. + /* write the address */
  41307. + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);
  41308. + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);
  41309. + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);
  41310. + ec_write(REG_XBISPIDAT, byte);
  41311. + /* start action */
  41312. + ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM);
  41313. + if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) {
  41314. + printk(KERN_ERR
  41315. + "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n");
  41316. + ret = -EINVAL;
  41317. + goto out;
  41318. + }
  41319. +
  41320. + out:
  41321. + /* disable spicmd writing. */
  41322. + ec_stop_spi();
  41323. +
  41324. + return ret;
  41325. +}
  41326. +
  41327. +/* unprotect SPI ROM */
  41328. +/* EC_ROM_unprotect function code */
  41329. +static int EC_ROM_unprotect(void)
  41330. +{
  41331. + unsigned char status;
  41332. +
  41333. + /* enable write spi flash */
  41334. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  41335. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  41336. + printk(KERN_ERR
  41337. + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
  41338. + return 1;
  41339. + }
  41340. +
  41341. + /* unprotect the status register of rom */
  41342. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  41343. + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
  41344. + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n");
  41345. + return 1;
  41346. + }
  41347. + status = ec_read(REG_XBISPIDAT);
  41348. + ec_write(REG_XBISPIDAT, status & 0x02);
  41349. + if (ec_instruction_cycle() < 0) {
  41350. + printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n");
  41351. + return 1;
  41352. + }
  41353. +
  41354. + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
  41355. + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
  41356. + printk(KERN_ERR
  41357. + "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n");
  41358. + return 1;
  41359. + }
  41360. +
  41361. + /* enable write spi flash */
  41362. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  41363. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  41364. + printk(KERN_ERR
  41365. + "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");
  41366. + return 1;
  41367. + }
  41368. +
  41369. + return 0;
  41370. +}
  41371. +
  41372. +/* erase one block or chip or sector as needed */
  41373. +static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr)
  41374. +{
  41375. + unsigned char status;
  41376. + int ret = 0, i = 0;
  41377. + int unprotect_count = 3;
  41378. + int check_flag = 0;
  41379. +
  41380. + /* enable spicmd writing. */
  41381. + ec_start_spi();
  41382. +
  41383. +#ifdef EC_ROM_PROTECTION
  41384. + /* added for re-check SPICMD_READ_STATUS */
  41385. + while (unprotect_count-- > 0) {
  41386. + if (EC_ROM_unprotect()) {
  41387. + ret = -EINVAL;
  41388. + goto out;
  41389. + }
  41390. +
  41391. + /* first time:500ms --> 5.5sec -->10.5sec */
  41392. + for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++)
  41393. + udelay(50000);
  41394. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  41395. + if (rom_instruction_cycle(SPICMD_READ_STATUS)
  41396. + == EC_STATE_BUSY) {
  41397. + printk(KERN_ERR
  41398. + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
  41399. + } else {
  41400. + status = ec_read(REG_XBISPIDAT);
  41401. + printk(KERN_INFO "Read unprotect status : 0x%x\n",
  41402. + status);
  41403. + if ((status & 0x1C) == 0x00) {
  41404. + printk(KERN_INFO
  41405. + "Read unprotect status OK1 : 0x%x\n",
  41406. + status & 0x1C);
  41407. + check_flag = 1;
  41408. + break;
  41409. + }
  41410. + }
  41411. + }
  41412. +
  41413. + if (!check_flag) {
  41414. + printk(KERN_INFO "SPI ROM unprotect fail.\n");
  41415. + return 1;
  41416. + }
  41417. +#endif
  41418. +
  41419. + /* block address fill */
  41420. + if (erase_cmd == SPICMD_BLK_ERASE) {
  41421. + ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16);
  41422. + ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8);
  41423. + ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0);
  41424. + }
  41425. +
  41426. + /* erase the whole chip first */
  41427. + ec_write(REG_XBISPICMD, erase_cmd);
  41428. + if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) {
  41429. + printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n");
  41430. + ret = -EINVAL;
  41431. + goto out;
  41432. + }
  41433. +
  41434. + out:
  41435. + /* disable spicmd writing. */
  41436. + ec_stop_spi();
  41437. +
  41438. + return ret;
  41439. +}
  41440. +
  41441. +/* update the whole rom content with H/W mode
  41442. + * PLEASE USING ec_unit_erase() FIRSTLY
  41443. + */
  41444. +static int ec_program_rom(struct ec_info *info, int flag)
  41445. +{
  41446. + unsigned int addr = 0;
  41447. + unsigned long size = 0;
  41448. + unsigned char *ptr = NULL;
  41449. + unsigned char data;
  41450. + unsigned char val = 0;
  41451. + int ret = 0;
  41452. + int i, j;
  41453. + unsigned char status;
  41454. +
  41455. + /* modify for program serial No.
  41456. + * set IE_START_ADDR & use idle mode,
  41457. + * disable WDD
  41458. + */
  41459. + if (flag == PROGRAM_FLAG_ROM) {
  41460. + ret = ec_init_reset_mode();
  41461. + addr = info->start_addr + EC_START_ADDR;
  41462. + printk(KERN_INFO "PROGRAM_FLAG_ROM..............\n");
  41463. + } else if (flag == PROGRAM_FLAG_IE) {
  41464. + ret = ec_init_idle_mode();
  41465. + ec_disable_WDD();
  41466. + addr = info->start_addr + IE_START_ADDR;
  41467. + printk(KERN_INFO "PROGRAM_FLAG_IE..............\n");
  41468. + } else {
  41469. + return 0;
  41470. + }
  41471. +
  41472. + if (ret < 0) {
  41473. + if (flag == PROGRAM_FLAG_IE)
  41474. + ec_enable_WDD();
  41475. + return ret;
  41476. + }
  41477. +
  41478. + size = info->size;
  41479. + ptr = info->buf;
  41480. + printk(KERN_INFO "starting update ec ROM..............\n");
  41481. +
  41482. + ret = ec_unit_erase(SPICMD_BLK_ERASE, addr);
  41483. + if (ret) {
  41484. + printk(KERN_ERR "program ec : erase block failed.\n");
  41485. + goto out;
  41486. + }
  41487. + printk(KERN_ERR "program ec : erase block OK.\n");
  41488. +
  41489. + i = 0;
  41490. + while (i < size) {
  41491. + data = *(ptr + i);
  41492. + ec_write_byte(addr, data);
  41493. + ec_read_byte(addr, &val);
  41494. + if (val != data) {
  41495. + ec_write_byte(addr, data);
  41496. + ec_read_byte(addr, &val);
  41497. + if (val != data) {
  41498. + printk(KERN_INFO
  41499. + "EC : Second flash program failed at:\t");
  41500. + printk(KERN_INFO
  41501. + "addr : 0x%x, source : 0x%x, dest: 0x%x\n",
  41502. + addr, data, val);
  41503. + printk(KERN_INFO "This should not happen... STOP\n");
  41504. + break;
  41505. + }
  41506. + }
  41507. + i++;
  41508. + addr++;
  41509. + }
  41510. +
  41511. +#ifdef EC_ROM_PROTECTION
  41512. + /* we should start spi access firstly */
  41513. + ec_start_spi();
  41514. +
  41515. + /* enable write spi flash */
  41516. + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);
  41517. + if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {
  41518. + printk(KERN_ERR
  41519. + "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n");
  41520. + goto out1;
  41521. + }
  41522. +
  41523. + /* protect the status register of rom */
  41524. + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);
  41525. + if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {
  41526. + printk(KERN_ERR
  41527. + "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");
  41528. + goto out1;
  41529. + }
  41530. + status = ec_read(REG_XBISPIDAT);
  41531. +
  41532. + ec_write(REG_XBISPIDAT, status | 0x1C);
  41533. + if (ec_instruction_cycle() < 0) {
  41534. + printk(KERN_ERR
  41535. + "EC_PROGRAM_ROM : write status value failed.\n");
  41536. + goto out1;
  41537. + }
  41538. +
  41539. + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);
  41540. + if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {
  41541. + printk(KERN_ERR
  41542. + "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n");
  41543. + goto out1;
  41544. + }
  41545. +#endif
  41546. +
  41547. + /* disable the write action to spi rom */
  41548. + ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE);
  41549. + if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) {
  41550. + printk(KERN_ERR
  41551. + "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n");
  41552. + goto out1;
  41553. + }
  41554. +
  41555. + out1:
  41556. + /* we should stop spi access firstly */
  41557. + ec_stop_spi();
  41558. + out:
  41559. + /* for security */
  41560. + for (j = 0; j < 2000; j++)
  41561. + udelay(1000);
  41562. +
  41563. + /* modify for program serial No.
  41564. + * after program No exit idle mode
  41565. + * and enable WDD
  41566. + */
  41567. + if (flag == PROGRAM_FLAG_ROM) {
  41568. + /* exit from the reset mode */
  41569. + ec_exit_reset_mode();
  41570. + } else {
  41571. + /* ec exit from idle mode */
  41572. + ret = ec_exit_idle_mode();
  41573. + ec_enable_WDD();
  41574. + if (ret < 0)
  41575. + return ret;
  41576. + }
  41577. +
  41578. + return 0;
  41579. +}
  41580. +
  41581. +/* ioctl */
  41582. +static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd,
  41583. + u_long arg)
  41584. +{
  41585. + struct ec_info ecinfo;
  41586. + void __user *ptr = (void __user *)arg;
  41587. + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
  41588. + int ret = 0;
  41589. +
  41590. + switch (cmd) {
  41591. + case IOCTL_RDREG:
  41592. + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
  41593. + if (ret) {
  41594. + printk(KERN_ERR "reg read : copy from user error.\n");
  41595. + return -EFAULT;
  41596. + }
  41597. + if ((ecreg->addr > EC_MAX_REGADDR)
  41598. + || (ecreg->addr < EC_MIN_REGADDR)) {
  41599. + printk(KERN_ERR
  41600. + "reg read : out of register address range.\n");
  41601. + return -EINVAL;
  41602. + }
  41603. + ecreg->val = ec_read(ecreg->addr);
  41604. + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
  41605. + if (ret) {
  41606. + printk(KERN_ERR "reg read : copy to user error.\n");
  41607. + return -EFAULT;
  41608. + }
  41609. + break;
  41610. + case IOCTL_WRREG:
  41611. + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
  41612. + if (ret) {
  41613. + printk(KERN_ERR "reg write : copy from user error.\n");
  41614. + return -EFAULT;
  41615. + }
  41616. + if ((ecreg->addr > EC_MAX_REGADDR)
  41617. + || (ecreg->addr < EC_MIN_REGADDR)) {
  41618. + printk(KERN_ERR
  41619. + "reg write : out of register address range.\n");
  41620. + return -EINVAL;
  41621. + }
  41622. + ec_write(ecreg->addr, ecreg->val);
  41623. + break;
  41624. + case IOCTL_READ_EC:
  41625. + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));
  41626. + if (ret) {
  41627. + printk(KERN_ERR "spi read : copy from user error.\n");
  41628. + return -EFAULT;
  41629. + }
  41630. + if ((ecreg->addr > EC_RAM_ADDR)
  41631. + && (ecreg->addr < EC_MAX_REGADDR)) {
  41632. + printk(KERN_ERR
  41633. + "spi read : out of register address range.\n");
  41634. + return -EINVAL;
  41635. + }
  41636. + ec_read_byte(ecreg->addr, &(ecreg->val));
  41637. + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));
  41638. + if (ret) {
  41639. + printk(KERN_ERR "spi read : copy to user error.\n");
  41640. + return -EFAULT;
  41641. + }
  41642. + break;
  41643. + case IOCTL_PROGRAM_IE:
  41644. + ecinfo.start_addr = EC_START_ADDR;
  41645. + ecinfo.size = EC_CONTENT_MAX_SIZE;
  41646. + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
  41647. + if (ecinfo.buf == NULL) {
  41648. + printk(KERN_ERR "program ie : kmalloc failed.\n");
  41649. + return -ENOMEM;
  41650. + }
  41651. + ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size);
  41652. + if (ret) {
  41653. + printk(KERN_ERR "program ie : copy from user error.\n");
  41654. + kfree(ecinfo.buf);
  41655. + ecinfo.buf = NULL;
  41656. + return -EFAULT;
  41657. + }
  41658. +
  41659. + /* use ec_program_rom to write serial No */
  41660. + ec_program_rom(&ecinfo, PROGRAM_FLAG_IE);
  41661. +
  41662. + kfree(ecinfo.buf);
  41663. + ecinfo.buf = NULL;
  41664. + break;
  41665. + case IOCTL_PROGRAM_EC:
  41666. + ecinfo.start_addr = EC_START_ADDR;
  41667. + if (get_user((ecinfo.size), (u32 *) ptr)) {
  41668. + printk(KERN_ERR "program ec : get user error.\n");
  41669. + return -EFAULT;
  41670. + }
  41671. + if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) {
  41672. + printk(KERN_ERR "program ec : size out of limited.\n");
  41673. + return -EINVAL;
  41674. + }
  41675. + ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);
  41676. + if (ecinfo.buf == NULL) {
  41677. + printk(KERN_ERR "program ec : kmalloc failed.\n");
  41678. + return -ENOMEM;
  41679. + }
  41680. + ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size);
  41681. + if (ret) {
  41682. + printk(KERN_ERR "program ec : copy from user error.\n");
  41683. + kfree(ecinfo.buf);
  41684. + ecinfo.buf = NULL;
  41685. + return -EFAULT;
  41686. + }
  41687. +
  41688. + ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM);
  41689. +
  41690. + kfree(ecinfo.buf);
  41691. + ecinfo.buf = NULL;
  41692. + break;
  41693. +
  41694. + default:
  41695. + break;
  41696. + }
  41697. +
  41698. + return 0;
  41699. +}
  41700. +
  41701. +static long misc_compat_ioctl(struct file *file, unsigned int cmd,
  41702. + unsigned long arg)
  41703. +{
  41704. + return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
  41705. +}
  41706. +
  41707. +static int misc_open(struct inode *inode, struct file *filp)
  41708. +{
  41709. + struct ec_reg *ecreg = NULL;
  41710. + ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL);
  41711. + if (ecreg)
  41712. + filp->private_data = ecreg;
  41713. +
  41714. + return ecreg ? 0 : -ENOMEM;
  41715. +}
  41716. +
  41717. +static int misc_release(struct inode *inode, struct file *filp)
  41718. +{
  41719. + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);
  41720. +
  41721. + filp->private_data = NULL;
  41722. + kfree(ecreg);
  41723. +
  41724. + return 0;
  41725. +}
  41726. +
  41727. +static const struct file_operations ecmisc_fops = {
  41728. + .open = misc_open,
  41729. + .release = misc_release,
  41730. + .read = NULL,
  41731. + .write = NULL,
  41732. +#ifdef CONFIG_64BIT
  41733. + .compat_ioctl = misc_compat_ioctl,
  41734. +#else
  41735. + .ioctl = misc_ioctl,
  41736. +#endif
  41737. +};
  41738. +
  41739. +static struct miscdevice ecmisc_device = {
  41740. + .minor = MISC_DYNAMIC_MINOR,
  41741. + .name = EC_MISC_DEV,
  41742. + .fops = &ecmisc_fops
  41743. +};
  41744. +
  41745. +static int __init ecmisc_init(void)
  41746. +{
  41747. + int ret;
  41748. +
  41749. + printk(KERN_INFO "EC misc device init.\n");
  41750. + ret = misc_register(&ecmisc_device);
  41751. +
  41752. + return ret;
  41753. +}
  41754. +
  41755. +static void __exit ecmisc_exit(void)
  41756. +{
  41757. + printk(KERN_INFO "EC misc device exit.\n");
  41758. + misc_deregister(&ecmisc_device);
  41759. +}
  41760. +
  41761. +module_init(ecmisc_init);
  41762. +module_exit(ecmisc_exit);
  41763. +
  41764. +MODULE_AUTHOR("liujl <liujl@lemote.com>");
  41765. +MODULE_DESCRIPTION("Driver for flushing/dumping ROM of EC on YeeLoong laptop");
  41766. +MODULE_LICENSE("GPL");
  41767. diff -Nur linux-2.6.34.orig/drivers/platform/mips/yeeloong_laptop.c linux-loongson/drivers/platform/mips/yeeloong_laptop.c
  41768. --- linux-2.6.34.orig/drivers/platform/mips/yeeloong_laptop.c 1970-01-01 01:00:00.000000000 +0100
  41769. +++ linux-loongson/drivers/platform/mips/yeeloong_laptop.c 2010-05-27 18:12:39.993464274 +0200
  41770. @@ -0,0 +1,1200 @@
  41771. +/*
  41772. + * Driver for YeeLoong laptop extras
  41773. + *
  41774. + * Copyright (C) 2009 Lemote Inc.
  41775. + * Author: Wu Zhangjin <wuzhangjin@gmail.com>, Liu Junliang <liujl@lemote.com>
  41776. + *
  41777. + * This program is free software; you can redistribute it and/or modify
  41778. + * it under the terms of the GNU General Public License version 2 as
  41779. + * published by the Free Software Foundation.
  41780. + */
  41781. +
  41782. +#include <linux/err.h>
  41783. +#include <linux/platform_device.h>
  41784. +#include <linux/backlight.h> /* for backlight subdriver */
  41785. +#include <linux/fb.h>
  41786. +#include <linux/hwmon.h> /* for hwmon subdriver */
  41787. +#include <linux/hwmon-sysfs.h>
  41788. +#include <linux/video_output.h> /* for video output subdriver */
  41789. +#include <linux/input.h> /* for hotkey subdriver */
  41790. +#include <linux/input/sparse-keymap.h>
  41791. +#include <linux/interrupt.h>
  41792. +#include <linux/delay.h>
  41793. +#include <linux/power_supply.h> /* for AC & Battery subdriver */
  41794. +
  41795. +#include <cs5536/cs5536.h>
  41796. +
  41797. +#include <loongson.h> /* for loongson_cmdline */
  41798. +#include <ec_kb3310b.h>
  41799. +
  41800. +/* common function */
  41801. +#define EC_VER_LEN 64
  41802. +
  41803. +static int ec_version_before(char *version)
  41804. +{
  41805. + char *p, ec_ver[EC_VER_LEN];
  41806. +
  41807. + p = strstr(loongson_cmdline, "EC_VER=");
  41808. + if (!p)
  41809. + memset(ec_ver, 0, EC_VER_LEN);
  41810. + else {
  41811. + strncpy(ec_ver, p, EC_VER_LEN);
  41812. + p = strstr(ec_ver, " ");
  41813. + if (p)
  41814. + *p = '\0';
  41815. + }
  41816. +
  41817. + return (strncasecmp(ec_ver, version, 64) < 0);
  41818. +}
  41819. +
  41820. +/* backlight subdriver */
  41821. +#define MAX_BRIGHTNESS 8
  41822. +
  41823. +static int yeeloong_set_brightness(struct backlight_device *bd)
  41824. +{
  41825. + unsigned int level, current_level;
  41826. + static unsigned int old_level;
  41827. +
  41828. + level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&
  41829. + bd->props.power == FB_BLANK_UNBLANK) ?
  41830. + bd->props.brightness : 0;
  41831. +
  41832. + level = SENSORS_LIMIT(level, 0, MAX_BRIGHTNESS);
  41833. +
  41834. + /* Avoid to modify the brightness when EC is tuning it */
  41835. + if (old_level != level) {
  41836. + current_level = ec_read(REG_DISPLAY_BRIGHTNESS);
  41837. + if (old_level == current_level)
  41838. + ec_write(REG_DISPLAY_BRIGHTNESS, level);
  41839. + old_level = level;
  41840. + }
  41841. +
  41842. + return 0;
  41843. +}
  41844. +
  41845. +static int yeeloong_get_brightness(struct backlight_device *bd)
  41846. +{
  41847. + return ec_read(REG_DISPLAY_BRIGHTNESS);
  41848. +}
  41849. +
  41850. +static struct backlight_ops backlight_ops = {
  41851. + .get_brightness = yeeloong_get_brightness,
  41852. + .update_status = yeeloong_set_brightness,
  41853. +};
  41854. +
  41855. +static struct backlight_device *yeeloong_backlight_dev;
  41856. +
  41857. +static int yeeloong_backlight_init(void)
  41858. +{
  41859. + int ret;
  41860. + struct backlight_properties props;
  41861. +
  41862. + memset(&props, 0, sizeof(struct backlight_properties));
  41863. + props.max_brightness = MAX_BRIGHTNESS;
  41864. + yeeloong_backlight_dev = backlight_device_register("backlight0", NULL,
  41865. + NULL, &backlight_ops, &props);
  41866. +
  41867. + if (IS_ERR(yeeloong_backlight_dev)) {
  41868. + ret = PTR_ERR(yeeloong_backlight_dev);
  41869. + yeeloong_backlight_dev = NULL;
  41870. + return ret;
  41871. + }
  41872. +
  41873. + yeeloong_backlight_dev->props.brightness =
  41874. + yeeloong_get_brightness(yeeloong_backlight_dev);
  41875. + backlight_update_status(yeeloong_backlight_dev);
  41876. +
  41877. + return 0;
  41878. +}
  41879. +
  41880. +static void yeeloong_backlight_exit(void)
  41881. +{
  41882. + if (yeeloong_backlight_dev) {
  41883. + backlight_device_unregister(yeeloong_backlight_dev);
  41884. + yeeloong_backlight_dev = NULL;
  41885. + }
  41886. +}
  41887. +
  41888. +/* AC & Battery subdriver */
  41889. +
  41890. +static struct power_supply yeeloong_ac, yeeloong_bat;
  41891. +
  41892. +#define AC_OFFLINE 0
  41893. +#define AC_ONLINE 1
  41894. +
  41895. +static int yeeloong_get_ac_props(struct power_supply *psy,
  41896. + enum power_supply_property psp,
  41897. + union power_supply_propval *val)
  41898. +{
  41899. + switch (psp) {
  41900. + case POWER_SUPPLY_PROP_ONLINE:
  41901. + val->intval = ((ec_read(REG_BAT_POWER)) & BIT_BAT_POWER_ACIN) ?
  41902. + AC_ONLINE : AC_OFFLINE;
  41903. + break;
  41904. + default:
  41905. + return -EINVAL;
  41906. + }
  41907. +
  41908. + return 0;
  41909. +}
  41910. +
  41911. +static enum power_supply_property yeeloong_ac_props[] = {
  41912. + POWER_SUPPLY_PROP_ONLINE,
  41913. +};
  41914. +
  41915. +static struct power_supply yeeloong_ac = {
  41916. + .name = "yeeloong-ac",
  41917. + .type = POWER_SUPPLY_TYPE_MAINS,
  41918. + .properties = yeeloong_ac_props,
  41919. + .num_properties = ARRAY_SIZE(yeeloong_ac_props),
  41920. + .get_property = yeeloong_get_ac_props,
  41921. +};
  41922. +
  41923. +#define BAT_CAP_CRITICAL 5
  41924. +#define BAT_CAP_HIGH 99
  41925. +
  41926. +#define get_bat_info(type) \
  41927. + ((ec_read(REG_BAT_##type##_HIGH) << 8) | \
  41928. + (ec_read(REG_BAT_##type##_LOW)))
  41929. +
  41930. +static int yeeloong_bat_get_ex_property(enum power_supply_property psp,
  41931. + union power_supply_propval *val)
  41932. +{
  41933. + int bat_in, curr_cap, cap_level, status, charge, health;
  41934. +
  41935. + status = ec_read(REG_BAT_STATUS);
  41936. + bat_in = status & BIT_BAT_STATUS_IN;
  41937. + curr_cap = get_bat_info(RELATIVE_CAP);
  41938. + if (status & BIT_BAT_STATUS_FULL)
  41939. + curr_cap = 100;
  41940. +
  41941. + switch (psp) {
  41942. + case POWER_SUPPLY_PROP_PRESENT:
  41943. + val->intval = bat_in;
  41944. + break;
  41945. + case POWER_SUPPLY_PROP_CAPACITY:
  41946. + val->intval = curr_cap;
  41947. + break;
  41948. + case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
  41949. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
  41950. + if (status & BIT_BAT_STATUS_LOW) {
  41951. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
  41952. + if (curr_cap <= BAT_CAP_CRITICAL)
  41953. + cap_level =
  41954. + POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
  41955. + } else if (status & BIT_BAT_STATUS_FULL) {
  41956. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
  41957. + if (curr_cap >= BAT_CAP_HIGH)
  41958. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
  41959. + } else if (status & BIT_BAT_STATUS_DESTROY)
  41960. + cap_level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
  41961. + val->intval = cap_level;
  41962. + break;
  41963. + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
  41964. + /* seconds */
  41965. + val->intval = bat_in ? (curr_cap - 3) * 54 + 142 : 0;
  41966. + break;
  41967. + case POWER_SUPPLY_PROP_STATUS:
  41968. + if (!bat_in)
  41969. + charge = POWER_SUPPLY_STATUS_UNKNOWN;
  41970. + else {
  41971. + if (status & BIT_BAT_STATUS_FULL) {
  41972. + val->intval = POWER_SUPPLY_STATUS_FULL;
  41973. + break;
  41974. + }
  41975. +
  41976. + charge = ec_read(REG_BAT_CHARGE);
  41977. + if (charge & FLAG_BAT_CHARGE_DISCHARGE)
  41978. + charge = POWER_SUPPLY_STATUS_DISCHARGING;
  41979. + else if (charge & FLAG_BAT_CHARGE_CHARGE)
  41980. + charge = POWER_SUPPLY_STATUS_CHARGING;
  41981. + else
  41982. + charge = POWER_SUPPLY_STATUS_NOT_CHARGING;
  41983. + }
  41984. + val->intval = charge;
  41985. + break;
  41986. + case POWER_SUPPLY_PROP_HEALTH:
  41987. + if (!bat_in) /* no battery present */
  41988. + health = POWER_SUPPLY_HEALTH_UNKNOWN;
  41989. + else { /* Assume it is good */
  41990. + health = POWER_SUPPLY_HEALTH_GOOD;
  41991. + if (status &
  41992. + (BIT_BAT_STATUS_DESTROY | BIT_BAT_STATUS_LOW))
  41993. + health = POWER_SUPPLY_HEALTH_DEAD;
  41994. + if (ec_read(REG_BAT_CHARGE_STATUS) &
  41995. + BIT_BAT_CHARGE_STATUS_OVERTEMP)
  41996. + health = POWER_SUPPLY_HEALTH_OVERHEAT;
  41997. + }
  41998. + val->intval = health;
  41999. + break;
  42000. + case POWER_SUPPLY_PROP_CHARGE_NOW: /* 1/100(%)*1000 繕Ah */
  42001. + val->intval = curr_cap * get_bat_info(FULLCHG_CAP) * 10;
  42002. + break;
  42003. + default:
  42004. + return -EINVAL;
  42005. + }
  42006. + return 0;
  42007. +}
  42008. +
  42009. +static int get_battery_temp(void)
  42010. +{
  42011. + int value;
  42012. +
  42013. + value = get_bat_info(TEMPERATURE);
  42014. +
  42015. + return value * 1000;
  42016. +}
  42017. +
  42018. +static int get_battery_current(void)
  42019. +{
  42020. + s16 value;
  42021. +
  42022. + value = get_bat_info(CURRENT);
  42023. +
  42024. + return -value;
  42025. +}
  42026. +
  42027. +static int get_battery_voltage(void)
  42028. +{
  42029. + int value;
  42030. +
  42031. + value = get_bat_info(VOLTAGE);
  42032. +
  42033. + return value;
  42034. +}
  42035. +
  42036. +static int yeeloong_get_bat_props(struct power_supply *psy,
  42037. + enum power_supply_property psp,
  42038. + union power_supply_propval *val)
  42039. +{
  42040. + switch (psp) {
  42041. + /* Fixed information */
  42042. + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
  42043. + val->intval = get_bat_info(DESIGN_VOL) * 1000; /* mV -> 繕V */
  42044. + break;
  42045. + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
  42046. + val->intval = get_bat_info(DESIGN_CAP) * 1000; /* mAh->繕Ah */
  42047. + break;
  42048. + case POWER_SUPPLY_PROP_CHARGE_FULL:
  42049. + val->intval = get_bat_info(FULLCHG_CAP) * 1000; /* 繕Ah */
  42050. + break;
  42051. + case POWER_SUPPLY_PROP_MANUFACTURER:
  42052. + val->strval = (ec_read(REG_BAT_VENDOR) ==
  42053. + FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO";
  42054. + break;
  42055. + /* Dynamic information */
  42056. + case POWER_SUPPLY_PROP_CURRENT_NOW:
  42057. + val->intval = get_battery_current() * 1000; /* mA -> 繕A */
  42058. + break;
  42059. + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  42060. + val->intval = get_battery_voltage() * 1000; /* mV -> 繕V */
  42061. + break;
  42062. + case POWER_SUPPLY_PROP_TEMP:
  42063. + val->intval = get_battery_temp(); /* Celcius */
  42064. + break;
  42065. + /* Dynamic but related information */
  42066. + default:
  42067. + return yeeloong_bat_get_ex_property(psp, val);
  42068. + }
  42069. +
  42070. + return 0;
  42071. +}
  42072. +
  42073. +static enum power_supply_property yeeloong_bat_props[] = {
  42074. + POWER_SUPPLY_PROP_STATUS,
  42075. + POWER_SUPPLY_PROP_PRESENT,
  42076. + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
  42077. + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
  42078. + POWER_SUPPLY_PROP_CHARGE_FULL,
  42079. + POWER_SUPPLY_PROP_CHARGE_NOW,
  42080. + POWER_SUPPLY_PROP_CURRENT_NOW,
  42081. + POWER_SUPPLY_PROP_VOLTAGE_NOW,
  42082. + POWER_SUPPLY_PROP_HEALTH,
  42083. + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
  42084. + POWER_SUPPLY_PROP_CAPACITY,
  42085. + POWER_SUPPLY_PROP_CAPACITY_LEVEL,
  42086. + POWER_SUPPLY_PROP_TEMP,
  42087. + POWER_SUPPLY_PROP_MANUFACTURER,
  42088. +};
  42089. +
  42090. +static struct power_supply yeeloong_bat = {
  42091. + .name = "yeeloong-bat",
  42092. + .type = POWER_SUPPLY_TYPE_BATTERY,
  42093. + .properties = yeeloong_bat_props,
  42094. + .num_properties = ARRAY_SIZE(yeeloong_bat_props),
  42095. + .get_property = yeeloong_get_bat_props,
  42096. +};
  42097. +
  42098. +static int ac_bat_initialized;
  42099. +
  42100. +static int yeeloong_bat_init(void)
  42101. +{
  42102. + int ret;
  42103. +
  42104. + ret = power_supply_register(NULL, &yeeloong_ac);
  42105. + if (ret)
  42106. + return ret;
  42107. + ret = power_supply_register(NULL, &yeeloong_bat);
  42108. + if (ret) {
  42109. + power_supply_unregister(&yeeloong_ac);
  42110. + return ret;
  42111. + }
  42112. + ac_bat_initialized = 1;
  42113. +
  42114. + return 0;
  42115. +}
  42116. +
  42117. +static void yeeloong_bat_exit(void)
  42118. +{
  42119. + ac_bat_initialized = 0;
  42120. +
  42121. + power_supply_unregister(&yeeloong_ac);
  42122. + power_supply_unregister(&yeeloong_bat);
  42123. +}
  42124. +/* hwmon subdriver */
  42125. +
  42126. +#define MIN_FAN_SPEED 0
  42127. +#define MAX_FAN_SPEED 3
  42128. +
  42129. +static int get_fan_pwm_enable(void)
  42130. +{
  42131. + int level, mode;
  42132. +
  42133. + level = ec_read(REG_FAN_SPEED_LEVEL);
  42134. + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
  42135. +
  42136. + if (level == MAX_FAN_SPEED && mode == BIT_FAN_MANUAL)
  42137. + mode = 0;
  42138. + else if (mode == BIT_FAN_MANUAL)
  42139. + mode = 1;
  42140. + else
  42141. + mode = 2;
  42142. +
  42143. + return mode;
  42144. +}
  42145. +
  42146. +static void set_fan_pwm_enable(int mode)
  42147. +{
  42148. + switch (mode) {
  42149. + case 0:
  42150. + /* fullspeed */
  42151. + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
  42152. + ec_write(REG_FAN_SPEED_LEVEL, MAX_FAN_SPEED);
  42153. + break;
  42154. + case 1:
  42155. + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);
  42156. + break;
  42157. + case 2:
  42158. + ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_AUTO);
  42159. + break;
  42160. + default:
  42161. + break;
  42162. + }
  42163. +}
  42164. +
  42165. +static int get_fan_pwm(void)
  42166. +{
  42167. + return ec_read(REG_FAN_SPEED_LEVEL);
  42168. +}
  42169. +
  42170. +static void set_fan_pwm(int value)
  42171. +{
  42172. + int mode;
  42173. +
  42174. + mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);
  42175. + if (mode != BIT_FAN_MANUAL)
  42176. + return;
  42177. +
  42178. + value = SENSORS_LIMIT(value, 0, 3);
  42179. +
  42180. + /* We must ensure the fan is on */
  42181. + if (value > 0)
  42182. + ec_write(REG_FAN_CONTROL, BIT_FAN_CONTROL_ON);
  42183. +
  42184. + ec_write(REG_FAN_SPEED_LEVEL, value);
  42185. +}
  42186. +
  42187. +static int get_fan_rpm(void)
  42188. +{
  42189. + int value;
  42190. +
  42191. + value = FAN_SPEED_DIVIDER /
  42192. + (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) |
  42193. + ec_read(REG_FAN_SPEED_LOW));
  42194. +
  42195. + return value;
  42196. +}
  42197. +
  42198. +static int get_cpu_temp(void)
  42199. +{
  42200. + s8 value;
  42201. +
  42202. + value = ec_read(REG_TEMPERATURE_VALUE);
  42203. +
  42204. + return value * 1000;
  42205. +}
  42206. +
  42207. +static int get_cpu_temp_max(void)
  42208. +{
  42209. + return 60 * 1000;
  42210. +}
  42211. +
  42212. +static int get_battery_temp_alarm(void)
  42213. +{
  42214. + int status;
  42215. +
  42216. + status = (ec_read(REG_BAT_CHARGE_STATUS) &
  42217. + BIT_BAT_CHARGE_STATUS_OVERTEMP);
  42218. +
  42219. + return !!status;
  42220. +}
  42221. +
  42222. +static ssize_t store_sys_hwmon(void (*set) (int), const char *buf, size_t count)
  42223. +{
  42224. + int ret;
  42225. + unsigned long value;
  42226. +
  42227. + if (!count)
  42228. + return 0;
  42229. +
  42230. + ret = strict_strtoul(buf, 10, &value);
  42231. + if (ret)
  42232. + return ret;
  42233. +
  42234. + set(value);
  42235. +
  42236. + return count;
  42237. +}
  42238. +
  42239. +static ssize_t show_sys_hwmon(int (*get) (void), char *buf)
  42240. +{
  42241. + return sprintf(buf, "%d\n", get());
  42242. +}
  42243. +
  42244. +#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
  42245. + static ssize_t show_##_name(struct device *dev, \
  42246. + struct device_attribute *attr, \
  42247. + char *buf) \
  42248. + { \
  42249. + return show_sys_hwmon(_set, buf); \
  42250. + } \
  42251. + static ssize_t store_##_name(struct device *dev, \
  42252. + struct device_attribute *attr, \
  42253. + const char *buf, size_t count) \
  42254. + { \
  42255. + return store_sys_hwmon(_get, buf, count); \
  42256. + } \
  42257. + static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
  42258. +
  42259. +CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
  42260. +CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, get_fan_pwm, set_fan_pwm);
  42261. +CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, get_fan_pwm_enable,
  42262. + set_fan_pwm_enable);
  42263. +CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL);
  42264. +CREATE_SENSOR_ATTR(temp1_max, S_IRUGO, get_cpu_temp_max, NULL);
  42265. +CREATE_SENSOR_ATTR(temp2_input, S_IRUGO, get_battery_temp, NULL);
  42266. +CREATE_SENSOR_ATTR(temp2_max_alarm, S_IRUGO, get_battery_temp_alarm, NULL);
  42267. +CREATE_SENSOR_ATTR(curr1_input, S_IRUGO, get_battery_current, NULL);
  42268. +CREATE_SENSOR_ATTR(in1_input, S_IRUGO, get_battery_voltage, NULL);
  42269. +
  42270. +static ssize_t
  42271. +show_name(struct device *dev, struct device_attribute *attr, char *buf)
  42272. +{
  42273. + return sprintf(buf, "yeeloong\n");
  42274. +}
  42275. +
  42276. +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
  42277. +
  42278. +static struct attribute *hwmon_attributes[] = {
  42279. + &sensor_dev_attr_pwm1.dev_attr.attr,
  42280. + &sensor_dev_attr_pwm1_enable.dev_attr.attr,
  42281. + &sensor_dev_attr_fan1_input.dev_attr.attr,
  42282. + &sensor_dev_attr_temp1_input.dev_attr.attr,
  42283. + &sensor_dev_attr_temp1_max.dev_attr.attr,
  42284. + &sensor_dev_attr_temp2_input.dev_attr.attr,
  42285. + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
  42286. + &sensor_dev_attr_curr1_input.dev_attr.attr,
  42287. + &sensor_dev_attr_in1_input.dev_attr.attr,
  42288. + &sensor_dev_attr_name.dev_attr.attr,
  42289. + NULL
  42290. +};
  42291. +
  42292. +static struct attribute_group hwmon_attribute_group = {
  42293. + .attrs = hwmon_attributes
  42294. +};
  42295. +
  42296. +static struct device *yeeloong_hwmon_dev;
  42297. +
  42298. +static int yeeloong_hwmon_init(void)
  42299. +{
  42300. + int ret;
  42301. +
  42302. + yeeloong_hwmon_dev = hwmon_device_register(NULL);
  42303. + if (IS_ERR(yeeloong_hwmon_dev)) {
  42304. + pr_err("Fail to register yeeloong hwmon device\n");
  42305. + yeeloong_hwmon_dev = NULL;
  42306. + return PTR_ERR(yeeloong_hwmon_dev);
  42307. + }
  42308. + ret = sysfs_create_group(&yeeloong_hwmon_dev->kobj,
  42309. + &hwmon_attribute_group);
  42310. + if (ret) {
  42311. + hwmon_device_unregister(yeeloong_hwmon_dev);
  42312. + yeeloong_hwmon_dev = NULL;
  42313. + return ret;
  42314. + }
  42315. + /* ensure fan is set to auto mode */
  42316. + set_fan_pwm_enable(2);
  42317. +
  42318. + return 0;
  42319. +}
  42320. +
  42321. +static void yeeloong_hwmon_exit(void)
  42322. +{
  42323. + if (yeeloong_hwmon_dev) {
  42324. + sysfs_remove_group(&yeeloong_hwmon_dev->kobj,
  42325. + &hwmon_attribute_group);
  42326. + hwmon_device_unregister(yeeloong_hwmon_dev);
  42327. + yeeloong_hwmon_dev = NULL;
  42328. + }
  42329. +}
  42330. +
  42331. +/* video output subdriver */
  42332. +
  42333. +static int lcd_video_output_get(struct output_device *od)
  42334. +{
  42335. + return ec_read(REG_DISPLAY_LCD);
  42336. +}
  42337. +
  42338. +#define LCD 0
  42339. +#define CRT 1
  42340. +
  42341. +static void display_vo_set(int display, int on)
  42342. +{
  42343. + int addr;
  42344. + unsigned long value;
  42345. +
  42346. + addr = (display == LCD) ? 0x31 : 0x21;
  42347. +
  42348. + outb(addr, 0x3c4);
  42349. + value = inb(0x3c5);
  42350. +
  42351. + if (display == LCD)
  42352. + value |= (on ? 0x03 : 0x02);
  42353. + else {
  42354. + if (on)
  42355. + clear_bit(7, &value);
  42356. + else
  42357. + set_bit(7, &value);
  42358. + }
  42359. +
  42360. + outb(addr, 0x3c4);
  42361. + outb(value, 0x3c5);
  42362. +}
  42363. +
  42364. +static int lcd_video_output_set(struct output_device *od)
  42365. +{
  42366. + unsigned long status;
  42367. +
  42368. + status = !!od->request_state;
  42369. +
  42370. + display_vo_set(LCD, status);
  42371. + ec_write(REG_BACKLIGHT_CTRL, status);
  42372. +
  42373. + return 0;
  42374. +}
  42375. +
  42376. +static struct output_properties lcd_output_properties = {
  42377. + .set_state = lcd_video_output_set,
  42378. + .get_status = lcd_video_output_get,
  42379. +};
  42380. +
  42381. +static int crt_video_output_get(struct output_device *od)
  42382. +{
  42383. + return ec_read(REG_CRT_DETECT);
  42384. +}
  42385. +
  42386. +static int crt_video_output_set(struct output_device *od)
  42387. +{
  42388. + unsigned long status;
  42389. +
  42390. + status = !!od->request_state;
  42391. +
  42392. + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_PLUG)
  42393. + display_vo_set(CRT, status);
  42394. +
  42395. + return 0;
  42396. +}
  42397. +
  42398. +static struct output_properties crt_output_properties = {
  42399. + .set_state = crt_video_output_set,
  42400. + .get_status = crt_video_output_get,
  42401. +};
  42402. +
  42403. +static struct output_device *lcd_output_dev, *crt_output_dev;
  42404. +
  42405. +static void yeeloong_lcd_vo_set(int status)
  42406. +{
  42407. + lcd_output_dev->request_state = status;
  42408. + lcd_video_output_set(lcd_output_dev);
  42409. +}
  42410. +
  42411. +static void yeeloong_crt_vo_set(int status)
  42412. +{
  42413. + crt_output_dev->request_state = status;
  42414. + crt_video_output_set(crt_output_dev);
  42415. +}
  42416. +
  42417. +static int yeeloong_vo_init(void)
  42418. +{
  42419. + int ret;
  42420. +
  42421. + /* Register video output device: lcd, crt */
  42422. + lcd_output_dev = video_output_register("LCD", NULL, NULL,
  42423. + &lcd_output_properties);
  42424. +
  42425. + if (IS_ERR(lcd_output_dev)) {
  42426. + ret = PTR_ERR(lcd_output_dev);
  42427. + lcd_output_dev = NULL;
  42428. + return ret;
  42429. + }
  42430. + /* Ensure LCD is on by default */
  42431. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  42432. +
  42433. + crt_output_dev = video_output_register("CRT", NULL, NULL,
  42434. + &crt_output_properties);
  42435. +
  42436. + if (IS_ERR(crt_output_dev)) {
  42437. + ret = PTR_ERR(crt_output_dev);
  42438. + crt_output_dev = NULL;
  42439. + return ret;
  42440. + }
  42441. +
  42442. + /* Turn off CRT by default, and will be enabled when the CRT
  42443. + * connectting event reported by SCI */
  42444. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  42445. +
  42446. + return 0;
  42447. +}
  42448. +
  42449. +static void yeeloong_vo_exit(void)
  42450. +{
  42451. + if (lcd_output_dev) {
  42452. + video_output_unregister(lcd_output_dev);
  42453. + lcd_output_dev = NULL;
  42454. + }
  42455. + if (crt_output_dev) {
  42456. + video_output_unregister(crt_output_dev);
  42457. + crt_output_dev = NULL;
  42458. + }
  42459. +}
  42460. +
  42461. +/* hotkey subdriver */
  42462. +
  42463. +static struct input_dev *yeeloong_hotkey_dev;
  42464. +
  42465. +static const struct key_entry yeeloong_keymap[] = {
  42466. + {KE_SW, EVENT_LID, { SW_LID } },
  42467. + {KE_KEY, EVENT_CAMERA, { KEY_CAMERA } }, /* Fn + ESC */
  42468. + {KE_KEY, EVENT_SLEEP, { KEY_SLEEP } }, /* Fn + F1 */
  42469. + {KE_KEY, EVENT_DISPLAYTOGGLE, { KEY_DISPLAYTOGGLE } }, /* Fn + F2 */
  42470. + {KE_KEY, EVENT_SWITCHVIDEOMODE, { KEY_SWITCHVIDEOMODE } }, /* Fn + F3 */
  42471. + {KE_KEY, EVENT_AUDIO_MUTE, { KEY_MUTE } }, /* Fn + F4 */
  42472. + {KE_KEY, EVENT_WLAN, { KEY_WLAN } }, /* Fn + F5 */
  42473. + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSUP } }, /* Fn + up */
  42474. + {KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSDOWN } }, /* Fn + down */
  42475. + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEUP } }, /* Fn + right */
  42476. + {KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEDOWN } }, /* Fn + left */
  42477. + {KE_END, 0}
  42478. +};
  42479. +
  42480. +static struct key_entry *get_event_key_entry(int event, int status)
  42481. +{
  42482. + struct key_entry *ke;
  42483. + static int old_brightness_status = -1;
  42484. + static int old_volume_status = -1;
  42485. +
  42486. + ke = sparse_keymap_entry_from_scancode(yeeloong_hotkey_dev, event);
  42487. + if (!ke)
  42488. + return NULL;
  42489. +
  42490. + switch (event) {
  42491. + case EVENT_DISPLAY_BRIGHTNESS:
  42492. + /* current status > old one, means up */
  42493. + if ((status < old_brightness_status) || (0 == status))
  42494. + ke++;
  42495. + old_brightness_status = status;
  42496. + break;
  42497. + case EVENT_AUDIO_VOLUME:
  42498. + if ((status < old_volume_status) || (0 == status))
  42499. + ke++;
  42500. + old_volume_status = status;
  42501. + break;
  42502. + default:
  42503. + break;
  42504. + }
  42505. +
  42506. + return ke;
  42507. +}
  42508. +
  42509. +static int report_lid_switch(int status)
  42510. +{
  42511. + input_report_switch(yeeloong_hotkey_dev, SW_LID, !status);
  42512. + input_sync(yeeloong_hotkey_dev);
  42513. +
  42514. + return status;
  42515. +}
  42516. +
  42517. +static int crt_detect_handler(int status)
  42518. +{
  42519. + if (status) {
  42520. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  42521. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  42522. + } else {
  42523. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  42524. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  42525. + }
  42526. + return status;
  42527. +}
  42528. +
  42529. +static int displaytoggle_handler(int status)
  42530. +{
  42531. + /* EC(>=PQ1D26) does this job for us, we can not do it again,
  42532. + * otherwise, the brightness will not resume to the normal level! */
  42533. + if (ec_version_before("EC_VER=PQ1D26"))
  42534. + yeeloong_lcd_vo_set(status);
  42535. +
  42536. + return status;
  42537. +}
  42538. +
  42539. +static int switchvideomode_handler(int status)
  42540. +{
  42541. + static int video_output_status;
  42542. +
  42543. + /* Only enable switch video output button
  42544. + * when CRT is connected */
  42545. + if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_UNPLUG)
  42546. + return 0;
  42547. + /* 0. no CRT connected: LCD on, CRT off
  42548. + * 1. BOTH on
  42549. + * 2. LCD off, CRT on
  42550. + * 3. BOTH off
  42551. + * 4. LCD on, CRT off
  42552. + */
  42553. + video_output_status++;
  42554. + if (video_output_status > 4)
  42555. + video_output_status = 1;
  42556. +
  42557. + switch (video_output_status) {
  42558. + case 1:
  42559. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  42560. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  42561. + break;
  42562. + case 2:
  42563. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  42564. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  42565. + break;
  42566. + case 3:
  42567. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  42568. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  42569. + break;
  42570. + case 4:
  42571. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  42572. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  42573. + break;
  42574. + default:
  42575. + /* Ensure LCD is on */
  42576. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  42577. + break;
  42578. + }
  42579. + return video_output_status;
  42580. +}
  42581. +
  42582. +static int camera_handler(int status)
  42583. +{
  42584. + int value;
  42585. +
  42586. + value = ec_read(REG_CAMERA_CONTROL);
  42587. + ec_write(REG_CAMERA_CONTROL, value | (1 << 1));
  42588. +
  42589. + return status;
  42590. +}
  42591. +
  42592. +static int usb2_handler(int status)
  42593. +{
  42594. + pr_emerg("USB2 Over Current occurred\n");
  42595. +
  42596. + return status;
  42597. +}
  42598. +
  42599. +static int usb0_handler(int status)
  42600. +{
  42601. + pr_emerg("USB0 Over Current occurred\n");
  42602. +
  42603. + return status;
  42604. +}
  42605. +
  42606. +static int ac_bat_handler(int status)
  42607. +{
  42608. + if (ac_bat_initialized) {
  42609. + power_supply_changed(&yeeloong_ac);
  42610. + power_supply_changed(&yeeloong_bat);
  42611. + }
  42612. + return status;
  42613. +}
  42614. +
  42615. +static void do_event_action(int event)
  42616. +{
  42617. + sci_handler handler;
  42618. + int reg, status;
  42619. + struct key_entry *ke;
  42620. +
  42621. + reg = 0;
  42622. + handler = NULL;
  42623. +
  42624. + switch (event) {
  42625. + case EVENT_LID:
  42626. + reg = REG_LID_DETECT;
  42627. + break;
  42628. + case EVENT_SWITCHVIDEOMODE:
  42629. + handler = switchvideomode_handler;
  42630. + break;
  42631. + case EVENT_CRT_DETECT:
  42632. + reg = REG_CRT_DETECT;
  42633. + handler = crt_detect_handler;
  42634. + break;
  42635. + case EVENT_CAMERA:
  42636. + reg = REG_CAMERA_STATUS;
  42637. + handler = camera_handler;
  42638. + break;
  42639. + case EVENT_USB_OC2:
  42640. + reg = REG_USB2_FLAG;
  42641. + handler = usb2_handler;
  42642. + break;
  42643. + case EVENT_USB_OC0:
  42644. + reg = REG_USB0_FLAG;
  42645. + handler = usb0_handler;
  42646. + break;
  42647. + case EVENT_DISPLAYTOGGLE:
  42648. + reg = REG_DISPLAY_LCD;
  42649. + handler = displaytoggle_handler;
  42650. + break;
  42651. + case EVENT_AUDIO_MUTE:
  42652. + reg = REG_AUDIO_MUTE;
  42653. + break;
  42654. + case EVENT_DISPLAY_BRIGHTNESS:
  42655. + reg = REG_DISPLAY_BRIGHTNESS;
  42656. + break;
  42657. + case EVENT_AUDIO_VOLUME:
  42658. + reg = REG_AUDIO_VOLUME;
  42659. + break;
  42660. + case EVENT_AC_BAT:
  42661. + handler = ac_bat_handler;
  42662. + break;
  42663. + default:
  42664. + break;
  42665. + }
  42666. +
  42667. + if (reg != 0)
  42668. + status = ec_read(reg);
  42669. +
  42670. + if (handler != NULL)
  42671. + status = handler(status);
  42672. +
  42673. + pr_info("%s: event: %d status: %d\n", __func__, event, status);
  42674. +
  42675. + /* Report current key to user-space */
  42676. + ke = get_event_key_entry(event, status);
  42677. + if (ke) {
  42678. + if (ke->keycode == SW_LID)
  42679. + report_lid_switch(status);
  42680. + else
  42681. + sparse_keymap_report_entry(yeeloong_hotkey_dev, ke, 1,
  42682. + true);
  42683. + }
  42684. +}
  42685. +
  42686. +/*
  42687. + * SCI(system control interrupt) main interrupt routine
  42688. + *
  42689. + * We will do the query and get event number together so the interrupt routine
  42690. + * should be longer than 120us now at least 3ms elpase for it.
  42691. + */
  42692. +static irqreturn_t sci_irq_handler(int irq, void *dev_id)
  42693. +{
  42694. + int ret, event;
  42695. +
  42696. + if (SCI_IRQ_NUM != irq)
  42697. + return IRQ_NONE;
  42698. +
  42699. + /* Query the event number */
  42700. + ret = ec_query_event_num();
  42701. + if (ret < 0)
  42702. + return IRQ_NONE;
  42703. +
  42704. + event = ec_get_event_num();
  42705. + if (event < EVENT_START || event > EVENT_END)
  42706. + return IRQ_NONE;
  42707. +
  42708. + /* Execute corresponding actions */
  42709. + do_event_action(event);
  42710. +
  42711. + return IRQ_HANDLED;
  42712. +}
  42713. +
  42714. +/*
  42715. + * Config and init some msr and gpio register properly.
  42716. + */
  42717. +static int sci_irq_init(void)
  42718. +{
  42719. + u32 hi, lo;
  42720. + u32 gpio_base;
  42721. + unsigned long flags;
  42722. + int ret;
  42723. +
  42724. + /* Get gpio base */
  42725. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
  42726. + gpio_base = lo & 0xff00;
  42727. +
  42728. + /* Filter the former kb3310 interrupt for security */
  42729. + ret = ec_query_event_num();
  42730. + if (ret)
  42731. + return ret;
  42732. +
  42733. + /* For filtering next number interrupt */
  42734. + udelay(10000);
  42735. +
  42736. + /* Set gpio native registers and msrs for GPIO27 SCI EVENT PIN
  42737. + * gpio :
  42738. + * input, pull-up, no-invert, event-count and value 0,
  42739. + * no-filter, no edge mode
  42740. + * gpio27 map to Virtual gpio0
  42741. + * msr :
  42742. + * no primary and lpc
  42743. + * Unrestricted Z input to IG10 from Virtual gpio 0.
  42744. + */
  42745. + local_irq_save(flags);
  42746. + _rdmsr(0x80000024, &hi, &lo);
  42747. + lo &= ~(1 << 10);
  42748. + _wrmsr(0x80000024, hi, lo);
  42749. + _rdmsr(0x80000025, &hi, &lo);
  42750. + lo &= ~(1 << 10);
  42751. + _wrmsr(0x80000025, hi, lo);
  42752. + _rdmsr(0x80000023, &hi, &lo);
  42753. + lo |= (0x0a << 0);
  42754. + _wrmsr(0x80000023, hi, lo);
  42755. + local_irq_restore(flags);
  42756. +
  42757. + /* Set gpio27 as sci interrupt
  42758. + *
  42759. + * input, pull-up, no-fliter, no-negedge, invert
  42760. + * the sci event is just about 120us
  42761. + */
  42762. + asm(".set noreorder\n");
  42763. + /* input enable */
  42764. + outl(0x00000800, (gpio_base | 0xA0));
  42765. + /* revert the input */
  42766. + outl(0x00000800, (gpio_base | 0xA4));
  42767. + /* event-int enable */
  42768. + outl(0x00000800, (gpio_base | 0xB8));
  42769. + asm(".set reorder\n");
  42770. +
  42771. + return 0;
  42772. +}
  42773. +
  42774. +static struct irqaction sci_irqaction = {
  42775. + .handler = sci_irq_handler,
  42776. + .name = "sci",
  42777. + .flags = IRQF_SHARED,
  42778. +};
  42779. +
  42780. +static int yeeloong_hotkey_init(void)
  42781. +{
  42782. + int ret;
  42783. +
  42784. + ret = sci_irq_init();
  42785. + if (ret)
  42786. + return -EFAULT;
  42787. +
  42788. + ret = setup_irq(SCI_IRQ_NUM, &sci_irqaction);
  42789. + if (ret)
  42790. + return -EFAULT;
  42791. +
  42792. + yeeloong_hotkey_dev = input_allocate_device();
  42793. +
  42794. + if (!yeeloong_hotkey_dev) {
  42795. + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
  42796. + return -ENOMEM;
  42797. + }
  42798. +
  42799. + yeeloong_hotkey_dev->name = "HotKeys";
  42800. + yeeloong_hotkey_dev->phys = "button/input0";
  42801. + yeeloong_hotkey_dev->id.bustype = BUS_HOST;
  42802. + yeeloong_hotkey_dev->dev.parent = NULL;
  42803. +
  42804. + ret = sparse_keymap_setup(yeeloong_hotkey_dev, yeeloong_keymap, NULL);
  42805. + if (ret) {
  42806. + pr_err("Fail to setup input device keymap\n");
  42807. + input_free_device(yeeloong_hotkey_dev);
  42808. + return ret;
  42809. + }
  42810. +
  42811. + ret = input_register_device(yeeloong_hotkey_dev);
  42812. + if (ret) {
  42813. + sparse_keymap_free(yeeloong_hotkey_dev);
  42814. + input_free_device(yeeloong_hotkey_dev);
  42815. + return ret;
  42816. + }
  42817. +
  42818. + /* Update the current status of LID */
  42819. + report_lid_switch(BIT_LID_DETECT_ON);
  42820. +
  42821. +#ifdef CONFIG_LOONGSON_SUSPEND
  42822. + /* Install the real yeeloong_report_lid_status for pm.c */
  42823. + yeeloong_report_lid_status = report_lid_switch;
  42824. +#endif
  42825. +
  42826. + return 0;
  42827. +}
  42828. +
  42829. +static void yeeloong_hotkey_exit(void)
  42830. +{
  42831. + /* Free irq */
  42832. + remove_irq(SCI_IRQ_NUM, &sci_irqaction);
  42833. +
  42834. +#ifdef CONFIG_LOONGSON_SUSPEND
  42835. + /* Uninstall yeeloong_report_lid_status for pm.c */
  42836. + if (yeeloong_report_lid_status == report_lid_switch)
  42837. + yeeloong_report_lid_status = NULL;
  42838. +#endif
  42839. +
  42840. + if (yeeloong_hotkey_dev) {
  42841. + sparse_keymap_free(yeeloong_hotkey_dev);
  42842. + input_unregister_device(yeeloong_hotkey_dev);
  42843. + yeeloong_hotkey_dev = NULL;
  42844. + }
  42845. +}
  42846. +
  42847. +#ifdef CONFIG_PM
  42848. +static void usb_ports_set(int status)
  42849. +{
  42850. + status = !!status;
  42851. +
  42852. + ec_write(REG_USB0_FLAG, status);
  42853. + ec_write(REG_USB1_FLAG, status);
  42854. + ec_write(REG_USB2_FLAG, status);
  42855. +}
  42856. +
  42857. +static int yeeloong_suspend(struct device *dev)
  42858. +
  42859. +{
  42860. + if (ec_version_before("EC_VER=PQ1D27"))
  42861. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);
  42862. + yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);
  42863. + usb_ports_set(BIT_USB_FLAG_OFF);
  42864. +
  42865. + return 0;
  42866. +}
  42867. +
  42868. +static int yeeloong_resume(struct device *dev)
  42869. +{
  42870. + if (ec_version_before("EC_VER=PQ1D27"))
  42871. + yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);
  42872. + yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);
  42873. + usb_ports_set(BIT_USB_FLAG_ON);
  42874. +
  42875. + return 0;
  42876. +}
  42877. +
  42878. +static const SIMPLE_DEV_PM_OPS(yeeloong_pm_ops, yeeloong_suspend,
  42879. + yeeloong_resume);
  42880. +#endif
  42881. +
  42882. +static struct platform_device_id platform_device_ids[] = {
  42883. + {
  42884. + .name = "yeeloong_laptop",
  42885. + },
  42886. + {}
  42887. +};
  42888. +
  42889. +MODULE_DEVICE_TABLE(platform, platform_device_ids);
  42890. +
  42891. +static struct platform_driver platform_driver = {
  42892. + .driver = {
  42893. + .name = "yeeloong_laptop",
  42894. + .owner = THIS_MODULE,
  42895. +#ifdef CONFIG_PM
  42896. + .pm = &yeeloong_pm_ops,
  42897. +#endif
  42898. + },
  42899. + .id_table = platform_device_ids,
  42900. +};
  42901. +
  42902. +static int __init yeeloong_init(void)
  42903. +{
  42904. + int ret;
  42905. +
  42906. + pr_info("Load YeeLoong Laptop Platform Specific Driver.\n");
  42907. +
  42908. + /* Register platform stuff */
  42909. + ret = platform_driver_register(&platform_driver);
  42910. + if (ret) {
  42911. + pr_err("Fail to register yeeloong platform driver.\n");
  42912. + return ret;
  42913. + }
  42914. +
  42915. + ret = yeeloong_backlight_init();
  42916. + if (ret) {
  42917. + pr_err("Fail to register yeeloong backlight driver.\n");
  42918. + yeeloong_backlight_exit();
  42919. + return ret;
  42920. + }
  42921. +
  42922. + ret = yeeloong_bat_init();
  42923. + if (ret) {
  42924. + pr_err("Fail to register yeeloong battery driver.\n");
  42925. + yeeloong_bat_exit();
  42926. + return ret;
  42927. + }
  42928. +
  42929. + ret = yeeloong_hwmon_init();
  42930. + if (ret) {
  42931. + pr_err("Fail to register yeeloong hwmon driver.\n");
  42932. + yeeloong_hwmon_exit();
  42933. + return ret;
  42934. + }
  42935. +
  42936. + ret = yeeloong_vo_init();
  42937. + if (ret) {
  42938. + pr_err("Fail to register yeeloong video output driver.\n");
  42939. + yeeloong_vo_exit();
  42940. + return ret;
  42941. + }
  42942. +
  42943. + ret = yeeloong_hotkey_init();
  42944. + if (ret) {
  42945. + pr_err("Fail to register yeeloong hotkey driver.\n");
  42946. + yeeloong_hotkey_exit();
  42947. + return ret;
  42948. + }
  42949. +
  42950. + return 0;
  42951. +}
  42952. +
  42953. +static void __exit yeeloong_exit(void)
  42954. +{
  42955. + yeeloong_hotkey_exit();
  42956. + yeeloong_vo_exit();
  42957. + yeeloong_hwmon_exit();
  42958. + yeeloong_bat_exit();
  42959. + yeeloong_backlight_exit();
  42960. + platform_driver_unregister(&platform_driver);
  42961. +
  42962. + pr_info("Unload YeeLoong Platform Specific Driver.\n");
  42963. +}
  42964. +
  42965. +module_init(yeeloong_init);
  42966. +module_exit(yeeloong_exit);
  42967. +
  42968. +MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Liu Junliang <liujl@lemote.com>");
  42969. +MODULE_DESCRIPTION("YeeLoong laptop driver");
  42970. +MODULE_LICENSE("GPL");
  42971. diff -Nur linux-2.6.34.orig/drivers/rtc/rtc-cmos.c linux-loongson/drivers/rtc/rtc-cmos.c
  42972. --- linux-2.6.34.orig/drivers/rtc/rtc-cmos.c 2010-05-16 23:17:36.000000000 +0200
  42973. +++ linux-loongson/drivers/rtc/rtc-cmos.c 2010-05-27 18:15:37.623465175 +0200
  42974. @@ -752,9 +752,8 @@
  42975. /* FIXME teach the alarm code how to handle binary mode;
  42976. * <asm-generic/rtc.h> doesn't know 12-hour mode either.
  42977. */
  42978. - if (is_valid_irq(rtc_irq) &&
  42979. - (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) {
  42980. - dev_dbg(dev, "only 24-hr BCD mode supported\n");
  42981. + if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
  42982. + dev_dbg(dev, "only 24-hr supported\n");
  42983. retval = -ENXIO;
  42984. goto cleanup1;
  42985. }
  42986. diff -Nur linux-2.6.34.orig/drivers/staging/sm7xx/smtcfb.c linux-loongson/drivers/staging/sm7xx/smtcfb.c
  42987. --- linux-2.6.34.orig/drivers/staging/sm7xx/smtcfb.c 2010-05-16 23:17:36.000000000 +0200
  42988. +++ linux-loongson/drivers/staging/sm7xx/smtcfb.c 2010-05-27 18:15:38.733462789 +0200
  42989. @@ -12,6 +12,8 @@
  42990. * License. See the file COPYING in the main directory of this archive for
  42991. * more details.
  42992. *
  42993. + * - Remove the buggy 2D support for Lynx, 2010/01/06, Wu Zhangjin
  42994. + *
  42995. * Version 0.10.26192.21.01
  42996. * - Add PowerPC/Big endian support
  42997. * - Add 2D support for Lynx
  42998. @@ -107,6 +109,7 @@
  42999. {"0x307", 1280, 1024, 8},
  43000. {"0x311", 640, 480, 16},
  43001. + {"0x313", 800, 480, 16},
  43002. {"0x314", 800, 600, 16},
  43003. {"0x317", 1024, 768, 16},
  43004. {"0x31A", 1280, 1024, 16},
  43005. diff -Nur linux-2.6.34.orig/drivers/usb/host/ohci-hcd.c linux-loongson/drivers/usb/host/ohci-hcd.c
  43006. --- linux-2.6.34.orig/drivers/usb/host/ohci-hcd.c 2010-05-16 23:17:36.000000000 +0200
  43007. +++ linux-loongson/drivers/usb/host/ohci-hcd.c 2010-05-27 18:15:39.022214534 +0200
  43008. @@ -832,9 +832,13 @@
  43009. }
  43010. if (ints & OHCI_INTR_WDH) {
  43011. - spin_lock (&ohci->lock);
  43012. - dl_done_list (ohci);
  43013. - spin_unlock (&ohci->lock);
  43014. + if (ohci->hcca->done_head == 0) {
  43015. + ints &= ~OHCI_INTR_WDH;
  43016. + } else {
  43017. + spin_lock (&ohci->lock);
  43018. + dl_done_list (ohci);
  43019. + spin_unlock (&ohci->lock);
  43020. + }
  43021. }
  43022. if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
  43023. diff -Nur linux-2.6.34.orig/drivers/video/tdfxfb.c linux-loongson/drivers/video/tdfxfb.c
  43024. --- linux-2.6.34.orig/drivers/video/tdfxfb.c 2010-05-16 23:17:36.000000000 +0200
  43025. +++ linux-loongson/drivers/video/tdfxfb.c 2010-05-27 18:12:44.063464481 +0200
  43026. @@ -1571,8 +1571,8 @@
  43027. if (default_par->mtrr_handle >= 0)
  43028. mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
  43029. info->fix.smem_len);
  43030. - release_mem_region(pci_resource_start(pdev, 2),
  43031. - pci_resource_len(pdev, 2));
  43032. + release_region(pci_resource_start(pdev, 2),
  43033. + pci_resource_len(pdev, 2));
  43034. out_err_screenbase:
  43035. if (info->screen_base)
  43036. iounmap(info->screen_base);
  43037. diff -Nur linux-2.6.34.orig/net/rfkill/core.c linux-loongson/net/rfkill/core.c
  43038. --- linux-2.6.34.orig/net/rfkill/core.c 2010-05-16 23:17:36.000000000 +0200
  43039. +++ linux-loongson/net/rfkill/core.c 2010-05-27 18:15:42.770974885 +0200
  43040. @@ -112,7 +112,7 @@
  43041. static DEFINE_MUTEX(rfkill_global_mutex);
  43042. static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */
  43043. -static unsigned int rfkill_default_state = 1;
  43044. +static unsigned int rfkill_default_state; /* default: 0 = radio off */
  43045. module_param_named(default_state, rfkill_default_state, uint, 0444);
  43046. MODULE_PARM_DESC(default_state,
  43047. "Default initial state for all radio types, 0 = radio off");