0111-NET-MIPS-add-ralink-SoC-ethernet-driver.patch 135 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947
  1. From ad11aedcc16574c0b3d3f5e40c67227d1846b94e Mon Sep 17 00:00:00 2001
  2. From: John Crispin <[email protected]>
  3. Date: Mon, 22 Apr 2013 23:20:03 +0200
  4. Subject: [PATCH 16/33] NET: MIPS: add ralink SoC ethernet driver
  5. Add support for Ralink FE and ESW.
  6. Signed-off-by: John Crispin <[email protected]>
  7. ---
  8. .../include/asm/mach-ralink/rt305x_esw_platform.h | 27 +
  9. arch/mips/ralink/rt305x.c | 1 +
  10. drivers/net/ethernet/Kconfig | 1 +
  11. drivers/net/ethernet/Makefile | 1 +
  12. drivers/net/ethernet/ralink/Kconfig | 31 +
  13. drivers/net/ethernet/ralink/Makefile | 18 +
  14. drivers/net/ethernet/ralink/esw_rt3052.c | 1463 ++++++++++++++++++++
  15. drivers/net/ethernet/ralink/esw_rt3052.h | 32 +
  16. drivers/net/ethernet/ralink/gsw_mt7620a.c | 1027 ++++++++++++++
  17. drivers/net/ethernet/ralink/gsw_mt7620a.h | 29 +
  18. drivers/net/ethernet/ralink/mdio.c | 245 ++++
  19. drivers/net/ethernet/ralink/mdio.h | 29 +
  20. drivers/net/ethernet/ralink/mdio_rt2880.c | 232 ++++
  21. drivers/net/ethernet/ralink/mdio_rt2880.h | 26 +
  22. drivers/net/ethernet/ralink/ralink_soc_eth.c | 735 ++++++++++
  23. drivers/net/ethernet/ralink/ralink_soc_eth.h | 374 +++++
  24. drivers/net/ethernet/ralink/soc_mt7620.c | 111 ++
  25. drivers/net/ethernet/ralink/soc_rt2880.c | 51 +
  26. drivers/net/ethernet/ralink/soc_rt305x.c | 113 ++
  27. drivers/net/ethernet/ralink/soc_rt3883.c | 60 +
  28. 20 files changed, 4606 insertions(+)
  29. create mode 100644 arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h
  30. create mode 100644 drivers/net/ethernet/ralink/Kconfig
  31. create mode 100644 drivers/net/ethernet/ralink/Makefile
  32. create mode 100644 drivers/net/ethernet/ralink/esw_rt3052.c
  33. create mode 100644 drivers/net/ethernet/ralink/esw_rt3052.h
  34. create mode 100644 drivers/net/ethernet/ralink/gsw_mt7620a.c
  35. create mode 100644 drivers/net/ethernet/ralink/gsw_mt7620a.h
  36. create mode 100644 drivers/net/ethernet/ralink/mdio.c
  37. create mode 100644 drivers/net/ethernet/ralink/mdio.h
  38. create mode 100644 drivers/net/ethernet/ralink/mdio_rt2880.c
  39. create mode 100644 drivers/net/ethernet/ralink/mdio_rt2880.h
  40. create mode 100644 drivers/net/ethernet/ralink/ralink_soc_eth.c
  41. create mode 100644 drivers/net/ethernet/ralink/ralink_soc_eth.h
  42. create mode 100644 drivers/net/ethernet/ralink/soc_mt7620.c
  43. create mode 100644 drivers/net/ethernet/ralink/soc_rt2880.c
  44. create mode 100644 drivers/net/ethernet/ralink/soc_rt305x.c
  45. create mode 100644 drivers/net/ethernet/ralink/soc_rt3883.c
  46. --- /dev/null
  47. +++ b/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h
  48. @@ -0,0 +1,27 @@
  49. +/*
  50. + * Ralink RT305x SoC platform device registration
  51. + *
  52. + * Copyright (C) 2010 Gabor Juhos <[email protected]>
  53. + *
  54. + * This program is free software; you can redistribute it and/or modify it
  55. + * under the terms of the GNU General Public License version 2 as published
  56. + * by the Free Software Foundation.
  57. + */
  58. +
  59. +#ifndef _RT305X_ESW_PLATFORM_H
  60. +#define _RT305X_ESW_PLATFORM_H
  61. +
  62. +enum {
  63. + RT305X_ESW_VLAN_CONFIG_NONE = 0,
  64. + RT305X_ESW_VLAN_CONFIG_LLLLW,
  65. + RT305X_ESW_VLAN_CONFIG_WLLLL,
  66. +};
  67. +
  68. +struct rt305x_esw_platform_data
  69. +{
  70. + u8 vlan_config;
  71. + u32 reg_initval_fct2;
  72. + u32 reg_initval_fpa2;
  73. +};
  74. +
  75. +#endif /* _RT305X_ESW_PLATFORM_H */
  76. --- a/arch/mips/ralink/rt305x.c
  77. +++ b/arch/mips/ralink/rt305x.c
  78. @@ -221,6 +221,7 @@ void __init ralink_clk_init(void)
  79. }
  80. ralink_clk_add("cpu", cpu_rate);
  81. + ralink_clk_add("sys", sys_rate);
  82. ralink_clk_add("10000b00.spi", sys_rate);
  83. ralink_clk_add("10000100.timer", wdt_rate);
  84. ralink_clk_add("10000120.watchdog", wdt_rate);
  85. --- a/drivers/net/ethernet/Kconfig
  86. +++ b/drivers/net/ethernet/Kconfig
  87. @@ -135,6 +135,7 @@ config ETHOC
  88. source "drivers/net/ethernet/packetengines/Kconfig"
  89. source "drivers/net/ethernet/pasemi/Kconfig"
  90. source "drivers/net/ethernet/qlogic/Kconfig"
  91. +source "drivers/net/ethernet/ralink/Kconfig"
  92. source "drivers/net/ethernet/realtek/Kconfig"
  93. source "drivers/net/ethernet/renesas/Kconfig"
  94. source "drivers/net/ethernet/rdc/Kconfig"
  95. --- a/drivers/net/ethernet/Makefile
  96. +++ b/drivers/net/ethernet/Makefile
  97. @@ -53,6 +53,7 @@ obj-$(CONFIG_ETHOC) += ethoc.o
  98. obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/
  99. obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
  100. obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
  101. +obj-$(CONFIG_NET_RALINK) += ralink/
  102. obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
  103. obj-$(CONFIG_SH_ETH) += renesas/
  104. obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
  105. --- /dev/null
  106. +++ b/drivers/net/ethernet/ralink/Kconfig
  107. @@ -0,0 +1,32 @@
  108. +config NET_RALINK
  109. + tristate "Ralink RT288X/RT3X5X/RT3662/RT3883/MT7620 ethernet driver"
  110. + depends on RALINK
  111. + help
  112. + This driver supports the ethernet mac inside the ralink wisocs
  113. +
  114. +if NET_RALINK
  115. +
  116. +config NET_RALINK_MDIO
  117. + def_bool NET_RALINK
  118. + depends on (SOC_RT288X || SOC_RT3883 || SOC_MT7620)
  119. + select PHYLIB
  120. +
  121. +config NET_RALINK_MDIO_RT2880
  122. + def_bool NET_RALINK
  123. + depends on (SOC_RT288X || SOC_RT3883)
  124. + select NET_RALINK_MDIO
  125. +
  126. +config NET_RALINK_ESW_RT3052
  127. + def_bool NET_RALINK
  128. + depends on SOC_RT305X
  129. + select PHYLIB
  130. + select SWCONFIG
  131. +
  132. +config NET_RALINK_GSW_MT7620
  133. + def_bool NET_RALINK
  134. + depends on SOC_MT7620
  135. + select INET_LRO
  136. + select NET_RALINK_MDIO
  137. + select PHYLIB
  138. + select SWCONFIG
  139. +endif
  140. --- /dev/null
  141. +++ b/drivers/net/ethernet/ralink/Makefile
  142. @@ -0,0 +1,18 @@
  143. +#
  144. +# Makefile for the Ralink SoCs built-in ethernet macs
  145. +#
  146. +
  147. +ralink-eth-y += ralink_soc_eth.o
  148. +
  149. +ralink-eth-$(CONFIG_NET_RALINK_MDIO) += mdio.o
  150. +ralink-eth-$(CONFIG_NET_RALINK_MDIO_RT2880) += mdio_rt2880.o
  151. +
  152. +ralink-eth-$(CONFIG_NET_RALINK_ESW_RT3052) += esw_rt3052.o
  153. +ralink-eth-$(CONFIG_NET_RALINK_GSW_MT7620) += gsw_mt7620a.o mt7530.o
  154. +
  155. +ralink-eth-$(CONFIG_SOC_RT288X) += soc_rt2880.o
  156. +ralink-eth-$(CONFIG_SOC_RT305X) += soc_rt305x.o
  157. +ralink-eth-$(CONFIG_SOC_RT3883) += soc_rt3883.o
  158. +ralink-eth-$(CONFIG_SOC_MT7620) += soc_mt7620.o
  159. +
  160. +obj-$(CONFIG_NET_RALINK) += ralink-eth.o
  161. --- /dev/null
  162. +++ b/drivers/net/ethernet/ralink/esw_rt3052.c
  163. @@ -0,0 +1,1463 @@
  164. +/*
  165. + * This program is free software; you can redistribute it and/or modify
  166. + * it under the terms of the GNU General Public License as published by
  167. + * the Free Software Foundation; version 2 of the License
  168. + *
  169. + * This program is distributed in the hope that it will be useful,
  170. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  171. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  172. + * GNU General Public License for more details.
  173. + *
  174. + * You should have received a copy of the GNU General Public License
  175. + * along with this program; if not, write to the Free Software
  176. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  177. + *
  178. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  179. + */
  180. +
  181. +#include <linux/module.h>
  182. +#include <linux/kernel.h>
  183. +#include <linux/types.h>
  184. +#include <linux/dma-mapping.h>
  185. +#include <linux/init.h>
  186. +#include <linux/skbuff.h>
  187. +#include <linux/etherdevice.h>
  188. +#include <linux/ethtool.h>
  189. +#include <linux/platform_device.h>
  190. +#include <linux/of_device.h>
  191. +#include <linux/clk.h>
  192. +#include <linux/of_net.h>
  193. +#include <linux/of_mdio.h>
  194. +
  195. +#include <asm/mach-ralink/ralink_regs.h>
  196. +
  197. +#include "ralink_soc_eth.h"
  198. +
  199. +#include <linux/ioport.h>
  200. +#include <linux/switch.h>
  201. +#include <linux/mii.h>
  202. +
  203. +#include <ralink_regs.h>
  204. +#include <asm/mach-ralink/rt305x.h>
  205. +#include <asm/mach-ralink/rt305x_esw_platform.h>
  206. +
  207. +/*
  208. + * HW limitations for this switch:
  209. + * - No large frame support (PKT_MAX_LEN at most 1536)
  210. + * - Can't have untagged vlan and tagged vlan on one port at the same time,
  211. + * though this might be possible using the undocumented PPE.
  212. + */
  213. +
  214. +#define RT305X_ESW_REG_ISR 0x00
  215. +#define RT305X_ESW_REG_IMR 0x04
  216. +#define RT305X_ESW_REG_FCT0 0x08
  217. +#define RT305X_ESW_REG_PFC1 0x14
  218. +#define RT305X_ESW_REG_ATS 0x24
  219. +#define RT305X_ESW_REG_ATS0 0x28
  220. +#define RT305X_ESW_REG_ATS1 0x2c
  221. +#define RT305X_ESW_REG_ATS2 0x30
  222. +#define RT305X_ESW_REG_PVIDC(_n) (0x40 + 4 * (_n))
  223. +#define RT305X_ESW_REG_VLANI(_n) (0x50 + 4 * (_n))
  224. +#define RT305X_ESW_REG_VMSC(_n) (0x70 + 4 * (_n))
  225. +#define RT305X_ESW_REG_POA 0x80
  226. +#define RT305X_ESW_REG_FPA 0x84
  227. +#define RT305X_ESW_REG_SOCPC 0x8c
  228. +#define RT305X_ESW_REG_POC0 0x90
  229. +#define RT305X_ESW_REG_POC1 0x94
  230. +#define RT305X_ESW_REG_POC2 0x98
  231. +#define RT305X_ESW_REG_SGC 0x9c
  232. +#define RT305X_ESW_REG_STRT 0xa0
  233. +#define RT305X_ESW_REG_PCR0 0xc0
  234. +#define RT305X_ESW_REG_PCR1 0xc4
  235. +#define RT305X_ESW_REG_FPA2 0xc8
  236. +#define RT305X_ESW_REG_FCT2 0xcc
  237. +#define RT305X_ESW_REG_SGC2 0xe4
  238. +#define RT305X_ESW_REG_P0LED 0xa4
  239. +#define RT305X_ESW_REG_P1LED 0xa8
  240. +#define RT305X_ESW_REG_P2LED 0xac
  241. +#define RT305X_ESW_REG_P3LED 0xb0
  242. +#define RT305X_ESW_REG_P4LED 0xb4
  243. +#define RT305X_ESW_REG_PXPC(_x) (0xe8 + (4 * _x))
  244. +#define RT305X_ESW_REG_P1PC 0xec
  245. +#define RT305X_ESW_REG_P2PC 0xf0
  246. +#define RT305X_ESW_REG_P3PC 0xf4
  247. +#define RT305X_ESW_REG_P4PC 0xf8
  248. +#define RT305X_ESW_REG_P5PC 0xfc
  249. +
  250. +#define RT305X_ESW_LED_LINK 0
  251. +#define RT305X_ESW_LED_100M 1
  252. +#define RT305X_ESW_LED_DUPLEX 2
  253. +#define RT305X_ESW_LED_ACTIVITY 3
  254. +#define RT305X_ESW_LED_COLLISION 4
  255. +#define RT305X_ESW_LED_LINKACT 5
  256. +#define RT305X_ESW_LED_DUPLCOLL 6
  257. +#define RT305X_ESW_LED_10MACT 7
  258. +#define RT305X_ESW_LED_100MACT 8
  259. +/* Additional led states not in datasheet: */
  260. +#define RT305X_ESW_LED_BLINK 10
  261. +#define RT305X_ESW_LED_ON 12
  262. +
  263. +#define RT305X_ESW_LINK_S 25
  264. +#define RT305X_ESW_DUPLEX_S 9
  265. +#define RT305X_ESW_SPD_S 0
  266. +
  267. +#define RT305X_ESW_PCR0_WT_NWAY_DATA_S 16
  268. +#define RT305X_ESW_PCR0_WT_PHY_CMD BIT(13)
  269. +#define RT305X_ESW_PCR0_CPU_PHY_REG_S 8
  270. +
  271. +#define RT305X_ESW_PCR1_WT_DONE BIT(0)
  272. +
  273. +#define RT305X_ESW_ATS_TIMEOUT (5 * HZ)
  274. +#define RT305X_ESW_PHY_TIMEOUT (5 * HZ)
  275. +
  276. +#define RT305X_ESW_PVIDC_PVID_M 0xfff
  277. +#define RT305X_ESW_PVIDC_PVID_S 12
  278. +
  279. +#define RT305X_ESW_VLANI_VID_M 0xfff
  280. +#define RT305X_ESW_VLANI_VID_S 12
  281. +
  282. +#define RT305X_ESW_VMSC_MSC_M 0xff
  283. +#define RT305X_ESW_VMSC_MSC_S 8
  284. +
  285. +#define RT305X_ESW_SOCPC_DISUN2CPU_S 0
  286. +#define RT305X_ESW_SOCPC_DISMC2CPU_S 8
  287. +#define RT305X_ESW_SOCPC_DISBC2CPU_S 16
  288. +#define RT305X_ESW_SOCPC_CRC_PADDING BIT(25)
  289. +
  290. +#define RT305X_ESW_POC0_EN_BP_S 0
  291. +#define RT305X_ESW_POC0_EN_FC_S 8
  292. +#define RT305X_ESW_POC0_DIS_RMC2CPU_S 16
  293. +#define RT305X_ESW_POC0_DIS_PORT_M 0x7f
  294. +#define RT305X_ESW_POC0_DIS_PORT_S 23
  295. +
  296. +#define RT305X_ESW_POC2_UNTAG_EN_M 0xff
  297. +#define RT305X_ESW_POC2_UNTAG_EN_S 0
  298. +#define RT305X_ESW_POC2_ENAGING_S 8
  299. +#define RT305X_ESW_POC2_DIS_UC_PAUSE_S 16
  300. +
  301. +#define RT305X_ESW_SGC2_DOUBLE_TAG_M 0x7f
  302. +#define RT305X_ESW_SGC2_DOUBLE_TAG_S 0
  303. +#define RT305X_ESW_SGC2_LAN_PMAP_M 0x3f
  304. +#define RT305X_ESW_SGC2_LAN_PMAP_S 24
  305. +
  306. +#define RT305X_ESW_PFC1_EN_VLAN_M 0xff
  307. +#define RT305X_ESW_PFC1_EN_VLAN_S 16
  308. +#define RT305X_ESW_PFC1_EN_TOS_S 24
  309. +
  310. +#define RT305X_ESW_VLAN_NONE 0xfff
  311. +
  312. +#define RT305X_ESW_GSC_BC_STROM_MASK 0x3
  313. +#define RT305X_ESW_GSC_BC_STROM_SHIFT 4
  314. +
  315. +#define RT305X_ESW_GSC_LED_FREQ_MASK 0x3
  316. +#define RT305X_ESW_GSC_LED_FREQ_SHIFT 23
  317. +
  318. +#define RT305X_ESW_POA_LINK_MASK 0x1f
  319. +#define RT305X_ESW_POA_LINK_SHIFT 25
  320. +
  321. +#define RT305X_ESW_PORT_ST_CHG BIT(26)
  322. +#define RT305X_ESW_PORT0 0
  323. +#define RT305X_ESW_PORT1 1
  324. +#define RT305X_ESW_PORT2 2
  325. +#define RT305X_ESW_PORT3 3
  326. +#define RT305X_ESW_PORT4 4
  327. +#define RT305X_ESW_PORT5 5
  328. +#define RT305X_ESW_PORT6 6
  329. +
  330. +#define RT305X_ESW_PORTS_NONE 0
  331. +
  332. +#define RT305X_ESW_PMAP_LLLLLL 0x3f
  333. +#define RT305X_ESW_PMAP_LLLLWL 0x2f
  334. +#define RT305X_ESW_PMAP_WLLLLL 0x3e
  335. +
  336. +#define RT305X_ESW_PORTS_INTERNAL \
  337. + (BIT(RT305X_ESW_PORT0) | BIT(RT305X_ESW_PORT1) | \
  338. + BIT(RT305X_ESW_PORT2) | BIT(RT305X_ESW_PORT3) | \
  339. + BIT(RT305X_ESW_PORT4))
  340. +
  341. +#define RT305X_ESW_PORTS_NOCPU \
  342. + (RT305X_ESW_PORTS_INTERNAL | BIT(RT305X_ESW_PORT5))
  343. +
  344. +#define RT305X_ESW_PORTS_CPU BIT(RT305X_ESW_PORT6)
  345. +
  346. +#define RT305X_ESW_PORTS_ALL \
  347. + (RT305X_ESW_PORTS_NOCPU | RT305X_ESW_PORTS_CPU)
  348. +
  349. +#define RT305X_ESW_NUM_VLANS 16
  350. +#define RT305X_ESW_NUM_VIDS 4096
  351. +#define RT305X_ESW_NUM_PORTS 7
  352. +#define RT305X_ESW_NUM_LANWAN 6
  353. +#define RT305X_ESW_NUM_LEDS 5
  354. +
  355. +#define RT5350_ESW_REG_PXTPC(_x) (0x150 + (4 * _x))
  356. +#define RT5350_EWS_REG_LED_POLARITY 0x168
  357. +#define RT5350_RESET_EPHY BIT(24)
  358. +#define SYSC_REG_RESET_CTRL 0x34
  359. +
  360. +enum {
  361. + /* Global attributes. */
  362. + RT305X_ESW_ATTR_ENABLE_VLAN,
  363. + RT305X_ESW_ATTR_ALT_VLAN_DISABLE,
  364. + RT305X_ESW_ATTR_BC_STATUS,
  365. + RT305X_ESW_ATTR_LED_FREQ,
  366. + /* Port attributes. */
  367. + RT305X_ESW_ATTR_PORT_DISABLE,
  368. + RT305X_ESW_ATTR_PORT_DOUBLETAG,
  369. + RT305X_ESW_ATTR_PORT_UNTAG,
  370. + RT305X_ESW_ATTR_PORT_LED,
  371. + RT305X_ESW_ATTR_PORT_LAN,
  372. + RT305X_ESW_ATTR_PORT_RECV_BAD,
  373. + RT305X_ESW_ATTR_PORT_RECV_GOOD,
  374. + RT5350_ESW_ATTR_PORT_TR_BAD,
  375. + RT5350_ESW_ATTR_PORT_TR_GOOD,
  376. +};
  377. +
  378. +struct esw_port {
  379. + bool disable;
  380. + bool doubletag;
  381. + bool untag;
  382. + u8 led;
  383. + u16 pvid;
  384. +};
  385. +
  386. +struct esw_vlan {
  387. + u8 ports;
  388. + u16 vid;
  389. +};
  390. +
  391. +struct rt305x_esw {
  392. + struct device *dev;
  393. + void __iomem *base;
  394. + int irq;
  395. + const struct rt305x_esw_platform_data *pdata;
  396. + /* Protects against concurrent register rmw operations. */
  397. + spinlock_t reg_rw_lock;
  398. +
  399. + unsigned char port_map;
  400. + unsigned int reg_initval_fct2;
  401. + unsigned int reg_initval_fpa2;
  402. + unsigned int reg_led_polarity;
  403. +
  404. +
  405. + struct switch_dev swdev;
  406. + bool global_vlan_enable;
  407. + bool alt_vlan_disable;
  408. + int bc_storm_protect;
  409. + int led_frequency;
  410. + struct esw_vlan vlans[RT305X_ESW_NUM_VLANS];
  411. + struct esw_port ports[RT305X_ESW_NUM_PORTS];
  412. +
  413. +};
  414. +
  415. +static inline void esw_w32(struct rt305x_esw *esw, u32 val, unsigned reg)
  416. +{
  417. + __raw_writel(val, esw->base + reg);
  418. +}
  419. +
  420. +static inline u32 esw_r32(struct rt305x_esw *esw, unsigned reg)
  421. +{
  422. + return __raw_readl(esw->base + reg);
  423. +}
  424. +
  425. +static inline void esw_rmw_raw(struct rt305x_esw *esw, unsigned reg, unsigned long mask,
  426. + unsigned long val)
  427. +{
  428. + unsigned long t;
  429. +
  430. + t = __raw_readl(esw->base + reg) & ~mask;
  431. + __raw_writel(t | val, esw->base + reg);
  432. +}
  433. +
  434. +static void esw_rmw(struct rt305x_esw *esw, unsigned reg, unsigned long mask,
  435. + unsigned long val)
  436. +{
  437. + unsigned long flags;
  438. +
  439. + spin_lock_irqsave(&esw->reg_rw_lock, flags);
  440. + esw_rmw_raw(esw, reg, mask, val);
  441. + spin_unlock_irqrestore(&esw->reg_rw_lock, flags);
  442. +}
  443. +
  444. +static u32 rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr, u32 phy_register,
  445. + u32 write_data)
  446. +{
  447. + unsigned long t_start = jiffies;
  448. + int ret = 0;
  449. +
  450. + while (1) {
  451. + if (!(esw_r32(esw, RT305X_ESW_REG_PCR1) &
  452. + RT305X_ESW_PCR1_WT_DONE))
  453. + break;
  454. + if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
  455. + ret = 1;
  456. + goto out;
  457. + }
  458. + }
  459. +
  460. + write_data &= 0xffff;
  461. + esw_w32(esw,
  462. + (write_data << RT305X_ESW_PCR0_WT_NWAY_DATA_S) |
  463. + (phy_register << RT305X_ESW_PCR0_CPU_PHY_REG_S) |
  464. + (phy_addr) | RT305X_ESW_PCR0_WT_PHY_CMD,
  465. + RT305X_ESW_REG_PCR0);
  466. +
  467. + t_start = jiffies;
  468. + while (1) {
  469. + if (esw_r32(esw, RT305X_ESW_REG_PCR1) &
  470. + RT305X_ESW_PCR1_WT_DONE)
  471. + break;
  472. +
  473. + if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
  474. + ret = 1;
  475. + break;
  476. + }
  477. + }
  478. +out:
  479. + if (ret)
  480. + printk(KERN_ERR "ramips_eth: MDIO timeout\n");
  481. + return ret;
  482. +}
  483. +
  484. +static unsigned esw_get_vlan_id(struct rt305x_esw *esw, unsigned vlan)
  485. +{
  486. + unsigned s;
  487. + unsigned val;
  488. +
  489. + s = RT305X_ESW_VLANI_VID_S * (vlan % 2);
  490. + val = esw_r32(esw, RT305X_ESW_REG_VLANI(vlan / 2));
  491. + val = (val >> s) & RT305X_ESW_VLANI_VID_M;
  492. +
  493. + return val;
  494. +}
  495. +
  496. +static void esw_set_vlan_id(struct rt305x_esw *esw, unsigned vlan, unsigned vid)
  497. +{
  498. + unsigned s;
  499. +
  500. + s = RT305X_ESW_VLANI_VID_S * (vlan % 2);
  501. + esw_rmw(esw,
  502. + RT305X_ESW_REG_VLANI(vlan / 2),
  503. + RT305X_ESW_VLANI_VID_M << s,
  504. + (vid & RT305X_ESW_VLANI_VID_M) << s);
  505. +}
  506. +
  507. +static unsigned esw_get_pvid(struct rt305x_esw *esw, unsigned port)
  508. +{
  509. + unsigned s, val;
  510. +
  511. + s = RT305X_ESW_PVIDC_PVID_S * (port % 2);
  512. + val = esw_r32(esw, RT305X_ESW_REG_PVIDC(port / 2));
  513. + return (val >> s) & RT305X_ESW_PVIDC_PVID_M;
  514. +}
  515. +
  516. +static void esw_set_pvid(struct rt305x_esw *esw, unsigned port, unsigned pvid)
  517. +{
  518. + unsigned s;
  519. +
  520. + s = RT305X_ESW_PVIDC_PVID_S * (port % 2);
  521. + esw_rmw(esw,
  522. + RT305X_ESW_REG_PVIDC(port / 2),
  523. + RT305X_ESW_PVIDC_PVID_M << s,
  524. + (pvid & RT305X_ESW_PVIDC_PVID_M) << s);
  525. +}
  526. +
  527. +static unsigned esw_get_vmsc(struct rt305x_esw *esw, unsigned vlan)
  528. +{
  529. + unsigned s, val;
  530. +
  531. + s = RT305X_ESW_VMSC_MSC_S * (vlan % 4);
  532. + val = esw_r32(esw, RT305X_ESW_REG_VMSC(vlan / 4));
  533. + val = (val >> s) & RT305X_ESW_VMSC_MSC_M;
  534. +
  535. + return val;
  536. +}
  537. +
  538. +static void esw_set_vmsc(struct rt305x_esw *esw, unsigned vlan, unsigned msc)
  539. +{
  540. + unsigned s;
  541. +
  542. + s = RT305X_ESW_VMSC_MSC_S * (vlan % 4);
  543. + esw_rmw(esw,
  544. + RT305X_ESW_REG_VMSC(vlan / 4),
  545. + RT305X_ESW_VMSC_MSC_M << s,
  546. + (msc & RT305X_ESW_VMSC_MSC_M) << s);
  547. +}
  548. +
  549. +static unsigned esw_get_port_disable(struct rt305x_esw *esw)
  550. +{
  551. + unsigned reg;
  552. + reg = esw_r32(esw, RT305X_ESW_REG_POC0);
  553. + return (reg >> RT305X_ESW_POC0_DIS_PORT_S) &
  554. + RT305X_ESW_POC0_DIS_PORT_M;
  555. +}
  556. +
  557. +static void esw_set_port_disable(struct rt305x_esw *esw, unsigned disable_mask)
  558. +{
  559. + unsigned old_mask;
  560. + unsigned enable_mask;
  561. + unsigned changed;
  562. + int i;
  563. +
  564. + old_mask = esw_get_port_disable(esw);
  565. + changed = old_mask ^ disable_mask;
  566. + enable_mask = old_mask & disable_mask;
  567. +
  568. + /* enable before writing to MII */
  569. + esw_rmw(esw, RT305X_ESW_REG_POC0,
  570. + (RT305X_ESW_POC0_DIS_PORT_M <<
  571. + RT305X_ESW_POC0_DIS_PORT_S),
  572. + enable_mask << RT305X_ESW_POC0_DIS_PORT_S);
  573. +
  574. + for (i = 0; i < RT305X_ESW_NUM_LEDS; i++) {
  575. + if (!(changed & (1 << i)))
  576. + continue;
  577. + if (disable_mask & (1 << i)) {
  578. + /* disable */
  579. + rt305x_mii_write(esw, i, MII_BMCR,
  580. + BMCR_PDOWN);
  581. + } else {
  582. + /* enable */
  583. + rt305x_mii_write(esw, i, MII_BMCR,
  584. + BMCR_FULLDPLX |
  585. + BMCR_ANENABLE |
  586. + BMCR_ANRESTART |
  587. + BMCR_SPEED100);
  588. + }
  589. + }
  590. +
  591. + /* disable after writing to MII */
  592. + esw_rmw(esw, RT305X_ESW_REG_POC0,
  593. + (RT305X_ESW_POC0_DIS_PORT_M <<
  594. + RT305X_ESW_POC0_DIS_PORT_S),
  595. + disable_mask << RT305X_ESW_POC0_DIS_PORT_S);
  596. +}
  597. +
  598. +static void esw_set_gsc(struct rt305x_esw *esw)
  599. +{
  600. + esw_rmw(esw, RT305X_ESW_REG_SGC,
  601. + RT305X_ESW_GSC_BC_STROM_MASK << RT305X_ESW_GSC_BC_STROM_SHIFT,
  602. + esw->bc_storm_protect << RT305X_ESW_GSC_BC_STROM_SHIFT);
  603. + esw_rmw(esw, RT305X_ESW_REG_SGC,
  604. + RT305X_ESW_GSC_LED_FREQ_MASK << RT305X_ESW_GSC_LED_FREQ_SHIFT,
  605. + esw->led_frequency << RT305X_ESW_GSC_LED_FREQ_SHIFT);
  606. +}
  607. +
  608. +static int esw_apply_config(struct switch_dev *dev);
  609. +
  610. +static void esw_hw_init(struct rt305x_esw *esw)
  611. +{
  612. + int i;
  613. + u8 port_disable = 0;
  614. + u8 port_map = RT305X_ESW_PMAP_LLLLLL;
  615. +
  616. + /* vodoo from original driver */
  617. + esw_w32(esw, 0xC8A07850, RT305X_ESW_REG_FCT0);
  618. + esw_w32(esw, 0x00000000, RT305X_ESW_REG_SGC2);
  619. + /* Port priority 1 for all ports, vlan enabled. */
  620. + esw_w32(esw, 0x00005555 |
  621. + (RT305X_ESW_PORTS_ALL << RT305X_ESW_PFC1_EN_VLAN_S),
  622. + RT305X_ESW_REG_PFC1);
  623. +
  624. + /* Enable Back Pressure, and Flow Control */
  625. + esw_w32(esw,
  626. + ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_BP_S) |
  627. + (RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_FC_S)),
  628. + RT305X_ESW_REG_POC0);
  629. +
  630. + /* Enable Aging, and VLAN TAG removal */
  631. + esw_w32(esw,
  632. + ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC2_ENAGING_S) |
  633. + (RT305X_ESW_PORTS_NOCPU << RT305X_ESW_POC2_UNTAG_EN_S)),
  634. + RT305X_ESW_REG_POC2);
  635. +
  636. + if (esw->reg_initval_fct2)
  637. + esw_w32(esw, esw->reg_initval_fct2, RT305X_ESW_REG_FCT2);
  638. + else
  639. + esw_w32(esw, esw->pdata->reg_initval_fct2, RT305X_ESW_REG_FCT2);
  640. +
  641. + /*
  642. + * 300s aging timer, max packet len 1536, broadcast storm prevention
  643. + * disabled, disable collision abort, mac xor48 hash, 10 packet back
  644. + * pressure jam, GMII disable was_transmit, back pressure disabled,
  645. + * 30ms led flash, unmatched IGMP as broadcast, rmc tb fault to all
  646. + * ports.
  647. + */
  648. + esw_w32(esw, 0x0008a301, RT305X_ESW_REG_SGC);
  649. +
  650. + /* Setup SoC Port control register */
  651. + esw_w32(esw,
  652. + (RT305X_ESW_SOCPC_CRC_PADDING |
  653. + (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISUN2CPU_S) |
  654. + (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISMC2CPU_S) |
  655. + (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISBC2CPU_S)),
  656. + RT305X_ESW_REG_SOCPC);
  657. +
  658. + if (esw->reg_initval_fpa2)
  659. + esw_w32(esw, esw->reg_initval_fpa2, RT305X_ESW_REG_FPA2);
  660. + else
  661. + esw_w32(esw, esw->pdata->reg_initval_fpa2, RT305X_ESW_REG_FPA2);
  662. + esw_w32(esw, 0x00000000, RT305X_ESW_REG_FPA);
  663. +
  664. + /* Force Link/Activity on ports */
  665. + esw_w32(esw, 0x00000005, RT305X_ESW_REG_P0LED);
  666. + esw_w32(esw, 0x00000005, RT305X_ESW_REG_P1LED);
  667. + esw_w32(esw, 0x00000005, RT305X_ESW_REG_P2LED);
  668. + esw_w32(esw, 0x00000005, RT305X_ESW_REG_P3LED);
  669. + esw_w32(esw, 0x00000005, RT305X_ESW_REG_P4LED);
  670. +
  671. + /* Copy disabled port configuration from bootloader setup */
  672. + port_disable = esw_get_port_disable(esw);
  673. + for (i = 0; i < 6; i++)
  674. + esw->ports[i].disable = (port_disable & (1 << i)) != 0;
  675. +
  676. + if (soc_is_rt3352()) {
  677. + /* reset EPHY */
  678. + u32 val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
  679. + rt_sysc_w32(val | RT5350_RESET_EPHY, SYSC_REG_RESET_CTRL);
  680. + rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
  681. +
  682. + rt305x_mii_write(esw, 0, 31, 0x8000);
  683. + for (i = 0; i < 5; i++) {
  684. + if (esw->ports[i].disable) {
  685. + rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
  686. + } else {
  687. + rt305x_mii_write(esw, i, MII_BMCR,
  688. + BMCR_FULLDPLX |
  689. + BMCR_ANENABLE |
  690. + BMCR_SPEED100);
  691. + }
  692. + /* TX10 waveform coefficient LSB=0 disable PHY */
  693. + rt305x_mii_write(esw, i, 26, 0x1601);
  694. + /* TX100/TX10 AD/DA current bias */
  695. + rt305x_mii_write(esw, i, 29, 0x7016);
  696. + /* TX100 slew rate control */
  697. + rt305x_mii_write(esw, i, 30, 0x0038);
  698. + }
  699. +
  700. + /* select global register */
  701. + rt305x_mii_write(esw, 0, 31, 0x0);
  702. + /* enlarge agcsel threshold 3 and threshold 2 */
  703. + rt305x_mii_write(esw, 0, 1, 0x4a40);
  704. + /* enlarge agcsel threshold 5 and threshold 4 */
  705. + rt305x_mii_write(esw, 0, 2, 0x6254);
  706. + /* enlarge agcsel threshold */
  707. + rt305x_mii_write(esw, 0, 3, 0xa17f);
  708. + rt305x_mii_write(esw, 0,12, 0x7eaa);
  709. + /* longer TP_IDL tail length */
  710. + rt305x_mii_write(esw, 0, 14, 0x65);
  711. + /* increased squelch pulse count threshold. */
  712. + rt305x_mii_write(esw, 0, 16, 0x0684);
  713. + /* set TX10 signal amplitude threshold to minimum */
  714. + rt305x_mii_write(esw, 0, 17, 0x0fe0);
  715. + /* set squelch amplitude to higher threshold */
  716. + rt305x_mii_write(esw, 0, 18, 0x40ba);
  717. + /* tune TP_IDL tail and head waveform, enable power down slew rate control */
  718. + rt305x_mii_write(esw, 0, 22, 0x253f);
  719. + /* set PLL/Receive bias current are calibrated */
  720. + rt305x_mii_write(esw, 0, 27, 0x2fda);
  721. + /* change PLL/Receive bias current to internal(RT3350) */
  722. + rt305x_mii_write(esw, 0, 28, 0xc410);
  723. + /* change PLL bias current to internal(RT3052_MP3) */
  724. + rt305x_mii_write(esw, 0, 29, 0x598b);
  725. + /* select local register */
  726. + rt305x_mii_write(esw, 0, 31, 0x8000);
  727. + } else if (soc_is_rt5350()) {
  728. + /* reset EPHY */
  729. + u32 val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
  730. + rt_sysc_w32(val | RT5350_RESET_EPHY, SYSC_REG_RESET_CTRL);
  731. + rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
  732. +
  733. + /* set the led polarity */
  734. + esw_w32(esw, esw->reg_led_polarity & 0x1F, RT5350_EWS_REG_LED_POLARITY);
  735. +
  736. + /* local registers */
  737. + rt305x_mii_write(esw, 0, 31, 0x8000);
  738. + for (i = 0; i < 5; i++) {
  739. + if (esw->ports[i].disable) {
  740. + rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
  741. + } else {
  742. + rt305x_mii_write(esw, i, MII_BMCR,
  743. + BMCR_FULLDPLX |
  744. + BMCR_ANENABLE |
  745. + BMCR_SPEED100);
  746. + }
  747. + /* TX10 waveform coefficient LSB=0 disable PHY */
  748. + rt305x_mii_write(esw, i, 26, 0x1601);
  749. + /* TX100/TX10 AD/DA current bias */
  750. + rt305x_mii_write(esw, i, 29, 0x7015);
  751. + /* TX100 slew rate control */
  752. + rt305x_mii_write(esw, i, 30, 0x0038);
  753. + }
  754. +
  755. + /* global registers */
  756. + rt305x_mii_write(esw, 0, 31, 0x0);
  757. + /* enlarge agcsel threshold 3 and threshold 2 */
  758. + rt305x_mii_write(esw, 0, 1, 0x4a40);
  759. + /* enlarge agcsel threshold 5 and threshold 4 */
  760. + rt305x_mii_write(esw, 0, 2, 0x6254);
  761. + /* enlarge agcsel threshold 6 */
  762. + rt305x_mii_write(esw, 0, 3, 0xa17f);
  763. + rt305x_mii_write(esw, 0, 12, 0x7eaa);
  764. + /* longer TP_IDL tail length */
  765. + rt305x_mii_write(esw, 0, 14, 0x65);
  766. + /* increased squelch pulse count threshold. */
  767. + rt305x_mii_write(esw, 0, 16, 0x0684);
  768. + /* set TX10 signal amplitude threshold to minimum */
  769. + rt305x_mii_write(esw, 0, 17, 0x0fe0);
  770. + /* set squelch amplitude to higher threshold */
  771. + rt305x_mii_write(esw, 0, 18, 0x40ba);
  772. + /* tune TP_IDL tail and head waveform, enable power down slew rate control */
  773. + rt305x_mii_write(esw, 0, 22, 0x253f);
  774. + /* set PLL/Receive bias current are calibrated */
  775. + rt305x_mii_write(esw, 0, 27, 0x2fda);
  776. + /* change PLL/Receive bias current to internal(RT3350) */
  777. + rt305x_mii_write(esw, 0, 28, 0xc410);
  778. + /* change PLL bias current to internal(RT3052_MP3) */
  779. + rt305x_mii_write(esw, 0, 29, 0x598b);
  780. + /* select local register */
  781. + rt305x_mii_write(esw, 0, 31, 0x8000);
  782. + } else {
  783. + rt305x_mii_write(esw, 0, 31, 0x8000);
  784. + for (i = 0; i < 5; i++) {
  785. + if (esw->ports[i].disable) {
  786. + rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
  787. + } else {
  788. + rt305x_mii_write(esw, i, MII_BMCR,
  789. + BMCR_FULLDPLX |
  790. + BMCR_ANENABLE |
  791. + BMCR_SPEED100);
  792. + }
  793. + /* TX10 waveform coefficient */
  794. + rt305x_mii_write(esw, i, 26, 0x1601);
  795. + /* TX100/TX10 AD/DA current bias */
  796. + rt305x_mii_write(esw, i, 29, 0x7058);
  797. + /* TX100 slew rate control */
  798. + rt305x_mii_write(esw, i, 30, 0x0018);
  799. + }
  800. +
  801. + /* PHY IOT */
  802. + /* select global register */
  803. + rt305x_mii_write(esw, 0, 31, 0x0);
  804. + /* tune TP_IDL tail and head waveform */
  805. + rt305x_mii_write(esw, 0, 22, 0x052f);
  806. + /* set TX10 signal amplitude threshold to minimum */
  807. + rt305x_mii_write(esw, 0, 17, 0x0fe0);
  808. + /* set squelch amplitude to higher threshold */
  809. + rt305x_mii_write(esw, 0, 18, 0x40ba);
  810. + /* longer TP_IDL tail length */
  811. + rt305x_mii_write(esw, 0, 14, 0x65);
  812. + /* select local register */
  813. + rt305x_mii_write(esw, 0, 31, 0x8000);
  814. + }
  815. +
  816. + if (esw->port_map)
  817. + port_map = esw->port_map;
  818. + else
  819. + port_map = RT305X_ESW_PMAP_LLLLLL;
  820. +
  821. + /*
  822. + * Unused HW feature, but still nice to be consistent here...
  823. + * This is also exported to userspace ('lan' attribute) so it's
  824. + * conveniently usable to decide which ports go into the wan vlan by
  825. + * default.
  826. + */
  827. + esw_rmw(esw, RT305X_ESW_REG_SGC2,
  828. + RT305X_ESW_SGC2_LAN_PMAP_M << RT305X_ESW_SGC2_LAN_PMAP_S,
  829. + port_map << RT305X_ESW_SGC2_LAN_PMAP_S);
  830. +
  831. + /* make the switch leds blink */
  832. + for (i = 0; i < RT305X_ESW_NUM_LEDS; i++)
  833. + esw->ports[i].led = 0x05;
  834. +
  835. + /* Apply the empty config. */
  836. + esw_apply_config(&esw->swdev);
  837. +
  838. + /* Only unmask the port change interrupt */
  839. + esw_w32(esw, ~RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_IMR);
  840. +}
  841. +
  842. +static irqreturn_t esw_interrupt(int irq, void *_esw)
  843. +{
  844. + struct rt305x_esw *esw = (struct rt305x_esw *) _esw;
  845. + u32 status;
  846. +
  847. + status = esw_r32(esw, RT305X_ESW_REG_ISR);
  848. + if (status & RT305X_ESW_PORT_ST_CHG) {
  849. + u32 link = esw_r32(esw, RT305X_ESW_REG_POA);
  850. + link >>= RT305X_ESW_POA_LINK_SHIFT;
  851. + link &= RT305X_ESW_POA_LINK_MASK;
  852. + dev_info(esw->dev, "link changed 0x%02X\n", link);
  853. + }
  854. + esw_w32(esw, status, RT305X_ESW_REG_ISR);
  855. +
  856. + return IRQ_HANDLED;
  857. +}
  858. +
  859. +static int esw_apply_config(struct switch_dev *dev)
  860. +{
  861. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  862. + int i;
  863. + u8 disable = 0;
  864. + u8 doubletag = 0;
  865. + u8 en_vlan = 0;
  866. + u8 untag = 0;
  867. +
  868. + for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) {
  869. + u32 vid, vmsc;
  870. + if (esw->global_vlan_enable) {
  871. + vid = esw->vlans[i].vid;
  872. + vmsc = esw->vlans[i].ports;
  873. + } else {
  874. + vid = RT305X_ESW_VLAN_NONE;
  875. + vmsc = RT305X_ESW_PORTS_NONE;
  876. + }
  877. + esw_set_vlan_id(esw, i, vid);
  878. + esw_set_vmsc(esw, i, vmsc);
  879. + }
  880. +
  881. + for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) {
  882. + u32 pvid;
  883. + disable |= esw->ports[i].disable << i;
  884. + if (esw->global_vlan_enable) {
  885. + doubletag |= esw->ports[i].doubletag << i;
  886. + en_vlan |= 1 << i;
  887. + untag |= esw->ports[i].untag << i;
  888. + pvid = esw->ports[i].pvid;
  889. + } else {
  890. + int x = esw->alt_vlan_disable ? 0 : 1;
  891. + doubletag |= x << i;
  892. + en_vlan |= x << i;
  893. + untag |= x << i;
  894. + pvid = 0;
  895. + }
  896. + esw_set_pvid(esw, i, pvid);
  897. + if (i < RT305X_ESW_NUM_LEDS)
  898. + esw_w32(esw, esw->ports[i].led,
  899. + RT305X_ESW_REG_P0LED + 4*i);
  900. + }
  901. +
  902. + esw_set_gsc(esw);
  903. + esw_set_port_disable(esw, disable);
  904. + esw_rmw(esw, RT305X_ESW_REG_SGC2,
  905. + (RT305X_ESW_SGC2_DOUBLE_TAG_M <<
  906. + RT305X_ESW_SGC2_DOUBLE_TAG_S),
  907. + doubletag << RT305X_ESW_SGC2_DOUBLE_TAG_S);
  908. + esw_rmw(esw, RT305X_ESW_REG_PFC1,
  909. + RT305X_ESW_PFC1_EN_VLAN_M << RT305X_ESW_PFC1_EN_VLAN_S,
  910. + en_vlan << RT305X_ESW_PFC1_EN_VLAN_S);
  911. + esw_rmw(esw, RT305X_ESW_REG_POC2,
  912. + RT305X_ESW_POC2_UNTAG_EN_M << RT305X_ESW_POC2_UNTAG_EN_S,
  913. + untag << RT305X_ESW_POC2_UNTAG_EN_S);
  914. +
  915. + if (!esw->global_vlan_enable) {
  916. + /*
  917. + * Still need to put all ports into vlan 0 or they'll be
  918. + * isolated.
  919. + * NOTE: vlan 0 is special, no vlan tag is prepended
  920. + */
  921. + esw_set_vlan_id(esw, 0, 0);
  922. + esw_set_vmsc(esw, 0, RT305X_ESW_PORTS_ALL);
  923. + }
  924. +
  925. + return 0;
  926. +}
  927. +
  928. +static int esw_reset_switch(struct switch_dev *dev)
  929. +{
  930. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  931. +
  932. + esw->global_vlan_enable = 0;
  933. + memset(esw->ports, 0, sizeof(esw->ports));
  934. + memset(esw->vlans, 0, sizeof(esw->vlans));
  935. + esw_hw_init(esw);
  936. +
  937. + return 0;
  938. +}
  939. +
  940. +static int esw_get_vlan_enable(struct switch_dev *dev,
  941. + const struct switch_attr *attr,
  942. + struct switch_val *val)
  943. +{
  944. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  945. +
  946. + val->value.i = esw->global_vlan_enable;
  947. +
  948. + return 0;
  949. +}
  950. +
  951. +static int esw_set_vlan_enable(struct switch_dev *dev,
  952. + const struct switch_attr *attr,
  953. + struct switch_val *val)
  954. +{
  955. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  956. +
  957. + esw->global_vlan_enable = val->value.i != 0;
  958. +
  959. + return 0;
  960. +}
  961. +
  962. +static int esw_get_alt_vlan_disable(struct switch_dev *dev,
  963. + const struct switch_attr *attr,
  964. + struct switch_val *val)
  965. +{
  966. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  967. +
  968. + val->value.i = esw->alt_vlan_disable;
  969. +
  970. + return 0;
  971. +}
  972. +
  973. +static int esw_set_alt_vlan_disable(struct switch_dev *dev,
  974. + const struct switch_attr *attr,
  975. + struct switch_val *val)
  976. +{
  977. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  978. +
  979. + esw->alt_vlan_disable = val->value.i != 0;
  980. +
  981. + return 0;
  982. +}
  983. +
  984. +static int
  985. +rt305x_esw_set_bc_status(struct switch_dev *dev,
  986. + const struct switch_attr *attr,
  987. + struct switch_val *val)
  988. +{
  989. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  990. +
  991. + esw->bc_storm_protect = val->value.i & RT305X_ESW_GSC_BC_STROM_MASK;
  992. +
  993. + return 0;
  994. +}
  995. +
  996. +static int
  997. +rt305x_esw_get_bc_status(struct switch_dev *dev,
  998. + const struct switch_attr *attr,
  999. + struct switch_val *val)
  1000. +{
  1001. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1002. +
  1003. + val->value.i = esw->bc_storm_protect;
  1004. +
  1005. + return 0;
  1006. +}
  1007. +
  1008. +static int
  1009. +rt305x_esw_set_led_freq(struct switch_dev *dev,
  1010. + const struct switch_attr *attr,
  1011. + struct switch_val *val)
  1012. +{
  1013. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1014. +
  1015. + esw->led_frequency = val->value.i & RT305X_ESW_GSC_LED_FREQ_MASK;
  1016. +
  1017. + return 0;
  1018. +}
  1019. +
  1020. +static int
  1021. +rt305x_esw_get_led_freq(struct switch_dev *dev,
  1022. + const struct switch_attr *attr,
  1023. + struct switch_val *val)
  1024. +{
  1025. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1026. +
  1027. + val->value.i = esw->led_frequency;
  1028. +
  1029. + return 0;
  1030. +}
  1031. +
  1032. +static int esw_get_port_link(struct switch_dev *dev,
  1033. + int port,
  1034. + struct switch_port_link *link)
  1035. +{
  1036. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1037. + u32 speed, poa;
  1038. +
  1039. + if (port < 0 || port >= RT305X_ESW_NUM_PORTS)
  1040. + return -EINVAL;
  1041. +
  1042. + poa = esw_r32(esw, RT305X_ESW_REG_POA) >> port;
  1043. +
  1044. + link->link = (poa >> RT305X_ESW_LINK_S) & 1;
  1045. + link->duplex = (poa >> RT305X_ESW_DUPLEX_S) & 1;
  1046. + if (port < RT305X_ESW_NUM_LEDS) {
  1047. + speed = (poa >> RT305X_ESW_SPD_S) & 1;
  1048. + } else {
  1049. + if (port == RT305X_ESW_NUM_PORTS - 1)
  1050. + poa >>= 1;
  1051. + speed = (poa >> RT305X_ESW_SPD_S) & 3;
  1052. + }
  1053. + switch (speed) {
  1054. + case 0:
  1055. + link->speed = SWITCH_PORT_SPEED_10;
  1056. + break;
  1057. + case 1:
  1058. + link->speed = SWITCH_PORT_SPEED_100;
  1059. + break;
  1060. + case 2:
  1061. + case 3: /* forced gige speed can be 2 or 3 */
  1062. + link->speed = SWITCH_PORT_SPEED_1000;
  1063. + break;
  1064. + default:
  1065. + link->speed = SWITCH_PORT_SPEED_UNKNOWN;
  1066. + break;
  1067. + }
  1068. +
  1069. + return 0;
  1070. +}
  1071. +
  1072. +static int esw_get_port_bool(struct switch_dev *dev,
  1073. + const struct switch_attr *attr,
  1074. + struct switch_val *val)
  1075. +{
  1076. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1077. + int idx = val->port_vlan;
  1078. + u32 x, reg, shift;
  1079. +
  1080. + if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS)
  1081. + return -EINVAL;
  1082. +
  1083. + switch (attr->id) {
  1084. + case RT305X_ESW_ATTR_PORT_DISABLE:
  1085. + reg = RT305X_ESW_REG_POC0;
  1086. + shift = RT305X_ESW_POC0_DIS_PORT_S;
  1087. + break;
  1088. + case RT305X_ESW_ATTR_PORT_DOUBLETAG:
  1089. + reg = RT305X_ESW_REG_SGC2;
  1090. + shift = RT305X_ESW_SGC2_DOUBLE_TAG_S;
  1091. + break;
  1092. + case RT305X_ESW_ATTR_PORT_UNTAG:
  1093. + reg = RT305X_ESW_REG_POC2;
  1094. + shift = RT305X_ESW_POC2_UNTAG_EN_S;
  1095. + break;
  1096. + case RT305X_ESW_ATTR_PORT_LAN:
  1097. + reg = RT305X_ESW_REG_SGC2;
  1098. + shift = RT305X_ESW_SGC2_LAN_PMAP_S;
  1099. + if (idx >= RT305X_ESW_NUM_LANWAN)
  1100. + return -EINVAL;
  1101. + break;
  1102. + default:
  1103. + return -EINVAL;
  1104. + }
  1105. +
  1106. + x = esw_r32(esw, reg);
  1107. + val->value.i = (x >> (idx + shift)) & 1;
  1108. +
  1109. + return 0;
  1110. +}
  1111. +
  1112. +static int esw_set_port_bool(struct switch_dev *dev,
  1113. + const struct switch_attr *attr,
  1114. + struct switch_val *val)
  1115. +{
  1116. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1117. + int idx = val->port_vlan;
  1118. +
  1119. + if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS ||
  1120. + val->value.i < 0 || val->value.i > 1)
  1121. + return -EINVAL;
  1122. +
  1123. + switch (attr->id) {
  1124. + case RT305X_ESW_ATTR_PORT_DISABLE:
  1125. + esw->ports[idx].disable = val->value.i;
  1126. + break;
  1127. + case RT305X_ESW_ATTR_PORT_DOUBLETAG:
  1128. + esw->ports[idx].doubletag = val->value.i;
  1129. + break;
  1130. + case RT305X_ESW_ATTR_PORT_UNTAG:
  1131. + esw->ports[idx].untag = val->value.i;
  1132. + break;
  1133. + default:
  1134. + return -EINVAL;
  1135. + }
  1136. +
  1137. + return 0;
  1138. +}
  1139. +
  1140. +static int esw_get_port_recv_badgood(struct switch_dev *dev,
  1141. + const struct switch_attr *attr,
  1142. + struct switch_val *val)
  1143. +{
  1144. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1145. + int idx = val->port_vlan;
  1146. + int shift = attr->id == RT305X_ESW_ATTR_PORT_RECV_GOOD ? 0 : 16;
  1147. + u32 reg;
  1148. +
  1149. + if (idx < 0 || idx >= RT305X_ESW_NUM_LANWAN)
  1150. + return -EINVAL;
  1151. + reg = esw_r32(esw, RT305X_ESW_REG_PXPC(idx));
  1152. + val->value.i = (reg >> shift) & 0xffff;
  1153. +
  1154. + return 0;
  1155. +}
  1156. +
  1157. +static int
  1158. +esw_get_port_tr_badgood(struct switch_dev *dev,
  1159. + const struct switch_attr *attr,
  1160. + struct switch_val *val)
  1161. +{
  1162. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1163. +
  1164. + int idx = val->port_vlan;
  1165. + int shift = attr->id == RT5350_ESW_ATTR_PORT_TR_GOOD ? 0 : 16;
  1166. + u32 reg;
  1167. +
  1168. + if (!soc_is_rt5350())
  1169. + return -EINVAL;
  1170. +
  1171. + if (idx < 0 || idx >= RT305X_ESW_NUM_LANWAN)
  1172. + return -EINVAL;
  1173. +
  1174. + reg = esw_r32(esw, RT5350_ESW_REG_PXTPC(idx));
  1175. + val->value.i = (reg >> shift) & 0xffff;
  1176. +
  1177. + return 0;
  1178. +}
  1179. +
  1180. +static int esw_get_port_led(struct switch_dev *dev,
  1181. + const struct switch_attr *attr,
  1182. + struct switch_val *val)
  1183. +{
  1184. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1185. + int idx = val->port_vlan;
  1186. +
  1187. + if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS ||
  1188. + idx >= RT305X_ESW_NUM_LEDS)
  1189. + return -EINVAL;
  1190. +
  1191. + val->value.i = esw_r32(esw, RT305X_ESW_REG_P0LED + 4*idx);
  1192. +
  1193. + return 0;
  1194. +}
  1195. +
  1196. +static int esw_set_port_led(struct switch_dev *dev,
  1197. + const struct switch_attr *attr,
  1198. + struct switch_val *val)
  1199. +{
  1200. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1201. + int idx = val->port_vlan;
  1202. +
  1203. + if (idx < 0 || idx >= RT305X_ESW_NUM_LEDS)
  1204. + return -EINVAL;
  1205. +
  1206. + esw->ports[idx].led = val->value.i;
  1207. +
  1208. + return 0;
  1209. +}
  1210. +
  1211. +static int esw_get_port_pvid(struct switch_dev *dev, int port, int *val)
  1212. +{
  1213. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1214. +
  1215. + if (port >= RT305X_ESW_NUM_PORTS)
  1216. + return -EINVAL;
  1217. +
  1218. + *val = esw_get_pvid(esw, port);
  1219. +
  1220. + return 0;
  1221. +}
  1222. +
  1223. +static int esw_set_port_pvid(struct switch_dev *dev, int port, int val)
  1224. +{
  1225. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1226. +
  1227. + if (port >= RT305X_ESW_NUM_PORTS)
  1228. + return -EINVAL;
  1229. +
  1230. + esw->ports[port].pvid = val;
  1231. +
  1232. + return 0;
  1233. +}
  1234. +
  1235. +static int esw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
  1236. +{
  1237. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1238. + u32 vmsc, poc2;
  1239. + int vlan_idx = -1;
  1240. + int i;
  1241. +
  1242. + val->len = 0;
  1243. +
  1244. + if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS)
  1245. + return -EINVAL;
  1246. +
  1247. + /* valid vlan? */
  1248. + for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) {
  1249. + if (esw_get_vlan_id(esw, i) == val->port_vlan &&
  1250. + esw_get_vmsc(esw, i) != RT305X_ESW_PORTS_NONE) {
  1251. + vlan_idx = i;
  1252. + break;
  1253. + }
  1254. + }
  1255. +
  1256. + if (vlan_idx == -1)
  1257. + return -EINVAL;
  1258. +
  1259. + vmsc = esw_get_vmsc(esw, vlan_idx);
  1260. + poc2 = esw_r32(esw, RT305X_ESW_REG_POC2);
  1261. +
  1262. + for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) {
  1263. + struct switch_port *p;
  1264. + int port_mask = 1 << i;
  1265. +
  1266. + if (!(vmsc & port_mask))
  1267. + continue;
  1268. +
  1269. + p = &val->value.ports[val->len++];
  1270. + p->id = i;
  1271. + if (poc2 & (port_mask << RT305X_ESW_POC2_UNTAG_EN_S))
  1272. + p->flags = 0;
  1273. + else
  1274. + p->flags = 1 << SWITCH_PORT_FLAG_TAGGED;
  1275. + }
  1276. +
  1277. + return 0;
  1278. +}
  1279. +
  1280. +static int esw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
  1281. +{
  1282. + struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
  1283. + int ports;
  1284. + int vlan_idx = -1;
  1285. + int i;
  1286. +
  1287. + if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS ||
  1288. + val->len > RT305X_ESW_NUM_PORTS)
  1289. + return -EINVAL;
  1290. +
  1291. + /* one of the already defined vlans? */
  1292. + for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) {
  1293. + if (esw->vlans[i].vid == val->port_vlan &&
  1294. + esw->vlans[i].ports != RT305X_ESW_PORTS_NONE) {
  1295. + vlan_idx = i;
  1296. + break;
  1297. + }
  1298. + }
  1299. +
  1300. + /* select a free slot */
  1301. + for (i = 0; vlan_idx == -1 && i < RT305X_ESW_NUM_VLANS; i++) {
  1302. + if (esw->vlans[i].ports == RT305X_ESW_PORTS_NONE)
  1303. + vlan_idx = i;
  1304. + }
  1305. +
  1306. + /* bail if all slots are in use */
  1307. + if (vlan_idx == -1)
  1308. + return -EINVAL;
  1309. +
  1310. + ports = RT305X_ESW_PORTS_NONE;
  1311. + for (i = 0; i < val->len; i++) {
  1312. + struct switch_port *p = &val->value.ports[i];
  1313. + int port_mask = 1 << p->id;
  1314. + bool untagged = !(p->flags & (1 << SWITCH_PORT_FLAG_TAGGED));
  1315. +
  1316. + if (p->id >= RT305X_ESW_NUM_PORTS)
  1317. + return -EINVAL;
  1318. +
  1319. + ports |= port_mask;
  1320. + esw->ports[p->id].untag = untagged;
  1321. + }
  1322. + esw->vlans[vlan_idx].ports = ports;
  1323. + if (ports == RT305X_ESW_PORTS_NONE)
  1324. + esw->vlans[vlan_idx].vid = RT305X_ESW_VLAN_NONE;
  1325. + else
  1326. + esw->vlans[vlan_idx].vid = val->port_vlan;
  1327. +
  1328. + return 0;
  1329. +}
  1330. +
  1331. +static const struct switch_attr esw_global[] = {
  1332. + {
  1333. + .type = SWITCH_TYPE_INT,
  1334. + .name = "enable_vlan",
  1335. + .description = "VLAN mode (1:enabled)",
  1336. + .max = 1,
  1337. + .id = RT305X_ESW_ATTR_ENABLE_VLAN,
  1338. + .get = esw_get_vlan_enable,
  1339. + .set = esw_set_vlan_enable,
  1340. + },
  1341. + {
  1342. + .type = SWITCH_TYPE_INT,
  1343. + .name = "alternate_vlan_disable",
  1344. + .description = "Use en_vlan instead of doubletag to disable"
  1345. + " VLAN mode",
  1346. + .max = 1,
  1347. + .id = RT305X_ESW_ATTR_ALT_VLAN_DISABLE,
  1348. + .get = esw_get_alt_vlan_disable,
  1349. + .set = esw_set_alt_vlan_disable,
  1350. + },
  1351. + {
  1352. + .type = SWITCH_TYPE_INT,
  1353. + .name = "bc_storm_protect",
  1354. + .description = "Global broadcast storm protection (0:Disable, 1:64 blocks, 2:96 blocks, 3:128 blocks)",
  1355. + .max = 3,
  1356. + .id = RT305X_ESW_ATTR_BC_STATUS,
  1357. + .get = rt305x_esw_get_bc_status,
  1358. + .set = rt305x_esw_set_bc_status,
  1359. + },
  1360. + {
  1361. + .type = SWITCH_TYPE_INT,
  1362. + .name = "led_frequency",
  1363. + .description = "LED Flash frequency (0:30mS, 1:60mS, 2:240mS, 3:480mS)",
  1364. + .max = 3,
  1365. + .id = RT305X_ESW_ATTR_LED_FREQ,
  1366. + .get = rt305x_esw_get_led_freq,
  1367. + .set = rt305x_esw_set_led_freq,
  1368. + }
  1369. +};
  1370. +
  1371. +static const struct switch_attr esw_port[] = {
  1372. + {
  1373. + .type = SWITCH_TYPE_INT,
  1374. + .name = "disable",
  1375. + .description = "Port state (1:disabled)",
  1376. + .max = 1,
  1377. + .id = RT305X_ESW_ATTR_PORT_DISABLE,
  1378. + .get = esw_get_port_bool,
  1379. + .set = esw_set_port_bool,
  1380. + },
  1381. + {
  1382. + .type = SWITCH_TYPE_INT,
  1383. + .name = "doubletag",
  1384. + .description = "Double tagging for incoming vlan packets "
  1385. + "(1:enabled)",
  1386. + .max = 1,
  1387. + .id = RT305X_ESW_ATTR_PORT_DOUBLETAG,
  1388. + .get = esw_get_port_bool,
  1389. + .set = esw_set_port_bool,
  1390. + },
  1391. + {
  1392. + .type = SWITCH_TYPE_INT,
  1393. + .name = "untag",
  1394. + .description = "Untag (1:strip outgoing vlan tag)",
  1395. + .max = 1,
  1396. + .id = RT305X_ESW_ATTR_PORT_UNTAG,
  1397. + .get = esw_get_port_bool,
  1398. + .set = esw_set_port_bool,
  1399. + },
  1400. + {
  1401. + .type = SWITCH_TYPE_INT,
  1402. + .name = "led",
  1403. + .description = "LED mode (0:link, 1:100m, 2:duplex, 3:activity,"
  1404. + " 4:collision, 5:linkact, 6:duplcoll, 7:10mact,"
  1405. + " 8:100mact, 10:blink, 11:off, 12:on)",
  1406. + .max = 15,
  1407. + .id = RT305X_ESW_ATTR_PORT_LED,
  1408. + .get = esw_get_port_led,
  1409. + .set = esw_set_port_led,
  1410. + },
  1411. + {
  1412. + .type = SWITCH_TYPE_INT,
  1413. + .name = "lan",
  1414. + .description = "HW port group (0:wan, 1:lan)",
  1415. + .max = 1,
  1416. + .id = RT305X_ESW_ATTR_PORT_LAN,
  1417. + .get = esw_get_port_bool,
  1418. + },
  1419. + {
  1420. + .type = SWITCH_TYPE_INT,
  1421. + .name = "recv_bad",
  1422. + .description = "Receive bad packet counter",
  1423. + .id = RT305X_ESW_ATTR_PORT_RECV_BAD,
  1424. + .get = esw_get_port_recv_badgood,
  1425. + },
  1426. + {
  1427. + .type = SWITCH_TYPE_INT,
  1428. + .name = "recv_good",
  1429. + .description = "Receive good packet counter",
  1430. + .id = RT305X_ESW_ATTR_PORT_RECV_GOOD,
  1431. + .get = esw_get_port_recv_badgood,
  1432. + },
  1433. + {
  1434. + .type = SWITCH_TYPE_INT,
  1435. + .name = "tr_bad",
  1436. +
  1437. + .description = "Transmit bad packet counter. rt5350 only",
  1438. + .id = RT5350_ESW_ATTR_PORT_TR_BAD,
  1439. + .get = esw_get_port_tr_badgood,
  1440. + },
  1441. + {
  1442. + .type = SWITCH_TYPE_INT,
  1443. + .name = "tr_good",
  1444. +
  1445. + .description = "Transmit good packet counter. rt5350 only",
  1446. + .id = RT5350_ESW_ATTR_PORT_TR_GOOD,
  1447. + .get = esw_get_port_tr_badgood,
  1448. + },
  1449. +};
  1450. +
  1451. +static const struct switch_attr esw_vlan[] = {
  1452. +};
  1453. +
  1454. +static const struct switch_dev_ops esw_ops = {
  1455. + .attr_global = {
  1456. + .attr = esw_global,
  1457. + .n_attr = ARRAY_SIZE(esw_global),
  1458. + },
  1459. + .attr_port = {
  1460. + .attr = esw_port,
  1461. + .n_attr = ARRAY_SIZE(esw_port),
  1462. + },
  1463. + .attr_vlan = {
  1464. + .attr = esw_vlan,
  1465. + .n_attr = ARRAY_SIZE(esw_vlan),
  1466. + },
  1467. + .get_vlan_ports = esw_get_vlan_ports,
  1468. + .set_vlan_ports = esw_set_vlan_ports,
  1469. + .get_port_pvid = esw_get_port_pvid,
  1470. + .set_port_pvid = esw_set_port_pvid,
  1471. + .get_port_link = esw_get_port_link,
  1472. + .apply_config = esw_apply_config,
  1473. + .reset_switch = esw_reset_switch,
  1474. +};
  1475. +
  1476. +static struct rt305x_esw_platform_data rt3050_esw_data = {
  1477. + /* All ports are LAN ports. */
  1478. + .vlan_config = RT305X_ESW_VLAN_CONFIG_NONE,
  1479. + .reg_initval_fct2 = 0x00d6500c,
  1480. + /*
  1481. + * ext phy base addr 31, enable port 5 polling, rx/tx clock skew 1,
  1482. + * turbo mii off, rgmi 3.3v off
  1483. + * port5: disabled
  1484. + * port6: enabled, gige, full-duplex, rx/tx-flow-control
  1485. + */
  1486. + .reg_initval_fpa2 = 0x3f502b28,
  1487. +};
  1488. +
  1489. +static const struct of_device_id ralink_esw_match[] = {
  1490. + { .compatible = "ralink,rt3050-esw", .data = &rt3050_esw_data },
  1491. + {},
  1492. +};
  1493. +MODULE_DEVICE_TABLE(of, ralink_esw_match);
  1494. +
  1495. +static int esw_probe(struct platform_device *pdev)
  1496. +{
  1497. + struct device_node *np = pdev->dev.of_node;
  1498. + const struct rt305x_esw_platform_data *pdata;
  1499. + const __be32 *port_map, *reg_init;
  1500. + struct rt305x_esw *esw;
  1501. + struct switch_dev *swdev;
  1502. + struct resource *res, *irq;
  1503. + int err;
  1504. +
  1505. + pdata = pdev->dev.platform_data;
  1506. + if (!pdata) {
  1507. + const struct of_device_id *match;
  1508. + match = of_match_device(ralink_esw_match, &pdev->dev);
  1509. + if (match)
  1510. + pdata = (struct rt305x_esw_platform_data *) match->data;
  1511. + }
  1512. + if (!pdata)
  1513. + return -EINVAL;
  1514. +
  1515. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1516. + if (!res) {
  1517. + dev_err(&pdev->dev, "no memory resource found\n");
  1518. + return -ENOMEM;
  1519. + }
  1520. +
  1521. + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  1522. + if (!irq) {
  1523. + dev_err(&pdev->dev, "no irq resource found\n");
  1524. + return -ENOMEM;
  1525. + }
  1526. +
  1527. + esw = kzalloc(sizeof(struct rt305x_esw), GFP_KERNEL);
  1528. + if (!esw) {
  1529. + dev_err(&pdev->dev, "no memory for private data\n");
  1530. + return -ENOMEM;
  1531. + }
  1532. +
  1533. + esw->dev = &pdev->dev;
  1534. + esw->irq = irq->start;
  1535. + esw->base = ioremap(res->start, resource_size(res));
  1536. + if (!esw->base) {
  1537. + dev_err(&pdev->dev, "ioremap failed\n");
  1538. + err = -ENOMEM;
  1539. + goto free_esw;
  1540. + }
  1541. +
  1542. + port_map = of_get_property(np, "ralink,portmap", NULL);
  1543. + if (port_map)
  1544. + esw->port_map = be32_to_cpu(*port_map);
  1545. +
  1546. + reg_init = of_get_property(np, "ralink,fct2", NULL);
  1547. + if (reg_init)
  1548. + esw->reg_initval_fct2 = be32_to_cpu(*reg_init);
  1549. +
  1550. + reg_init = of_get_property(np, "ralink,fpa2", NULL);
  1551. + if (reg_init)
  1552. + esw->reg_initval_fpa2 = be32_to_cpu(*reg_init);
  1553. +
  1554. + reg_init = of_get_property(np, "ralink,led_polarity", NULL);
  1555. + if (reg_init)
  1556. + esw->reg_led_polarity = be32_to_cpu(*reg_init);
  1557. +
  1558. + swdev = &esw->swdev;
  1559. + swdev->of_node = pdev->dev.of_node;
  1560. + swdev->name = "rt305x-esw";
  1561. + swdev->alias = "rt305x";
  1562. + swdev->cpu_port = RT305X_ESW_PORT6;
  1563. + swdev->ports = RT305X_ESW_NUM_PORTS;
  1564. + swdev->vlans = RT305X_ESW_NUM_VIDS;
  1565. + swdev->ops = &esw_ops;
  1566. +
  1567. + err = register_switch(swdev, NULL);
  1568. + if (err < 0) {
  1569. + dev_err(&pdev->dev, "register_switch failed\n");
  1570. + goto unmap_base;
  1571. + }
  1572. +
  1573. + platform_set_drvdata(pdev, esw);
  1574. +
  1575. + esw->pdata = pdata;
  1576. + spin_lock_init(&esw->reg_rw_lock);
  1577. +
  1578. + esw_hw_init(esw);
  1579. +
  1580. + esw_w32(esw, RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_ISR);
  1581. + esw_w32(esw, ~RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_IMR);
  1582. + request_irq(esw->irq, esw_interrupt, 0, "esw", esw);
  1583. +
  1584. + return 0;
  1585. +
  1586. +unmap_base:
  1587. + iounmap(esw->base);
  1588. +free_esw:
  1589. + kfree(esw);
  1590. + return err;
  1591. +}
  1592. +
  1593. +static int esw_remove(struct platform_device *pdev)
  1594. +{
  1595. + struct rt305x_esw *esw;
  1596. +
  1597. + esw = platform_get_drvdata(pdev);
  1598. + if (esw) {
  1599. + unregister_switch(&esw->swdev);
  1600. + platform_set_drvdata(pdev, NULL);
  1601. + iounmap(esw->base);
  1602. + kfree(esw);
  1603. + }
  1604. +
  1605. + return 0;
  1606. +}
  1607. +
  1608. +static struct platform_driver esw_driver = {
  1609. + .probe = esw_probe,
  1610. + .remove = esw_remove,
  1611. + .driver = {
  1612. + .name = "rt305x-esw",
  1613. + .owner = THIS_MODULE,
  1614. + .of_match_table = ralink_esw_match,
  1615. + },
  1616. +};
  1617. +
  1618. +int __init rtesw_init(void)
  1619. +{
  1620. + return platform_driver_register(&esw_driver);
  1621. +}
  1622. +
  1623. +void rtesw_exit(void)
  1624. +{
  1625. + platform_driver_unregister(&esw_driver);
  1626. +}
  1627. --- /dev/null
  1628. +++ b/drivers/net/ethernet/ralink/esw_rt3052.h
  1629. @@ -0,0 +1,32 @@
  1630. +/*
  1631. + * This program is free software; you can redistribute it and/or modify
  1632. + * it under the terms of the GNU General Public License as published by
  1633. + * the Free Software Foundation; version 2 of the License
  1634. + *
  1635. + * This program is distributed in the hope that it will be useful,
  1636. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1637. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1638. + * GNU General Public License for more details.
  1639. + *
  1640. + * You should have received a copy of the GNU General Public License
  1641. + * along with this program; if not, write to the Free Software
  1642. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  1643. + *
  1644. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  1645. + */
  1646. +
  1647. +#ifndef _RALINK_ESW_RT3052_H__
  1648. +#define _RALINK_ESW_RT3052_H__
  1649. +
  1650. +#ifdef CONFIG_NET_RALINK_ESW_RT3052
  1651. +
  1652. +int __init rtesw_init(void);
  1653. +void rtesw_exit(void);
  1654. +
  1655. +#else
  1656. +
  1657. +static inline int __init rtesw_init(void) { return 0; }
  1658. +static inline void rtesw_exit(void) { }
  1659. +
  1660. +#endif
  1661. +#endif
  1662. --- /dev/null
  1663. +++ b/drivers/net/ethernet/ralink/gsw_mt7620a.c
  1664. @@ -0,0 +1,566 @@
  1665. +/*
  1666. + * This program is free software; you can redistribute it and/or modify
  1667. + * it under the terms of the GNU General Public License as published by
  1668. + * the Free Software Foundation; version 2 of the License
  1669. + *
  1670. + * This program is distributed in the hope that it will be useful,
  1671. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1672. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1673. + * GNU General Public License for more details.
  1674. + *
  1675. + * You should have received a copy of the GNU General Public License
  1676. + * along with this program; if not, write to the Free Software
  1677. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  1678. + *
  1679. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  1680. + */
  1681. +
  1682. +#include <linux/module.h>
  1683. +#include <linux/kernel.h>
  1684. +#include <linux/types.h>
  1685. +#include <linux/dma-mapping.h>
  1686. +#include <linux/init.h>
  1687. +#include <linux/skbuff.h>
  1688. +#include <linux/etherdevice.h>
  1689. +#include <linux/ethtool.h>
  1690. +#include <linux/platform_device.h>
  1691. +#include <linux/of_device.h>
  1692. +#include <linux/clk.h>
  1693. +#include <linux/of_net.h>
  1694. +#include <linux/of_mdio.h>
  1695. +#include <linux/of_irq.h>
  1696. +#include <linux/of_address.h>
  1697. +#include <linux/switch.h>
  1698. +
  1699. +#include <asm/mach-ralink/ralink_regs.h>
  1700. +
  1701. +#include "ralink_soc_eth.h"
  1702. +
  1703. +#include <linux/ioport.h>
  1704. +#include <linux/switch.h>
  1705. +#include <linux/mii.h>
  1706. +
  1707. +#include <ralink_regs.h>
  1708. +#include <asm/mach-ralink/mt7620.h>
  1709. +
  1710. +#include "ralink_soc_eth.h"
  1711. +#include "gsw_mt7620a.h"
  1712. +#include "mt7530.h"
  1713. +#include "mdio.h"
  1714. +
  1715. +#define GSW_REG_PHY_TIMEOUT (5 * HZ)
  1716. +
  1717. +#define MT7620A_GSW_REG_PIAC 0x7004
  1718. +
  1719. +#define GSW_NUM_VLANS 16
  1720. +#define GSW_NUM_VIDS 4096
  1721. +#define GSW_NUM_PORTS 7
  1722. +#define GSW_PORT6 6
  1723. +
  1724. +#define GSW_MDIO_ACCESS BIT(31)
  1725. +#define GSW_MDIO_READ BIT(19)
  1726. +#define GSW_MDIO_WRITE BIT(18)
  1727. +#define GSW_MDIO_START BIT(16)
  1728. +#define GSW_MDIO_ADDR_SHIFT 20
  1729. +#define GSW_MDIO_REG_SHIFT 25
  1730. +
  1731. +#define GSW_REG_PORT_PMCR(x) (0x3000 + (x * 0x100))
  1732. +#define GSW_REG_PORT_STATUS(x) (0x3008 + (x * 0x100))
  1733. +#define GSW_REG_SMACCR0 0x3fE4
  1734. +#define GSW_REG_SMACCR1 0x3fE8
  1735. +#define GSW_REG_CKGCR 0x3ff0
  1736. +
  1737. +#define GSW_REG_IMR 0x7008
  1738. +#define GSW_REG_ISR 0x700c
  1739. +
  1740. +#define SYSC_REG_CFG1 0x14
  1741. +
  1742. +#define PORT_IRQ_ST_CHG 0x7f
  1743. +
  1744. +#define SYSCFG1 0x14
  1745. +
  1746. +#define ESW_PHY_POLLING 0x7000
  1747. +
  1748. +#define PMCR_IPG BIT(18)
  1749. +#define PMCR_MAC_MODE BIT(16)
  1750. +#define PMCR_FORCE BIT(15)
  1751. +#define PMCR_TX_EN BIT(14)
  1752. +#define PMCR_RX_EN BIT(13)
  1753. +#define PMCR_BACKOFF BIT(9)
  1754. +#define PMCR_BACKPRES BIT(8)
  1755. +#define PMCR_RX_FC BIT(5)
  1756. +#define PMCR_TX_FC BIT(4)
  1757. +#define PMCR_SPEED(_x) (_x << 2)
  1758. +#define PMCR_DUPLEX BIT(1)
  1759. +#define PMCR_LINK BIT(0)
  1760. +
  1761. +#define PHY_AN_EN BIT(31)
  1762. +#define PHY_PRE_EN BIT(30)
  1763. +#define PMY_MDC_CONF(_x) ((_x & 0x3f) << 24)
  1764. +
  1765. +enum {
  1766. + /* Global attributes. */
  1767. + GSW_ATTR_ENABLE_VLAN,
  1768. + /* Port attributes. */
  1769. + GSW_ATTR_PORT_UNTAG,
  1770. +};
  1771. +
  1772. +enum {
  1773. + PORT4_EPHY = 0,
  1774. + PORT4_EXT,
  1775. +};
  1776. +
  1777. +struct mt7620_gsw {
  1778. + struct device *dev;
  1779. + void __iomem *base;
  1780. + int irq;
  1781. + int port4;
  1782. + long unsigned int autopoll;
  1783. +};
  1784. +
  1785. +static inline void gsw_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg)
  1786. +{
  1787. + iowrite32(val, gsw->base + reg);
  1788. +}
  1789. +
  1790. +static inline u32 gsw_r32(struct mt7620_gsw *gsw, unsigned reg)
  1791. +{
  1792. + return ioread32(gsw->base + reg);
  1793. +}
  1794. +
  1795. +static int mt7620_mii_busy_wait(struct mt7620_gsw *gsw)
  1796. +{
  1797. + unsigned long t_start = jiffies;
  1798. +
  1799. + while (1) {
  1800. + if (!(gsw_r32(gsw, MT7620A_GSW_REG_PIAC) & GSW_MDIO_ACCESS))
  1801. + return 0;
  1802. + if (time_after(jiffies, t_start + GSW_REG_PHY_TIMEOUT)) {
  1803. + break;
  1804. + }
  1805. + }
  1806. +
  1807. + printk(KERN_ERR "mdio: MDIO timeout\n");
  1808. + return -1;
  1809. +}
  1810. +
  1811. +static u32 _mt7620_mii_write(struct mt7620_gsw *gsw, u32 phy_addr, u32 phy_register,
  1812. + u32 write_data)
  1813. +{
  1814. + if (mt7620_mii_busy_wait(gsw))
  1815. + return -1;
  1816. +
  1817. + write_data &= 0xffff;
  1818. +
  1819. + gsw_w32(gsw, GSW_MDIO_ACCESS | GSW_MDIO_START | GSW_MDIO_WRITE |
  1820. + (phy_register << GSW_MDIO_REG_SHIFT) |
  1821. + (phy_addr << GSW_MDIO_ADDR_SHIFT) | write_data,
  1822. + MT7620A_GSW_REG_PIAC);
  1823. +
  1824. + if (mt7620_mii_busy_wait(gsw))
  1825. + return -1;
  1826. +
  1827. + return 0;
  1828. +}
  1829. +
  1830. +static u32 _mt7620_mii_read(struct mt7620_gsw *gsw, int phy_addr, int phy_reg)
  1831. +{
  1832. + u32 d;
  1833. +
  1834. + if (mt7620_mii_busy_wait(gsw))
  1835. + return 0xffff;
  1836. +
  1837. + gsw_w32(gsw, GSW_MDIO_ACCESS | GSW_MDIO_START | GSW_MDIO_READ |
  1838. + (phy_reg << GSW_MDIO_REG_SHIFT) |
  1839. + (phy_addr << GSW_MDIO_ADDR_SHIFT),
  1840. + MT7620A_GSW_REG_PIAC);
  1841. +
  1842. + if (mt7620_mii_busy_wait(gsw))
  1843. + return 0xffff;
  1844. +
  1845. + d = gsw_r32(gsw, MT7620A_GSW_REG_PIAC) & 0xffff;
  1846. +
  1847. + return d;
  1848. +}
  1849. +
  1850. +int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val)
  1851. +{
  1852. + struct fe_priv *priv = bus->priv;
  1853. + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
  1854. +
  1855. + return _mt7620_mii_write(gsw, phy_addr, phy_reg, val);
  1856. +}
  1857. +
  1858. +int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
  1859. +{
  1860. + struct fe_priv *priv = bus->priv;
  1861. + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
  1862. +
  1863. + return _mt7620_mii_read(gsw, phy_addr, phy_reg);
  1864. +}
  1865. +
  1866. +static unsigned char *fe_speed_str(int speed)
  1867. +{
  1868. + switch (speed) {
  1869. + case 2:
  1870. + case SPEED_1000:
  1871. + return "1000";
  1872. + case 1:
  1873. + case SPEED_100:
  1874. + return "100";
  1875. + case 0:
  1876. + case SPEED_10:
  1877. + return "10";
  1878. + }
  1879. +
  1880. + return "? ";
  1881. +}
  1882. +
  1883. +int mt7620a_has_carrier(struct fe_priv *priv)
  1884. +{
  1885. + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
  1886. + int i;
  1887. +
  1888. + for (i = 0; i < GSW_PORT6; i++)
  1889. + if (gsw_r32(gsw, GSW_REG_PORT_STATUS(i)) & 0x1)
  1890. + return 1;
  1891. + return 0;
  1892. +}
  1893. +
  1894. +static void mt7620a_handle_carrier(struct fe_priv *priv)
  1895. +{
  1896. + if (!priv->phy)
  1897. + return;
  1898. +
  1899. + if (mt7620a_has_carrier(priv))
  1900. + netif_carrier_on(priv->netdev);
  1901. + else
  1902. + netif_carrier_off(priv->netdev);
  1903. +}
  1904. +
  1905. +void mt7620_mdio_link_adjust(struct fe_priv *priv, int port)
  1906. +{
  1907. + if (priv->link[port])
  1908. + netdev_info(priv->netdev, "port %d link up (%sMbps/%s duplex)\n",
  1909. + port, fe_speed_str(priv->phy->speed[port]),
  1910. + (DUPLEX_FULL == priv->phy->duplex[port]) ? "Full" : "Half");
  1911. + else
  1912. + netdev_info(priv->netdev, "port %d link down\n", port);
  1913. + mt7620a_handle_carrier(priv);
  1914. +}
  1915. +
  1916. +static irqreturn_t gsw_interrupt(int irq, void *_priv)
  1917. +{
  1918. + struct fe_priv *priv = (struct fe_priv *) _priv;
  1919. + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
  1920. + u32 status;
  1921. + int i, max = (gsw->port4 == PORT4_EPHY) ? (4) : (3);
  1922. +
  1923. + status = gsw_r32(gsw, GSW_REG_ISR);
  1924. + if (status & PORT_IRQ_ST_CHG)
  1925. + for (i = 0; i <= max; i++) {
  1926. + u32 status = gsw_r32(gsw, GSW_REG_PORT_STATUS(i));
  1927. + int link = status & 0x1;
  1928. +
  1929. + if (link != priv->link[i]) {
  1930. + if (link)
  1931. + netdev_info(priv->netdev, "port %d link up (%sMbps/%s duplex)\n",
  1932. + i, fe_speed_str((status >> 2) & 3),
  1933. + (status & 0x2) ? "Full" : "Half");
  1934. + else
  1935. + netdev_info(priv->netdev, "port %d link down\n", i);
  1936. + }
  1937. +
  1938. + priv->link[i] = link;
  1939. + }
  1940. + mt7620a_handle_carrier(priv);
  1941. +
  1942. + gsw_w32(gsw, status, GSW_REG_ISR);
  1943. +
  1944. + return IRQ_HANDLED;
  1945. +}
  1946. +
  1947. +static int mt7620_is_bga(void)
  1948. +{
  1949. + u32 bga = rt_sysc_r32(0x0c);
  1950. +
  1951. + return (bga >> 16) & 1;
  1952. +}
  1953. +
  1954. +static void gsw_auto_poll(struct mt7620_gsw *gsw)
  1955. +{
  1956. + int phy;
  1957. + int lsb = -1, msb = 0;
  1958. +
  1959. + for_each_set_bit(phy, &gsw->autopoll, 32) {
  1960. + if (lsb < 0)
  1961. + lsb = phy;
  1962. + msb = phy;
  1963. + }
  1964. +
  1965. + gsw_w32(gsw, PHY_AN_EN | PHY_PRE_EN | PMY_MDC_CONF(5) | (msb << 8) | lsb, ESW_PHY_POLLING);
  1966. +}
  1967. +
  1968. +void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
  1969. +{
  1970. + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
  1971. + const __be32 *_id = of_get_property(np, "reg", NULL);
  1972. + int phy_mode, size, id;
  1973. + int shift = 12;
  1974. + u32 val, mask = 0;
  1975. + int min = (gsw->port4 == PORT4_EPHY) ? (5) : (4);
  1976. +
  1977. + if (!_id || (be32_to_cpu(*_id) < min) || (be32_to_cpu(*_id) > 5)) {
  1978. + if (_id)
  1979. + pr_err("%s: invalid port id %d\n", np->name, be32_to_cpu(*_id));
  1980. + else
  1981. + pr_err("%s: invalid port id\n", np->name);
  1982. + return;
  1983. + }
  1984. +
  1985. + id = be32_to_cpu(*_id);
  1986. +
  1987. + if (id == 4)
  1988. + shift = 14;
  1989. +
  1990. + priv->phy->phy_fixed[id] = of_get_property(np, "ralink,fixed-link", &size);
  1991. + if (priv->phy->phy_fixed[id] && (size != (4 * sizeof(*priv->phy->phy_fixed[id])))) {
  1992. + pr_err("%s: invalid fixed link property\n", np->name);
  1993. + priv->phy->phy_fixed[id] = NULL;
  1994. + return;
  1995. + }
  1996. +
  1997. + phy_mode = of_get_phy_mode(np);
  1998. + switch (phy_mode) {
  1999. + case PHY_INTERFACE_MODE_RGMII:
  2000. + mask = 0;
  2001. + break;
  2002. + case PHY_INTERFACE_MODE_MII:
  2003. + mask = 1;
  2004. + break;
  2005. + case PHY_INTERFACE_MODE_RMII:
  2006. + mask = 2;
  2007. + break;
  2008. + default:
  2009. + dev_err(priv->device, "port %d - invalid phy mode\n", id);
  2010. + return;
  2011. + }
  2012. +
  2013. + priv->phy->phy_node[id] = of_parse_phandle(np, "phy-handle", 0);
  2014. + if (!priv->phy->phy_node[id] && !priv->phy->phy_fixed[id])
  2015. + return;
  2016. +
  2017. + val = rt_sysc_r32(SYSCFG1);
  2018. + val &= ~(3 << shift);
  2019. + val |= mask << shift;
  2020. + rt_sysc_w32(val, SYSCFG1);
  2021. +
  2022. + if (priv->phy->phy_fixed[id]) {
  2023. + const __be32 *link = priv->phy->phy_fixed[id];
  2024. + int tx_fc, rx_fc;
  2025. + u32 val = 0;
  2026. +
  2027. + priv->phy->speed[id] = be32_to_cpup(link++);
  2028. + tx_fc = be32_to_cpup(link++);
  2029. + rx_fc = be32_to_cpup(link++);
  2030. + priv->phy->duplex[id] = be32_to_cpup(link++);
  2031. + priv->link[id] = 1;
  2032. +
  2033. + switch (priv->phy->speed[id]) {
  2034. + case SPEED_10:
  2035. + val = 0;
  2036. + break;
  2037. + case SPEED_100:
  2038. + val = 1;
  2039. + break;
  2040. + case SPEED_1000:
  2041. + val = 2;
  2042. + break;
  2043. + default:
  2044. + dev_err(priv->device, "invalid link speed: %d\n", priv->phy->speed[id]);
  2045. + priv->phy->phy_fixed[id] = 0;
  2046. + return;
  2047. + }
  2048. + val = PMCR_SPEED(val);
  2049. + val |= PMCR_LINK | PMCR_BACKPRES | PMCR_BACKOFF | PMCR_RX_EN |
  2050. + PMCR_TX_EN | PMCR_FORCE | PMCR_MAC_MODE | PMCR_IPG;
  2051. + if (tx_fc)
  2052. + val |= PMCR_TX_FC;
  2053. + if (rx_fc)
  2054. + val |= PMCR_RX_FC;
  2055. + if (priv->phy->duplex[id])
  2056. + val |= PMCR_DUPLEX;
  2057. + gsw_w32(gsw, val, GSW_REG_PORT_PMCR(id));
  2058. + dev_info(priv->device, "using fixed link parameters\n");
  2059. + return;
  2060. + }
  2061. +
  2062. + if (priv->phy->phy_node[id] && priv->mii_bus->phy_map[id]) {
  2063. + u32 val = PMCR_BACKPRES | PMCR_BACKOFF | PMCR_RX_EN |
  2064. + PMCR_TX_EN | PMCR_MAC_MODE | PMCR_IPG;
  2065. +
  2066. + gsw_w32(gsw, val, GSW_REG_PORT_PMCR(id));
  2067. + fe_connect_phy_node(priv, priv->phy->phy_node[id]);
  2068. + gsw->autopoll |= BIT(id);
  2069. + gsw_auto_poll(gsw);
  2070. + return;
  2071. + }
  2072. +}
  2073. +
  2074. +static void gsw_hw_init(struct mt7620_gsw *gsw)
  2075. +{
  2076. + u32 is_BGA = mt7620_is_bga();
  2077. +
  2078. + rt_sysc_w32(rt_sysc_r32(SYSC_REG_CFG1) | BIT(8), SYSC_REG_CFG1);
  2079. + gsw_w32(gsw, gsw_r32(gsw, GSW_REG_CKGCR) & ~(0x3 << 4), GSW_REG_CKGCR);
  2080. +
  2081. + /*correct PHY setting L3.0 BGA*/
  2082. + _mt7620_mii_write(gsw, 1, 31, 0x4000); //global, page 4
  2083. +
  2084. + _mt7620_mii_write(gsw, 1, 17, 0x7444);
  2085. + if (is_BGA)
  2086. + _mt7620_mii_write(gsw, 1, 19, 0x0114);
  2087. + else
  2088. + _mt7620_mii_write(gsw, 1, 19, 0x0117);
  2089. +
  2090. + _mt7620_mii_write(gsw, 1, 22, 0x10cf);
  2091. + _mt7620_mii_write(gsw, 1, 25, 0x6212);
  2092. + _mt7620_mii_write(gsw, 1, 26, 0x0777);
  2093. + _mt7620_mii_write(gsw, 1, 29, 0x4000);
  2094. + _mt7620_mii_write(gsw, 1, 28, 0xc077);
  2095. + _mt7620_mii_write(gsw, 1, 24, 0x0000);
  2096. +
  2097. + _mt7620_mii_write(gsw, 1, 31, 0x3000); //global, page 3
  2098. + _mt7620_mii_write(gsw, 1, 17, 0x4838);
  2099. +
  2100. + _mt7620_mii_write(gsw, 1, 31, 0x2000); //global, page 2
  2101. + if (is_BGA) {
  2102. + _mt7620_mii_write(gsw, 1, 21, 0x0515);
  2103. + _mt7620_mii_write(gsw, 1, 22, 0x0053);
  2104. + _mt7620_mii_write(gsw, 1, 23, 0x00bf);
  2105. + _mt7620_mii_write(gsw, 1, 24, 0x0aaf);
  2106. + _mt7620_mii_write(gsw, 1, 25, 0x0fad);
  2107. + _mt7620_mii_write(gsw, 1, 26, 0x0fc1);
  2108. + } else {
  2109. + _mt7620_mii_write(gsw, 1, 21, 0x0517);
  2110. + _mt7620_mii_write(gsw, 1, 22, 0x0fd2);
  2111. + _mt7620_mii_write(gsw, 1, 23, 0x00bf);
  2112. + _mt7620_mii_write(gsw, 1, 24, 0x0aab);
  2113. + _mt7620_mii_write(gsw, 1, 25, 0x00ae);
  2114. + _mt7620_mii_write(gsw, 1, 26, 0x0fff);
  2115. + }
  2116. + _mt7620_mii_write(gsw, 1, 31, 0x1000); //global, page 1
  2117. + _mt7620_mii_write(gsw, 1, 17, 0xe7f8);
  2118. +
  2119. + _mt7620_mii_write(gsw, 1, 31, 0x8000); //local, page 0
  2120. + _mt7620_mii_write(gsw, 0, 30, 0xa000);
  2121. + _mt7620_mii_write(gsw, 1, 30, 0xa000);
  2122. + _mt7620_mii_write(gsw, 2, 30, 0xa000);
  2123. + _mt7620_mii_write(gsw, 3, 30, 0xa000);
  2124. +
  2125. + _mt7620_mii_write(gsw, 0, 4, 0x05e1);
  2126. + _mt7620_mii_write(gsw, 1, 4, 0x05e1);
  2127. + _mt7620_mii_write(gsw, 2, 4, 0x05e1);
  2128. + _mt7620_mii_write(gsw, 3, 4, 0x05e1);
  2129. + _mt7620_mii_write(gsw, 1, 31, 0xa000); //local, page 2
  2130. + _mt7620_mii_write(gsw, 0, 16, 0x1111);
  2131. + _mt7620_mii_write(gsw, 1, 16, 0x1010);
  2132. + _mt7620_mii_write(gsw, 2, 16, 0x1515);
  2133. + _mt7620_mii_write(gsw, 3, 16, 0x0f0f);
  2134. +
  2135. + /* CPU Port6 Force Link 1G, FC ON */
  2136. + gsw_w32(gsw, 0x5e33b, GSW_REG_PORT_PMCR(6));
  2137. + /* Set Port6 CPU Port */
  2138. + gsw_w32(gsw, 0x7f7f7fe0, 0x0010);
  2139. +
  2140. + /* setup port 4 */
  2141. + if (gsw->port4 == PORT4_EPHY) {
  2142. + u32 val = rt_sysc_r32(SYSCFG1);
  2143. + val |= 3 << 14;
  2144. + rt_sysc_w32(val, SYSCFG1);
  2145. + _mt7620_mii_write(gsw, 4, 30, 0xa000);
  2146. + _mt7620_mii_write(gsw, 4, 4, 0x05e1);
  2147. + _mt7620_mii_write(gsw, 4, 16, 0x1313);
  2148. + pr_info("gsw: setting port4 to ephy mode\n");
  2149. + }
  2150. +}
  2151. +
  2152. +void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac)
  2153. +{
  2154. + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
  2155. + unsigned long flags;
  2156. +
  2157. + spin_lock_irqsave(&priv->page_lock, flags);
  2158. + gsw_w32(gsw, (mac[0] << 8) | mac[1], GSW_REG_SMACCR1);
  2159. + gsw_w32(gsw, (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
  2160. + GSW_REG_SMACCR0);
  2161. + spin_unlock_irqrestore(&priv->page_lock, flags);
  2162. +}
  2163. +
  2164. +static struct of_device_id gsw_match[] = {
  2165. + { .compatible = "ralink,mt7620a-gsw" },
  2166. + {}
  2167. +};
  2168. +
  2169. +int mt7620_gsw_config(struct fe_priv *priv)
  2170. +{
  2171. + struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
  2172. +
  2173. + /* is the mt7530 internal or external */
  2174. + if ((_mt7620_mii_read(gsw, 0x1f, 2) == 1) && (_mt7620_mii_read(gsw, 0x1f, 3) == 0xbeef))
  2175. + mt7530_probe(priv->device, NULL, priv->mii_bus);
  2176. + else
  2177. + mt7530_probe(priv->device, gsw->base, NULL);
  2178. +
  2179. + return 0;
  2180. +}
  2181. +
  2182. +int mt7620_gsw_probe(struct fe_priv *priv)
  2183. +{
  2184. + struct mt7620_gsw *gsw;
  2185. + struct device_node *np;
  2186. + const char *port4 = NULL;
  2187. +
  2188. + np = of_find_matching_node(NULL, gsw_match);
  2189. + if (!np) {
  2190. + dev_err(priv->device, "no gsw node found\n");
  2191. + return -EINVAL;
  2192. + }
  2193. + np = of_node_get(np);
  2194. +
  2195. + gsw = devm_kzalloc(priv->device, sizeof(struct mt7620_gsw), GFP_KERNEL);
  2196. + if (!gsw) {
  2197. + dev_err(priv->device, "no gsw memory for private data\n");
  2198. + return -ENOMEM;
  2199. + }
  2200. +
  2201. + gsw->irq = irq_of_parse_and_map(np, 0);
  2202. + if (!gsw->irq) {
  2203. + dev_err(priv->device, "no gsw irq resource found\n");
  2204. + return -ENOMEM;
  2205. + }
  2206. +
  2207. + gsw->base = of_iomap(np, 0);
  2208. + if (!gsw->base) {
  2209. + dev_err(priv->device, "gsw ioremap failed\n");
  2210. + return -ENOMEM;
  2211. + }
  2212. +
  2213. + gsw->dev = priv->device;
  2214. + priv->soc->swpriv = gsw;
  2215. +
  2216. + of_property_read_string(np, "ralink,port4", &port4);
  2217. + if (port4 && !strcmp(port4, "ephy"))
  2218. + gsw->port4 = PORT4_EPHY;
  2219. + else if (port4 && !strcmp(port4, "gmac"))
  2220. + gsw->port4 = PORT4_EXT;
  2221. + else
  2222. + WARN_ON(port4);
  2223. +
  2224. + gsw_hw_init(gsw);
  2225. +
  2226. + gsw_w32(gsw, ~PORT_IRQ_ST_CHG, GSW_REG_IMR);
  2227. + request_irq(gsw->irq, gsw_interrupt, 0, "gsw", priv);
  2228. +
  2229. + return 0;
  2230. +}
  2231. --- /dev/null
  2232. +++ b/drivers/net/ethernet/ralink/gsw_mt7620a.h
  2233. @@ -0,0 +1,30 @@
  2234. +/*
  2235. + * This program is free software; you can redistribute it and/or modify
  2236. + * it under the terms of the GNU General Public License as published by
  2237. + * the Free Software Foundation; version 2 of the License
  2238. + *
  2239. + * This program is distributed in the hope that it will be useful,
  2240. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2241. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2242. + * GNU General Public License for more details.
  2243. + *
  2244. + * You should have received a copy of the GNU General Public License
  2245. + * along with this program; if not, write to the Free Software
  2246. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  2247. + *
  2248. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  2249. + */
  2250. +
  2251. +#ifndef _RALINK_GSW_MT7620_H__
  2252. +#define _RALINK_GSW_MT7620_H__
  2253. +
  2254. +extern int mt7620_gsw_config(struct fe_priv *priv);
  2255. +extern int mt7620_gsw_probe(struct fe_priv *priv);
  2256. +extern void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac);
  2257. +extern int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
  2258. +extern int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg);
  2259. +extern void mt7620_mdio_link_adjust(struct fe_priv *priv, int port);
  2260. +extern void mt7620_port_init(struct fe_priv *priv, struct device_node *np);
  2261. +extern int mt7620a_has_carrier(struct fe_priv *priv);
  2262. +
  2263. +#endif
  2264. --- /dev/null
  2265. +++ b/drivers/net/ethernet/ralink/mdio.c
  2266. @@ -0,0 +1,244 @@
  2267. +/*
  2268. + * This program is free software; you can redistribute it and/or modify
  2269. + * it under the terms of the GNU General Public License as published by
  2270. + * the Free Software Foundation; version 2 of the License
  2271. + *
  2272. + * This program is distributed in the hope that it will be useful,
  2273. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2274. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2275. + * GNU General Public License for more details.
  2276. + *
  2277. + * You should have received a copy of the GNU General Public License
  2278. + * along with this program; if not, write to the Free Software
  2279. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  2280. + *
  2281. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  2282. + */
  2283. +
  2284. +#include <linux/module.h>
  2285. +#include <linux/kernel.h>
  2286. +#include <linux/types.h>
  2287. +#include <linux/dma-mapping.h>
  2288. +#include <linux/init.h>
  2289. +#include <linux/skbuff.h>
  2290. +#include <linux/etherdevice.h>
  2291. +#include <linux/ethtool.h>
  2292. +#include <linux/platform_device.h>
  2293. +#include <linux/phy.h>
  2294. +#include <linux/of_device.h>
  2295. +#include <linux/clk.h>
  2296. +#include <linux/of_net.h>
  2297. +#include <linux/of_mdio.h>
  2298. +
  2299. +#include "ralink_soc_eth.h"
  2300. +#include "mdio.h"
  2301. +
  2302. +static int fe_mdio_reset(struct mii_bus *bus)
  2303. +{
  2304. + /* TODO */
  2305. + return 0;
  2306. +}
  2307. +
  2308. +static void fe_phy_link_adjust(struct net_device *dev)
  2309. +{
  2310. + struct fe_priv *priv = netdev_priv(dev);
  2311. + unsigned long flags;
  2312. + int i;
  2313. +
  2314. + spin_lock_irqsave(&priv->phy->lock, flags);
  2315. + for (i = 0; i < 8; i++) {
  2316. + if (priv->phy->phy_node[i]) {
  2317. + struct phy_device *phydev = priv->phy->phy[i];
  2318. + int status_change = 0;
  2319. +
  2320. + if (phydev->link)
  2321. + if (priv->phy->duplex[i] != phydev->duplex ||
  2322. + priv->phy->speed[i] != phydev->speed)
  2323. + status_change = 1;
  2324. +
  2325. + if (phydev->link != priv->link[i])
  2326. + status_change = 1;
  2327. +
  2328. + switch (phydev->speed) {
  2329. + case SPEED_1000:
  2330. + case SPEED_100:
  2331. + case SPEED_10:
  2332. + priv->link[i] = phydev->link;
  2333. + priv->phy->duplex[i] = phydev->duplex;
  2334. + priv->phy->speed[i] = phydev->speed;
  2335. +
  2336. + if (status_change && priv->soc->mdio_adjust_link)
  2337. + priv->soc->mdio_adjust_link(priv, i);
  2338. + break;
  2339. + }
  2340. + }
  2341. + }
  2342. +}
  2343. +
  2344. +int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node)
  2345. +{
  2346. + const __be32 *_port = NULL;
  2347. + struct phy_device *phydev;
  2348. + int phy_mode, port;
  2349. +
  2350. + _port = of_get_property(phy_node, "reg", NULL);
  2351. +
  2352. + if (!_port || (be32_to_cpu(*_port) >= 0x20)) {
  2353. + pr_err("%s: invalid port id\n", phy_node->name);
  2354. + return -EINVAL;
  2355. + }
  2356. + port = be32_to_cpu(*_port);
  2357. + phy_mode = of_get_phy_mode(phy_node);
  2358. + if (phy_mode < 0) {
  2359. + dev_err(priv->device, "incorrect phy-mode %d\n", phy_mode);
  2360. + priv->phy->phy_node[port] = NULL;
  2361. + return -EINVAL;
  2362. + }
  2363. +
  2364. + phydev = of_phy_connect(priv->netdev, phy_node, fe_phy_link_adjust,
  2365. + 0, phy_mode);
  2366. + if (IS_ERR(phydev)) {
  2367. + dev_err(priv->device, "could not connect to PHY\n");
  2368. + priv->phy->phy_node[port] = NULL;
  2369. + return PTR_ERR(phydev);
  2370. + }
  2371. +
  2372. + phydev->supported &= PHY_GBIT_FEATURES;
  2373. + phydev->advertising = phydev->supported;
  2374. + phydev->no_auto_carrier_off = 1;
  2375. +
  2376. + dev_info(priv->device,
  2377. + "connected port %d to PHY at %s [uid=%08x, driver=%s]\n",
  2378. + port, dev_name(&phydev->dev), phydev->phy_id,
  2379. + phydev->drv->name);
  2380. +
  2381. + priv->phy->phy[port] = phydev;
  2382. + priv->link[port] = 0;
  2383. +
  2384. + return 0;
  2385. +}
  2386. +
  2387. +static int fe_phy_connect(struct fe_priv *priv)
  2388. +{
  2389. + return 0;
  2390. +}
  2391. +
  2392. +static void fe_phy_disconnect(struct fe_priv *priv)
  2393. +{
  2394. + unsigned long flags;
  2395. + int i;
  2396. +
  2397. + for (i = 0; i < 8; i++)
  2398. + if (priv->phy->phy_fixed[i]) {
  2399. + spin_lock_irqsave(&priv->phy->lock, flags);
  2400. + priv->link[i] = 0;
  2401. + if (priv->soc->mdio_adjust_link)
  2402. + priv->soc->mdio_adjust_link(priv, i);
  2403. + spin_unlock_irqrestore(&priv->phy->lock, flags);
  2404. + } else if (priv->phy->phy[i]) {
  2405. + phy_disconnect(priv->phy->phy[i]);
  2406. + }
  2407. +}
  2408. +
  2409. +static void fe_phy_start(struct fe_priv *priv)
  2410. +{
  2411. + unsigned long flags;
  2412. + int i;
  2413. +
  2414. + for (i = 0; i < 8; i++) {
  2415. + if (priv->phy->phy_fixed[i]) {
  2416. + spin_lock_irqsave(&priv->phy->lock, flags);
  2417. + priv->link[i] = 1;
  2418. + if (priv->soc->mdio_adjust_link)
  2419. + priv->soc->mdio_adjust_link(priv, i);
  2420. + spin_unlock_irqrestore(&priv->phy->lock, flags);
  2421. + } else if (priv->phy->phy[i]) {
  2422. + phy_start(priv->phy->phy[i]);
  2423. + }
  2424. + }
  2425. +}
  2426. +
  2427. +static void fe_phy_stop(struct fe_priv *priv)
  2428. +{
  2429. + unsigned long flags;
  2430. + int i;
  2431. +
  2432. + for (i = 0; i < 8; i++)
  2433. + if (priv->phy->phy_fixed[i]) {
  2434. + spin_lock_irqsave(&priv->phy->lock, flags);
  2435. + priv->link[i] = 0;
  2436. + if (priv->soc->mdio_adjust_link)
  2437. + priv->soc->mdio_adjust_link(priv, i);
  2438. + spin_unlock_irqrestore(&priv->phy->lock, flags);
  2439. + } else if (priv->phy->phy[i]) {
  2440. + phy_stop(priv->phy->phy[i]);
  2441. + }
  2442. +}
  2443. +
  2444. +static struct fe_phy phy_ralink = {
  2445. + .connect = fe_phy_connect,
  2446. + .disconnect = fe_phy_disconnect,
  2447. + .start = fe_phy_start,
  2448. + .stop = fe_phy_stop,
  2449. +};
  2450. +
  2451. +int fe_mdio_init(struct fe_priv *priv)
  2452. +{
  2453. + struct device_node *mii_np;
  2454. + int err;
  2455. +
  2456. + if (!priv->soc->mdio_read || !priv->soc->mdio_write)
  2457. + return 0;
  2458. +
  2459. + spin_lock_init(&phy_ralink.lock);
  2460. + priv->phy = &phy_ralink;
  2461. +
  2462. + mii_np = of_get_child_by_name(priv->device->of_node, "mdio-bus");
  2463. + if (!mii_np) {
  2464. + dev_err(priv->device, "no %s child node found", "mdio-bus");
  2465. + return -ENODEV;
  2466. + }
  2467. +
  2468. + if (!of_device_is_available(mii_np)) {
  2469. + err = 0;
  2470. + goto err_put_node;
  2471. + }
  2472. +
  2473. + priv->mii_bus = mdiobus_alloc();
  2474. + if (priv->mii_bus == NULL) {
  2475. + err = -ENOMEM;
  2476. + goto err_put_node;
  2477. + }
  2478. +
  2479. + priv->mii_bus->name = "mdio";
  2480. + priv->mii_bus->read = priv->soc->mdio_read;
  2481. + priv->mii_bus->write = priv->soc->mdio_write;
  2482. + priv->mii_bus->reset = fe_mdio_reset;
  2483. + priv->mii_bus->irq = priv->mii_irq;
  2484. + priv->mii_bus->priv = priv;
  2485. + priv->mii_bus->parent = priv->device;
  2486. +
  2487. + snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name);
  2488. + err = of_mdiobus_register(priv->mii_bus, mii_np);
  2489. + if (err)
  2490. + goto err_free_bus;
  2491. +
  2492. + return 0;
  2493. +
  2494. +err_free_bus:
  2495. + kfree(priv->mii_bus);
  2496. +err_put_node:
  2497. + of_node_put(mii_np);
  2498. + priv->mii_bus = NULL;
  2499. + return err;
  2500. +}
  2501. +
  2502. +void fe_mdio_cleanup(struct fe_priv *priv)
  2503. +{
  2504. + if (!priv->mii_bus)
  2505. + return;
  2506. +
  2507. + mdiobus_unregister(priv->mii_bus);
  2508. + of_node_put(priv->mii_bus->dev.of_node);
  2509. + kfree(priv->mii_bus);
  2510. +}
  2511. --- /dev/null
  2512. +++ b/drivers/net/ethernet/ralink/mdio.h
  2513. @@ -0,0 +1,29 @@
  2514. +/*
  2515. + * This program is free software; you can redistribute it and/or modify
  2516. + * it under the terms of the GNU General Public License as published by
  2517. + * the Free Software Foundation; version 2 of the License
  2518. + *
  2519. + * This program is distributed in the hope that it will be useful,
  2520. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2521. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2522. + * GNU General Public License for more details.
  2523. + *
  2524. + * You should have received a copy of the GNU General Public License
  2525. + * along with this program; if not, write to the Free Software
  2526. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  2527. + *
  2528. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  2529. + */
  2530. +
  2531. +#ifndef _RALINK_MDIO_H__
  2532. +#define _RALINK_MDIO_H__
  2533. +
  2534. +#ifdef CONFIG_NET_RALINK_MDIO
  2535. +extern int fe_mdio_init(struct fe_priv *priv);
  2536. +extern void fe_mdio_cleanup(struct fe_priv *priv);
  2537. +extern int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node);
  2538. +#else
  2539. +static inline int fe_mdio_init(struct fe_priv *priv) { return 0; }
  2540. +static inline void fe_mdio_cleanup(struct fe_priv *priv) {}
  2541. +#endif
  2542. +#endif
  2543. --- /dev/null
  2544. +++ b/drivers/net/ethernet/ralink/mdio_rt2880.c
  2545. @@ -0,0 +1,232 @@
  2546. +/*
  2547. + * This program is free software; you can redistribute it and/or modify
  2548. + * it under the terms of the GNU General Public License as published by
  2549. + * the Free Software Foundation; version 2 of the License
  2550. + *
  2551. + * This program is distributed in the hope that it will be useful,
  2552. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2553. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2554. + * GNU General Public License for more details.
  2555. + *
  2556. + * You should have received a copy of the GNU General Public License
  2557. + * along with this program; if not, write to the Free Software
  2558. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  2559. + *
  2560. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  2561. + */
  2562. +
  2563. +#include <linux/module.h>
  2564. +#include <linux/kernel.h>
  2565. +#include <linux/types.h>
  2566. +#include <linux/dma-mapping.h>
  2567. +#include <linux/init.h>
  2568. +#include <linux/skbuff.h>
  2569. +#include <linux/etherdevice.h>
  2570. +#include <linux/ethtool.h>
  2571. +#include <linux/platform_device.h>
  2572. +#include <linux/phy.h>
  2573. +#include <linux/of_device.h>
  2574. +#include <linux/clk.h>
  2575. +#include <linux/of_net.h>
  2576. +#include <linux/of_mdio.h>
  2577. +
  2578. +#include "ralink_soc_eth.h"
  2579. +#include "mdio_rt2880.h"
  2580. +#include "mdio.h"
  2581. +
  2582. +#define FE_MDIO_RETRY 1000
  2583. +
  2584. +static unsigned char *rt2880_speed_str(struct fe_priv *priv)
  2585. +{
  2586. + switch (priv->phy->speed[0]) {
  2587. + case SPEED_1000:
  2588. + return "1000";
  2589. + case SPEED_100:
  2590. + return "100";
  2591. + case SPEED_10:
  2592. + return "10";
  2593. + }
  2594. +
  2595. + return "?";
  2596. +}
  2597. +
  2598. +void rt2880_mdio_link_adjust(struct fe_priv *priv, int port)
  2599. +{
  2600. + u32 mdio_cfg;
  2601. +
  2602. + if (!priv->link[0]) {
  2603. + netif_carrier_off(priv->netdev);
  2604. + netdev_info(priv->netdev, "link down\n");
  2605. + return;
  2606. + }
  2607. +
  2608. + mdio_cfg = FE_MDIO_CFG_TX_CLK_SKEW_200 |
  2609. + FE_MDIO_CFG_RX_CLK_SKEW_200 |
  2610. + FE_MDIO_CFG_GP1_FRC_EN;
  2611. +
  2612. + if (priv->phy->duplex[0] == DUPLEX_FULL)
  2613. + mdio_cfg |= FE_MDIO_CFG_GP1_DUPLEX;
  2614. +
  2615. + if (priv->phy->tx_fc[0])
  2616. + mdio_cfg |= FE_MDIO_CFG_GP1_FC_TX;
  2617. +
  2618. + if (priv->phy->rx_fc[0])
  2619. + mdio_cfg |= FE_MDIO_CFG_GP1_FC_RX;
  2620. +
  2621. + switch (priv->phy->speed[0]) {
  2622. + case SPEED_10:
  2623. + mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_10;
  2624. + break;
  2625. + case SPEED_100:
  2626. + mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_100;
  2627. + break;
  2628. + case SPEED_1000:
  2629. + mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_1000;
  2630. + break;
  2631. + default:
  2632. + BUG();
  2633. + }
  2634. +
  2635. + fe_w32(mdio_cfg, FE_MDIO_CFG);
  2636. +
  2637. + netif_carrier_on(priv->netdev);
  2638. + netdev_info(priv->netdev, "link up (%sMbps/%s duplex)\n",
  2639. + rt2880_speed_str(priv),
  2640. + (DUPLEX_FULL == priv->phy->duplex[0]) ? "Full" : "Half");
  2641. +}
  2642. +
  2643. +static int rt2880_mdio_wait_ready(struct fe_priv *priv)
  2644. +{
  2645. + int retries;
  2646. +
  2647. + retries = FE_MDIO_RETRY;
  2648. + while (1) {
  2649. + u32 t;
  2650. +
  2651. + t = fe_r32(FE_MDIO_ACCESS);
  2652. + if ((t & (0x1 << 31)) == 0)
  2653. + return 0;
  2654. +
  2655. + if (retries-- == 0)
  2656. + break;
  2657. +
  2658. + udelay(1);
  2659. + }
  2660. +
  2661. + dev_err(priv->device, "MDIO operation timed out\n");
  2662. + return -ETIMEDOUT;
  2663. +}
  2664. +
  2665. +int rt2880_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
  2666. +{
  2667. + struct fe_priv *priv = bus->priv;
  2668. + int err;
  2669. + u32 t;
  2670. +
  2671. + err = rt2880_mdio_wait_ready(priv);
  2672. + if (err)
  2673. + return 0xffff;
  2674. +
  2675. + t = (phy_addr << 24) | (phy_reg << 16);
  2676. + fe_w32(t, FE_MDIO_ACCESS);
  2677. + t |= (1 << 31);
  2678. + fe_w32(t, FE_MDIO_ACCESS);
  2679. +
  2680. + err = rt2880_mdio_wait_ready(priv);
  2681. + if (err)
  2682. + return 0xffff;
  2683. +
  2684. + pr_info("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
  2685. + phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
  2686. +
  2687. + return fe_r32(FE_MDIO_ACCESS) & 0xffff;
  2688. +}
  2689. +
  2690. +int rt2880_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val)
  2691. +{
  2692. + struct fe_priv *priv = bus->priv;
  2693. + int err;
  2694. + u32 t;
  2695. +
  2696. + pr_info("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
  2697. + phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
  2698. +
  2699. + err = rt2880_mdio_wait_ready(priv);
  2700. + if (err)
  2701. + return err;
  2702. +
  2703. + t = (1 << 30) | (phy_addr << 24) | (phy_reg << 16) | val;
  2704. + fe_w32(t, FE_MDIO_ACCESS);
  2705. + t |= (1 << 31);
  2706. + fe_w32(t, FE_MDIO_ACCESS);
  2707. +
  2708. + return rt2880_mdio_wait_ready(priv);
  2709. +}
  2710. +
  2711. +void rt2880_port_init(struct fe_priv *priv, struct device_node *np)
  2712. +{
  2713. + const __be32 *id = of_get_property(np, "reg", NULL);
  2714. + const __be32 *link;
  2715. + int size;
  2716. + int phy_mode;
  2717. +
  2718. + if (!id || (be32_to_cpu(*id) != 0)) {
  2719. + pr_err("%s: invalid port id\n", np->name);
  2720. + return;
  2721. + }
  2722. +
  2723. + priv->phy->phy_fixed[0] = of_get_property(np, "ralink,fixed-link", &size);
  2724. + if (priv->phy->phy_fixed[0] && (size != (4 * sizeof(*priv->phy->phy_fixed[0])))) {
  2725. + pr_err("%s: invalid fixed link property\n", np->name);
  2726. + priv->phy->phy_fixed[0] = NULL;
  2727. + return;
  2728. + }
  2729. +
  2730. + phy_mode = of_get_phy_mode(np);
  2731. + switch (phy_mode) {
  2732. + case PHY_INTERFACE_MODE_RGMII:
  2733. + break;
  2734. + case PHY_INTERFACE_MODE_MII:
  2735. + break;
  2736. + case PHY_INTERFACE_MODE_RMII:
  2737. + break;
  2738. + default:
  2739. + if (!priv->phy->phy_fixed[0])
  2740. + dev_err(priv->device, "port %d - invalid phy mode\n", priv->phy->speed[0]);
  2741. + break;
  2742. + }
  2743. +
  2744. + priv->phy->phy_node[0] = of_parse_phandle(np, "phy-handle", 0);
  2745. + if (!priv->phy->phy_node[0] && !priv->phy->phy_fixed[0])
  2746. + return;
  2747. +
  2748. + if (priv->phy->phy_fixed[0]) {
  2749. + link = priv->phy->phy_fixed[0];
  2750. + priv->phy->speed[0] = be32_to_cpup(link++);
  2751. + priv->phy->duplex[0] = be32_to_cpup(link++);
  2752. + priv->phy->tx_fc[0] = be32_to_cpup(link++);
  2753. + priv->phy->rx_fc[0] = be32_to_cpup(link++);
  2754. +
  2755. + priv->link[0] = 1;
  2756. + switch (priv->phy->speed[0]) {
  2757. + case SPEED_10:
  2758. + break;
  2759. + case SPEED_100:
  2760. + break;
  2761. + case SPEED_1000:
  2762. + break;
  2763. + default:
  2764. + dev_err(priv->device, "invalid link speed: %d\n", priv->phy->speed[0]);
  2765. + priv->phy->phy_fixed[0] = 0;
  2766. + return;
  2767. + }
  2768. + dev_info(priv->device, "using fixed link parameters\n");
  2769. + rt2880_mdio_link_adjust(priv, 0);
  2770. + return;
  2771. + }
  2772. + if (priv->phy->phy_node[0] && priv->mii_bus->phy_map[0]) {
  2773. + fe_connect_phy_node(priv, priv->phy->phy_node[0]);
  2774. + }
  2775. +
  2776. + return;
  2777. +}
  2778. --- /dev/null
  2779. +++ b/drivers/net/ethernet/ralink/mdio_rt2880.h
  2780. @@ -0,0 +1,26 @@
  2781. +/*
  2782. + * This program is free software; you can redistribute it and/or modify
  2783. + * it under the terms of the GNU General Public License as published by
  2784. + * the Free Software Foundation; version 2 of the License
  2785. + *
  2786. + * This program is distributed in the hope that it will be useful,
  2787. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2788. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2789. + * GNU General Public License for more details.
  2790. + *
  2791. + * You should have received a copy of the GNU General Public License
  2792. + * along with this program; if not, write to the Free Software
  2793. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  2794. + *
  2795. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  2796. + */
  2797. +
  2798. +#ifndef _RALINK_MDIO_RT2880_H__
  2799. +#define _RALINK_MDIO_RT2880_H__
  2800. +
  2801. +void rt2880_mdio_link_adjust(struct fe_priv *priv, int port);
  2802. +int rt2880_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg);
  2803. +int rt2880_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
  2804. +void rt2880_port_init(struct fe_priv *priv, struct device_node *np);
  2805. +
  2806. +#endif
  2807. --- /dev/null
  2808. +++ b/drivers/net/ethernet/ralink/ralink_soc_eth.c
  2809. @@ -0,0 +1,846 @@
  2810. +/*
  2811. + * This program is free software; you can redistribute it and/or modify
  2812. + * it under the terms of the GNU General Public License as published by
  2813. + * the Free Software Foundation; version 2 of the License
  2814. + *
  2815. + * This program is distributed in the hope that it will be useful,
  2816. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2817. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2818. + * GNU General Public License for more details.
  2819. + *
  2820. + * You should have received a copy of the GNU General Public License
  2821. + * along with this program; if not, write to the Free Software
  2822. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  2823. + *
  2824. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  2825. + */
  2826. +
  2827. +#include <linux/module.h>
  2828. +#include <linux/kernel.h>
  2829. +#include <linux/types.h>
  2830. +#include <linux/dma-mapping.h>
  2831. +#include <linux/init.h>
  2832. +#include <linux/skbuff.h>
  2833. +#include <linux/etherdevice.h>
  2834. +#include <linux/ethtool.h>
  2835. +#include <linux/platform_device.h>
  2836. +#include <linux/of_device.h>
  2837. +#include <linux/clk.h>
  2838. +#include <linux/of_net.h>
  2839. +#include <linux/of_mdio.h>
  2840. +#include <linux/if_vlan.h>
  2841. +#include <linux/reset.h>
  2842. +
  2843. +#include <asm/mach-ralink/ralink_regs.h>
  2844. +
  2845. +#include "ralink_soc_eth.h"
  2846. +#include "esw_rt3052.h"
  2847. +#include "mdio.h"
  2848. +
  2849. +#define TX_TIMEOUT (2 * HZ)
  2850. +#define MAX_RX_LENGTH 1536
  2851. +#define DMA_DUMMY_DESC 0xffffffff
  2852. +
  2853. +static const u32 fe_reg_table_default[FE_REG_COUNT] = {
  2854. + [FE_REG_PDMA_GLO_CFG] = FE_PDMA_GLO_CFG,
  2855. + [FE_REG_PDMA_RST_CFG] = FE_PDMA_RST_CFG,
  2856. + [FE_REG_DLY_INT_CFG] = FE_DLY_INT_CFG,
  2857. + [FE_REG_TX_BASE_PTR0] = FE_TX_BASE_PTR0,
  2858. + [FE_REG_TX_MAX_CNT0] = FE_TX_MAX_CNT0,
  2859. + [FE_REG_TX_CTX_IDX0] = FE_TX_CTX_IDX0,
  2860. + [FE_REG_RX_BASE_PTR0] = FE_RX_BASE_PTR0,
  2861. + [FE_REG_RX_MAX_CNT0] = FE_RX_MAX_CNT0,
  2862. + [FE_REG_RX_CALC_IDX0] = FE_RX_CALC_IDX0,
  2863. + [FE_REG_FE_INT_ENABLE] = FE_FE_INT_ENABLE,
  2864. + [FE_REG_FE_INT_STATUS] = FE_FE_INT_STATUS,
  2865. +};
  2866. +
  2867. +static const u32 *fe_reg_table = fe_reg_table_default;
  2868. +
  2869. +static void __iomem *fe_base = 0;
  2870. +
  2871. +void fe_w32(u32 val, unsigned reg)
  2872. +{
  2873. + __raw_writel(val, fe_base + reg);
  2874. +}
  2875. +
  2876. +u32 fe_r32(unsigned reg)
  2877. +{
  2878. + return __raw_readl(fe_base + reg);
  2879. +}
  2880. +
  2881. +static inline void fe_reg_w32(u32 val, enum fe_reg reg)
  2882. +{
  2883. + fe_w32(val, fe_reg_table[reg]);
  2884. +}
  2885. +
  2886. +static inline u32 fe_reg_r32(enum fe_reg reg)
  2887. +{
  2888. + return fe_r32(fe_reg_table[reg]);
  2889. +}
  2890. +
  2891. +static inline void fe_int_disable(u32 mask)
  2892. +{
  2893. + fe_reg_w32(fe_reg_r32(FE_REG_FE_INT_ENABLE) & ~mask,
  2894. + FE_REG_FE_INT_ENABLE);
  2895. + /* flush write */
  2896. + fe_reg_r32(FE_REG_FE_INT_ENABLE);
  2897. +}
  2898. +
  2899. +static inline void fe_int_enable(u32 mask)
  2900. +{
  2901. + fe_reg_w32(fe_reg_r32(FE_REG_FE_INT_ENABLE) | mask,
  2902. + FE_REG_FE_INT_ENABLE);
  2903. + /* flush write */
  2904. + fe_reg_r32(FE_REG_FE_INT_ENABLE);
  2905. +}
  2906. +
  2907. +static inline void fe_hw_set_macaddr(struct fe_priv *priv, unsigned char *mac)
  2908. +{
  2909. + unsigned long flags;
  2910. +
  2911. + spin_lock_irqsave(&priv->page_lock, flags);
  2912. + fe_w32((mac[0] << 8) | mac[1], FE_GDMA1_MAC_ADRH);
  2913. + fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
  2914. + FE_GDMA1_MAC_ADRL);
  2915. + spin_unlock_irqrestore(&priv->page_lock, flags);
  2916. +}
  2917. +
  2918. +static int fe_set_mac_address(struct net_device *dev, void *p)
  2919. +{
  2920. + int ret = eth_mac_addr(dev, p);
  2921. +
  2922. + if (!ret) {
  2923. + struct fe_priv *priv = netdev_priv(dev);
  2924. +
  2925. + if (priv->soc->set_mac)
  2926. + priv->soc->set_mac(priv, dev->dev_addr);
  2927. + else
  2928. + fe_hw_set_macaddr(priv, p);
  2929. + }
  2930. +
  2931. + return ret;
  2932. +}
  2933. +
  2934. +static struct sk_buff* fe_alloc_skb(struct fe_priv *priv)
  2935. +{
  2936. + struct sk_buff *skb;
  2937. +
  2938. + skb = netdev_alloc_skb(priv->netdev, MAX_RX_LENGTH + NET_IP_ALIGN);
  2939. + if (!skb)
  2940. + return NULL;
  2941. +
  2942. + skb_reserve(skb, NET_IP_ALIGN);
  2943. +
  2944. + return skb;
  2945. +}
  2946. +
  2947. +static int fe_alloc_rx(struct fe_priv *priv)
  2948. +{
  2949. + int size = NUM_DMA_DESC * sizeof(struct fe_rx_dma);
  2950. + int i;
  2951. +
  2952. + priv->rx_dma = dma_alloc_coherent(&priv->netdev->dev, size,
  2953. + &priv->rx_phys, GFP_ATOMIC);
  2954. + if (!priv->rx_dma)
  2955. + return -ENOMEM;
  2956. +
  2957. + memset(priv->rx_dma, 0, size);
  2958. +
  2959. + for (i = 0; i < NUM_DMA_DESC; i++) {
  2960. + priv->rx_skb[i] = fe_alloc_skb(priv);
  2961. + if (!priv->rx_skb[i])
  2962. + return -ENOMEM;
  2963. + }
  2964. +
  2965. + for (i = 0; i < NUM_DMA_DESC; i++) {
  2966. + dma_addr_t dma_addr = dma_map_single(&priv->netdev->dev,
  2967. + priv->rx_skb[i]->data,
  2968. + MAX_RX_LENGTH,
  2969. + DMA_FROM_DEVICE);
  2970. + priv->rx_dma[i].rxd1 = (unsigned int) dma_addr;
  2971. +
  2972. + if (priv->soc->rx_dma)
  2973. + priv->soc->rx_dma(priv, i, MAX_RX_LENGTH);
  2974. + else
  2975. + priv->rx_dma[i].rxd2 = RX_DMA_LSO;
  2976. + }
  2977. + wmb();
  2978. +
  2979. + fe_reg_w32(priv->rx_phys, FE_REG_RX_BASE_PTR0);
  2980. + fe_reg_w32(NUM_DMA_DESC, FE_REG_RX_MAX_CNT0);
  2981. + fe_reg_w32((NUM_DMA_DESC - 1), FE_REG_RX_CALC_IDX0);
  2982. + fe_reg_w32(FE_PST_DRX_IDX0, FE_REG_PDMA_RST_CFG);
  2983. +
  2984. + return 0;
  2985. +}
  2986. +
  2987. +static int fe_alloc_tx(struct fe_priv *priv)
  2988. +{
  2989. + int size = NUM_DMA_DESC * sizeof(struct fe_tx_dma);
  2990. + int i;
  2991. +
  2992. + priv->tx_free_idx = 0;
  2993. +
  2994. + priv->tx_dma = dma_alloc_coherent(&priv->netdev->dev, size,
  2995. + &priv->tx_phys, GFP_ATOMIC);
  2996. + if (!priv->tx_dma)
  2997. + return -ENOMEM;
  2998. +
  2999. + memset(priv->tx_dma, 0, size);
  3000. +
  3001. + for (i = 0; i < NUM_DMA_DESC; i++) {
  3002. + if (priv->soc->tx_dma) {
  3003. + priv->soc->tx_dma(priv, i, NULL);
  3004. + continue;
  3005. + }
  3006. +
  3007. + priv->tx_dma[i].txd2 = TX_DMA_LSO | TX_DMA_DONE;
  3008. + priv->tx_dma[i].txd4 = TX_DMA_QN(3) | TX_DMA_PN(1);
  3009. + }
  3010. +
  3011. + fe_reg_w32(priv->tx_phys, FE_REG_TX_BASE_PTR0);
  3012. + fe_reg_w32(NUM_DMA_DESC, FE_REG_TX_MAX_CNT0);
  3013. + fe_reg_w32(0, FE_REG_TX_CTX_IDX0);
  3014. + fe_reg_w32(FE_PST_DTX_IDX0, FE_REG_PDMA_RST_CFG);
  3015. +
  3016. + return 0;
  3017. +}
  3018. +
  3019. +static void fe_free_dma(struct fe_priv *priv)
  3020. +{
  3021. + int i;
  3022. +
  3023. + for (i = 0; i < NUM_DMA_DESC; i++) {
  3024. + if (priv->rx_skb[i]) {
  3025. + dma_unmap_single(&priv->netdev->dev, priv->rx_dma[i].rxd1,
  3026. + MAX_RX_LENGTH, DMA_FROM_DEVICE);
  3027. + dev_kfree_skb_any(priv->rx_skb[i]);
  3028. + priv->rx_skb[i] = NULL;
  3029. + }
  3030. +
  3031. + if (priv->tx_skb[i]) {
  3032. + dev_kfree_skb_any(priv->tx_skb[i]);
  3033. + priv->tx_skb[i] = NULL;
  3034. + }
  3035. + }
  3036. +
  3037. + if (priv->rx_dma) {
  3038. + int size = NUM_DMA_DESC * sizeof(struct fe_rx_dma);
  3039. + dma_free_coherent(&priv->netdev->dev, size, priv->rx_dma,
  3040. + priv->rx_phys);
  3041. + }
  3042. +
  3043. + if (priv->tx_dma) {
  3044. + int size = NUM_DMA_DESC * sizeof(struct fe_tx_dma);
  3045. + dma_free_coherent(&priv->netdev->dev, size, priv->tx_dma,
  3046. + priv->tx_phys);
  3047. + }
  3048. +
  3049. + netdev_reset_queue(priv->netdev);
  3050. +}
  3051. +
  3052. +static void fe_start_tso(struct sk_buff *skb, struct net_device *dev, unsigned int nr_frags, int idx)
  3053. +{
  3054. + struct fe_priv *priv = netdev_priv(dev);
  3055. + struct skb_frag_struct *frag;
  3056. + int i;
  3057. +
  3058. + for (i = 0; i < nr_frags; i++) {
  3059. + dma_addr_t mapped_addr;
  3060. +
  3061. + frag = &skb_shinfo(skb)->frags[i];
  3062. + mapped_addr = skb_frag_dma_map(&dev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE);
  3063. + if (i % 2) {
  3064. + idx = (idx + 1) % NUM_DMA_DESC;
  3065. + priv->tx_dma[idx].txd1 = mapped_addr;
  3066. + if (i == nr_frags - 1)
  3067. + priv->tx_dma[idx].txd2 = TX_DMA_LSO | TX_DMA_PLEN0(frag->size);
  3068. + else
  3069. + priv->tx_dma[idx].txd2 = TX_DMA_PLEN0(frag->size);
  3070. + } else {
  3071. + priv->tx_dma[idx].txd3 = mapped_addr;
  3072. + if (i == nr_frags - 1)
  3073. + priv->tx_dma[idx].txd2 |= TX_DMA_LS1 | TX_DMA_PLEN1(frag->size);
  3074. + else
  3075. + priv->tx_dma[idx].txd2 |= TX_DMA_PLEN1(frag->size);
  3076. + }
  3077. + }
  3078. +}
  3079. +
  3080. +static int fe_start_xmit(struct sk_buff *skb, struct net_device *dev)
  3081. +{
  3082. + unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
  3083. + struct fe_priv *priv = netdev_priv(dev);
  3084. + dma_addr_t mapped_addr;
  3085. + u32 tx_next, tx, tx_num = 1;
  3086. + int i;
  3087. +
  3088. + if (priv->soc->min_pkt_len) {
  3089. + if (skb->len < priv->soc->min_pkt_len) {
  3090. + if (skb_padto(skb, priv->soc->min_pkt_len)) {
  3091. + printk(KERN_ERR
  3092. + "fe_eth: skb_padto failed\n");
  3093. + kfree_skb(skb);
  3094. + return 0;
  3095. + }
  3096. + skb_put(skb, priv->soc->min_pkt_len - skb->len);
  3097. + }
  3098. + }
  3099. +
  3100. + dev->trans_start = jiffies;
  3101. + mapped_addr = dma_map_single(&priv->netdev->dev, skb->data,
  3102. + skb->len, DMA_TO_DEVICE);
  3103. +
  3104. + spin_lock(&priv->page_lock);
  3105. +
  3106. + tx = fe_reg_r32(FE_REG_TX_CTX_IDX0);
  3107. + if (priv->soc->tso && nr_frags)
  3108. + tx_num += nr_frags >> 1;
  3109. + tx_next = (tx + tx_num) % NUM_DMA_DESC;
  3110. + if ((priv->tx_skb[tx]) || (priv->tx_skb[tx_next]) ||
  3111. + !(priv->tx_dma[tx].txd2 & TX_DMA_DONE) ||
  3112. + !(priv->tx_dma[tx_next].txd2 & TX_DMA_DONE))
  3113. + {
  3114. + spin_unlock(&priv->page_lock);
  3115. + dev->stats.tx_dropped++;
  3116. + kfree_skb(skb);
  3117. +
  3118. + return NETDEV_TX_OK;
  3119. + }
  3120. +
  3121. + if (priv->soc->tso) {
  3122. + int t = tx_num;
  3123. +
  3124. + priv->tx_skb[(tx + t - 1) % NUM_DMA_DESC] = skb;
  3125. + while (--t)
  3126. + priv->tx_skb[(tx + t - 1) % NUM_DMA_DESC] = (struct sk_buff *) DMA_DUMMY_DESC;
  3127. + } else {
  3128. + priv->tx_skb[tx] = skb;
  3129. + }
  3130. + priv->tx_dma[tx].txd1 = (unsigned int) mapped_addr;
  3131. + wmb();
  3132. +
  3133. + priv->tx_dma[tx].txd4 &= ~0x80;
  3134. + if (priv->soc->tx_dma)
  3135. + priv->soc->tx_dma(priv, tx, skb);
  3136. + else
  3137. + priv->tx_dma[tx].txd2 = TX_DMA_LSO | TX_DMA_PLEN0(skb->len);
  3138. +
  3139. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  3140. + priv->tx_dma[tx].txd4 |= TX_DMA_CHKSUM;
  3141. + else
  3142. + priv->tx_dma[tx].txd4 &= ~TX_DMA_CHKSUM;
  3143. +
  3144. + if (priv->soc->tso)
  3145. + fe_start_tso(skb, dev, nr_frags, tx);
  3146. +
  3147. + if (skb_shinfo(skb)->gso_segs > 1) {
  3148. + struct iphdr *iph = NULL;
  3149. + struct tcphdr *th = NULL;
  3150. + struct ipv6hdr *ip6h = NULL;
  3151. +
  3152. + ip6h = (struct ipv6hdr *) skb_network_header(skb);
  3153. + iph = (struct iphdr *) skb_network_header(skb);
  3154. + if ((iph->version == 4) && (iph->protocol == IPPROTO_TCP)) {
  3155. + th = (struct tcphdr *)skb_transport_header(skb);
  3156. + priv->tx_dma[tx].txd4 |= BIT(28);
  3157. + th->check = htons(skb_shinfo(skb)->gso_size);
  3158. + dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE);
  3159. + } else if ((ip6h->version == 6) && (ip6h->nexthdr == NEXTHDR_TCP)) {
  3160. + th = (struct tcphdr *)skb_transport_header(skb);
  3161. + priv->tx_dma[tx].txd4 |= BIT(28);
  3162. + th->check = htons(skb_shinfo(skb)->gso_size);
  3163. + dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE);
  3164. + }
  3165. + }
  3166. +
  3167. + for (i = 0; i < tx_num; i++)
  3168. + dma_cache_sync(NULL, &priv->tx_dma[tx + i], sizeof(struct fe_tx_dma), DMA_TO_DEVICE);
  3169. +
  3170. + dev->stats.tx_packets++;
  3171. + dev->stats.tx_bytes += skb->len;
  3172. +
  3173. + wmb();
  3174. + fe_reg_w32(tx_next, FE_REG_TX_CTX_IDX0);
  3175. + netdev_sent_queue(dev, skb->len);
  3176. +
  3177. + spin_unlock(&priv->page_lock);
  3178. +
  3179. + return NETDEV_TX_OK;
  3180. +}
  3181. +
  3182. +static int fe_poll_rx(struct napi_struct *napi, int budget)
  3183. +{
  3184. + struct fe_priv *priv = container_of(napi, struct fe_priv, rx_napi);
  3185. + int idx = fe_reg_r32(FE_REG_RX_CALC_IDX0);
  3186. + int complete = 0;
  3187. + int rx = 0;
  3188. +
  3189. + while ((rx < budget) && !complete) {
  3190. + idx = (idx + 1) % NUM_DMA_DESC;
  3191. +
  3192. + if (priv->rx_dma[idx].rxd2 & RX_DMA_DONE) {
  3193. + struct sk_buff *new_skb = fe_alloc_skb(priv);
  3194. +
  3195. + if (new_skb) {
  3196. + int pktlen = RX_DMA_PLEN0(priv->rx_dma[idx].rxd2);
  3197. + dma_addr_t dma_addr;
  3198. +
  3199. + dma_unmap_single(&priv->netdev->dev, priv->rx_dma[idx].rxd1,
  3200. + MAX_RX_LENGTH, DMA_FROM_DEVICE);
  3201. +
  3202. + skb_put(priv->rx_skb[idx], pktlen);
  3203. + priv->rx_skb[idx]->dev = priv->netdev;
  3204. + priv->rx_skb[idx]->protocol = eth_type_trans(priv->rx_skb[idx], priv->netdev);
  3205. + if (priv->rx_dma[idx].rxd4 & priv->soc->checksum_bit)
  3206. + priv->rx_skb[idx]->ip_summed = CHECKSUM_UNNECESSARY;
  3207. + else
  3208. + priv->rx_skb[idx]->ip_summed = CHECKSUM_NONE;
  3209. + priv->netdev->stats.rx_packets++;
  3210. + priv->netdev->stats.rx_bytes += pktlen;
  3211. +
  3212. +#ifdef CONFIG_INET_LRO
  3213. + if (priv->soc->get_skb_header && priv->rx_skb[idx]->ip_summed == CHECKSUM_UNNECESSARY)
  3214. + lro_receive_skb(&priv->lro_mgr, priv->rx_skb[idx], NULL);
  3215. + else
  3216. +#endif
  3217. + netif_receive_skb(priv->rx_skb[idx]);
  3218. +
  3219. + priv->rx_skb[idx] = new_skb;
  3220. +
  3221. + dma_addr = dma_map_single(&priv->netdev->dev,
  3222. + new_skb->data,
  3223. + MAX_RX_LENGTH,
  3224. + DMA_FROM_DEVICE);
  3225. + priv->rx_dma[idx].rxd1 = (unsigned int) dma_addr;
  3226. + wmb();
  3227. + } else {
  3228. + priv->netdev->stats.rx_dropped++;
  3229. + }
  3230. +
  3231. + if (priv->soc->rx_dma)
  3232. + priv->soc->rx_dma(priv, idx, MAX_RX_LENGTH);
  3233. + else
  3234. + priv->rx_dma[idx].rxd2 = RX_DMA_LSO;
  3235. + fe_reg_w32(idx, FE_REG_RX_CALC_IDX0);
  3236. +
  3237. + rx++;
  3238. + } else {
  3239. + complete = 1;
  3240. + }
  3241. + }
  3242. +
  3243. +#ifdef CONFIG_INET_LRO
  3244. + if (priv->soc->get_skb_header)
  3245. + lro_flush_all(&priv->lro_mgr);
  3246. +#endif
  3247. + if (complete) {
  3248. + napi_complete(&priv->rx_napi);
  3249. + fe_int_enable(priv->soc->rx_dly_int);
  3250. + }
  3251. +
  3252. + return rx;
  3253. +}
  3254. +
  3255. +static void fe_tx_housekeeping(unsigned long ptr)
  3256. +{
  3257. + struct net_device *dev = (struct net_device*)ptr;
  3258. + struct fe_priv *priv = netdev_priv(dev);
  3259. + unsigned int bytes_compl = 0;
  3260. + unsigned int pkts_compl = 0;
  3261. +
  3262. + spin_lock(&priv->page_lock);
  3263. + while (1) {
  3264. + struct fe_tx_dma *txd;
  3265. +
  3266. + txd = &priv->tx_dma[priv->tx_free_idx];
  3267. +
  3268. + if (!(txd->txd2 & TX_DMA_DONE) || !(priv->tx_skb[priv->tx_free_idx]))
  3269. + break;
  3270. +
  3271. + if (priv->tx_skb[priv->tx_free_idx] != (struct sk_buff *) DMA_DUMMY_DESC) {
  3272. + bytes_compl += priv->tx_skb[priv->tx_free_idx]->len;
  3273. + dev_kfree_skb_irq(priv->tx_skb[priv->tx_free_idx]);
  3274. + }
  3275. + pkts_compl++;
  3276. + priv->tx_skb[priv->tx_free_idx] = NULL;
  3277. + priv->tx_free_idx++;
  3278. + if (priv->tx_free_idx >= NUM_DMA_DESC)
  3279. + priv->tx_free_idx = 0;
  3280. + }
  3281. +
  3282. + netdev_completed_queue(priv->netdev, pkts_compl, bytes_compl);
  3283. + spin_unlock(&priv->page_lock);
  3284. +
  3285. + fe_int_enable(priv->soc->tx_dly_int);
  3286. +}
  3287. +
  3288. +static void fe_tx_timeout(struct net_device *dev)
  3289. +{
  3290. + struct fe_priv *priv = netdev_priv(dev);
  3291. +
  3292. + tasklet_schedule(&priv->tx_tasklet);
  3293. + priv->netdev->stats.tx_errors++;
  3294. + netdev_err(dev, "transmit timed out, waking up the queue\n");
  3295. + netif_wake_queue(dev);
  3296. +}
  3297. +
  3298. +static irqreturn_t fe_handle_irq(int irq, void *dev)
  3299. +{
  3300. + struct fe_priv *priv = netdev_priv(dev);
  3301. + unsigned int status;
  3302. + unsigned int mask;
  3303. +
  3304. + status = fe_reg_r32(FE_REG_FE_INT_STATUS);
  3305. + mask = fe_reg_r32(FE_REG_FE_INT_ENABLE);
  3306. +
  3307. + if (!(status & mask))
  3308. + return IRQ_NONE;
  3309. +
  3310. + if (status & priv->soc->rx_dly_int) {
  3311. + fe_int_disable(priv->soc->rx_dly_int);
  3312. + napi_schedule(&priv->rx_napi);
  3313. + }
  3314. +
  3315. + if (status & priv->soc->tx_dly_int) {
  3316. + fe_int_disable(priv->soc->tx_dly_int);
  3317. + tasklet_schedule(&priv->tx_tasklet);
  3318. + }
  3319. +
  3320. + fe_reg_w32(status, FE_REG_FE_INT_STATUS);
  3321. +
  3322. + return IRQ_HANDLED;
  3323. +}
  3324. +
  3325. +static int fe_hw_init(struct net_device *dev)
  3326. +{
  3327. + struct fe_priv *priv = netdev_priv(dev);
  3328. + int err;
  3329. +
  3330. + err = devm_request_irq(priv->device, dev->irq, fe_handle_irq, 0,
  3331. + dev_name(priv->device), dev);
  3332. + if (err)
  3333. + return err;
  3334. +
  3335. + err = fe_alloc_rx(priv);
  3336. + if (!err)
  3337. + err = fe_alloc_tx(priv);
  3338. + if (err)
  3339. + return err;
  3340. +
  3341. + if (priv->soc->set_mac)
  3342. + priv->soc->set_mac(priv, dev->dev_addr);
  3343. + else
  3344. + fe_hw_set_macaddr(priv, dev->dev_addr);
  3345. +
  3346. + fe_reg_w32(FE_DELAY_INIT, FE_REG_DLY_INT_CFG);
  3347. +
  3348. + fe_int_disable(priv->soc->tx_dly_int | priv->soc->rx_dly_int);
  3349. +
  3350. + tasklet_init(&priv->tx_tasklet, fe_tx_housekeeping, (unsigned long)dev);
  3351. +
  3352. + if (priv->soc->fwd_config) {
  3353. + priv->soc->fwd_config(priv);
  3354. + } else {
  3355. + unsigned long sysclk = priv->sysclk;
  3356. +
  3357. + if (!sysclk) {
  3358. + netdev_err(dev, "unable to get clock\n");
  3359. + return -EINVAL;
  3360. + }
  3361. +
  3362. + sysclk /= FE_US_CYC_CNT_DIVISOR;
  3363. + sysclk <<= FE_US_CYC_CNT_SHIFT;
  3364. +
  3365. + fe_w32((fe_r32(FE_FE_GLO_CFG) &
  3366. + ~(FE_US_CYC_CNT_MASK << FE_US_CYC_CNT_SHIFT)) | sysclk,
  3367. + FE_FE_GLO_CFG);
  3368. +
  3369. + fe_w32(fe_r32(FE_GDMA1_FWD_CFG) & ~0xffff, FE_GDMA1_FWD_CFG);
  3370. + fe_w32(fe_r32(FE_GDMA1_FWD_CFG) | (FE_GDM1_ICS_EN | FE_GDM1_TCS_EN | FE_GDM1_UCS_EN),
  3371. + FE_GDMA1_FWD_CFG);
  3372. + fe_w32(fe_r32(FE_CDMA_CSG_CFG) | (FE_ICS_GEN_EN | FE_TCS_GEN_EN | FE_UCS_GEN_EN),
  3373. + FE_CDMA_CSG_CFG);
  3374. + fe_w32(FE_PSE_FQFC_CFG_INIT, FE_PSE_FQ_CFG);
  3375. + }
  3376. +
  3377. + fe_w32(1, FE_FE_RST_GL);
  3378. + fe_w32(0, FE_FE_RST_GL);
  3379. +
  3380. + return 0;
  3381. +}
  3382. +
  3383. +static int fe_open(struct net_device *dev)
  3384. +{
  3385. + struct fe_priv *priv = netdev_priv(dev);
  3386. + unsigned long flags;
  3387. + u32 val;
  3388. +
  3389. + spin_lock_irqsave(&priv->page_lock, flags);
  3390. + napi_enable(&priv->rx_napi);
  3391. +
  3392. + val = FE_TX_WB_DDONE | FE_RX_DMA_EN | FE_TX_DMA_EN;
  3393. + val |= priv->soc->pdma_glo_cfg;
  3394. + fe_reg_w32(val, FE_REG_PDMA_GLO_CFG);
  3395. +
  3396. + spin_unlock_irqrestore(&priv->page_lock, flags);
  3397. +
  3398. + if (priv->phy)
  3399. + priv->phy->start(priv);
  3400. +
  3401. + if (priv->soc->has_carrier && priv->soc->has_carrier(priv))
  3402. + netif_carrier_on(dev);
  3403. +
  3404. + netif_start_queue(dev);
  3405. + fe_int_enable(priv->soc->tx_dly_int | priv->soc->rx_dly_int);
  3406. +
  3407. + return 0;
  3408. +}
  3409. +
  3410. +static int fe_stop(struct net_device *dev)
  3411. +{
  3412. + struct fe_priv *priv = netdev_priv(dev);
  3413. + unsigned long flags;
  3414. +
  3415. + fe_int_disable(priv->soc->tx_dly_int | priv->soc->rx_dly_int);
  3416. +
  3417. + netif_stop_queue(dev);
  3418. +
  3419. + if (priv->phy)
  3420. + priv->phy->stop(priv);
  3421. +
  3422. + spin_lock_irqsave(&priv->page_lock, flags);
  3423. + napi_disable(&priv->rx_napi);
  3424. +
  3425. + fe_reg_w32(fe_reg_r32(FE_REG_PDMA_GLO_CFG) &
  3426. + ~(FE_TX_WB_DDONE | FE_RX_DMA_EN | FE_TX_DMA_EN),
  3427. + FE_REG_PDMA_GLO_CFG);
  3428. + spin_unlock_irqrestore(&priv->page_lock, flags);
  3429. +
  3430. + return 0;
  3431. +}
  3432. +
  3433. +static int __init fe_init(struct net_device *dev)
  3434. +{
  3435. + struct fe_priv *priv = netdev_priv(dev);
  3436. + struct device_node *port;
  3437. + int err;
  3438. +
  3439. + BUG_ON(!priv->soc->reset_fe);
  3440. + priv->soc->reset_fe();
  3441. +
  3442. + if (priv->soc->switch_init)
  3443. + priv->soc->switch_init(priv);
  3444. +
  3445. + net_srandom(jiffies);
  3446. + memcpy(dev->dev_addr, priv->soc->mac, ETH_ALEN);
  3447. + of_get_mac_address_mtd(priv->device->of_node, dev->dev_addr);
  3448. +
  3449. + err = fe_mdio_init(priv);
  3450. + if (err)
  3451. + return err;
  3452. +
  3453. + if (priv->phy) {
  3454. + err = priv->phy->connect(priv);
  3455. + if (err)
  3456. + goto err_mdio_cleanup;
  3457. + }
  3458. +
  3459. + if (priv->soc->port_init)
  3460. + for_each_child_of_node(priv->device->of_node, port)
  3461. + if (of_device_is_compatible(port, "ralink,eth-port") && of_device_is_available(port))
  3462. + priv->soc->port_init(priv, port);
  3463. +
  3464. + err = fe_hw_init(dev);
  3465. + if (err)
  3466. + goto err_phy_disconnect;
  3467. +
  3468. + if (priv->soc->switch_config)
  3469. + priv->soc->switch_config(priv);
  3470. +
  3471. + return 0;
  3472. +
  3473. +err_phy_disconnect:
  3474. + if (priv->phy)
  3475. + priv->phy->disconnect(priv);
  3476. +err_mdio_cleanup:
  3477. + fe_mdio_cleanup(priv);
  3478. +
  3479. + return err;
  3480. +}
  3481. +
  3482. +static void fe_uninit(struct net_device *dev)
  3483. +{
  3484. + struct fe_priv *priv = netdev_priv(dev);
  3485. +
  3486. + tasklet_kill(&priv->tx_tasklet);
  3487. +
  3488. + if (priv->phy)
  3489. + priv->phy->disconnect(priv);
  3490. + fe_mdio_cleanup(priv);
  3491. +
  3492. + fe_reg_w32(0, FE_REG_FE_INT_ENABLE);
  3493. + free_irq(dev->irq, dev);
  3494. +
  3495. + fe_free_dma(priv);
  3496. +}
  3497. +
  3498. +static const struct net_device_ops fe_netdev_ops = {
  3499. + .ndo_init = fe_init,
  3500. + .ndo_uninit = fe_uninit,
  3501. + .ndo_open = fe_open,
  3502. + .ndo_stop = fe_stop,
  3503. + .ndo_start_xmit = fe_start_xmit,
  3504. + .ndo_tx_timeout = fe_tx_timeout,
  3505. + .ndo_set_mac_address = fe_set_mac_address,
  3506. + .ndo_change_mtu = eth_change_mtu,
  3507. + .ndo_validate_addr = eth_validate_addr,
  3508. +};
  3509. +
  3510. +static int fe_probe(struct platform_device *pdev)
  3511. +{
  3512. + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  3513. + const struct of_device_id *match;
  3514. + struct fe_soc_data *soc = NULL;
  3515. + struct net_device *netdev;
  3516. + struct fe_priv *priv;
  3517. + struct clk *sysclk;
  3518. + int err;
  3519. +
  3520. + device_reset(&pdev->dev);
  3521. +
  3522. + match = of_match_device(of_fe_match, &pdev->dev);
  3523. + soc = (struct fe_soc_data *) match->data;
  3524. +
  3525. + if (soc->init_data)
  3526. + soc->init_data(soc);
  3527. + if (soc->reg_table)
  3528. + fe_reg_table = soc->reg_table;
  3529. +
  3530. + fe_base = devm_request_and_ioremap(&pdev->dev, res);
  3531. + if (!fe_base)
  3532. + return -ENOMEM;
  3533. +
  3534. + netdev = alloc_etherdev(sizeof(struct fe_priv));
  3535. + if (!netdev) {
  3536. + dev_err(&pdev->dev, "alloc_etherdev failed\n");
  3537. + return -ENOMEM;
  3538. + }
  3539. +
  3540. + strcpy(netdev->name, "eth%d");
  3541. + netdev->netdev_ops = &fe_netdev_ops;
  3542. + netdev->base_addr = (unsigned long) fe_base;
  3543. + netdev->watchdog_timeo = TX_TIMEOUT;
  3544. + netdev->features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
  3545. +
  3546. + if (fe_reg_table[FE_REG_FE_DMA_VID_BASE])
  3547. + netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
  3548. +
  3549. + if (soc->tso) {
  3550. + dev_info(&pdev->dev, "Enabling TSO\n");
  3551. + netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_IPV6_CSUM;
  3552. + }
  3553. +
  3554. + netdev->hw_features = netdev->vlan_features = netdev->features;
  3555. +
  3556. + netdev->irq = platform_get_irq(pdev, 0);
  3557. + if (netdev->irq < 0) {
  3558. + dev_err(&pdev->dev, "no IRQ resource found\n");
  3559. + kfree(netdev);
  3560. + return -ENXIO;
  3561. + }
  3562. +
  3563. + priv = netdev_priv(netdev);
  3564. + memset(priv, 0, sizeof(struct fe_priv));
  3565. + spin_lock_init(&priv->page_lock);
  3566. +
  3567. + sysclk = devm_clk_get(&pdev->dev, NULL);
  3568. + if (!IS_ERR(sysclk))
  3569. + priv->sysclk = clk_get_rate(sysclk);
  3570. +
  3571. + priv->netdev = netdev;
  3572. + priv->device = &pdev->dev;
  3573. + priv->soc = soc;
  3574. +
  3575. + err = register_netdev(netdev);
  3576. + if (err) {
  3577. + dev_err(&pdev->dev, "error bringing up device\n");
  3578. + kfree(netdev);
  3579. + return err;
  3580. + }
  3581. + netif_napi_add(netdev, &priv->rx_napi, fe_poll_rx, 32);
  3582. +
  3583. +#ifdef CONFIG_INET_LRO
  3584. + if (priv->soc->get_skb_header) {
  3585. + priv->lro_mgr.dev = netdev;
  3586. + memset(&priv->lro_mgr.stats, 0, sizeof(priv->lro_mgr.stats));
  3587. + priv->lro_mgr.features = LRO_F_NAPI;
  3588. + priv->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
  3589. + priv->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
  3590. + priv->lro_mgr.max_desc = ARRAY_SIZE(priv->lro_arr);
  3591. + priv->lro_mgr.max_aggr = 64;
  3592. + priv->lro_mgr.frag_align_pad = 0;
  3593. + priv->lro_mgr.lro_arr = priv->lro_arr;
  3594. + priv->lro_mgr.get_skb_header = priv->soc->get_skb_header;
  3595. + }
  3596. +#endif
  3597. +
  3598. + platform_set_drvdata(pdev, netdev);
  3599. +
  3600. + netdev_info(netdev, "done loading\n");
  3601. +
  3602. + return 0;
  3603. +}
  3604. +
  3605. +static int fe_remove(struct platform_device *pdev)
  3606. +{
  3607. + struct net_device *dev = platform_get_drvdata(pdev);
  3608. + struct fe_priv *priv = netdev_priv(dev);
  3609. +
  3610. + netif_stop_queue(dev);
  3611. + netif_napi_del(&priv->rx_napi);
  3612. +
  3613. + unregister_netdev(dev);
  3614. + free_netdev(dev);
  3615. +
  3616. + return 0;
  3617. +}
  3618. +
  3619. +static struct platform_driver fe_driver = {
  3620. + .probe = fe_probe,
  3621. + .remove = fe_remove,
  3622. + .driver = {
  3623. + .name = "ralink_soc_eth",
  3624. + .owner = THIS_MODULE,
  3625. + .of_match_table = of_fe_match,
  3626. + },
  3627. +};
  3628. +
  3629. +static int __init init_rtfe(void)
  3630. +{
  3631. + int ret;
  3632. +
  3633. + ret = rtesw_init();
  3634. + if (ret)
  3635. + return ret;
  3636. +
  3637. + ret = platform_driver_register(&fe_driver);
  3638. + if (ret)
  3639. + rtesw_exit();
  3640. +
  3641. + return ret;
  3642. +}
  3643. +
  3644. +static void __exit exit_rtfe(void)
  3645. +{
  3646. + platform_driver_unregister(&fe_driver);
  3647. + rtesw_exit();
  3648. +}
  3649. +
  3650. +module_init(init_rtfe);
  3651. +module_exit(exit_rtfe);
  3652. +
  3653. +MODULE_LICENSE("GPL");
  3654. +MODULE_AUTHOR("John Crispin <[email protected]>");
  3655. +MODULE_DESCRIPTION("Ethernet driver for Ralink SoC");
  3656. --- /dev/null
  3657. +++ b/drivers/net/ethernet/ralink/ralink_soc_eth.h
  3658. @@ -0,0 +1,384 @@
  3659. +/*
  3660. + * This program is free software; you can redistribute it and/or modify
  3661. + * it under the terms of the GNU General Public License as published by
  3662. + * the Free Software Foundation; version 2 of the License
  3663. + *
  3664. + * This program is distributed in the hope that it will be useful,
  3665. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3666. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3667. + * GNU General Public License for more details.
  3668. + *
  3669. + * You should have received a copy of the GNU General Public License
  3670. + * along with this program; if not, write to the Free Software
  3671. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  3672. + *
  3673. + * based on Ralink SDK3.3
  3674. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  3675. + */
  3676. +
  3677. +#ifndef FE_ETH_H
  3678. +#define FE_ETH_H
  3679. +
  3680. +#include <linux/mii.h>
  3681. +#include <linux/interrupt.h>
  3682. +#include <linux/netdevice.h>
  3683. +#include <linux/dma-mapping.h>
  3684. +#include <linux/phy.h>
  3685. +#include <linux/inet_lro.h>
  3686. +
  3687. +
  3688. +enum fe_reg {
  3689. + FE_REG_PDMA_GLO_CFG = 0,
  3690. + FE_REG_PDMA_RST_CFG,
  3691. + FE_REG_DLY_INT_CFG,
  3692. + FE_REG_TX_BASE_PTR0,
  3693. + FE_REG_TX_MAX_CNT0,
  3694. + FE_REG_TX_CTX_IDX0,
  3695. + FE_REG_RX_BASE_PTR0,
  3696. + FE_REG_RX_MAX_CNT0,
  3697. + FE_REG_RX_CALC_IDX0,
  3698. + FE_REG_FE_INT_ENABLE,
  3699. + FE_REG_FE_INT_STATUS,
  3700. + FE_REG_FE_DMA_VID_BASE,
  3701. + FE_REG_COUNT
  3702. +};
  3703. +
  3704. +#define NUM_DMA_DESC 0x100
  3705. +
  3706. +#define FE_DELAY_EN_INT 0x80
  3707. +#define FE_DELAY_MAX_INT 0x04
  3708. +#define FE_DELAY_MAX_TOUT 0x04
  3709. +#define FE_DELAY_CHAN (((FE_DELAY_EN_INT | FE_DELAY_MAX_INT) << 8) | FE_DELAY_MAX_TOUT)
  3710. +#define FE_DELAY_INIT ((FE_DELAY_CHAN << 16) | FE_DELAY_CHAN)
  3711. +#define FE_PSE_FQFC_CFG_INIT 0x80504000
  3712. +
  3713. +/* interrupt bits */
  3714. +#define FE_CNT_PPE_AF BIT(31)
  3715. +#define FE_CNT_GDM_AF BIT(29)
  3716. +#define FE_PSE_P2_FC BIT(26)
  3717. +#define FE_PSE_BUF_DROP BIT(24)
  3718. +#define FE_GDM_OTHER_DROP BIT(23)
  3719. +#define FE_PSE_P1_FC BIT(22)
  3720. +#define FE_PSE_P0_FC BIT(21)
  3721. +#define FE_PSE_FQ_EMPTY BIT(20)
  3722. +#define FE_GE1_STA_CHG BIT(18)
  3723. +#define FE_TX_COHERENT BIT(17)
  3724. +#define FE_RX_COHERENT BIT(16)
  3725. +#define FE_TX_DONE_INT3 BIT(11)
  3726. +#define FE_TX_DONE_INT2 BIT(10)
  3727. +#define FE_TX_DONE_INT1 BIT(9)
  3728. +#define FE_TX_DONE_INT0 BIT(8)
  3729. +#define FE_RX_DONE_INT0 BIT(2)
  3730. +#define FE_TX_DLY_INT BIT(1)
  3731. +#define FE_RX_DLY_INT BIT(0)
  3732. +
  3733. +#define RT5350_RX_DLY_INT BIT(30)
  3734. +#define RT5350_TX_DLY_INT BIT(28)
  3735. +
  3736. +/* registers */
  3737. +#define FE_FE_OFFSET 0x0000
  3738. +#define FE_GDMA_OFFSET 0x0020
  3739. +#define FE_PSE_OFFSET 0x0040
  3740. +#define FE_GDMA2_OFFSET 0x0060
  3741. +#define FE_CDMA_OFFSET 0x0080
  3742. +#define FE_DMA_VID0 0x00a8
  3743. +#define FE_PDMA_OFFSET 0x0100
  3744. +#define FE_PPE_OFFSET 0x0200
  3745. +#define FE_CMTABLE_OFFSET 0x0400
  3746. +#define FE_POLICYTABLE_OFFSET 0x1000
  3747. +
  3748. +#define RT5350_PDMA_OFFSET 0x0800
  3749. +#define RT5350_SDM_OFFSET 0x0c00
  3750. +
  3751. +#define FE_MDIO_ACCESS (FE_FE_OFFSET + 0x00)
  3752. +#define FE_MDIO_CFG (FE_FE_OFFSET + 0x04)
  3753. +#define FE_FE_GLO_CFG (FE_FE_OFFSET + 0x08)
  3754. +#define FE_FE_RST_GL (FE_FE_OFFSET + 0x0C)
  3755. +#define FE_FE_INT_STATUS (FE_FE_OFFSET + 0x10)
  3756. +#define FE_FE_INT_ENABLE (FE_FE_OFFSET + 0x14)
  3757. +#define FE_MDIO_CFG2 (FE_FE_OFFSET + 0x18)
  3758. +#define FE_FOC_TS_T (FE_FE_OFFSET + 0x1C)
  3759. +
  3760. +#define FE_GDMA1_FWD_CFG (FE_GDMA_OFFSET + 0x00)
  3761. +#define FE_GDMA1_SCH_CFG (FE_GDMA_OFFSET + 0x04)
  3762. +#define FE_GDMA1_SHPR_CFG (FE_GDMA_OFFSET + 0x08)
  3763. +#define FE_GDMA1_MAC_ADRL (FE_GDMA_OFFSET + 0x0C)
  3764. +#define FE_GDMA1_MAC_ADRH (FE_GDMA_OFFSET + 0x10)
  3765. +
  3766. +#define FE_GDMA2_FWD_CFG (FE_GDMA2_OFFSET + 0x00)
  3767. +#define FE_GDMA2_SCH_CFG (FE_GDMA2_OFFSET + 0x04)
  3768. +#define FE_GDMA2_SHPR_CFG (FE_GDMA2_OFFSET + 0x08)
  3769. +#define FE_GDMA2_MAC_ADRL (FE_GDMA2_OFFSET + 0x0C)
  3770. +#define FE_GDMA2_MAC_ADRH (FE_GDMA2_OFFSET + 0x10)
  3771. +
  3772. +#define FE_PSE_FQ_CFG (FE_PSE_OFFSET + 0x00)
  3773. +#define FE_CDMA_FC_CFG (FE_PSE_OFFSET + 0x04)
  3774. +#define FE_GDMA1_FC_CFG (FE_PSE_OFFSET + 0x08)
  3775. +#define FE_GDMA2_FC_CFG (FE_PSE_OFFSET + 0x0C)
  3776. +
  3777. +#define FE_CDMA_CSG_CFG (FE_CDMA_OFFSET + 0x00)
  3778. +#define FE_CDMA_SCH_CFG (FE_CDMA_OFFSET + 0x04)
  3779. +
  3780. +#define MT7620A_GDMA_OFFSET 0x0600
  3781. +#define MT7620A_GDMA1_FWD_CFG (MT7620A_GDMA_OFFSET + 0x00)
  3782. +#define MT7620A_FE_GDMA1_SCH_CFG (MT7620A_GDMA_OFFSET + 0x04)
  3783. +#define MT7620A_FE_GDMA1_SHPR_CFG (MT7620A_GDMA_OFFSET + 0x08)
  3784. +#define MT7620A_FE_GDMA1_MAC_ADRL (MT7620A_GDMA_OFFSET + 0x0C)
  3785. +#define MT7620A_FE_GDMA1_MAC_ADRH (MT7620A_GDMA_OFFSET + 0x10)
  3786. +
  3787. +#define RT5350_TX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x00)
  3788. +#define RT5350_TX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x04)
  3789. +#define RT5350_TX_CTX_IDX0 (RT5350_PDMA_OFFSET + 0x08)
  3790. +#define RT5350_TX_DTX_IDX0 (RT5350_PDMA_OFFSET + 0x0C)
  3791. +#define RT5350_TX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x10)
  3792. +#define RT5350_TX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x14)
  3793. +#define RT5350_TX_CTX_IDX1 (RT5350_PDMA_OFFSET + 0x18)
  3794. +#define RT5350_TX_DTX_IDX1 (RT5350_PDMA_OFFSET + 0x1C)
  3795. +#define RT5350_TX_BASE_PTR2 (RT5350_PDMA_OFFSET + 0x20)
  3796. +#define RT5350_TX_MAX_CNT2 (RT5350_PDMA_OFFSET + 0x24)
  3797. +#define RT5350_TX_CTX_IDX2 (RT5350_PDMA_OFFSET + 0x28)
  3798. +#define RT5350_TX_DTX_IDX2 (RT5350_PDMA_OFFSET + 0x2C)
  3799. +#define RT5350_TX_BASE_PTR3 (RT5350_PDMA_OFFSET + 0x30)
  3800. +#define RT5350_TX_MAX_CNT3 (RT5350_PDMA_OFFSET + 0x34)
  3801. +#define RT5350_TX_CTX_IDX3 (RT5350_PDMA_OFFSET + 0x38)
  3802. +#define RT5350_TX_DTX_IDX3 (RT5350_PDMA_OFFSET + 0x3C)
  3803. +#define RT5350_RX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x100)
  3804. +#define RT5350_RX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x104)
  3805. +#define RT5350_RX_CALC_IDX0 (RT5350_PDMA_OFFSET + 0x108)
  3806. +#define RT5350_RX_DRX_IDX0 (RT5350_PDMA_OFFSET + 0x10C)
  3807. +#define RT5350_RX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x110)
  3808. +#define RT5350_RX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x114)
  3809. +#define RT5350_RX_CALC_IDX1 (RT5350_PDMA_OFFSET + 0x118)
  3810. +#define RT5350_RX_DRX_IDX1 (RT5350_PDMA_OFFSET + 0x11C)
  3811. +#define RT5350_PDMA_GLO_CFG (RT5350_PDMA_OFFSET + 0x204)
  3812. +#define RT5350_PDMA_RST_CFG (RT5350_PDMA_OFFSET + 0x208)
  3813. +#define RT5350_DLY_INT_CFG (RT5350_PDMA_OFFSET + 0x20c)
  3814. +#define RT5350_FE_INT_STATUS (RT5350_PDMA_OFFSET + 0x220)
  3815. +#define RT5350_FE_INT_ENABLE (RT5350_PDMA_OFFSET + 0x228)
  3816. +#define RT5350_PDMA_SCH_CFG (RT5350_PDMA_OFFSET + 0x280)
  3817. +
  3818. +#define FE_PDMA_GLO_CFG (FE_PDMA_OFFSET + 0x00)
  3819. +#define FE_PDMA_RST_CFG (FE_PDMA_OFFSET + 0x04)
  3820. +#define FE_PDMA_SCH_CFG (FE_PDMA_OFFSET + 0x08)
  3821. +#define FE_DLY_INT_CFG (FE_PDMA_OFFSET + 0x0C)
  3822. +#define FE_TX_BASE_PTR0 (FE_PDMA_OFFSET + 0x10)
  3823. +#define FE_TX_MAX_CNT0 (FE_PDMA_OFFSET + 0x14)
  3824. +#define FE_TX_CTX_IDX0 (FE_PDMA_OFFSET + 0x18)
  3825. +#define FE_TX_DTX_IDX0 (FE_PDMA_OFFSET + 0x1C)
  3826. +#define FE_TX_BASE_PTR1 (FE_PDMA_OFFSET + 0x20)
  3827. +#define FE_TX_MAX_CNT1 (FE_PDMA_OFFSET + 0x24)
  3828. +#define FE_TX_CTX_IDX1 (FE_PDMA_OFFSET + 0x28)
  3829. +#define FE_TX_DTX_IDX1 (FE_PDMA_OFFSET + 0x2C)
  3830. +#define FE_RX_BASE_PTR0 (FE_PDMA_OFFSET + 0x30)
  3831. +#define FE_RX_MAX_CNT0 (FE_PDMA_OFFSET + 0x34)
  3832. +#define FE_RX_CALC_IDX0 (FE_PDMA_OFFSET + 0x38)
  3833. +#define FE_RX_DRX_IDX0 (FE_PDMA_OFFSET + 0x3C)
  3834. +#define FE_TX_BASE_PTR2 (FE_PDMA_OFFSET + 0x40)
  3835. +#define FE_TX_MAX_CNT2 (FE_PDMA_OFFSET + 0x44)
  3836. +#define FE_TX_CTX_IDX2 (FE_PDMA_OFFSET + 0x48)
  3837. +#define FE_TX_DTX_IDX2 (FE_PDMA_OFFSET + 0x4C)
  3838. +#define FE_TX_BASE_PTR3 (FE_PDMA_OFFSET + 0x50)
  3839. +#define FE_TX_MAX_CNT3 (FE_PDMA_OFFSET + 0x54)
  3840. +#define FE_TX_CTX_IDX3 (FE_PDMA_OFFSET + 0x58)
  3841. +#define FE_TX_DTX_IDX3 (FE_PDMA_OFFSET + 0x5C)
  3842. +#define FE_RX_BASE_PTR1 (FE_PDMA_OFFSET + 0x60)
  3843. +#define FE_RX_MAX_CNT1 (FE_PDMA_OFFSET + 0x64)
  3844. +#define FE_RX_CALC_IDX1 (FE_PDMA_OFFSET + 0x68)
  3845. +#define FE_RX_DRX_IDX1 (FE_PDMA_OFFSET + 0x6C)
  3846. +
  3847. +#define RT5350_SDM_CFG (RT5350_SDM_OFFSET + 0x00) //Switch DMA configuration
  3848. +#define RT5350_SDM_RRING (RT5350_SDM_OFFSET + 0x04) //Switch DMA Rx Ring
  3849. +#define RT5350_SDM_TRING (RT5350_SDM_OFFSET + 0x08) //Switch DMA Tx Ring
  3850. +#define RT5350_SDM_MAC_ADRL (RT5350_SDM_OFFSET + 0x0C) //Switch MAC address LSB
  3851. +#define RT5350_SDM_MAC_ADRH (RT5350_SDM_OFFSET + 0x10) //Switch MAC Address MSB
  3852. +#define RT5350_SDM_TPCNT (RT5350_SDM_OFFSET + 0x100) //Switch DMA Tx packet count
  3853. +#define RT5350_SDM_TBCNT (RT5350_SDM_OFFSET + 0x104) //Switch DMA Tx byte count
  3854. +#define RT5350_SDM_RPCNT (RT5350_SDM_OFFSET + 0x108) //Switch DMA rx packet count
  3855. +#define RT5350_SDM_RBCNT (RT5350_SDM_OFFSET + 0x10C) //Switch DMA rx byte count
  3856. +#define RT5350_SDM_CS_ERR (RT5350_SDM_OFFSET + 0x110) //Switch DMA rx checksum error count
  3857. +
  3858. +#define RT5350_SDM_ICS_EN BIT(16)
  3859. +#define RT5350_SDM_TCS_EN BIT(17)
  3860. +#define RT5350_SDM_UCS_EN BIT(18)
  3861. +
  3862. +
  3863. +/* MDIO_CFG register bits */
  3864. +#define FE_MDIO_CFG_AUTO_POLL_EN BIT(29)
  3865. +#define FE_MDIO_CFG_GP1_BP_EN BIT(16)
  3866. +#define FE_MDIO_CFG_GP1_FRC_EN BIT(15)
  3867. +#define FE_MDIO_CFG_GP1_SPEED_10 (0 << 13)
  3868. +#define FE_MDIO_CFG_GP1_SPEED_100 (1 << 13)
  3869. +#define FE_MDIO_CFG_GP1_SPEED_1000 (2 << 13)
  3870. +#define FE_MDIO_CFG_GP1_DUPLEX BIT(12)
  3871. +#define FE_MDIO_CFG_GP1_FC_TX BIT(11)
  3872. +#define FE_MDIO_CFG_GP1_FC_RX BIT(10)
  3873. +#define FE_MDIO_CFG_GP1_LNK_DWN BIT(9)
  3874. +#define FE_MDIO_CFG_GP1_AN_FAIL BIT(8)
  3875. +#define FE_MDIO_CFG_MDC_CLK_DIV_1 (0 << 6)
  3876. +#define FE_MDIO_CFG_MDC_CLK_DIV_2 (1 << 6)
  3877. +#define FE_MDIO_CFG_MDC_CLK_DIV_4 (2 << 6)
  3878. +#define FE_MDIO_CFG_MDC_CLK_DIV_8 (3 << 6)
  3879. +#define FE_MDIO_CFG_TURBO_MII_FREQ BIT(5)
  3880. +#define FE_MDIO_CFG_TURBO_MII_MODE BIT(4)
  3881. +#define FE_MDIO_CFG_RX_CLK_SKEW_0 (0 << 2)
  3882. +#define FE_MDIO_CFG_RX_CLK_SKEW_200 (1 << 2)
  3883. +#define FE_MDIO_CFG_RX_CLK_SKEW_400 (2 << 2)
  3884. +#define FE_MDIO_CFG_RX_CLK_SKEW_INV (3 << 2)
  3885. +#define FE_MDIO_CFG_TX_CLK_SKEW_0 0
  3886. +#define FE_MDIO_CFG_TX_CLK_SKEW_200 1
  3887. +#define FE_MDIO_CFG_TX_CLK_SKEW_400 2
  3888. +#define FE_MDIO_CFG_TX_CLK_SKEW_INV 3
  3889. +
  3890. +/* uni-cast port */
  3891. +#define FE_GDM1_ICS_EN BIT(22)
  3892. +#define FE_GDM1_TCS_EN BIT(21)
  3893. +#define FE_GDM1_UCS_EN BIT(20)
  3894. +#define FE_GDM1_JMB_EN BIT(19)
  3895. +#define FE_GDM1_STRPCRC BIT(16)
  3896. +#define FE_GDM1_UFRC_P_CPU (0 << 12)
  3897. +#define FE_GDM1_UFRC_P_GDMA1 (1 << 12)
  3898. +#define FE_GDM1_UFRC_P_PPE (6 << 12)
  3899. +
  3900. +/* checksums */
  3901. +#define FE_ICS_GEN_EN BIT(2)
  3902. +#define FE_UCS_GEN_EN BIT(1)
  3903. +#define FE_TCS_GEN_EN BIT(0)
  3904. +
  3905. +/* dma ring */
  3906. +#define FE_PST_DRX_IDX0 BIT(16)
  3907. +#define FE_PST_DTX_IDX3 BIT(3)
  3908. +#define FE_PST_DTX_IDX2 BIT(2)
  3909. +#define FE_PST_DTX_IDX1 BIT(1)
  3910. +#define FE_PST_DTX_IDX0 BIT(0)
  3911. +
  3912. +#define FE_TX_WB_DDONE BIT(6)
  3913. +#define FE_RX_DMA_BUSY BIT(3)
  3914. +#define FE_TX_DMA_BUSY BIT(1)
  3915. +#define FE_RX_DMA_EN BIT(2)
  3916. +#define FE_TX_DMA_EN BIT(0)
  3917. +
  3918. +#define FE_PDMA_SIZE_4DWORDS (0 << 4)
  3919. +#define FE_PDMA_SIZE_8DWORDS (1 << 4)
  3920. +#define FE_PDMA_SIZE_16DWORDS (2 << 4)
  3921. +
  3922. +#define FE_US_CYC_CNT_MASK 0xff
  3923. +#define FE_US_CYC_CNT_SHIFT 0x8
  3924. +#define FE_US_CYC_CNT_DIVISOR 1000000
  3925. +
  3926. +#define RX_DMA_PLEN0(_x) (((_x) >> 16) & 0x3fff)
  3927. +#define RX_DMA_LSO BIT(30)
  3928. +#define RX_DMA_DONE BIT(31)
  3929. +#define RX_DMA_L4VALID BIT(30)
  3930. +
  3931. +struct fe_rx_dma {
  3932. + unsigned int rxd1;
  3933. + unsigned int rxd2;
  3934. + unsigned int rxd3;
  3935. + unsigned int rxd4;
  3936. +} __packed __aligned(4);
  3937. +
  3938. +#define TX_DMA_PLEN0_MASK ((0x3fff) << 16)
  3939. +#define TX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16)
  3940. +#define TX_DMA_PLEN1(_x) ((_x) & 0x3fff)
  3941. +#define TX_DMA_LS1 BIT(14)
  3942. +#define TX_DMA_LSO BIT(30)
  3943. +#define TX_DMA_DONE BIT(31)
  3944. +#define TX_DMA_QN(_x) ((_x) << 16)
  3945. +#define TX_DMA_PN(_x) ((_x) << 24)
  3946. +#define TX_DMA_QN_MASK TX_DMA_QN(0x7)
  3947. +#define TX_DMA_PN_MASK TX_DMA_PN(0x7)
  3948. +#define TX_DMA_CHKSUM (0x7 << 29)
  3949. +
  3950. +struct fe_tx_dma {
  3951. + unsigned int txd1;
  3952. + unsigned int txd2;
  3953. + unsigned int txd3;
  3954. + unsigned int txd4;
  3955. +} __packed __aligned(4);
  3956. +
  3957. +struct fe_priv;
  3958. +
  3959. +struct fe_phy {
  3960. + struct phy_device *phy[8];
  3961. + struct device_node *phy_node[8];
  3962. + const __be32 *phy_fixed[8];
  3963. + int duplex[8];
  3964. + int speed[8];
  3965. + int tx_fc[8];
  3966. + int rx_fc[8];
  3967. + spinlock_t lock;
  3968. +
  3969. + int (*connect)(struct fe_priv *priv);
  3970. + void (*disconnect)(struct fe_priv *priv);
  3971. + void (*start)(struct fe_priv *priv);
  3972. + void (*stop)(struct fe_priv *priv);
  3973. +};
  3974. +
  3975. +struct fe_soc_data
  3976. +{
  3977. + unsigned char mac[6];
  3978. + const u32 *reg_table;
  3979. +
  3980. + void (*init_data)(struct fe_soc_data *data);
  3981. + void (*reset_fe)(void);
  3982. + void (*set_mac)(struct fe_priv *priv, unsigned char *mac);
  3983. + void (*fwd_config)(struct fe_priv *priv);
  3984. + void (*tx_dma)(struct fe_priv *priv, int idx, struct sk_buff *skb);
  3985. + void (*rx_dma)(struct fe_priv *priv, int idx, int len);
  3986. + int (*switch_init)(struct fe_priv *priv);
  3987. + int (*switch_config)(struct fe_priv *priv);
  3988. + void (*port_init)(struct fe_priv *priv, struct device_node *port);
  3989. + int (*has_carrier)(struct fe_priv *priv);
  3990. + int (*mdio_init)(struct fe_priv *priv);
  3991. + void (*mdio_cleanup)(struct fe_priv *priv);
  3992. + int (*mdio_write)(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
  3993. + int (*mdio_read)(struct mii_bus *bus, int phy_addr, int phy_reg);
  3994. + void (*mdio_adjust_link)(struct fe_priv *priv, int port);
  3995. + int (*get_skb_header)(struct sk_buff *skb, void **iphdr, void **tcph, u64 *hdr_flags, void *priv);
  3996. +
  3997. + void *swpriv;
  3998. + u32 pdma_glo_cfg;
  3999. + u32 rx_dly_int;
  4000. + u32 tx_dly_int;
  4001. + u32 checksum_bit;
  4002. + u32 tso;
  4003. +
  4004. + int min_pkt_len;
  4005. +};
  4006. +
  4007. +struct fe_priv
  4008. +{
  4009. + spinlock_t page_lock;
  4010. +
  4011. + struct fe_soc_data *soc;
  4012. + struct net_device *netdev;
  4013. + struct device *device;
  4014. + unsigned long sysclk;
  4015. +
  4016. + struct fe_rx_dma *rx_dma;
  4017. + struct napi_struct rx_napi;
  4018. + struct sk_buff *rx_skb[NUM_DMA_DESC];
  4019. + dma_addr_t rx_phys;
  4020. +
  4021. + struct fe_tx_dma *tx_dma;
  4022. + struct tasklet_struct tx_tasklet;
  4023. + struct sk_buff *tx_skb[NUM_DMA_DESC];
  4024. + dma_addr_t tx_phys;
  4025. + unsigned int tx_free_idx;
  4026. +
  4027. + struct fe_phy *phy;
  4028. + struct mii_bus *mii_bus;
  4029. + int mii_irq[PHY_MAX_ADDR];
  4030. +
  4031. + int link[8];
  4032. +
  4033. + struct net_lro_mgr lro_mgr;
  4034. + struct net_lro_desc lro_arr[8];
  4035. +};
  4036. +
  4037. +extern const struct of_device_id of_fe_match[];
  4038. +
  4039. +void fe_w32(u32 val, unsigned reg);
  4040. +u32 fe_r32(unsigned reg);
  4041. +
  4042. +#endif /* FE_ETH_H */
  4043. --- /dev/null
  4044. +++ b/drivers/net/ethernet/ralink/soc_mt7620.c
  4045. @@ -0,0 +1,172 @@
  4046. +/*
  4047. + * This program is free software; you can redistribute it and/or modify
  4048. + * it under the terms of the GNU General Public License as published by
  4049. + * the Free Software Foundation; version 2 of the License
  4050. + *
  4051. + * This program is distributed in the hope that it will be useful,
  4052. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4053. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4054. + * GNU General Public License for more details.
  4055. + *
  4056. + * You should have received a copy of the GNU General Public License
  4057. + * along with this program; if not, write to the Free Software
  4058. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  4059. + *
  4060. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  4061. + */
  4062. +
  4063. +#include <linux/module.h>
  4064. +#include <linux/platform_device.h>
  4065. +#include <linux/if_vlan.h>
  4066. +
  4067. +#include <asm/mach-ralink/ralink_regs.h>
  4068. +
  4069. +#include <mt7620.h>
  4070. +#include "ralink_soc_eth.h"
  4071. +#include "gsw_mt7620a.h"
  4072. +
  4073. +#define MT7620A_CDMA_CSG_CFG 0x400
  4074. +#define MT7620_DMA_VID (MT7620A_CDMA_CSG_CFG | 0x30)
  4075. +#define MT7620A_DMA_2B_OFFSET BIT(31)
  4076. +#define MT7620A_RESET_FE BIT(21)
  4077. +#define MT7620A_RESET_ESW BIT(23)
  4078. +#define MT7620_L4_VALID BIT(23)
  4079. +
  4080. +#define SYSC_REG_RESET_CTRL 0x34
  4081. +#define MAX_RX_LENGTH 1536
  4082. +
  4083. +#define CDMA_ICS_EN BIT(2)
  4084. +#define CDMA_UCS_EN BIT(1)
  4085. +#define CDMA_TCS_EN BIT(0)
  4086. +
  4087. +#define GDMA_ICS_EN BIT(22)
  4088. +#define GDMA_TCS_EN BIT(21)
  4089. +#define GDMA_UCS_EN BIT(20)
  4090. +
  4091. +static const u32 rt5350_reg_table[FE_REG_COUNT] = {
  4092. + [FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
  4093. + [FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
  4094. + [FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
  4095. + [FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
  4096. + [FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
  4097. + [FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
  4098. + [FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
  4099. + [FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
  4100. + [FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
  4101. + [FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
  4102. + [FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
  4103. + [FE_REG_FE_DMA_VID_BASE] = MT7620_DMA_VID,
  4104. +};
  4105. +
  4106. +static void mt7620_fe_reset(void)
  4107. +{
  4108. + rt_sysc_w32(MT7620A_RESET_FE | MT7620A_RESET_ESW, SYSC_REG_RESET_CTRL);
  4109. + rt_sysc_w32(0, SYSC_REG_RESET_CTRL);
  4110. +}
  4111. +
  4112. +static void mt7620_fwd_config(struct fe_priv *priv)
  4113. +{
  4114. + int i;
  4115. +
  4116. + /* frame engine will push VLAN tag regarding to VIDX feild in Tx desc. */
  4117. + for (i = 0; i < 16; i += 2)
  4118. + fe_w32(((i + 1) << 16) + i, MT7620_DMA_VID + (i * 2));
  4119. +
  4120. + fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~7, MT7620A_GDMA1_FWD_CFG);
  4121. + fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) | (GDMA_ICS_EN | GDMA_TCS_EN | GDMA_UCS_EN), MT7620A_GDMA1_FWD_CFG);
  4122. + fe_w32(fe_r32(MT7620A_CDMA_CSG_CFG) | (CDMA_ICS_EN | CDMA_UCS_EN | CDMA_TCS_EN), MT7620A_CDMA_CSG_CFG);
  4123. +}
  4124. +
  4125. +static void mt7620_tx_dma(struct fe_priv *priv, int idx, struct sk_buff *skb)
  4126. +{
  4127. + unsigned int nr_frags = 0;
  4128. + unsigned int len = 0;
  4129. +
  4130. + if (skb) {
  4131. + nr_frags = skb_shinfo(skb)->nr_frags;
  4132. + len = skb->len - skb->data_len;
  4133. + }
  4134. +
  4135. + if (!skb)
  4136. + priv->tx_dma[idx].txd2 = TX_DMA_LSO | TX_DMA_DONE;
  4137. + else if (!nr_frags)
  4138. + priv->tx_dma[idx].txd2 = TX_DMA_LSO | TX_DMA_PLEN0(len);
  4139. + else
  4140. + priv->tx_dma[idx].txd2 = TX_DMA_PLEN0(len);
  4141. +
  4142. + if(skb && vlan_tx_tag_present(skb))
  4143. + priv->tx_dma[idx].txd4 = 0x80 | (vlan_tx_tag_get(skb) >> 13) << 4 | (vlan_tx_tag_get(skb) & 0xF);
  4144. + else
  4145. + priv->tx_dma[idx].txd4 = 0;
  4146. +}
  4147. +
  4148. +static void mt7620_rx_dma(struct fe_priv *priv, int idx, int len)
  4149. +{
  4150. + priv->rx_dma[idx].rxd2 = RX_DMA_PLEN0(len);
  4151. +}
  4152. +
  4153. +#ifdef CONFIG_INET_LRO
  4154. +static int
  4155. +mt7620_get_skb_header(struct sk_buff *skb, void **iphdr, void **tcph,
  4156. + u64 *hdr_flags, void *_priv)
  4157. +{
  4158. + struct iphdr *iph = NULL;
  4159. + int vhdr_len = 0;
  4160. +
  4161. + /*
  4162. + * Make sure that this packet is Ethernet II, is not VLAN
  4163. + * tagged, is IPv4, has a valid IP header, and is TCP.
  4164. + */
  4165. + if (skb->protocol == 0x0081)
  4166. + vhdr_len = VLAN_HLEN;
  4167. +
  4168. + iph = (struct iphdr *)(skb->data + vhdr_len);
  4169. + if(iph->protocol != IPPROTO_TCP)
  4170. + return -1;
  4171. +
  4172. + *iphdr = iph;
  4173. + *tcph = skb->data + (iph->ihl << 2) + vhdr_len;
  4174. + *hdr_flags = LRO_IPV4 | LRO_TCP;
  4175. +
  4176. + return 0;
  4177. +}
  4178. +#endif
  4179. +
  4180. +static void mt7620_init_data(struct fe_soc_data *data)
  4181. +{
  4182. + if (mt7620_get_eco() >= 5)
  4183. + data->tso = 1;
  4184. +}
  4185. +
  4186. +static struct fe_soc_data mt7620_data = {
  4187. + .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
  4188. + .init_data = mt7620_init_data,
  4189. + .reset_fe = mt7620_fe_reset,
  4190. + .set_mac = mt7620_set_mac,
  4191. + .fwd_config = mt7620_fwd_config,
  4192. + .tx_dma = mt7620_tx_dma,
  4193. + .rx_dma = mt7620_rx_dma,
  4194. + .switch_init = mt7620_gsw_probe,
  4195. + .switch_config = mt7620_gsw_config,
  4196. + .port_init = mt7620_port_init,
  4197. + .min_pkt_len = 0,
  4198. + .reg_table = rt5350_reg_table,
  4199. + .pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS | MT7620A_DMA_2B_OFFSET,
  4200. + .rx_dly_int = RT5350_RX_DLY_INT,
  4201. + .tx_dly_int = RT5350_TX_DLY_INT,
  4202. + .checksum_bit = MT7620_L4_VALID,
  4203. + .has_carrier = mt7620a_has_carrier,
  4204. + .mdio_read = mt7620_mdio_read,
  4205. + .mdio_write = mt7620_mdio_write,
  4206. + .mdio_adjust_link = mt7620_mdio_link_adjust,
  4207. +#ifdef CONFIG_INET_LRO
  4208. + .get_skb_header = mt7620_get_skb_header,
  4209. +#endif
  4210. +};
  4211. +
  4212. +const struct of_device_id of_fe_match[] = {
  4213. + { .compatible = "ralink,mt7620a-eth", .data = &mt7620_data },
  4214. + {},
  4215. +};
  4216. +
  4217. +MODULE_DEVICE_TABLE(of, of_fe_match);
  4218. --- /dev/null
  4219. +++ b/drivers/net/ethernet/ralink/soc_rt2880.c
  4220. @@ -0,0 +1,51 @@
  4221. +/*
  4222. + * This program is free software; you can redistribute it and/or modify
  4223. + * it under the terms of the GNU General Public License as published by
  4224. + * the Free Software Foundation; version 2 of the License
  4225. + *
  4226. + * This program is distributed in the hope that it will be useful,
  4227. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4228. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4229. + * GNU General Public License for more details.
  4230. + *
  4231. + * You should have received a copy of the GNU General Public License
  4232. + * along with this program; if not, write to the Free Software
  4233. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  4234. + *
  4235. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  4236. + */
  4237. +
  4238. +#include <linux/module.h>
  4239. +
  4240. +#include <asm/mach-ralink/ralink_regs.h>
  4241. +
  4242. +#include "ralink_soc_eth.h"
  4243. +#include "mdio_rt2880.h"
  4244. +
  4245. +#define SYSC_REG_RESET_CTRL 0x034
  4246. +#define RT2880_RESET_FE BIT(18)
  4247. +
  4248. +void rt2880_fe_reset(void)
  4249. +{
  4250. + rt_sysc_w32(RT2880_RESET_FE, SYSC_REG_RESET_CTRL);
  4251. +}
  4252. +
  4253. +struct fe_soc_data rt2880_data = {
  4254. + .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
  4255. + .reset_fe = rt2880_fe_reset,
  4256. + .min_pkt_len = 64,
  4257. + .pdma_glo_cfg = FE_PDMA_SIZE_4DWORDS,
  4258. + .checksum_bit = RX_DMA_L4VALID,
  4259. + .rx_dly_int = FE_RX_DLY_INT,
  4260. + .tx_dly_int = FE_TX_DLY_INT,
  4261. + .mdio_read = rt2880_mdio_read,
  4262. + .mdio_write = rt2880_mdio_write,
  4263. + .mdio_adjust_link = rt2880_mdio_link_adjust,
  4264. +};
  4265. +
  4266. +const struct of_device_id of_fe_match[] = {
  4267. + { .compatible = "ralink,rt2880-eth", .data = &rt2880_data },
  4268. + {},
  4269. +};
  4270. +
  4271. +MODULE_DEVICE_TABLE(of, of_fe_match);
  4272. --- /dev/null
  4273. +++ b/drivers/net/ethernet/ralink/soc_rt305x.c
  4274. @@ -0,0 +1,113 @@
  4275. +/*
  4276. + * This program is free software; you can redistribute it and/or modify
  4277. + * it under the terms of the GNU General Public License as published by
  4278. + * the Free Software Foundation; version 2 of the License
  4279. + *
  4280. + * This program is distributed in the hope that it will be useful,
  4281. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4282. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4283. + * GNU General Public License for more details.
  4284. + *
  4285. + * You should have received a copy of the GNU General Public License
  4286. + * along with this program; if not, write to the Free Software
  4287. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  4288. + *
  4289. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  4290. + */
  4291. +
  4292. +#include <linux/module.h>
  4293. +
  4294. +#include <asm/mach-ralink/ralink_regs.h>
  4295. +
  4296. +#include "ralink_soc_eth.h"
  4297. +
  4298. +#define RT305X_RESET_FE BIT(21)
  4299. +#define RT305X_RESET_ESW BIT(23)
  4300. +#define SYSC_REG_RESET_CTRL 0x034
  4301. +
  4302. +static const u32 rt5350_reg_table[FE_REG_COUNT] = {
  4303. + [FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
  4304. + [FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
  4305. + [FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
  4306. + [FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
  4307. + [FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
  4308. + [FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
  4309. + [FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
  4310. + [FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
  4311. + [FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
  4312. + [FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
  4313. + [FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
  4314. + [FE_REG_FE_DMA_VID_BASE] = 0,
  4315. +};
  4316. +
  4317. +static void rt305x_fe_reset(void)
  4318. +{
  4319. + rt_sysc_w32(RT305X_RESET_FE, SYSC_REG_RESET_CTRL);
  4320. + rt_sysc_w32(0, SYSC_REG_RESET_CTRL);
  4321. +}
  4322. +
  4323. +static void rt5350_set_mac(struct fe_priv *priv, unsigned char *mac)
  4324. +{
  4325. + unsigned long flags;
  4326. +
  4327. + spin_lock_irqsave(&priv->page_lock, flags);
  4328. + fe_w32((mac[0] << 8) | mac[1], RT5350_SDM_MAC_ADRH);
  4329. + fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
  4330. + RT5350_SDM_MAC_ADRL);
  4331. + spin_unlock_irqrestore(&priv->page_lock, flags);
  4332. +}
  4333. +
  4334. +static void rt5350_fwd_config(struct fe_priv *priv)
  4335. +{
  4336. + unsigned long sysclk = priv->sysclk;
  4337. +
  4338. + if (sysclk) {
  4339. + sysclk /= FE_US_CYC_CNT_DIVISOR;
  4340. + sysclk <<= FE_US_CYC_CNT_SHIFT;
  4341. +
  4342. + fe_w32((fe_r32(FE_FE_GLO_CFG) &
  4343. + ~(FE_US_CYC_CNT_MASK << FE_US_CYC_CNT_SHIFT)) | sysclk,
  4344. + FE_FE_GLO_CFG);
  4345. + }
  4346. +
  4347. + fe_w32(fe_r32(RT5350_SDM_CFG) & ~0xffff, RT5350_SDM_CFG);
  4348. + fe_w32(fe_r32(RT5350_SDM_CFG) | RT5350_SDM_ICS_EN | RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN,
  4349. + RT5350_SDM_CFG);
  4350. +}
  4351. +
  4352. +static void rt5350_fe_reset(void)
  4353. +{
  4354. + rt_sysc_w32(RT305X_RESET_FE | RT305X_RESET_ESW, SYSC_REG_RESET_CTRL);
  4355. + rt_sysc_w32(0, SYSC_REG_RESET_CTRL);
  4356. +}
  4357. +
  4358. +static struct fe_soc_data rt3050_data = {
  4359. + .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
  4360. + .reset_fe = rt305x_fe_reset,
  4361. + .min_pkt_len = 64,
  4362. + .pdma_glo_cfg = FE_PDMA_SIZE_4DWORDS,
  4363. + .checksum_bit = RX_DMA_L4VALID,
  4364. + .rx_dly_int = FE_RX_DLY_INT,
  4365. + .tx_dly_int = FE_TX_DLY_INT,
  4366. +};
  4367. +
  4368. +static struct fe_soc_data rt5350_data = {
  4369. + .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
  4370. + .reg_table = rt5350_reg_table,
  4371. + .reset_fe = rt5350_fe_reset,
  4372. + .set_mac = rt5350_set_mac,
  4373. + .fwd_config = rt5350_fwd_config,
  4374. + .min_pkt_len = 64,
  4375. + .pdma_glo_cfg = FE_PDMA_SIZE_4DWORDS,
  4376. + .checksum_bit = RX_DMA_L4VALID,
  4377. + .rx_dly_int = RT5350_RX_DLY_INT,
  4378. + .tx_dly_int = RT5350_TX_DLY_INT,
  4379. +};
  4380. +
  4381. +const struct of_device_id of_fe_match[] = {
  4382. + { .compatible = "ralink,rt3050-eth", .data = &rt3050_data },
  4383. + { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
  4384. + {},
  4385. +};
  4386. +
  4387. +MODULE_DEVICE_TABLE(of, of_fe_match);
  4388. --- /dev/null
  4389. +++ b/drivers/net/ethernet/ralink/soc_rt3883.c
  4390. @@ -0,0 +1,60 @@
  4391. +/*
  4392. + * This program is free software; you can redistribute it and/or modify
  4393. + * it under the terms of the GNU General Public License as published by
  4394. + * the Free Software Foundation; version 2 of the License
  4395. + *
  4396. + * This program is distributed in the hope that it will be useful,
  4397. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4398. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4399. + * GNU General Public License for more details.
  4400. + *
  4401. + * You should have received a copy of the GNU General Public License
  4402. + * along with this program; if not, write to the Free Software
  4403. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  4404. + *
  4405. + * Copyright (C) 2009-2013 John Crispin <[email protected]>
  4406. + */
  4407. +
  4408. +#include <linux/module.h>
  4409. +
  4410. +#include <asm/mach-ralink/ralink_regs.h>
  4411. +
  4412. +#include "ralink_soc_eth.h"
  4413. +#include "mdio_rt2880.h"
  4414. +
  4415. +#define RT3883_SYSC_REG_RSTCTRL 0x34
  4416. +#define RT3883_RSTCTRL_FE BIT(21)
  4417. +
  4418. +static void rt3883_fe_reset(void)
  4419. +{
  4420. + u32 t;
  4421. +
  4422. + t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL);
  4423. + t |= RT3883_RSTCTRL_FE;
  4424. + rt_sysc_w32(t , RT3883_SYSC_REG_RSTCTRL);
  4425. +
  4426. + t &= ~RT3883_RSTCTRL_FE;
  4427. + rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL);
  4428. +}
  4429. +
  4430. +static struct fe_soc_data rt3883_data = {
  4431. + .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
  4432. + .reset_fe = rt3883_fe_reset,
  4433. + .min_pkt_len = 64,
  4434. + .pdma_glo_cfg = FE_PDMA_SIZE_4DWORDS,
  4435. + .rx_dly_int = FE_RX_DLY_INT,
  4436. + .tx_dly_int = FE_TX_DLY_INT,
  4437. + .checksum_bit = RX_DMA_L4VALID,
  4438. + .mdio_read = rt2880_mdio_read,
  4439. + .mdio_write = rt2880_mdio_write,
  4440. + .mdio_adjust_link = rt2880_mdio_link_adjust,
  4441. + .port_init = rt2880_port_init,
  4442. +};
  4443. +
  4444. +const struct of_device_id of_fe_match[] = {
  4445. + { .compatible = "ralink,rt3883-eth", .data = &rt3883_data },
  4446. + {},
  4447. +};
  4448. +
  4449. +MODULE_DEVICE_TABLE(of, of_fe_match);
  4450. +
  4451. --- /dev/null
  4452. +++ b/drivers/net/ethernet/ralink/mt7530.c
  4453. @@ -0,0 +1,467 @@
  4454. +/*
  4455. + * This program is free software; you can redistribute it and/or
  4456. + * modify it under the terms of the GNU General Public License
  4457. + * as published by the Free Software Foundation; either version 2
  4458. + * of the License, or (at your option) any later version.
  4459. + *
  4460. + * This program is distributed in the hope that it will be useful,
  4461. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4462. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4463. + * GNU General Public License for more details.
  4464. + *
  4465. + * Copyright (C) 2013 John Crispin <[email protected]>
  4466. + */
  4467. +
  4468. +#include <linux/if.h>
  4469. +#include <linux/module.h>
  4470. +#include <linux/init.h>
  4471. +#include <linux/list.h>
  4472. +#include <linux/if_ether.h>
  4473. +#include <linux/skbuff.h>
  4474. +#include <linux/netdevice.h>
  4475. +#include <linux/netlink.h>
  4476. +#include <linux/bitops.h>
  4477. +#include <net/genetlink.h>
  4478. +#include <linux/switch.h>
  4479. +#include <linux/delay.h>
  4480. +#include <linux/phy.h>
  4481. +#include <linux/netdevice.h>
  4482. +#include <linux/etherdevice.h>
  4483. +#include <linux/lockdep.h>
  4484. +#include <linux/workqueue.h>
  4485. +#include <linux/of_device.h>
  4486. +
  4487. +#include "mt7530.h"
  4488. +
  4489. +#define MT7530_CPU_PORT 6
  4490. +#define MT7530_NUM_PORTS 7
  4491. +#define MT7530_NUM_VLANS 16
  4492. +#define MT7530_NUM_VIDS 16
  4493. +
  4494. +#define REG_ESW_VLAN_VTCR 0x90
  4495. +#define REG_ESW_VLAN_VAWD1 0x94
  4496. +#define REG_ESW_VLAN_VAWD2 0x98
  4497. +
  4498. +enum {
  4499. + /* Global attributes. */
  4500. + MT7530_ATTR_ENABLE_VLAN,
  4501. +};
  4502. +
  4503. +struct mt7530_port {
  4504. + u16 pvid;
  4505. +};
  4506. +
  4507. +struct mt7530_vlan {
  4508. + u8 ports;
  4509. +};
  4510. +
  4511. +struct mt7530_priv {
  4512. + void __iomem *base;
  4513. + struct mii_bus *bus;
  4514. + struct switch_dev swdev;
  4515. +
  4516. + bool global_vlan_enable;
  4517. + struct mt7530_vlan vlans[MT7530_NUM_VLANS];
  4518. + struct mt7530_port ports[MT7530_NUM_PORTS];
  4519. +};
  4520. +
  4521. +struct mt7530_mapping {
  4522. + char *name;
  4523. + u8 pvids[6];
  4524. + u8 vlans[8];
  4525. +} mt7530_defaults[] = {
  4526. + {
  4527. + .name = "llllw",
  4528. + .pvids = { 1, 1, 1, 1, 2, 1 },
  4529. + .vlans = { 0, 0x6f, 0x50 },
  4530. + }, {
  4531. + .name = "wllll",
  4532. + .pvids = { 2, 1, 1, 1, 1, 1 },
  4533. + .vlans = { 0, 0x7e, 0x41 },
  4534. + },
  4535. +};
  4536. +
  4537. +struct mt7530_mapping*
  4538. +mt7530_find_mapping(struct device_node *np)
  4539. +{
  4540. + const char *map;
  4541. + int i;
  4542. +
  4543. + if (of_property_read_string(np, "ralink,port-map", &map))
  4544. + return NULL;
  4545. +
  4546. + for (i = 0; i < ARRAY_SIZE(mt7530_defaults); i++)
  4547. + if (!strcmp(map, mt7530_defaults[i].name))
  4548. + return &mt7530_defaults[i];
  4549. +
  4550. + return NULL;
  4551. +}
  4552. +
  4553. +static void
  4554. +mt7530_apply_mapping(struct mt7530_priv *mt7530, struct mt7530_mapping *map)
  4555. +{
  4556. + int i = 0;
  4557. +
  4558. + mt7530->global_vlan_enable = 1;
  4559. +
  4560. + for (i = 0; i < 6; i++)
  4561. + mt7530->ports[i].pvid = map->pvids[i];
  4562. + for (i = 0; i < 8; i++)
  4563. + mt7530->vlans[i].ports = map->vlans[i];
  4564. +}
  4565. +
  4566. +static int
  4567. +mt7530_reset_switch(struct switch_dev *dev)
  4568. +{
  4569. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4570. +
  4571. + memset(priv->ports, 0, sizeof(priv->ports));
  4572. + memset(priv->vlans, 0, sizeof(priv->vlans));
  4573. +
  4574. + return 0;
  4575. +}
  4576. +
  4577. +static int
  4578. +mt7530_get_vlan_enable(struct switch_dev *dev,
  4579. + const struct switch_attr *attr,
  4580. + struct switch_val *val)
  4581. +{
  4582. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4583. +
  4584. + val->value.i = priv->global_vlan_enable;
  4585. +
  4586. + return 0;
  4587. +}
  4588. +
  4589. +static int
  4590. +mt7530_set_vlan_enable(struct switch_dev *dev,
  4591. + const struct switch_attr *attr,
  4592. + struct switch_val *val)
  4593. +{
  4594. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4595. +
  4596. + priv->global_vlan_enable = val->value.i != 0;
  4597. +
  4598. + return 0;
  4599. +}
  4600. +
  4601. +static u32
  4602. +mt7530_r32(struct mt7530_priv *priv, u32 reg)
  4603. +{
  4604. + if (priv->bus) {
  4605. + u16 high, low;
  4606. +
  4607. + mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
  4608. + low = mdiobus_read(priv->bus, 0x1f, (reg >> 2) & 0xf);
  4609. + high = mdiobus_read(priv->bus, 0x1f, 0x10);
  4610. +
  4611. + return (high << 16) | (low & 0xffff);
  4612. + }
  4613. +
  4614. + return ioread32(priv->base + reg);
  4615. +}
  4616. +
  4617. +static void
  4618. +mt7530_w32(struct mt7530_priv *priv, u32 reg, u32 val)
  4619. +{
  4620. + if (priv->bus) {
  4621. + mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
  4622. + mdiobus_write(priv->bus, 0x1f, (reg >> 2) & 0xf, val & 0xffff);
  4623. + mdiobus_write(priv->bus, 0x1f, 0x10, val >> 16);
  4624. + return;
  4625. + }
  4626. +
  4627. + iowrite32(val, priv->base + reg);
  4628. +}
  4629. +
  4630. +static void
  4631. +mt7530_vtcr(struct mt7530_priv *priv, u32 cmd, u32 val)
  4632. +{
  4633. + int i;
  4634. +
  4635. + mt7530_w32(priv, REG_ESW_VLAN_VTCR, BIT(31) | (cmd << 12) | val);
  4636. +
  4637. + for (i = 0; i < 20; i++) {
  4638. + u32 val = mt7530_r32(priv, REG_ESW_VLAN_VTCR);
  4639. +
  4640. + if ((val & BIT(31)) == 0)
  4641. + break;
  4642. +
  4643. + udelay(1000);
  4644. + }
  4645. + if (i == 20)
  4646. + printk("mt7530: vtcr timeout\n");
  4647. +}
  4648. +
  4649. +static int
  4650. +mt7530_get_port_pvid(struct switch_dev *dev, int port, int *val)
  4651. +{
  4652. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4653. +
  4654. + if (port >= MT7530_NUM_PORTS)
  4655. + return -EINVAL;
  4656. +
  4657. + *val = mt7530_r32(priv, 0x2014 + (0x100 * port));
  4658. + *val &= 0xff;
  4659. +
  4660. + return 0;
  4661. +}
  4662. +
  4663. +static int
  4664. +mt7530_set_port_pvid(struct switch_dev *dev, int port, int pvid)
  4665. +{
  4666. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4667. +
  4668. + if (port >= MT7530_NUM_PORTS)
  4669. + return -1;
  4670. +
  4671. + priv->ports[port].pvid = pvid;
  4672. +
  4673. + return 0;
  4674. +}
  4675. +
  4676. +static int
  4677. +mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
  4678. +{
  4679. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4680. + u32 member;
  4681. + int i;
  4682. +
  4683. + val->len = 0;
  4684. +
  4685. + if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VIDS)
  4686. + return -EINVAL;
  4687. +
  4688. + mt7530_vtcr(priv, 0, val->port_vlan);
  4689. + member = mt7530_r32(priv, REG_ESW_VLAN_VAWD1);
  4690. + member >>= 16;
  4691. + member &= 0xff;
  4692. +
  4693. + for (i = 0; i < MT7530_NUM_PORTS; i++) {
  4694. + struct switch_port *p;
  4695. + if (!(member & BIT(i)))
  4696. + continue;
  4697. +
  4698. + p = &val->value.ports[val->len++];
  4699. + p->id = i;
  4700. + p->flags = 0;
  4701. + }
  4702. +
  4703. + return 0;
  4704. +}
  4705. +
  4706. +static int
  4707. +mt7530_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
  4708. +{
  4709. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4710. + int ports = 0;
  4711. + int i;
  4712. +
  4713. + if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VIDS ||
  4714. + val->len > MT7530_NUM_PORTS)
  4715. + return -EINVAL;
  4716. +
  4717. + for (i = 0; i < val->len; i++) {
  4718. + struct switch_port *p = &val->value.ports[i];
  4719. +
  4720. + if (p->id >= MT7530_NUM_PORTS)
  4721. + return -EINVAL;
  4722. +
  4723. + ports |= BIT(p->id);
  4724. + }
  4725. + priv->vlans[val->port_vlan].ports = ports;
  4726. +
  4727. + return 0;
  4728. +}
  4729. +
  4730. +static int
  4731. +mt7530_apply_config(struct switch_dev *dev)
  4732. +{
  4733. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4734. + int i;
  4735. +
  4736. + if (!priv->global_vlan_enable) {
  4737. + mt7530_w32(priv, 0x2004, 0xff000);
  4738. + mt7530_w32(priv, 0x2104, 0xff000);
  4739. + mt7530_w32(priv, 0x2204, 0xff000);
  4740. + mt7530_w32(priv, 0x2304, 0xff000);
  4741. + mt7530_w32(priv, 0x2404, 0xff000);
  4742. + mt7530_w32(priv, 0x2504, 0xff000);
  4743. + mt7530_w32(priv, 0x2604, 0xff000);
  4744. + mt7530_w32(priv, 0x2010, 0x810000c);
  4745. + mt7530_w32(priv, 0x2110, 0x810000c);
  4746. + mt7530_w32(priv, 0x2210, 0x810000c);
  4747. + mt7530_w32(priv, 0x2310, 0x810000c);
  4748. + mt7530_w32(priv, 0x2410, 0x810000c);
  4749. + mt7530_w32(priv, 0x2510, 0x810000c);
  4750. + mt7530_w32(priv, 0x2610, 0x810000c);
  4751. + return 0;
  4752. + }
  4753. +
  4754. + // LAN/WAN ports as security mode
  4755. + mt7530_w32(priv, 0x2004, 0xff0003);
  4756. + mt7530_w32(priv, 0x2104, 0xff0003);
  4757. + mt7530_w32(priv, 0x2204, 0xff0003);
  4758. + mt7530_w32(priv, 0x2304, 0xff0003);
  4759. + mt7530_w32(priv, 0x2404, 0xff0003);
  4760. + mt7530_w32(priv, 0x2504, 0xff0003);
  4761. + // LAN/WAN ports as transparent port
  4762. + mt7530_w32(priv, 0x2010, 0x810000c0);
  4763. + mt7530_w32(priv, 0x2110, 0x810000c0);
  4764. + mt7530_w32(priv, 0x2210, 0x810000c0);
  4765. + mt7530_w32(priv, 0x2310, 0x810000c0);
  4766. + mt7530_w32(priv, 0x2410, 0x810000c0);
  4767. + mt7530_w32(priv, 0x2510, 0x810000c0);
  4768. +
  4769. + // set CPU/P7 port as user port
  4770. + mt7530_w32(priv, 0x2610, 0x81000000);
  4771. + mt7530_w32(priv, 0x2710, 0x81000000);
  4772. +
  4773. + mt7530_w32(priv, 0x2604, 0x20ff0003);
  4774. + mt7530_w32(priv, 0x2704, 0x20ff0003);
  4775. + mt7530_w32(priv, 0x2610, 0x81000000);
  4776. +
  4777. + for (i = 0; i < MT7530_NUM_VLANS; i++) {
  4778. + u8 ports = priv->vlans[i].ports;
  4779. + u32 val = mt7530_r32(priv, 0x100 + 4 * (i / 2));
  4780. +
  4781. + if (i % 2 == 0) {
  4782. + val &= 0xfff000;
  4783. + val |= i;
  4784. + } else {
  4785. + val &= 0xfff;
  4786. + val |= (i << 12);
  4787. + }
  4788. + mt7530_w32(priv, 0x100 + 4 * (i / 2), val);
  4789. +
  4790. + if (ports)
  4791. + mt7530_w32(priv, REG_ESW_VLAN_VAWD1, BIT(30) | (ports << 16) | BIT(0));
  4792. + else
  4793. + mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
  4794. +
  4795. + mt7530_vtcr(priv, 1, i);
  4796. + }
  4797. +
  4798. + for (i = 0; i < MT7530_NUM_PORTS; i++)
  4799. + mt7530_w32(priv, 0x2014 + (0x100 * i), 0x10000 | priv->ports[i].pvid);
  4800. +
  4801. + return 0;
  4802. +}
  4803. +
  4804. +static int
  4805. +mt7530_get_port_link(struct switch_dev *dev, int port,
  4806. + struct switch_port_link *link)
  4807. +{
  4808. + struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
  4809. + u32 speed, pmsr;
  4810. +
  4811. + if (port < 0 || port >= MT7530_NUM_PORTS)
  4812. + return -EINVAL;
  4813. +
  4814. + pmsr = mt7530_r32(priv, 0x3008 + (0x100 * port));
  4815. +
  4816. + link->link = pmsr & 1;
  4817. + link->duplex = (pmsr >> 1) & 1;
  4818. + speed = (pmsr >> 2) & 3;
  4819. +
  4820. + switch (speed) {
  4821. + case 0:
  4822. + link->speed = SWITCH_PORT_SPEED_10;
  4823. + break;
  4824. + case 1:
  4825. + link->speed = SWITCH_PORT_SPEED_100;
  4826. + break;
  4827. + case 2:
  4828. + case 3: /* forced gige speed can be 2 or 3 */
  4829. + link->speed = SWITCH_PORT_SPEED_1000;
  4830. + break;
  4831. + default:
  4832. + link->speed = SWITCH_PORT_SPEED_UNKNOWN;
  4833. + break;
  4834. + }
  4835. +
  4836. + return 0;
  4837. +}
  4838. +
  4839. +static const struct switch_attr mt7530_global[] = {
  4840. + {
  4841. + .type = SWITCH_TYPE_INT,
  4842. + .name = "enable_vlan",
  4843. + .description = "VLAN mode (1:enabled)",
  4844. + .max = 1,
  4845. + .id = MT7530_ATTR_ENABLE_VLAN,
  4846. + .get = mt7530_get_vlan_enable,
  4847. + .set = mt7530_set_vlan_enable,
  4848. + },
  4849. +};
  4850. +
  4851. +static const struct switch_attr mt7530_port[] = {
  4852. +};
  4853. +
  4854. +static const struct switch_attr mt7530_vlan[] = {
  4855. +};
  4856. +
  4857. +static const struct switch_dev_ops mt7530_ops = {
  4858. + .attr_global = {
  4859. + .attr = mt7530_global,
  4860. + .n_attr = ARRAY_SIZE(mt7530_global),
  4861. + },
  4862. + .attr_port = {
  4863. + .attr = mt7530_port,
  4864. + .n_attr = ARRAY_SIZE(mt7530_port),
  4865. + },
  4866. + .attr_vlan = {
  4867. + .attr = mt7530_vlan,
  4868. + .n_attr = ARRAY_SIZE(mt7530_vlan),
  4869. + },
  4870. + .get_vlan_ports = mt7530_get_vlan_ports,
  4871. + .set_vlan_ports = mt7530_set_vlan_ports,
  4872. + .get_port_pvid = mt7530_get_port_pvid,
  4873. + .set_port_pvid = mt7530_set_port_pvid,
  4874. + .get_port_link = mt7530_get_port_link,
  4875. + .apply_config = mt7530_apply_config,
  4876. + .reset_switch = mt7530_reset_switch,
  4877. +};
  4878. +
  4879. +int
  4880. +mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus)
  4881. +{
  4882. + struct switch_dev *swdev;
  4883. + struct mt7530_priv *mt7530;
  4884. + struct mt7530_mapping *map;
  4885. + int ret;
  4886. +
  4887. + if (bus && bus->phy_map[0x1f]->phy_id != 0x1beef)
  4888. + return 0;
  4889. +
  4890. + mt7530 = devm_kzalloc(dev, sizeof(struct mt7530_priv), GFP_KERNEL);
  4891. + if (!mt7530)
  4892. + return -ENOMEM;
  4893. +
  4894. + mt7530->base = base;
  4895. + mt7530->bus = bus;
  4896. + mt7530->global_vlan_enable = 1;
  4897. +
  4898. + swdev = &mt7530->swdev;
  4899. + swdev->name = "mt7530";
  4900. + swdev->alias = "mt7530";
  4901. + swdev->cpu_port = MT7530_CPU_PORT;
  4902. + swdev->ports = MT7530_NUM_PORTS;
  4903. + swdev->vlans = MT7530_NUM_VLANS;
  4904. + swdev->ops = &mt7530_ops;
  4905. +
  4906. + ret = register_switch(swdev, NULL);
  4907. + if (ret) {
  4908. + dev_err(dev, "failed to register mt7530\n");
  4909. + return ret;
  4910. + }
  4911. +
  4912. + dev_info(dev, "loaded mt7530 driver\n");
  4913. +
  4914. + map = mt7530_find_mapping(dev->of_node);
  4915. + if (map)
  4916. + mt7530_apply_mapping(mt7530, map);
  4917. + mt7530_apply_config(swdev);
  4918. +
  4919. + return 0;
  4920. +}
  4921. --- /dev/null
  4922. +++ b/drivers/net/ethernet/ralink/mt7530.h
  4923. @@ -0,0 +1,20 @@
  4924. +/*
  4925. + * This program is free software; you can redistribute it and/or
  4926. + * modify it under the terms of the GNU General Public License
  4927. + * as published by the Free Software Foundation; either version 2
  4928. + * of the License, or (at your option) any later version.
  4929. + *
  4930. + * This program is distributed in the hope that it will be useful,
  4931. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4932. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4933. + * GNU General Public License for more details.
  4934. + *
  4935. + * Copyright (C) 2013 John Crispin <[email protected]>
  4936. + */
  4937. +
  4938. +#ifndef _MT7530_H__
  4939. +#define _MT7530_H__
  4940. +
  4941. +int mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus);
  4942. +
  4943. +#endif