bnx2x_link.c 159 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699
  1. /* Copyright 2008-2009 Broadcom Corporation
  2. *
  3. * Unless you and Broadcom execute a separate written software license
  4. * agreement governing use of this software, this software is licensed to you
  5. * under the terms of the GNU General Public License version 2, available
  6. * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
  7. *
  8. * Notwithstanding the above, under no circumstances may you combine this
  9. * software in any way with any other Broadcom software provided under a
  10. * license other than the GPL, without Broadcom's express prior written
  11. * consent.
  12. *
  13. * Written by Yaniv Rosner
  14. *
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/errno.h>
  18. #include <linux/pci.h>
  19. #include <linux/netdevice.h>
  20. #include <linux/delay.h>
  21. #include <linux/ethtool.h>
  22. #include <linux/mutex.h>
  23. #include "bnx2x.h"
  24. /********************************************************/
  25. #define ETH_HLEN 14
  26. #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
  27. #define ETH_MIN_PACKET_SIZE 60
  28. #define ETH_MAX_PACKET_SIZE 1500
  29. #define ETH_MAX_JUMBO_PACKET_SIZE 9600
  30. #define MDIO_ACCESS_TIMEOUT 1000
  31. #define BMAC_CONTROL_RX_ENABLE 2
  32. /***********************************************************/
  33. /* Shortcut definitions */
  34. /***********************************************************/
  35. #define NIG_STATUS_XGXS0_LINK10G \
  36. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
  37. #define NIG_STATUS_XGXS0_LINK_STATUS \
  38. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
  39. #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
  40. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
  41. #define NIG_STATUS_SERDES0_LINK_STATUS \
  42. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
  43. #define NIG_MASK_MI_INT \
  44. NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
  45. #define NIG_MASK_XGXS0_LINK10G \
  46. NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
  47. #define NIG_MASK_XGXS0_LINK_STATUS \
  48. NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
  49. #define NIG_MASK_SERDES0_LINK_STATUS \
  50. NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
  51. #define MDIO_AN_CL73_OR_37_COMPLETE \
  52. (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
  53. MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
  54. #define XGXS_RESET_BITS \
  55. (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
  56. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
  57. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
  58. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
  59. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
  60. #define SERDES_RESET_BITS \
  61. (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
  62. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
  63. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
  64. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
  65. #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
  66. #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
  67. #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
  68. #define AUTONEG_PARALLEL \
  69. SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
  70. #define AUTONEG_SGMII_FIBER_AUTODET \
  71. SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
  72. #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
  73. #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
  74. MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
  75. #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
  76. MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
  77. #define GP_STATUS_SPEED_MASK \
  78. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
  79. #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
  80. #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
  81. #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
  82. #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
  83. #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
  84. #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
  85. #define GP_STATUS_10G_HIG \
  86. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
  87. #define GP_STATUS_10G_CX4 \
  88. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
  89. #define GP_STATUS_12G_HIG \
  90. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
  91. #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
  92. #define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
  93. #define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
  94. #define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
  95. #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
  96. #define GP_STATUS_10G_KX4 \
  97. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
  98. #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
  99. #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
  100. #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
  101. #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
  102. #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
  103. #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
  104. #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
  105. #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
  106. #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
  107. #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
  108. #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
  109. #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
  110. #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
  111. #define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
  112. #define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
  113. #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
  114. #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
  115. #define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
  116. #define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
  117. #define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
  118. #define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
  119. #define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
  120. #define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
  121. #define PHY_XGXS_FLAG 0x1
  122. #define PHY_SGMII_FLAG 0x2
  123. #define PHY_SERDES_FLAG 0x4
  124. /* */
  125. #define SFP_EEPROM_CON_TYPE_ADDR 0x2
  126. #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
  127. #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
  128. #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
  129. #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
  130. #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
  131. #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
  132. #define SFP_EEPROM_VENDOR_NAME_SIZE 16
  133. #define SFP_EEPROM_OPTIONS_ADDR 0x40
  134. #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
  135. #define SFP_EEPROM_OPTIONS_SIZE 2
  136. #define SFP_MODULE_TYPE_UNKNOWN 0x0
  137. #define SFP_MODULE_TYPE_LC 0x1
  138. #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2
  139. #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3
  140. #define SFP_LIMITING_MODE_VALUE 0x0044
  141. /**********************************************************/
  142. /* INTERFACE */
  143. /**********************************************************/
  144. #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
  145. bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
  146. DEFAULT_PHY_DEV_ADDR, \
  147. (_bank + (_addr & 0xf)), \
  148. _val)
  149. #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
  150. bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
  151. DEFAULT_PHY_DEV_ADDR, \
  152. (_bank + (_addr & 0xf)), \
  153. _val)
  154. static void bnx2x_set_serdes_access(struct link_params *params)
  155. {
  156. struct bnx2x *bp = params->bp;
  157. u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  158. /* Set Clause 22 */
  159. REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
  160. REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
  161. udelay(500);
  162. REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
  163. udelay(500);
  164. /* Set Clause 45 */
  165. REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
  166. }
  167. static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
  168. {
  169. struct bnx2x *bp = params->bp;
  170. if (phy_flags & PHY_XGXS_FLAG) {
  171. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
  172. params->port*0x18, 0);
  173. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
  174. DEFAULT_PHY_DEV_ADDR);
  175. } else {
  176. bnx2x_set_serdes_access(params);
  177. REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
  178. params->port*0x10,
  179. DEFAULT_PHY_DEV_ADDR);
  180. }
  181. }
  182. static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
  183. {
  184. u32 val = REG_RD(bp, reg);
  185. val |= bits;
  186. REG_WR(bp, reg, val);
  187. return val;
  188. }
  189. static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
  190. {
  191. u32 val = REG_RD(bp, reg);
  192. val &= ~bits;
  193. REG_WR(bp, reg, val);
  194. return val;
  195. }
  196. static void bnx2x_emac_init(struct link_params *params,
  197. struct link_vars *vars)
  198. {
  199. /* reset and unreset the emac core */
  200. struct bnx2x *bp = params->bp;
  201. u8 port = params->port;
  202. u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  203. u32 val;
  204. u16 timeout;
  205. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  206. (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
  207. udelay(5);
  208. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  209. (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
  210. /* init emac - use read-modify-write */
  211. /* self clear reset */
  212. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  213. EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
  214. timeout = 200;
  215. do {
  216. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  217. DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
  218. if (!timeout) {
  219. DP(NETIF_MSG_LINK, "EMAC timeout!\n");
  220. return;
  221. }
  222. timeout--;
  223. } while (val & EMAC_MODE_RESET);
  224. /* Set mac address */
  225. val = ((params->mac_addr[0] << 8) |
  226. params->mac_addr[1]);
  227. EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
  228. val = ((params->mac_addr[2] << 24) |
  229. (params->mac_addr[3] << 16) |
  230. (params->mac_addr[4] << 8) |
  231. params->mac_addr[5]);
  232. EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
  233. }
  234. static u8 bnx2x_emac_enable(struct link_params *params,
  235. struct link_vars *vars, u8 lb)
  236. {
  237. struct bnx2x *bp = params->bp;
  238. u8 port = params->port;
  239. u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  240. u32 val;
  241. DP(NETIF_MSG_LINK, "enabling EMAC\n");
  242. /* enable emac and not bmac */
  243. REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
  244. /* for paladium */
  245. if (CHIP_REV_IS_EMUL(bp)) {
  246. /* Use lane 1 (of lanes 0-3) */
  247. REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
  248. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
  249. port*4, 1);
  250. }
  251. /* for fpga */
  252. else
  253. if (CHIP_REV_IS_FPGA(bp)) {
  254. /* Use lane 1 (of lanes 0-3) */
  255. DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
  256. REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
  257. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
  258. 0);
  259. } else
  260. /* ASIC */
  261. if (vars->phy_flags & PHY_XGXS_FLAG) {
  262. u32 ser_lane = ((params->lane_config &
  263. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  264. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  265. DP(NETIF_MSG_LINK, "XGXS\n");
  266. /* select the master lanes (out of 0-3) */
  267. REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
  268. port*4, ser_lane);
  269. /* select XGXS */
  270. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
  271. port*4, 1);
  272. } else { /* SerDes */
  273. DP(NETIF_MSG_LINK, "SerDes\n");
  274. /* select SerDes */
  275. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
  276. port*4, 0);
  277. }
  278. bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
  279. EMAC_RX_MODE_RESET);
  280. bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
  281. EMAC_TX_MODE_RESET);
  282. if (CHIP_REV_IS_SLOW(bp)) {
  283. /* config GMII mode */
  284. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  285. EMAC_WR(bp, EMAC_REG_EMAC_MODE,
  286. (val | EMAC_MODE_PORT_GMII));
  287. } else { /* ASIC */
  288. /* pause enable/disable */
  289. bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
  290. EMAC_RX_MODE_FLOW_EN);
  291. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
  292. bnx2x_bits_en(bp, emac_base +
  293. EMAC_REG_EMAC_RX_MODE,
  294. EMAC_RX_MODE_FLOW_EN);
  295. bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
  296. (EMAC_TX_MODE_EXT_PAUSE_EN |
  297. EMAC_TX_MODE_FLOW_EN));
  298. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  299. bnx2x_bits_en(bp, emac_base +
  300. EMAC_REG_EMAC_TX_MODE,
  301. (EMAC_TX_MODE_EXT_PAUSE_EN |
  302. EMAC_TX_MODE_FLOW_EN));
  303. }
  304. /* KEEP_VLAN_TAG, promiscuous */
  305. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
  306. val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
  307. EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
  308. /* Set Loopback */
  309. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  310. if (lb)
  311. val |= 0x810;
  312. else
  313. val &= ~0x810;
  314. EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
  315. /* enable emac */
  316. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
  317. /* enable emac for jumbo packets */
  318. EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
  319. (EMAC_RX_MTU_SIZE_JUMBO_ENA |
  320. (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
  321. /* strip CRC */
  322. REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
  323. /* disable the NIG in/out to the bmac */
  324. REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
  325. REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
  326. REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
  327. /* enable the NIG in/out to the emac */
  328. REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
  329. val = 0;
  330. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  331. val = 1;
  332. REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
  333. REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
  334. if (CHIP_REV_IS_EMUL(bp)) {
  335. /* take the BigMac out of reset */
  336. REG_WR(bp,
  337. GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  338. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  339. /* enable access for bmac registers */
  340. REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
  341. }
  342. vars->mac_type = MAC_TYPE_EMAC;
  343. return 0;
  344. }
  345. static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
  346. u8 is_lb)
  347. {
  348. struct bnx2x *bp = params->bp;
  349. u8 port = params->port;
  350. u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
  351. NIG_REG_INGRESS_BMAC0_MEM;
  352. u32 wb_data[2];
  353. u32 val;
  354. DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
  355. /* reset and unreset the BigMac */
  356. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  357. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  358. msleep(1);
  359. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  360. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  361. /* enable access for bmac registers */
  362. REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
  363. /* XGXS control */
  364. wb_data[0] = 0x3c;
  365. wb_data[1] = 0;
  366. REG_WR_DMAE(bp, bmac_addr +
  367. BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
  368. wb_data, 2);
  369. /* tx MAC SA */
  370. wb_data[0] = ((params->mac_addr[2] << 24) |
  371. (params->mac_addr[3] << 16) |
  372. (params->mac_addr[4] << 8) |
  373. params->mac_addr[5]);
  374. wb_data[1] = ((params->mac_addr[0] << 8) |
  375. params->mac_addr[1]);
  376. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
  377. wb_data, 2);
  378. /* tx control */
  379. val = 0xc0;
  380. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  381. val |= 0x800000;
  382. wb_data[0] = val;
  383. wb_data[1] = 0;
  384. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
  385. wb_data, 2);
  386. /* mac control */
  387. val = 0x3;
  388. if (is_lb) {
  389. val |= 0x4;
  390. DP(NETIF_MSG_LINK, "enable bmac loopback\n");
  391. }
  392. wb_data[0] = val;
  393. wb_data[1] = 0;
  394. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
  395. wb_data, 2);
  396. /* set rx mtu */
  397. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  398. wb_data[1] = 0;
  399. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
  400. wb_data, 2);
  401. /* rx control set to don't strip crc */
  402. val = 0x14;
  403. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
  404. val |= 0x20;
  405. wb_data[0] = val;
  406. wb_data[1] = 0;
  407. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
  408. wb_data, 2);
  409. /* set tx mtu */
  410. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  411. wb_data[1] = 0;
  412. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
  413. wb_data, 2);
  414. /* set cnt max size */
  415. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  416. wb_data[1] = 0;
  417. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
  418. wb_data, 2);
  419. /* configure safc */
  420. wb_data[0] = 0x1000200;
  421. wb_data[1] = 0;
  422. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
  423. wb_data, 2);
  424. /* fix for emulation */
  425. if (CHIP_REV_IS_EMUL(bp)) {
  426. wb_data[0] = 0xf000;
  427. wb_data[1] = 0;
  428. REG_WR_DMAE(bp,
  429. bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
  430. wb_data, 2);
  431. }
  432. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
  433. REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
  434. REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
  435. val = 0;
  436. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  437. val = 1;
  438. REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
  439. REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
  440. REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
  441. REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
  442. REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
  443. REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
  444. vars->mac_type = MAC_TYPE_BMAC;
  445. return 0;
  446. }
  447. static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
  448. {
  449. struct bnx2x *bp = params->bp;
  450. u32 val;
  451. if (phy_flags & PHY_XGXS_FLAG) {
  452. DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
  453. val = XGXS_RESET_BITS;
  454. } else { /* SerDes */
  455. DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
  456. val = SERDES_RESET_BITS;
  457. }
  458. val = val << (params->port*16);
  459. /* reset and unreset the SerDes/XGXS */
  460. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
  461. val);
  462. udelay(500);
  463. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
  464. val);
  465. bnx2x_set_phy_mdio(params, phy_flags);
  466. }
  467. void bnx2x_link_status_update(struct link_params *params,
  468. struct link_vars *vars)
  469. {
  470. struct bnx2x *bp = params->bp;
  471. u8 link_10g;
  472. u8 port = params->port;
  473. if (params->switch_cfg == SWITCH_CFG_1G)
  474. vars->phy_flags = PHY_SERDES_FLAG;
  475. else
  476. vars->phy_flags = PHY_XGXS_FLAG;
  477. vars->link_status = REG_RD(bp, params->shmem_base +
  478. offsetof(struct shmem_region,
  479. port_mb[port].link_status));
  480. vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
  481. if (vars->link_up) {
  482. DP(NETIF_MSG_LINK, "phy link up\n");
  483. vars->phy_link_up = 1;
  484. vars->duplex = DUPLEX_FULL;
  485. switch (vars->link_status &
  486. LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
  487. case LINK_10THD:
  488. vars->duplex = DUPLEX_HALF;
  489. /* fall thru */
  490. case LINK_10TFD:
  491. vars->line_speed = SPEED_10;
  492. break;
  493. case LINK_100TXHD:
  494. vars->duplex = DUPLEX_HALF;
  495. /* fall thru */
  496. case LINK_100T4:
  497. case LINK_100TXFD:
  498. vars->line_speed = SPEED_100;
  499. break;
  500. case LINK_1000THD:
  501. vars->duplex = DUPLEX_HALF;
  502. /* fall thru */
  503. case LINK_1000TFD:
  504. vars->line_speed = SPEED_1000;
  505. break;
  506. case LINK_2500THD:
  507. vars->duplex = DUPLEX_HALF;
  508. /* fall thru */
  509. case LINK_2500TFD:
  510. vars->line_speed = SPEED_2500;
  511. break;
  512. case LINK_10GTFD:
  513. vars->line_speed = SPEED_10000;
  514. break;
  515. case LINK_12GTFD:
  516. vars->line_speed = SPEED_12000;
  517. break;
  518. case LINK_12_5GTFD:
  519. vars->line_speed = SPEED_12500;
  520. break;
  521. case LINK_13GTFD:
  522. vars->line_speed = SPEED_13000;
  523. break;
  524. case LINK_15GTFD:
  525. vars->line_speed = SPEED_15000;
  526. break;
  527. case LINK_16GTFD:
  528. vars->line_speed = SPEED_16000;
  529. break;
  530. default:
  531. break;
  532. }
  533. if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
  534. vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
  535. else
  536. vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
  537. if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
  538. vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
  539. else
  540. vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
  541. if (vars->phy_flags & PHY_XGXS_FLAG) {
  542. if (vars->line_speed &&
  543. ((vars->line_speed == SPEED_10) ||
  544. (vars->line_speed == SPEED_100))) {
  545. vars->phy_flags |= PHY_SGMII_FLAG;
  546. } else {
  547. vars->phy_flags &= ~PHY_SGMII_FLAG;
  548. }
  549. }
  550. /* anything 10 and over uses the bmac */
  551. link_10g = ((vars->line_speed == SPEED_10000) ||
  552. (vars->line_speed == SPEED_12000) ||
  553. (vars->line_speed == SPEED_12500) ||
  554. (vars->line_speed == SPEED_13000) ||
  555. (vars->line_speed == SPEED_15000) ||
  556. (vars->line_speed == SPEED_16000));
  557. if (link_10g)
  558. vars->mac_type = MAC_TYPE_BMAC;
  559. else
  560. vars->mac_type = MAC_TYPE_EMAC;
  561. } else { /* link down */
  562. DP(NETIF_MSG_LINK, "phy link down\n");
  563. vars->phy_link_up = 0;
  564. vars->line_speed = 0;
  565. vars->duplex = DUPLEX_FULL;
  566. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  567. /* indicate no mac active */
  568. vars->mac_type = MAC_TYPE_NONE;
  569. }
  570. DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
  571. vars->link_status, vars->phy_link_up);
  572. DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
  573. vars->line_speed, vars->duplex, vars->flow_ctrl);
  574. }
  575. static void bnx2x_update_mng(struct link_params *params, u32 link_status)
  576. {
  577. struct bnx2x *bp = params->bp;
  578. REG_WR(bp, params->shmem_base +
  579. offsetof(struct shmem_region,
  580. port_mb[params->port].link_status),
  581. link_status);
  582. }
  583. static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
  584. {
  585. u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
  586. NIG_REG_INGRESS_BMAC0_MEM;
  587. u32 wb_data[2];
  588. u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
  589. /* Only if the bmac is out of reset */
  590. if (REG_RD(bp, MISC_REG_RESET_REG_2) &
  591. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
  592. nig_bmac_enable) {
  593. /* Clear Rx Enable bit in BMAC_CONTROL register */
  594. REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
  595. wb_data, 2);
  596. wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
  597. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
  598. wb_data, 2);
  599. msleep(1);
  600. }
  601. }
  602. static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
  603. u32 line_speed)
  604. {
  605. struct bnx2x *bp = params->bp;
  606. u8 port = params->port;
  607. u32 init_crd, crd;
  608. u32 count = 1000;
  609. /* disable port */
  610. REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
  611. /* wait for init credit */
  612. init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
  613. crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
  614. DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
  615. while ((init_crd != crd) && count) {
  616. msleep(5);
  617. crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
  618. count--;
  619. }
  620. crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
  621. if (init_crd != crd) {
  622. DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
  623. init_crd, crd);
  624. return -EINVAL;
  625. }
  626. if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
  627. line_speed == SPEED_10 ||
  628. line_speed == SPEED_100 ||
  629. line_speed == SPEED_1000 ||
  630. line_speed == SPEED_2500) {
  631. REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
  632. /* update threshold */
  633. REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
  634. /* update init credit */
  635. init_crd = 778; /* (800-18-4) */
  636. } else {
  637. u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
  638. ETH_OVREHEAD)/16;
  639. REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
  640. /* update threshold */
  641. REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
  642. /* update init credit */
  643. switch (line_speed) {
  644. case SPEED_10000:
  645. init_crd = thresh + 553 - 22;
  646. break;
  647. case SPEED_12000:
  648. init_crd = thresh + 664 - 22;
  649. break;
  650. case SPEED_13000:
  651. init_crd = thresh + 742 - 22;
  652. break;
  653. case SPEED_16000:
  654. init_crd = thresh + 778 - 22;
  655. break;
  656. default:
  657. DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
  658. line_speed);
  659. return -EINVAL;
  660. break;
  661. }
  662. }
  663. REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
  664. DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
  665. line_speed, init_crd);
  666. /* probe the credit changes */
  667. REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
  668. msleep(5);
  669. REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
  670. /* enable port */
  671. REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
  672. return 0;
  673. }
  674. static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
  675. {
  676. u32 emac_base;
  677. switch (ext_phy_type) {
  678. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  679. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  680. /* All MDC/MDIO is directed through single EMAC */
  681. if (REG_RD(bp, NIG_REG_PORT_SWAP))
  682. emac_base = GRCBASE_EMAC0;
  683. else
  684. emac_base = GRCBASE_EMAC1;
  685. break;
  686. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  687. emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
  688. break;
  689. default:
  690. emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  691. break;
  692. }
  693. return emac_base;
  694. }
  695. u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
  696. u8 phy_addr, u8 devad, u16 reg, u16 val)
  697. {
  698. u32 tmp, saved_mode;
  699. u8 i, rc = 0;
  700. u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
  701. /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
  702. * (a value of 49==0x31) and make sure that the AUTO poll is off
  703. */
  704. saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
  705. tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
  706. EMAC_MDIO_MODE_CLOCK_CNT);
  707. tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
  708. (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
  709. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
  710. REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
  711. udelay(40);
  712. /* address */
  713. tmp = ((phy_addr << 21) | (devad << 16) | reg |
  714. EMAC_MDIO_COMM_COMMAND_ADDRESS |
  715. EMAC_MDIO_COMM_START_BUSY);
  716. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
  717. for (i = 0; i < 50; i++) {
  718. udelay(10);
  719. tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
  720. if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
  721. udelay(5);
  722. break;
  723. }
  724. }
  725. if (tmp & EMAC_MDIO_COMM_START_BUSY) {
  726. DP(NETIF_MSG_LINK, "write phy register failed\n");
  727. rc = -EFAULT;
  728. } else {
  729. /* data */
  730. tmp = ((phy_addr << 21) | (devad << 16) | val |
  731. EMAC_MDIO_COMM_COMMAND_WRITE_45 |
  732. EMAC_MDIO_COMM_START_BUSY);
  733. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
  734. for (i = 0; i < 50; i++) {
  735. udelay(10);
  736. tmp = REG_RD(bp, mdio_ctrl +
  737. EMAC_REG_EMAC_MDIO_COMM);
  738. if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
  739. udelay(5);
  740. break;
  741. }
  742. }
  743. if (tmp & EMAC_MDIO_COMM_START_BUSY) {
  744. DP(NETIF_MSG_LINK, "write phy register failed\n");
  745. rc = -EFAULT;
  746. }
  747. }
  748. /* Restore the saved mode */
  749. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
  750. return rc;
  751. }
  752. u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
  753. u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
  754. {
  755. u32 val, saved_mode;
  756. u16 i;
  757. u8 rc = 0;
  758. u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
  759. /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
  760. * (a value of 49==0x31) and make sure that the AUTO poll is off
  761. */
  762. saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
  763. val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
  764. EMAC_MDIO_MODE_CLOCK_CNT));
  765. val |= (EMAC_MDIO_MODE_CLAUSE_45 |
  766. (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
  767. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
  768. REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
  769. udelay(40);
  770. /* address */
  771. val = ((phy_addr << 21) | (devad << 16) | reg |
  772. EMAC_MDIO_COMM_COMMAND_ADDRESS |
  773. EMAC_MDIO_COMM_START_BUSY);
  774. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
  775. for (i = 0; i < 50; i++) {
  776. udelay(10);
  777. val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
  778. if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
  779. udelay(5);
  780. break;
  781. }
  782. }
  783. if (val & EMAC_MDIO_COMM_START_BUSY) {
  784. DP(NETIF_MSG_LINK, "read phy register failed\n");
  785. *ret_val = 0;
  786. rc = -EFAULT;
  787. } else {
  788. /* data */
  789. val = ((phy_addr << 21) | (devad << 16) |
  790. EMAC_MDIO_COMM_COMMAND_READ_45 |
  791. EMAC_MDIO_COMM_START_BUSY);
  792. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
  793. for (i = 0; i < 50; i++) {
  794. udelay(10);
  795. val = REG_RD(bp, mdio_ctrl +
  796. EMAC_REG_EMAC_MDIO_COMM);
  797. if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
  798. *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
  799. break;
  800. }
  801. }
  802. if (val & EMAC_MDIO_COMM_START_BUSY) {
  803. DP(NETIF_MSG_LINK, "read phy register failed\n");
  804. *ret_val = 0;
  805. rc = -EFAULT;
  806. }
  807. }
  808. /* Restore the saved mode */
  809. REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
  810. return rc;
  811. }
  812. static void bnx2x_set_aer_mmd(struct link_params *params,
  813. struct link_vars *vars)
  814. {
  815. struct bnx2x *bp = params->bp;
  816. u32 ser_lane;
  817. u16 offset;
  818. ser_lane = ((params->lane_config &
  819. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  820. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  821. offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
  822. (params->phy_addr + ser_lane) : 0;
  823. CL45_WR_OVER_CL22(bp, params->port,
  824. params->phy_addr,
  825. MDIO_REG_BANK_AER_BLOCK,
  826. MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
  827. }
  828. static void bnx2x_set_master_ln(struct link_params *params)
  829. {
  830. struct bnx2x *bp = params->bp;
  831. u16 new_master_ln, ser_lane;
  832. ser_lane = ((params->lane_config &
  833. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  834. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  835. /* set the master_ln for AN */
  836. CL45_RD_OVER_CL22(bp, params->port,
  837. params->phy_addr,
  838. MDIO_REG_BANK_XGXS_BLOCK2,
  839. MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
  840. &new_master_ln);
  841. CL45_WR_OVER_CL22(bp, params->port,
  842. params->phy_addr,
  843. MDIO_REG_BANK_XGXS_BLOCK2 ,
  844. MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
  845. (new_master_ln | ser_lane));
  846. }
  847. static u8 bnx2x_reset_unicore(struct link_params *params)
  848. {
  849. struct bnx2x *bp = params->bp;
  850. u16 mii_control;
  851. u16 i;
  852. CL45_RD_OVER_CL22(bp, params->port,
  853. params->phy_addr,
  854. MDIO_REG_BANK_COMBO_IEEE0,
  855. MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
  856. /* reset the unicore */
  857. CL45_WR_OVER_CL22(bp, params->port,
  858. params->phy_addr,
  859. MDIO_REG_BANK_COMBO_IEEE0,
  860. MDIO_COMBO_IEEE0_MII_CONTROL,
  861. (mii_control |
  862. MDIO_COMBO_IEEO_MII_CONTROL_RESET));
  863. bnx2x_set_serdes_access(params);
  864. /* wait for the reset to self clear */
  865. for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
  866. udelay(5);
  867. /* the reset erased the previous bank value */
  868. CL45_RD_OVER_CL22(bp, params->port,
  869. params->phy_addr,
  870. MDIO_REG_BANK_COMBO_IEEE0,
  871. MDIO_COMBO_IEEE0_MII_CONTROL,
  872. &mii_control);
  873. if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
  874. udelay(5);
  875. return 0;
  876. }
  877. }
  878. DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
  879. return -EINVAL;
  880. }
  881. static void bnx2x_set_swap_lanes(struct link_params *params)
  882. {
  883. struct bnx2x *bp = params->bp;
  884. /* Each two bits represents a lane number:
  885. No swap is 0123 => 0x1b no need to enable the swap */
  886. u16 ser_lane, rx_lane_swap, tx_lane_swap;
  887. ser_lane = ((params->lane_config &
  888. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  889. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  890. rx_lane_swap = ((params->lane_config &
  891. PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
  892. PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
  893. tx_lane_swap = ((params->lane_config &
  894. PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
  895. PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
  896. if (rx_lane_swap != 0x1b) {
  897. CL45_WR_OVER_CL22(bp, params->port,
  898. params->phy_addr,
  899. MDIO_REG_BANK_XGXS_BLOCK2,
  900. MDIO_XGXS_BLOCK2_RX_LN_SWAP,
  901. (rx_lane_swap |
  902. MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
  903. MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
  904. } else {
  905. CL45_WR_OVER_CL22(bp, params->port,
  906. params->phy_addr,
  907. MDIO_REG_BANK_XGXS_BLOCK2,
  908. MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
  909. }
  910. if (tx_lane_swap != 0x1b) {
  911. CL45_WR_OVER_CL22(bp, params->port,
  912. params->phy_addr,
  913. MDIO_REG_BANK_XGXS_BLOCK2,
  914. MDIO_XGXS_BLOCK2_TX_LN_SWAP,
  915. (tx_lane_swap |
  916. MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
  917. } else {
  918. CL45_WR_OVER_CL22(bp, params->port,
  919. params->phy_addr,
  920. MDIO_REG_BANK_XGXS_BLOCK2,
  921. MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
  922. }
  923. }
  924. static void bnx2x_set_parallel_detection(struct link_params *params,
  925. u8 phy_flags)
  926. {
  927. struct bnx2x *bp = params->bp;
  928. u16 control2;
  929. CL45_RD_OVER_CL22(bp, params->port,
  930. params->phy_addr,
  931. MDIO_REG_BANK_SERDES_DIGITAL,
  932. MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
  933. &control2);
  934. control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
  935. CL45_WR_OVER_CL22(bp, params->port,
  936. params->phy_addr,
  937. MDIO_REG_BANK_SERDES_DIGITAL,
  938. MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
  939. control2);
  940. if (phy_flags & PHY_XGXS_FLAG) {
  941. DP(NETIF_MSG_LINK, "XGXS\n");
  942. CL45_WR_OVER_CL22(bp, params->port,
  943. params->phy_addr,
  944. MDIO_REG_BANK_10G_PARALLEL_DETECT,
  945. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
  946. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
  947. CL45_RD_OVER_CL22(bp, params->port,
  948. params->phy_addr,
  949. MDIO_REG_BANK_10G_PARALLEL_DETECT,
  950. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
  951. &control2);
  952. control2 |=
  953. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
  954. CL45_WR_OVER_CL22(bp, params->port,
  955. params->phy_addr,
  956. MDIO_REG_BANK_10G_PARALLEL_DETECT,
  957. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
  958. control2);
  959. /* Disable parallel detection of HiG */
  960. CL45_WR_OVER_CL22(bp, params->port,
  961. params->phy_addr,
  962. MDIO_REG_BANK_XGXS_BLOCK2,
  963. MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
  964. MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
  965. MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
  966. }
  967. }
  968. static void bnx2x_set_autoneg(struct link_params *params,
  969. struct link_vars *vars)
  970. {
  971. struct bnx2x *bp = params->bp;
  972. u16 reg_val;
  973. /* CL37 Autoneg */
  974. CL45_RD_OVER_CL22(bp, params->port,
  975. params->phy_addr,
  976. MDIO_REG_BANK_COMBO_IEEE0,
  977. MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
  978. /* CL37 Autoneg Enabled */
  979. if (vars->line_speed == SPEED_AUTO_NEG)
  980. reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
  981. else /* CL37 Autoneg Disabled */
  982. reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
  983. MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
  984. CL45_WR_OVER_CL22(bp, params->port,
  985. params->phy_addr,
  986. MDIO_REG_BANK_COMBO_IEEE0,
  987. MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
  988. /* Enable/Disable Autodetection */
  989. CL45_RD_OVER_CL22(bp, params->port,
  990. params->phy_addr,
  991. MDIO_REG_BANK_SERDES_DIGITAL,
  992. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
  993. reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
  994. if (vars->line_speed == SPEED_AUTO_NEG)
  995. reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
  996. else
  997. reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
  998. CL45_WR_OVER_CL22(bp, params->port,
  999. params->phy_addr,
  1000. MDIO_REG_BANK_SERDES_DIGITAL,
  1001. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
  1002. /* Enable TetonII and BAM autoneg */
  1003. CL45_RD_OVER_CL22(bp, params->port,
  1004. params->phy_addr,
  1005. MDIO_REG_BANK_BAM_NEXT_PAGE,
  1006. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
  1007. &reg_val);
  1008. if (vars->line_speed == SPEED_AUTO_NEG) {
  1009. /* Enable BAM aneg Mode and TetonII aneg Mode */
  1010. reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
  1011. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
  1012. } else {
  1013. /* TetonII and BAM Autoneg Disabled */
  1014. reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
  1015. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
  1016. }
  1017. CL45_WR_OVER_CL22(bp, params->port,
  1018. params->phy_addr,
  1019. MDIO_REG_BANK_BAM_NEXT_PAGE,
  1020. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
  1021. reg_val);
  1022. /* CL73 Autoneg Disabled */
  1023. reg_val = 0;
  1024. CL45_WR_OVER_CL22(bp, params->port,
  1025. params->phy_addr,
  1026. MDIO_REG_BANK_CL73_IEEEB0,
  1027. MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
  1028. }
  1029. /* program SerDes, forced speed */
  1030. static void bnx2x_program_serdes(struct link_params *params,
  1031. struct link_vars *vars)
  1032. {
  1033. struct bnx2x *bp = params->bp;
  1034. u16 reg_val;
  1035. /* program duplex, disable autoneg */
  1036. CL45_RD_OVER_CL22(bp, params->port,
  1037. params->phy_addr,
  1038. MDIO_REG_BANK_COMBO_IEEE0,
  1039. MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
  1040. reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
  1041. MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
  1042. if (params->req_duplex == DUPLEX_FULL)
  1043. reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
  1044. CL45_WR_OVER_CL22(bp, params->port,
  1045. params->phy_addr,
  1046. MDIO_REG_BANK_COMBO_IEEE0,
  1047. MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
  1048. /* program speed
  1049. - needed only if the speed is greater than 1G (2.5G or 10G) */
  1050. CL45_RD_OVER_CL22(bp, params->port,
  1051. params->phy_addr,
  1052. MDIO_REG_BANK_SERDES_DIGITAL,
  1053. MDIO_SERDES_DIGITAL_MISC1, &reg_val);
  1054. /* clearing the speed value before setting the right speed */
  1055. DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
  1056. reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
  1057. MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
  1058. if (!((vars->line_speed == SPEED_1000) ||
  1059. (vars->line_speed == SPEED_100) ||
  1060. (vars->line_speed == SPEED_10))) {
  1061. reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
  1062. MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
  1063. if (vars->line_speed == SPEED_10000)
  1064. reg_val |=
  1065. MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
  1066. if (vars->line_speed == SPEED_13000)
  1067. reg_val |=
  1068. MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
  1069. }
  1070. CL45_WR_OVER_CL22(bp, params->port,
  1071. params->phy_addr,
  1072. MDIO_REG_BANK_SERDES_DIGITAL,
  1073. MDIO_SERDES_DIGITAL_MISC1, reg_val);
  1074. }
  1075. static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
  1076. {
  1077. struct bnx2x *bp = params->bp;
  1078. u16 val = 0;
  1079. /* configure the 48 bits for BAM AN */
  1080. /* set extended capabilities */
  1081. if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
  1082. val |= MDIO_OVER_1G_UP1_2_5G;
  1083. if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
  1084. val |= MDIO_OVER_1G_UP1_10G;
  1085. CL45_WR_OVER_CL22(bp, params->port,
  1086. params->phy_addr,
  1087. MDIO_REG_BANK_OVER_1G,
  1088. MDIO_OVER_1G_UP1, val);
  1089. CL45_WR_OVER_CL22(bp, params->port,
  1090. params->phy_addr,
  1091. MDIO_REG_BANK_OVER_1G,
  1092. MDIO_OVER_1G_UP3, 0);
  1093. }
  1094. static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
  1095. {
  1096. *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
  1097. /* resolve pause mode and advertisement
  1098. * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
  1099. switch (params->req_flow_ctrl) {
  1100. case BNX2X_FLOW_CTRL_AUTO:
  1101. if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
  1102. *ieee_fc |=
  1103. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  1104. } else {
  1105. *ieee_fc |=
  1106. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
  1107. }
  1108. break;
  1109. case BNX2X_FLOW_CTRL_TX:
  1110. *ieee_fc |=
  1111. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
  1112. break;
  1113. case BNX2X_FLOW_CTRL_RX:
  1114. case BNX2X_FLOW_CTRL_BOTH:
  1115. *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  1116. break;
  1117. case BNX2X_FLOW_CTRL_NONE:
  1118. default:
  1119. *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
  1120. break;
  1121. }
  1122. }
  1123. static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
  1124. u32 ieee_fc)
  1125. {
  1126. struct bnx2x *bp = params->bp;
  1127. /* for AN, we are always publishing full duplex */
  1128. CL45_WR_OVER_CL22(bp, params->port,
  1129. params->phy_addr,
  1130. MDIO_REG_BANK_COMBO_IEEE0,
  1131. MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
  1132. }
  1133. static void bnx2x_restart_autoneg(struct link_params *params)
  1134. {
  1135. struct bnx2x *bp = params->bp;
  1136. u16 mii_control;
  1137. DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
  1138. /* Enable and restart BAM/CL37 aneg */
  1139. CL45_RD_OVER_CL22(bp, params->port,
  1140. params->phy_addr,
  1141. MDIO_REG_BANK_COMBO_IEEE0,
  1142. MDIO_COMBO_IEEE0_MII_CONTROL,
  1143. &mii_control);
  1144. DP(NETIF_MSG_LINK,
  1145. "bnx2x_restart_autoneg mii_control before = 0x%x\n",
  1146. mii_control);
  1147. CL45_WR_OVER_CL22(bp, params->port,
  1148. params->phy_addr,
  1149. MDIO_REG_BANK_COMBO_IEEE0,
  1150. MDIO_COMBO_IEEE0_MII_CONTROL,
  1151. (mii_control |
  1152. MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
  1153. MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
  1154. }
  1155. static void bnx2x_initialize_sgmii_process(struct link_params *params,
  1156. struct link_vars *vars)
  1157. {
  1158. struct bnx2x *bp = params->bp;
  1159. u16 control1;
  1160. /* in SGMII mode, the unicore is always slave */
  1161. CL45_RD_OVER_CL22(bp, params->port,
  1162. params->phy_addr,
  1163. MDIO_REG_BANK_SERDES_DIGITAL,
  1164. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
  1165. &control1);
  1166. control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
  1167. /* set sgmii mode (and not fiber) */
  1168. control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
  1169. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
  1170. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
  1171. CL45_WR_OVER_CL22(bp, params->port,
  1172. params->phy_addr,
  1173. MDIO_REG_BANK_SERDES_DIGITAL,
  1174. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
  1175. control1);
  1176. /* if forced speed */
  1177. if (!(vars->line_speed == SPEED_AUTO_NEG)) {
  1178. /* set speed, disable autoneg */
  1179. u16 mii_control;
  1180. CL45_RD_OVER_CL22(bp, params->port,
  1181. params->phy_addr,
  1182. MDIO_REG_BANK_COMBO_IEEE0,
  1183. MDIO_COMBO_IEEE0_MII_CONTROL,
  1184. &mii_control);
  1185. mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
  1186. MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
  1187. MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
  1188. switch (vars->line_speed) {
  1189. case SPEED_100:
  1190. mii_control |=
  1191. MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
  1192. break;
  1193. case SPEED_1000:
  1194. mii_control |=
  1195. MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
  1196. break;
  1197. case SPEED_10:
  1198. /* there is nothing to set for 10M */
  1199. break;
  1200. default:
  1201. /* invalid speed for SGMII */
  1202. DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
  1203. vars->line_speed);
  1204. break;
  1205. }
  1206. /* setting the full duplex */
  1207. if (params->req_duplex == DUPLEX_FULL)
  1208. mii_control |=
  1209. MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
  1210. CL45_WR_OVER_CL22(bp, params->port,
  1211. params->phy_addr,
  1212. MDIO_REG_BANK_COMBO_IEEE0,
  1213. MDIO_COMBO_IEEE0_MII_CONTROL,
  1214. mii_control);
  1215. } else { /* AN mode */
  1216. /* enable and restart AN */
  1217. bnx2x_restart_autoneg(params);
  1218. }
  1219. }
  1220. /*
  1221. * link management
  1222. */
  1223. static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
  1224. { /* LD LP */
  1225. switch (pause_result) { /* ASYM P ASYM P */
  1226. case 0xb: /* 1 0 1 1 */
  1227. vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
  1228. break;
  1229. case 0xe: /* 1 1 1 0 */
  1230. vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
  1231. break;
  1232. case 0x5: /* 0 1 0 1 */
  1233. case 0x7: /* 0 1 1 1 */
  1234. case 0xd: /* 1 1 0 1 */
  1235. case 0xf: /* 1 1 1 1 */
  1236. vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
  1237. break;
  1238. default:
  1239. break;
  1240. }
  1241. }
  1242. static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
  1243. struct link_vars *vars)
  1244. {
  1245. struct bnx2x *bp = params->bp;
  1246. u8 ext_phy_addr;
  1247. u16 ld_pause; /* local */
  1248. u16 lp_pause; /* link partner */
  1249. u16 an_complete; /* AN complete */
  1250. u16 pause_result;
  1251. u8 ret = 0;
  1252. u32 ext_phy_type;
  1253. u8 port = params->port;
  1254. ext_phy_addr = ((params->ext_phy_config &
  1255. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  1256. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  1257. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  1258. /* read twice */
  1259. bnx2x_cl45_read(bp, port,
  1260. ext_phy_type,
  1261. ext_phy_addr,
  1262. MDIO_AN_DEVAD,
  1263. MDIO_AN_REG_STATUS, &an_complete);
  1264. bnx2x_cl45_read(bp, port,
  1265. ext_phy_type,
  1266. ext_phy_addr,
  1267. MDIO_AN_DEVAD,
  1268. MDIO_AN_REG_STATUS, &an_complete);
  1269. if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
  1270. ret = 1;
  1271. bnx2x_cl45_read(bp, port,
  1272. ext_phy_type,
  1273. ext_phy_addr,
  1274. MDIO_AN_DEVAD,
  1275. MDIO_AN_REG_ADV_PAUSE, &ld_pause);
  1276. bnx2x_cl45_read(bp, port,
  1277. ext_phy_type,
  1278. ext_phy_addr,
  1279. MDIO_AN_DEVAD,
  1280. MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
  1281. pause_result = (ld_pause &
  1282. MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
  1283. pause_result |= (lp_pause &
  1284. MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
  1285. DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
  1286. pause_result);
  1287. bnx2x_pause_resolve(vars, pause_result);
  1288. if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
  1289. ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
  1290. bnx2x_cl45_read(bp, port,
  1291. ext_phy_type,
  1292. ext_phy_addr,
  1293. MDIO_AN_DEVAD,
  1294. MDIO_AN_REG_CL37_FC_LD, &ld_pause);
  1295. bnx2x_cl45_read(bp, port,
  1296. ext_phy_type,
  1297. ext_phy_addr,
  1298. MDIO_AN_DEVAD,
  1299. MDIO_AN_REG_CL37_FC_LP, &lp_pause);
  1300. pause_result = (ld_pause &
  1301. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
  1302. pause_result |= (lp_pause &
  1303. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
  1304. bnx2x_pause_resolve(vars, pause_result);
  1305. DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
  1306. pause_result);
  1307. }
  1308. }
  1309. return ret;
  1310. }
  1311. static void bnx2x_flow_ctrl_resolve(struct link_params *params,
  1312. struct link_vars *vars,
  1313. u32 gp_status)
  1314. {
  1315. struct bnx2x *bp = params->bp;
  1316. u16 ld_pause; /* local driver */
  1317. u16 lp_pause; /* link partner */
  1318. u16 pause_result;
  1319. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  1320. /* resolve from gp_status in case of AN complete and not sgmii */
  1321. if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
  1322. (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
  1323. (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
  1324. (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
  1325. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
  1326. CL45_RD_OVER_CL22(bp, params->port,
  1327. params->phy_addr,
  1328. MDIO_REG_BANK_COMBO_IEEE0,
  1329. MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
  1330. &ld_pause);
  1331. CL45_RD_OVER_CL22(bp, params->port,
  1332. params->phy_addr,
  1333. MDIO_REG_BANK_COMBO_IEEE0,
  1334. MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
  1335. &lp_pause);
  1336. pause_result = (ld_pause &
  1337. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
  1338. pause_result |= (lp_pause &
  1339. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
  1340. DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
  1341. bnx2x_pause_resolve(vars, pause_result);
  1342. } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
  1343. (bnx2x_ext_phy_resove_fc(params, vars))) {
  1344. return;
  1345. } else {
  1346. if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
  1347. vars->flow_ctrl = params->req_fc_auto_adv;
  1348. else
  1349. vars->flow_ctrl = params->req_flow_ctrl;
  1350. }
  1351. DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
  1352. }
  1353. static u8 bnx2x_link_settings_status(struct link_params *params,
  1354. struct link_vars *vars,
  1355. u32 gp_status)
  1356. {
  1357. struct bnx2x *bp = params->bp;
  1358. u16 new_line_speed;
  1359. u8 rc = 0;
  1360. vars->link_status = 0;
  1361. if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
  1362. DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
  1363. gp_status);
  1364. vars->phy_link_up = 1;
  1365. vars->link_status |= LINK_STATUS_LINK_UP;
  1366. if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
  1367. vars->duplex = DUPLEX_FULL;
  1368. else
  1369. vars->duplex = DUPLEX_HALF;
  1370. bnx2x_flow_ctrl_resolve(params, vars, gp_status);
  1371. switch (gp_status & GP_STATUS_SPEED_MASK) {
  1372. case GP_STATUS_10M:
  1373. new_line_speed = SPEED_10;
  1374. if (vars->duplex == DUPLEX_FULL)
  1375. vars->link_status |= LINK_10TFD;
  1376. else
  1377. vars->link_status |= LINK_10THD;
  1378. break;
  1379. case GP_STATUS_100M:
  1380. new_line_speed = SPEED_100;
  1381. if (vars->duplex == DUPLEX_FULL)
  1382. vars->link_status |= LINK_100TXFD;
  1383. else
  1384. vars->link_status |= LINK_100TXHD;
  1385. break;
  1386. case GP_STATUS_1G:
  1387. case GP_STATUS_1G_KX:
  1388. new_line_speed = SPEED_1000;
  1389. if (vars->duplex == DUPLEX_FULL)
  1390. vars->link_status |= LINK_1000TFD;
  1391. else
  1392. vars->link_status |= LINK_1000THD;
  1393. break;
  1394. case GP_STATUS_2_5G:
  1395. new_line_speed = SPEED_2500;
  1396. if (vars->duplex == DUPLEX_FULL)
  1397. vars->link_status |= LINK_2500TFD;
  1398. else
  1399. vars->link_status |= LINK_2500THD;
  1400. break;
  1401. case GP_STATUS_5G:
  1402. case GP_STATUS_6G:
  1403. DP(NETIF_MSG_LINK,
  1404. "link speed unsupported gp_status 0x%x\n",
  1405. gp_status);
  1406. return -EINVAL;
  1407. break;
  1408. case GP_STATUS_10G_KX4:
  1409. case GP_STATUS_10G_HIG:
  1410. case GP_STATUS_10G_CX4:
  1411. new_line_speed = SPEED_10000;
  1412. vars->link_status |= LINK_10GTFD;
  1413. break;
  1414. case GP_STATUS_12G_HIG:
  1415. new_line_speed = SPEED_12000;
  1416. vars->link_status |= LINK_12GTFD;
  1417. break;
  1418. case GP_STATUS_12_5G:
  1419. new_line_speed = SPEED_12500;
  1420. vars->link_status |= LINK_12_5GTFD;
  1421. break;
  1422. case GP_STATUS_13G:
  1423. new_line_speed = SPEED_13000;
  1424. vars->link_status |= LINK_13GTFD;
  1425. break;
  1426. case GP_STATUS_15G:
  1427. new_line_speed = SPEED_15000;
  1428. vars->link_status |= LINK_15GTFD;
  1429. break;
  1430. case GP_STATUS_16G:
  1431. new_line_speed = SPEED_16000;
  1432. vars->link_status |= LINK_16GTFD;
  1433. break;
  1434. default:
  1435. DP(NETIF_MSG_LINK,
  1436. "link speed unsupported gp_status 0x%x\n",
  1437. gp_status);
  1438. return -EINVAL;
  1439. break;
  1440. }
  1441. /* Upon link speed change set the NIG into drain mode.
  1442. Comes to deals with possible FIFO glitch due to clk change
  1443. when speed is decreased without link down indicator */
  1444. if (new_line_speed != vars->line_speed) {
  1445. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
  1446. + params->port*4, 0);
  1447. msleep(1);
  1448. }
  1449. vars->line_speed = new_line_speed;
  1450. vars->link_status |= LINK_STATUS_SERDES_LINK;
  1451. if ((params->req_line_speed == SPEED_AUTO_NEG) &&
  1452. ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
  1453. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
  1454. (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
  1455. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
  1456. (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
  1457. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
  1458. (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
  1459. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
  1460. vars->autoneg = AUTO_NEG_ENABLED;
  1461. if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
  1462. vars->autoneg |= AUTO_NEG_COMPLETE;
  1463. vars->link_status |=
  1464. LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
  1465. }
  1466. vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
  1467. vars->link_status |=
  1468. LINK_STATUS_PARALLEL_DETECTION_USED;
  1469. }
  1470. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  1471. vars->link_status |=
  1472. LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
  1473. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
  1474. vars->link_status |=
  1475. LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
  1476. } else { /* link_down */
  1477. DP(NETIF_MSG_LINK, "phy link down\n");
  1478. vars->phy_link_up = 0;
  1479. vars->duplex = DUPLEX_FULL;
  1480. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  1481. vars->autoneg = AUTO_NEG_DISABLED;
  1482. vars->mac_type = MAC_TYPE_NONE;
  1483. }
  1484. DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
  1485. gp_status, vars->phy_link_up, vars->line_speed);
  1486. DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
  1487. " autoneg 0x%x\n",
  1488. vars->duplex,
  1489. vars->flow_ctrl, vars->autoneg);
  1490. DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
  1491. return rc;
  1492. }
  1493. static void bnx2x_set_gmii_tx_driver(struct link_params *params)
  1494. {
  1495. struct bnx2x *bp = params->bp;
  1496. u16 lp_up2;
  1497. u16 tx_driver;
  1498. u16 bank;
  1499. /* read precomp */
  1500. CL45_RD_OVER_CL22(bp, params->port,
  1501. params->phy_addr,
  1502. MDIO_REG_BANK_OVER_1G,
  1503. MDIO_OVER_1G_LP_UP2, &lp_up2);
  1504. /* bits [10:7] at lp_up2, positioned at [15:12] */
  1505. lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
  1506. MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
  1507. MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
  1508. if (lp_up2 == 0)
  1509. return;
  1510. for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
  1511. bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
  1512. CL45_RD_OVER_CL22(bp, params->port,
  1513. params->phy_addr,
  1514. bank,
  1515. MDIO_TX0_TX_DRIVER, &tx_driver);
  1516. /* replace tx_driver bits [15:12] */
  1517. if (lp_up2 !=
  1518. (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
  1519. tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
  1520. tx_driver |= lp_up2;
  1521. CL45_WR_OVER_CL22(bp, params->port,
  1522. params->phy_addr,
  1523. bank,
  1524. MDIO_TX0_TX_DRIVER, tx_driver);
  1525. }
  1526. }
  1527. }
  1528. static u8 bnx2x_emac_program(struct link_params *params,
  1529. u32 line_speed, u32 duplex)
  1530. {
  1531. struct bnx2x *bp = params->bp;
  1532. u8 port = params->port;
  1533. u16 mode = 0;
  1534. DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
  1535. bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
  1536. EMAC_REG_EMAC_MODE,
  1537. (EMAC_MODE_25G_MODE |
  1538. EMAC_MODE_PORT_MII_10M |
  1539. EMAC_MODE_HALF_DUPLEX));
  1540. switch (line_speed) {
  1541. case SPEED_10:
  1542. mode |= EMAC_MODE_PORT_MII_10M;
  1543. break;
  1544. case SPEED_100:
  1545. mode |= EMAC_MODE_PORT_MII;
  1546. break;
  1547. case SPEED_1000:
  1548. mode |= EMAC_MODE_PORT_GMII;
  1549. break;
  1550. case SPEED_2500:
  1551. mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
  1552. break;
  1553. default:
  1554. /* 10G not valid for EMAC */
  1555. DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
  1556. return -EINVAL;
  1557. }
  1558. if (duplex == DUPLEX_HALF)
  1559. mode |= EMAC_MODE_HALF_DUPLEX;
  1560. bnx2x_bits_en(bp,
  1561. GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
  1562. mode);
  1563. bnx2x_set_led(bp, params->port, LED_MODE_OPER,
  1564. line_speed, params->hw_led_mode, params->chip_id);
  1565. return 0;
  1566. }
  1567. /*****************************************************************************/
  1568. /* External Phy section */
  1569. /*****************************************************************************/
  1570. static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
  1571. {
  1572. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  1573. MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
  1574. msleep(1);
  1575. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  1576. MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
  1577. }
  1578. static void bnx2x_ext_phy_reset(struct link_params *params,
  1579. struct link_vars *vars)
  1580. {
  1581. struct bnx2x *bp = params->bp;
  1582. u32 ext_phy_type;
  1583. u8 ext_phy_addr = ((params->ext_phy_config &
  1584. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  1585. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  1586. DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
  1587. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  1588. /* The PHY reset is controled by GPIO 1
  1589. * Give it 1ms of reset pulse
  1590. */
  1591. if (vars->phy_flags & PHY_XGXS_FLAG) {
  1592. switch (ext_phy_type) {
  1593. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  1594. DP(NETIF_MSG_LINK, "XGXS Direct\n");
  1595. break;
  1596. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
  1597. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
  1598. DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
  1599. /* Restore normal power mode*/
  1600. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  1601. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1602. params->port);
  1603. /* HW reset */
  1604. bnx2x_hw_reset(bp, params->port);
  1605. bnx2x_cl45_write(bp, params->port,
  1606. ext_phy_type,
  1607. ext_phy_addr,
  1608. MDIO_PMA_DEVAD,
  1609. MDIO_PMA_REG_CTRL, 0xa040);
  1610. break;
  1611. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  1612. /* Restore normal power mode*/
  1613. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  1614. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1615. params->port);
  1616. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  1617. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1618. params->port);
  1619. bnx2x_cl45_write(bp, params->port,
  1620. ext_phy_type,
  1621. ext_phy_addr,
  1622. MDIO_PMA_DEVAD,
  1623. MDIO_PMA_REG_CTRL,
  1624. 1<<15);
  1625. break;
  1626. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  1627. /* Unset Low Power Mode and SW reset */
  1628. /* Restore normal power mode*/
  1629. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  1630. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1631. params->port);
  1632. DP(NETIF_MSG_LINK, "XGXS 8072\n");
  1633. bnx2x_cl45_write(bp, params->port,
  1634. ext_phy_type,
  1635. ext_phy_addr,
  1636. MDIO_PMA_DEVAD,
  1637. MDIO_PMA_REG_CTRL,
  1638. 1<<15);
  1639. break;
  1640. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  1641. {
  1642. /* Restore normal power mode*/
  1643. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  1644. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1645. params->port);
  1646. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  1647. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1648. params->port);
  1649. DP(NETIF_MSG_LINK, "XGXS 8073\n");
  1650. }
  1651. break;
  1652. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
  1653. DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
  1654. /* Restore normal power mode*/
  1655. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  1656. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1657. params->port);
  1658. /* HW reset */
  1659. bnx2x_hw_reset(bp, params->port);
  1660. break;
  1661. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
  1662. /* Restore normal power mode*/
  1663. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  1664. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  1665. params->port);
  1666. /* HW reset */
  1667. bnx2x_hw_reset(bp, params->port);
  1668. bnx2x_cl45_write(bp, params->port,
  1669. ext_phy_type,
  1670. ext_phy_addr,
  1671. MDIO_PMA_DEVAD,
  1672. MDIO_PMA_REG_CTRL,
  1673. 1<<15);
  1674. break;
  1675. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
  1676. DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
  1677. break;
  1678. default:
  1679. DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
  1680. params->ext_phy_config);
  1681. break;
  1682. }
  1683. } else { /* SerDes */
  1684. ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
  1685. switch (ext_phy_type) {
  1686. case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
  1687. DP(NETIF_MSG_LINK, "SerDes Direct\n");
  1688. break;
  1689. case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
  1690. DP(NETIF_MSG_LINK, "SerDes 5482\n");
  1691. bnx2x_hw_reset(bp, params->port);
  1692. break;
  1693. default:
  1694. DP(NETIF_MSG_LINK,
  1695. "BAD SerDes ext_phy_config 0x%x\n",
  1696. params->ext_phy_config);
  1697. break;
  1698. }
  1699. }
  1700. }
  1701. static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
  1702. u32 shmem_base, u32 spirom_ver)
  1703. {
  1704. DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
  1705. (u16)(spirom_ver>>16), (u16)spirom_ver);
  1706. REG_WR(bp, shmem_base +
  1707. offsetof(struct shmem_region,
  1708. port_mb[port].ext_phy_fw_version),
  1709. spirom_ver);
  1710. }
  1711. static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
  1712. u32 ext_phy_type, u8 ext_phy_addr,
  1713. u32 shmem_base)
  1714. {
  1715. u16 fw_ver1, fw_ver2;
  1716. bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
  1717. MDIO_PMA_REG_ROM_VER1, &fw_ver1);
  1718. bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
  1719. MDIO_PMA_REG_ROM_VER2, &fw_ver2);
  1720. bnx2x_save_spirom_version(bp, port, shmem_base,
  1721. (u32)(fw_ver1<<16 | fw_ver2));
  1722. }
  1723. static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
  1724. {
  1725. struct bnx2x *bp = params->bp;
  1726. u8 port = params->port;
  1727. u8 ext_phy_addr = ((params->ext_phy_config &
  1728. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  1729. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  1730. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  1731. /* Need to wait 200ms after reset */
  1732. msleep(200);
  1733. /* Boot port from external ROM
  1734. * Set ser_boot_ctl bit in the MISC_CTRL1 register
  1735. */
  1736. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1737. MDIO_PMA_DEVAD,
  1738. MDIO_PMA_REG_MISC_CTRL1, 0x0001);
  1739. /* Reset internal microprocessor */
  1740. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1741. MDIO_PMA_DEVAD,
  1742. MDIO_PMA_REG_GEN_CTRL,
  1743. MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
  1744. /* set micro reset = 0 */
  1745. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1746. MDIO_PMA_DEVAD,
  1747. MDIO_PMA_REG_GEN_CTRL,
  1748. MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
  1749. /* Reset internal microprocessor */
  1750. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1751. MDIO_PMA_DEVAD,
  1752. MDIO_PMA_REG_GEN_CTRL,
  1753. MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
  1754. /* wait for 100ms for code download via SPI port */
  1755. msleep(100);
  1756. /* Clear ser_boot_ctl bit */
  1757. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1758. MDIO_PMA_DEVAD,
  1759. MDIO_PMA_REG_MISC_CTRL1, 0x0000);
  1760. /* Wait 100ms */
  1761. msleep(100);
  1762. bnx2x_save_bcm_spirom_ver(bp, port,
  1763. ext_phy_type,
  1764. ext_phy_addr,
  1765. params->shmem_base);
  1766. }
  1767. static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
  1768. {
  1769. /* This is only required for 8073A1, version 102 only */
  1770. struct bnx2x *bp = params->bp;
  1771. u8 ext_phy_addr = ((params->ext_phy_config &
  1772. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  1773. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  1774. u16 val;
  1775. /* Read 8073 HW revision*/
  1776. bnx2x_cl45_read(bp, params->port,
  1777. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1778. ext_phy_addr,
  1779. MDIO_PMA_DEVAD,
  1780. MDIO_PMA_REG_8073_CHIP_REV, &val);
  1781. if (val != 1) {
  1782. /* No need to workaround in 8073 A1 */
  1783. return 0;
  1784. }
  1785. bnx2x_cl45_read(bp, params->port,
  1786. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1787. ext_phy_addr,
  1788. MDIO_PMA_DEVAD,
  1789. MDIO_PMA_REG_ROM_VER2, &val);
  1790. /* SNR should be applied only for version 0x102 */
  1791. if (val != 0x102)
  1792. return 0;
  1793. return 1;
  1794. }
  1795. static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
  1796. {
  1797. struct bnx2x *bp = params->bp;
  1798. u8 ext_phy_addr = ((params->ext_phy_config &
  1799. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  1800. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  1801. u16 val, cnt, cnt1 ;
  1802. bnx2x_cl45_read(bp, params->port,
  1803. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1804. ext_phy_addr,
  1805. MDIO_PMA_DEVAD,
  1806. MDIO_PMA_REG_8073_CHIP_REV, &val);
  1807. if (val > 0) {
  1808. /* No need to workaround in 8073 A1 */
  1809. return 0;
  1810. }
  1811. /* XAUI workaround in 8073 A0: */
  1812. /* After loading the boot ROM and restarting Autoneg,
  1813. poll Dev1, Reg $C820: */
  1814. for (cnt = 0; cnt < 1000; cnt++) {
  1815. bnx2x_cl45_read(bp, params->port,
  1816. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1817. ext_phy_addr,
  1818. MDIO_PMA_DEVAD,
  1819. MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
  1820. &val);
  1821. /* If bit [14] = 0 or bit [13] = 0, continue on with
  1822. system initialization (XAUI work-around not required,
  1823. as these bits indicate 2.5G or 1G link up). */
  1824. if (!(val & (1<<14)) || !(val & (1<<13))) {
  1825. DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
  1826. return 0;
  1827. } else if (!(val & (1<<15))) {
  1828. DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
  1829. /* If bit 15 is 0, then poll Dev1, Reg $C841 until
  1830. it's MSB (bit 15) goes to 1 (indicating that the
  1831. XAUI workaround has completed),
  1832. then continue on with system initialization.*/
  1833. for (cnt1 = 0; cnt1 < 1000; cnt1++) {
  1834. bnx2x_cl45_read(bp, params->port,
  1835. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1836. ext_phy_addr,
  1837. MDIO_PMA_DEVAD,
  1838. MDIO_PMA_REG_8073_XAUI_WA, &val);
  1839. if (val & (1<<15)) {
  1840. DP(NETIF_MSG_LINK,
  1841. "XAUI workaround has completed\n");
  1842. return 0;
  1843. }
  1844. msleep(3);
  1845. }
  1846. break;
  1847. }
  1848. msleep(3);
  1849. }
  1850. DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
  1851. return -EINVAL;
  1852. }
  1853. static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
  1854. u8 ext_phy_addr, u32 shmem_base)
  1855. {
  1856. /* Boot port from external ROM */
  1857. /* EDC grst */
  1858. bnx2x_cl45_write(bp, port,
  1859. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1860. ext_phy_addr,
  1861. MDIO_PMA_DEVAD,
  1862. MDIO_PMA_REG_GEN_CTRL,
  1863. 0x0001);
  1864. /* ucode reboot and rst */
  1865. bnx2x_cl45_write(bp, port,
  1866. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1867. ext_phy_addr,
  1868. MDIO_PMA_DEVAD,
  1869. MDIO_PMA_REG_GEN_CTRL,
  1870. 0x008c);
  1871. bnx2x_cl45_write(bp, port,
  1872. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1873. ext_phy_addr,
  1874. MDIO_PMA_DEVAD,
  1875. MDIO_PMA_REG_MISC_CTRL1, 0x0001);
  1876. /* Reset internal microprocessor */
  1877. bnx2x_cl45_write(bp, port,
  1878. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1879. ext_phy_addr,
  1880. MDIO_PMA_DEVAD,
  1881. MDIO_PMA_REG_GEN_CTRL,
  1882. MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
  1883. /* Release srst bit */
  1884. bnx2x_cl45_write(bp, port,
  1885. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1886. ext_phy_addr,
  1887. MDIO_PMA_DEVAD,
  1888. MDIO_PMA_REG_GEN_CTRL,
  1889. MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
  1890. /* wait for 100ms for code download via SPI port */
  1891. msleep(100);
  1892. /* Clear ser_boot_ctl bit */
  1893. bnx2x_cl45_write(bp, port,
  1894. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1895. ext_phy_addr,
  1896. MDIO_PMA_DEVAD,
  1897. MDIO_PMA_REG_MISC_CTRL1, 0x0000);
  1898. bnx2x_save_bcm_spirom_ver(bp, port,
  1899. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  1900. ext_phy_addr,
  1901. shmem_base);
  1902. }
  1903. static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
  1904. {
  1905. struct bnx2x *bp = params->bp;
  1906. u8 port = params->port;
  1907. u8 ext_phy_addr = ((params->ext_phy_config &
  1908. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  1909. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  1910. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  1911. /* Need to wait 100ms after reset */
  1912. msleep(100);
  1913. /* Set serial boot control for external load */
  1914. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1915. MDIO_PMA_DEVAD,
  1916. MDIO_PMA_REG_MISC_CTRL1, 0x0001);
  1917. /* Micro controller re-boot */
  1918. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1919. MDIO_PMA_DEVAD,
  1920. MDIO_PMA_REG_GEN_CTRL,
  1921. MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
  1922. /* Set soft reset */
  1923. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1924. MDIO_PMA_DEVAD,
  1925. MDIO_PMA_REG_GEN_CTRL,
  1926. MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
  1927. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1928. MDIO_PMA_DEVAD,
  1929. MDIO_PMA_REG_GEN_CTRL2,
  1930. 0x73A0);
  1931. /* Clear soft reset.
  1932. Will automatically reset micro-controller re-boot */
  1933. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1934. MDIO_PMA_DEVAD,
  1935. MDIO_PMA_REG_GEN_CTRL,
  1936. MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
  1937. /* wait for 150ms for microcode load */
  1938. msleep(150);
  1939. /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
  1940. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  1941. MDIO_PMA_DEVAD,
  1942. MDIO_PMA_REG_MISC_CTRL1, 0x0000);
  1943. msleep(200);
  1944. bnx2x_save_bcm_spirom_ver(bp, port,
  1945. ext_phy_type,
  1946. ext_phy_addr,
  1947. params->shmem_base);
  1948. }
  1949. static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
  1950. u8 ext_phy_addr, u8 tx_en)
  1951. {
  1952. u16 val;
  1953. DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
  1954. tx_en, port);
  1955. /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
  1956. bnx2x_cl45_read(bp, port,
  1957. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  1958. ext_phy_addr,
  1959. MDIO_PMA_DEVAD,
  1960. MDIO_PMA_REG_PHY_IDENTIFIER,
  1961. &val);
  1962. if (tx_en)
  1963. val &= ~(1<<15);
  1964. else
  1965. val |= (1<<15);
  1966. bnx2x_cl45_write(bp, port,
  1967. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  1968. ext_phy_addr,
  1969. MDIO_PMA_DEVAD,
  1970. MDIO_PMA_REG_PHY_IDENTIFIER,
  1971. val);
  1972. }
  1973. static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
  1974. u8 byte_cnt, u8 *o_buf) {
  1975. struct bnx2x *bp = params->bp;
  1976. u16 val, i;
  1977. u8 port = params->port;
  1978. u8 ext_phy_addr = ((params->ext_phy_config &
  1979. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  1980. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  1981. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  1982. if (byte_cnt > 16) {
  1983. DP(NETIF_MSG_LINK, "Reading from eeprom is"
  1984. " is limited to 0xf\n");
  1985. return -EINVAL;
  1986. }
  1987. /* Set the read command byte count */
  1988. bnx2x_cl45_write(bp, port,
  1989. ext_phy_type,
  1990. ext_phy_addr,
  1991. MDIO_PMA_DEVAD,
  1992. MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
  1993. (byte_cnt | 0xa000));
  1994. /* Set the read command address */
  1995. bnx2x_cl45_write(bp, port,
  1996. ext_phy_type,
  1997. ext_phy_addr,
  1998. MDIO_PMA_DEVAD,
  1999. MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
  2000. addr);
  2001. /* Activate read command */
  2002. bnx2x_cl45_write(bp, port,
  2003. ext_phy_type,
  2004. ext_phy_addr,
  2005. MDIO_PMA_DEVAD,
  2006. MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
  2007. 0x2c0f);
  2008. /* Wait up to 500us for command complete status */
  2009. for (i = 0; i < 100; i++) {
  2010. bnx2x_cl45_read(bp, port,
  2011. ext_phy_type,
  2012. ext_phy_addr,
  2013. MDIO_PMA_DEVAD,
  2014. MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
  2015. if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
  2016. MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
  2017. break;
  2018. udelay(5);
  2019. }
  2020. if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
  2021. MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
  2022. DP(NETIF_MSG_LINK,
  2023. "Got bad status 0x%x when reading from SFP+ EEPROM\n",
  2024. (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
  2025. return -EINVAL;
  2026. }
  2027. /* Read the buffer */
  2028. for (i = 0; i < byte_cnt; i++) {
  2029. bnx2x_cl45_read(bp, port,
  2030. ext_phy_type,
  2031. ext_phy_addr,
  2032. MDIO_PMA_DEVAD,
  2033. MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
  2034. o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
  2035. }
  2036. for (i = 0; i < 100; i++) {
  2037. bnx2x_cl45_read(bp, port,
  2038. ext_phy_type,
  2039. ext_phy_addr,
  2040. MDIO_PMA_DEVAD,
  2041. MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
  2042. if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
  2043. MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
  2044. return 0;;
  2045. msleep(1);
  2046. }
  2047. return -EINVAL;
  2048. }
  2049. static u8 bnx2x_get_sfp_module_type(struct link_params *params,
  2050. u8 *module_type)
  2051. {
  2052. struct bnx2x *bp = params->bp;
  2053. u8 val;
  2054. *module_type = SFP_MODULE_TYPE_UNKNOWN;
  2055. /* First check for copper cable */
  2056. if (bnx2x_read_sfp_module_eeprom(params,
  2057. SFP_EEPROM_CON_TYPE_ADDR,
  2058. 1,
  2059. &val) != 0) {
  2060. DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
  2061. return -EINVAL;
  2062. }
  2063. switch (val) {
  2064. case SFP_EEPROM_CON_TYPE_VAL_COPPER:
  2065. {
  2066. u8 copper_module_type;
  2067. /* Check if its active cable( includes SFP+ module)
  2068. of passive cable*/
  2069. if (bnx2x_read_sfp_module_eeprom(params,
  2070. SFP_EEPROM_FC_TX_TECH_ADDR,
  2071. 1,
  2072. &copper_module_type) !=
  2073. 0) {
  2074. DP(NETIF_MSG_LINK,
  2075. "Failed to read copper-cable-type"
  2076. " from SFP+ EEPROM\n");
  2077. return -EINVAL;
  2078. }
  2079. if (copper_module_type &
  2080. SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
  2081. DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
  2082. *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
  2083. } else if (copper_module_type &
  2084. SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
  2085. DP(NETIF_MSG_LINK, "Passive Copper"
  2086. " cable detected\n");
  2087. *module_type =
  2088. SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
  2089. } else {
  2090. DP(NETIF_MSG_LINK, "Unknown copper-cable-"
  2091. "type 0x%x !!!\n", copper_module_type);
  2092. return -EINVAL;
  2093. }
  2094. break;
  2095. }
  2096. case SFP_EEPROM_CON_TYPE_VAL_LC:
  2097. DP(NETIF_MSG_LINK, "Optic module detected\n");
  2098. *module_type = SFP_MODULE_TYPE_LC;
  2099. break;
  2100. default:
  2101. DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
  2102. val);
  2103. return -EINVAL;
  2104. }
  2105. return 0;
  2106. }
  2107. /* This function read the relevant field from the module ( SFP+ ),
  2108. and verify it is compliant with this board */
  2109. static u8 bnx2x_verify_sfp_module(struct link_params *params,
  2110. u8 module_type)
  2111. {
  2112. struct bnx2x *bp = params->bp;
  2113. u8 *str_p, *tmp_buf;
  2114. u16 i;
  2115. #define COMPLIANCE_STR_CNT 6
  2116. u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
  2117. "FINISAR CORP. ", "Amphenol"};
  2118. u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
  2119. /* Passive Copper cables are allowed to participate,
  2120. since the module is hardwired to the copper cable */
  2121. if (!(params->feature_config_flags &
  2122. FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
  2123. DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
  2124. return 0;
  2125. }
  2126. if (module_type != SFP_MODULE_TYPE_LC) {
  2127. DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
  2128. return 0;
  2129. }
  2130. /* In case of non copper cable or Active copper cable,
  2131. verify that the SFP+ module is compliant with this board*/
  2132. if (bnx2x_read_sfp_module_eeprom(params,
  2133. SFP_EEPROM_VENDOR_NAME_ADDR,
  2134. SFP_EEPROM_VENDOR_NAME_SIZE,
  2135. buf) != 0) {
  2136. DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
  2137. " module EEPROM\n");
  2138. return -EINVAL;
  2139. }
  2140. for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
  2141. str_p = compliance_str[i];
  2142. tmp_buf = buf;
  2143. while (*str_p) {
  2144. if ((u8)(*tmp_buf) != (u8)(*str_p))
  2145. break;
  2146. str_p++;
  2147. tmp_buf++;
  2148. }
  2149. if (!(*str_p)) {
  2150. DP(NETIF_MSG_LINK, "SFP+ Module verified, "
  2151. "index=%x\n", i);
  2152. return 0;
  2153. }
  2154. }
  2155. DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
  2156. return -EINVAL;
  2157. }
  2158. static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
  2159. u8 module_type)
  2160. {
  2161. struct bnx2x *bp = params->bp;
  2162. u8 port = params->port;
  2163. u8 options[SFP_EEPROM_OPTIONS_SIZE];
  2164. u8 limiting_mode;
  2165. u8 ext_phy_addr = ((params->ext_phy_config &
  2166. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2167. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2168. u16 cur_limiting_mode;
  2169. if (bnx2x_read_sfp_module_eeprom(params,
  2170. SFP_EEPROM_OPTIONS_ADDR,
  2171. SFP_EEPROM_OPTIONS_SIZE,
  2172. options) != 0) {
  2173. DP(NETIF_MSG_LINK, "Failed to read Option field from"
  2174. " module EEPROM\n");
  2175. return -EINVAL;
  2176. }
  2177. limiting_mode = !(options[0] &
  2178. SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
  2179. bnx2x_cl45_read(bp, port,
  2180. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  2181. ext_phy_addr,
  2182. MDIO_PMA_DEVAD,
  2183. MDIO_PMA_REG_ROM_VER2,
  2184. &cur_limiting_mode);
  2185. DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
  2186. cur_limiting_mode);
  2187. if (limiting_mode &&
  2188. (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
  2189. DP(NETIF_MSG_LINK,
  2190. "Module options = 0x%x.Setting LIMITING MODE\n",
  2191. options[0]);
  2192. bnx2x_cl45_write(bp, port,
  2193. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  2194. ext_phy_addr,
  2195. MDIO_PMA_DEVAD,
  2196. MDIO_PMA_REG_ROM_VER2,
  2197. SFP_LIMITING_MODE_VALUE);
  2198. } else { /* LRM mode ( default )*/
  2199. DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
  2200. options[0]);
  2201. /* Changing to LRM mode takes quite few seconds.
  2202. So do it only if current mode is limiting
  2203. ( default is LRM )*/
  2204. if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
  2205. return 0;
  2206. bnx2x_cl45_write(bp, port,
  2207. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  2208. ext_phy_addr,
  2209. MDIO_PMA_DEVAD,
  2210. MDIO_PMA_REG_LRM_MODE,
  2211. 0);
  2212. bnx2x_cl45_write(bp, port,
  2213. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  2214. ext_phy_addr,
  2215. MDIO_PMA_DEVAD,
  2216. MDIO_PMA_REG_ROM_VER2,
  2217. 0x128);
  2218. bnx2x_cl45_write(bp, port,
  2219. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  2220. ext_phy_addr,
  2221. MDIO_PMA_DEVAD,
  2222. MDIO_PMA_REG_MISC_CTRL0,
  2223. 0x4008);
  2224. bnx2x_cl45_write(bp, port,
  2225. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  2226. ext_phy_addr,
  2227. MDIO_PMA_DEVAD,
  2228. MDIO_PMA_REG_LRM_MODE,
  2229. 0xaaaa);
  2230. }
  2231. return 0;
  2232. }
  2233. static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
  2234. {
  2235. u8 val;
  2236. struct bnx2x *bp = params->bp;
  2237. u16 timeout;
  2238. /* Initialization time after hot-plug may take up to 300ms for some
  2239. phys type ( e.g. JDSU ) */
  2240. for (timeout = 0; timeout < 60; timeout++) {
  2241. if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
  2242. == 0) {
  2243. DP(NETIF_MSG_LINK, "SFP+ module initialization "
  2244. "took %d ms\n", timeout * 5);
  2245. return 0;
  2246. }
  2247. msleep(5);
  2248. }
  2249. return -EINVAL;
  2250. }
  2251. static u8 bnx2x_sfp_module_detection(struct link_params *params)
  2252. {
  2253. struct bnx2x *bp = params->bp;
  2254. u8 module_type;
  2255. u8 ext_phy_addr = ((params->ext_phy_config &
  2256. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2257. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2258. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  2259. if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
  2260. DP(NETIF_MSG_LINK, "Module detection is not required "
  2261. "for this phy\n");
  2262. return 0;
  2263. }
  2264. DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
  2265. params->port);
  2266. if (bnx2x_get_sfp_module_type(params,
  2267. &module_type) != 0) {
  2268. DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
  2269. if (!(params->feature_config_flags &
  2270. FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
  2271. /* In case module detection is disabled, it trys to
  2272. link up. The issue that can happen here is LRM /
  2273. LIMITING mode which set according to the module-type*/
  2274. DP(NETIF_MSG_LINK, "Unable to read module-type."
  2275. "Probably due to Bit Stretching."
  2276. " Proceeding...\n");
  2277. } else {
  2278. return -EINVAL;
  2279. }
  2280. } else if (bnx2x_verify_sfp_module(params, module_type) !=
  2281. 0) {
  2282. /* check SFP+ module compatibility */
  2283. DP(NETIF_MSG_LINK, "Module verification failed!!\n");
  2284. /* Turn on fault module-detected led */
  2285. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
  2286. MISC_REGISTERS_GPIO_HIGH,
  2287. params->port);
  2288. return -EINVAL;
  2289. }
  2290. /* Turn off fault module-detected led */
  2291. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
  2292. MISC_REGISTERS_GPIO_LOW,
  2293. params->port);
  2294. /* Check and set limiting mode / LRM mode */
  2295. bnx2x_bcm8726_set_limiting_mode(params, module_type);
  2296. /* Enable transmit for this module */
  2297. bnx2x_bcm8726_set_transmitter(bp, params->port,
  2298. ext_phy_addr, 1);
  2299. return 0;
  2300. }
  2301. void bnx2x_handle_module_detect_int(struct link_params *params)
  2302. {
  2303. struct bnx2x *bp = params->bp;
  2304. u32 gpio_val;
  2305. u8 port = params->port;
  2306. /* Set valid module led off */
  2307. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
  2308. MISC_REGISTERS_GPIO_HIGH,
  2309. params->port);
  2310. /* Get current gpio val refelecting module plugged in / out*/
  2311. gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
  2312. /* Call the handling function in case module is detected */
  2313. if (gpio_val == 0) {
  2314. bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
  2315. MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
  2316. port);
  2317. if (bnx2x_wait_for_sfp_module_initialized(params)
  2318. == 0)
  2319. bnx2x_sfp_module_detection(params);
  2320. else
  2321. DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
  2322. } else {
  2323. u8 ext_phy_addr = ((params->ext_phy_config &
  2324. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2325. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2326. bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
  2327. MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
  2328. port);
  2329. /* Module was plugged out. */
  2330. /* Disable transmit for this module */
  2331. bnx2x_bcm8726_set_transmitter(bp, params->port,
  2332. ext_phy_addr, 0);
  2333. }
  2334. }
  2335. static void bnx2x_bcm807x_force_10G(struct link_params *params)
  2336. {
  2337. struct bnx2x *bp = params->bp;
  2338. u8 port = params->port;
  2339. u8 ext_phy_addr = ((params->ext_phy_config &
  2340. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2341. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2342. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  2343. /* Force KR or KX */
  2344. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2345. MDIO_PMA_DEVAD,
  2346. MDIO_PMA_REG_CTRL,
  2347. 0x2040);
  2348. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2349. MDIO_PMA_DEVAD,
  2350. MDIO_PMA_REG_10G_CTRL2,
  2351. 0x000b);
  2352. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2353. MDIO_PMA_DEVAD,
  2354. MDIO_PMA_REG_BCM_CTRL,
  2355. 0x0000);
  2356. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2357. MDIO_AN_DEVAD,
  2358. MDIO_AN_REG_CTRL,
  2359. 0x0000);
  2360. }
  2361. static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
  2362. {
  2363. struct bnx2x *bp = params->bp;
  2364. u8 port = params->port;
  2365. u16 val;
  2366. u8 ext_phy_addr = ((params->ext_phy_config &
  2367. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2368. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2369. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  2370. bnx2x_cl45_read(bp, params->port,
  2371. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  2372. ext_phy_addr,
  2373. MDIO_PMA_DEVAD,
  2374. MDIO_PMA_REG_8073_CHIP_REV, &val);
  2375. if (val == 0) {
  2376. /* Mustn't set low power mode in 8073 A0 */
  2377. return;
  2378. }
  2379. /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
  2380. bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
  2381. MDIO_XS_DEVAD,
  2382. MDIO_XS_PLL_SEQUENCER, &val);
  2383. val &= ~(1<<13);
  2384. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2385. MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
  2386. /* PLL controls */
  2387. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2388. MDIO_XS_DEVAD, 0x805E, 0x1077);
  2389. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2390. MDIO_XS_DEVAD, 0x805D, 0x0000);
  2391. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2392. MDIO_XS_DEVAD, 0x805C, 0x030B);
  2393. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2394. MDIO_XS_DEVAD, 0x805B, 0x1240);
  2395. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2396. MDIO_XS_DEVAD, 0x805A, 0x2490);
  2397. /* Tx Controls */
  2398. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2399. MDIO_XS_DEVAD, 0x80A7, 0x0C74);
  2400. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2401. MDIO_XS_DEVAD, 0x80A6, 0x9041);
  2402. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2403. MDIO_XS_DEVAD, 0x80A5, 0x4640);
  2404. /* Rx Controls */
  2405. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2406. MDIO_XS_DEVAD, 0x80FE, 0x01C4);
  2407. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2408. MDIO_XS_DEVAD, 0x80FD, 0x9249);
  2409. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2410. MDIO_XS_DEVAD, 0x80FC, 0x2015);
  2411. /* Enable PLL sequencer (use read-modify-write to set bit 13) */
  2412. bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
  2413. MDIO_XS_DEVAD,
  2414. MDIO_XS_PLL_SEQUENCER, &val);
  2415. val |= (1<<13);
  2416. bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
  2417. MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
  2418. }
  2419. static void bnx2x_8073_set_pause_cl37(struct link_params *params,
  2420. struct link_vars *vars)
  2421. {
  2422. struct bnx2x *bp = params->bp;
  2423. u16 cl37_val;
  2424. u8 ext_phy_addr = ((params->ext_phy_config &
  2425. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2426. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2427. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  2428. bnx2x_cl45_read(bp, params->port,
  2429. ext_phy_type,
  2430. ext_phy_addr,
  2431. MDIO_AN_DEVAD,
  2432. MDIO_AN_REG_CL37_FC_LD, &cl37_val);
  2433. cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  2434. /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
  2435. if ((vars->ieee_fc &
  2436. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
  2437. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
  2438. cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
  2439. }
  2440. if ((vars->ieee_fc &
  2441. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
  2442. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
  2443. cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
  2444. }
  2445. if ((vars->ieee_fc &
  2446. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
  2447. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
  2448. cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  2449. }
  2450. DP(NETIF_MSG_LINK,
  2451. "Ext phy AN advertize cl37 0x%x\n", cl37_val);
  2452. bnx2x_cl45_write(bp, params->port,
  2453. ext_phy_type,
  2454. ext_phy_addr,
  2455. MDIO_AN_DEVAD,
  2456. MDIO_AN_REG_CL37_FC_LD, cl37_val);
  2457. msleep(500);
  2458. }
  2459. static void bnx2x_ext_phy_set_pause(struct link_params *params,
  2460. struct link_vars *vars)
  2461. {
  2462. struct bnx2x *bp = params->bp;
  2463. u16 val;
  2464. u8 ext_phy_addr = ((params->ext_phy_config &
  2465. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2466. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2467. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  2468. /* read modify write pause advertizing */
  2469. bnx2x_cl45_read(bp, params->port,
  2470. ext_phy_type,
  2471. ext_phy_addr,
  2472. MDIO_AN_DEVAD,
  2473. MDIO_AN_REG_ADV_PAUSE, &val);
  2474. val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
  2475. /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
  2476. if ((vars->ieee_fc &
  2477. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
  2478. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
  2479. val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
  2480. }
  2481. if ((vars->ieee_fc &
  2482. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
  2483. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
  2484. val |=
  2485. MDIO_AN_REG_ADV_PAUSE_PAUSE;
  2486. }
  2487. DP(NETIF_MSG_LINK,
  2488. "Ext phy AN advertize 0x%x\n", val);
  2489. bnx2x_cl45_write(bp, params->port,
  2490. ext_phy_type,
  2491. ext_phy_addr,
  2492. MDIO_AN_DEVAD,
  2493. MDIO_AN_REG_ADV_PAUSE, val);
  2494. }
  2495. static void bnx2x_set_preemphasis(struct link_params *params)
  2496. {
  2497. u16 bank, i = 0;
  2498. struct bnx2x *bp = params->bp;
  2499. for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
  2500. bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
  2501. CL45_WR_OVER_CL22(bp, params->port,
  2502. params->phy_addr,
  2503. bank,
  2504. MDIO_RX0_RX_EQ_BOOST,
  2505. params->xgxs_config_rx[i]);
  2506. }
  2507. for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
  2508. bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
  2509. CL45_WR_OVER_CL22(bp, params->port,
  2510. params->phy_addr,
  2511. bank,
  2512. MDIO_TX0_TX_DRIVER,
  2513. params->xgxs_config_tx[i]);
  2514. }
  2515. }
  2516. static void bnx2x_init_internal_phy(struct link_params *params,
  2517. struct link_vars *vars)
  2518. {
  2519. struct bnx2x *bp = params->bp;
  2520. if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
  2521. if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
  2522. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
  2523. (params->feature_config_flags &
  2524. FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
  2525. bnx2x_set_preemphasis(params);
  2526. /* forced speed requested? */
  2527. if (vars->line_speed != SPEED_AUTO_NEG) {
  2528. DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
  2529. /* disable autoneg */
  2530. bnx2x_set_autoneg(params, vars);
  2531. /* program speed and duplex */
  2532. bnx2x_program_serdes(params, vars);
  2533. } else { /* AN_mode */
  2534. DP(NETIF_MSG_LINK, "not SGMII, AN\n");
  2535. /* AN enabled */
  2536. bnx2x_set_brcm_cl37_advertisment(params);
  2537. /* program duplex & pause advertisement (for aneg) */
  2538. bnx2x_set_ieee_aneg_advertisment(params,
  2539. vars->ieee_fc);
  2540. /* enable autoneg */
  2541. bnx2x_set_autoneg(params, vars);
  2542. /* enable and restart AN */
  2543. bnx2x_restart_autoneg(params);
  2544. }
  2545. } else { /* SGMII mode */
  2546. DP(NETIF_MSG_LINK, "SGMII\n");
  2547. bnx2x_initialize_sgmii_process(params, vars);
  2548. }
  2549. }
  2550. static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
  2551. {
  2552. struct bnx2x *bp = params->bp;
  2553. u32 ext_phy_type;
  2554. u8 ext_phy_addr;
  2555. u16 cnt;
  2556. u16 ctrl = 0;
  2557. u16 val = 0;
  2558. u8 rc = 0;
  2559. if (vars->phy_flags & PHY_XGXS_FLAG) {
  2560. ext_phy_addr = ((params->ext_phy_config &
  2561. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  2562. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  2563. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  2564. /* Make sure that the soft reset is off (expect for the 8072:
  2565. * due to the lock, it will be done inside the specific
  2566. * handling)
  2567. */
  2568. if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
  2569. (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
  2570. (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
  2571. (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
  2572. (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
  2573. /* Wait for soft reset to get cleared upto 1 sec */
  2574. for (cnt = 0; cnt < 1000; cnt++) {
  2575. bnx2x_cl45_read(bp, params->port,
  2576. ext_phy_type,
  2577. ext_phy_addr,
  2578. MDIO_PMA_DEVAD,
  2579. MDIO_PMA_REG_CTRL, &ctrl);
  2580. if (!(ctrl & (1<<15)))
  2581. break;
  2582. msleep(1);
  2583. }
  2584. DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
  2585. ctrl, cnt);
  2586. }
  2587. switch (ext_phy_type) {
  2588. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  2589. break;
  2590. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
  2591. DP(NETIF_MSG_LINK, "XGXS 8705\n");
  2592. bnx2x_cl45_write(bp, params->port,
  2593. ext_phy_type,
  2594. ext_phy_addr,
  2595. MDIO_PMA_DEVAD,
  2596. MDIO_PMA_REG_MISC_CTRL,
  2597. 0x8288);
  2598. bnx2x_cl45_write(bp, params->port,
  2599. ext_phy_type,
  2600. ext_phy_addr,
  2601. MDIO_PMA_DEVAD,
  2602. MDIO_PMA_REG_PHY_IDENTIFIER,
  2603. 0x7fbf);
  2604. bnx2x_cl45_write(bp, params->port,
  2605. ext_phy_type,
  2606. ext_phy_addr,
  2607. MDIO_PMA_DEVAD,
  2608. MDIO_PMA_REG_CMU_PLL_BYPASS,
  2609. 0x0100);
  2610. bnx2x_cl45_write(bp, params->port,
  2611. ext_phy_type,
  2612. ext_phy_addr,
  2613. MDIO_WIS_DEVAD,
  2614. MDIO_WIS_REG_LASI_CNTL, 0x1);
  2615. /* BCM8705 doesn't have microcode, hence the 0 */
  2616. bnx2x_save_spirom_version(bp, params->port,
  2617. params->shmem_base, 0);
  2618. break;
  2619. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
  2620. /* Wait until fw is loaded */
  2621. for (cnt = 0; cnt < 100; cnt++) {
  2622. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  2623. ext_phy_addr, MDIO_PMA_DEVAD,
  2624. MDIO_PMA_REG_ROM_VER1, &val);
  2625. if (val)
  2626. break;
  2627. msleep(10);
  2628. }
  2629. DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
  2630. "after %d ms\n", cnt);
  2631. if ((params->feature_config_flags &
  2632. FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
  2633. u8 i;
  2634. u16 reg;
  2635. for (i = 0; i < 4; i++) {
  2636. reg = MDIO_XS_8706_REG_BANK_RX0 +
  2637. i*(MDIO_XS_8706_REG_BANK_RX1 -
  2638. MDIO_XS_8706_REG_BANK_RX0);
  2639. bnx2x_cl45_read(bp, params->port,
  2640. ext_phy_type,
  2641. ext_phy_addr,
  2642. MDIO_XS_DEVAD,
  2643. reg, &val);
  2644. /* Clear first 3 bits of the control */
  2645. val &= ~0x7;
  2646. /* Set control bits according to
  2647. configuation */
  2648. val |= (params->xgxs_config_rx[i] &
  2649. 0x7);
  2650. DP(NETIF_MSG_LINK, "Setting RX"
  2651. "Equalizer to BCM8706 reg 0x%x"
  2652. " <-- val 0x%x\n", reg, val);
  2653. bnx2x_cl45_write(bp, params->port,
  2654. ext_phy_type,
  2655. ext_phy_addr,
  2656. MDIO_XS_DEVAD,
  2657. reg, val);
  2658. }
  2659. }
  2660. /* Force speed */
  2661. /* First enable LASI */
  2662. bnx2x_cl45_write(bp, params->port,
  2663. ext_phy_type,
  2664. ext_phy_addr,
  2665. MDIO_PMA_DEVAD,
  2666. MDIO_PMA_REG_RX_ALARM_CTRL,
  2667. 0x0400);
  2668. bnx2x_cl45_write(bp, params->port,
  2669. ext_phy_type,
  2670. ext_phy_addr,
  2671. MDIO_PMA_DEVAD,
  2672. MDIO_PMA_REG_LASI_CTRL, 0x0004);
  2673. if (params->req_line_speed == SPEED_10000) {
  2674. DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
  2675. bnx2x_cl45_write(bp, params->port,
  2676. ext_phy_type,
  2677. ext_phy_addr,
  2678. MDIO_PMA_DEVAD,
  2679. MDIO_PMA_REG_DIGITAL_CTRL,
  2680. 0x400);
  2681. } else {
  2682. /* Force 1Gbps using autoneg with 1G
  2683. advertisment */
  2684. /* Allow CL37 through CL73 */
  2685. DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
  2686. bnx2x_cl45_write(bp, params->port,
  2687. ext_phy_type,
  2688. ext_phy_addr,
  2689. MDIO_AN_DEVAD,
  2690. MDIO_AN_REG_CL37_CL73,
  2691. 0x040c);
  2692. /* Enable Full-Duplex advertisment on CL37 */
  2693. bnx2x_cl45_write(bp, params->port,
  2694. ext_phy_type,
  2695. ext_phy_addr,
  2696. MDIO_AN_DEVAD,
  2697. MDIO_AN_REG_CL37_FC_LP,
  2698. 0x0020);
  2699. /* Enable CL37 AN */
  2700. bnx2x_cl45_write(bp, params->port,
  2701. ext_phy_type,
  2702. ext_phy_addr,
  2703. MDIO_AN_DEVAD,
  2704. MDIO_AN_REG_CL37_AN,
  2705. 0x1000);
  2706. /* 1G support */
  2707. bnx2x_cl45_write(bp, params->port,
  2708. ext_phy_type,
  2709. ext_phy_addr,
  2710. MDIO_AN_DEVAD,
  2711. MDIO_AN_REG_ADV, (1<<5));
  2712. /* Enable clause 73 AN */
  2713. bnx2x_cl45_write(bp, params->port,
  2714. ext_phy_type,
  2715. ext_phy_addr,
  2716. MDIO_AN_DEVAD,
  2717. MDIO_AN_REG_CTRL,
  2718. 0x1200);
  2719. }
  2720. bnx2x_save_bcm_spirom_ver(bp, params->port,
  2721. ext_phy_type,
  2722. ext_phy_addr,
  2723. params->shmem_base);
  2724. break;
  2725. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  2726. DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
  2727. bnx2x_bcm8726_external_rom_boot(params);
  2728. /* Need to call module detected on initialization since
  2729. the module detection triggered by actual module
  2730. insertion might occur before driver is loaded, and when
  2731. driver is loaded, it reset all registers, including the
  2732. transmitter */
  2733. bnx2x_sfp_module_detection(params);
  2734. if (params->req_line_speed == SPEED_1000) {
  2735. DP(NETIF_MSG_LINK, "Setting 1G force\n");
  2736. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2737. ext_phy_addr, MDIO_PMA_DEVAD,
  2738. MDIO_PMA_REG_CTRL, 0x40);
  2739. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2740. ext_phy_addr, MDIO_PMA_DEVAD,
  2741. MDIO_PMA_REG_10G_CTRL2, 0xD);
  2742. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2743. ext_phy_addr, MDIO_PMA_DEVAD,
  2744. MDIO_PMA_REG_LASI_CTRL, 0x5);
  2745. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2746. ext_phy_addr, MDIO_PMA_DEVAD,
  2747. MDIO_PMA_REG_RX_ALARM_CTRL,
  2748. 0x400);
  2749. } else if ((params->req_line_speed ==
  2750. SPEED_AUTO_NEG) &&
  2751. ((params->speed_cap_mask &
  2752. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
  2753. DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
  2754. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2755. ext_phy_addr, MDIO_AN_DEVAD,
  2756. MDIO_AN_REG_ADV, 0x20);
  2757. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2758. ext_phy_addr, MDIO_AN_DEVAD,
  2759. MDIO_AN_REG_CL37_CL73, 0x040c);
  2760. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2761. ext_phy_addr, MDIO_AN_DEVAD,
  2762. MDIO_AN_REG_CL37_FC_LD, 0x0020);
  2763. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2764. ext_phy_addr, MDIO_AN_DEVAD,
  2765. MDIO_AN_REG_CL37_AN, 0x1000);
  2766. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2767. ext_phy_addr, MDIO_AN_DEVAD,
  2768. MDIO_AN_REG_CTRL, 0x1200);
  2769. /* Enable RX-ALARM control to receive
  2770. interrupt for 1G speed change */
  2771. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2772. ext_phy_addr, MDIO_PMA_DEVAD,
  2773. MDIO_PMA_REG_LASI_CTRL, 0x4);
  2774. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2775. ext_phy_addr, MDIO_PMA_DEVAD,
  2776. MDIO_PMA_REG_RX_ALARM_CTRL,
  2777. 0x400);
  2778. } else { /* Default 10G. Set only LASI control */
  2779. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  2780. ext_phy_addr, MDIO_PMA_DEVAD,
  2781. MDIO_PMA_REG_LASI_CTRL, 1);
  2782. }
  2783. /* Set TX PreEmphasis if needed */
  2784. if ((params->feature_config_flags &
  2785. FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
  2786. DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
  2787. "TX_CTRL2 0x%x\n",
  2788. params->xgxs_config_tx[0],
  2789. params->xgxs_config_tx[1]);
  2790. bnx2x_cl45_write(bp, params->port,
  2791. ext_phy_type,
  2792. ext_phy_addr,
  2793. MDIO_PMA_DEVAD,
  2794. MDIO_PMA_REG_8726_TX_CTRL1,
  2795. params->xgxs_config_tx[0]);
  2796. bnx2x_cl45_write(bp, params->port,
  2797. ext_phy_type,
  2798. ext_phy_addr,
  2799. MDIO_PMA_DEVAD,
  2800. MDIO_PMA_REG_8726_TX_CTRL2,
  2801. params->xgxs_config_tx[1]);
  2802. }
  2803. break;
  2804. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  2805. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  2806. {
  2807. u16 tmp1;
  2808. u16 rx_alarm_ctrl_val;
  2809. u16 lasi_ctrl_val;
  2810. if (ext_phy_type ==
  2811. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
  2812. rx_alarm_ctrl_val = 0x400;
  2813. lasi_ctrl_val = 0x0004;
  2814. } else {
  2815. rx_alarm_ctrl_val = (1<<2);
  2816. lasi_ctrl_val = 0x0004;
  2817. }
  2818. /* enable LASI */
  2819. bnx2x_cl45_write(bp, params->port,
  2820. ext_phy_type,
  2821. ext_phy_addr,
  2822. MDIO_PMA_DEVAD,
  2823. MDIO_PMA_REG_RX_ALARM_CTRL,
  2824. rx_alarm_ctrl_val);
  2825. bnx2x_cl45_write(bp, params->port,
  2826. ext_phy_type,
  2827. ext_phy_addr,
  2828. MDIO_PMA_DEVAD,
  2829. MDIO_PMA_REG_LASI_CTRL,
  2830. lasi_ctrl_val);
  2831. bnx2x_8073_set_pause_cl37(params, vars);
  2832. if (ext_phy_type ==
  2833. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
  2834. bnx2x_bcm8072_external_rom_boot(params);
  2835. } else {
  2836. /* In case of 8073 with long xaui lines,
  2837. don't set the 8073 xaui low power*/
  2838. bnx2x_bcm8073_set_xaui_low_power_mode(params);
  2839. }
  2840. bnx2x_cl45_read(bp, params->port,
  2841. ext_phy_type,
  2842. ext_phy_addr,
  2843. MDIO_PMA_DEVAD,
  2844. MDIO_PMA_REG_M8051_MSGOUT_REG,
  2845. &tmp1);
  2846. bnx2x_cl45_read(bp, params->port,
  2847. ext_phy_type,
  2848. ext_phy_addr,
  2849. MDIO_PMA_DEVAD,
  2850. MDIO_PMA_REG_RX_ALARM, &tmp1);
  2851. DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
  2852. "0x%x\n", tmp1);
  2853. /* If this is forced speed, set to KR or KX
  2854. * (all other are not supported)
  2855. */
  2856. if (params->loopback_mode == LOOPBACK_EXT) {
  2857. bnx2x_bcm807x_force_10G(params);
  2858. DP(NETIF_MSG_LINK,
  2859. "Forced speed 10G on 807X\n");
  2860. break;
  2861. } else {
  2862. bnx2x_cl45_write(bp, params->port,
  2863. ext_phy_type, ext_phy_addr,
  2864. MDIO_PMA_DEVAD,
  2865. MDIO_PMA_REG_BCM_CTRL,
  2866. 0x0002);
  2867. }
  2868. if (params->req_line_speed != SPEED_AUTO_NEG) {
  2869. if (params->req_line_speed == SPEED_10000) {
  2870. val = (1<<7);
  2871. } else if (params->req_line_speed ==
  2872. SPEED_2500) {
  2873. val = (1<<5);
  2874. /* Note that 2.5G works only
  2875. when used with 1G advertisment */
  2876. } else
  2877. val = (1<<5);
  2878. } else {
  2879. val = 0;
  2880. if (params->speed_cap_mask &
  2881. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
  2882. val |= (1<<7);
  2883. /* Note that 2.5G works only when
  2884. used with 1G advertisment */
  2885. if (params->speed_cap_mask &
  2886. (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
  2887. PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
  2888. val |= (1<<5);
  2889. DP(NETIF_MSG_LINK,
  2890. "807x autoneg val = 0x%x\n", val);
  2891. }
  2892. bnx2x_cl45_write(bp, params->port,
  2893. ext_phy_type,
  2894. ext_phy_addr,
  2895. MDIO_AN_DEVAD,
  2896. MDIO_AN_REG_ADV, val);
  2897. if (ext_phy_type ==
  2898. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
  2899. bnx2x_cl45_read(bp, params->port,
  2900. ext_phy_type,
  2901. ext_phy_addr,
  2902. MDIO_AN_DEVAD,
  2903. MDIO_AN_REG_8073_2_5G, &tmp1);
  2904. if (((params->speed_cap_mask &
  2905. PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
  2906. (params->req_line_speed ==
  2907. SPEED_AUTO_NEG)) ||
  2908. (params->req_line_speed ==
  2909. SPEED_2500)) {
  2910. u16 phy_ver;
  2911. /* Allow 2.5G for A1 and above */
  2912. bnx2x_cl45_read(bp, params->port,
  2913. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  2914. ext_phy_addr,
  2915. MDIO_PMA_DEVAD,
  2916. MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
  2917. DP(NETIF_MSG_LINK, "Add 2.5G\n");
  2918. if (phy_ver > 0)
  2919. tmp1 |= 1;
  2920. else
  2921. tmp1 &= 0xfffe;
  2922. } else {
  2923. DP(NETIF_MSG_LINK, "Disable 2.5G\n");
  2924. tmp1 &= 0xfffe;
  2925. }
  2926. bnx2x_cl45_write(bp, params->port,
  2927. ext_phy_type,
  2928. ext_phy_addr,
  2929. MDIO_AN_DEVAD,
  2930. MDIO_AN_REG_8073_2_5G, tmp1);
  2931. }
  2932. /* Add support for CL37 (passive mode) II */
  2933. bnx2x_cl45_read(bp, params->port,
  2934. ext_phy_type,
  2935. ext_phy_addr,
  2936. MDIO_AN_DEVAD,
  2937. MDIO_AN_REG_CL37_FC_LD,
  2938. &tmp1);
  2939. bnx2x_cl45_write(bp, params->port,
  2940. ext_phy_type,
  2941. ext_phy_addr,
  2942. MDIO_AN_DEVAD,
  2943. MDIO_AN_REG_CL37_FC_LD, (tmp1 |
  2944. ((params->req_duplex == DUPLEX_FULL) ?
  2945. 0x20 : 0x40)));
  2946. /* Add support for CL37 (passive mode) III */
  2947. bnx2x_cl45_write(bp, params->port,
  2948. ext_phy_type,
  2949. ext_phy_addr,
  2950. MDIO_AN_DEVAD,
  2951. MDIO_AN_REG_CL37_AN, 0x1000);
  2952. if (ext_phy_type ==
  2953. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
  2954. /* The SNR will improve about 2db by changing
  2955. BW and FEE main tap. Rest commands are executed
  2956. after link is up*/
  2957. /*Change FFE main cursor to 5 in EDC register*/
  2958. if (bnx2x_8073_is_snr_needed(params))
  2959. bnx2x_cl45_write(bp, params->port,
  2960. ext_phy_type,
  2961. ext_phy_addr,
  2962. MDIO_PMA_DEVAD,
  2963. MDIO_PMA_REG_EDC_FFE_MAIN,
  2964. 0xFB0C);
  2965. /* Enable FEC (Forware Error Correction)
  2966. Request in the AN */
  2967. bnx2x_cl45_read(bp, params->port,
  2968. ext_phy_type,
  2969. ext_phy_addr,
  2970. MDIO_AN_DEVAD,
  2971. MDIO_AN_REG_ADV2, &tmp1);
  2972. tmp1 |= (1<<15);
  2973. bnx2x_cl45_write(bp, params->port,
  2974. ext_phy_type,
  2975. ext_phy_addr,
  2976. MDIO_AN_DEVAD,
  2977. MDIO_AN_REG_ADV2, tmp1);
  2978. }
  2979. bnx2x_ext_phy_set_pause(params, vars);
  2980. /* Restart autoneg */
  2981. msleep(500);
  2982. bnx2x_cl45_write(bp, params->port,
  2983. ext_phy_type,
  2984. ext_phy_addr,
  2985. MDIO_AN_DEVAD,
  2986. MDIO_AN_REG_CTRL, 0x1200);
  2987. DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
  2988. "Advertise 1G=%x, 10G=%x\n",
  2989. ((val & (1<<5)) > 0),
  2990. ((val & (1<<7)) > 0));
  2991. break;
  2992. }
  2993. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
  2994. {
  2995. u16 fw_ver1, fw_ver2;
  2996. DP(NETIF_MSG_LINK,
  2997. "Setting the SFX7101 LASI indication\n");
  2998. bnx2x_cl45_write(bp, params->port,
  2999. ext_phy_type,
  3000. ext_phy_addr,
  3001. MDIO_PMA_DEVAD,
  3002. MDIO_PMA_REG_LASI_CTRL, 0x1);
  3003. DP(NETIF_MSG_LINK,
  3004. "Setting the SFX7101 LED to blink on traffic\n");
  3005. bnx2x_cl45_write(bp, params->port,
  3006. ext_phy_type,
  3007. ext_phy_addr,
  3008. MDIO_PMA_DEVAD,
  3009. MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
  3010. bnx2x_ext_phy_set_pause(params, vars);
  3011. /* Restart autoneg */
  3012. bnx2x_cl45_read(bp, params->port,
  3013. ext_phy_type,
  3014. ext_phy_addr,
  3015. MDIO_AN_DEVAD,
  3016. MDIO_AN_REG_CTRL, &val);
  3017. val |= 0x200;
  3018. bnx2x_cl45_write(bp, params->port,
  3019. ext_phy_type,
  3020. ext_phy_addr,
  3021. MDIO_AN_DEVAD,
  3022. MDIO_AN_REG_CTRL, val);
  3023. /* Save spirom version */
  3024. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3025. ext_phy_addr, MDIO_PMA_DEVAD,
  3026. MDIO_PMA_REG_7101_VER1, &fw_ver1);
  3027. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3028. ext_phy_addr, MDIO_PMA_DEVAD,
  3029. MDIO_PMA_REG_7101_VER2, &fw_ver2);
  3030. bnx2x_save_spirom_version(params->bp, params->port,
  3031. params->shmem_base,
  3032. (u32)(fw_ver1<<16 | fw_ver2));
  3033. break;
  3034. }
  3035. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
  3036. DP(NETIF_MSG_LINK,
  3037. "Setting the BCM8481 LASI control\n");
  3038. bnx2x_cl45_write(bp, params->port,
  3039. ext_phy_type,
  3040. ext_phy_addr,
  3041. MDIO_PMA_DEVAD,
  3042. MDIO_PMA_REG_LASI_CTRL, 0x1);
  3043. /* Restart autoneg */
  3044. bnx2x_cl45_read(bp, params->port,
  3045. ext_phy_type,
  3046. ext_phy_addr,
  3047. MDIO_AN_DEVAD,
  3048. MDIO_AN_REG_CTRL, &val);
  3049. val |= 0x200;
  3050. bnx2x_cl45_write(bp, params->port,
  3051. ext_phy_type,
  3052. ext_phy_addr,
  3053. MDIO_AN_DEVAD,
  3054. MDIO_AN_REG_CTRL, val);
  3055. bnx2x_save_bcm_spirom_ver(bp, params->port,
  3056. ext_phy_type,
  3057. ext_phy_addr,
  3058. params->shmem_base);
  3059. break;
  3060. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
  3061. DP(NETIF_MSG_LINK,
  3062. "XGXS PHY Failure detected 0x%x\n",
  3063. params->ext_phy_config);
  3064. rc = -EINVAL;
  3065. break;
  3066. default:
  3067. DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
  3068. params->ext_phy_config);
  3069. rc = -EINVAL;
  3070. break;
  3071. }
  3072. } else { /* SerDes */
  3073. ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
  3074. switch (ext_phy_type) {
  3075. case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
  3076. DP(NETIF_MSG_LINK, "SerDes Direct\n");
  3077. break;
  3078. case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
  3079. DP(NETIF_MSG_LINK, "SerDes 5482\n");
  3080. break;
  3081. default:
  3082. DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
  3083. params->ext_phy_config);
  3084. break;
  3085. }
  3086. }
  3087. return rc;
  3088. }
  3089. static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
  3090. struct link_vars *vars)
  3091. {
  3092. struct bnx2x *bp = params->bp;
  3093. u32 ext_phy_type;
  3094. u8 ext_phy_addr;
  3095. u16 val1 = 0, val2;
  3096. u16 rx_sd, pcs_status;
  3097. u8 ext_phy_link_up = 0;
  3098. u8 port = params->port;
  3099. if (vars->phy_flags & PHY_XGXS_FLAG) {
  3100. ext_phy_addr = ((params->ext_phy_config &
  3101. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  3102. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  3103. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  3104. switch (ext_phy_type) {
  3105. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  3106. DP(NETIF_MSG_LINK, "XGXS Direct\n");
  3107. ext_phy_link_up = 1;
  3108. break;
  3109. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
  3110. DP(NETIF_MSG_LINK, "XGXS 8705\n");
  3111. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3112. ext_phy_addr,
  3113. MDIO_WIS_DEVAD,
  3114. MDIO_WIS_REG_LASI_STATUS, &val1);
  3115. DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
  3116. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3117. ext_phy_addr,
  3118. MDIO_WIS_DEVAD,
  3119. MDIO_WIS_REG_LASI_STATUS, &val1);
  3120. DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
  3121. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3122. ext_phy_addr,
  3123. MDIO_PMA_DEVAD,
  3124. MDIO_PMA_REG_RX_SD, &rx_sd);
  3125. DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
  3126. ext_phy_link_up = (rx_sd & 0x1);
  3127. if (ext_phy_link_up)
  3128. vars->line_speed = SPEED_10000;
  3129. break;
  3130. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
  3131. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  3132. DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
  3133. /* Clear RX Alarm*/
  3134. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3135. ext_phy_addr,
  3136. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
  3137. &val2);
  3138. /* clear LASI indication*/
  3139. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3140. ext_phy_addr,
  3141. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
  3142. &val1);
  3143. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3144. ext_phy_addr,
  3145. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
  3146. &val2);
  3147. DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
  3148. "0x%x\n", val1, val2);
  3149. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3150. ext_phy_addr,
  3151. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
  3152. &rx_sd);
  3153. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3154. ext_phy_addr,
  3155. MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
  3156. &pcs_status);
  3157. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3158. ext_phy_addr,
  3159. MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
  3160. &val2);
  3161. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3162. ext_phy_addr,
  3163. MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
  3164. &val2);
  3165. DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
  3166. " pcs_status 0x%x 1Gbps link_status 0x%x\n",
  3167. rx_sd, pcs_status, val2);
  3168. /* link is up if both bit 0 of pmd_rx_sd and
  3169. * bit 0 of pcs_status are set, or if the autoneg bit
  3170. 1 is set
  3171. */
  3172. ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
  3173. (val2 & (1<<1)));
  3174. if (ext_phy_link_up) {
  3175. if (ext_phy_type ==
  3176. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
  3177. /* If transmitter is disabled,
  3178. ignore false link up indication */
  3179. bnx2x_cl45_read(bp, params->port,
  3180. ext_phy_type,
  3181. ext_phy_addr,
  3182. MDIO_PMA_DEVAD,
  3183. MDIO_PMA_REG_PHY_IDENTIFIER,
  3184. &val1);
  3185. if (val1 & (1<<15)) {
  3186. DP(NETIF_MSG_LINK, "Tx is "
  3187. "disabled\n");
  3188. ext_phy_link_up = 0;
  3189. break;
  3190. }
  3191. }
  3192. if (val2 & (1<<1))
  3193. vars->line_speed = SPEED_1000;
  3194. else
  3195. vars->line_speed = SPEED_10000;
  3196. }
  3197. break;
  3198. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  3199. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  3200. {
  3201. u16 link_status = 0;
  3202. u16 an1000_status = 0;
  3203. if (ext_phy_type ==
  3204. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
  3205. bnx2x_cl45_read(bp, params->port,
  3206. ext_phy_type,
  3207. ext_phy_addr,
  3208. MDIO_PCS_DEVAD,
  3209. MDIO_PCS_REG_LASI_STATUS, &val1);
  3210. bnx2x_cl45_read(bp, params->port,
  3211. ext_phy_type,
  3212. ext_phy_addr,
  3213. MDIO_PCS_DEVAD,
  3214. MDIO_PCS_REG_LASI_STATUS, &val2);
  3215. DP(NETIF_MSG_LINK,
  3216. "870x LASI status 0x%x->0x%x\n",
  3217. val1, val2);
  3218. } else {
  3219. /* In 8073, port1 is directed through emac0 and
  3220. * port0 is directed through emac1
  3221. */
  3222. bnx2x_cl45_read(bp, params->port,
  3223. ext_phy_type,
  3224. ext_phy_addr,
  3225. MDIO_PMA_DEVAD,
  3226. MDIO_PMA_REG_LASI_STATUS, &val1);
  3227. DP(NETIF_MSG_LINK,
  3228. "8703 LASI status 0x%x\n",
  3229. val1);
  3230. }
  3231. /* clear the interrupt LASI status register */
  3232. bnx2x_cl45_read(bp, params->port,
  3233. ext_phy_type,
  3234. ext_phy_addr,
  3235. MDIO_PCS_DEVAD,
  3236. MDIO_PCS_REG_STATUS, &val2);
  3237. bnx2x_cl45_read(bp, params->port,
  3238. ext_phy_type,
  3239. ext_phy_addr,
  3240. MDIO_PCS_DEVAD,
  3241. MDIO_PCS_REG_STATUS, &val1);
  3242. DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
  3243. val2, val1);
  3244. /* Clear MSG-OUT */
  3245. bnx2x_cl45_read(bp, params->port,
  3246. ext_phy_type,
  3247. ext_phy_addr,
  3248. MDIO_PMA_DEVAD,
  3249. MDIO_PMA_REG_M8051_MSGOUT_REG,
  3250. &val1);
  3251. /* Check the LASI */
  3252. bnx2x_cl45_read(bp, params->port,
  3253. ext_phy_type,
  3254. ext_phy_addr,
  3255. MDIO_PMA_DEVAD,
  3256. MDIO_PMA_REG_RX_ALARM, &val2);
  3257. DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
  3258. /* Check the link status */
  3259. bnx2x_cl45_read(bp, params->port,
  3260. ext_phy_type,
  3261. ext_phy_addr,
  3262. MDIO_PCS_DEVAD,
  3263. MDIO_PCS_REG_STATUS, &val2);
  3264. DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
  3265. bnx2x_cl45_read(bp, params->port,
  3266. ext_phy_type,
  3267. ext_phy_addr,
  3268. MDIO_PMA_DEVAD,
  3269. MDIO_PMA_REG_STATUS, &val2);
  3270. bnx2x_cl45_read(bp, params->port,
  3271. ext_phy_type,
  3272. ext_phy_addr,
  3273. MDIO_PMA_DEVAD,
  3274. MDIO_PMA_REG_STATUS, &val1);
  3275. ext_phy_link_up = ((val1 & 4) == 4);
  3276. DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
  3277. if (ext_phy_type ==
  3278. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
  3279. if (ext_phy_link_up &&
  3280. ((params->req_line_speed !=
  3281. SPEED_10000))) {
  3282. if (bnx2x_bcm8073_xaui_wa(params)
  3283. != 0) {
  3284. ext_phy_link_up = 0;
  3285. break;
  3286. }
  3287. }
  3288. bnx2x_cl45_read(bp, params->port,
  3289. ext_phy_type,
  3290. ext_phy_addr,
  3291. MDIO_AN_DEVAD,
  3292. MDIO_AN_REG_LINK_STATUS,
  3293. &an1000_status);
  3294. bnx2x_cl45_read(bp, params->port,
  3295. ext_phy_type,
  3296. ext_phy_addr,
  3297. MDIO_AN_DEVAD,
  3298. MDIO_AN_REG_LINK_STATUS,
  3299. &an1000_status);
  3300. /* Check the link status on 1.1.2 */
  3301. bnx2x_cl45_read(bp, params->port,
  3302. ext_phy_type,
  3303. ext_phy_addr,
  3304. MDIO_PMA_DEVAD,
  3305. MDIO_PMA_REG_STATUS, &val2);
  3306. bnx2x_cl45_read(bp, params->port,
  3307. ext_phy_type,
  3308. ext_phy_addr,
  3309. MDIO_PMA_DEVAD,
  3310. MDIO_PMA_REG_STATUS, &val1);
  3311. DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
  3312. "an_link_status=0x%x\n",
  3313. val2, val1, an1000_status);
  3314. ext_phy_link_up = (((val1 & 4) == 4) ||
  3315. (an1000_status & (1<<1)));
  3316. if (ext_phy_link_up &&
  3317. bnx2x_8073_is_snr_needed(params)) {
  3318. /* The SNR will improve about 2dbby
  3319. changing the BW and FEE main tap.*/
  3320. /* The 1st write to change FFE main
  3321. tap is set before restart AN */
  3322. /* Change PLL Bandwidth in EDC
  3323. register */
  3324. bnx2x_cl45_write(bp, port, ext_phy_type,
  3325. ext_phy_addr,
  3326. MDIO_PMA_DEVAD,
  3327. MDIO_PMA_REG_PLL_BANDWIDTH,
  3328. 0x26BC);
  3329. /* Change CDR Bandwidth in EDC
  3330. register */
  3331. bnx2x_cl45_write(bp, port, ext_phy_type,
  3332. ext_phy_addr,
  3333. MDIO_PMA_DEVAD,
  3334. MDIO_PMA_REG_CDR_BANDWIDTH,
  3335. 0x0333);
  3336. }
  3337. bnx2x_cl45_read(bp, params->port,
  3338. ext_phy_type,
  3339. ext_phy_addr,
  3340. MDIO_PMA_DEVAD,
  3341. MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
  3342. &link_status);
  3343. /* Bits 0..2 --> speed detected,
  3344. bits 13..15--> link is down */
  3345. if ((link_status & (1<<2)) &&
  3346. (!(link_status & (1<<15)))) {
  3347. ext_phy_link_up = 1;
  3348. vars->line_speed = SPEED_10000;
  3349. DP(NETIF_MSG_LINK,
  3350. "port %x: External link"
  3351. " up in 10G\n", params->port);
  3352. } else if ((link_status & (1<<1)) &&
  3353. (!(link_status & (1<<14)))) {
  3354. ext_phy_link_up = 1;
  3355. vars->line_speed = SPEED_2500;
  3356. DP(NETIF_MSG_LINK,
  3357. "port %x: External link"
  3358. " up in 2.5G\n", params->port);
  3359. } else if ((link_status & (1<<0)) &&
  3360. (!(link_status & (1<<13)))) {
  3361. ext_phy_link_up = 1;
  3362. vars->line_speed = SPEED_1000;
  3363. DP(NETIF_MSG_LINK,
  3364. "port %x: External link"
  3365. " up in 1G\n", params->port);
  3366. } else {
  3367. ext_phy_link_up = 0;
  3368. DP(NETIF_MSG_LINK,
  3369. "port %x: External link"
  3370. " is down\n", params->port);
  3371. }
  3372. } else {
  3373. /* See if 1G link is up for the 8072 */
  3374. bnx2x_cl45_read(bp, params->port,
  3375. ext_phy_type,
  3376. ext_phy_addr,
  3377. MDIO_AN_DEVAD,
  3378. MDIO_AN_REG_LINK_STATUS,
  3379. &an1000_status);
  3380. bnx2x_cl45_read(bp, params->port,
  3381. ext_phy_type,
  3382. ext_phy_addr,
  3383. MDIO_AN_DEVAD,
  3384. MDIO_AN_REG_LINK_STATUS,
  3385. &an1000_status);
  3386. if (an1000_status & (1<<1)) {
  3387. ext_phy_link_up = 1;
  3388. vars->line_speed = SPEED_1000;
  3389. DP(NETIF_MSG_LINK,
  3390. "port %x: External link"
  3391. " up in 1G\n", params->port);
  3392. } else if (ext_phy_link_up) {
  3393. ext_phy_link_up = 1;
  3394. vars->line_speed = SPEED_10000;
  3395. DP(NETIF_MSG_LINK,
  3396. "port %x: External link"
  3397. " up in 10G\n", params->port);
  3398. }
  3399. }
  3400. break;
  3401. }
  3402. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
  3403. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3404. ext_phy_addr,
  3405. MDIO_PMA_DEVAD,
  3406. MDIO_PMA_REG_LASI_STATUS, &val2);
  3407. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3408. ext_phy_addr,
  3409. MDIO_PMA_DEVAD,
  3410. MDIO_PMA_REG_LASI_STATUS, &val1);
  3411. DP(NETIF_MSG_LINK,
  3412. "10G-base-T LASI status 0x%x->0x%x\n",
  3413. val2, val1);
  3414. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3415. ext_phy_addr,
  3416. MDIO_PMA_DEVAD,
  3417. MDIO_PMA_REG_STATUS, &val2);
  3418. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3419. ext_phy_addr,
  3420. MDIO_PMA_DEVAD,
  3421. MDIO_PMA_REG_STATUS, &val1);
  3422. DP(NETIF_MSG_LINK,
  3423. "10G-base-T PMA status 0x%x->0x%x\n",
  3424. val2, val1);
  3425. ext_phy_link_up = ((val1 & 4) == 4);
  3426. /* if link is up
  3427. * print the AN outcome of the SFX7101 PHY
  3428. */
  3429. if (ext_phy_link_up) {
  3430. bnx2x_cl45_read(bp, params->port,
  3431. ext_phy_type,
  3432. ext_phy_addr,
  3433. MDIO_AN_DEVAD,
  3434. MDIO_AN_REG_MASTER_STATUS,
  3435. &val2);
  3436. vars->line_speed = SPEED_10000;
  3437. DP(NETIF_MSG_LINK,
  3438. "SFX7101 AN status 0x%x->Master=%x\n",
  3439. val2,
  3440. (val2 & (1<<14)));
  3441. }
  3442. break;
  3443. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
  3444. /* Clear LASI interrupt */
  3445. bnx2x_cl45_read(bp, params->port,
  3446. ext_phy_type,
  3447. ext_phy_addr,
  3448. MDIO_PMA_DEVAD,
  3449. MDIO_PMA_REG_LASI_STATUS, &val1);
  3450. DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
  3451. val1);
  3452. /* Check 10G-BaseT link status */
  3453. /* Check Global PMD signal ok */
  3454. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3455. ext_phy_addr,
  3456. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
  3457. &rx_sd);
  3458. /* Check PCS block lock */
  3459. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3460. ext_phy_addr,
  3461. MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
  3462. &pcs_status);
  3463. DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
  3464. rx_sd, pcs_status);
  3465. if (rx_sd & pcs_status & 0x1) {
  3466. vars->line_speed = SPEED_10000;
  3467. ext_phy_link_up = 1;
  3468. } else {
  3469. /* Check 1000-BaseT link status */
  3470. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3471. ext_phy_addr,
  3472. MDIO_AN_DEVAD, 0xFFE1,
  3473. &val1);
  3474. bnx2x_cl45_read(bp, params->port, ext_phy_type,
  3475. ext_phy_addr,
  3476. MDIO_AN_DEVAD, 0xFFE1,
  3477. &val2);
  3478. DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
  3479. "0x%x-->0x%x\n", val1, val2);
  3480. if (val2 & (1<<2)) {
  3481. vars->line_speed = SPEED_1000;
  3482. ext_phy_link_up = 1;
  3483. }
  3484. }
  3485. break;
  3486. default:
  3487. DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
  3488. params->ext_phy_config);
  3489. ext_phy_link_up = 0;
  3490. break;
  3491. }
  3492. } else { /* SerDes */
  3493. ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
  3494. switch (ext_phy_type) {
  3495. case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
  3496. DP(NETIF_MSG_LINK, "SerDes Direct\n");
  3497. ext_phy_link_up = 1;
  3498. break;
  3499. case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
  3500. DP(NETIF_MSG_LINK, "SerDes 5482\n");
  3501. ext_phy_link_up = 1;
  3502. break;
  3503. default:
  3504. DP(NETIF_MSG_LINK,
  3505. "BAD SerDes ext_phy_config 0x%x\n",
  3506. params->ext_phy_config);
  3507. ext_phy_link_up = 0;
  3508. break;
  3509. }
  3510. }
  3511. return ext_phy_link_up;
  3512. }
  3513. static void bnx2x_link_int_enable(struct link_params *params)
  3514. {
  3515. u8 port = params->port;
  3516. u32 ext_phy_type;
  3517. u32 mask;
  3518. struct bnx2x *bp = params->bp;
  3519. /* setting the status to report on link up
  3520. for either XGXS or SerDes */
  3521. if (params->switch_cfg == SWITCH_CFG_10G) {
  3522. mask = (NIG_MASK_XGXS0_LINK10G |
  3523. NIG_MASK_XGXS0_LINK_STATUS);
  3524. DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
  3525. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  3526. if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
  3527. (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
  3528. (ext_phy_type !=
  3529. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
  3530. mask |= NIG_MASK_MI_INT;
  3531. DP(NETIF_MSG_LINK, "enabled external phy int\n");
  3532. }
  3533. } else { /* SerDes */
  3534. mask = NIG_MASK_SERDES0_LINK_STATUS;
  3535. DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
  3536. ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
  3537. if ((ext_phy_type !=
  3538. PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
  3539. (ext_phy_type !=
  3540. PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
  3541. mask |= NIG_MASK_MI_INT;
  3542. DP(NETIF_MSG_LINK, "enabled external phy int\n");
  3543. }
  3544. }
  3545. bnx2x_bits_en(bp,
  3546. NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
  3547. mask);
  3548. DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
  3549. (params->switch_cfg == SWITCH_CFG_10G),
  3550. REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
  3551. DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
  3552. REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
  3553. REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
  3554. REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
  3555. DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
  3556. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
  3557. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
  3558. }
  3559. /*
  3560. * link management
  3561. */
  3562. static void bnx2x_link_int_ack(struct link_params *params,
  3563. struct link_vars *vars, u8 is_10g)
  3564. {
  3565. struct bnx2x *bp = params->bp;
  3566. u8 port = params->port;
  3567. /* first reset all status
  3568. * we assume only one line will be change at a time */
  3569. bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
  3570. (NIG_STATUS_XGXS0_LINK10G |
  3571. NIG_STATUS_XGXS0_LINK_STATUS |
  3572. NIG_STATUS_SERDES0_LINK_STATUS));
  3573. if (vars->phy_link_up) {
  3574. if (is_10g) {
  3575. /* Disable the 10G link interrupt
  3576. * by writing 1 to the status register
  3577. */
  3578. DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
  3579. bnx2x_bits_en(bp,
  3580. NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
  3581. NIG_STATUS_XGXS0_LINK10G);
  3582. } else if (params->switch_cfg == SWITCH_CFG_10G) {
  3583. /* Disable the link interrupt
  3584. * by writing 1 to the relevant lane
  3585. * in the status register
  3586. */
  3587. u32 ser_lane = ((params->lane_config &
  3588. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  3589. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  3590. DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
  3591. bnx2x_bits_en(bp,
  3592. NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
  3593. ((1 << ser_lane) <<
  3594. NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
  3595. } else { /* SerDes */
  3596. DP(NETIF_MSG_LINK, "SerDes phy link up\n");
  3597. /* Disable the link interrupt
  3598. * by writing 1 to the status register
  3599. */
  3600. bnx2x_bits_en(bp,
  3601. NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
  3602. NIG_STATUS_SERDES0_LINK_STATUS);
  3603. }
  3604. } else { /* link_down */
  3605. }
  3606. }
  3607. static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
  3608. {
  3609. u8 *str_ptr = str;
  3610. u32 mask = 0xf0000000;
  3611. u8 shift = 8*4;
  3612. u8 digit;
  3613. if (len < 10) {
  3614. /* Need more than 10chars for this format */
  3615. *str_ptr = '\0';
  3616. return -EINVAL;
  3617. }
  3618. while (shift > 0) {
  3619. shift -= 4;
  3620. digit = ((num & mask) >> shift);
  3621. if (digit < 0xa)
  3622. *str_ptr = digit + '0';
  3623. else
  3624. *str_ptr = digit - 0xa + 'a';
  3625. str_ptr++;
  3626. mask = mask >> 4;
  3627. if (shift == 4*4) {
  3628. *str_ptr = ':';
  3629. str_ptr++;
  3630. }
  3631. }
  3632. *str_ptr = '\0';
  3633. return 0;
  3634. }
  3635. static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
  3636. u32 ext_phy_type)
  3637. {
  3638. u32 cnt = 0;
  3639. u16 ctrl = 0;
  3640. /* Enable EMAC0 in to enable MDIO */
  3641. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  3642. (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
  3643. msleep(5);
  3644. /* take ext phy out of reset */
  3645. bnx2x_set_gpio(bp,
  3646. MISC_REGISTERS_GPIO_2,
  3647. MISC_REGISTERS_GPIO_HIGH,
  3648. port);
  3649. bnx2x_set_gpio(bp,
  3650. MISC_REGISTERS_GPIO_1,
  3651. MISC_REGISTERS_GPIO_HIGH,
  3652. port);
  3653. /* wait for 5ms */
  3654. msleep(5);
  3655. for (cnt = 0; cnt < 1000; cnt++) {
  3656. msleep(1);
  3657. bnx2x_cl45_read(bp, port,
  3658. ext_phy_type,
  3659. ext_phy_addr,
  3660. MDIO_PMA_DEVAD,
  3661. MDIO_PMA_REG_CTRL,
  3662. &ctrl);
  3663. if (!(ctrl & (1<<15))) {
  3664. DP(NETIF_MSG_LINK, "Reset completed\n\n");
  3665. break;
  3666. }
  3667. }
  3668. }
  3669. static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
  3670. {
  3671. /* put sf to reset */
  3672. bnx2x_set_gpio(bp,
  3673. MISC_REGISTERS_GPIO_1,
  3674. MISC_REGISTERS_GPIO_LOW,
  3675. port);
  3676. bnx2x_set_gpio(bp,
  3677. MISC_REGISTERS_GPIO_2,
  3678. MISC_REGISTERS_GPIO_LOW,
  3679. port);
  3680. }
  3681. u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
  3682. u8 *version, u16 len)
  3683. {
  3684. struct bnx2x *bp;
  3685. u32 ext_phy_type = 0;
  3686. u32 spirom_ver = 0;
  3687. u8 status = 0 ;
  3688. if (version == NULL || params == NULL)
  3689. return -EINVAL;
  3690. bp = params->bp;
  3691. spirom_ver = REG_RD(bp, params->shmem_base +
  3692. offsetof(struct shmem_region,
  3693. port_mb[params->port].ext_phy_fw_version));
  3694. /* reset the returned value to zero */
  3695. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  3696. switch (ext_phy_type) {
  3697. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
  3698. if (len < 5)
  3699. return -EINVAL;
  3700. version[0] = (spirom_ver & 0xFF);
  3701. version[1] = (spirom_ver & 0xFF00) >> 8;
  3702. version[2] = (spirom_ver & 0xFF0000) >> 16;
  3703. version[3] = (spirom_ver & 0xFF000000) >> 24;
  3704. version[4] = '\0';
  3705. break;
  3706. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  3707. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  3708. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
  3709. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
  3710. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  3711. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
  3712. status = bnx2x_format_ver(spirom_ver, version, len);
  3713. break;
  3714. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  3715. break;
  3716. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
  3717. DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
  3718. " type is FAILURE!\n");
  3719. status = -EINVAL;
  3720. break;
  3721. default:
  3722. break;
  3723. }
  3724. return status;
  3725. }
  3726. static void bnx2x_set_xgxs_loopback(struct link_params *params,
  3727. struct link_vars *vars,
  3728. u8 is_10g)
  3729. {
  3730. u8 port = params->port;
  3731. struct bnx2x *bp = params->bp;
  3732. if (is_10g) {
  3733. u32 md_devad;
  3734. DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
  3735. /* change the uni_phy_addr in the nig */
  3736. md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
  3737. port*0x18));
  3738. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
  3739. bnx2x_cl45_write(bp, port, 0,
  3740. params->phy_addr,
  3741. 5,
  3742. (MDIO_REG_BANK_AER_BLOCK +
  3743. (MDIO_AER_BLOCK_AER_REG & 0xf)),
  3744. 0x2800);
  3745. bnx2x_cl45_write(bp, port, 0,
  3746. params->phy_addr,
  3747. 5,
  3748. (MDIO_REG_BANK_CL73_IEEEB0 +
  3749. (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
  3750. 0x6041);
  3751. msleep(200);
  3752. /* set aer mmd back */
  3753. bnx2x_set_aer_mmd(params, vars);
  3754. /* and md_devad */
  3755. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
  3756. md_devad);
  3757. } else {
  3758. u16 mii_control;
  3759. DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
  3760. CL45_RD_OVER_CL22(bp, port,
  3761. params->phy_addr,
  3762. MDIO_REG_BANK_COMBO_IEEE0,
  3763. MDIO_COMBO_IEEE0_MII_CONTROL,
  3764. &mii_control);
  3765. CL45_WR_OVER_CL22(bp, port,
  3766. params->phy_addr,
  3767. MDIO_REG_BANK_COMBO_IEEE0,
  3768. MDIO_COMBO_IEEE0_MII_CONTROL,
  3769. (mii_control |
  3770. MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
  3771. }
  3772. }
  3773. static void bnx2x_ext_phy_loopback(struct link_params *params)
  3774. {
  3775. struct bnx2x *bp = params->bp;
  3776. u8 ext_phy_addr;
  3777. u32 ext_phy_type;
  3778. if (params->switch_cfg == SWITCH_CFG_10G) {
  3779. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  3780. /* CL37 Autoneg Enabled */
  3781. ext_phy_addr = ((params->ext_phy_config &
  3782. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  3783. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  3784. switch (ext_phy_type) {
  3785. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  3786. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
  3787. DP(NETIF_MSG_LINK,
  3788. "ext_phy_loopback: We should not get here\n");
  3789. break;
  3790. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
  3791. DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
  3792. break;
  3793. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
  3794. DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
  3795. break;
  3796. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  3797. DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
  3798. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  3799. ext_phy_addr,
  3800. MDIO_PMA_DEVAD,
  3801. MDIO_PMA_REG_CTRL,
  3802. 0x0001);
  3803. break;
  3804. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
  3805. /* SFX7101_XGXS_TEST1 */
  3806. bnx2x_cl45_write(bp, params->port, ext_phy_type,
  3807. ext_phy_addr,
  3808. MDIO_XS_DEVAD,
  3809. MDIO_XS_SFX7101_XGXS_TEST1,
  3810. 0x100);
  3811. DP(NETIF_MSG_LINK,
  3812. "ext_phy_loopback: set ext phy loopback\n");
  3813. break;
  3814. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  3815. break;
  3816. } /* switch external PHY type */
  3817. } else {
  3818. /* serdes */
  3819. ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
  3820. ext_phy_addr = (params->ext_phy_config &
  3821. PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
  3822. >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
  3823. }
  3824. }
  3825. /*
  3826. *------------------------------------------------------------------------
  3827. * bnx2x_override_led_value -
  3828. *
  3829. * Override the led value of the requsted led
  3830. *
  3831. *------------------------------------------------------------------------
  3832. */
  3833. u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
  3834. u32 led_idx, u32 value)
  3835. {
  3836. u32 reg_val;
  3837. /* If port 0 then use EMAC0, else use EMAC1*/
  3838. u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  3839. DP(NETIF_MSG_LINK,
  3840. "bnx2x_override_led_value() port %x led_idx %d value %d\n",
  3841. port, led_idx, value);
  3842. switch (led_idx) {
  3843. case 0: /* 10MB led */
  3844. /* Read the current value of the LED register in
  3845. the EMAC block */
  3846. reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
  3847. /* Set the OVERRIDE bit to 1 */
  3848. reg_val |= EMAC_LED_OVERRIDE;
  3849. /* If value is 1, set the 10M_OVERRIDE bit,
  3850. otherwise reset it.*/
  3851. reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
  3852. (reg_val & ~EMAC_LED_10MB_OVERRIDE);
  3853. REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
  3854. break;
  3855. case 1: /*100MB led */
  3856. /*Read the current value of the LED register in
  3857. the EMAC block */
  3858. reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
  3859. /* Set the OVERRIDE bit to 1 */
  3860. reg_val |= EMAC_LED_OVERRIDE;
  3861. /* If value is 1, set the 100M_OVERRIDE bit,
  3862. otherwise reset it.*/
  3863. reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
  3864. (reg_val & ~EMAC_LED_100MB_OVERRIDE);
  3865. REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
  3866. break;
  3867. case 2: /* 1000MB led */
  3868. /* Read the current value of the LED register in the
  3869. EMAC block */
  3870. reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
  3871. /* Set the OVERRIDE bit to 1 */
  3872. reg_val |= EMAC_LED_OVERRIDE;
  3873. /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
  3874. reset it. */
  3875. reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
  3876. (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
  3877. REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
  3878. break;
  3879. case 3: /* 2500MB led */
  3880. /* Read the current value of the LED register in the
  3881. EMAC block*/
  3882. reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
  3883. /* Set the OVERRIDE bit to 1 */
  3884. reg_val |= EMAC_LED_OVERRIDE;
  3885. /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
  3886. reset it.*/
  3887. reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
  3888. (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
  3889. REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
  3890. break;
  3891. case 4: /*10G led */
  3892. if (port == 0) {
  3893. REG_WR(bp, NIG_REG_LED_10G_P0,
  3894. value);
  3895. } else {
  3896. REG_WR(bp, NIG_REG_LED_10G_P1,
  3897. value);
  3898. }
  3899. break;
  3900. case 5: /* TRAFFIC led */
  3901. /* Find if the traffic control is via BMAC or EMAC */
  3902. if (port == 0)
  3903. reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
  3904. else
  3905. reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
  3906. /* Override the traffic led in the EMAC:*/
  3907. if (reg_val == 1) {
  3908. /* Read the current value of the LED register in
  3909. the EMAC block */
  3910. reg_val = REG_RD(bp, emac_base +
  3911. EMAC_REG_EMAC_LED);
  3912. /* Set the TRAFFIC_OVERRIDE bit to 1 */
  3913. reg_val |= EMAC_LED_OVERRIDE;
  3914. /* If value is 1, set the TRAFFIC bit, otherwise
  3915. reset it.*/
  3916. reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
  3917. (reg_val & ~EMAC_LED_TRAFFIC);
  3918. REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
  3919. } else { /* Override the traffic led in the BMAC: */
  3920. REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
  3921. + port*4, 1);
  3922. REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
  3923. value);
  3924. }
  3925. break;
  3926. default:
  3927. DP(NETIF_MSG_LINK,
  3928. "bnx2x_override_led_value() unknown led index %d "
  3929. "(should be 0-5)\n", led_idx);
  3930. return -EINVAL;
  3931. }
  3932. return 0;
  3933. }
  3934. u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
  3935. u16 hw_led_mode, u32 chip_id)
  3936. {
  3937. u8 rc = 0;
  3938. u32 tmp;
  3939. u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  3940. DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
  3941. DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
  3942. speed, hw_led_mode);
  3943. switch (mode) {
  3944. case LED_MODE_OFF:
  3945. REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
  3946. REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
  3947. SHARED_HW_CFG_LED_MAC1);
  3948. tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
  3949. EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
  3950. break;
  3951. case LED_MODE_OPER:
  3952. REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
  3953. REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
  3954. port*4, 0);
  3955. /* Set blinking rate to ~15.9Hz */
  3956. REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
  3957. LED_BLINK_RATE_VAL);
  3958. REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
  3959. port*4, 1);
  3960. tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
  3961. EMAC_WR(bp, EMAC_REG_EMAC_LED,
  3962. (tmp & (~EMAC_LED_OVERRIDE)));
  3963. if (!CHIP_IS_E1H(bp) &&
  3964. ((speed == SPEED_2500) ||
  3965. (speed == SPEED_1000) ||
  3966. (speed == SPEED_100) ||
  3967. (speed == SPEED_10))) {
  3968. /* On Everest 1 Ax chip versions for speeds less than
  3969. 10G LED scheme is different */
  3970. REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
  3971. + port*4, 1);
  3972. REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
  3973. port*4, 0);
  3974. REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
  3975. port*4, 1);
  3976. }
  3977. break;
  3978. default:
  3979. rc = -EINVAL;
  3980. DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
  3981. mode);
  3982. break;
  3983. }
  3984. return rc;
  3985. }
  3986. u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
  3987. {
  3988. struct bnx2x *bp = params->bp;
  3989. u16 gp_status = 0;
  3990. CL45_RD_OVER_CL22(bp, params->port,
  3991. params->phy_addr,
  3992. MDIO_REG_BANK_GP_STATUS,
  3993. MDIO_GP_STATUS_TOP_AN_STATUS1,
  3994. &gp_status);
  3995. /* link is up only if both local phy and external phy are up */
  3996. if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
  3997. bnx2x_ext_phy_is_link_up(params, vars))
  3998. return 0;
  3999. return -ESRCH;
  4000. }
  4001. static u8 bnx2x_link_initialize(struct link_params *params,
  4002. struct link_vars *vars)
  4003. {
  4004. struct bnx2x *bp = params->bp;
  4005. u8 port = params->port;
  4006. u8 rc = 0;
  4007. u8 non_ext_phy;
  4008. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  4009. /* Activate the external PHY */
  4010. bnx2x_ext_phy_reset(params, vars);
  4011. bnx2x_set_aer_mmd(params, vars);
  4012. if (vars->phy_flags & PHY_XGXS_FLAG)
  4013. bnx2x_set_master_ln(params);
  4014. rc = bnx2x_reset_unicore(params);
  4015. /* reset the SerDes and wait for reset bit return low */
  4016. if (rc != 0)
  4017. return rc;
  4018. bnx2x_set_aer_mmd(params, vars);
  4019. /* setting the masterLn_def again after the reset */
  4020. if (vars->phy_flags & PHY_XGXS_FLAG) {
  4021. bnx2x_set_master_ln(params);
  4022. bnx2x_set_swap_lanes(params);
  4023. }
  4024. if (vars->phy_flags & PHY_XGXS_FLAG) {
  4025. if ((params->req_line_speed &&
  4026. ((params->req_line_speed == SPEED_100) ||
  4027. (params->req_line_speed == SPEED_10))) ||
  4028. (!params->req_line_speed &&
  4029. (params->speed_cap_mask >=
  4030. PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
  4031. (params->speed_cap_mask <
  4032. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
  4033. )) {
  4034. vars->phy_flags |= PHY_SGMII_FLAG;
  4035. } else {
  4036. vars->phy_flags &= ~PHY_SGMII_FLAG;
  4037. }
  4038. }
  4039. /* In case of external phy existance, the line speed would be the
  4040. line speed linked up by the external phy. In case it is direct only,
  4041. then the line_speed during initialization will be equal to the
  4042. req_line_speed*/
  4043. vars->line_speed = params->req_line_speed;
  4044. bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
  4045. /* init ext phy and enable link state int */
  4046. non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
  4047. (params->loopback_mode == LOOPBACK_XGXS_10));
  4048. if (non_ext_phy ||
  4049. (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
  4050. (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
  4051. (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
  4052. (params->loopback_mode == LOOPBACK_EXT_PHY)) {
  4053. if (params->req_line_speed == SPEED_AUTO_NEG)
  4054. bnx2x_set_parallel_detection(params, vars->phy_flags);
  4055. bnx2x_init_internal_phy(params, vars);
  4056. }
  4057. if (!non_ext_phy)
  4058. rc |= bnx2x_ext_phy_init(params, vars);
  4059. bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
  4060. (NIG_STATUS_XGXS0_LINK10G |
  4061. NIG_STATUS_XGXS0_LINK_STATUS |
  4062. NIG_STATUS_SERDES0_LINK_STATUS));
  4063. return rc;
  4064. }
  4065. u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
  4066. {
  4067. struct bnx2x *bp = params->bp;
  4068. u32 val;
  4069. DP(NETIF_MSG_LINK, "Phy Initialization started \n");
  4070. DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
  4071. params->req_line_speed, params->req_flow_ctrl);
  4072. vars->link_status = 0;
  4073. vars->phy_link_up = 0;
  4074. vars->link_up = 0;
  4075. vars->line_speed = 0;
  4076. vars->duplex = DUPLEX_FULL;
  4077. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  4078. vars->mac_type = MAC_TYPE_NONE;
  4079. if (params->switch_cfg == SWITCH_CFG_1G)
  4080. vars->phy_flags = PHY_SERDES_FLAG;
  4081. else
  4082. vars->phy_flags = PHY_XGXS_FLAG;
  4083. /* disable attentions */
  4084. bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
  4085. (NIG_MASK_XGXS0_LINK_STATUS |
  4086. NIG_MASK_XGXS0_LINK10G |
  4087. NIG_MASK_SERDES0_LINK_STATUS |
  4088. NIG_MASK_MI_INT));
  4089. bnx2x_emac_init(params, vars);
  4090. if (CHIP_REV_IS_FPGA(bp)) {
  4091. vars->link_up = 1;
  4092. vars->line_speed = SPEED_10000;
  4093. vars->duplex = DUPLEX_FULL;
  4094. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  4095. vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
  4096. /* enable on E1.5 FPGA */
  4097. if (CHIP_IS_E1H(bp)) {
  4098. vars->flow_ctrl |=
  4099. (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
  4100. vars->link_status |=
  4101. (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
  4102. LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
  4103. }
  4104. bnx2x_emac_enable(params, vars, 0);
  4105. bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
  4106. /* disable drain */
  4107. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
  4108. + params->port*4, 0);
  4109. /* update shared memory */
  4110. bnx2x_update_mng(params, vars->link_status);
  4111. return 0;
  4112. } else
  4113. if (CHIP_REV_IS_EMUL(bp)) {
  4114. vars->link_up = 1;
  4115. vars->line_speed = SPEED_10000;
  4116. vars->duplex = DUPLEX_FULL;
  4117. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  4118. vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
  4119. bnx2x_bmac_enable(params, vars, 0);
  4120. bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
  4121. /* Disable drain */
  4122. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
  4123. + params->port*4, 0);
  4124. /* update shared memory */
  4125. bnx2x_update_mng(params, vars->link_status);
  4126. return 0;
  4127. } else
  4128. if (params->loopback_mode == LOOPBACK_BMAC) {
  4129. vars->link_up = 1;
  4130. vars->line_speed = SPEED_10000;
  4131. vars->duplex = DUPLEX_FULL;
  4132. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  4133. vars->mac_type = MAC_TYPE_BMAC;
  4134. vars->phy_flags = PHY_XGXS_FLAG;
  4135. bnx2x_phy_deassert(params, vars->phy_flags);
  4136. /* set bmac loopback */
  4137. bnx2x_bmac_enable(params, vars, 1);
  4138. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
  4139. params->port*4, 0);
  4140. } else if (params->loopback_mode == LOOPBACK_EMAC) {
  4141. vars->link_up = 1;
  4142. vars->line_speed = SPEED_1000;
  4143. vars->duplex = DUPLEX_FULL;
  4144. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  4145. vars->mac_type = MAC_TYPE_EMAC;
  4146. vars->phy_flags = PHY_XGXS_FLAG;
  4147. bnx2x_phy_deassert(params, vars->phy_flags);
  4148. /* set bmac loopback */
  4149. bnx2x_emac_enable(params, vars, 1);
  4150. bnx2x_emac_program(params, vars->line_speed,
  4151. vars->duplex);
  4152. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
  4153. params->port*4, 0);
  4154. } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
  4155. (params->loopback_mode == LOOPBACK_EXT_PHY)) {
  4156. vars->link_up = 1;
  4157. vars->line_speed = SPEED_10000;
  4158. vars->duplex = DUPLEX_FULL;
  4159. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  4160. vars->phy_flags = PHY_XGXS_FLAG;
  4161. val = REG_RD(bp,
  4162. NIG_REG_XGXS0_CTRL_PHY_ADDR+
  4163. params->port*0x18);
  4164. params->phy_addr = (u8)val;
  4165. bnx2x_phy_deassert(params, vars->phy_flags);
  4166. bnx2x_link_initialize(params, vars);
  4167. vars->mac_type = MAC_TYPE_BMAC;
  4168. bnx2x_bmac_enable(params, vars, 0);
  4169. if (params->loopback_mode == LOOPBACK_XGXS_10) {
  4170. /* set 10G XGXS loopback */
  4171. bnx2x_set_xgxs_loopback(params, vars, 1);
  4172. } else {
  4173. /* set external phy loopback */
  4174. bnx2x_ext_phy_loopback(params);
  4175. }
  4176. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
  4177. params->port*4, 0);
  4178. } else
  4179. /* No loopback */
  4180. {
  4181. bnx2x_phy_deassert(params, vars->phy_flags);
  4182. switch (params->switch_cfg) {
  4183. case SWITCH_CFG_1G:
  4184. vars->phy_flags |= PHY_SERDES_FLAG;
  4185. if ((params->ext_phy_config &
  4186. PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
  4187. PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
  4188. vars->phy_flags |=
  4189. PHY_SGMII_FLAG;
  4190. }
  4191. val = REG_RD(bp,
  4192. NIG_REG_SERDES0_CTRL_PHY_ADDR+
  4193. params->port*0x10);
  4194. params->phy_addr = (u8)val;
  4195. break;
  4196. case SWITCH_CFG_10G:
  4197. vars->phy_flags |= PHY_XGXS_FLAG;
  4198. val = REG_RD(bp,
  4199. NIG_REG_XGXS0_CTRL_PHY_ADDR+
  4200. params->port*0x18);
  4201. params->phy_addr = (u8)val;
  4202. break;
  4203. default:
  4204. DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
  4205. return -EINVAL;
  4206. break;
  4207. }
  4208. DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
  4209. bnx2x_link_initialize(params, vars);
  4210. msleep(30);
  4211. bnx2x_link_int_enable(params);
  4212. }
  4213. return 0;
  4214. }
  4215. static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
  4216. {
  4217. DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
  4218. /* Set serial boot control for external load */
  4219. bnx2x_cl45_write(bp, port,
  4220. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
  4221. MDIO_PMA_DEVAD,
  4222. MDIO_PMA_REG_GEN_CTRL, 0x0001);
  4223. /* Disable Transmitter */
  4224. bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
  4225. }
  4226. u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
  4227. u8 reset_ext_phy)
  4228. {
  4229. struct bnx2x *bp = params->bp;
  4230. u32 ext_phy_config = params->ext_phy_config;
  4231. u16 hw_led_mode = params->hw_led_mode;
  4232. u32 chip_id = params->chip_id;
  4233. u8 port = params->port;
  4234. u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
  4235. /* disable attentions */
  4236. vars->link_status = 0;
  4237. bnx2x_update_mng(params, vars->link_status);
  4238. bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
  4239. (NIG_MASK_XGXS0_LINK_STATUS |
  4240. NIG_MASK_XGXS0_LINK10G |
  4241. NIG_MASK_SERDES0_LINK_STATUS |
  4242. NIG_MASK_MI_INT));
  4243. /* activate nig drain */
  4244. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
  4245. /* disable nig egress interface */
  4246. REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
  4247. REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
  4248. /* Stop BigMac rx */
  4249. bnx2x_bmac_rx_disable(bp, port);
  4250. /* disable emac */
  4251. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
  4252. msleep(10);
  4253. /* The PHY reset is controled by GPIO 1
  4254. * Hold it as vars low
  4255. */
  4256. /* clear link led */
  4257. bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
  4258. if (reset_ext_phy) {
  4259. switch (ext_phy_type) {
  4260. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  4261. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  4262. break;
  4263. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  4264. DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
  4265. "low power mode\n",
  4266. port);
  4267. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  4268. MISC_REGISTERS_GPIO_OUTPUT_LOW,
  4269. port);
  4270. break;
  4271. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  4272. {
  4273. u8 ext_phy_addr = ((params->ext_phy_config &
  4274. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  4275. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  4276. /* Set soft reset */
  4277. bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
  4278. break;
  4279. }
  4280. default:
  4281. /* HW reset */
  4282. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  4283. MISC_REGISTERS_GPIO_OUTPUT_LOW,
  4284. port);
  4285. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  4286. MISC_REGISTERS_GPIO_OUTPUT_LOW,
  4287. port);
  4288. DP(NETIF_MSG_LINK, "reset external PHY\n");
  4289. }
  4290. }
  4291. /* reset the SerDes/XGXS */
  4292. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
  4293. (0x1ff << (port*16)));
  4294. /* reset BigMac */
  4295. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  4296. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  4297. /* disable nig ingress interface */
  4298. REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
  4299. REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
  4300. REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
  4301. REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
  4302. vars->link_up = 0;
  4303. return 0;
  4304. }
  4305. static u8 bnx2x_update_link_down(struct link_params *params,
  4306. struct link_vars *vars)
  4307. {
  4308. struct bnx2x *bp = params->bp;
  4309. u8 port = params->port;
  4310. DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
  4311. bnx2x_set_led(bp, port, LED_MODE_OFF,
  4312. 0, params->hw_led_mode,
  4313. params->chip_id);
  4314. /* indicate no mac active */
  4315. vars->mac_type = MAC_TYPE_NONE;
  4316. /* update shared memory */
  4317. vars->link_status = 0;
  4318. vars->line_speed = 0;
  4319. bnx2x_update_mng(params, vars->link_status);
  4320. /* activate nig drain */
  4321. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
  4322. /* disable emac */
  4323. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
  4324. msleep(10);
  4325. /* reset BigMac */
  4326. bnx2x_bmac_rx_disable(bp, params->port);
  4327. REG_WR(bp, GRCBASE_MISC +
  4328. MISC_REGISTERS_RESET_REG_2_CLEAR,
  4329. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  4330. return 0;
  4331. }
  4332. static u8 bnx2x_update_link_up(struct link_params *params,
  4333. struct link_vars *vars,
  4334. u8 link_10g, u32 gp_status)
  4335. {
  4336. struct bnx2x *bp = params->bp;
  4337. u8 port = params->port;
  4338. u8 rc = 0;
  4339. vars->link_status |= LINK_STATUS_LINK_UP;
  4340. if (link_10g) {
  4341. bnx2x_bmac_enable(params, vars, 0);
  4342. bnx2x_set_led(bp, port, LED_MODE_OPER,
  4343. SPEED_10000, params->hw_led_mode,
  4344. params->chip_id);
  4345. } else {
  4346. bnx2x_emac_enable(params, vars, 0);
  4347. rc = bnx2x_emac_program(params, vars->line_speed,
  4348. vars->duplex);
  4349. /* AN complete? */
  4350. if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
  4351. if (!(vars->phy_flags &
  4352. PHY_SGMII_FLAG))
  4353. bnx2x_set_gmii_tx_driver(params);
  4354. }
  4355. }
  4356. /* PBF - link up */
  4357. rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
  4358. vars->line_speed);
  4359. /* disable drain */
  4360. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
  4361. /* update shared memory */
  4362. bnx2x_update_mng(params, vars->link_status);
  4363. msleep(20);
  4364. return rc;
  4365. }
  4366. /* This function should called upon link interrupt */
  4367. /* In case vars->link_up, driver needs to
  4368. 1. Update the pbf
  4369. 2. Disable drain
  4370. 3. Update the shared memory
  4371. 4. Indicate link up
  4372. 5. Set LEDs
  4373. Otherwise,
  4374. 1. Update shared memory
  4375. 2. Reset BigMac
  4376. 3. Report link down
  4377. 4. Unset LEDs
  4378. */
  4379. u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
  4380. {
  4381. struct bnx2x *bp = params->bp;
  4382. u8 port = params->port;
  4383. u16 gp_status;
  4384. u8 link_10g;
  4385. u8 ext_phy_link_up, rc = 0;
  4386. u32 ext_phy_type;
  4387. DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
  4388. port,
  4389. (vars->phy_flags & PHY_XGXS_FLAG),
  4390. REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
  4391. DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
  4392. REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
  4393. REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
  4394. REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
  4395. DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
  4396. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
  4397. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
  4398. /* disable emac */
  4399. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
  4400. ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
  4401. /* Check external link change only for non-direct */
  4402. ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
  4403. /* Read gp_status */
  4404. CL45_RD_OVER_CL22(bp, port, params->phy_addr,
  4405. MDIO_REG_BANK_GP_STATUS,
  4406. MDIO_GP_STATUS_TOP_AN_STATUS1,
  4407. &gp_status);
  4408. rc = bnx2x_link_settings_status(params, vars, gp_status);
  4409. if (rc != 0)
  4410. return rc;
  4411. /* anything 10 and over uses the bmac */
  4412. link_10g = ((vars->line_speed == SPEED_10000) ||
  4413. (vars->line_speed == SPEED_12000) ||
  4414. (vars->line_speed == SPEED_12500) ||
  4415. (vars->line_speed == SPEED_13000) ||
  4416. (vars->line_speed == SPEED_15000) ||
  4417. (vars->line_speed == SPEED_16000));
  4418. bnx2x_link_int_ack(params, vars, link_10g);
  4419. /* In case external phy link is up, and internal link is down
  4420. ( not initialized yet probably after link initialization, it needs
  4421. to be initialized.
  4422. Note that after link down-up as result of cable plug,
  4423. the xgxs link would probably become up again without the need to
  4424. initialize it*/
  4425. if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
  4426. (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
  4427. (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
  4428. (ext_phy_link_up && !vars->phy_link_up))
  4429. bnx2x_init_internal_phy(params, vars);
  4430. /* link is up only if both local phy and external phy are up */
  4431. vars->link_up = (ext_phy_link_up && vars->phy_link_up);
  4432. if (vars->link_up)
  4433. rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
  4434. else
  4435. rc = bnx2x_update_link_down(params, vars);
  4436. return rc;
  4437. }
  4438. static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
  4439. {
  4440. u8 ext_phy_addr[PORT_MAX];
  4441. u16 val;
  4442. s8 port;
  4443. /* PART1 - Reset both phys */
  4444. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  4445. /* Extract the ext phy address for the port */
  4446. u32 ext_phy_config = REG_RD(bp, shmem_base +
  4447. offsetof(struct shmem_region,
  4448. dev_info.port_hw_config[port].external_phy_config));
  4449. /* disable attentions */
  4450. bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
  4451. (NIG_MASK_XGXS0_LINK_STATUS |
  4452. NIG_MASK_XGXS0_LINK10G |
  4453. NIG_MASK_SERDES0_LINK_STATUS |
  4454. NIG_MASK_MI_INT));
  4455. ext_phy_addr[port] =
  4456. ((ext_phy_config &
  4457. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  4458. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  4459. /* Need to take the phy out of low power mode in order
  4460. to write to access its registers */
  4461. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  4462. MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
  4463. /* Reset the phy */
  4464. bnx2x_cl45_write(bp, port,
  4465. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4466. ext_phy_addr[port],
  4467. MDIO_PMA_DEVAD,
  4468. MDIO_PMA_REG_CTRL,
  4469. 1<<15);
  4470. }
  4471. /* Add delay of 150ms after reset */
  4472. msleep(150);
  4473. /* PART2 - Download firmware to both phys */
  4474. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  4475. u16 fw_ver1;
  4476. bnx2x_bcm8073_external_rom_boot(bp, port,
  4477. ext_phy_addr[port], shmem_base);
  4478. bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4479. ext_phy_addr[port],
  4480. MDIO_PMA_DEVAD,
  4481. MDIO_PMA_REG_ROM_VER1, &fw_ver1);
  4482. if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
  4483. DP(NETIF_MSG_LINK,
  4484. "bnx2x_8073_common_init_phy port %x:"
  4485. "Download failed. fw version = 0x%x\n",
  4486. port, fw_ver1);
  4487. return -EINVAL;
  4488. }
  4489. /* Only set bit 10 = 1 (Tx power down) */
  4490. bnx2x_cl45_read(bp, port,
  4491. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4492. ext_phy_addr[port],
  4493. MDIO_PMA_DEVAD,
  4494. MDIO_PMA_REG_TX_POWER_DOWN, &val);
  4495. /* Phase1 of TX_POWER_DOWN reset */
  4496. bnx2x_cl45_write(bp, port,
  4497. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4498. ext_phy_addr[port],
  4499. MDIO_PMA_DEVAD,
  4500. MDIO_PMA_REG_TX_POWER_DOWN,
  4501. (val | 1<<10));
  4502. }
  4503. /* Toggle Transmitter: Power down and then up with 600ms
  4504. delay between */
  4505. msleep(600);
  4506. /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
  4507. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  4508. /* Phase2 of POWER_DOWN_RESET */
  4509. /* Release bit 10 (Release Tx power down) */
  4510. bnx2x_cl45_read(bp, port,
  4511. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4512. ext_phy_addr[port],
  4513. MDIO_PMA_DEVAD,
  4514. MDIO_PMA_REG_TX_POWER_DOWN, &val);
  4515. bnx2x_cl45_write(bp, port,
  4516. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4517. ext_phy_addr[port],
  4518. MDIO_PMA_DEVAD,
  4519. MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
  4520. msleep(15);
  4521. /* Read modify write the SPI-ROM version select register */
  4522. bnx2x_cl45_read(bp, port,
  4523. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4524. ext_phy_addr[port],
  4525. MDIO_PMA_DEVAD,
  4526. MDIO_PMA_REG_EDC_FFE_MAIN, &val);
  4527. bnx2x_cl45_write(bp, port,
  4528. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  4529. ext_phy_addr[port],
  4530. MDIO_PMA_DEVAD,
  4531. MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
  4532. /* set GPIO2 back to LOW */
  4533. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  4534. MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
  4535. }
  4536. return 0;
  4537. }
  4538. static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
  4539. {
  4540. u8 ext_phy_addr;
  4541. u32 val;
  4542. s8 port;
  4543. /* Use port1 because of the static port-swap */
  4544. /* Enable the module detection interrupt */
  4545. val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
  4546. val |= ((1<<MISC_REGISTERS_GPIO_3)|
  4547. (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
  4548. REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
  4549. bnx2x_hw_reset(bp, 1);
  4550. msleep(5);
  4551. for (port = 0; port < PORT_MAX; port++) {
  4552. /* Extract the ext phy address for the port */
  4553. u32 ext_phy_config = REG_RD(bp, shmem_base +
  4554. offsetof(struct shmem_region,
  4555. dev_info.port_hw_config[port].external_phy_config));
  4556. ext_phy_addr =
  4557. ((ext_phy_config &
  4558. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  4559. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  4560. DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
  4561. ext_phy_addr);
  4562. bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
  4563. /* Set fault module detected LED on */
  4564. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
  4565. MISC_REGISTERS_GPIO_HIGH,
  4566. port);
  4567. }
  4568. return 0;
  4569. }
  4570. u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
  4571. {
  4572. u8 rc = 0;
  4573. u32 ext_phy_type;
  4574. DP(NETIF_MSG_LINK, "Begin common phy init\n");
  4575. /* Read the ext_phy_type for arbitrary port(0) */
  4576. ext_phy_type = XGXS_EXT_PHY_TYPE(
  4577. REG_RD(bp, shmem_base +
  4578. offsetof(struct shmem_region,
  4579. dev_info.port_hw_config[0].external_phy_config)));
  4580. switch (ext_phy_type) {
  4581. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  4582. {
  4583. rc = bnx2x_8073_common_init_phy(bp, shmem_base);
  4584. break;
  4585. }
  4586. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  4587. /* GPIO1 affects both ports, so there's need to pull
  4588. it for single port alone */
  4589. rc = bnx2x_8726_common_init_phy(bp, shmem_base);
  4590. break;
  4591. default:
  4592. DP(NETIF_MSG_LINK,
  4593. "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
  4594. ext_phy_type);
  4595. break;
  4596. }
  4597. return rc;
  4598. }
  4599. static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
  4600. {
  4601. u16 val, cnt;
  4602. bnx2x_cl45_read(bp, port,
  4603. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4604. phy_addr,
  4605. MDIO_PMA_DEVAD,
  4606. MDIO_PMA_REG_7101_RESET, &val);
  4607. for (cnt = 0; cnt < 10; cnt++) {
  4608. msleep(50);
  4609. /* Writes a self-clearing reset */
  4610. bnx2x_cl45_write(bp, port,
  4611. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4612. phy_addr,
  4613. MDIO_PMA_DEVAD,
  4614. MDIO_PMA_REG_7101_RESET,
  4615. (val | (1<<15)));
  4616. /* Wait for clear */
  4617. bnx2x_cl45_read(bp, port,
  4618. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4619. phy_addr,
  4620. MDIO_PMA_DEVAD,
  4621. MDIO_PMA_REG_7101_RESET, &val);
  4622. if ((val & (1<<15)) == 0)
  4623. break;
  4624. }
  4625. }
  4626. #define RESERVED_SIZE 256
  4627. /* max application is 160K bytes - data at end of RAM */
  4628. #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
  4629. /* Header is 14 bytes */
  4630. #define HEADER_SIZE 14
  4631. #define DATA_OFFSET HEADER_SIZE
  4632. #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
  4633. bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
  4634. ext_phy_addr, \
  4635. MDIO_PCS_DEVAD, \
  4636. MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
  4637. /* Programs an image to DSP's flash via the SPI port*/
  4638. static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
  4639. u8 ext_phy_addr,
  4640. char data[], u32 size)
  4641. {
  4642. const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
  4643. /* Doesn't include last trans!*/
  4644. const u16 last_trans_size = size%4; /* Num bytes on last trans */
  4645. u16 trans_cnt, byte_cnt;
  4646. u32 data_index;
  4647. u16 tmp;
  4648. u16 code_started = 0;
  4649. u16 image_revision1, image_revision2;
  4650. u16 cnt;
  4651. DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
  4652. /* Going to flash*/
  4653. if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
  4654. /* This very often will be the case, because the image is built
  4655. with 160Kbytes size whereas the total image size must actually
  4656. be 160Kbytes-RESERVED_SIZE */
  4657. DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
  4658. "truncated to %d bytes\n", size, MAX_APP_SIZE);
  4659. size = MAX_APP_SIZE+HEADER_SIZE;
  4660. }
  4661. DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
  4662. DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
  4663. /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
  4664. and issuing a reset.*/
  4665. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
  4666. MISC_REGISTERS_GPIO_HIGH, port);
  4667. bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
  4668. /* wait 0.5 sec */
  4669. for (cnt = 0; cnt < 100; cnt++)
  4670. msleep(5);
  4671. /* Make sure we can access the DSP
  4672. And it's in the correct mode (waiting for download) */
  4673. bnx2x_cl45_read(bp, port,
  4674. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4675. ext_phy_addr,
  4676. MDIO_PCS_DEVAD,
  4677. MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
  4678. if (tmp != 0x000A) {
  4679. DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
  4680. "Expected 0x000A, read 0x%04X\n", tmp);
  4681. DP(NETIF_MSG_LINK, "Download failed\n");
  4682. return -EINVAL;
  4683. }
  4684. /* Mux the SPI interface away from the internal processor */
  4685. bnx2x_cl45_write(bp, port,
  4686. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4687. ext_phy_addr,
  4688. MDIO_PCS_DEVAD,
  4689. MDIO_PCS_REG_7101_SPI_MUX, 1);
  4690. /* Reset the SPI port */
  4691. bnx2x_cl45_write(bp, port,
  4692. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4693. ext_phy_addr,
  4694. MDIO_PCS_DEVAD,
  4695. MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
  4696. bnx2x_cl45_write(bp, port,
  4697. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4698. ext_phy_addr,
  4699. MDIO_PCS_DEVAD,
  4700. MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
  4701. (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
  4702. bnx2x_cl45_write(bp, port,
  4703. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4704. ext_phy_addr,
  4705. MDIO_PCS_DEVAD,
  4706. MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
  4707. /* Erase the flash */
  4708. bnx2x_cl45_write(bp, port,
  4709. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4710. ext_phy_addr,
  4711. MDIO_PCS_DEVAD,
  4712. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4713. MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
  4714. bnx2x_cl45_write(bp, port,
  4715. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4716. ext_phy_addr,
  4717. MDIO_PCS_DEVAD,
  4718. MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
  4719. 1);
  4720. SPI_START_TRANSFER(bp, port, ext_phy_addr);
  4721. bnx2x_cl45_write(bp, port,
  4722. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4723. ext_phy_addr,
  4724. MDIO_PCS_DEVAD,
  4725. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4726. MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
  4727. bnx2x_cl45_write(bp, port,
  4728. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4729. ext_phy_addr,
  4730. MDIO_PCS_DEVAD,
  4731. MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
  4732. 1);
  4733. SPI_START_TRANSFER(bp, port, ext_phy_addr);
  4734. /* Wait 10 seconds, the maximum time for the erase to complete */
  4735. DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
  4736. for (cnt = 0; cnt < 1000; cnt++)
  4737. msleep(10);
  4738. DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
  4739. data_index = 0;
  4740. for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
  4741. bnx2x_cl45_write(bp, port,
  4742. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4743. ext_phy_addr,
  4744. MDIO_PCS_DEVAD,
  4745. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4746. MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
  4747. bnx2x_cl45_write(bp, port,
  4748. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4749. ext_phy_addr,
  4750. MDIO_PCS_DEVAD,
  4751. MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
  4752. 1);
  4753. SPI_START_TRANSFER(bp, port, ext_phy_addr);
  4754. bnx2x_cl45_write(bp, port,
  4755. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4756. ext_phy_addr,
  4757. MDIO_PCS_DEVAD,
  4758. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4759. MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
  4760. /* Bits 23-16 of address */
  4761. bnx2x_cl45_write(bp, port,
  4762. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4763. ext_phy_addr,
  4764. MDIO_PCS_DEVAD,
  4765. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4766. (data_index>>16));
  4767. /* Bits 15-8 of address */
  4768. bnx2x_cl45_write(bp, port,
  4769. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4770. ext_phy_addr,
  4771. MDIO_PCS_DEVAD,
  4772. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4773. (data_index>>8));
  4774. /* Bits 7-0 of address */
  4775. bnx2x_cl45_write(bp, port,
  4776. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4777. ext_phy_addr,
  4778. MDIO_PCS_DEVAD,
  4779. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4780. ((u16)data_index));
  4781. byte_cnt = 0;
  4782. while (byte_cnt < 4 && data_index < size) {
  4783. bnx2x_cl45_write(bp, port,
  4784. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4785. ext_phy_addr,
  4786. MDIO_PCS_DEVAD,
  4787. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4788. data[data_index++]);
  4789. byte_cnt++;
  4790. }
  4791. bnx2x_cl45_write(bp, port,
  4792. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4793. ext_phy_addr,
  4794. MDIO_PCS_DEVAD,
  4795. MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
  4796. byte_cnt+4);
  4797. SPI_START_TRANSFER(bp, port, ext_phy_addr);
  4798. msleep(5); /* Wait 5 ms minimum between transs */
  4799. /* Let the user know something's going on.*/
  4800. /* a pacifier ever 4K */
  4801. if ((data_index % 1023) == 0)
  4802. DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
  4803. }
  4804. DP(NETIF_MSG_LINK, "\n");
  4805. /* Transfer the last block if there is data remaining */
  4806. if (last_trans_size) {
  4807. bnx2x_cl45_write(bp, port,
  4808. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4809. ext_phy_addr,
  4810. MDIO_PCS_DEVAD,
  4811. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4812. MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
  4813. bnx2x_cl45_write(bp, port,
  4814. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4815. ext_phy_addr,
  4816. MDIO_PCS_DEVAD,
  4817. MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
  4818. 1);
  4819. SPI_START_TRANSFER(bp, port, ext_phy_addr);
  4820. bnx2x_cl45_write(bp, port,
  4821. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4822. ext_phy_addr,
  4823. MDIO_PCS_DEVAD,
  4824. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4825. MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
  4826. /* Bits 23-16 of address */
  4827. bnx2x_cl45_write(bp, port,
  4828. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4829. ext_phy_addr,
  4830. MDIO_PCS_DEVAD,
  4831. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4832. (data_index>>16));
  4833. /* Bits 15-8 of address */
  4834. bnx2x_cl45_write(bp, port,
  4835. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4836. ext_phy_addr,
  4837. MDIO_PCS_DEVAD,
  4838. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4839. (data_index>>8));
  4840. /* Bits 7-0 of address */
  4841. bnx2x_cl45_write(bp, port,
  4842. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4843. ext_phy_addr,
  4844. MDIO_PCS_DEVAD,
  4845. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4846. ((u16)data_index));
  4847. byte_cnt = 0;
  4848. while (byte_cnt < last_trans_size && data_index < size) {
  4849. /* Bits 7-0 of address */
  4850. bnx2x_cl45_write(bp, port,
  4851. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4852. ext_phy_addr,
  4853. MDIO_PCS_DEVAD,
  4854. MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
  4855. data[data_index++]);
  4856. byte_cnt++;
  4857. }
  4858. bnx2x_cl45_write(bp, port,
  4859. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4860. ext_phy_addr,
  4861. MDIO_PCS_DEVAD,
  4862. MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
  4863. byte_cnt+4);
  4864. SPI_START_TRANSFER(bp, port, ext_phy_addr);
  4865. }
  4866. /* DSP Remove Download Mode */
  4867. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
  4868. MISC_REGISTERS_GPIO_LOW, port);
  4869. bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
  4870. /* wait 0.5 sec to allow it to run */
  4871. for (cnt = 0; cnt < 100; cnt++)
  4872. msleep(5);
  4873. bnx2x_hw_reset(bp, port);
  4874. for (cnt = 0; cnt < 100; cnt++)
  4875. msleep(5);
  4876. /* Check that the code is started. In case the download
  4877. checksum failed, the code won't be started. */
  4878. bnx2x_cl45_read(bp, port,
  4879. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4880. ext_phy_addr,
  4881. MDIO_PCS_DEVAD,
  4882. MDIO_PCS_REG_7101_DSP_ACCESS,
  4883. &tmp);
  4884. code_started = (tmp & (1<<4));
  4885. if (!code_started) {
  4886. DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
  4887. return -EINVAL;
  4888. }
  4889. /* Verify that the file revision is now equal to the image
  4890. revision within the DSP */
  4891. bnx2x_cl45_read(bp, port,
  4892. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4893. ext_phy_addr,
  4894. MDIO_PMA_DEVAD,
  4895. MDIO_PMA_REG_7101_VER1,
  4896. &image_revision1);
  4897. bnx2x_cl45_read(bp, port,
  4898. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  4899. ext_phy_addr,
  4900. MDIO_PMA_DEVAD,
  4901. MDIO_PMA_REG_7101_VER2,
  4902. &image_revision2);
  4903. if (data[0x14e] != (image_revision2&0xFF) ||
  4904. data[0x14f] != ((image_revision2&0xFF00)>>8) ||
  4905. data[0x150] != (image_revision1&0xFF) ||
  4906. data[0x151] != ((image_revision1&0xFF00)>>8)) {
  4907. DP(NETIF_MSG_LINK, "Download failed.\n");
  4908. return -EINVAL;
  4909. }
  4910. DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
  4911. return 0;
  4912. }
  4913. u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
  4914. u8 driver_loaded, char data[], u32 size)
  4915. {
  4916. u8 rc = 0;
  4917. u32 ext_phy_type;
  4918. u8 ext_phy_addr;
  4919. ext_phy_addr = ((ext_phy_config &
  4920. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
  4921. PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
  4922. ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
  4923. switch (ext_phy_type) {
  4924. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
  4925. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  4926. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
  4927. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
  4928. DP(NETIF_MSG_LINK,
  4929. "Flash download not supported for this ext phy\n");
  4930. rc = -EINVAL;
  4931. break;
  4932. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
  4933. /* Take ext phy out of reset */
  4934. if (!driver_loaded)
  4935. bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
  4936. rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
  4937. data, size);
  4938. if (!driver_loaded)
  4939. bnx2x_turn_off_sf(bp, port);
  4940. break;
  4941. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  4942. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
  4943. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
  4944. default:
  4945. DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
  4946. rc = -EINVAL;
  4947. break;
  4948. }
  4949. return rc;
  4950. }