bnx2x_link.c 317 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131
  1. /* Copyright 2008-2011 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. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  17. #include <linux/kernel.h>
  18. #include <linux/errno.h>
  19. #include <linux/pci.h>
  20. #include <linux/netdevice.h>
  21. #include <linux/delay.h>
  22. #include <linux/ethtool.h>
  23. #include <linux/mutex.h>
  24. #include "bnx2x.h"
  25. #include "bnx2x_cmn.h"
  26. /********************************************************/
  27. #define ETH_HLEN 14
  28. /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
  29. #define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
  30. #define ETH_MIN_PACKET_SIZE 60
  31. #define ETH_MAX_PACKET_SIZE 1500
  32. #define ETH_MAX_JUMBO_PACKET_SIZE 9600
  33. #define MDIO_ACCESS_TIMEOUT 1000
  34. #define BMAC_CONTROL_RX_ENABLE 2
  35. #define WC_LANE_MAX 4
  36. #define I2C_SWITCH_WIDTH 2
  37. #define I2C_BSC0 0
  38. #define I2C_BSC1 1
  39. #define I2C_WA_RETRY_CNT 3
  40. #define MCPR_IMC_COMMAND_READ_OP 1
  41. #define MCPR_IMC_COMMAND_WRITE_OP 2
  42. /***********************************************************/
  43. /* Shortcut definitions */
  44. /***********************************************************/
  45. #define NIG_LATCH_BC_ENABLE_MI_INT 0
  46. #define NIG_STATUS_EMAC0_MI_INT \
  47. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
  48. #define NIG_STATUS_XGXS0_LINK10G \
  49. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
  50. #define NIG_STATUS_XGXS0_LINK_STATUS \
  51. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
  52. #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
  53. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
  54. #define NIG_STATUS_SERDES0_LINK_STATUS \
  55. NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
  56. #define NIG_MASK_MI_INT \
  57. NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
  58. #define NIG_MASK_XGXS0_LINK10G \
  59. NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
  60. #define NIG_MASK_XGXS0_LINK_STATUS \
  61. NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
  62. #define NIG_MASK_SERDES0_LINK_STATUS \
  63. NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
  64. #define MDIO_AN_CL73_OR_37_COMPLETE \
  65. (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
  66. MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
  67. #define XGXS_RESET_BITS \
  68. (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
  69. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
  70. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
  71. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
  72. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
  73. #define SERDES_RESET_BITS \
  74. (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
  75. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
  76. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
  77. MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
  78. #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
  79. #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
  80. #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
  81. #define AUTONEG_PARALLEL \
  82. SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
  83. #define AUTONEG_SGMII_FIBER_AUTODET \
  84. SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
  85. #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
  86. #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
  87. MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
  88. #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
  89. MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
  90. #define GP_STATUS_SPEED_MASK \
  91. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
  92. #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
  93. #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
  94. #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
  95. #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
  96. #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
  97. #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
  98. #define GP_STATUS_10G_HIG \
  99. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
  100. #define GP_STATUS_10G_CX4 \
  101. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
  102. #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
  103. #define GP_STATUS_10G_KX4 \
  104. MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
  105. #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
  106. #define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
  107. #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
  108. #define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
  109. #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
  110. #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
  111. #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
  112. #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
  113. #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
  114. #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
  115. #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
  116. #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
  117. #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
  118. #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
  119. #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
  120. #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
  121. #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
  122. #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
  123. #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
  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_COMP_CODE_ADDR 0x3
  129. #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
  130. #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
  131. #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
  132. #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
  133. #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
  134. #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
  135. #define SFP_EEPROM_OPTIONS_ADDR 0x40
  136. #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
  137. #define SFP_EEPROM_OPTIONS_SIZE 2
  138. #define EDC_MODE_LINEAR 0x0022
  139. #define EDC_MODE_LIMITING 0x0044
  140. #define EDC_MODE_PASSIVE_DAC 0x0055
  141. /* BRB thresholds for E2*/
  142. #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE 170
  143. #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
  144. #define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE 250
  145. #define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
  146. #define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE 10
  147. #define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 90
  148. #define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE 50
  149. #define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE 250
  150. /* BRB thresholds for E3A0 */
  151. #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE 290
  152. #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
  153. #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE 410
  154. #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
  155. #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE 10
  156. #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 170
  157. #define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE 50
  158. #define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE 410
  159. /* BRB thresholds for E3B0 2 port mode*/
  160. #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 1025
  161. #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
  162. #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE 1025
  163. #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
  164. #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
  165. #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 1025
  166. #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE 50
  167. #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE 1025
  168. /* only for E3B0*/
  169. #define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR 1025
  170. #define PFC_E3B0_2P_BRB_FULL_LB_XON_THR 1025
  171. /* Lossy +Lossless GUARANTIED == GUART */
  172. #define PFC_E3B0_2P_MIX_PAUSE_LB_GUART 284
  173. /* Lossless +Lossless*/
  174. #define PFC_E3B0_2P_PAUSE_LB_GUART 236
  175. /* Lossy +Lossy*/
  176. #define PFC_E3B0_2P_NON_PAUSE_LB_GUART 342
  177. /* Lossy +Lossless*/
  178. #define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART 284
  179. /* Lossless +Lossless*/
  180. #define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART 236
  181. /* Lossy +Lossy*/
  182. #define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART 336
  183. #define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST 80
  184. #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART 0
  185. #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST 0
  186. /* BRB thresholds for E3B0 4 port mode */
  187. #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE 304
  188. #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE 0
  189. #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE 384
  190. #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE 0
  191. #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE 10
  192. #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE 304
  193. #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE 50
  194. #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE 384
  195. /* only for E3B0*/
  196. #define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR 304
  197. #define PFC_E3B0_4P_BRB_FULL_LB_XON_THR 384
  198. #define PFC_E3B0_4P_LB_GUART 120
  199. #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART 120
  200. #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST 80
  201. #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART 80
  202. #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST 120
  203. #define DCBX_INVALID_COS (0xFF)
  204. #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
  205. #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
  206. #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS (1360)
  207. #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS (2720)
  208. #define ETS_E3B0_PBF_MIN_W_VAL (10000)
  209. #define MAX_PACKET_SIZE (9700)
  210. #define WC_UC_TIMEOUT 100
  211. /**********************************************************/
  212. /* INTERFACE */
  213. /**********************************************************/
  214. #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
  215. bnx2x_cl45_write(_bp, _phy, \
  216. (_phy)->def_md_devad, \
  217. (_bank + (_addr & 0xf)), \
  218. _val)
  219. #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
  220. bnx2x_cl45_read(_bp, _phy, \
  221. (_phy)->def_md_devad, \
  222. (_bank + (_addr & 0xf)), \
  223. _val)
  224. static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
  225. {
  226. u32 val = REG_RD(bp, reg);
  227. val |= bits;
  228. REG_WR(bp, reg, val);
  229. return val;
  230. }
  231. static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
  232. {
  233. u32 val = REG_RD(bp, reg);
  234. val &= ~bits;
  235. REG_WR(bp, reg, val);
  236. return val;
  237. }
  238. /******************************************************************/
  239. /* EPIO/GPIO section */
  240. /******************************************************************/
  241. static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
  242. {
  243. u32 epio_mask, gp_output, gp_oenable;
  244. /* Sanity check */
  245. if (epio_pin > 31) {
  246. DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
  247. return;
  248. }
  249. DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
  250. epio_mask = 1 << epio_pin;
  251. /* Set this EPIO to output */
  252. gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
  253. if (en)
  254. gp_output |= epio_mask;
  255. else
  256. gp_output &= ~epio_mask;
  257. REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
  258. /* Set the value for this EPIO */
  259. gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
  260. REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
  261. }
  262. static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
  263. {
  264. if (pin_cfg == PIN_CFG_NA)
  265. return;
  266. if (pin_cfg >= PIN_CFG_EPIO0) {
  267. bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
  268. } else {
  269. u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
  270. u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
  271. bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port);
  272. }
  273. }
  274. /******************************************************************/
  275. /* ETS section */
  276. /******************************************************************/
  277. void bnx2x_ets_disabled(struct link_params *params)
  278. {
  279. /* ETS disabled configuration*/
  280. struct bnx2x *bp = params->bp;
  281. DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
  282. /*
  283. * mapping between entry priority to client number (0,1,2 -debug and
  284. * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
  285. * 3bits client num.
  286. * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
  287. * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
  288. */
  289. REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
  290. /*
  291. * Bitmap of 5bits length. Each bit specifies whether the entry behaves
  292. * as strict. Bits 0,1,2 - debug and management entries, 3 -
  293. * COS0 entry, 4 - COS1 entry.
  294. * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
  295. * bit4 bit3 bit2 bit1 bit0
  296. * MCP and debug are strict
  297. */
  298. REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
  299. /* defines which entries (clients) are subjected to WFQ arbitration */
  300. REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
  301. /*
  302. * For strict priority entries defines the number of consecutive
  303. * slots for the highest priority.
  304. */
  305. REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
  306. /*
  307. * mapping between the CREDIT_WEIGHT registers and actual client
  308. * numbers
  309. */
  310. REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
  311. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
  312. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
  313. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
  314. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
  315. REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
  316. /* ETS mode disable */
  317. REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
  318. /*
  319. * If ETS mode is enabled (there is no strict priority) defines a WFQ
  320. * weight for COS0/COS1.
  321. */
  322. REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
  323. REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
  324. /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
  325. REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
  326. REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
  327. /* Defines the number of consecutive slots for the strict priority */
  328. REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
  329. }
  330. static void bnx2x_ets_bw_limit_common(const struct link_params *params)
  331. {
  332. /* ETS disabled configuration */
  333. struct bnx2x *bp = params->bp;
  334. DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
  335. /*
  336. * defines which entries (clients) are subjected to WFQ arbitration
  337. * COS0 0x8
  338. * COS1 0x10
  339. */
  340. REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
  341. /*
  342. * mapping between the ARB_CREDIT_WEIGHT registers and actual
  343. * client numbers (WEIGHT_0 does not actually have to represent
  344. * client 0)
  345. * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
  346. * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
  347. */
  348. REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
  349. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
  350. ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
  351. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
  352. ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
  353. /* ETS mode enabled*/
  354. REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
  355. /* Defines the number of consecutive slots for the strict priority */
  356. REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
  357. /*
  358. * Bitmap of 5bits length. Each bit specifies whether the entry behaves
  359. * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
  360. * entry, 4 - COS1 entry.
  361. * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
  362. * bit4 bit3 bit2 bit1 bit0
  363. * MCP and debug are strict
  364. */
  365. REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
  366. /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
  367. REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
  368. ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
  369. REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
  370. ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
  371. }
  372. void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
  373. const u32 cos1_bw)
  374. {
  375. /* ETS disabled configuration*/
  376. struct bnx2x *bp = params->bp;
  377. const u32 total_bw = cos0_bw + cos1_bw;
  378. u32 cos0_credit_weight = 0;
  379. u32 cos1_credit_weight = 0;
  380. DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
  381. if ((0 == total_bw) ||
  382. (0 == cos0_bw) ||
  383. (0 == cos1_bw)) {
  384. DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
  385. return;
  386. }
  387. cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
  388. total_bw;
  389. cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
  390. total_bw;
  391. bnx2x_ets_bw_limit_common(params);
  392. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
  393. REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
  394. REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
  395. REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
  396. }
  397. int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
  398. {
  399. /* ETS disabled configuration*/
  400. struct bnx2x *bp = params->bp;
  401. u32 val = 0;
  402. DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
  403. /*
  404. * Bitmap of 5bits length. Each bit specifies whether the entry behaves
  405. * as strict. Bits 0,1,2 - debug and management entries,
  406. * 3 - COS0 entry, 4 - COS1 entry.
  407. * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
  408. * bit4 bit3 bit2 bit1 bit0
  409. * MCP and debug are strict
  410. */
  411. REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
  412. /*
  413. * For strict priority entries defines the number of consecutive slots
  414. * for the highest priority.
  415. */
  416. REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
  417. /* ETS mode disable */
  418. REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
  419. /* Defines the number of consecutive slots for the strict priority */
  420. REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
  421. /* Defines the number of consecutive slots for the strict priority */
  422. REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
  423. /*
  424. * mapping between entry priority to client number (0,1,2 -debug and
  425. * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
  426. * 3bits client num.
  427. * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
  428. * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000
  429. * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000
  430. */
  431. val = (0 == strict_cos) ? 0x2318 : 0x22E0;
  432. REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
  433. return 0;
  434. }
  435. /******************************************************************/
  436. /* PFC section */
  437. /******************************************************************/
  438. static void bnx2x_update_pfc_xmac(struct link_params *params,
  439. struct link_vars *vars,
  440. u8 is_lb)
  441. {
  442. struct bnx2x *bp = params->bp;
  443. u32 xmac_base;
  444. u32 pause_val, pfc0_val, pfc1_val;
  445. /* XMAC base adrr */
  446. xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
  447. /* Initialize pause and pfc registers */
  448. pause_val = 0x18000;
  449. pfc0_val = 0xFFFF8000;
  450. pfc1_val = 0x2;
  451. /* No PFC support */
  452. if (!(params->feature_config_flags &
  453. FEATURE_CONFIG_PFC_ENABLED)) {
  454. /*
  455. * RX flow control - Process pause frame in receive direction
  456. */
  457. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
  458. pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
  459. /*
  460. * TX flow control - Send pause packet when buffer is full
  461. */
  462. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  463. pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
  464. } else {/* PFC support */
  465. pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
  466. XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
  467. XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
  468. XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
  469. }
  470. /* Write pause and PFC registers */
  471. REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
  472. REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
  473. REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
  474. udelay(30);
  475. }
  476. static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
  477. u32 pfc_frames_sent[2],
  478. u32 pfc_frames_received[2])
  479. {
  480. /* Read pfc statistic */
  481. struct bnx2x *bp = params->bp;
  482. u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
  483. NIG_REG_INGRESS_BMAC0_MEM;
  484. DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
  485. REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
  486. pfc_frames_sent, 2);
  487. REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
  488. pfc_frames_received, 2);
  489. }
  490. static void bnx2x_emac_get_pfc_stat(struct link_params *params,
  491. u32 pfc_frames_sent[2],
  492. u32 pfc_frames_received[2])
  493. {
  494. /* Read pfc statistic */
  495. struct bnx2x *bp = params->bp;
  496. u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  497. u32 val_xon = 0;
  498. u32 val_xoff = 0;
  499. DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
  500. /* PFC received frames */
  501. val_xoff = REG_RD(bp, emac_base +
  502. EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
  503. val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
  504. val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
  505. val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
  506. pfc_frames_received[0] = val_xon + val_xoff;
  507. /* PFC received sent */
  508. val_xoff = REG_RD(bp, emac_base +
  509. EMAC_REG_RX_PFC_STATS_XOFF_SENT);
  510. val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
  511. val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
  512. val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
  513. pfc_frames_sent[0] = val_xon + val_xoff;
  514. }
  515. void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
  516. u32 pfc_frames_sent[2],
  517. u32 pfc_frames_received[2])
  518. {
  519. /* Read pfc statistic */
  520. struct bnx2x *bp = params->bp;
  521. u32 val = 0;
  522. DP(NETIF_MSG_LINK, "pfc statistic\n");
  523. if (!vars->link_up)
  524. return;
  525. val = REG_RD(bp, MISC_REG_RESET_REG_2);
  526. if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
  527. == 0) {
  528. DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
  529. bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
  530. pfc_frames_received);
  531. } else {
  532. DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
  533. bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
  534. pfc_frames_received);
  535. }
  536. }
  537. /******************************************************************/
  538. /* MAC/PBF section */
  539. /******************************************************************/
  540. static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
  541. {
  542. u32 mode, emac_base;
  543. /**
  544. * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
  545. * (a value of 49==0x31) and make sure that the AUTO poll is off
  546. */
  547. if (CHIP_IS_E2(bp))
  548. emac_base = GRCBASE_EMAC0;
  549. else
  550. emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  551. mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
  552. mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
  553. EMAC_MDIO_MODE_CLOCK_CNT);
  554. if (USES_WARPCORE(bp))
  555. mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
  556. else
  557. mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
  558. mode |= (EMAC_MDIO_MODE_CLAUSE_45);
  559. REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
  560. udelay(40);
  561. }
  562. static void bnx2x_emac_init(struct link_params *params,
  563. struct link_vars *vars)
  564. {
  565. /* reset and unreset the emac core */
  566. struct bnx2x *bp = params->bp;
  567. u8 port = params->port;
  568. u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  569. u32 val;
  570. u16 timeout;
  571. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  572. (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
  573. udelay(5);
  574. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  575. (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
  576. /* init emac - use read-modify-write */
  577. /* self clear reset */
  578. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  579. EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
  580. timeout = 200;
  581. do {
  582. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  583. DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
  584. if (!timeout) {
  585. DP(NETIF_MSG_LINK, "EMAC timeout!\n");
  586. return;
  587. }
  588. timeout--;
  589. } while (val & EMAC_MODE_RESET);
  590. bnx2x_set_mdio_clk(bp, params->chip_id, port);
  591. /* Set mac address */
  592. val = ((params->mac_addr[0] << 8) |
  593. params->mac_addr[1]);
  594. EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
  595. val = ((params->mac_addr[2] << 24) |
  596. (params->mac_addr[3] << 16) |
  597. (params->mac_addr[4] << 8) |
  598. params->mac_addr[5]);
  599. EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
  600. }
  601. static void bnx2x_set_xumac_nig(struct link_params *params,
  602. u16 tx_pause_en,
  603. u8 enable)
  604. {
  605. struct bnx2x *bp = params->bp;
  606. REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
  607. enable);
  608. REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
  609. enable);
  610. REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
  611. NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
  612. }
  613. static void bnx2x_umac_enable(struct link_params *params,
  614. struct link_vars *vars, u8 lb)
  615. {
  616. u32 val;
  617. u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
  618. struct bnx2x *bp = params->bp;
  619. /* Reset UMAC */
  620. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  621. (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
  622. usleep_range(1000, 1000);
  623. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  624. (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
  625. DP(NETIF_MSG_LINK, "enabling UMAC\n");
  626. /**
  627. * This register determines on which events the MAC will assert
  628. * error on the i/f to the NIG along w/ EOP.
  629. */
  630. /**
  631. * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
  632. * params->port*0x14, 0xfffff.
  633. */
  634. /* This register opens the gate for the UMAC despite its name */
  635. REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
  636. val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
  637. UMAC_COMMAND_CONFIG_REG_PAD_EN |
  638. UMAC_COMMAND_CONFIG_REG_SW_RESET |
  639. UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
  640. switch (vars->line_speed) {
  641. case SPEED_10:
  642. val |= (0<<2);
  643. break;
  644. case SPEED_100:
  645. val |= (1<<2);
  646. break;
  647. case SPEED_1000:
  648. val |= (2<<2);
  649. break;
  650. case SPEED_2500:
  651. val |= (3<<2);
  652. break;
  653. default:
  654. DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
  655. vars->line_speed);
  656. break;
  657. }
  658. REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
  659. udelay(50);
  660. /* Enable RX and TX */
  661. val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
  662. val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
  663. UMAC_COMMAND_CONFIG_REG_RX_ENA;
  664. REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
  665. udelay(50);
  666. /* Remove SW Reset */
  667. val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
  668. /* Check loopback mode */
  669. if (lb)
  670. val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
  671. REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
  672. /*
  673. * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
  674. * length used by the MAC receive logic to check frames.
  675. */
  676. REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
  677. bnx2x_set_xumac_nig(params,
  678. ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
  679. vars->mac_type = MAC_TYPE_UMAC;
  680. }
  681. static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
  682. {
  683. u32 port4mode_ovwr_val;
  684. /* Check 4-port override enabled */
  685. port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
  686. if (port4mode_ovwr_val & (1<<0)) {
  687. /* Return 4-port mode override value */
  688. return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
  689. }
  690. /* Return 4-port mode from input pin */
  691. return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN);
  692. }
  693. /* Define the XMAC mode */
  694. static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
  695. {
  696. u32 is_port4mode = bnx2x_is_4_port_mode(bp);
  697. /**
  698. * In 4-port mode, need to set the mode only once, so if XMAC is
  699. * already out of reset, it means the mode has already been set,
  700. * and it must not* reset the XMAC again, since it controls both
  701. * ports of the path
  702. **/
  703. if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) &
  704. MISC_REGISTERS_RESET_REG_2_XMAC)) {
  705. DP(NETIF_MSG_LINK, "XMAC already out of reset"
  706. " in 4-port mode\n");
  707. return;
  708. }
  709. /* Hard reset */
  710. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  711. MISC_REGISTERS_RESET_REG_2_XMAC);
  712. usleep_range(1000, 1000);
  713. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  714. MISC_REGISTERS_RESET_REG_2_XMAC);
  715. if (is_port4mode) {
  716. DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
  717. /* Set the number of ports on the system side to up to 2 */
  718. REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
  719. /* Set the number of ports on the Warp Core to 10G */
  720. REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
  721. } else {
  722. /* Set the number of ports on the system side to 1 */
  723. REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
  724. if (max_speed == SPEED_10000) {
  725. DP(NETIF_MSG_LINK, "Init XMAC to 10G x 1"
  726. " port per path\n");
  727. /* Set the number of ports on the Warp Core to 10G */
  728. REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
  729. } else {
  730. DP(NETIF_MSG_LINK, "Init XMAC to 20G x 2 ports"
  731. " per path\n");
  732. /* Set the number of ports on the Warp Core to 20G */
  733. REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
  734. }
  735. }
  736. /* Soft reset */
  737. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  738. MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
  739. usleep_range(1000, 1000);
  740. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  741. MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
  742. }
  743. static void bnx2x_xmac_disable(struct link_params *params)
  744. {
  745. u8 port = params->port;
  746. struct bnx2x *bp = params->bp;
  747. u32 xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
  748. if (REG_RD(bp, MISC_REG_RESET_REG_2) &
  749. MISC_REGISTERS_RESET_REG_2_XMAC) {
  750. DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
  751. REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
  752. usleep_range(1000, 1000);
  753. bnx2x_set_xumac_nig(params, 0, 0);
  754. REG_WR(bp, xmac_base + XMAC_REG_CTRL,
  755. XMAC_CTRL_REG_SOFT_RESET);
  756. }
  757. }
  758. static int bnx2x_xmac_enable(struct link_params *params,
  759. struct link_vars *vars, u8 lb)
  760. {
  761. u32 val, xmac_base;
  762. struct bnx2x *bp = params->bp;
  763. DP(NETIF_MSG_LINK, "enabling XMAC\n");
  764. xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
  765. bnx2x_xmac_init(bp, vars->line_speed);
  766. /*
  767. * This register determines on which events the MAC will assert
  768. * error on the i/f to the NIG along w/ EOP.
  769. */
  770. /*
  771. * This register tells the NIG whether to send traffic to UMAC
  772. * or XMAC
  773. */
  774. REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
  775. /* Set Max packet size */
  776. REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
  777. /* CRC append for Tx packets */
  778. REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
  779. /* update PFC */
  780. bnx2x_update_pfc_xmac(params, vars, 0);
  781. /* Enable TX and RX */
  782. val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
  783. /* Check loopback mode */
  784. if (lb)
  785. val |= XMAC_CTRL_REG_CORE_LOCAL_LPBK;
  786. REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
  787. bnx2x_set_xumac_nig(params,
  788. ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
  789. vars->mac_type = MAC_TYPE_XMAC;
  790. return 0;
  791. }
  792. static int bnx2x_emac_enable(struct link_params *params,
  793. struct link_vars *vars, u8 lb)
  794. {
  795. struct bnx2x *bp = params->bp;
  796. u8 port = params->port;
  797. u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  798. u32 val;
  799. DP(NETIF_MSG_LINK, "enabling EMAC\n");
  800. /* enable emac and not bmac */
  801. REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
  802. /* ASIC */
  803. if (vars->phy_flags & PHY_XGXS_FLAG) {
  804. u32 ser_lane = ((params->lane_config &
  805. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  806. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  807. DP(NETIF_MSG_LINK, "XGXS\n");
  808. /* select the master lanes (out of 0-3) */
  809. REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
  810. /* select XGXS */
  811. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
  812. } else { /* SerDes */
  813. DP(NETIF_MSG_LINK, "SerDes\n");
  814. /* select SerDes */
  815. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
  816. }
  817. bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
  818. EMAC_RX_MODE_RESET);
  819. bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
  820. EMAC_TX_MODE_RESET);
  821. if (CHIP_REV_IS_SLOW(bp)) {
  822. /* config GMII mode */
  823. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  824. EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
  825. } else { /* ASIC */
  826. /* pause enable/disable */
  827. bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
  828. EMAC_RX_MODE_FLOW_EN);
  829. bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
  830. (EMAC_TX_MODE_EXT_PAUSE_EN |
  831. EMAC_TX_MODE_FLOW_EN));
  832. if (!(params->feature_config_flags &
  833. FEATURE_CONFIG_PFC_ENABLED)) {
  834. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
  835. bnx2x_bits_en(bp, emac_base +
  836. EMAC_REG_EMAC_RX_MODE,
  837. EMAC_RX_MODE_FLOW_EN);
  838. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  839. bnx2x_bits_en(bp, emac_base +
  840. EMAC_REG_EMAC_TX_MODE,
  841. (EMAC_TX_MODE_EXT_PAUSE_EN |
  842. EMAC_TX_MODE_FLOW_EN));
  843. } else
  844. bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
  845. EMAC_TX_MODE_FLOW_EN);
  846. }
  847. /* KEEP_VLAN_TAG, promiscuous */
  848. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
  849. val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
  850. /*
  851. * Setting this bit causes MAC control frames (except for pause
  852. * frames) to be passed on for processing. This setting has no
  853. * affect on the operation of the pause frames. This bit effects
  854. * all packets regardless of RX Parser packet sorting logic.
  855. * Turn the PFC off to make sure we are in Xon state before
  856. * enabling it.
  857. */
  858. EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
  859. if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
  860. DP(NETIF_MSG_LINK, "PFC is enabled\n");
  861. /* Enable PFC again */
  862. EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
  863. EMAC_REG_RX_PFC_MODE_RX_EN |
  864. EMAC_REG_RX_PFC_MODE_TX_EN |
  865. EMAC_REG_RX_PFC_MODE_PRIORITIES);
  866. EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
  867. ((0x0101 <<
  868. EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
  869. (0x00ff <<
  870. EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
  871. val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
  872. }
  873. EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
  874. /* Set Loopback */
  875. val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
  876. if (lb)
  877. val |= 0x810;
  878. else
  879. val &= ~0x810;
  880. EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
  881. /* enable emac */
  882. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
  883. /* enable emac for jumbo packets */
  884. EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
  885. (EMAC_RX_MTU_SIZE_JUMBO_ENA |
  886. (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
  887. /* strip CRC */
  888. REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
  889. /* disable the NIG in/out to the bmac */
  890. REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
  891. REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
  892. REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
  893. /* enable the NIG in/out to the emac */
  894. REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
  895. val = 0;
  896. if ((params->feature_config_flags &
  897. FEATURE_CONFIG_PFC_ENABLED) ||
  898. (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
  899. val = 1;
  900. REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
  901. REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
  902. REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
  903. vars->mac_type = MAC_TYPE_EMAC;
  904. return 0;
  905. }
  906. static void bnx2x_update_pfc_bmac1(struct link_params *params,
  907. struct link_vars *vars)
  908. {
  909. u32 wb_data[2];
  910. struct bnx2x *bp = params->bp;
  911. u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
  912. NIG_REG_INGRESS_BMAC0_MEM;
  913. u32 val = 0x14;
  914. if ((!(params->feature_config_flags &
  915. FEATURE_CONFIG_PFC_ENABLED)) &&
  916. (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
  917. /* Enable BigMAC to react on received Pause packets */
  918. val |= (1<<5);
  919. wb_data[0] = val;
  920. wb_data[1] = 0;
  921. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
  922. /* tx control */
  923. val = 0xc0;
  924. if (!(params->feature_config_flags &
  925. FEATURE_CONFIG_PFC_ENABLED) &&
  926. (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
  927. val |= 0x800000;
  928. wb_data[0] = val;
  929. wb_data[1] = 0;
  930. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
  931. }
  932. static void bnx2x_update_pfc_bmac2(struct link_params *params,
  933. struct link_vars *vars,
  934. u8 is_lb)
  935. {
  936. /*
  937. * Set rx control: Strip CRC and enable BigMAC to relay
  938. * control packets to the system as well
  939. */
  940. u32 wb_data[2];
  941. struct bnx2x *bp = params->bp;
  942. u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
  943. NIG_REG_INGRESS_BMAC0_MEM;
  944. u32 val = 0x14;
  945. if ((!(params->feature_config_flags &
  946. FEATURE_CONFIG_PFC_ENABLED)) &&
  947. (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
  948. /* Enable BigMAC to react on received Pause packets */
  949. val |= (1<<5);
  950. wb_data[0] = val;
  951. wb_data[1] = 0;
  952. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
  953. udelay(30);
  954. /* Tx control */
  955. val = 0xc0;
  956. if (!(params->feature_config_flags &
  957. FEATURE_CONFIG_PFC_ENABLED) &&
  958. (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
  959. val |= 0x800000;
  960. wb_data[0] = val;
  961. wb_data[1] = 0;
  962. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
  963. if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
  964. DP(NETIF_MSG_LINK, "PFC is enabled\n");
  965. /* Enable PFC RX & TX & STATS and set 8 COS */
  966. wb_data[0] = 0x0;
  967. wb_data[0] |= (1<<0); /* RX */
  968. wb_data[0] |= (1<<1); /* TX */
  969. wb_data[0] |= (1<<2); /* Force initial Xon */
  970. wb_data[0] |= (1<<3); /* 8 cos */
  971. wb_data[0] |= (1<<5); /* STATS */
  972. wb_data[1] = 0;
  973. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
  974. wb_data, 2);
  975. /* Clear the force Xon */
  976. wb_data[0] &= ~(1<<2);
  977. } else {
  978. DP(NETIF_MSG_LINK, "PFC is disabled\n");
  979. /* disable PFC RX & TX & STATS and set 8 COS */
  980. wb_data[0] = 0x8;
  981. wb_data[1] = 0;
  982. }
  983. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
  984. /*
  985. * Set Time (based unit is 512 bit time) between automatic
  986. * re-sending of PP packets amd enable automatic re-send of
  987. * Per-Priroity Packet as long as pp_gen is asserted and
  988. * pp_disable is low.
  989. */
  990. val = 0x8000;
  991. if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
  992. val |= (1<<16); /* enable automatic re-send */
  993. wb_data[0] = val;
  994. wb_data[1] = 0;
  995. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
  996. wb_data, 2);
  997. /* mac control */
  998. val = 0x3; /* Enable RX and TX */
  999. if (is_lb) {
  1000. val |= 0x4; /* Local loopback */
  1001. DP(NETIF_MSG_LINK, "enable bmac loopback\n");
  1002. }
  1003. /* When PFC enabled, Pass pause frames towards the NIG. */
  1004. if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
  1005. val |= ((1<<6)|(1<<5));
  1006. wb_data[0] = val;
  1007. wb_data[1] = 0;
  1008. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
  1009. }
  1010. /* PFC BRB internal port configuration params */
  1011. struct bnx2x_pfc_brb_threshold_val {
  1012. u32 pause_xoff;
  1013. u32 pause_xon;
  1014. u32 full_xoff;
  1015. u32 full_xon;
  1016. };
  1017. struct bnx2x_pfc_brb_e3b0_val {
  1018. u32 full_lb_xoff_th;
  1019. u32 full_lb_xon_threshold;
  1020. u32 lb_guarantied;
  1021. u32 mac_0_class_t_guarantied;
  1022. u32 mac_0_class_t_guarantied_hyst;
  1023. u32 mac_1_class_t_guarantied;
  1024. u32 mac_1_class_t_guarantied_hyst;
  1025. };
  1026. struct bnx2x_pfc_brb_th_val {
  1027. struct bnx2x_pfc_brb_threshold_val pauseable_th;
  1028. struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
  1029. };
  1030. static int bnx2x_pfc_brb_get_config_params(
  1031. struct link_params *params,
  1032. struct bnx2x_pfc_brb_th_val *config_val)
  1033. {
  1034. struct bnx2x *bp = params->bp;
  1035. DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
  1036. if (CHIP_IS_E2(bp)) {
  1037. config_val->pauseable_th.pause_xoff =
  1038. PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
  1039. config_val->pauseable_th.pause_xon =
  1040. PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
  1041. config_val->pauseable_th.full_xoff =
  1042. PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
  1043. config_val->pauseable_th.full_xon =
  1044. PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
  1045. /* non pause able*/
  1046. config_val->non_pauseable_th.pause_xoff =
  1047. PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
  1048. config_val->non_pauseable_th.pause_xon =
  1049. PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
  1050. config_val->non_pauseable_th.full_xoff =
  1051. PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
  1052. config_val->non_pauseable_th.full_xon =
  1053. PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
  1054. } else if (CHIP_IS_E3A0(bp)) {
  1055. config_val->pauseable_th.pause_xoff =
  1056. PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
  1057. config_val->pauseable_th.pause_xon =
  1058. PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
  1059. config_val->pauseable_th.full_xoff =
  1060. PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
  1061. config_val->pauseable_th.full_xon =
  1062. PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
  1063. /* non pause able*/
  1064. config_val->non_pauseable_th.pause_xoff =
  1065. PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
  1066. config_val->non_pauseable_th.pause_xon =
  1067. PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
  1068. config_val->non_pauseable_th.full_xoff =
  1069. PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
  1070. config_val->non_pauseable_th.full_xon =
  1071. PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
  1072. } else if (CHIP_IS_E3B0(bp)) {
  1073. if (params->phy[INT_PHY].flags &
  1074. FLAGS_4_PORT_MODE) {
  1075. config_val->pauseable_th.pause_xoff =
  1076. PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
  1077. config_val->pauseable_th.pause_xon =
  1078. PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
  1079. config_val->pauseable_th.full_xoff =
  1080. PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
  1081. config_val->pauseable_th.full_xon =
  1082. PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
  1083. /* non pause able*/
  1084. config_val->non_pauseable_th.pause_xoff =
  1085. PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
  1086. config_val->non_pauseable_th.pause_xon =
  1087. PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
  1088. config_val->non_pauseable_th.full_xoff =
  1089. PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
  1090. config_val->non_pauseable_th.full_xon =
  1091. PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
  1092. } else {
  1093. config_val->pauseable_th.pause_xoff =
  1094. PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
  1095. config_val->pauseable_th.pause_xon =
  1096. PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
  1097. config_val->pauseable_th.full_xoff =
  1098. PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
  1099. config_val->pauseable_th.full_xon =
  1100. PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
  1101. /* non pause able*/
  1102. config_val->non_pauseable_th.pause_xoff =
  1103. PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
  1104. config_val->non_pauseable_th.pause_xon =
  1105. PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
  1106. config_val->non_pauseable_th.full_xoff =
  1107. PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
  1108. config_val->non_pauseable_th.full_xon =
  1109. PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
  1110. }
  1111. } else
  1112. return -EINVAL;
  1113. return 0;
  1114. }
  1115. static void bnx2x_pfc_brb_get_e3b0_config_params(struct link_params *params,
  1116. struct bnx2x_pfc_brb_e3b0_val
  1117. *e3b0_val,
  1118. u32 cos0_pauseable,
  1119. u32 cos1_pauseable)
  1120. {
  1121. if (params->phy[INT_PHY].flags & FLAGS_4_PORT_MODE) {
  1122. e3b0_val->full_lb_xoff_th =
  1123. PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
  1124. e3b0_val->full_lb_xon_threshold =
  1125. PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
  1126. e3b0_val->lb_guarantied =
  1127. PFC_E3B0_4P_LB_GUART;
  1128. e3b0_val->mac_0_class_t_guarantied =
  1129. PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
  1130. e3b0_val->mac_0_class_t_guarantied_hyst =
  1131. PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
  1132. e3b0_val->mac_1_class_t_guarantied =
  1133. PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
  1134. e3b0_val->mac_1_class_t_guarantied_hyst =
  1135. PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
  1136. } else {
  1137. e3b0_val->full_lb_xoff_th =
  1138. PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
  1139. e3b0_val->full_lb_xon_threshold =
  1140. PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
  1141. e3b0_val->mac_0_class_t_guarantied_hyst =
  1142. PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
  1143. e3b0_val->mac_1_class_t_guarantied =
  1144. PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
  1145. e3b0_val->mac_1_class_t_guarantied_hyst =
  1146. PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
  1147. if (cos0_pauseable != cos1_pauseable) {
  1148. /* nonpauseable= Lossy + pauseable = Lossless*/
  1149. e3b0_val->lb_guarantied =
  1150. PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
  1151. e3b0_val->mac_0_class_t_guarantied =
  1152. PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
  1153. } else if (cos0_pauseable) {
  1154. /* Lossless +Lossless*/
  1155. e3b0_val->lb_guarantied =
  1156. PFC_E3B0_2P_PAUSE_LB_GUART;
  1157. e3b0_val->mac_0_class_t_guarantied =
  1158. PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
  1159. } else {
  1160. /* Lossy +Lossy*/
  1161. e3b0_val->lb_guarantied =
  1162. PFC_E3B0_2P_NON_PAUSE_LB_GUART;
  1163. e3b0_val->mac_0_class_t_guarantied =
  1164. PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
  1165. }
  1166. }
  1167. }
  1168. static int bnx2x_update_pfc_brb(struct link_params *params,
  1169. struct link_vars *vars,
  1170. struct bnx2x_nig_brb_pfc_port_params
  1171. *pfc_params)
  1172. {
  1173. struct bnx2x *bp = params->bp;
  1174. struct bnx2x_pfc_brb_th_val config_val = { {0} };
  1175. struct bnx2x_pfc_brb_threshold_val *reg_th_config =
  1176. &config_val.pauseable_th;
  1177. struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
  1178. int set_pfc = params->feature_config_flags &
  1179. FEATURE_CONFIG_PFC_ENABLED;
  1180. int bnx2x_status = 0;
  1181. u8 port = params->port;
  1182. /* default - pause configuration */
  1183. reg_th_config = &config_val.pauseable_th;
  1184. bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
  1185. if (0 != bnx2x_status)
  1186. return bnx2x_status;
  1187. if (set_pfc && pfc_params)
  1188. /* First COS */
  1189. if (!pfc_params->cos0_pauseable)
  1190. reg_th_config = &config_val.non_pauseable_th;
  1191. /*
  1192. * The number of free blocks below which the pause signal to class 0
  1193. * of MAC #n is asserted. n=0,1
  1194. */
  1195. REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
  1196. BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
  1197. reg_th_config->pause_xoff);
  1198. /*
  1199. * The number of free blocks above which the pause signal to class 0
  1200. * of MAC #n is de-asserted. n=0,1
  1201. */
  1202. REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
  1203. BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
  1204. /*
  1205. * The number of free blocks below which the full signal to class 0
  1206. * of MAC #n is asserted. n=0,1
  1207. */
  1208. REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
  1209. BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
  1210. /*
  1211. * The number of free blocks above which the full signal to class 0
  1212. * of MAC #n is de-asserted. n=0,1
  1213. */
  1214. REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
  1215. BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
  1216. if (set_pfc && pfc_params) {
  1217. /* Second COS */
  1218. if (pfc_params->cos1_pauseable)
  1219. reg_th_config = &config_val.pauseable_th;
  1220. else
  1221. reg_th_config = &config_val.non_pauseable_th;
  1222. /*
  1223. * The number of free blocks below which the pause signal to
  1224. * class 1 of MAC #n is asserted. n=0,1
  1225. **/
  1226. REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
  1227. BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
  1228. reg_th_config->pause_xoff);
  1229. /*
  1230. * The number of free blocks above which the pause signal to
  1231. * class 1 of MAC #n is de-asserted. n=0,1
  1232. */
  1233. REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
  1234. BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
  1235. reg_th_config->pause_xon);
  1236. /*
  1237. * The number of free blocks below which the full signal to
  1238. * class 1 of MAC #n is asserted. n=0,1
  1239. */
  1240. REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
  1241. BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
  1242. reg_th_config->full_xoff);
  1243. /*
  1244. * The number of free blocks above which the full signal to
  1245. * class 1 of MAC #n is de-asserted. n=0,1
  1246. */
  1247. REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
  1248. BRB1_REG_FULL_1_XON_THRESHOLD_0,
  1249. reg_th_config->full_xon);
  1250. if (CHIP_IS_E3B0(bp)) {
  1251. /*Should be done by init tool */
  1252. /*
  1253. * BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD
  1254. * reset value
  1255. * 944
  1256. */
  1257. /**
  1258. * The hysteresis on the guarantied buffer space for the Lb port
  1259. * before signaling XON.
  1260. **/
  1261. REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST, 80);
  1262. bnx2x_pfc_brb_get_e3b0_config_params(
  1263. params,
  1264. &e3b0_val,
  1265. pfc_params->cos0_pauseable,
  1266. pfc_params->cos1_pauseable);
  1267. /**
  1268. * The number of free blocks below which the full signal to the
  1269. * LB port is asserted.
  1270. */
  1271. REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
  1272. e3b0_val.full_lb_xoff_th);
  1273. /**
  1274. * The number of free blocks above which the full signal to the
  1275. * LB port is de-asserted.
  1276. */
  1277. REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
  1278. e3b0_val.full_lb_xon_threshold);
  1279. /**
  1280. * The number of blocks guarantied for the MAC #n port. n=0,1
  1281. */
  1282. /*The number of blocks guarantied for the LB port.*/
  1283. REG_WR(bp, BRB1_REG_LB_GUARANTIED,
  1284. e3b0_val.lb_guarantied);
  1285. /**
  1286. * The number of blocks guarantied for the MAC #n port.
  1287. */
  1288. REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
  1289. 2 * e3b0_val.mac_0_class_t_guarantied);
  1290. REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
  1291. 2 * e3b0_val.mac_1_class_t_guarantied);
  1292. /**
  1293. * The number of blocks guarantied for class #t in MAC0. t=0,1
  1294. */
  1295. REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
  1296. e3b0_val.mac_0_class_t_guarantied);
  1297. REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
  1298. e3b0_val.mac_0_class_t_guarantied);
  1299. /**
  1300. * The hysteresis on the guarantied buffer space for class in
  1301. * MAC0. t=0,1
  1302. */
  1303. REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
  1304. e3b0_val.mac_0_class_t_guarantied_hyst);
  1305. REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
  1306. e3b0_val.mac_0_class_t_guarantied_hyst);
  1307. /**
  1308. * The number of blocks guarantied for class #t in MAC1.t=0,1
  1309. */
  1310. REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
  1311. e3b0_val.mac_1_class_t_guarantied);
  1312. REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
  1313. e3b0_val.mac_1_class_t_guarantied);
  1314. /**
  1315. * The hysteresis on the guarantied buffer space for class #t
  1316. * in MAC1. t=0,1
  1317. */
  1318. REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
  1319. e3b0_val.mac_1_class_t_guarantied_hyst);
  1320. REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
  1321. e3b0_val.mac_1_class_t_guarantied_hyst);
  1322. }
  1323. }
  1324. return bnx2x_status;
  1325. }
  1326. /******************************************************************************
  1327. * Description:
  1328. * This function is needed because NIG ARB_CREDIT_WEIGHT_X are
  1329. * not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
  1330. ******************************************************************************/
  1331. int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
  1332. u8 cos_entry,
  1333. u32 priority_mask, u8 port)
  1334. {
  1335. u32 nig_reg_rx_priority_mask_add = 0;
  1336. switch (cos_entry) {
  1337. case 0:
  1338. nig_reg_rx_priority_mask_add = (port) ?
  1339. NIG_REG_P1_RX_COS0_PRIORITY_MASK :
  1340. NIG_REG_P0_RX_COS0_PRIORITY_MASK;
  1341. break;
  1342. case 1:
  1343. nig_reg_rx_priority_mask_add = (port) ?
  1344. NIG_REG_P1_RX_COS1_PRIORITY_MASK :
  1345. NIG_REG_P0_RX_COS1_PRIORITY_MASK;
  1346. break;
  1347. case 2:
  1348. nig_reg_rx_priority_mask_add = (port) ?
  1349. NIG_REG_P1_RX_COS2_PRIORITY_MASK :
  1350. NIG_REG_P0_RX_COS2_PRIORITY_MASK;
  1351. break;
  1352. case 3:
  1353. if (port)
  1354. return -EINVAL;
  1355. nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
  1356. break;
  1357. case 4:
  1358. if (port)
  1359. return -EINVAL;
  1360. nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
  1361. break;
  1362. case 5:
  1363. if (port)
  1364. return -EINVAL;
  1365. nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
  1366. break;
  1367. }
  1368. REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
  1369. return 0;
  1370. }
  1371. static void bnx2x_update_pfc_nig(struct link_params *params,
  1372. struct link_vars *vars,
  1373. struct bnx2x_nig_brb_pfc_port_params *nig_params)
  1374. {
  1375. u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
  1376. u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
  1377. u32 pkt_priority_to_cos = 0;
  1378. struct bnx2x *bp = params->bp;
  1379. u8 port = params->port;
  1380. int set_pfc = params->feature_config_flags &
  1381. FEATURE_CONFIG_PFC_ENABLED;
  1382. DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
  1383. /*
  1384. * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
  1385. * MAC control frames (that are not pause packets)
  1386. * will be forwarded to the XCM.
  1387. */
  1388. xcm_mask = REG_RD(bp,
  1389. port ? NIG_REG_LLH1_XCM_MASK :
  1390. NIG_REG_LLH0_XCM_MASK);
  1391. /*
  1392. * nig params will override non PFC params, since it's possible to
  1393. * do transition from PFC to SAFC
  1394. */
  1395. if (set_pfc) {
  1396. pause_enable = 0;
  1397. llfc_out_en = 0;
  1398. llfc_enable = 0;
  1399. if (CHIP_IS_E3(bp))
  1400. ppp_enable = 0;
  1401. else
  1402. ppp_enable = 1;
  1403. xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
  1404. NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
  1405. xcm0_out_en = 0;
  1406. p0_hwpfc_enable = 1;
  1407. } else {
  1408. if (nig_params) {
  1409. llfc_out_en = nig_params->llfc_out_en;
  1410. llfc_enable = nig_params->llfc_enable;
  1411. pause_enable = nig_params->pause_enable;
  1412. } else /*defaul non PFC mode - PAUSE */
  1413. pause_enable = 1;
  1414. xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
  1415. NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
  1416. xcm0_out_en = 1;
  1417. }
  1418. if (CHIP_IS_E3(bp))
  1419. REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
  1420. NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
  1421. REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
  1422. NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
  1423. REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
  1424. NIG_REG_LLFC_ENABLE_0, llfc_enable);
  1425. REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
  1426. NIG_REG_PAUSE_ENABLE_0, pause_enable);
  1427. REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
  1428. NIG_REG_PPP_ENABLE_0, ppp_enable);
  1429. REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
  1430. NIG_REG_LLH0_XCM_MASK, xcm_mask);
  1431. REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
  1432. /* output enable for RX_XCM # IF */
  1433. REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
  1434. /* HW PFC TX enable */
  1435. REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
  1436. if (nig_params) {
  1437. u8 i = 0;
  1438. pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
  1439. for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
  1440. bnx2x_pfc_nig_rx_priority_mask(bp, i,
  1441. nig_params->rx_cos_priority_mask[i], port);
  1442. REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
  1443. NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
  1444. nig_params->llfc_high_priority_classes);
  1445. REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
  1446. NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
  1447. nig_params->llfc_low_priority_classes);
  1448. }
  1449. REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
  1450. NIG_REG_P0_PKT_PRIORITY_TO_COS,
  1451. pkt_priority_to_cos);
  1452. }
  1453. int bnx2x_update_pfc(struct link_params *params,
  1454. struct link_vars *vars,
  1455. struct bnx2x_nig_brb_pfc_port_params *pfc_params)
  1456. {
  1457. /*
  1458. * The PFC and pause are orthogonal to one another, meaning when
  1459. * PFC is enabled, the pause are disabled, and when PFC is
  1460. * disabled, pause are set according to the pause result.
  1461. */
  1462. u32 val;
  1463. struct bnx2x *bp = params->bp;
  1464. int bnx2x_status = 0;
  1465. u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
  1466. /* update NIG params */
  1467. bnx2x_update_pfc_nig(params, vars, pfc_params);
  1468. /* update BRB params */
  1469. bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
  1470. if (0 != bnx2x_status)
  1471. return bnx2x_status;
  1472. if (!vars->link_up)
  1473. return bnx2x_status;
  1474. DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
  1475. if (CHIP_IS_E3(bp))
  1476. bnx2x_update_pfc_xmac(params, vars, 0);
  1477. else {
  1478. val = REG_RD(bp, MISC_REG_RESET_REG_2);
  1479. if ((val &
  1480. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
  1481. == 0) {
  1482. DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
  1483. bnx2x_emac_enable(params, vars, 0);
  1484. return bnx2x_status;
  1485. }
  1486. if (CHIP_IS_E2(bp))
  1487. bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
  1488. else
  1489. bnx2x_update_pfc_bmac1(params, vars);
  1490. val = 0;
  1491. if ((params->feature_config_flags &
  1492. FEATURE_CONFIG_PFC_ENABLED) ||
  1493. (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
  1494. val = 1;
  1495. REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
  1496. }
  1497. return bnx2x_status;
  1498. }
  1499. static int bnx2x_bmac1_enable(struct link_params *params,
  1500. struct link_vars *vars,
  1501. u8 is_lb)
  1502. {
  1503. struct bnx2x *bp = params->bp;
  1504. u8 port = params->port;
  1505. u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
  1506. NIG_REG_INGRESS_BMAC0_MEM;
  1507. u32 wb_data[2];
  1508. u32 val;
  1509. DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
  1510. /* XGXS control */
  1511. wb_data[0] = 0x3c;
  1512. wb_data[1] = 0;
  1513. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
  1514. wb_data, 2);
  1515. /* tx MAC SA */
  1516. wb_data[0] = ((params->mac_addr[2] << 24) |
  1517. (params->mac_addr[3] << 16) |
  1518. (params->mac_addr[4] << 8) |
  1519. params->mac_addr[5]);
  1520. wb_data[1] = ((params->mac_addr[0] << 8) |
  1521. params->mac_addr[1]);
  1522. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
  1523. /* mac control */
  1524. val = 0x3;
  1525. if (is_lb) {
  1526. val |= 0x4;
  1527. DP(NETIF_MSG_LINK, "enable bmac loopback\n");
  1528. }
  1529. wb_data[0] = val;
  1530. wb_data[1] = 0;
  1531. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
  1532. /* set rx mtu */
  1533. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  1534. wb_data[1] = 0;
  1535. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
  1536. bnx2x_update_pfc_bmac1(params, vars);
  1537. /* set tx mtu */
  1538. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  1539. wb_data[1] = 0;
  1540. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
  1541. /* set cnt max size */
  1542. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  1543. wb_data[1] = 0;
  1544. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
  1545. /* configure safc */
  1546. wb_data[0] = 0x1000200;
  1547. wb_data[1] = 0;
  1548. REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
  1549. wb_data, 2);
  1550. return 0;
  1551. }
  1552. static int bnx2x_bmac2_enable(struct link_params *params,
  1553. struct link_vars *vars,
  1554. u8 is_lb)
  1555. {
  1556. struct bnx2x *bp = params->bp;
  1557. u8 port = params->port;
  1558. u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
  1559. NIG_REG_INGRESS_BMAC0_MEM;
  1560. u32 wb_data[2];
  1561. DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
  1562. wb_data[0] = 0;
  1563. wb_data[1] = 0;
  1564. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
  1565. udelay(30);
  1566. /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
  1567. wb_data[0] = 0x3c;
  1568. wb_data[1] = 0;
  1569. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
  1570. wb_data, 2);
  1571. udelay(30);
  1572. /* tx MAC SA */
  1573. wb_data[0] = ((params->mac_addr[2] << 24) |
  1574. (params->mac_addr[3] << 16) |
  1575. (params->mac_addr[4] << 8) |
  1576. params->mac_addr[5]);
  1577. wb_data[1] = ((params->mac_addr[0] << 8) |
  1578. params->mac_addr[1]);
  1579. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
  1580. wb_data, 2);
  1581. udelay(30);
  1582. /* Configure SAFC */
  1583. wb_data[0] = 0x1000200;
  1584. wb_data[1] = 0;
  1585. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
  1586. wb_data, 2);
  1587. udelay(30);
  1588. /* set rx mtu */
  1589. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  1590. wb_data[1] = 0;
  1591. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
  1592. udelay(30);
  1593. /* set tx mtu */
  1594. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
  1595. wb_data[1] = 0;
  1596. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
  1597. udelay(30);
  1598. /* set cnt max size */
  1599. wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
  1600. wb_data[1] = 0;
  1601. REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
  1602. udelay(30);
  1603. bnx2x_update_pfc_bmac2(params, vars, is_lb);
  1604. return 0;
  1605. }
  1606. static int bnx2x_bmac_enable(struct link_params *params,
  1607. struct link_vars *vars,
  1608. u8 is_lb)
  1609. {
  1610. int rc = 0;
  1611. u8 port = params->port;
  1612. struct bnx2x *bp = params->bp;
  1613. u32 val;
  1614. /* reset and unreset the BigMac */
  1615. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  1616. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  1617. msleep(1);
  1618. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
  1619. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  1620. /* enable access for bmac registers */
  1621. REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
  1622. /* Enable BMAC according to BMAC type*/
  1623. if (CHIP_IS_E2(bp))
  1624. rc = bnx2x_bmac2_enable(params, vars, is_lb);
  1625. else
  1626. rc = bnx2x_bmac1_enable(params, vars, is_lb);
  1627. REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
  1628. REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
  1629. REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
  1630. val = 0;
  1631. if ((params->feature_config_flags &
  1632. FEATURE_CONFIG_PFC_ENABLED) ||
  1633. (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
  1634. val = 1;
  1635. REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
  1636. REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
  1637. REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
  1638. REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
  1639. REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
  1640. REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
  1641. vars->mac_type = MAC_TYPE_BMAC;
  1642. return rc;
  1643. }
  1644. static void bnx2x_update_mng(struct link_params *params, u32 link_status)
  1645. {
  1646. struct bnx2x *bp = params->bp;
  1647. REG_WR(bp, params->shmem_base +
  1648. offsetof(struct shmem_region,
  1649. port_mb[params->port].link_status), link_status);
  1650. }
  1651. static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
  1652. {
  1653. u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
  1654. NIG_REG_INGRESS_BMAC0_MEM;
  1655. u32 wb_data[2];
  1656. u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
  1657. /* Only if the bmac is out of reset */
  1658. if (REG_RD(bp, MISC_REG_RESET_REG_2) &
  1659. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
  1660. nig_bmac_enable) {
  1661. if (CHIP_IS_E2(bp)) {
  1662. /* Clear Rx Enable bit in BMAC_CONTROL register */
  1663. REG_RD_DMAE(bp, bmac_addr +
  1664. BIGMAC2_REGISTER_BMAC_CONTROL,
  1665. wb_data, 2);
  1666. wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
  1667. REG_WR_DMAE(bp, bmac_addr +
  1668. BIGMAC2_REGISTER_BMAC_CONTROL,
  1669. wb_data, 2);
  1670. } else {
  1671. /* Clear Rx Enable bit in BMAC_CONTROL register */
  1672. REG_RD_DMAE(bp, bmac_addr +
  1673. BIGMAC_REGISTER_BMAC_CONTROL,
  1674. wb_data, 2);
  1675. wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
  1676. REG_WR_DMAE(bp, bmac_addr +
  1677. BIGMAC_REGISTER_BMAC_CONTROL,
  1678. wb_data, 2);
  1679. }
  1680. msleep(1);
  1681. }
  1682. }
  1683. static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
  1684. u32 line_speed)
  1685. {
  1686. struct bnx2x *bp = params->bp;
  1687. u8 port = params->port;
  1688. u32 init_crd, crd;
  1689. u32 count = 1000;
  1690. /* disable port */
  1691. REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
  1692. /* wait for init credit */
  1693. init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
  1694. crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
  1695. DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
  1696. while ((init_crd != crd) && count) {
  1697. msleep(5);
  1698. crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
  1699. count--;
  1700. }
  1701. crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
  1702. if (init_crd != crd) {
  1703. DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
  1704. init_crd, crd);
  1705. return -EINVAL;
  1706. }
  1707. if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
  1708. line_speed == SPEED_10 ||
  1709. line_speed == SPEED_100 ||
  1710. line_speed == SPEED_1000 ||
  1711. line_speed == SPEED_2500) {
  1712. REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
  1713. /* update threshold */
  1714. REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
  1715. /* update init credit */
  1716. init_crd = 778; /* (800-18-4) */
  1717. } else {
  1718. u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
  1719. ETH_OVREHEAD)/16;
  1720. REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
  1721. /* update threshold */
  1722. REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
  1723. /* update init credit */
  1724. switch (line_speed) {
  1725. case SPEED_10000:
  1726. init_crd = thresh + 553 - 22;
  1727. break;
  1728. default:
  1729. DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
  1730. line_speed);
  1731. return -EINVAL;
  1732. }
  1733. }
  1734. REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
  1735. DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
  1736. line_speed, init_crd);
  1737. /* probe the credit changes */
  1738. REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
  1739. msleep(5);
  1740. REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
  1741. /* enable port */
  1742. REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
  1743. return 0;
  1744. }
  1745. /**
  1746. * bnx2x_get_emac_base - retrive emac base address
  1747. *
  1748. * @bp: driver handle
  1749. * @mdc_mdio_access: access type
  1750. * @port: port id
  1751. *
  1752. * This function selects the MDC/MDIO access (through emac0 or
  1753. * emac1) depend on the mdc_mdio_access, port, port swapped. Each
  1754. * phy has a default access mode, which could also be overridden
  1755. * by nvram configuration. This parameter, whether this is the
  1756. * default phy configuration, or the nvram overrun
  1757. * configuration, is passed here as mdc_mdio_access and selects
  1758. * the emac_base for the CL45 read/writes operations
  1759. */
  1760. static u32 bnx2x_get_emac_base(struct bnx2x *bp,
  1761. u32 mdc_mdio_access, u8 port)
  1762. {
  1763. u32 emac_base = 0;
  1764. switch (mdc_mdio_access) {
  1765. case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
  1766. break;
  1767. case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
  1768. if (REG_RD(bp, NIG_REG_PORT_SWAP))
  1769. emac_base = GRCBASE_EMAC1;
  1770. else
  1771. emac_base = GRCBASE_EMAC0;
  1772. break;
  1773. case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
  1774. if (REG_RD(bp, NIG_REG_PORT_SWAP))
  1775. emac_base = GRCBASE_EMAC0;
  1776. else
  1777. emac_base = GRCBASE_EMAC1;
  1778. break;
  1779. case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
  1780. emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  1781. break;
  1782. case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
  1783. emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
  1784. break;
  1785. default:
  1786. break;
  1787. }
  1788. return emac_base;
  1789. }
  1790. /******************************************************************/
  1791. /* CL22 access functions */
  1792. /******************************************************************/
  1793. static int bnx2x_cl22_write(struct bnx2x *bp,
  1794. struct bnx2x_phy *phy,
  1795. u16 reg, u16 val)
  1796. {
  1797. u32 tmp, mode;
  1798. u8 i;
  1799. int rc = 0;
  1800. /* Switch to CL22 */
  1801. mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
  1802. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
  1803. mode & ~EMAC_MDIO_MODE_CLAUSE_45);
  1804. /* address */
  1805. tmp = ((phy->addr << 21) | (reg << 16) | val |
  1806. EMAC_MDIO_COMM_COMMAND_WRITE_22 |
  1807. EMAC_MDIO_COMM_START_BUSY);
  1808. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
  1809. for (i = 0; i < 50; i++) {
  1810. udelay(10);
  1811. tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
  1812. if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
  1813. udelay(5);
  1814. break;
  1815. }
  1816. }
  1817. if (tmp & EMAC_MDIO_COMM_START_BUSY) {
  1818. DP(NETIF_MSG_LINK, "write phy register failed\n");
  1819. rc = -EFAULT;
  1820. }
  1821. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
  1822. return rc;
  1823. }
  1824. static int bnx2x_cl22_read(struct bnx2x *bp,
  1825. struct bnx2x_phy *phy,
  1826. u16 reg, u16 *ret_val)
  1827. {
  1828. u32 val, mode;
  1829. u16 i;
  1830. int rc = 0;
  1831. /* Switch to CL22 */
  1832. mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
  1833. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
  1834. mode & ~EMAC_MDIO_MODE_CLAUSE_45);
  1835. /* address */
  1836. val = ((phy->addr << 21) | (reg << 16) |
  1837. EMAC_MDIO_COMM_COMMAND_READ_22 |
  1838. EMAC_MDIO_COMM_START_BUSY);
  1839. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
  1840. for (i = 0; i < 50; i++) {
  1841. udelay(10);
  1842. val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
  1843. if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
  1844. *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
  1845. udelay(5);
  1846. break;
  1847. }
  1848. }
  1849. if (val & EMAC_MDIO_COMM_START_BUSY) {
  1850. DP(NETIF_MSG_LINK, "read phy register failed\n");
  1851. *ret_val = 0;
  1852. rc = -EFAULT;
  1853. }
  1854. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
  1855. return rc;
  1856. }
  1857. /******************************************************************/
  1858. /* CL45 access functions */
  1859. /******************************************************************/
  1860. static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
  1861. u8 devad, u16 reg, u16 *ret_val)
  1862. {
  1863. u32 val;
  1864. u16 i;
  1865. int rc = 0;
  1866. /* address */
  1867. val = ((phy->addr << 21) | (devad << 16) | reg |
  1868. EMAC_MDIO_COMM_COMMAND_ADDRESS |
  1869. EMAC_MDIO_COMM_START_BUSY);
  1870. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
  1871. for (i = 0; i < 50; i++) {
  1872. udelay(10);
  1873. val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
  1874. if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
  1875. udelay(5);
  1876. break;
  1877. }
  1878. }
  1879. if (val & EMAC_MDIO_COMM_START_BUSY) {
  1880. DP(NETIF_MSG_LINK, "read phy register failed\n");
  1881. netdev_err(bp->dev, "MDC/MDIO access timeout\n");
  1882. *ret_val = 0;
  1883. rc = -EFAULT;
  1884. } else {
  1885. /* data */
  1886. val = ((phy->addr << 21) | (devad << 16) |
  1887. EMAC_MDIO_COMM_COMMAND_READ_45 |
  1888. EMAC_MDIO_COMM_START_BUSY);
  1889. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
  1890. for (i = 0; i < 50; i++) {
  1891. udelay(10);
  1892. val = REG_RD(bp, phy->mdio_ctrl +
  1893. EMAC_REG_EMAC_MDIO_COMM);
  1894. if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
  1895. *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
  1896. break;
  1897. }
  1898. }
  1899. if (val & EMAC_MDIO_COMM_START_BUSY) {
  1900. DP(NETIF_MSG_LINK, "read phy register failed\n");
  1901. netdev_err(bp->dev, "MDC/MDIO access timeout\n");
  1902. *ret_val = 0;
  1903. rc = -EFAULT;
  1904. }
  1905. }
  1906. /* Work around for E3 A0 */
  1907. if (phy->flags & FLAGS_MDC_MDIO_WA) {
  1908. phy->flags ^= FLAGS_DUMMY_READ;
  1909. if (phy->flags & FLAGS_DUMMY_READ) {
  1910. u16 temp_val;
  1911. bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
  1912. }
  1913. }
  1914. return rc;
  1915. }
  1916. static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
  1917. u8 devad, u16 reg, u16 val)
  1918. {
  1919. u32 tmp;
  1920. u8 i;
  1921. int rc = 0;
  1922. /* address */
  1923. tmp = ((phy->addr << 21) | (devad << 16) | reg |
  1924. EMAC_MDIO_COMM_COMMAND_ADDRESS |
  1925. EMAC_MDIO_COMM_START_BUSY);
  1926. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
  1927. for (i = 0; i < 50; i++) {
  1928. udelay(10);
  1929. tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
  1930. if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
  1931. udelay(5);
  1932. break;
  1933. }
  1934. }
  1935. if (tmp & EMAC_MDIO_COMM_START_BUSY) {
  1936. DP(NETIF_MSG_LINK, "write phy register failed\n");
  1937. netdev_err(bp->dev, "MDC/MDIO access timeout\n");
  1938. rc = -EFAULT;
  1939. } else {
  1940. /* data */
  1941. tmp = ((phy->addr << 21) | (devad << 16) | val |
  1942. EMAC_MDIO_COMM_COMMAND_WRITE_45 |
  1943. EMAC_MDIO_COMM_START_BUSY);
  1944. REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
  1945. for (i = 0; i < 50; i++) {
  1946. udelay(10);
  1947. tmp = REG_RD(bp, phy->mdio_ctrl +
  1948. EMAC_REG_EMAC_MDIO_COMM);
  1949. if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
  1950. udelay(5);
  1951. break;
  1952. }
  1953. }
  1954. if (tmp & EMAC_MDIO_COMM_START_BUSY) {
  1955. DP(NETIF_MSG_LINK, "write phy register failed\n");
  1956. netdev_err(bp->dev, "MDC/MDIO access timeout\n");
  1957. rc = -EFAULT;
  1958. }
  1959. }
  1960. /* Work around for E3 A0 */
  1961. if (phy->flags & FLAGS_MDC_MDIO_WA) {
  1962. phy->flags ^= FLAGS_DUMMY_READ;
  1963. if (phy->flags & FLAGS_DUMMY_READ) {
  1964. u16 temp_val;
  1965. bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
  1966. }
  1967. }
  1968. return rc;
  1969. }
  1970. /******************************************************************/
  1971. /* BSC access functions from E3 */
  1972. /******************************************************************/
  1973. static void bnx2x_bsc_module_sel(struct link_params *params)
  1974. {
  1975. int idx;
  1976. u32 board_cfg, sfp_ctrl;
  1977. u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
  1978. struct bnx2x *bp = params->bp;
  1979. u8 port = params->port;
  1980. /* Read I2C output PINs */
  1981. board_cfg = REG_RD(bp, params->shmem_base +
  1982. offsetof(struct shmem_region,
  1983. dev_info.shared_hw_config.board));
  1984. i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
  1985. i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
  1986. SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
  1987. /* Read I2C output value */
  1988. sfp_ctrl = REG_RD(bp, params->shmem_base +
  1989. offsetof(struct shmem_region,
  1990. dev_info.port_hw_config[port].e3_cmn_pin_cfg));
  1991. i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
  1992. i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
  1993. DP(NETIF_MSG_LINK, "Setting BSC switch\n");
  1994. for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
  1995. bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
  1996. }
  1997. static int bnx2x_bsc_read(struct link_params *params,
  1998. struct bnx2x_phy *phy,
  1999. u8 sl_devid,
  2000. u16 sl_addr,
  2001. u8 lc_addr,
  2002. u8 xfer_cnt,
  2003. u32 *data_array)
  2004. {
  2005. u32 val, i;
  2006. int rc = 0;
  2007. struct bnx2x *bp = params->bp;
  2008. if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
  2009. DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
  2010. return -EINVAL;
  2011. }
  2012. if (xfer_cnt > 16) {
  2013. DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
  2014. xfer_cnt);
  2015. return -EINVAL;
  2016. }
  2017. bnx2x_bsc_module_sel(params);
  2018. xfer_cnt = 16 - lc_addr;
  2019. /* enable the engine */
  2020. val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
  2021. val |= MCPR_IMC_COMMAND_ENABLE;
  2022. REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
  2023. /* program slave device ID */
  2024. val = (sl_devid << 16) | sl_addr;
  2025. REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
  2026. /* start xfer with 0 byte to update the address pointer ???*/
  2027. val = (MCPR_IMC_COMMAND_ENABLE) |
  2028. (MCPR_IMC_COMMAND_WRITE_OP <<
  2029. MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
  2030. (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
  2031. REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
  2032. /* poll for completion */
  2033. i = 0;
  2034. val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
  2035. while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
  2036. udelay(10);
  2037. val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
  2038. if (i++ > 1000) {
  2039. DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
  2040. i);
  2041. rc = -EFAULT;
  2042. break;
  2043. }
  2044. }
  2045. if (rc == -EFAULT)
  2046. return rc;
  2047. /* start xfer with read op */
  2048. val = (MCPR_IMC_COMMAND_ENABLE) |
  2049. (MCPR_IMC_COMMAND_READ_OP <<
  2050. MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
  2051. (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
  2052. (xfer_cnt);
  2053. REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
  2054. /* poll for completion */
  2055. i = 0;
  2056. val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
  2057. while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
  2058. udelay(10);
  2059. val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
  2060. if (i++ > 1000) {
  2061. DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
  2062. rc = -EFAULT;
  2063. break;
  2064. }
  2065. }
  2066. if (rc == -EFAULT)
  2067. return rc;
  2068. for (i = (lc_addr >> 2); i < 4; i++) {
  2069. data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
  2070. #ifdef __BIG_ENDIAN
  2071. data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
  2072. ((data_array[i] & 0x0000ff00) << 8) |
  2073. ((data_array[i] & 0x00ff0000) >> 8) |
  2074. ((data_array[i] & 0xff000000) >> 24);
  2075. #endif
  2076. }
  2077. return rc;
  2078. }
  2079. static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
  2080. u8 devad, u16 reg, u16 or_val)
  2081. {
  2082. u16 val;
  2083. bnx2x_cl45_read(bp, phy, devad, reg, &val);
  2084. bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
  2085. }
  2086. int bnx2x_phy_read(struct link_params *params, u8 phy_addr,
  2087. u8 devad, u16 reg, u16 *ret_val)
  2088. {
  2089. u8 phy_index;
  2090. /*
  2091. * Probe for the phy according to the given phy_addr, and execute
  2092. * the read request on it
  2093. */
  2094. for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
  2095. if (params->phy[phy_index].addr == phy_addr) {
  2096. return bnx2x_cl45_read(params->bp,
  2097. &params->phy[phy_index], devad,
  2098. reg, ret_val);
  2099. }
  2100. }
  2101. return -EINVAL;
  2102. }
  2103. int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
  2104. u8 devad, u16 reg, u16 val)
  2105. {
  2106. u8 phy_index;
  2107. /*
  2108. * Probe for the phy according to the given phy_addr, and execute
  2109. * the write request on it
  2110. */
  2111. for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
  2112. if (params->phy[phy_index].addr == phy_addr) {
  2113. return bnx2x_cl45_write(params->bp,
  2114. &params->phy[phy_index], devad,
  2115. reg, val);
  2116. }
  2117. }
  2118. return -EINVAL;
  2119. }
  2120. static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
  2121. struct link_params *params)
  2122. {
  2123. u8 lane = 0;
  2124. struct bnx2x *bp = params->bp;
  2125. u32 path_swap, path_swap_ovr;
  2126. u8 path, port;
  2127. path = BP_PATH(bp);
  2128. port = params->port;
  2129. if (bnx2x_is_4_port_mode(bp)) {
  2130. u32 port_swap, port_swap_ovr;
  2131. /*figure out path swap value */
  2132. path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
  2133. if (path_swap_ovr & 0x1)
  2134. path_swap = (path_swap_ovr & 0x2);
  2135. else
  2136. path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
  2137. if (path_swap)
  2138. path = path ^ 1;
  2139. /*figure out port swap value */
  2140. port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
  2141. if (port_swap_ovr & 0x1)
  2142. port_swap = (port_swap_ovr & 0x2);
  2143. else
  2144. port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
  2145. if (port_swap)
  2146. port = port ^ 1;
  2147. lane = (port<<1) + path;
  2148. } else { /* two port mode - no port swap */
  2149. /*figure out path swap value */
  2150. path_swap_ovr =
  2151. REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
  2152. if (path_swap_ovr & 0x1) {
  2153. path_swap = (path_swap_ovr & 0x2);
  2154. } else {
  2155. path_swap =
  2156. REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
  2157. }
  2158. if (path_swap)
  2159. path = path ^ 1;
  2160. lane = path << 1 ;
  2161. }
  2162. return lane;
  2163. }
  2164. static void bnx2x_set_aer_mmd(struct link_params *params,
  2165. struct bnx2x_phy *phy)
  2166. {
  2167. u32 ser_lane;
  2168. u16 offset, aer_val;
  2169. struct bnx2x *bp = params->bp;
  2170. ser_lane = ((params->lane_config &
  2171. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  2172. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  2173. offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
  2174. (phy->addr + ser_lane) : 0;
  2175. if (USES_WARPCORE(bp)) {
  2176. aer_val = bnx2x_get_warpcore_lane(phy, params);
  2177. /*
  2178. * In Dual-lane mode, two lanes are joined together,
  2179. * so in order to configure them, the AER broadcast method is
  2180. * used here.
  2181. * 0x200 is the broadcast address for lanes 0,1
  2182. * 0x201 is the broadcast address for lanes 2,3
  2183. */
  2184. if (phy->flags & FLAGS_WC_DUAL_MODE)
  2185. aer_val = (aer_val >> 1) | 0x200;
  2186. } else if (CHIP_IS_E2(bp))
  2187. aer_val = 0x3800 + offset - 1;
  2188. else
  2189. aer_val = 0x3800 + offset;
  2190. DP(NETIF_MSG_LINK, "Set AER to 0x%x\n", aer_val);
  2191. CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
  2192. MDIO_AER_BLOCK_AER_REG, aer_val);
  2193. }
  2194. /******************************************************************/
  2195. /* Internal phy section */
  2196. /******************************************************************/
  2197. static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
  2198. {
  2199. u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  2200. /* Set Clause 22 */
  2201. REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
  2202. REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
  2203. udelay(500);
  2204. REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
  2205. udelay(500);
  2206. /* Set Clause 45 */
  2207. REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
  2208. }
  2209. static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
  2210. {
  2211. u32 val;
  2212. DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
  2213. val = SERDES_RESET_BITS << (port*16);
  2214. /* reset and unreset the SerDes/XGXS */
  2215. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
  2216. udelay(500);
  2217. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
  2218. bnx2x_set_serdes_access(bp, port);
  2219. REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
  2220. DEFAULT_PHY_DEV_ADDR);
  2221. }
  2222. static void bnx2x_xgxs_deassert(struct link_params *params)
  2223. {
  2224. struct bnx2x *bp = params->bp;
  2225. u8 port;
  2226. u32 val;
  2227. DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
  2228. port = params->port;
  2229. val = XGXS_RESET_BITS << (port*16);
  2230. /* reset and unreset the SerDes/XGXS */
  2231. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
  2232. udelay(500);
  2233. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
  2234. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
  2235. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
  2236. params->phy[INT_PHY].def_md_devad);
  2237. }
  2238. static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
  2239. struct link_params *params, u16 *ieee_fc)
  2240. {
  2241. struct bnx2x *bp = params->bp;
  2242. *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
  2243. /**
  2244. * resolve pause mode and advertisement Please refer to Table
  2245. * 28B-3 of the 802.3ab-1999 spec
  2246. */
  2247. switch (phy->req_flow_ctrl) {
  2248. case BNX2X_FLOW_CTRL_AUTO:
  2249. if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
  2250. *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  2251. else
  2252. *ieee_fc |=
  2253. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
  2254. break;
  2255. case BNX2X_FLOW_CTRL_TX:
  2256. *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
  2257. break;
  2258. case BNX2X_FLOW_CTRL_RX:
  2259. case BNX2X_FLOW_CTRL_BOTH:
  2260. *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  2261. break;
  2262. case BNX2X_FLOW_CTRL_NONE:
  2263. default:
  2264. *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
  2265. break;
  2266. }
  2267. DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
  2268. }
  2269. static void set_phy_vars(struct link_params *params,
  2270. struct link_vars *vars)
  2271. {
  2272. struct bnx2x *bp = params->bp;
  2273. u8 actual_phy_idx, phy_index, link_cfg_idx;
  2274. u8 phy_config_swapped = params->multi_phy_config &
  2275. PORT_HW_CFG_PHY_SWAPPED_ENABLED;
  2276. for (phy_index = INT_PHY; phy_index < params->num_phys;
  2277. phy_index++) {
  2278. link_cfg_idx = LINK_CONFIG_IDX(phy_index);
  2279. actual_phy_idx = phy_index;
  2280. if (phy_config_swapped) {
  2281. if (phy_index == EXT_PHY1)
  2282. actual_phy_idx = EXT_PHY2;
  2283. else if (phy_index == EXT_PHY2)
  2284. actual_phy_idx = EXT_PHY1;
  2285. }
  2286. params->phy[actual_phy_idx].req_flow_ctrl =
  2287. params->req_flow_ctrl[link_cfg_idx];
  2288. params->phy[actual_phy_idx].req_line_speed =
  2289. params->req_line_speed[link_cfg_idx];
  2290. params->phy[actual_phy_idx].speed_cap_mask =
  2291. params->speed_cap_mask[link_cfg_idx];
  2292. params->phy[actual_phy_idx].req_duplex =
  2293. params->req_duplex[link_cfg_idx];
  2294. if (params->req_line_speed[link_cfg_idx] ==
  2295. SPEED_AUTO_NEG)
  2296. vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
  2297. DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
  2298. " speed_cap_mask %x\n",
  2299. params->phy[actual_phy_idx].req_flow_ctrl,
  2300. params->phy[actual_phy_idx].req_line_speed,
  2301. params->phy[actual_phy_idx].speed_cap_mask);
  2302. }
  2303. }
  2304. static void bnx2x_ext_phy_set_pause(struct link_params *params,
  2305. struct bnx2x_phy *phy,
  2306. struct link_vars *vars)
  2307. {
  2308. u16 val;
  2309. struct bnx2x *bp = params->bp;
  2310. /* read modify write pause advertizing */
  2311. bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
  2312. val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
  2313. /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
  2314. bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
  2315. if ((vars->ieee_fc &
  2316. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
  2317. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
  2318. val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
  2319. }
  2320. if ((vars->ieee_fc &
  2321. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
  2322. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
  2323. val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
  2324. }
  2325. DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
  2326. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
  2327. }
  2328. static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
  2329. { /* LD LP */
  2330. switch (pause_result) { /* ASYM P ASYM P */
  2331. case 0xb: /* 1 0 1 1 */
  2332. vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
  2333. break;
  2334. case 0xe: /* 1 1 1 0 */
  2335. vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
  2336. break;
  2337. case 0x5: /* 0 1 0 1 */
  2338. case 0x7: /* 0 1 1 1 */
  2339. case 0xd: /* 1 1 0 1 */
  2340. case 0xf: /* 1 1 1 1 */
  2341. vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
  2342. break;
  2343. default:
  2344. break;
  2345. }
  2346. if (pause_result & (1<<0))
  2347. vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
  2348. if (pause_result & (1<<1))
  2349. vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
  2350. }
  2351. static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
  2352. struct link_params *params,
  2353. struct link_vars *vars)
  2354. {
  2355. struct bnx2x *bp = params->bp;
  2356. u16 ld_pause; /* local */
  2357. u16 lp_pause; /* link partner */
  2358. u16 pause_result;
  2359. u8 ret = 0;
  2360. /* read twice */
  2361. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  2362. if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
  2363. vars->flow_ctrl = phy->req_flow_ctrl;
  2364. else if (phy->req_line_speed != SPEED_AUTO_NEG)
  2365. vars->flow_ctrl = params->req_fc_auto_adv;
  2366. else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
  2367. ret = 1;
  2368. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) {
  2369. bnx2x_cl22_read(bp, phy,
  2370. 0x4, &ld_pause);
  2371. bnx2x_cl22_read(bp, phy,
  2372. 0x5, &lp_pause);
  2373. } else {
  2374. bnx2x_cl45_read(bp, phy,
  2375. MDIO_AN_DEVAD,
  2376. MDIO_AN_REG_ADV_PAUSE, &ld_pause);
  2377. bnx2x_cl45_read(bp, phy,
  2378. MDIO_AN_DEVAD,
  2379. MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
  2380. }
  2381. pause_result = (ld_pause &
  2382. MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
  2383. pause_result |= (lp_pause &
  2384. MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
  2385. DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
  2386. pause_result);
  2387. bnx2x_pause_resolve(vars, pause_result);
  2388. }
  2389. return ret;
  2390. }
  2391. /******************************************************************/
  2392. /* Warpcore section */
  2393. /******************************************************************/
  2394. /* The init_internal_warpcore should mirror the xgxs,
  2395. * i.e. reset the lane (if needed), set aer for the
  2396. * init configuration, and set/clear SGMII flag. Internal
  2397. * phy init is done purely in phy_init stage.
  2398. */
  2399. static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
  2400. struct link_params *params,
  2401. struct link_vars *vars) {
  2402. u16 val16 = 0, lane;
  2403. struct bnx2x *bp = params->bp;
  2404. DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
  2405. /* Check adding advertisement for 1G KX */
  2406. if (((vars->line_speed == SPEED_AUTO_NEG) &&
  2407. (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
  2408. (vars->line_speed == SPEED_1000)) {
  2409. u16 sd_digital;
  2410. val16 |= (1<<5);
  2411. /* Enable CL37 1G Parallel Detect */
  2412. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2413. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
  2414. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2415. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
  2416. (sd_digital | 0x1));
  2417. DP(NETIF_MSG_LINK, "Advertize 1G\n");
  2418. }
  2419. if (((vars->line_speed == SPEED_AUTO_NEG) &&
  2420. (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
  2421. (vars->line_speed == SPEED_10000)) {
  2422. /* Check adding advertisement for 10G KR */
  2423. val16 |= (1<<7);
  2424. /* Enable 10G Parallel Detect */
  2425. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
  2426. MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
  2427. DP(NETIF_MSG_LINK, "Advertize 10G\n");
  2428. }
  2429. /* Set Transmit PMD settings */
  2430. lane = bnx2x_get_warpcore_lane(phy, params);
  2431. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2432. MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
  2433. ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
  2434. (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
  2435. (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
  2436. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2437. MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
  2438. 0x03f0);
  2439. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2440. MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
  2441. 0x03f0);
  2442. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2443. MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
  2444. 0x383f);
  2445. /* Advertised speeds */
  2446. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
  2447. MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
  2448. /* Advertise pause */
  2449. bnx2x_ext_phy_set_pause(params, phy, vars);
  2450. /* Enable Autoneg */
  2451. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
  2452. MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
  2453. /* Over 1G - AN local device user page 1 */
  2454. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2455. MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
  2456. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2457. MDIO_WC_REG_DIGITAL5_MISC7, &val16);
  2458. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2459. MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
  2460. }
  2461. static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
  2462. struct link_params *params,
  2463. struct link_vars *vars)
  2464. {
  2465. struct bnx2x *bp = params->bp;
  2466. u16 val;
  2467. /* Disable Autoneg */
  2468. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2469. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
  2470. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
  2471. MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
  2472. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2473. MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
  2474. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
  2475. MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
  2476. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
  2477. MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
  2478. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2479. MDIO_WC_REG_DIGITAL3_UP1, 0x1);
  2480. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2481. MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
  2482. /* Disable CL36 PCS Tx */
  2483. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2484. MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
  2485. /* Double Wide Single Data Rate @ pll rate */
  2486. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2487. MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
  2488. /* Leave cl72 training enable, needed for KR */
  2489. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
  2490. MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
  2491. 0x2);
  2492. /* Leave CL72 enabled */
  2493. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2494. MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
  2495. &val);
  2496. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2497. MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
  2498. val | 0x3800);
  2499. /* Set speed via PMA/PMD register */
  2500. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
  2501. MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
  2502. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
  2503. MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
  2504. /*Enable encoded forced speed */
  2505. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2506. MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
  2507. /* Turn TX scramble payload only the 64/66 scrambler */
  2508. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2509. MDIO_WC_REG_TX66_CONTROL, 0x9);
  2510. /* Turn RX scramble payload only the 64/66 scrambler */
  2511. bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
  2512. MDIO_WC_REG_RX66_CONTROL, 0xF9);
  2513. /* set and clear loopback to cause a reset to 64/66 decoder */
  2514. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2515. MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
  2516. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2517. MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
  2518. }
  2519. static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
  2520. struct link_params *params,
  2521. u8 is_xfi)
  2522. {
  2523. struct bnx2x *bp = params->bp;
  2524. u16 misc1_val, tap_val, tx_driver_val, lane, val;
  2525. /* Hold rxSeqStart */
  2526. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2527. MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
  2528. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2529. MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
  2530. /* Hold tx_fifo_reset */
  2531. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2532. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
  2533. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2534. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
  2535. /* Disable CL73 AN */
  2536. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
  2537. /* Disable 100FX Enable and Auto-Detect */
  2538. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2539. MDIO_WC_REG_FX100_CTRL1, &val);
  2540. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2541. MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
  2542. /* Disable 100FX Idle detect */
  2543. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2544. MDIO_WC_REG_FX100_CTRL3, &val);
  2545. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2546. MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
  2547. /* Set Block address to Remote PHY & Clear forced_speed[5] */
  2548. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2549. MDIO_WC_REG_DIGITAL4_MISC3, &val);
  2550. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2551. MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
  2552. /* Turn off auto-detect & fiber mode */
  2553. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2554. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
  2555. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2556. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
  2557. (val & 0xFFEE));
  2558. /* Set filter_force_link, disable_false_link and parallel_detect */
  2559. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2560. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
  2561. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2562. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
  2563. ((val | 0x0006) & 0xFFFE));
  2564. /* Set XFI / SFI */
  2565. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2566. MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
  2567. misc1_val &= ~(0x1f);
  2568. if (is_xfi) {
  2569. misc1_val |= 0x5;
  2570. tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
  2571. (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
  2572. (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
  2573. tx_driver_val =
  2574. ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
  2575. (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
  2576. (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
  2577. } else {
  2578. misc1_val |= 0x9;
  2579. tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
  2580. (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
  2581. (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
  2582. tx_driver_val =
  2583. ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
  2584. (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
  2585. (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
  2586. }
  2587. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2588. MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
  2589. /* Set Transmit PMD settings */
  2590. lane = bnx2x_get_warpcore_lane(phy, params);
  2591. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2592. MDIO_WC_REG_TX_FIR_TAP,
  2593. tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
  2594. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2595. MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
  2596. tx_driver_val);
  2597. /* Enable fiber mode, enable and invert sig_det */
  2598. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2599. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
  2600. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2601. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
  2602. /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
  2603. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2604. MDIO_WC_REG_DIGITAL4_MISC3, &val);
  2605. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2606. MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
  2607. /* 10G XFI Full Duplex */
  2608. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2609. MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
  2610. /* Release tx_fifo_reset */
  2611. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2612. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
  2613. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2614. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
  2615. /* Release rxSeqStart */
  2616. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2617. MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
  2618. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2619. MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
  2620. }
  2621. static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
  2622. struct bnx2x_phy *phy)
  2623. {
  2624. DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
  2625. }
  2626. static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
  2627. struct bnx2x_phy *phy,
  2628. u16 lane)
  2629. {
  2630. /* Rx0 anaRxControl1G */
  2631. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2632. MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
  2633. /* Rx2 anaRxControl1G */
  2634. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2635. MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
  2636. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2637. MDIO_WC_REG_RX66_SCW0, 0xE070);
  2638. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2639. MDIO_WC_REG_RX66_SCW1, 0xC0D0);
  2640. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2641. MDIO_WC_REG_RX66_SCW2, 0xA0B0);
  2642. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2643. MDIO_WC_REG_RX66_SCW3, 0x8090);
  2644. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2645. MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
  2646. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2647. MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
  2648. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2649. MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
  2650. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2651. MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
  2652. /* Serdes Digital Misc1 */
  2653. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2654. MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
  2655. /* Serdes Digital4 Misc3 */
  2656. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2657. MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
  2658. /* Set Transmit PMD settings */
  2659. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2660. MDIO_WC_REG_TX_FIR_TAP,
  2661. ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
  2662. (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
  2663. (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
  2664. MDIO_WC_REG_TX_FIR_TAP_ENABLE));
  2665. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2666. MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
  2667. ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
  2668. (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
  2669. (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
  2670. }
  2671. static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
  2672. struct link_params *params,
  2673. u8 fiber_mode)
  2674. {
  2675. struct bnx2x *bp = params->bp;
  2676. u16 val16, digctrl_kx1, digctrl_kx2;
  2677. u8 lane;
  2678. lane = bnx2x_get_warpcore_lane(phy, params);
  2679. /* Clear XFI clock comp in non-10G single lane mode. */
  2680. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2681. MDIO_WC_REG_RX66_CONTROL, &val16);
  2682. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2683. MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
  2684. if (phy->req_line_speed == SPEED_AUTO_NEG) {
  2685. /* SGMII Autoneg */
  2686. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2687. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
  2688. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2689. MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
  2690. val16 | 0x1000);
  2691. DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
  2692. } else {
  2693. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2694. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
  2695. val16 &= 0xcfbf;
  2696. switch (phy->req_line_speed) {
  2697. case SPEED_10:
  2698. break;
  2699. case SPEED_100:
  2700. val16 |= 0x2000;
  2701. break;
  2702. case SPEED_1000:
  2703. val16 |= 0x0040;
  2704. break;
  2705. default:
  2706. DP(NETIF_MSG_LINK, "Speed not supported: 0x%x"
  2707. "\n", phy->req_line_speed);
  2708. return;
  2709. }
  2710. if (phy->req_duplex == DUPLEX_FULL)
  2711. val16 |= 0x0100;
  2712. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2713. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
  2714. DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
  2715. phy->req_line_speed);
  2716. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2717. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
  2718. DP(NETIF_MSG_LINK, " (readback) %x\n", val16);
  2719. }
  2720. /* SGMII Slave mode and disable signal detect */
  2721. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2722. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
  2723. if (fiber_mode)
  2724. digctrl_kx1 = 1;
  2725. else
  2726. digctrl_kx1 &= 0xff4a;
  2727. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2728. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
  2729. digctrl_kx1);
  2730. /* Turn off parallel detect */
  2731. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2732. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
  2733. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2734. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
  2735. (digctrl_kx2 & ~(1<<2)));
  2736. /* Re-enable parallel detect */
  2737. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2738. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
  2739. (digctrl_kx2 | (1<<2)));
  2740. /* Enable autodet */
  2741. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2742. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
  2743. (digctrl_kx1 | 0x10));
  2744. }
  2745. static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
  2746. struct bnx2x_phy *phy,
  2747. u8 reset)
  2748. {
  2749. u16 val;
  2750. /* Take lane out of reset after configuration is finished */
  2751. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2752. MDIO_WC_REG_DIGITAL5_MISC6, &val);
  2753. if (reset)
  2754. val |= 0xC000;
  2755. else
  2756. val &= 0x3FFF;
  2757. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2758. MDIO_WC_REG_DIGITAL5_MISC6, val);
  2759. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2760. MDIO_WC_REG_DIGITAL5_MISC6, &val);
  2761. }
  2762. /* Clear SFI/XFI link settings registers */
  2763. static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
  2764. struct link_params *params,
  2765. u16 lane)
  2766. {
  2767. struct bnx2x *bp = params->bp;
  2768. u16 val16;
  2769. /* Set XFI clock comp as default. */
  2770. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2771. MDIO_WC_REG_RX66_CONTROL, &val16);
  2772. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2773. MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
  2774. bnx2x_warpcore_reset_lane(bp, phy, 1);
  2775. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
  2776. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2777. MDIO_WC_REG_FX100_CTRL1, 0x014a);
  2778. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2779. MDIO_WC_REG_FX100_CTRL3, 0x0800);
  2780. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2781. MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
  2782. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2783. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
  2784. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2785. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
  2786. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2787. MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
  2788. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2789. MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
  2790. lane = bnx2x_get_warpcore_lane(phy, params);
  2791. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2792. MDIO_WC_REG_TX_FIR_TAP, 0x0000);
  2793. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2794. MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
  2795. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2796. MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
  2797. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2798. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
  2799. bnx2x_warpcore_reset_lane(bp, phy, 0);
  2800. }
  2801. static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
  2802. u32 chip_id,
  2803. u32 shmem_base, u8 port,
  2804. u8 *gpio_num, u8 *gpio_port)
  2805. {
  2806. u32 cfg_pin;
  2807. *gpio_num = 0;
  2808. *gpio_port = 0;
  2809. if (CHIP_IS_E3(bp)) {
  2810. cfg_pin = (REG_RD(bp, shmem_base +
  2811. offsetof(struct shmem_region,
  2812. dev_info.port_hw_config[port].e3_sfp_ctrl)) &
  2813. PORT_HW_CFG_E3_MOD_ABS_MASK) >>
  2814. PORT_HW_CFG_E3_MOD_ABS_SHIFT;
  2815. /*
  2816. * Should not happen. This function called upon interrupt
  2817. * triggered by GPIO ( since EPIO can only generate interrupts
  2818. * to MCP).
  2819. * So if this function was called and none of the GPIOs was set,
  2820. * it means the shit hit the fan.
  2821. */
  2822. if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
  2823. (cfg_pin > PIN_CFG_GPIO3_P1)) {
  2824. DP(NETIF_MSG_LINK, "ERROR: Invalid cfg pin %x for "
  2825. "module detect indication\n",
  2826. cfg_pin);
  2827. return -EINVAL;
  2828. }
  2829. *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
  2830. *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
  2831. } else {
  2832. *gpio_num = MISC_REGISTERS_GPIO_3;
  2833. *gpio_port = port;
  2834. }
  2835. DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
  2836. return 0;
  2837. }
  2838. static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
  2839. struct link_params *params)
  2840. {
  2841. struct bnx2x *bp = params->bp;
  2842. u8 gpio_num, gpio_port;
  2843. u32 gpio_val;
  2844. if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
  2845. params->shmem_base, params->port,
  2846. &gpio_num, &gpio_port) != 0)
  2847. return 0;
  2848. gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
  2849. /* Call the handling function in case module is detected */
  2850. if (gpio_val == 0)
  2851. return 1;
  2852. else
  2853. return 0;
  2854. }
  2855. static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
  2856. struct link_params *params,
  2857. struct link_vars *vars)
  2858. {
  2859. struct bnx2x *bp = params->bp;
  2860. u32 serdes_net_if;
  2861. u8 fiber_mode;
  2862. u16 lane = bnx2x_get_warpcore_lane(phy, params);
  2863. serdes_net_if = (REG_RD(bp, params->shmem_base +
  2864. offsetof(struct shmem_region, dev_info.
  2865. port_hw_config[params->port].default_cfg)) &
  2866. PORT_HW_CFG_NET_SERDES_IF_MASK);
  2867. DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
  2868. "serdes_net_if = 0x%x\n",
  2869. vars->line_speed, serdes_net_if);
  2870. bnx2x_set_aer_mmd(params, phy);
  2871. vars->phy_flags |= PHY_XGXS_FLAG;
  2872. if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
  2873. (phy->req_line_speed &&
  2874. ((phy->req_line_speed == SPEED_100) ||
  2875. (phy->req_line_speed == SPEED_10)))) {
  2876. vars->phy_flags |= PHY_SGMII_FLAG;
  2877. DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
  2878. bnx2x_warpcore_clear_regs(phy, params, lane);
  2879. bnx2x_warpcore_set_sgmii_speed(phy, params, 0);
  2880. } else {
  2881. switch (serdes_net_if) {
  2882. case PORT_HW_CFG_NET_SERDES_IF_KR:
  2883. /* Enable KR Auto Neg */
  2884. if (params->loopback_mode == LOOPBACK_NONE)
  2885. bnx2x_warpcore_enable_AN_KR(phy, params, vars);
  2886. else {
  2887. DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
  2888. bnx2x_warpcore_set_10G_KR(phy, params, vars);
  2889. }
  2890. break;
  2891. case PORT_HW_CFG_NET_SERDES_IF_XFI:
  2892. bnx2x_warpcore_clear_regs(phy, params, lane);
  2893. if (vars->line_speed == SPEED_10000) {
  2894. DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
  2895. bnx2x_warpcore_set_10G_XFI(phy, params, 1);
  2896. } else {
  2897. if (SINGLE_MEDIA_DIRECT(params)) {
  2898. DP(NETIF_MSG_LINK, "1G Fiber\n");
  2899. fiber_mode = 1;
  2900. } else {
  2901. DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
  2902. fiber_mode = 0;
  2903. }
  2904. bnx2x_warpcore_set_sgmii_speed(phy,
  2905. params,
  2906. fiber_mode);
  2907. }
  2908. break;
  2909. case PORT_HW_CFG_NET_SERDES_IF_SFI:
  2910. bnx2x_warpcore_clear_regs(phy, params, lane);
  2911. if (vars->line_speed == SPEED_10000) {
  2912. DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
  2913. bnx2x_warpcore_set_10G_XFI(phy, params, 0);
  2914. } else if (vars->line_speed == SPEED_1000) {
  2915. DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
  2916. bnx2x_warpcore_set_sgmii_speed(phy, params, 1);
  2917. }
  2918. /* Issue Module detection */
  2919. if (bnx2x_is_sfp_module_plugged(phy, params))
  2920. bnx2x_sfp_module_detection(phy, params);
  2921. break;
  2922. case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
  2923. if (vars->line_speed != SPEED_20000) {
  2924. DP(NETIF_MSG_LINK, "Speed not supported yet\n");
  2925. return;
  2926. }
  2927. DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
  2928. bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
  2929. /* Issue Module detection */
  2930. bnx2x_sfp_module_detection(phy, params);
  2931. break;
  2932. case PORT_HW_CFG_NET_SERDES_IF_KR2:
  2933. if (vars->line_speed != SPEED_20000) {
  2934. DP(NETIF_MSG_LINK, "Speed not supported yet\n");
  2935. return;
  2936. }
  2937. DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
  2938. bnx2x_warpcore_set_20G_KR2(bp, phy);
  2939. break;
  2940. default:
  2941. DP(NETIF_MSG_LINK, "Unsupported Serdes Net Interface "
  2942. "0x%x\n", serdes_net_if);
  2943. return;
  2944. }
  2945. }
  2946. /* Take lane out of reset after configuration is finished */
  2947. bnx2x_warpcore_reset_lane(bp, phy, 0);
  2948. DP(NETIF_MSG_LINK, "Exit config init\n");
  2949. }
  2950. static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
  2951. struct bnx2x_phy *phy,
  2952. u8 tx_en)
  2953. {
  2954. struct bnx2x *bp = params->bp;
  2955. u32 cfg_pin;
  2956. u8 port = params->port;
  2957. cfg_pin = REG_RD(bp, params->shmem_base +
  2958. offsetof(struct shmem_region,
  2959. dev_info.port_hw_config[port].e3_sfp_ctrl)) &
  2960. PORT_HW_CFG_TX_LASER_MASK;
  2961. /* Set the !tx_en since this pin is DISABLE_TX_LASER */
  2962. DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
  2963. /* For 20G, the expected pin to be used is 3 pins after the current */
  2964. bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
  2965. if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
  2966. bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
  2967. }
  2968. static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
  2969. struct link_params *params)
  2970. {
  2971. struct bnx2x *bp = params->bp;
  2972. u16 val16;
  2973. bnx2x_sfp_e3_set_transmitter(params, phy, 0);
  2974. bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
  2975. bnx2x_set_aer_mmd(params, phy);
  2976. /* Global register */
  2977. bnx2x_warpcore_reset_lane(bp, phy, 1);
  2978. /* Clear loopback settings (if any) */
  2979. /* 10G & 20G */
  2980. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2981. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
  2982. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2983. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
  2984. 0xBFFF);
  2985. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2986. MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
  2987. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2988. MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
  2989. /* Update those 1-copy registers */
  2990. CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
  2991. MDIO_AER_BLOCK_AER_REG, 0);
  2992. /* Enable 1G MDIO (1-copy) */
  2993. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  2994. MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
  2995. &val16);
  2996. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  2997. MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
  2998. val16 & ~0x10);
  2999. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3000. MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
  3001. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  3002. MDIO_WC_REG_XGXSBLK1_LANECTRL2,
  3003. val16 & 0xff00);
  3004. }
  3005. static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
  3006. struct link_params *params)
  3007. {
  3008. struct bnx2x *bp = params->bp;
  3009. u16 val16;
  3010. u32 lane;
  3011. DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
  3012. params->loopback_mode, phy->req_line_speed);
  3013. if (phy->req_line_speed < SPEED_10000) {
  3014. /* 10/100/1000 */
  3015. /* Update those 1-copy registers */
  3016. CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
  3017. MDIO_AER_BLOCK_AER_REG, 0);
  3018. /* Enable 1G MDIO (1-copy) */
  3019. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3020. MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
  3021. &val16);
  3022. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  3023. MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
  3024. val16 | 0x10);
  3025. /* Set 1G loopback based on lane (1-copy) */
  3026. lane = bnx2x_get_warpcore_lane(phy, params);
  3027. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3028. MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
  3029. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  3030. MDIO_WC_REG_XGXSBLK1_LANECTRL2,
  3031. val16 | (1<<lane));
  3032. /* Switch back to 4-copy registers */
  3033. bnx2x_set_aer_mmd(params, phy);
  3034. /* Global loopback, not recommended. */
  3035. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3036. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
  3037. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  3038. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
  3039. 0x4000);
  3040. } else {
  3041. /* 10G & 20G */
  3042. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3043. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
  3044. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  3045. MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
  3046. 0x4000);
  3047. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3048. MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
  3049. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  3050. MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
  3051. }
  3052. }
  3053. void bnx2x_link_status_update(struct link_params *params,
  3054. struct link_vars *vars)
  3055. {
  3056. struct bnx2x *bp = params->bp;
  3057. u8 link_10g_plus;
  3058. u8 port = params->port;
  3059. u32 sync_offset, media_types;
  3060. /* Update PHY configuration */
  3061. set_phy_vars(params, vars);
  3062. vars->link_status = REG_RD(bp, params->shmem_base +
  3063. offsetof(struct shmem_region,
  3064. port_mb[port].link_status));
  3065. vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
  3066. vars->phy_flags = PHY_XGXS_FLAG;
  3067. if (vars->link_up) {
  3068. DP(NETIF_MSG_LINK, "phy link up\n");
  3069. vars->phy_link_up = 1;
  3070. vars->duplex = DUPLEX_FULL;
  3071. switch (vars->link_status &
  3072. LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
  3073. case LINK_10THD:
  3074. vars->duplex = DUPLEX_HALF;
  3075. /* fall thru */
  3076. case LINK_10TFD:
  3077. vars->line_speed = SPEED_10;
  3078. break;
  3079. case LINK_100TXHD:
  3080. vars->duplex = DUPLEX_HALF;
  3081. /* fall thru */
  3082. case LINK_100T4:
  3083. case LINK_100TXFD:
  3084. vars->line_speed = SPEED_100;
  3085. break;
  3086. case LINK_1000THD:
  3087. vars->duplex = DUPLEX_HALF;
  3088. /* fall thru */
  3089. case LINK_1000TFD:
  3090. vars->line_speed = SPEED_1000;
  3091. break;
  3092. case LINK_2500THD:
  3093. vars->duplex = DUPLEX_HALF;
  3094. /* fall thru */
  3095. case LINK_2500TFD:
  3096. vars->line_speed = SPEED_2500;
  3097. break;
  3098. case LINK_10GTFD:
  3099. vars->line_speed = SPEED_10000;
  3100. break;
  3101. case LINK_20GTFD:
  3102. vars->line_speed = SPEED_20000;
  3103. break;
  3104. default:
  3105. break;
  3106. }
  3107. vars->flow_ctrl = 0;
  3108. if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
  3109. vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
  3110. if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
  3111. vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
  3112. if (!vars->flow_ctrl)
  3113. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  3114. if (vars->line_speed &&
  3115. ((vars->line_speed == SPEED_10) ||
  3116. (vars->line_speed == SPEED_100))) {
  3117. vars->phy_flags |= PHY_SGMII_FLAG;
  3118. } else {
  3119. vars->phy_flags &= ~PHY_SGMII_FLAG;
  3120. }
  3121. if (vars->line_speed &&
  3122. USES_WARPCORE(bp) &&
  3123. (vars->line_speed == SPEED_1000))
  3124. vars->phy_flags |= PHY_SGMII_FLAG;
  3125. /* anything 10 and over uses the bmac */
  3126. link_10g_plus = (vars->line_speed >= SPEED_10000);
  3127. if (link_10g_plus) {
  3128. if (USES_WARPCORE(bp))
  3129. vars->mac_type = MAC_TYPE_XMAC;
  3130. else
  3131. vars->mac_type = MAC_TYPE_BMAC;
  3132. } else {
  3133. if (USES_WARPCORE(bp))
  3134. vars->mac_type = MAC_TYPE_UMAC;
  3135. else
  3136. vars->mac_type = MAC_TYPE_EMAC;
  3137. }
  3138. } else { /* link down */
  3139. DP(NETIF_MSG_LINK, "phy link down\n");
  3140. vars->phy_link_up = 0;
  3141. vars->line_speed = 0;
  3142. vars->duplex = DUPLEX_FULL;
  3143. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  3144. /* indicate no mac active */
  3145. vars->mac_type = MAC_TYPE_NONE;
  3146. }
  3147. /* Sync media type */
  3148. sync_offset = params->shmem_base +
  3149. offsetof(struct shmem_region,
  3150. dev_info.port_hw_config[port].media_type);
  3151. media_types = REG_RD(bp, sync_offset);
  3152. params->phy[INT_PHY].media_type =
  3153. (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
  3154. PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
  3155. params->phy[EXT_PHY1].media_type =
  3156. (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
  3157. PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
  3158. params->phy[EXT_PHY2].media_type =
  3159. (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
  3160. PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
  3161. DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
  3162. /* Sync AEU offset */
  3163. sync_offset = params->shmem_base +
  3164. offsetof(struct shmem_region,
  3165. dev_info.port_hw_config[port].aeu_int_mask);
  3166. vars->aeu_int_mask = REG_RD(bp, sync_offset);
  3167. DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n",
  3168. vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
  3169. DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
  3170. vars->line_speed, vars->duplex, vars->flow_ctrl);
  3171. }
  3172. static void bnx2x_set_master_ln(struct link_params *params,
  3173. struct bnx2x_phy *phy)
  3174. {
  3175. struct bnx2x *bp = params->bp;
  3176. u16 new_master_ln, ser_lane;
  3177. ser_lane = ((params->lane_config &
  3178. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  3179. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  3180. /* set the master_ln for AN */
  3181. CL22_RD_OVER_CL45(bp, phy,
  3182. MDIO_REG_BANK_XGXS_BLOCK2,
  3183. MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
  3184. &new_master_ln);
  3185. CL22_WR_OVER_CL45(bp, phy,
  3186. MDIO_REG_BANK_XGXS_BLOCK2 ,
  3187. MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
  3188. (new_master_ln | ser_lane));
  3189. }
  3190. static int bnx2x_reset_unicore(struct link_params *params,
  3191. struct bnx2x_phy *phy,
  3192. u8 set_serdes)
  3193. {
  3194. struct bnx2x *bp = params->bp;
  3195. u16 mii_control;
  3196. u16 i;
  3197. CL22_RD_OVER_CL45(bp, phy,
  3198. MDIO_REG_BANK_COMBO_IEEE0,
  3199. MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
  3200. /* reset the unicore */
  3201. CL22_WR_OVER_CL45(bp, phy,
  3202. MDIO_REG_BANK_COMBO_IEEE0,
  3203. MDIO_COMBO_IEEE0_MII_CONTROL,
  3204. (mii_control |
  3205. MDIO_COMBO_IEEO_MII_CONTROL_RESET));
  3206. if (set_serdes)
  3207. bnx2x_set_serdes_access(bp, params->port);
  3208. /* wait for the reset to self clear */
  3209. for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
  3210. udelay(5);
  3211. /* the reset erased the previous bank value */
  3212. CL22_RD_OVER_CL45(bp, phy,
  3213. MDIO_REG_BANK_COMBO_IEEE0,
  3214. MDIO_COMBO_IEEE0_MII_CONTROL,
  3215. &mii_control);
  3216. if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
  3217. udelay(5);
  3218. return 0;
  3219. }
  3220. }
  3221. netdev_err(bp->dev, "Warning: PHY was not initialized,"
  3222. " Port %d\n",
  3223. params->port);
  3224. DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
  3225. return -EINVAL;
  3226. }
  3227. static void bnx2x_set_swap_lanes(struct link_params *params,
  3228. struct bnx2x_phy *phy)
  3229. {
  3230. struct bnx2x *bp = params->bp;
  3231. /*
  3232. * Each two bits represents a lane number:
  3233. * No swap is 0123 => 0x1b no need to enable the swap
  3234. */
  3235. u16 ser_lane, rx_lane_swap, tx_lane_swap;
  3236. ser_lane = ((params->lane_config &
  3237. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  3238. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  3239. rx_lane_swap = ((params->lane_config &
  3240. PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
  3241. PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
  3242. tx_lane_swap = ((params->lane_config &
  3243. PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
  3244. PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
  3245. if (rx_lane_swap != 0x1b) {
  3246. CL22_WR_OVER_CL45(bp, phy,
  3247. MDIO_REG_BANK_XGXS_BLOCK2,
  3248. MDIO_XGXS_BLOCK2_RX_LN_SWAP,
  3249. (rx_lane_swap |
  3250. MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
  3251. MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
  3252. } else {
  3253. CL22_WR_OVER_CL45(bp, phy,
  3254. MDIO_REG_BANK_XGXS_BLOCK2,
  3255. MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
  3256. }
  3257. if (tx_lane_swap != 0x1b) {
  3258. CL22_WR_OVER_CL45(bp, phy,
  3259. MDIO_REG_BANK_XGXS_BLOCK2,
  3260. MDIO_XGXS_BLOCK2_TX_LN_SWAP,
  3261. (tx_lane_swap |
  3262. MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
  3263. } else {
  3264. CL22_WR_OVER_CL45(bp, phy,
  3265. MDIO_REG_BANK_XGXS_BLOCK2,
  3266. MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
  3267. }
  3268. }
  3269. static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
  3270. struct link_params *params)
  3271. {
  3272. struct bnx2x *bp = params->bp;
  3273. u16 control2;
  3274. CL22_RD_OVER_CL45(bp, phy,
  3275. MDIO_REG_BANK_SERDES_DIGITAL,
  3276. MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
  3277. &control2);
  3278. if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
  3279. control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
  3280. else
  3281. control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
  3282. DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
  3283. phy->speed_cap_mask, control2);
  3284. CL22_WR_OVER_CL45(bp, phy,
  3285. MDIO_REG_BANK_SERDES_DIGITAL,
  3286. MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
  3287. control2);
  3288. if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
  3289. (phy->speed_cap_mask &
  3290. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
  3291. DP(NETIF_MSG_LINK, "XGXS\n");
  3292. CL22_WR_OVER_CL45(bp, phy,
  3293. MDIO_REG_BANK_10G_PARALLEL_DETECT,
  3294. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
  3295. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
  3296. CL22_RD_OVER_CL45(bp, phy,
  3297. MDIO_REG_BANK_10G_PARALLEL_DETECT,
  3298. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
  3299. &control2);
  3300. control2 |=
  3301. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
  3302. CL22_WR_OVER_CL45(bp, phy,
  3303. MDIO_REG_BANK_10G_PARALLEL_DETECT,
  3304. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
  3305. control2);
  3306. /* Disable parallel detection of HiG */
  3307. CL22_WR_OVER_CL45(bp, phy,
  3308. MDIO_REG_BANK_XGXS_BLOCK2,
  3309. MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
  3310. MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
  3311. MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
  3312. }
  3313. }
  3314. static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
  3315. struct link_params *params,
  3316. struct link_vars *vars,
  3317. u8 enable_cl73)
  3318. {
  3319. struct bnx2x *bp = params->bp;
  3320. u16 reg_val;
  3321. /* CL37 Autoneg */
  3322. CL22_RD_OVER_CL45(bp, phy,
  3323. MDIO_REG_BANK_COMBO_IEEE0,
  3324. MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
  3325. /* CL37 Autoneg Enabled */
  3326. if (vars->line_speed == SPEED_AUTO_NEG)
  3327. reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
  3328. else /* CL37 Autoneg Disabled */
  3329. reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
  3330. MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
  3331. CL22_WR_OVER_CL45(bp, phy,
  3332. MDIO_REG_BANK_COMBO_IEEE0,
  3333. MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
  3334. /* Enable/Disable Autodetection */
  3335. CL22_RD_OVER_CL45(bp, phy,
  3336. MDIO_REG_BANK_SERDES_DIGITAL,
  3337. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
  3338. reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
  3339. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
  3340. reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
  3341. if (vars->line_speed == SPEED_AUTO_NEG)
  3342. reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
  3343. else
  3344. reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
  3345. CL22_WR_OVER_CL45(bp, phy,
  3346. MDIO_REG_BANK_SERDES_DIGITAL,
  3347. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
  3348. /* Enable TetonII and BAM autoneg */
  3349. CL22_RD_OVER_CL45(bp, phy,
  3350. MDIO_REG_BANK_BAM_NEXT_PAGE,
  3351. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
  3352. &reg_val);
  3353. if (vars->line_speed == SPEED_AUTO_NEG) {
  3354. /* Enable BAM aneg Mode and TetonII aneg Mode */
  3355. reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
  3356. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
  3357. } else {
  3358. /* TetonII and BAM Autoneg Disabled */
  3359. reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
  3360. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
  3361. }
  3362. CL22_WR_OVER_CL45(bp, phy,
  3363. MDIO_REG_BANK_BAM_NEXT_PAGE,
  3364. MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
  3365. reg_val);
  3366. if (enable_cl73) {
  3367. /* Enable Cl73 FSM status bits */
  3368. CL22_WR_OVER_CL45(bp, phy,
  3369. MDIO_REG_BANK_CL73_USERB0,
  3370. MDIO_CL73_USERB0_CL73_UCTRL,
  3371. 0xe);
  3372. /* Enable BAM Station Manager*/
  3373. CL22_WR_OVER_CL45(bp, phy,
  3374. MDIO_REG_BANK_CL73_USERB0,
  3375. MDIO_CL73_USERB0_CL73_BAM_CTRL1,
  3376. MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
  3377. MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
  3378. MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
  3379. /* Advertise CL73 link speeds */
  3380. CL22_RD_OVER_CL45(bp, phy,
  3381. MDIO_REG_BANK_CL73_IEEEB1,
  3382. MDIO_CL73_IEEEB1_AN_ADV2,
  3383. &reg_val);
  3384. if (phy->speed_cap_mask &
  3385. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
  3386. reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
  3387. if (phy->speed_cap_mask &
  3388. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
  3389. reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
  3390. CL22_WR_OVER_CL45(bp, phy,
  3391. MDIO_REG_BANK_CL73_IEEEB1,
  3392. MDIO_CL73_IEEEB1_AN_ADV2,
  3393. reg_val);
  3394. /* CL73 Autoneg Enabled */
  3395. reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
  3396. } else /* CL73 Autoneg Disabled */
  3397. reg_val = 0;
  3398. CL22_WR_OVER_CL45(bp, phy,
  3399. MDIO_REG_BANK_CL73_IEEEB0,
  3400. MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
  3401. }
  3402. /* program SerDes, forced speed */
  3403. static void bnx2x_program_serdes(struct bnx2x_phy *phy,
  3404. struct link_params *params,
  3405. struct link_vars *vars)
  3406. {
  3407. struct bnx2x *bp = params->bp;
  3408. u16 reg_val;
  3409. /* program duplex, disable autoneg and sgmii*/
  3410. CL22_RD_OVER_CL45(bp, phy,
  3411. MDIO_REG_BANK_COMBO_IEEE0,
  3412. MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
  3413. reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
  3414. MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
  3415. MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
  3416. if (phy->req_duplex == DUPLEX_FULL)
  3417. reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
  3418. CL22_WR_OVER_CL45(bp, phy,
  3419. MDIO_REG_BANK_COMBO_IEEE0,
  3420. MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
  3421. /*
  3422. * program speed
  3423. * - needed only if the speed is greater than 1G (2.5G or 10G)
  3424. */
  3425. CL22_RD_OVER_CL45(bp, phy,
  3426. MDIO_REG_BANK_SERDES_DIGITAL,
  3427. MDIO_SERDES_DIGITAL_MISC1, &reg_val);
  3428. /* clearing the speed value before setting the right speed */
  3429. DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
  3430. reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
  3431. MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
  3432. if (!((vars->line_speed == SPEED_1000) ||
  3433. (vars->line_speed == SPEED_100) ||
  3434. (vars->line_speed == SPEED_10))) {
  3435. reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
  3436. MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
  3437. if (vars->line_speed == SPEED_10000)
  3438. reg_val |=
  3439. MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
  3440. }
  3441. CL22_WR_OVER_CL45(bp, phy,
  3442. MDIO_REG_BANK_SERDES_DIGITAL,
  3443. MDIO_SERDES_DIGITAL_MISC1, reg_val);
  3444. }
  3445. static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
  3446. struct link_params *params)
  3447. {
  3448. struct bnx2x *bp = params->bp;
  3449. u16 val = 0;
  3450. /* configure the 48 bits for BAM AN */
  3451. /* set extended capabilities */
  3452. if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
  3453. val |= MDIO_OVER_1G_UP1_2_5G;
  3454. if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
  3455. val |= MDIO_OVER_1G_UP1_10G;
  3456. CL22_WR_OVER_CL45(bp, phy,
  3457. MDIO_REG_BANK_OVER_1G,
  3458. MDIO_OVER_1G_UP1, val);
  3459. CL22_WR_OVER_CL45(bp, phy,
  3460. MDIO_REG_BANK_OVER_1G,
  3461. MDIO_OVER_1G_UP3, 0x400);
  3462. }
  3463. static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
  3464. struct link_params *params,
  3465. u16 ieee_fc)
  3466. {
  3467. struct bnx2x *bp = params->bp;
  3468. u16 val;
  3469. /* for AN, we are always publishing full duplex */
  3470. CL22_WR_OVER_CL45(bp, phy,
  3471. MDIO_REG_BANK_COMBO_IEEE0,
  3472. MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
  3473. CL22_RD_OVER_CL45(bp, phy,
  3474. MDIO_REG_BANK_CL73_IEEEB1,
  3475. MDIO_CL73_IEEEB1_AN_ADV1, &val);
  3476. val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
  3477. val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
  3478. CL22_WR_OVER_CL45(bp, phy,
  3479. MDIO_REG_BANK_CL73_IEEEB1,
  3480. MDIO_CL73_IEEEB1_AN_ADV1, val);
  3481. }
  3482. static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
  3483. struct link_params *params,
  3484. u8 enable_cl73)
  3485. {
  3486. struct bnx2x *bp = params->bp;
  3487. u16 mii_control;
  3488. DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
  3489. /* Enable and restart BAM/CL37 aneg */
  3490. if (enable_cl73) {
  3491. CL22_RD_OVER_CL45(bp, phy,
  3492. MDIO_REG_BANK_CL73_IEEEB0,
  3493. MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
  3494. &mii_control);
  3495. CL22_WR_OVER_CL45(bp, phy,
  3496. MDIO_REG_BANK_CL73_IEEEB0,
  3497. MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
  3498. (mii_control |
  3499. MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
  3500. MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
  3501. } else {
  3502. CL22_RD_OVER_CL45(bp, phy,
  3503. MDIO_REG_BANK_COMBO_IEEE0,
  3504. MDIO_COMBO_IEEE0_MII_CONTROL,
  3505. &mii_control);
  3506. DP(NETIF_MSG_LINK,
  3507. "bnx2x_restart_autoneg mii_control before = 0x%x\n",
  3508. mii_control);
  3509. CL22_WR_OVER_CL45(bp, phy,
  3510. MDIO_REG_BANK_COMBO_IEEE0,
  3511. MDIO_COMBO_IEEE0_MII_CONTROL,
  3512. (mii_control |
  3513. MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
  3514. MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
  3515. }
  3516. }
  3517. static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
  3518. struct link_params *params,
  3519. struct link_vars *vars)
  3520. {
  3521. struct bnx2x *bp = params->bp;
  3522. u16 control1;
  3523. /* in SGMII mode, the unicore is always slave */
  3524. CL22_RD_OVER_CL45(bp, phy,
  3525. MDIO_REG_BANK_SERDES_DIGITAL,
  3526. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
  3527. &control1);
  3528. control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
  3529. /* set sgmii mode (and not fiber) */
  3530. control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
  3531. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
  3532. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
  3533. CL22_WR_OVER_CL45(bp, phy,
  3534. MDIO_REG_BANK_SERDES_DIGITAL,
  3535. MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
  3536. control1);
  3537. /* if forced speed */
  3538. if (!(vars->line_speed == SPEED_AUTO_NEG)) {
  3539. /* set speed, disable autoneg */
  3540. u16 mii_control;
  3541. CL22_RD_OVER_CL45(bp, phy,
  3542. MDIO_REG_BANK_COMBO_IEEE0,
  3543. MDIO_COMBO_IEEE0_MII_CONTROL,
  3544. &mii_control);
  3545. mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
  3546. MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
  3547. MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
  3548. switch (vars->line_speed) {
  3549. case SPEED_100:
  3550. mii_control |=
  3551. MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
  3552. break;
  3553. case SPEED_1000:
  3554. mii_control |=
  3555. MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
  3556. break;
  3557. case SPEED_10:
  3558. /* there is nothing to set for 10M */
  3559. break;
  3560. default:
  3561. /* invalid speed for SGMII */
  3562. DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
  3563. vars->line_speed);
  3564. break;
  3565. }
  3566. /* setting the full duplex */
  3567. if (phy->req_duplex == DUPLEX_FULL)
  3568. mii_control |=
  3569. MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
  3570. CL22_WR_OVER_CL45(bp, phy,
  3571. MDIO_REG_BANK_COMBO_IEEE0,
  3572. MDIO_COMBO_IEEE0_MII_CONTROL,
  3573. mii_control);
  3574. } else { /* AN mode */
  3575. /* enable and restart AN */
  3576. bnx2x_restart_autoneg(phy, params, 0);
  3577. }
  3578. }
  3579. /*
  3580. * link management
  3581. */
  3582. static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
  3583. struct link_params *params)
  3584. {
  3585. struct bnx2x *bp = params->bp;
  3586. u16 pd_10g, status2_1000x;
  3587. if (phy->req_line_speed != SPEED_AUTO_NEG)
  3588. return 0;
  3589. CL22_RD_OVER_CL45(bp, phy,
  3590. MDIO_REG_BANK_SERDES_DIGITAL,
  3591. MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
  3592. &status2_1000x);
  3593. CL22_RD_OVER_CL45(bp, phy,
  3594. MDIO_REG_BANK_SERDES_DIGITAL,
  3595. MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
  3596. &status2_1000x);
  3597. if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
  3598. DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
  3599. params->port);
  3600. return 1;
  3601. }
  3602. CL22_RD_OVER_CL45(bp, phy,
  3603. MDIO_REG_BANK_10G_PARALLEL_DETECT,
  3604. MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
  3605. &pd_10g);
  3606. if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
  3607. DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
  3608. params->port);
  3609. return 1;
  3610. }
  3611. return 0;
  3612. }
  3613. static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
  3614. struct link_params *params,
  3615. struct link_vars *vars,
  3616. u32 gp_status)
  3617. {
  3618. struct bnx2x *bp = params->bp;
  3619. u16 ld_pause; /* local driver */
  3620. u16 lp_pause; /* link partner */
  3621. u16 pause_result;
  3622. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  3623. /* resolve from gp_status in case of AN complete and not sgmii */
  3624. if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
  3625. vars->flow_ctrl = phy->req_flow_ctrl;
  3626. else if (phy->req_line_speed != SPEED_AUTO_NEG)
  3627. vars->flow_ctrl = params->req_fc_auto_adv;
  3628. else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
  3629. (!(vars->phy_flags & PHY_SGMII_FLAG))) {
  3630. if (bnx2x_direct_parallel_detect_used(phy, params)) {
  3631. vars->flow_ctrl = params->req_fc_auto_adv;
  3632. return;
  3633. }
  3634. if ((gp_status &
  3635. (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
  3636. MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
  3637. (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
  3638. MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
  3639. CL22_RD_OVER_CL45(bp, phy,
  3640. MDIO_REG_BANK_CL73_IEEEB1,
  3641. MDIO_CL73_IEEEB1_AN_ADV1,
  3642. &ld_pause);
  3643. CL22_RD_OVER_CL45(bp, phy,
  3644. MDIO_REG_BANK_CL73_IEEEB1,
  3645. MDIO_CL73_IEEEB1_AN_LP_ADV1,
  3646. &lp_pause);
  3647. pause_result = (ld_pause &
  3648. MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
  3649. >> 8;
  3650. pause_result |= (lp_pause &
  3651. MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
  3652. >> 10;
  3653. DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
  3654. pause_result);
  3655. } else {
  3656. CL22_RD_OVER_CL45(bp, phy,
  3657. MDIO_REG_BANK_COMBO_IEEE0,
  3658. MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
  3659. &ld_pause);
  3660. CL22_RD_OVER_CL45(bp, phy,
  3661. MDIO_REG_BANK_COMBO_IEEE0,
  3662. MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
  3663. &lp_pause);
  3664. pause_result = (ld_pause &
  3665. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
  3666. pause_result |= (lp_pause &
  3667. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
  3668. DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
  3669. pause_result);
  3670. }
  3671. bnx2x_pause_resolve(vars, pause_result);
  3672. }
  3673. DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
  3674. }
  3675. static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
  3676. struct link_params *params)
  3677. {
  3678. struct bnx2x *bp = params->bp;
  3679. u16 rx_status, ustat_val, cl37_fsm_received;
  3680. DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
  3681. /* Step 1: Make sure signal is detected */
  3682. CL22_RD_OVER_CL45(bp, phy,
  3683. MDIO_REG_BANK_RX0,
  3684. MDIO_RX0_RX_STATUS,
  3685. &rx_status);
  3686. if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
  3687. (MDIO_RX0_RX_STATUS_SIGDET)) {
  3688. DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
  3689. "rx_status(0x80b0) = 0x%x\n", rx_status);
  3690. CL22_WR_OVER_CL45(bp, phy,
  3691. MDIO_REG_BANK_CL73_IEEEB0,
  3692. MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
  3693. MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
  3694. return;
  3695. }
  3696. /* Step 2: Check CL73 state machine */
  3697. CL22_RD_OVER_CL45(bp, phy,
  3698. MDIO_REG_BANK_CL73_USERB0,
  3699. MDIO_CL73_USERB0_CL73_USTAT1,
  3700. &ustat_val);
  3701. if ((ustat_val &
  3702. (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
  3703. MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
  3704. (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
  3705. MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
  3706. DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
  3707. "ustat_val(0x8371) = 0x%x\n", ustat_val);
  3708. return;
  3709. }
  3710. /*
  3711. * Step 3: Check CL37 Message Pages received to indicate LP
  3712. * supports only CL37
  3713. */
  3714. CL22_RD_OVER_CL45(bp, phy,
  3715. MDIO_REG_BANK_REMOTE_PHY,
  3716. MDIO_REMOTE_PHY_MISC_RX_STATUS,
  3717. &cl37_fsm_received);
  3718. if ((cl37_fsm_received &
  3719. (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
  3720. MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
  3721. (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
  3722. MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
  3723. DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
  3724. "misc_rx_status(0x8330) = 0x%x\n",
  3725. cl37_fsm_received);
  3726. return;
  3727. }
  3728. /*
  3729. * The combined cl37/cl73 fsm state information indicating that
  3730. * we are connected to a device which does not support cl73, but
  3731. * does support cl37 BAM. In this case we disable cl73 and
  3732. * restart cl37 auto-neg
  3733. */
  3734. /* Disable CL73 */
  3735. CL22_WR_OVER_CL45(bp, phy,
  3736. MDIO_REG_BANK_CL73_IEEEB0,
  3737. MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
  3738. 0);
  3739. /* Restart CL37 autoneg */
  3740. bnx2x_restart_autoneg(phy, params, 0);
  3741. DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
  3742. }
  3743. static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
  3744. struct link_params *params,
  3745. struct link_vars *vars,
  3746. u32 gp_status)
  3747. {
  3748. if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
  3749. vars->link_status |=
  3750. LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
  3751. if (bnx2x_direct_parallel_detect_used(phy, params))
  3752. vars->link_status |=
  3753. LINK_STATUS_PARALLEL_DETECTION_USED;
  3754. }
  3755. static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
  3756. struct link_params *params,
  3757. struct link_vars *vars,
  3758. u16 is_link_up,
  3759. u16 speed_mask,
  3760. u16 is_duplex)
  3761. {
  3762. struct bnx2x *bp = params->bp;
  3763. if (phy->req_line_speed == SPEED_AUTO_NEG)
  3764. vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
  3765. if (is_link_up) {
  3766. DP(NETIF_MSG_LINK, "phy link up\n");
  3767. vars->phy_link_up = 1;
  3768. vars->link_status |= LINK_STATUS_LINK_UP;
  3769. switch (speed_mask) {
  3770. case GP_STATUS_10M:
  3771. vars->line_speed = SPEED_10;
  3772. if (vars->duplex == DUPLEX_FULL)
  3773. vars->link_status |= LINK_10TFD;
  3774. else
  3775. vars->link_status |= LINK_10THD;
  3776. break;
  3777. case GP_STATUS_100M:
  3778. vars->line_speed = SPEED_100;
  3779. if (vars->duplex == DUPLEX_FULL)
  3780. vars->link_status |= LINK_100TXFD;
  3781. else
  3782. vars->link_status |= LINK_100TXHD;
  3783. break;
  3784. case GP_STATUS_1G:
  3785. case GP_STATUS_1G_KX:
  3786. vars->line_speed = SPEED_1000;
  3787. if (vars->duplex == DUPLEX_FULL)
  3788. vars->link_status |= LINK_1000TFD;
  3789. else
  3790. vars->link_status |= LINK_1000THD;
  3791. break;
  3792. case GP_STATUS_2_5G:
  3793. vars->line_speed = SPEED_2500;
  3794. if (vars->duplex == DUPLEX_FULL)
  3795. vars->link_status |= LINK_2500TFD;
  3796. else
  3797. vars->link_status |= LINK_2500THD;
  3798. break;
  3799. case GP_STATUS_5G:
  3800. case GP_STATUS_6G:
  3801. DP(NETIF_MSG_LINK,
  3802. "link speed unsupported gp_status 0x%x\n",
  3803. speed_mask);
  3804. return -EINVAL;
  3805. case GP_STATUS_10G_KX4:
  3806. case GP_STATUS_10G_HIG:
  3807. case GP_STATUS_10G_CX4:
  3808. case GP_STATUS_10G_KR:
  3809. case GP_STATUS_10G_SFI:
  3810. case GP_STATUS_10G_XFI:
  3811. vars->line_speed = SPEED_10000;
  3812. vars->link_status |= LINK_10GTFD;
  3813. break;
  3814. case GP_STATUS_20G_DXGXS:
  3815. vars->line_speed = SPEED_20000;
  3816. vars->link_status |= LINK_20GTFD;
  3817. break;
  3818. default:
  3819. DP(NETIF_MSG_LINK,
  3820. "link speed unsupported gp_status 0x%x\n",
  3821. speed_mask);
  3822. return -EINVAL;
  3823. }
  3824. } else { /* link_down */
  3825. DP(NETIF_MSG_LINK, "phy link down\n");
  3826. vars->phy_link_up = 0;
  3827. vars->duplex = DUPLEX_FULL;
  3828. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  3829. vars->mac_type = MAC_TYPE_NONE;
  3830. }
  3831. DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
  3832. vars->phy_link_up, vars->line_speed);
  3833. return 0;
  3834. }
  3835. static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
  3836. struct link_params *params,
  3837. struct link_vars *vars)
  3838. {
  3839. struct bnx2x *bp = params->bp;
  3840. u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
  3841. int rc = 0;
  3842. /* Read gp_status */
  3843. CL22_RD_OVER_CL45(bp, phy,
  3844. MDIO_REG_BANK_GP_STATUS,
  3845. MDIO_GP_STATUS_TOP_AN_STATUS1,
  3846. &gp_status);
  3847. if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
  3848. duplex = DUPLEX_FULL;
  3849. if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
  3850. link_up = 1;
  3851. speed_mask = gp_status & GP_STATUS_SPEED_MASK;
  3852. DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
  3853. gp_status, link_up, speed_mask);
  3854. rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
  3855. duplex);
  3856. if (rc == -EINVAL)
  3857. return rc;
  3858. if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
  3859. if (SINGLE_MEDIA_DIRECT(params)) {
  3860. bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
  3861. if (phy->req_line_speed == SPEED_AUTO_NEG)
  3862. bnx2x_xgxs_an_resolve(phy, params, vars,
  3863. gp_status);
  3864. }
  3865. } else { /* link_down */
  3866. if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
  3867. SINGLE_MEDIA_DIRECT(params)) {
  3868. /* Check signal is detected */
  3869. bnx2x_check_fallback_to_cl37(phy, params);
  3870. }
  3871. }
  3872. DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
  3873. vars->duplex, vars->flow_ctrl, vars->link_status);
  3874. return rc;
  3875. }
  3876. static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
  3877. struct link_params *params,
  3878. struct link_vars *vars)
  3879. {
  3880. struct bnx2x *bp = params->bp;
  3881. u8 lane;
  3882. u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
  3883. int rc = 0;
  3884. lane = bnx2x_get_warpcore_lane(phy, params);
  3885. /* Read gp_status */
  3886. if (phy->req_line_speed > SPEED_10000) {
  3887. u16 temp_link_up;
  3888. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3889. 1, &temp_link_up);
  3890. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3891. 1, &link_up);
  3892. DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
  3893. temp_link_up, link_up);
  3894. link_up &= (1<<2);
  3895. if (link_up)
  3896. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  3897. } else {
  3898. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3899. MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
  3900. DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
  3901. /* Check for either KR or generic link up. */
  3902. gp_status1 = ((gp_status1 >> 8) & 0xf) |
  3903. ((gp_status1 >> 12) & 0xf);
  3904. link_up = gp_status1 & (1 << lane);
  3905. if (link_up && SINGLE_MEDIA_DIRECT(params)) {
  3906. u16 pd, gp_status4;
  3907. if (phy->req_line_speed == SPEED_AUTO_NEG) {
  3908. /* Check Autoneg complete */
  3909. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3910. MDIO_WC_REG_GP2_STATUS_GP_2_4,
  3911. &gp_status4);
  3912. if (gp_status4 & ((1<<12)<<lane))
  3913. vars->link_status |=
  3914. LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
  3915. /* Check parallel detect used */
  3916. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3917. MDIO_WC_REG_PAR_DET_10G_STATUS,
  3918. &pd);
  3919. if (pd & (1<<15))
  3920. vars->link_status |=
  3921. LINK_STATUS_PARALLEL_DETECTION_USED;
  3922. }
  3923. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  3924. }
  3925. }
  3926. if (lane < 2) {
  3927. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3928. MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
  3929. } else {
  3930. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  3931. MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
  3932. }
  3933. DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
  3934. if ((lane & 1) == 0)
  3935. gp_speed <<= 8;
  3936. gp_speed &= 0x3f00;
  3937. rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
  3938. duplex);
  3939. DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
  3940. vars->duplex, vars->flow_ctrl, vars->link_status);
  3941. return rc;
  3942. }
  3943. static void bnx2x_set_gmii_tx_driver(struct link_params *params)
  3944. {
  3945. struct bnx2x *bp = params->bp;
  3946. struct bnx2x_phy *phy = &params->phy[INT_PHY];
  3947. u16 lp_up2;
  3948. u16 tx_driver;
  3949. u16 bank;
  3950. /* read precomp */
  3951. CL22_RD_OVER_CL45(bp, phy,
  3952. MDIO_REG_BANK_OVER_1G,
  3953. MDIO_OVER_1G_LP_UP2, &lp_up2);
  3954. /* bits [10:7] at lp_up2, positioned at [15:12] */
  3955. lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
  3956. MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
  3957. MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
  3958. if (lp_up2 == 0)
  3959. return;
  3960. for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
  3961. bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
  3962. CL22_RD_OVER_CL45(bp, phy,
  3963. bank,
  3964. MDIO_TX0_TX_DRIVER, &tx_driver);
  3965. /* replace tx_driver bits [15:12] */
  3966. if (lp_up2 !=
  3967. (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
  3968. tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
  3969. tx_driver |= lp_up2;
  3970. CL22_WR_OVER_CL45(bp, phy,
  3971. bank,
  3972. MDIO_TX0_TX_DRIVER, tx_driver);
  3973. }
  3974. }
  3975. }
  3976. static int bnx2x_emac_program(struct link_params *params,
  3977. struct link_vars *vars)
  3978. {
  3979. struct bnx2x *bp = params->bp;
  3980. u8 port = params->port;
  3981. u16 mode = 0;
  3982. DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
  3983. bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
  3984. EMAC_REG_EMAC_MODE,
  3985. (EMAC_MODE_25G_MODE |
  3986. EMAC_MODE_PORT_MII_10M |
  3987. EMAC_MODE_HALF_DUPLEX));
  3988. switch (vars->line_speed) {
  3989. case SPEED_10:
  3990. mode |= EMAC_MODE_PORT_MII_10M;
  3991. break;
  3992. case SPEED_100:
  3993. mode |= EMAC_MODE_PORT_MII;
  3994. break;
  3995. case SPEED_1000:
  3996. mode |= EMAC_MODE_PORT_GMII;
  3997. break;
  3998. case SPEED_2500:
  3999. mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
  4000. break;
  4001. default:
  4002. /* 10G not valid for EMAC */
  4003. DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
  4004. vars->line_speed);
  4005. return -EINVAL;
  4006. }
  4007. if (vars->duplex == DUPLEX_HALF)
  4008. mode |= EMAC_MODE_HALF_DUPLEX;
  4009. bnx2x_bits_en(bp,
  4010. GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
  4011. mode);
  4012. bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
  4013. return 0;
  4014. }
  4015. static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
  4016. struct link_params *params)
  4017. {
  4018. u16 bank, i = 0;
  4019. struct bnx2x *bp = params->bp;
  4020. for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
  4021. bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
  4022. CL22_WR_OVER_CL45(bp, phy,
  4023. bank,
  4024. MDIO_RX0_RX_EQ_BOOST,
  4025. phy->rx_preemphasis[i]);
  4026. }
  4027. for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
  4028. bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
  4029. CL22_WR_OVER_CL45(bp, phy,
  4030. bank,
  4031. MDIO_TX0_TX_DRIVER,
  4032. phy->tx_preemphasis[i]);
  4033. }
  4034. }
  4035. static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
  4036. struct link_params *params,
  4037. struct link_vars *vars)
  4038. {
  4039. struct bnx2x *bp = params->bp;
  4040. u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
  4041. (params->loopback_mode == LOOPBACK_XGXS));
  4042. if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
  4043. if (SINGLE_MEDIA_DIRECT(params) &&
  4044. (params->feature_config_flags &
  4045. FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
  4046. bnx2x_set_preemphasis(phy, params);
  4047. /* forced speed requested? */
  4048. if (vars->line_speed != SPEED_AUTO_NEG ||
  4049. (SINGLE_MEDIA_DIRECT(params) &&
  4050. params->loopback_mode == LOOPBACK_EXT)) {
  4051. DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
  4052. /* disable autoneg */
  4053. bnx2x_set_autoneg(phy, params, vars, 0);
  4054. /* program speed and duplex */
  4055. bnx2x_program_serdes(phy, params, vars);
  4056. } else { /* AN_mode */
  4057. DP(NETIF_MSG_LINK, "not SGMII, AN\n");
  4058. /* AN enabled */
  4059. bnx2x_set_brcm_cl37_advertisement(phy, params);
  4060. /* program duplex & pause advertisement (for aneg) */
  4061. bnx2x_set_ieee_aneg_advertisement(phy, params,
  4062. vars->ieee_fc);
  4063. /* enable autoneg */
  4064. bnx2x_set_autoneg(phy, params, vars, enable_cl73);
  4065. /* enable and restart AN */
  4066. bnx2x_restart_autoneg(phy, params, enable_cl73);
  4067. }
  4068. } else { /* SGMII mode */
  4069. DP(NETIF_MSG_LINK, "SGMII\n");
  4070. bnx2x_initialize_sgmii_process(phy, params, vars);
  4071. }
  4072. }
  4073. static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
  4074. struct link_params *params,
  4075. struct link_vars *vars)
  4076. {
  4077. int rc;
  4078. vars->phy_flags |= PHY_XGXS_FLAG;
  4079. if ((phy->req_line_speed &&
  4080. ((phy->req_line_speed == SPEED_100) ||
  4081. (phy->req_line_speed == SPEED_10))) ||
  4082. (!phy->req_line_speed &&
  4083. (phy->speed_cap_mask >=
  4084. PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
  4085. (phy->speed_cap_mask <
  4086. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
  4087. (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
  4088. vars->phy_flags |= PHY_SGMII_FLAG;
  4089. else
  4090. vars->phy_flags &= ~PHY_SGMII_FLAG;
  4091. bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
  4092. bnx2x_set_aer_mmd(params, phy);
  4093. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
  4094. bnx2x_set_master_ln(params, phy);
  4095. rc = bnx2x_reset_unicore(params, phy, 0);
  4096. /* reset the SerDes and wait for reset bit return low */
  4097. if (rc != 0)
  4098. return rc;
  4099. bnx2x_set_aer_mmd(params, phy);
  4100. /* setting the masterLn_def again after the reset */
  4101. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
  4102. bnx2x_set_master_ln(params, phy);
  4103. bnx2x_set_swap_lanes(params, phy);
  4104. }
  4105. return rc;
  4106. }
  4107. static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
  4108. struct bnx2x_phy *phy,
  4109. struct link_params *params)
  4110. {
  4111. u16 cnt, ctrl;
  4112. /* Wait for soft reset to get cleared up to 1 sec */
  4113. for (cnt = 0; cnt < 1000; cnt++) {
  4114. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616)
  4115. bnx2x_cl22_read(bp, phy,
  4116. MDIO_PMA_REG_CTRL, &ctrl);
  4117. else
  4118. bnx2x_cl45_read(bp, phy,
  4119. MDIO_PMA_DEVAD,
  4120. MDIO_PMA_REG_CTRL, &ctrl);
  4121. if (!(ctrl & (1<<15)))
  4122. break;
  4123. msleep(1);
  4124. }
  4125. if (cnt == 1000)
  4126. netdev_err(bp->dev, "Warning: PHY was not initialized,"
  4127. " Port %d\n",
  4128. params->port);
  4129. DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
  4130. return cnt;
  4131. }
  4132. static void bnx2x_link_int_enable(struct link_params *params)
  4133. {
  4134. u8 port = params->port;
  4135. u32 mask;
  4136. struct bnx2x *bp = params->bp;
  4137. /* Setting the status to report on link up for either XGXS or SerDes */
  4138. if (CHIP_IS_E3(bp)) {
  4139. mask = NIG_MASK_XGXS0_LINK_STATUS;
  4140. if (!(SINGLE_MEDIA_DIRECT(params)))
  4141. mask |= NIG_MASK_MI_INT;
  4142. } else if (params->switch_cfg == SWITCH_CFG_10G) {
  4143. mask = (NIG_MASK_XGXS0_LINK10G |
  4144. NIG_MASK_XGXS0_LINK_STATUS);
  4145. DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
  4146. if (!(SINGLE_MEDIA_DIRECT(params)) &&
  4147. params->phy[INT_PHY].type !=
  4148. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
  4149. mask |= NIG_MASK_MI_INT;
  4150. DP(NETIF_MSG_LINK, "enabled external phy int\n");
  4151. }
  4152. } else { /* SerDes */
  4153. mask = NIG_MASK_SERDES0_LINK_STATUS;
  4154. DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
  4155. if (!(SINGLE_MEDIA_DIRECT(params)) &&
  4156. params->phy[INT_PHY].type !=
  4157. PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
  4158. mask |= NIG_MASK_MI_INT;
  4159. DP(NETIF_MSG_LINK, "enabled external phy int\n");
  4160. }
  4161. }
  4162. bnx2x_bits_en(bp,
  4163. NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
  4164. mask);
  4165. DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
  4166. (params->switch_cfg == SWITCH_CFG_10G),
  4167. REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
  4168. DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
  4169. REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
  4170. REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
  4171. REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
  4172. DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
  4173. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
  4174. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
  4175. }
  4176. static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
  4177. u8 exp_mi_int)
  4178. {
  4179. u32 latch_status = 0;
  4180. /*
  4181. * Disable the MI INT ( external phy int ) by writing 1 to the
  4182. * status register. Link down indication is high-active-signal,
  4183. * so in this case we need to write the status to clear the XOR
  4184. */
  4185. /* Read Latched signals */
  4186. latch_status = REG_RD(bp,
  4187. NIG_REG_LATCH_STATUS_0 + port*8);
  4188. DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
  4189. /* Handle only those with latched-signal=up.*/
  4190. if (exp_mi_int)
  4191. bnx2x_bits_en(bp,
  4192. NIG_REG_STATUS_INTERRUPT_PORT0
  4193. + port*4,
  4194. NIG_STATUS_EMAC0_MI_INT);
  4195. else
  4196. bnx2x_bits_dis(bp,
  4197. NIG_REG_STATUS_INTERRUPT_PORT0
  4198. + port*4,
  4199. NIG_STATUS_EMAC0_MI_INT);
  4200. if (latch_status & 1) {
  4201. /* For all latched-signal=up : Re-Arm Latch signals */
  4202. REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
  4203. (latch_status & 0xfffe) | (latch_status & 1));
  4204. }
  4205. /* For all latched-signal=up,Write original_signal to status */
  4206. }
  4207. static void bnx2x_link_int_ack(struct link_params *params,
  4208. struct link_vars *vars, u8 is_10g_plus)
  4209. {
  4210. struct bnx2x *bp = params->bp;
  4211. u8 port = params->port;
  4212. u32 mask;
  4213. /*
  4214. * First reset all status we assume only one line will be
  4215. * change at a time
  4216. */
  4217. bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
  4218. (NIG_STATUS_XGXS0_LINK10G |
  4219. NIG_STATUS_XGXS0_LINK_STATUS |
  4220. NIG_STATUS_SERDES0_LINK_STATUS));
  4221. if (vars->phy_link_up) {
  4222. if (USES_WARPCORE(bp))
  4223. mask = NIG_STATUS_XGXS0_LINK_STATUS;
  4224. else {
  4225. if (is_10g_plus)
  4226. mask = NIG_STATUS_XGXS0_LINK10G;
  4227. else if (params->switch_cfg == SWITCH_CFG_10G) {
  4228. /*
  4229. * Disable the link interrupt by writing 1 to
  4230. * the relevant lane in the status register
  4231. */
  4232. u32 ser_lane =
  4233. ((params->lane_config &
  4234. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
  4235. PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
  4236. mask = ((1 << ser_lane) <<
  4237. NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
  4238. } else
  4239. mask = NIG_STATUS_SERDES0_LINK_STATUS;
  4240. }
  4241. DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
  4242. mask);
  4243. bnx2x_bits_en(bp,
  4244. NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
  4245. mask);
  4246. }
  4247. }
  4248. static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
  4249. {
  4250. u8 *str_ptr = str;
  4251. u32 mask = 0xf0000000;
  4252. u8 shift = 8*4;
  4253. u8 digit;
  4254. u8 remove_leading_zeros = 1;
  4255. if (*len < 10) {
  4256. /* Need more than 10chars for this format */
  4257. *str_ptr = '\0';
  4258. (*len)--;
  4259. return -EINVAL;
  4260. }
  4261. while (shift > 0) {
  4262. shift -= 4;
  4263. digit = ((num & mask) >> shift);
  4264. if (digit == 0 && remove_leading_zeros) {
  4265. mask = mask >> 4;
  4266. continue;
  4267. } else if (digit < 0xa)
  4268. *str_ptr = digit + '0';
  4269. else
  4270. *str_ptr = digit - 0xa + 'a';
  4271. remove_leading_zeros = 0;
  4272. str_ptr++;
  4273. (*len)--;
  4274. mask = mask >> 4;
  4275. if (shift == 4*4) {
  4276. *str_ptr = '.';
  4277. str_ptr++;
  4278. (*len)--;
  4279. remove_leading_zeros = 1;
  4280. }
  4281. }
  4282. return 0;
  4283. }
  4284. static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
  4285. {
  4286. str[0] = '\0';
  4287. (*len)--;
  4288. return 0;
  4289. }
  4290. int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
  4291. u8 *version, u16 len)
  4292. {
  4293. struct bnx2x *bp;
  4294. u32 spirom_ver = 0;
  4295. int status = 0;
  4296. u8 *ver_p = version;
  4297. u16 remain_len = len;
  4298. if (version == NULL || params == NULL)
  4299. return -EINVAL;
  4300. bp = params->bp;
  4301. /* Extract first external phy*/
  4302. version[0] = '\0';
  4303. spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
  4304. if (params->phy[EXT_PHY1].format_fw_ver) {
  4305. status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
  4306. ver_p,
  4307. &remain_len);
  4308. ver_p += (len - remain_len);
  4309. }
  4310. if ((params->num_phys == MAX_PHYS) &&
  4311. (params->phy[EXT_PHY2].ver_addr != 0)) {
  4312. spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
  4313. if (params->phy[EXT_PHY2].format_fw_ver) {
  4314. *ver_p = '/';
  4315. ver_p++;
  4316. remain_len--;
  4317. status |= params->phy[EXT_PHY2].format_fw_ver(
  4318. spirom_ver,
  4319. ver_p,
  4320. &remain_len);
  4321. ver_p = version + (len - remain_len);
  4322. }
  4323. }
  4324. *ver_p = '\0';
  4325. return status;
  4326. }
  4327. static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
  4328. struct link_params *params)
  4329. {
  4330. u8 port = params->port;
  4331. struct bnx2x *bp = params->bp;
  4332. if (phy->req_line_speed != SPEED_1000) {
  4333. u32 md_devad = 0;
  4334. DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
  4335. if (!CHIP_IS_E3(bp)) {
  4336. /* change the uni_phy_addr in the nig */
  4337. md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
  4338. port*0x18));
  4339. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
  4340. 0x5);
  4341. }
  4342. bnx2x_cl45_write(bp, phy,
  4343. 5,
  4344. (MDIO_REG_BANK_AER_BLOCK +
  4345. (MDIO_AER_BLOCK_AER_REG & 0xf)),
  4346. 0x2800);
  4347. bnx2x_cl45_write(bp, phy,
  4348. 5,
  4349. (MDIO_REG_BANK_CL73_IEEEB0 +
  4350. (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
  4351. 0x6041);
  4352. msleep(200);
  4353. /* set aer mmd back */
  4354. bnx2x_set_aer_mmd(params, phy);
  4355. if (!CHIP_IS_E3(bp)) {
  4356. /* and md_devad */
  4357. REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
  4358. md_devad);
  4359. }
  4360. } else {
  4361. u16 mii_ctrl;
  4362. DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
  4363. bnx2x_cl45_read(bp, phy, 5,
  4364. (MDIO_REG_BANK_COMBO_IEEE0 +
  4365. (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
  4366. &mii_ctrl);
  4367. bnx2x_cl45_write(bp, phy, 5,
  4368. (MDIO_REG_BANK_COMBO_IEEE0 +
  4369. (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
  4370. mii_ctrl |
  4371. MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
  4372. }
  4373. }
  4374. int bnx2x_set_led(struct link_params *params,
  4375. struct link_vars *vars, u8 mode, u32 speed)
  4376. {
  4377. u8 port = params->port;
  4378. u16 hw_led_mode = params->hw_led_mode;
  4379. int rc = 0;
  4380. u8 phy_idx;
  4381. u32 tmp;
  4382. u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
  4383. struct bnx2x *bp = params->bp;
  4384. DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
  4385. DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
  4386. speed, hw_led_mode);
  4387. /* In case */
  4388. for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
  4389. if (params->phy[phy_idx].set_link_led) {
  4390. params->phy[phy_idx].set_link_led(
  4391. &params->phy[phy_idx], params, mode);
  4392. }
  4393. }
  4394. switch (mode) {
  4395. case LED_MODE_FRONT_PANEL_OFF:
  4396. case LED_MODE_OFF:
  4397. REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
  4398. REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
  4399. SHARED_HW_CFG_LED_MAC1);
  4400. tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
  4401. EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
  4402. break;
  4403. case LED_MODE_OPER:
  4404. /*
  4405. * For all other phys, OPER mode is same as ON, so in case
  4406. * link is down, do nothing
  4407. */
  4408. if (!vars->link_up)
  4409. break;
  4410. case LED_MODE_ON:
  4411. if (((params->phy[EXT_PHY1].type ==
  4412. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
  4413. (params->phy[EXT_PHY1].type ==
  4414. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
  4415. CHIP_IS_E2(bp) && params->num_phys == 2) {
  4416. /*
  4417. * This is a work-around for E2+8727 Configurations
  4418. */
  4419. if (mode == LED_MODE_ON ||
  4420. speed == SPEED_10000){
  4421. REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
  4422. REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
  4423. tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
  4424. EMAC_WR(bp, EMAC_REG_EMAC_LED,
  4425. (tmp | EMAC_LED_OVERRIDE));
  4426. return rc;
  4427. }
  4428. } else if (SINGLE_MEDIA_DIRECT(params) &&
  4429. (CHIP_IS_E1x(bp) ||
  4430. CHIP_IS_E2(bp))) {
  4431. /*
  4432. * This is a work-around for HW issue found when link
  4433. * is up in CL73
  4434. */
  4435. REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
  4436. REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
  4437. } else {
  4438. REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
  4439. }
  4440. REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
  4441. /* Set blinking rate to ~15.9Hz */
  4442. REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
  4443. LED_BLINK_RATE_VAL);
  4444. REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
  4445. port*4, 1);
  4446. tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
  4447. EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
  4448. if (CHIP_IS_E1(bp) &&
  4449. ((speed == SPEED_2500) ||
  4450. (speed == SPEED_1000) ||
  4451. (speed == SPEED_100) ||
  4452. (speed == SPEED_10))) {
  4453. /*
  4454. * On Everest 1 Ax chip versions for speeds less than
  4455. * 10G LED scheme is different
  4456. */
  4457. REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
  4458. + port*4, 1);
  4459. REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
  4460. port*4, 0);
  4461. REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
  4462. port*4, 1);
  4463. }
  4464. break;
  4465. default:
  4466. rc = -EINVAL;
  4467. DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
  4468. mode);
  4469. break;
  4470. }
  4471. return rc;
  4472. }
  4473. /*
  4474. * This function comes to reflect the actual link state read DIRECTLY from the
  4475. * HW
  4476. */
  4477. int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
  4478. u8 is_serdes)
  4479. {
  4480. struct bnx2x *bp = params->bp;
  4481. u16 gp_status = 0, phy_index = 0;
  4482. u8 ext_phy_link_up = 0, serdes_phy_type;
  4483. struct link_vars temp_vars;
  4484. struct bnx2x_phy *int_phy = &params->phy[INT_PHY];
  4485. if (CHIP_IS_E3(bp)) {
  4486. u16 link_up;
  4487. if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
  4488. > SPEED_10000) {
  4489. /* Check 20G link */
  4490. bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
  4491. 1, &link_up);
  4492. bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
  4493. 1, &link_up);
  4494. link_up &= (1<<2);
  4495. } else {
  4496. /* Check 10G link and below*/
  4497. u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
  4498. bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
  4499. MDIO_WC_REG_GP2_STATUS_GP_2_1,
  4500. &gp_status);
  4501. gp_status = ((gp_status >> 8) & 0xf) |
  4502. ((gp_status >> 12) & 0xf);
  4503. link_up = gp_status & (1 << lane);
  4504. }
  4505. if (!link_up)
  4506. return -ESRCH;
  4507. } else {
  4508. CL22_RD_OVER_CL45(bp, int_phy,
  4509. MDIO_REG_BANK_GP_STATUS,
  4510. MDIO_GP_STATUS_TOP_AN_STATUS1,
  4511. &gp_status);
  4512. /* link is up only if both local phy and external phy are up */
  4513. if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
  4514. return -ESRCH;
  4515. }
  4516. /* In XGXS loopback mode, do not check external PHY */
  4517. if (params->loopback_mode == LOOPBACK_XGXS)
  4518. return 0;
  4519. switch (params->num_phys) {
  4520. case 1:
  4521. /* No external PHY */
  4522. return 0;
  4523. case 2:
  4524. ext_phy_link_up = params->phy[EXT_PHY1].read_status(
  4525. &params->phy[EXT_PHY1],
  4526. params, &temp_vars);
  4527. break;
  4528. case 3: /* Dual Media */
  4529. for (phy_index = EXT_PHY1; phy_index < params->num_phys;
  4530. phy_index++) {
  4531. serdes_phy_type = ((params->phy[phy_index].media_type ==
  4532. ETH_PHY_SFP_FIBER) ||
  4533. (params->phy[phy_index].media_type ==
  4534. ETH_PHY_XFP_FIBER) ||
  4535. (params->phy[phy_index].media_type ==
  4536. ETH_PHY_DA_TWINAX));
  4537. if (is_serdes != serdes_phy_type)
  4538. continue;
  4539. if (params->phy[phy_index].read_status) {
  4540. ext_phy_link_up |=
  4541. params->phy[phy_index].read_status(
  4542. &params->phy[phy_index],
  4543. params, &temp_vars);
  4544. }
  4545. }
  4546. break;
  4547. }
  4548. if (ext_phy_link_up)
  4549. return 0;
  4550. return -ESRCH;
  4551. }
  4552. static int bnx2x_link_initialize(struct link_params *params,
  4553. struct link_vars *vars)
  4554. {
  4555. int rc = 0;
  4556. u8 phy_index, non_ext_phy;
  4557. struct bnx2x *bp = params->bp;
  4558. /*
  4559. * In case of external phy existence, the line speed would be the
  4560. * line speed linked up by the external phy. In case it is direct
  4561. * only, then the line_speed during initialization will be
  4562. * equal to the req_line_speed
  4563. */
  4564. vars->line_speed = params->phy[INT_PHY].req_line_speed;
  4565. /*
  4566. * Initialize the internal phy in case this is a direct board
  4567. * (no external phys), or this board has external phy which requires
  4568. * to first.
  4569. */
  4570. if (!USES_WARPCORE(bp))
  4571. bnx2x_prepare_xgxs(&params->phy[INT_PHY], params, vars);
  4572. /* init ext phy and enable link state int */
  4573. non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
  4574. (params->loopback_mode == LOOPBACK_XGXS));
  4575. if (non_ext_phy ||
  4576. (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
  4577. (params->loopback_mode == LOOPBACK_EXT_PHY)) {
  4578. struct bnx2x_phy *phy = &params->phy[INT_PHY];
  4579. if (vars->line_speed == SPEED_AUTO_NEG &&
  4580. (CHIP_IS_E1x(bp) ||
  4581. CHIP_IS_E2(bp)))
  4582. bnx2x_set_parallel_detection(phy, params);
  4583. if (params->phy[INT_PHY].config_init)
  4584. params->phy[INT_PHY].config_init(phy,
  4585. params,
  4586. vars);
  4587. }
  4588. /* Init external phy*/
  4589. if (non_ext_phy) {
  4590. if (params->phy[INT_PHY].supported &
  4591. SUPPORTED_FIBRE)
  4592. vars->link_status |= LINK_STATUS_SERDES_LINK;
  4593. } else {
  4594. for (phy_index = EXT_PHY1; phy_index < params->num_phys;
  4595. phy_index++) {
  4596. /*
  4597. * No need to initialize second phy in case of first
  4598. * phy only selection. In case of second phy, we do
  4599. * need to initialize the first phy, since they are
  4600. * connected.
  4601. */
  4602. if (params->phy[phy_index].supported &
  4603. SUPPORTED_FIBRE)
  4604. vars->link_status |= LINK_STATUS_SERDES_LINK;
  4605. if (phy_index == EXT_PHY2 &&
  4606. (bnx2x_phy_selection(params) ==
  4607. PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
  4608. DP(NETIF_MSG_LINK, "Not initializing"
  4609. " second phy\n");
  4610. continue;
  4611. }
  4612. params->phy[phy_index].config_init(
  4613. &params->phy[phy_index],
  4614. params, vars);
  4615. }
  4616. }
  4617. /* Reset the interrupt indication after phy was initialized */
  4618. bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
  4619. params->port*4,
  4620. (NIG_STATUS_XGXS0_LINK10G |
  4621. NIG_STATUS_XGXS0_LINK_STATUS |
  4622. NIG_STATUS_SERDES0_LINK_STATUS |
  4623. NIG_MASK_MI_INT));
  4624. bnx2x_update_mng(params, vars->link_status);
  4625. return rc;
  4626. }
  4627. static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
  4628. struct link_params *params)
  4629. {
  4630. /* reset the SerDes/XGXS */
  4631. REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
  4632. (0x1ff << (params->port*16)));
  4633. }
  4634. static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
  4635. struct link_params *params)
  4636. {
  4637. struct bnx2x *bp = params->bp;
  4638. u8 gpio_port;
  4639. /* HW reset */
  4640. if (CHIP_IS_E2(bp))
  4641. gpio_port = BP_PATH(bp);
  4642. else
  4643. gpio_port = params->port;
  4644. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  4645. MISC_REGISTERS_GPIO_OUTPUT_LOW,
  4646. gpio_port);
  4647. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  4648. MISC_REGISTERS_GPIO_OUTPUT_LOW,
  4649. gpio_port);
  4650. DP(NETIF_MSG_LINK, "reset external PHY\n");
  4651. }
  4652. static int bnx2x_update_link_down(struct link_params *params,
  4653. struct link_vars *vars)
  4654. {
  4655. struct bnx2x *bp = params->bp;
  4656. u8 port = params->port;
  4657. DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
  4658. bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
  4659. /* indicate no mac active */
  4660. vars->mac_type = MAC_TYPE_NONE;
  4661. /* update shared memory */
  4662. vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
  4663. LINK_STATUS_LINK_UP |
  4664. LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
  4665. LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
  4666. LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
  4667. LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK);
  4668. vars->line_speed = 0;
  4669. bnx2x_update_mng(params, vars->link_status);
  4670. /* activate nig drain */
  4671. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
  4672. /* disable emac */
  4673. if (!CHIP_IS_E3(bp))
  4674. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
  4675. msleep(10);
  4676. /* reset BigMac/Xmac */
  4677. if (CHIP_IS_E1x(bp) ||
  4678. CHIP_IS_E2(bp)) {
  4679. bnx2x_bmac_rx_disable(bp, params->port);
  4680. REG_WR(bp, GRCBASE_MISC +
  4681. MISC_REGISTERS_RESET_REG_2_CLEAR,
  4682. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  4683. }
  4684. if (CHIP_IS_E3(bp))
  4685. bnx2x_xmac_disable(params);
  4686. return 0;
  4687. }
  4688. static int bnx2x_update_link_up(struct link_params *params,
  4689. struct link_vars *vars,
  4690. u8 link_10g)
  4691. {
  4692. struct bnx2x *bp = params->bp;
  4693. u8 port = params->port;
  4694. int rc = 0;
  4695. vars->link_status |= LINK_STATUS_LINK_UP;
  4696. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
  4697. vars->link_status |=
  4698. LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
  4699. if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
  4700. vars->link_status |=
  4701. LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
  4702. if (USES_WARPCORE(bp)) {
  4703. if (link_10g)
  4704. bnx2x_xmac_enable(params, vars, 0);
  4705. else
  4706. bnx2x_umac_enable(params, vars, 0);
  4707. bnx2x_set_led(params, vars,
  4708. LED_MODE_OPER, vars->line_speed);
  4709. }
  4710. if ((CHIP_IS_E1x(bp) ||
  4711. CHIP_IS_E2(bp))) {
  4712. if (link_10g) {
  4713. bnx2x_bmac_enable(params, vars, 0);
  4714. bnx2x_set_led(params, vars,
  4715. LED_MODE_OPER, SPEED_10000);
  4716. } else {
  4717. rc = bnx2x_emac_program(params, vars);
  4718. bnx2x_emac_enable(params, vars, 0);
  4719. /* AN complete? */
  4720. if ((vars->link_status &
  4721. LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
  4722. && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
  4723. SINGLE_MEDIA_DIRECT(params))
  4724. bnx2x_set_gmii_tx_driver(params);
  4725. }
  4726. }
  4727. /* PBF - link up */
  4728. if (CHIP_IS_E1x(bp))
  4729. rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
  4730. vars->line_speed);
  4731. /* disable drain */
  4732. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
  4733. /* update shared memory */
  4734. bnx2x_update_mng(params, vars->link_status);
  4735. msleep(20);
  4736. return rc;
  4737. }
  4738. /*
  4739. * The bnx2x_link_update function should be called upon link
  4740. * interrupt.
  4741. * Link is considered up as follows:
  4742. * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
  4743. * to be up
  4744. * - SINGLE_MEDIA - The link between the 577xx and the external
  4745. * phy (XGXS) need to up as well as the external link of the
  4746. * phy (PHY_EXT1)
  4747. * - DUAL_MEDIA - The link between the 577xx and the first
  4748. * external phy needs to be up, and at least one of the 2
  4749. * external phy link must be up.
  4750. */
  4751. int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
  4752. {
  4753. struct bnx2x *bp = params->bp;
  4754. struct link_vars phy_vars[MAX_PHYS];
  4755. u8 port = params->port;
  4756. u8 link_10g_plus, phy_index;
  4757. u8 ext_phy_link_up = 0, cur_link_up;
  4758. int rc = 0;
  4759. u8 is_mi_int = 0;
  4760. u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
  4761. u8 active_external_phy = INT_PHY;
  4762. for (phy_index = INT_PHY; phy_index < params->num_phys;
  4763. phy_index++) {
  4764. phy_vars[phy_index].flow_ctrl = 0;
  4765. phy_vars[phy_index].link_status = 0;
  4766. phy_vars[phy_index].line_speed = 0;
  4767. phy_vars[phy_index].duplex = DUPLEX_FULL;
  4768. phy_vars[phy_index].phy_link_up = 0;
  4769. phy_vars[phy_index].link_up = 0;
  4770. phy_vars[phy_index].fault_detected = 0;
  4771. }
  4772. if (USES_WARPCORE(bp))
  4773. bnx2x_set_aer_mmd(params, &params->phy[INT_PHY]);
  4774. DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
  4775. port, (vars->phy_flags & PHY_XGXS_FLAG),
  4776. REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
  4777. is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
  4778. port*0x18) > 0);
  4779. DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
  4780. REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
  4781. is_mi_int,
  4782. REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
  4783. DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
  4784. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
  4785. REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
  4786. /* disable emac */
  4787. if (!CHIP_IS_E3(bp))
  4788. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
  4789. /*
  4790. * Step 1:
  4791. * Check external link change only for external phys, and apply
  4792. * priority selection between them in case the link on both phys
  4793. * is up. Note that instead of the common vars, a temporary
  4794. * vars argument is used since each phy may have different link/
  4795. * speed/duplex result
  4796. */
  4797. for (phy_index = EXT_PHY1; phy_index < params->num_phys;
  4798. phy_index++) {
  4799. struct bnx2x_phy *phy = &params->phy[phy_index];
  4800. if (!phy->read_status)
  4801. continue;
  4802. /* Read link status and params of this ext phy */
  4803. cur_link_up = phy->read_status(phy, params,
  4804. &phy_vars[phy_index]);
  4805. if (cur_link_up) {
  4806. DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
  4807. phy_index);
  4808. } else {
  4809. DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
  4810. phy_index);
  4811. continue;
  4812. }
  4813. if (!ext_phy_link_up) {
  4814. ext_phy_link_up = 1;
  4815. active_external_phy = phy_index;
  4816. } else {
  4817. switch (bnx2x_phy_selection(params)) {
  4818. case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
  4819. case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
  4820. /*
  4821. * In this option, the first PHY makes sure to pass the
  4822. * traffic through itself only.
  4823. * Its not clear how to reset the link on the second phy
  4824. */
  4825. active_external_phy = EXT_PHY1;
  4826. break;
  4827. case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
  4828. /*
  4829. * In this option, the first PHY makes sure to pass the
  4830. * traffic through the second PHY.
  4831. */
  4832. active_external_phy = EXT_PHY2;
  4833. break;
  4834. default:
  4835. /*
  4836. * Link indication on both PHYs with the following cases
  4837. * is invalid:
  4838. * - FIRST_PHY means that second phy wasn't initialized,
  4839. * hence its link is expected to be down
  4840. * - SECOND_PHY means that first phy should not be able
  4841. * to link up by itself (using configuration)
  4842. * - DEFAULT should be overriden during initialiazation
  4843. */
  4844. DP(NETIF_MSG_LINK, "Invalid link indication"
  4845. "mpc=0x%x. DISABLING LINK !!!\n",
  4846. params->multi_phy_config);
  4847. ext_phy_link_up = 0;
  4848. break;
  4849. }
  4850. }
  4851. }
  4852. prev_line_speed = vars->line_speed;
  4853. /*
  4854. * Step 2:
  4855. * Read the status of the internal phy. In case of
  4856. * DIRECT_SINGLE_MEDIA board, this link is the external link,
  4857. * otherwise this is the link between the 577xx and the first
  4858. * external phy
  4859. */
  4860. if (params->phy[INT_PHY].read_status)
  4861. params->phy[INT_PHY].read_status(
  4862. &params->phy[INT_PHY],
  4863. params, vars);
  4864. /*
  4865. * The INT_PHY flow control reside in the vars. This include the
  4866. * case where the speed or flow control are not set to AUTO.
  4867. * Otherwise, the active external phy flow control result is set
  4868. * to the vars. The ext_phy_line_speed is needed to check if the
  4869. * speed is different between the internal phy and external phy.
  4870. * This case may be result of intermediate link speed change.
  4871. */
  4872. if (active_external_phy > INT_PHY) {
  4873. vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
  4874. /*
  4875. * Link speed is taken from the XGXS. AN and FC result from
  4876. * the external phy.
  4877. */
  4878. vars->link_status |= phy_vars[active_external_phy].link_status;
  4879. /*
  4880. * if active_external_phy is first PHY and link is up - disable
  4881. * disable TX on second external PHY
  4882. */
  4883. if (active_external_phy == EXT_PHY1) {
  4884. if (params->phy[EXT_PHY2].phy_specific_func) {
  4885. DP(NETIF_MSG_LINK, "Disabling TX on"
  4886. " EXT_PHY2\n");
  4887. params->phy[EXT_PHY2].phy_specific_func(
  4888. &params->phy[EXT_PHY2],
  4889. params, DISABLE_TX);
  4890. }
  4891. }
  4892. ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
  4893. vars->duplex = phy_vars[active_external_phy].duplex;
  4894. if (params->phy[active_external_phy].supported &
  4895. SUPPORTED_FIBRE)
  4896. vars->link_status |= LINK_STATUS_SERDES_LINK;
  4897. else
  4898. vars->link_status &= ~LINK_STATUS_SERDES_LINK;
  4899. DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
  4900. active_external_phy);
  4901. }
  4902. for (phy_index = EXT_PHY1; phy_index < params->num_phys;
  4903. phy_index++) {
  4904. if (params->phy[phy_index].flags &
  4905. FLAGS_REARM_LATCH_SIGNAL) {
  4906. bnx2x_rearm_latch_signal(bp, port,
  4907. phy_index ==
  4908. active_external_phy);
  4909. break;
  4910. }
  4911. }
  4912. DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
  4913. " ext_phy_line_speed = %d\n", vars->flow_ctrl,
  4914. vars->link_status, ext_phy_line_speed);
  4915. /*
  4916. * Upon link speed change set the NIG into drain mode. Comes to
  4917. * deals with possible FIFO glitch due to clk change when speed
  4918. * is decreased without link down indicator
  4919. */
  4920. if (vars->phy_link_up) {
  4921. if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
  4922. (ext_phy_line_speed != vars->line_speed)) {
  4923. DP(NETIF_MSG_LINK, "Internal link speed %d is"
  4924. " different than the external"
  4925. " link speed %d\n", vars->line_speed,
  4926. ext_phy_line_speed);
  4927. vars->phy_link_up = 0;
  4928. } else if (prev_line_speed != vars->line_speed) {
  4929. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
  4930. 0);
  4931. msleep(1);
  4932. }
  4933. }
  4934. /* anything 10 and over uses the bmac */
  4935. link_10g_plus = (vars->line_speed >= SPEED_10000);
  4936. bnx2x_link_int_ack(params, vars, link_10g_plus);
  4937. /*
  4938. * In case external phy link is up, and internal link is down
  4939. * (not initialized yet probably after link initialization, it
  4940. * needs to be initialized.
  4941. * Note that after link down-up as result of cable plug, the xgxs
  4942. * link would probably become up again without the need
  4943. * initialize it
  4944. */
  4945. if (!(SINGLE_MEDIA_DIRECT(params))) {
  4946. DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
  4947. " init_preceding = %d\n", ext_phy_link_up,
  4948. vars->phy_link_up,
  4949. params->phy[EXT_PHY1].flags &
  4950. FLAGS_INIT_XGXS_FIRST);
  4951. if (!(params->phy[EXT_PHY1].flags &
  4952. FLAGS_INIT_XGXS_FIRST)
  4953. && ext_phy_link_up && !vars->phy_link_up) {
  4954. vars->line_speed = ext_phy_line_speed;
  4955. if (vars->line_speed < SPEED_1000)
  4956. vars->phy_flags |= PHY_SGMII_FLAG;
  4957. else
  4958. vars->phy_flags &= ~PHY_SGMII_FLAG;
  4959. if (params->phy[INT_PHY].config_init)
  4960. params->phy[INT_PHY].config_init(
  4961. &params->phy[INT_PHY], params,
  4962. vars);
  4963. }
  4964. }
  4965. /*
  4966. * Link is up only if both local phy and external phy (in case of
  4967. * non-direct board) are up and no fault detected on active PHY.
  4968. */
  4969. vars->link_up = (vars->phy_link_up &&
  4970. (ext_phy_link_up ||
  4971. SINGLE_MEDIA_DIRECT(params)) &&
  4972. (phy_vars[active_external_phy].fault_detected == 0));
  4973. if (vars->link_up)
  4974. rc = bnx2x_update_link_up(params, vars, link_10g_plus);
  4975. else
  4976. rc = bnx2x_update_link_down(params, vars);
  4977. return rc;
  4978. }
  4979. /*****************************************************************************/
  4980. /* External Phy section */
  4981. /*****************************************************************************/
  4982. void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
  4983. {
  4984. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  4985. MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
  4986. msleep(1);
  4987. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  4988. MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
  4989. }
  4990. static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
  4991. u32 spirom_ver, u32 ver_addr)
  4992. {
  4993. DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
  4994. (u16)(spirom_ver>>16), (u16)spirom_ver, port);
  4995. if (ver_addr)
  4996. REG_WR(bp, ver_addr, spirom_ver);
  4997. }
  4998. static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
  4999. struct bnx2x_phy *phy,
  5000. u8 port)
  5001. {
  5002. u16 fw_ver1, fw_ver2;
  5003. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
  5004. MDIO_PMA_REG_ROM_VER1, &fw_ver1);
  5005. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
  5006. MDIO_PMA_REG_ROM_VER2, &fw_ver2);
  5007. bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
  5008. phy->ver_addr);
  5009. }
  5010. static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
  5011. struct bnx2x_phy *phy,
  5012. struct link_vars *vars)
  5013. {
  5014. u16 val;
  5015. bnx2x_cl45_read(bp, phy,
  5016. MDIO_AN_DEVAD,
  5017. MDIO_AN_REG_STATUS, &val);
  5018. bnx2x_cl45_read(bp, phy,
  5019. MDIO_AN_DEVAD,
  5020. MDIO_AN_REG_STATUS, &val);
  5021. if (val & (1<<5))
  5022. vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
  5023. if ((val & (1<<0)) == 0)
  5024. vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
  5025. }
  5026. /******************************************************************/
  5027. /* common BCM8073/BCM8727 PHY SECTION */
  5028. /******************************************************************/
  5029. static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
  5030. struct link_params *params,
  5031. struct link_vars *vars)
  5032. {
  5033. struct bnx2x *bp = params->bp;
  5034. if (phy->req_line_speed == SPEED_10 ||
  5035. phy->req_line_speed == SPEED_100) {
  5036. vars->flow_ctrl = phy->req_flow_ctrl;
  5037. return;
  5038. }
  5039. if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
  5040. (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
  5041. u16 pause_result;
  5042. u16 ld_pause; /* local */
  5043. u16 lp_pause; /* link partner */
  5044. bnx2x_cl45_read(bp, phy,
  5045. MDIO_AN_DEVAD,
  5046. MDIO_AN_REG_CL37_FC_LD, &ld_pause);
  5047. bnx2x_cl45_read(bp, phy,
  5048. MDIO_AN_DEVAD,
  5049. MDIO_AN_REG_CL37_FC_LP, &lp_pause);
  5050. pause_result = (ld_pause &
  5051. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
  5052. pause_result |= (lp_pause &
  5053. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
  5054. bnx2x_pause_resolve(vars, pause_result);
  5055. DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
  5056. pause_result);
  5057. }
  5058. }
  5059. static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
  5060. struct bnx2x_phy *phy,
  5061. u8 port)
  5062. {
  5063. u32 count = 0;
  5064. u16 fw_ver1, fw_msgout;
  5065. int rc = 0;
  5066. /* Boot port from external ROM */
  5067. /* EDC grst */
  5068. bnx2x_cl45_write(bp, phy,
  5069. MDIO_PMA_DEVAD,
  5070. MDIO_PMA_REG_GEN_CTRL,
  5071. 0x0001);
  5072. /* ucode reboot and rst */
  5073. bnx2x_cl45_write(bp, phy,
  5074. MDIO_PMA_DEVAD,
  5075. MDIO_PMA_REG_GEN_CTRL,
  5076. 0x008c);
  5077. bnx2x_cl45_write(bp, phy,
  5078. MDIO_PMA_DEVAD,
  5079. MDIO_PMA_REG_MISC_CTRL1, 0x0001);
  5080. /* Reset internal microprocessor */
  5081. bnx2x_cl45_write(bp, phy,
  5082. MDIO_PMA_DEVAD,
  5083. MDIO_PMA_REG_GEN_CTRL,
  5084. MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
  5085. /* Release srst bit */
  5086. bnx2x_cl45_write(bp, phy,
  5087. MDIO_PMA_DEVAD,
  5088. MDIO_PMA_REG_GEN_CTRL,
  5089. MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
  5090. /* Delay 100ms per the PHY specifications */
  5091. msleep(100);
  5092. /* 8073 sometimes taking longer to download */
  5093. do {
  5094. count++;
  5095. if (count > 300) {
  5096. DP(NETIF_MSG_LINK,
  5097. "bnx2x_8073_8727_external_rom_boot port %x:"
  5098. "Download failed. fw version = 0x%x\n",
  5099. port, fw_ver1);
  5100. rc = -EINVAL;
  5101. break;
  5102. }
  5103. bnx2x_cl45_read(bp, phy,
  5104. MDIO_PMA_DEVAD,
  5105. MDIO_PMA_REG_ROM_VER1, &fw_ver1);
  5106. bnx2x_cl45_read(bp, phy,
  5107. MDIO_PMA_DEVAD,
  5108. MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
  5109. msleep(1);
  5110. } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
  5111. ((fw_msgout & 0xff) != 0x03 && (phy->type ==
  5112. PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
  5113. /* Clear ser_boot_ctl bit */
  5114. bnx2x_cl45_write(bp, phy,
  5115. MDIO_PMA_DEVAD,
  5116. MDIO_PMA_REG_MISC_CTRL1, 0x0000);
  5117. bnx2x_save_bcm_spirom_ver(bp, phy, port);
  5118. DP(NETIF_MSG_LINK,
  5119. "bnx2x_8073_8727_external_rom_boot port %x:"
  5120. "Download complete. fw version = 0x%x\n",
  5121. port, fw_ver1);
  5122. return rc;
  5123. }
  5124. /******************************************************************/
  5125. /* BCM8073 PHY SECTION */
  5126. /******************************************************************/
  5127. static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
  5128. {
  5129. /* This is only required for 8073A1, version 102 only */
  5130. u16 val;
  5131. /* Read 8073 HW revision*/
  5132. bnx2x_cl45_read(bp, phy,
  5133. MDIO_PMA_DEVAD,
  5134. MDIO_PMA_REG_8073_CHIP_REV, &val);
  5135. if (val != 1) {
  5136. /* No need to workaround in 8073 A1 */
  5137. return 0;
  5138. }
  5139. bnx2x_cl45_read(bp, phy,
  5140. MDIO_PMA_DEVAD,
  5141. MDIO_PMA_REG_ROM_VER2, &val);
  5142. /* SNR should be applied only for version 0x102 */
  5143. if (val != 0x102)
  5144. return 0;
  5145. return 1;
  5146. }
  5147. static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
  5148. {
  5149. u16 val, cnt, cnt1 ;
  5150. bnx2x_cl45_read(bp, phy,
  5151. MDIO_PMA_DEVAD,
  5152. MDIO_PMA_REG_8073_CHIP_REV, &val);
  5153. if (val > 0) {
  5154. /* No need to workaround in 8073 A1 */
  5155. return 0;
  5156. }
  5157. /* XAUI workaround in 8073 A0: */
  5158. /*
  5159. * After loading the boot ROM and restarting Autoneg, poll
  5160. * Dev1, Reg $C820:
  5161. */
  5162. for (cnt = 0; cnt < 1000; cnt++) {
  5163. bnx2x_cl45_read(bp, phy,
  5164. MDIO_PMA_DEVAD,
  5165. MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
  5166. &val);
  5167. /*
  5168. * If bit [14] = 0 or bit [13] = 0, continue on with
  5169. * system initialization (XAUI work-around not required, as
  5170. * these bits indicate 2.5G or 1G link up).
  5171. */
  5172. if (!(val & (1<<14)) || !(val & (1<<13))) {
  5173. DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
  5174. return 0;
  5175. } else if (!(val & (1<<15))) {
  5176. DP(NETIF_MSG_LINK, "bit 15 went off\n");
  5177. /*
  5178. * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
  5179. * MSB (bit15) goes to 1 (indicating that the XAUI
  5180. * workaround has completed), then continue on with
  5181. * system initialization.
  5182. */
  5183. for (cnt1 = 0; cnt1 < 1000; cnt1++) {
  5184. bnx2x_cl45_read(bp, phy,
  5185. MDIO_PMA_DEVAD,
  5186. MDIO_PMA_REG_8073_XAUI_WA, &val);
  5187. if (val & (1<<15)) {
  5188. DP(NETIF_MSG_LINK,
  5189. "XAUI workaround has completed\n");
  5190. return 0;
  5191. }
  5192. msleep(3);
  5193. }
  5194. break;
  5195. }
  5196. msleep(3);
  5197. }
  5198. DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
  5199. return -EINVAL;
  5200. }
  5201. static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
  5202. {
  5203. /* Force KR or KX */
  5204. bnx2x_cl45_write(bp, phy,
  5205. MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
  5206. bnx2x_cl45_write(bp, phy,
  5207. MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
  5208. bnx2x_cl45_write(bp, phy,
  5209. MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
  5210. bnx2x_cl45_write(bp, phy,
  5211. MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
  5212. }
  5213. static void bnx2x_8073_set_pause_cl37(struct link_params *params,
  5214. struct bnx2x_phy *phy,
  5215. struct link_vars *vars)
  5216. {
  5217. u16 cl37_val;
  5218. struct bnx2x *bp = params->bp;
  5219. bnx2x_cl45_read(bp, phy,
  5220. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
  5221. cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  5222. /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
  5223. bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
  5224. if ((vars->ieee_fc &
  5225. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
  5226. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
  5227. cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
  5228. }
  5229. if ((vars->ieee_fc &
  5230. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
  5231. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
  5232. cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
  5233. }
  5234. if ((vars->ieee_fc &
  5235. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
  5236. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
  5237. cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
  5238. }
  5239. DP(NETIF_MSG_LINK,
  5240. "Ext phy AN advertize cl37 0x%x\n", cl37_val);
  5241. bnx2x_cl45_write(bp, phy,
  5242. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
  5243. msleep(500);
  5244. }
  5245. static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
  5246. struct link_params *params,
  5247. struct link_vars *vars)
  5248. {
  5249. struct bnx2x *bp = params->bp;
  5250. u16 val = 0, tmp1;
  5251. u8 gpio_port;
  5252. DP(NETIF_MSG_LINK, "Init 8073\n");
  5253. if (CHIP_IS_E2(bp))
  5254. gpio_port = BP_PATH(bp);
  5255. else
  5256. gpio_port = params->port;
  5257. /* Restore normal power mode*/
  5258. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  5259. MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
  5260. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  5261. MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
  5262. /* enable LASI */
  5263. bnx2x_cl45_write(bp, phy,
  5264. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
  5265. bnx2x_cl45_write(bp, phy,
  5266. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
  5267. bnx2x_8073_set_pause_cl37(params, phy, vars);
  5268. bnx2x_cl45_read(bp, phy,
  5269. MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
  5270. bnx2x_cl45_read(bp, phy,
  5271. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
  5272. DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
  5273. /* Swap polarity if required - Must be done only in non-1G mode */
  5274. if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
  5275. /* Configure the 8073 to swap _P and _N of the KR lines */
  5276. DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
  5277. /* 10G Rx/Tx and 1G Tx signal polarity swap */
  5278. bnx2x_cl45_read(bp, phy,
  5279. MDIO_PMA_DEVAD,
  5280. MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
  5281. bnx2x_cl45_write(bp, phy,
  5282. MDIO_PMA_DEVAD,
  5283. MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
  5284. (val | (3<<9)));
  5285. }
  5286. /* Enable CL37 BAM */
  5287. if (REG_RD(bp, params->shmem_base +
  5288. offsetof(struct shmem_region, dev_info.
  5289. port_hw_config[params->port].default_cfg)) &
  5290. PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
  5291. bnx2x_cl45_read(bp, phy,
  5292. MDIO_AN_DEVAD,
  5293. MDIO_AN_REG_8073_BAM, &val);
  5294. bnx2x_cl45_write(bp, phy,
  5295. MDIO_AN_DEVAD,
  5296. MDIO_AN_REG_8073_BAM, val | 1);
  5297. DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
  5298. }
  5299. if (params->loopback_mode == LOOPBACK_EXT) {
  5300. bnx2x_807x_force_10G(bp, phy);
  5301. DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
  5302. return 0;
  5303. } else {
  5304. bnx2x_cl45_write(bp, phy,
  5305. MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
  5306. }
  5307. if (phy->req_line_speed != SPEED_AUTO_NEG) {
  5308. if (phy->req_line_speed == SPEED_10000) {
  5309. val = (1<<7);
  5310. } else if (phy->req_line_speed == SPEED_2500) {
  5311. val = (1<<5);
  5312. /*
  5313. * Note that 2.5G works only when used with 1G
  5314. * advertisement
  5315. */
  5316. } else
  5317. val = (1<<5);
  5318. } else {
  5319. val = 0;
  5320. if (phy->speed_cap_mask &
  5321. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
  5322. val |= (1<<7);
  5323. /* Note that 2.5G works only when used with 1G advertisement */
  5324. if (phy->speed_cap_mask &
  5325. (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
  5326. PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
  5327. val |= (1<<5);
  5328. DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
  5329. }
  5330. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
  5331. bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
  5332. if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
  5333. (phy->req_line_speed == SPEED_AUTO_NEG)) ||
  5334. (phy->req_line_speed == SPEED_2500)) {
  5335. u16 phy_ver;
  5336. /* Allow 2.5G for A1 and above */
  5337. bnx2x_cl45_read(bp, phy,
  5338. MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
  5339. &phy_ver);
  5340. DP(NETIF_MSG_LINK, "Add 2.5G\n");
  5341. if (phy_ver > 0)
  5342. tmp1 |= 1;
  5343. else
  5344. tmp1 &= 0xfffe;
  5345. } else {
  5346. DP(NETIF_MSG_LINK, "Disable 2.5G\n");
  5347. tmp1 &= 0xfffe;
  5348. }
  5349. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
  5350. /* Add support for CL37 (passive mode) II */
  5351. bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
  5352. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
  5353. (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
  5354. 0x20 : 0x40)));
  5355. /* Add support for CL37 (passive mode) III */
  5356. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
  5357. /*
  5358. * The SNR will improve about 2db by changing BW and FEE main
  5359. * tap. Rest commands are executed after link is up
  5360. * Change FFE main cursor to 5 in EDC register
  5361. */
  5362. if (bnx2x_8073_is_snr_needed(bp, phy))
  5363. bnx2x_cl45_write(bp, phy,
  5364. MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
  5365. 0xFB0C);
  5366. /* Enable FEC (Forware Error Correction) Request in the AN */
  5367. bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
  5368. tmp1 |= (1<<15);
  5369. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
  5370. bnx2x_ext_phy_set_pause(params, phy, vars);
  5371. /* Restart autoneg */
  5372. msleep(500);
  5373. bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
  5374. DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
  5375. ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
  5376. return 0;
  5377. }
  5378. static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
  5379. struct link_params *params,
  5380. struct link_vars *vars)
  5381. {
  5382. struct bnx2x *bp = params->bp;
  5383. u8 link_up = 0;
  5384. u16 val1, val2;
  5385. u16 link_status = 0;
  5386. u16 an1000_status = 0;
  5387. bnx2x_cl45_read(bp, phy,
  5388. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
  5389. DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
  5390. /* clear the interrupt LASI status register */
  5391. bnx2x_cl45_read(bp, phy,
  5392. MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
  5393. bnx2x_cl45_read(bp, phy,
  5394. MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
  5395. DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
  5396. /* Clear MSG-OUT */
  5397. bnx2x_cl45_read(bp, phy,
  5398. MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
  5399. /* Check the LASI */
  5400. bnx2x_cl45_read(bp, phy,
  5401. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
  5402. DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
  5403. /* Check the link status */
  5404. bnx2x_cl45_read(bp, phy,
  5405. MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
  5406. DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
  5407. bnx2x_cl45_read(bp, phy,
  5408. MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
  5409. bnx2x_cl45_read(bp, phy,
  5410. MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
  5411. link_up = ((val1 & 4) == 4);
  5412. DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
  5413. if (link_up &&
  5414. ((phy->req_line_speed != SPEED_10000))) {
  5415. if (bnx2x_8073_xaui_wa(bp, phy) != 0)
  5416. return 0;
  5417. }
  5418. bnx2x_cl45_read(bp, phy,
  5419. MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
  5420. bnx2x_cl45_read(bp, phy,
  5421. MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
  5422. /* Check the link status on 1.1.2 */
  5423. bnx2x_cl45_read(bp, phy,
  5424. MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
  5425. bnx2x_cl45_read(bp, phy,
  5426. MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
  5427. DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
  5428. "an_link_status=0x%x\n", val2, val1, an1000_status);
  5429. link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
  5430. if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
  5431. /*
  5432. * The SNR will improve about 2dbby changing the BW and FEE main
  5433. * tap. The 1st write to change FFE main tap is set before
  5434. * restart AN. Change PLL Bandwidth in EDC register
  5435. */
  5436. bnx2x_cl45_write(bp, phy,
  5437. MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
  5438. 0x26BC);
  5439. /* Change CDR Bandwidth in EDC register */
  5440. bnx2x_cl45_write(bp, phy,
  5441. MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
  5442. 0x0333);
  5443. }
  5444. bnx2x_cl45_read(bp, phy,
  5445. MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
  5446. &link_status);
  5447. /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
  5448. if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
  5449. link_up = 1;
  5450. vars->line_speed = SPEED_10000;
  5451. DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
  5452. params->port);
  5453. } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
  5454. link_up = 1;
  5455. vars->line_speed = SPEED_2500;
  5456. DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
  5457. params->port);
  5458. } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
  5459. link_up = 1;
  5460. vars->line_speed = SPEED_1000;
  5461. DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
  5462. params->port);
  5463. } else {
  5464. link_up = 0;
  5465. DP(NETIF_MSG_LINK, "port %x: External link is down\n",
  5466. params->port);
  5467. }
  5468. if (link_up) {
  5469. /* Swap polarity if required */
  5470. if (params->lane_config &
  5471. PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
  5472. /* Configure the 8073 to swap P and N of the KR lines */
  5473. bnx2x_cl45_read(bp, phy,
  5474. MDIO_XS_DEVAD,
  5475. MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
  5476. /*
  5477. * Set bit 3 to invert Rx in 1G mode and clear this bit
  5478. * when it`s in 10G mode.
  5479. */
  5480. if (vars->line_speed == SPEED_1000) {
  5481. DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
  5482. "the 8073\n");
  5483. val1 |= (1<<3);
  5484. } else
  5485. val1 &= ~(1<<3);
  5486. bnx2x_cl45_write(bp, phy,
  5487. MDIO_XS_DEVAD,
  5488. MDIO_XS_REG_8073_RX_CTRL_PCIE,
  5489. val1);
  5490. }
  5491. bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
  5492. bnx2x_8073_resolve_fc(phy, params, vars);
  5493. vars->duplex = DUPLEX_FULL;
  5494. }
  5495. return link_up;
  5496. }
  5497. static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
  5498. struct link_params *params)
  5499. {
  5500. struct bnx2x *bp = params->bp;
  5501. u8 gpio_port;
  5502. if (CHIP_IS_E2(bp))
  5503. gpio_port = BP_PATH(bp);
  5504. else
  5505. gpio_port = params->port;
  5506. DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
  5507. gpio_port);
  5508. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  5509. MISC_REGISTERS_GPIO_OUTPUT_LOW,
  5510. gpio_port);
  5511. }
  5512. /******************************************************************/
  5513. /* BCM8705 PHY SECTION */
  5514. /******************************************************************/
  5515. static int bnx2x_8705_config_init(struct bnx2x_phy *phy,
  5516. struct link_params *params,
  5517. struct link_vars *vars)
  5518. {
  5519. struct bnx2x *bp = params->bp;
  5520. DP(NETIF_MSG_LINK, "init 8705\n");
  5521. /* Restore normal power mode*/
  5522. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  5523. MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
  5524. /* HW reset */
  5525. bnx2x_ext_phy_hw_reset(bp, params->port);
  5526. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
  5527. bnx2x_wait_reset_complete(bp, phy, params);
  5528. bnx2x_cl45_write(bp, phy,
  5529. MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
  5530. bnx2x_cl45_write(bp, phy,
  5531. MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
  5532. bnx2x_cl45_write(bp, phy,
  5533. MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
  5534. bnx2x_cl45_write(bp, phy,
  5535. MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
  5536. /* BCM8705 doesn't have microcode, hence the 0 */
  5537. bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
  5538. return 0;
  5539. }
  5540. static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
  5541. struct link_params *params,
  5542. struct link_vars *vars)
  5543. {
  5544. u8 link_up = 0;
  5545. u16 val1, rx_sd;
  5546. struct bnx2x *bp = params->bp;
  5547. DP(NETIF_MSG_LINK, "read status 8705\n");
  5548. bnx2x_cl45_read(bp, phy,
  5549. MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
  5550. DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
  5551. bnx2x_cl45_read(bp, phy,
  5552. MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
  5553. DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
  5554. bnx2x_cl45_read(bp, phy,
  5555. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
  5556. bnx2x_cl45_read(bp, phy,
  5557. MDIO_PMA_DEVAD, 0xc809, &val1);
  5558. bnx2x_cl45_read(bp, phy,
  5559. MDIO_PMA_DEVAD, 0xc809, &val1);
  5560. DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
  5561. link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
  5562. if (link_up) {
  5563. vars->line_speed = SPEED_10000;
  5564. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  5565. }
  5566. return link_up;
  5567. }
  5568. /******************************************************************/
  5569. /* SFP+ module Section */
  5570. /******************************************************************/
  5571. static u8 bnx2x_get_gpio_port(struct link_params *params)
  5572. {
  5573. u8 gpio_port;
  5574. u32 swap_val, swap_override;
  5575. struct bnx2x *bp = params->bp;
  5576. if (CHIP_IS_E2(bp))
  5577. gpio_port = BP_PATH(bp);
  5578. else
  5579. gpio_port = params->port;
  5580. swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
  5581. swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
  5582. return gpio_port ^ (swap_val && swap_override);
  5583. }
  5584. static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
  5585. struct bnx2x_phy *phy,
  5586. u8 tx_en)
  5587. {
  5588. u16 val;
  5589. u8 port = params->port;
  5590. struct bnx2x *bp = params->bp;
  5591. u32 tx_en_mode;
  5592. /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
  5593. tx_en_mode = REG_RD(bp, params->shmem_base +
  5594. offsetof(struct shmem_region,
  5595. dev_info.port_hw_config[port].sfp_ctrl)) &
  5596. PORT_HW_CFG_TX_LASER_MASK;
  5597. DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
  5598. "mode = %x\n", tx_en, port, tx_en_mode);
  5599. switch (tx_en_mode) {
  5600. case PORT_HW_CFG_TX_LASER_MDIO:
  5601. bnx2x_cl45_read(bp, phy,
  5602. MDIO_PMA_DEVAD,
  5603. MDIO_PMA_REG_PHY_IDENTIFIER,
  5604. &val);
  5605. if (tx_en)
  5606. val &= ~(1<<15);
  5607. else
  5608. val |= (1<<15);
  5609. bnx2x_cl45_write(bp, phy,
  5610. MDIO_PMA_DEVAD,
  5611. MDIO_PMA_REG_PHY_IDENTIFIER,
  5612. val);
  5613. break;
  5614. case PORT_HW_CFG_TX_LASER_GPIO0:
  5615. case PORT_HW_CFG_TX_LASER_GPIO1:
  5616. case PORT_HW_CFG_TX_LASER_GPIO2:
  5617. case PORT_HW_CFG_TX_LASER_GPIO3:
  5618. {
  5619. u16 gpio_pin;
  5620. u8 gpio_port, gpio_mode;
  5621. if (tx_en)
  5622. gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
  5623. else
  5624. gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
  5625. gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
  5626. gpio_port = bnx2x_get_gpio_port(params);
  5627. bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
  5628. break;
  5629. }
  5630. default:
  5631. DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
  5632. break;
  5633. }
  5634. }
  5635. static void bnx2x_sfp_set_transmitter(struct link_params *params,
  5636. struct bnx2x_phy *phy,
  5637. u8 tx_en)
  5638. {
  5639. struct bnx2x *bp = params->bp;
  5640. DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
  5641. if (CHIP_IS_E3(bp))
  5642. bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
  5643. else
  5644. bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
  5645. }
  5646. static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
  5647. struct link_params *params,
  5648. u16 addr, u8 byte_cnt, u8 *o_buf)
  5649. {
  5650. struct bnx2x *bp = params->bp;
  5651. u16 val = 0;
  5652. u16 i;
  5653. if (byte_cnt > 16) {
  5654. DP(NETIF_MSG_LINK, "Reading from eeprom is"
  5655. " is limited to 0xf\n");
  5656. return -EINVAL;
  5657. }
  5658. /* Set the read command byte count */
  5659. bnx2x_cl45_write(bp, phy,
  5660. MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
  5661. (byte_cnt | 0xa000));
  5662. /* Set the read command address */
  5663. bnx2x_cl45_write(bp, phy,
  5664. MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
  5665. addr);
  5666. /* Activate read command */
  5667. bnx2x_cl45_write(bp, phy,
  5668. MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
  5669. 0x2c0f);
  5670. /* Wait up to 500us for command complete status */
  5671. for (i = 0; i < 100; i++) {
  5672. bnx2x_cl45_read(bp, phy,
  5673. MDIO_PMA_DEVAD,
  5674. MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
  5675. if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
  5676. MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
  5677. break;
  5678. udelay(5);
  5679. }
  5680. if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
  5681. MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
  5682. DP(NETIF_MSG_LINK,
  5683. "Got bad status 0x%x when reading from SFP+ EEPROM\n",
  5684. (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
  5685. return -EINVAL;
  5686. }
  5687. /* Read the buffer */
  5688. for (i = 0; i < byte_cnt; i++) {
  5689. bnx2x_cl45_read(bp, phy,
  5690. MDIO_PMA_DEVAD,
  5691. MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
  5692. o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
  5693. }
  5694. for (i = 0; i < 100; i++) {
  5695. bnx2x_cl45_read(bp, phy,
  5696. MDIO_PMA_DEVAD,
  5697. MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
  5698. if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
  5699. MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
  5700. return 0;
  5701. msleep(1);
  5702. }
  5703. return -EINVAL;
  5704. }
  5705. static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
  5706. struct link_params *params,
  5707. u16 addr, u8 byte_cnt,
  5708. u8 *o_buf)
  5709. {
  5710. int rc = 0;
  5711. u8 i, j = 0, cnt = 0;
  5712. u32 data_array[4];
  5713. u16 addr32;
  5714. struct bnx2x *bp = params->bp;
  5715. /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
  5716. " addr %d, cnt %d\n",
  5717. addr, byte_cnt);*/
  5718. if (byte_cnt > 16) {
  5719. DP(NETIF_MSG_LINK, "Reading from eeprom is"
  5720. " is limited to 16 bytes\n");
  5721. return -EINVAL;
  5722. }
  5723. /* 4 byte aligned address */
  5724. addr32 = addr & (~0x3);
  5725. do {
  5726. rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
  5727. data_array);
  5728. } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
  5729. if (rc == 0) {
  5730. for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
  5731. o_buf[j] = *((u8 *)data_array + i);
  5732. j++;
  5733. }
  5734. }
  5735. return rc;
  5736. }
  5737. static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
  5738. struct link_params *params,
  5739. u16 addr, u8 byte_cnt, u8 *o_buf)
  5740. {
  5741. struct bnx2x *bp = params->bp;
  5742. u16 val, i;
  5743. if (byte_cnt > 16) {
  5744. DP(NETIF_MSG_LINK, "Reading from eeprom is"
  5745. " is limited to 0xf\n");
  5746. return -EINVAL;
  5747. }
  5748. /* Need to read from 1.8000 to clear it */
  5749. bnx2x_cl45_read(bp, phy,
  5750. MDIO_PMA_DEVAD,
  5751. MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
  5752. &val);
  5753. /* Set the read command byte count */
  5754. bnx2x_cl45_write(bp, phy,
  5755. MDIO_PMA_DEVAD,
  5756. MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
  5757. ((byte_cnt < 2) ? 2 : byte_cnt));
  5758. /* Set the read command address */
  5759. bnx2x_cl45_write(bp, phy,
  5760. MDIO_PMA_DEVAD,
  5761. MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
  5762. addr);
  5763. /* Set the destination address */
  5764. bnx2x_cl45_write(bp, phy,
  5765. MDIO_PMA_DEVAD,
  5766. 0x8004,
  5767. MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
  5768. /* Activate read command */
  5769. bnx2x_cl45_write(bp, phy,
  5770. MDIO_PMA_DEVAD,
  5771. MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
  5772. 0x8002);
  5773. /*
  5774. * Wait appropriate time for two-wire command to finish before
  5775. * polling the status register
  5776. */
  5777. msleep(1);
  5778. /* Wait up to 500us for command complete status */
  5779. for (i = 0; i < 100; i++) {
  5780. bnx2x_cl45_read(bp, phy,
  5781. MDIO_PMA_DEVAD,
  5782. MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
  5783. if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
  5784. MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
  5785. break;
  5786. udelay(5);
  5787. }
  5788. if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
  5789. MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
  5790. DP(NETIF_MSG_LINK,
  5791. "Got bad status 0x%x when reading from SFP+ EEPROM\n",
  5792. (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
  5793. return -EFAULT;
  5794. }
  5795. /* Read the buffer */
  5796. for (i = 0; i < byte_cnt; i++) {
  5797. bnx2x_cl45_read(bp, phy,
  5798. MDIO_PMA_DEVAD,
  5799. MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
  5800. o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
  5801. }
  5802. for (i = 0; i < 100; i++) {
  5803. bnx2x_cl45_read(bp, phy,
  5804. MDIO_PMA_DEVAD,
  5805. MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
  5806. if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
  5807. MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
  5808. return 0;
  5809. msleep(1);
  5810. }
  5811. return -EINVAL;
  5812. }
  5813. int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
  5814. struct link_params *params, u16 addr,
  5815. u8 byte_cnt, u8 *o_buf)
  5816. {
  5817. int rc = -EINVAL;
  5818. switch (phy->type) {
  5819. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  5820. rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
  5821. byte_cnt, o_buf);
  5822. break;
  5823. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
  5824. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
  5825. rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
  5826. byte_cnt, o_buf);
  5827. break;
  5828. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  5829. rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
  5830. byte_cnt, o_buf);
  5831. break;
  5832. }
  5833. return rc;
  5834. }
  5835. static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
  5836. struct link_params *params,
  5837. u16 *edc_mode)
  5838. {
  5839. struct bnx2x *bp = params->bp;
  5840. u32 sync_offset = 0, phy_idx, media_types;
  5841. u8 val, check_limiting_mode = 0;
  5842. *edc_mode = EDC_MODE_LIMITING;
  5843. phy->media_type = ETH_PHY_UNSPECIFIED;
  5844. /* First check for copper cable */
  5845. if (bnx2x_read_sfp_module_eeprom(phy,
  5846. params,
  5847. SFP_EEPROM_CON_TYPE_ADDR,
  5848. 1,
  5849. &val) != 0) {
  5850. DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
  5851. return -EINVAL;
  5852. }
  5853. switch (val) {
  5854. case SFP_EEPROM_CON_TYPE_VAL_COPPER:
  5855. {
  5856. u8 copper_module_type;
  5857. phy->media_type = ETH_PHY_DA_TWINAX;
  5858. /*
  5859. * Check if its active cable (includes SFP+ module)
  5860. * of passive cable
  5861. */
  5862. if (bnx2x_read_sfp_module_eeprom(phy,
  5863. params,
  5864. SFP_EEPROM_FC_TX_TECH_ADDR,
  5865. 1,
  5866. &copper_module_type) != 0) {
  5867. DP(NETIF_MSG_LINK,
  5868. "Failed to read copper-cable-type"
  5869. " from SFP+ EEPROM\n");
  5870. return -EINVAL;
  5871. }
  5872. if (copper_module_type &
  5873. SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
  5874. DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
  5875. check_limiting_mode = 1;
  5876. } else if (copper_module_type &
  5877. SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
  5878. DP(NETIF_MSG_LINK, "Passive Copper"
  5879. " cable detected\n");
  5880. *edc_mode =
  5881. EDC_MODE_PASSIVE_DAC;
  5882. } else {
  5883. DP(NETIF_MSG_LINK, "Unknown copper-cable-"
  5884. "type 0x%x !!!\n", copper_module_type);
  5885. return -EINVAL;
  5886. }
  5887. break;
  5888. }
  5889. case SFP_EEPROM_CON_TYPE_VAL_LC:
  5890. phy->media_type = ETH_PHY_SFP_FIBER;
  5891. DP(NETIF_MSG_LINK, "Optic module detected\n");
  5892. check_limiting_mode = 1;
  5893. break;
  5894. default:
  5895. DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
  5896. val);
  5897. return -EINVAL;
  5898. }
  5899. sync_offset = params->shmem_base +
  5900. offsetof(struct shmem_region,
  5901. dev_info.port_hw_config[params->port].media_type);
  5902. media_types = REG_RD(bp, sync_offset);
  5903. /* Update media type for non-PMF sync */
  5904. for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
  5905. if (&(params->phy[phy_idx]) == phy) {
  5906. media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
  5907. (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
  5908. media_types |= ((phy->media_type &
  5909. PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
  5910. (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
  5911. break;
  5912. }
  5913. }
  5914. REG_WR(bp, sync_offset, media_types);
  5915. if (check_limiting_mode) {
  5916. u8 options[SFP_EEPROM_OPTIONS_SIZE];
  5917. if (bnx2x_read_sfp_module_eeprom(phy,
  5918. params,
  5919. SFP_EEPROM_OPTIONS_ADDR,
  5920. SFP_EEPROM_OPTIONS_SIZE,
  5921. options) != 0) {
  5922. DP(NETIF_MSG_LINK, "Failed to read Option"
  5923. " field from module EEPROM\n");
  5924. return -EINVAL;
  5925. }
  5926. if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
  5927. *edc_mode = EDC_MODE_LINEAR;
  5928. else
  5929. *edc_mode = EDC_MODE_LIMITING;
  5930. }
  5931. DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
  5932. return 0;
  5933. }
  5934. /*
  5935. * This function read the relevant field from the module (SFP+), and verify it
  5936. * is compliant with this board
  5937. */
  5938. static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
  5939. struct link_params *params)
  5940. {
  5941. struct bnx2x *bp = params->bp;
  5942. u32 val, cmd;
  5943. u32 fw_resp, fw_cmd_param;
  5944. char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
  5945. char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
  5946. phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
  5947. val = REG_RD(bp, params->shmem_base +
  5948. offsetof(struct shmem_region, dev_info.
  5949. port_feature_config[params->port].config));
  5950. if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
  5951. PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
  5952. DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
  5953. return 0;
  5954. }
  5955. if (params->feature_config_flags &
  5956. FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
  5957. /* Use specific phy request */
  5958. cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
  5959. } else if (params->feature_config_flags &
  5960. FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
  5961. /* Use first phy request only in case of non-dual media*/
  5962. if (DUAL_MEDIA(params)) {
  5963. DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
  5964. "verification\n");
  5965. return -EINVAL;
  5966. }
  5967. cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
  5968. } else {
  5969. /* No support in OPT MDL detection */
  5970. DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
  5971. "verification\n");
  5972. return -EINVAL;
  5973. }
  5974. fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
  5975. fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
  5976. if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
  5977. DP(NETIF_MSG_LINK, "Approved module\n");
  5978. return 0;
  5979. }
  5980. /* format the warning message */
  5981. if (bnx2x_read_sfp_module_eeprom(phy,
  5982. params,
  5983. SFP_EEPROM_VENDOR_NAME_ADDR,
  5984. SFP_EEPROM_VENDOR_NAME_SIZE,
  5985. (u8 *)vendor_name))
  5986. vendor_name[0] = '\0';
  5987. else
  5988. vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
  5989. if (bnx2x_read_sfp_module_eeprom(phy,
  5990. params,
  5991. SFP_EEPROM_PART_NO_ADDR,
  5992. SFP_EEPROM_PART_NO_SIZE,
  5993. (u8 *)vendor_pn))
  5994. vendor_pn[0] = '\0';
  5995. else
  5996. vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
  5997. netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected,"
  5998. " Port %d from %s part number %s\n",
  5999. params->port, vendor_name, vendor_pn);
  6000. phy->flags |= FLAGS_SFP_NOT_APPROVED;
  6001. return -EINVAL;
  6002. }
  6003. static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
  6004. struct link_params *params)
  6005. {
  6006. u8 val;
  6007. struct bnx2x *bp = params->bp;
  6008. u16 timeout;
  6009. /*
  6010. * Initialization time after hot-plug may take up to 300ms for
  6011. * some phys type ( e.g. JDSU )
  6012. */
  6013. for (timeout = 0; timeout < 60; timeout++) {
  6014. if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
  6015. == 0) {
  6016. DP(NETIF_MSG_LINK, "SFP+ module initialization "
  6017. "took %d ms\n", timeout * 5);
  6018. return 0;
  6019. }
  6020. msleep(5);
  6021. }
  6022. return -EINVAL;
  6023. }
  6024. static void bnx2x_8727_power_module(struct bnx2x *bp,
  6025. struct bnx2x_phy *phy,
  6026. u8 is_power_up) {
  6027. /* Make sure GPIOs are not using for LED mode */
  6028. u16 val;
  6029. /*
  6030. * In the GPIO register, bit 4 is use to determine if the GPIOs are
  6031. * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
  6032. * output
  6033. * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
  6034. * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
  6035. * where the 1st bit is the over-current(only input), and 2nd bit is
  6036. * for power( only output )
  6037. *
  6038. * In case of NOC feature is disabled and power is up, set GPIO control
  6039. * as input to enable listening of over-current indication
  6040. */
  6041. if (phy->flags & FLAGS_NOC)
  6042. return;
  6043. if (is_power_up)
  6044. val = (1<<4);
  6045. else
  6046. /*
  6047. * Set GPIO control to OUTPUT, and set the power bit
  6048. * to according to the is_power_up
  6049. */
  6050. val = (1<<1);
  6051. bnx2x_cl45_write(bp, phy,
  6052. MDIO_PMA_DEVAD,
  6053. MDIO_PMA_REG_8727_GPIO_CTRL,
  6054. val);
  6055. }
  6056. static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
  6057. struct bnx2x_phy *phy,
  6058. u16 edc_mode)
  6059. {
  6060. u16 cur_limiting_mode;
  6061. bnx2x_cl45_read(bp, phy,
  6062. MDIO_PMA_DEVAD,
  6063. MDIO_PMA_REG_ROM_VER2,
  6064. &cur_limiting_mode);
  6065. DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
  6066. cur_limiting_mode);
  6067. if (edc_mode == EDC_MODE_LIMITING) {
  6068. DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
  6069. bnx2x_cl45_write(bp, phy,
  6070. MDIO_PMA_DEVAD,
  6071. MDIO_PMA_REG_ROM_VER2,
  6072. EDC_MODE_LIMITING);
  6073. } else { /* LRM mode ( default )*/
  6074. DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
  6075. /*
  6076. * Changing to LRM mode takes quite few seconds. So do it only
  6077. * if current mode is limiting (default is LRM)
  6078. */
  6079. if (cur_limiting_mode != EDC_MODE_LIMITING)
  6080. return 0;
  6081. bnx2x_cl45_write(bp, phy,
  6082. MDIO_PMA_DEVAD,
  6083. MDIO_PMA_REG_LRM_MODE,
  6084. 0);
  6085. bnx2x_cl45_write(bp, phy,
  6086. MDIO_PMA_DEVAD,
  6087. MDIO_PMA_REG_ROM_VER2,
  6088. 0x128);
  6089. bnx2x_cl45_write(bp, phy,
  6090. MDIO_PMA_DEVAD,
  6091. MDIO_PMA_REG_MISC_CTRL0,
  6092. 0x4008);
  6093. bnx2x_cl45_write(bp, phy,
  6094. MDIO_PMA_DEVAD,
  6095. MDIO_PMA_REG_LRM_MODE,
  6096. 0xaaaa);
  6097. }
  6098. return 0;
  6099. }
  6100. static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
  6101. struct bnx2x_phy *phy,
  6102. u16 edc_mode)
  6103. {
  6104. u16 phy_identifier;
  6105. u16 rom_ver2_val;
  6106. bnx2x_cl45_read(bp, phy,
  6107. MDIO_PMA_DEVAD,
  6108. MDIO_PMA_REG_PHY_IDENTIFIER,
  6109. &phy_identifier);
  6110. bnx2x_cl45_write(bp, phy,
  6111. MDIO_PMA_DEVAD,
  6112. MDIO_PMA_REG_PHY_IDENTIFIER,
  6113. (phy_identifier & ~(1<<9)));
  6114. bnx2x_cl45_read(bp, phy,
  6115. MDIO_PMA_DEVAD,
  6116. MDIO_PMA_REG_ROM_VER2,
  6117. &rom_ver2_val);
  6118. /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
  6119. bnx2x_cl45_write(bp, phy,
  6120. MDIO_PMA_DEVAD,
  6121. MDIO_PMA_REG_ROM_VER2,
  6122. (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
  6123. bnx2x_cl45_write(bp, phy,
  6124. MDIO_PMA_DEVAD,
  6125. MDIO_PMA_REG_PHY_IDENTIFIER,
  6126. (phy_identifier | (1<<9)));
  6127. return 0;
  6128. }
  6129. static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
  6130. struct link_params *params,
  6131. u32 action)
  6132. {
  6133. struct bnx2x *bp = params->bp;
  6134. switch (action) {
  6135. case DISABLE_TX:
  6136. bnx2x_sfp_set_transmitter(params, phy, 0);
  6137. break;
  6138. case ENABLE_TX:
  6139. if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
  6140. bnx2x_sfp_set_transmitter(params, phy, 1);
  6141. break;
  6142. default:
  6143. DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
  6144. action);
  6145. return;
  6146. }
  6147. }
  6148. static void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
  6149. u8 gpio_mode)
  6150. {
  6151. struct bnx2x *bp = params->bp;
  6152. u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
  6153. offsetof(struct shmem_region,
  6154. dev_info.port_hw_config[params->port].sfp_ctrl)) &
  6155. PORT_HW_CFG_FAULT_MODULE_LED_MASK;
  6156. switch (fault_led_gpio) {
  6157. case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
  6158. return;
  6159. case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
  6160. case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
  6161. case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
  6162. case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
  6163. {
  6164. u8 gpio_port = bnx2x_get_gpio_port(params);
  6165. u16 gpio_pin = fault_led_gpio -
  6166. PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
  6167. DP(NETIF_MSG_LINK, "Set fault module-detected led "
  6168. "pin %x port %x mode %x\n",
  6169. gpio_pin, gpio_port, gpio_mode);
  6170. bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
  6171. }
  6172. break;
  6173. default:
  6174. DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
  6175. fault_led_gpio);
  6176. }
  6177. }
  6178. static void bnx2x_set_e3_module_fault_led(struct link_params *params,
  6179. u8 gpio_mode)
  6180. {
  6181. u32 pin_cfg;
  6182. u8 port = params->port;
  6183. struct bnx2x *bp = params->bp;
  6184. pin_cfg = (REG_RD(bp, params->shmem_base +
  6185. offsetof(struct shmem_region,
  6186. dev_info.port_hw_config[port].e3_sfp_ctrl)) &
  6187. PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
  6188. PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
  6189. DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
  6190. gpio_mode, pin_cfg);
  6191. bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
  6192. }
  6193. static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
  6194. u8 gpio_mode)
  6195. {
  6196. struct bnx2x *bp = params->bp;
  6197. DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
  6198. if (CHIP_IS_E3(bp)) {
  6199. /*
  6200. * Low ==> if SFP+ module is supported otherwise
  6201. * High ==> if SFP+ module is not on the approved vendor list
  6202. */
  6203. bnx2x_set_e3_module_fault_led(params, gpio_mode);
  6204. } else
  6205. bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
  6206. }
  6207. static void bnx2x_warpcore_power_module(struct link_params *params,
  6208. struct bnx2x_phy *phy,
  6209. u8 power)
  6210. {
  6211. u32 pin_cfg;
  6212. struct bnx2x *bp = params->bp;
  6213. pin_cfg = (REG_RD(bp, params->shmem_base +
  6214. offsetof(struct shmem_region,
  6215. dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
  6216. PORT_HW_CFG_E3_PWR_DIS_MASK) >>
  6217. PORT_HW_CFG_E3_PWR_DIS_SHIFT;
  6218. DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
  6219. power, pin_cfg);
  6220. /*
  6221. * Low ==> corresponding SFP+ module is powered
  6222. * high ==> the SFP+ module is powered down
  6223. */
  6224. bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
  6225. }
  6226. static void bnx2x_power_sfp_module(struct link_params *params,
  6227. struct bnx2x_phy *phy,
  6228. u8 power)
  6229. {
  6230. struct bnx2x *bp = params->bp;
  6231. DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
  6232. switch (phy->type) {
  6233. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
  6234. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
  6235. bnx2x_8727_power_module(params->bp, phy, power);
  6236. break;
  6237. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  6238. bnx2x_warpcore_power_module(params, phy, power);
  6239. break;
  6240. default:
  6241. break;
  6242. }
  6243. }
  6244. static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
  6245. struct bnx2x_phy *phy,
  6246. u16 edc_mode)
  6247. {
  6248. u16 val = 0;
  6249. u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
  6250. struct bnx2x *bp = params->bp;
  6251. u8 lane = bnx2x_get_warpcore_lane(phy, params);
  6252. /* This is a global register which controls all lanes */
  6253. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  6254. MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
  6255. val &= ~(0xf << (lane << 2));
  6256. switch (edc_mode) {
  6257. case EDC_MODE_LINEAR:
  6258. case EDC_MODE_LIMITING:
  6259. mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
  6260. break;
  6261. case EDC_MODE_PASSIVE_DAC:
  6262. mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
  6263. break;
  6264. default:
  6265. break;
  6266. }
  6267. val |= (mode << (lane << 2));
  6268. bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
  6269. MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
  6270. /* A must read */
  6271. bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
  6272. MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
  6273. }
  6274. static void bnx2x_set_limiting_mode(struct link_params *params,
  6275. struct bnx2x_phy *phy,
  6276. u16 edc_mode)
  6277. {
  6278. switch (phy->type) {
  6279. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  6280. bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
  6281. break;
  6282. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
  6283. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
  6284. bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
  6285. break;
  6286. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
  6287. bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
  6288. break;
  6289. }
  6290. }
  6291. int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
  6292. struct link_params *params)
  6293. {
  6294. struct bnx2x *bp = params->bp;
  6295. u16 edc_mode;
  6296. int rc = 0;
  6297. u32 val = REG_RD(bp, params->shmem_base +
  6298. offsetof(struct shmem_region, dev_info.
  6299. port_feature_config[params->port].config));
  6300. DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
  6301. params->port);
  6302. /* Power up module */
  6303. bnx2x_power_sfp_module(params, phy, 1);
  6304. if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
  6305. DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
  6306. return -EINVAL;
  6307. } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
  6308. /* check SFP+ module compatibility */
  6309. DP(NETIF_MSG_LINK, "Module verification failed!!\n");
  6310. rc = -EINVAL;
  6311. /* Turn on fault module-detected led */
  6312. bnx2x_set_sfp_module_fault_led(params,
  6313. MISC_REGISTERS_GPIO_HIGH);
  6314. /* Check if need to power down the SFP+ module */
  6315. if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
  6316. PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
  6317. DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
  6318. bnx2x_power_sfp_module(params, phy, 0);
  6319. return rc;
  6320. }
  6321. } else {
  6322. /* Turn off fault module-detected led */
  6323. bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
  6324. }
  6325. /*
  6326. * Check and set limiting mode / LRM mode on 8726. On 8727 it
  6327. * is done automatically
  6328. */
  6329. bnx2x_set_limiting_mode(params, phy, edc_mode);
  6330. /*
  6331. * Enable transmit for this module if the module is approved, or
  6332. * if unapproved modules should also enable the Tx laser
  6333. */
  6334. if (rc == 0 ||
  6335. (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
  6336. PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
  6337. bnx2x_sfp_set_transmitter(params, phy, 1);
  6338. else
  6339. bnx2x_sfp_set_transmitter(params, phy, 0);
  6340. return rc;
  6341. }
  6342. void bnx2x_handle_module_detect_int(struct link_params *params)
  6343. {
  6344. struct bnx2x *bp = params->bp;
  6345. struct bnx2x_phy *phy;
  6346. u32 gpio_val;
  6347. u8 gpio_num, gpio_port;
  6348. if (CHIP_IS_E3(bp))
  6349. phy = &params->phy[INT_PHY];
  6350. else
  6351. phy = &params->phy[EXT_PHY1];
  6352. if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
  6353. params->port, &gpio_num, &gpio_port) ==
  6354. -EINVAL) {
  6355. DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
  6356. return;
  6357. }
  6358. /* Set valid module led off */
  6359. bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
  6360. /* Get current gpio val reflecting module plugged in / out*/
  6361. gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
  6362. /* Call the handling function in case module is detected */
  6363. if (gpio_val == 0) {
  6364. bnx2x_power_sfp_module(params, phy, 1);
  6365. bnx2x_set_gpio_int(bp, gpio_num,
  6366. MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
  6367. gpio_port);
  6368. if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
  6369. bnx2x_sfp_module_detection(phy, params);
  6370. else
  6371. DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
  6372. } else {
  6373. u32 val = REG_RD(bp, params->shmem_base +
  6374. offsetof(struct shmem_region, dev_info.
  6375. port_feature_config[params->port].
  6376. config));
  6377. bnx2x_set_gpio_int(bp, gpio_num,
  6378. MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
  6379. gpio_port);
  6380. /*
  6381. * Module was plugged out.
  6382. * Disable transmit for this module
  6383. */
  6384. phy->media_type = ETH_PHY_NOT_PRESENT;
  6385. if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
  6386. PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
  6387. bnx2x_sfp_set_transmitter(params, phy, 0);
  6388. }
  6389. }
  6390. /******************************************************************/
  6391. /* Used by 8706 and 8727 */
  6392. /******************************************************************/
  6393. static void bnx2x_sfp_mask_fault(struct bnx2x *bp,
  6394. struct bnx2x_phy *phy,
  6395. u16 alarm_status_offset,
  6396. u16 alarm_ctrl_offset)
  6397. {
  6398. u16 alarm_status, val;
  6399. bnx2x_cl45_read(bp, phy,
  6400. MDIO_PMA_DEVAD, alarm_status_offset,
  6401. &alarm_status);
  6402. bnx2x_cl45_read(bp, phy,
  6403. MDIO_PMA_DEVAD, alarm_status_offset,
  6404. &alarm_status);
  6405. /* Mask or enable the fault event. */
  6406. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
  6407. if (alarm_status & (1<<0))
  6408. val &= ~(1<<0);
  6409. else
  6410. val |= (1<<0);
  6411. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
  6412. }
  6413. /******************************************************************/
  6414. /* common BCM8706/BCM8726 PHY SECTION */
  6415. /******************************************************************/
  6416. static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
  6417. struct link_params *params,
  6418. struct link_vars *vars)
  6419. {
  6420. u8 link_up = 0;
  6421. u16 val1, val2, rx_sd, pcs_status;
  6422. struct bnx2x *bp = params->bp;
  6423. DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
  6424. /* Clear RX Alarm*/
  6425. bnx2x_cl45_read(bp, phy,
  6426. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
  6427. bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
  6428. MDIO_PMA_REG_TX_ALARM_CTRL);
  6429. /* clear LASI indication*/
  6430. bnx2x_cl45_read(bp, phy,
  6431. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
  6432. bnx2x_cl45_read(bp, phy,
  6433. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
  6434. DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
  6435. bnx2x_cl45_read(bp, phy,
  6436. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
  6437. bnx2x_cl45_read(bp, phy,
  6438. MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
  6439. bnx2x_cl45_read(bp, phy,
  6440. MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
  6441. bnx2x_cl45_read(bp, phy,
  6442. MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
  6443. DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
  6444. " link_status 0x%x\n", rx_sd, pcs_status, val2);
  6445. /*
  6446. * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
  6447. * are set, or if the autoneg bit 1 is set
  6448. */
  6449. link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
  6450. if (link_up) {
  6451. if (val2 & (1<<1))
  6452. vars->line_speed = SPEED_1000;
  6453. else
  6454. vars->line_speed = SPEED_10000;
  6455. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  6456. vars->duplex = DUPLEX_FULL;
  6457. }
  6458. /* Capture 10G link fault. Read twice to clear stale value. */
  6459. if (vars->line_speed == SPEED_10000) {
  6460. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
  6461. MDIO_PMA_REG_TX_ALARM, &val1);
  6462. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
  6463. MDIO_PMA_REG_TX_ALARM, &val1);
  6464. if (val1 & (1<<0))
  6465. vars->fault_detected = 1;
  6466. }
  6467. return link_up;
  6468. }
  6469. /******************************************************************/
  6470. /* BCM8706 PHY SECTION */
  6471. /******************************************************************/
  6472. static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
  6473. struct link_params *params,
  6474. struct link_vars *vars)
  6475. {
  6476. u32 tx_en_mode;
  6477. u16 cnt, val, tmp1;
  6478. struct bnx2x *bp = params->bp;
  6479. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  6480. MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
  6481. /* HW reset */
  6482. bnx2x_ext_phy_hw_reset(bp, params->port);
  6483. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
  6484. bnx2x_wait_reset_complete(bp, phy, params);
  6485. /* Wait until fw is loaded */
  6486. for (cnt = 0; cnt < 100; cnt++) {
  6487. bnx2x_cl45_read(bp, phy,
  6488. MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
  6489. if (val)
  6490. break;
  6491. msleep(10);
  6492. }
  6493. DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
  6494. if ((params->feature_config_flags &
  6495. FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
  6496. u8 i;
  6497. u16 reg;
  6498. for (i = 0; i < 4; i++) {
  6499. reg = MDIO_XS_8706_REG_BANK_RX0 +
  6500. i*(MDIO_XS_8706_REG_BANK_RX1 -
  6501. MDIO_XS_8706_REG_BANK_RX0);
  6502. bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
  6503. /* Clear first 3 bits of the control */
  6504. val &= ~0x7;
  6505. /* Set control bits according to configuration */
  6506. val |= (phy->rx_preemphasis[i] & 0x7);
  6507. DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
  6508. " reg 0x%x <-- val 0x%x\n", reg, val);
  6509. bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
  6510. }
  6511. }
  6512. /* Force speed */
  6513. if (phy->req_line_speed == SPEED_10000) {
  6514. DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
  6515. bnx2x_cl45_write(bp, phy,
  6516. MDIO_PMA_DEVAD,
  6517. MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
  6518. bnx2x_cl45_write(bp, phy,
  6519. MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
  6520. 0);
  6521. /* Arm LASI for link and Tx fault. */
  6522. bnx2x_cl45_write(bp, phy,
  6523. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 3);
  6524. } else {
  6525. /* Force 1Gbps using autoneg with 1G advertisement */
  6526. /* Allow CL37 through CL73 */
  6527. DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
  6528. bnx2x_cl45_write(bp, phy,
  6529. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
  6530. /* Enable Full-Duplex advertisement on CL37 */
  6531. bnx2x_cl45_write(bp, phy,
  6532. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
  6533. /* Enable CL37 AN */
  6534. bnx2x_cl45_write(bp, phy,
  6535. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
  6536. /* 1G support */
  6537. bnx2x_cl45_write(bp, phy,
  6538. MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
  6539. /* Enable clause 73 AN */
  6540. bnx2x_cl45_write(bp, phy,
  6541. MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
  6542. bnx2x_cl45_write(bp, phy,
  6543. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
  6544. 0x0400);
  6545. bnx2x_cl45_write(bp, phy,
  6546. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
  6547. 0x0004);
  6548. }
  6549. bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
  6550. /*
  6551. * If TX Laser is controlled by GPIO_0, do not let PHY go into low
  6552. * power mode, if TX Laser is disabled
  6553. */
  6554. tx_en_mode = REG_RD(bp, params->shmem_base +
  6555. offsetof(struct shmem_region,
  6556. dev_info.port_hw_config[params->port].sfp_ctrl))
  6557. & PORT_HW_CFG_TX_LASER_MASK;
  6558. if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
  6559. DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
  6560. bnx2x_cl45_read(bp, phy,
  6561. MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
  6562. tmp1 |= 0x1;
  6563. bnx2x_cl45_write(bp, phy,
  6564. MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
  6565. }
  6566. return 0;
  6567. }
  6568. static int bnx2x_8706_read_status(struct bnx2x_phy *phy,
  6569. struct link_params *params,
  6570. struct link_vars *vars)
  6571. {
  6572. return bnx2x_8706_8726_read_status(phy, params, vars);
  6573. }
  6574. /******************************************************************/
  6575. /* BCM8726 PHY SECTION */
  6576. /******************************************************************/
  6577. static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
  6578. struct link_params *params)
  6579. {
  6580. struct bnx2x *bp = params->bp;
  6581. DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
  6582. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
  6583. }
  6584. static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
  6585. struct link_params *params)
  6586. {
  6587. struct bnx2x *bp = params->bp;
  6588. /* Need to wait 100ms after reset */
  6589. msleep(100);
  6590. /* Micro controller re-boot */
  6591. bnx2x_cl45_write(bp, phy,
  6592. MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
  6593. /* Set soft reset */
  6594. bnx2x_cl45_write(bp, phy,
  6595. MDIO_PMA_DEVAD,
  6596. MDIO_PMA_REG_GEN_CTRL,
  6597. MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
  6598. bnx2x_cl45_write(bp, phy,
  6599. MDIO_PMA_DEVAD,
  6600. MDIO_PMA_REG_MISC_CTRL1, 0x0001);
  6601. bnx2x_cl45_write(bp, phy,
  6602. MDIO_PMA_DEVAD,
  6603. MDIO_PMA_REG_GEN_CTRL,
  6604. MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
  6605. /* wait for 150ms for microcode load */
  6606. msleep(150);
  6607. /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
  6608. bnx2x_cl45_write(bp, phy,
  6609. MDIO_PMA_DEVAD,
  6610. MDIO_PMA_REG_MISC_CTRL1, 0x0000);
  6611. msleep(200);
  6612. bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
  6613. }
  6614. static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
  6615. struct link_params *params,
  6616. struct link_vars *vars)
  6617. {
  6618. struct bnx2x *bp = params->bp;
  6619. u16 val1;
  6620. u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
  6621. if (link_up) {
  6622. bnx2x_cl45_read(bp, phy,
  6623. MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
  6624. &val1);
  6625. if (val1 & (1<<15)) {
  6626. DP(NETIF_MSG_LINK, "Tx is disabled\n");
  6627. link_up = 0;
  6628. vars->line_speed = 0;
  6629. }
  6630. }
  6631. return link_up;
  6632. }
  6633. static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
  6634. struct link_params *params,
  6635. struct link_vars *vars)
  6636. {
  6637. struct bnx2x *bp = params->bp;
  6638. DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
  6639. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
  6640. bnx2x_wait_reset_complete(bp, phy, params);
  6641. bnx2x_8726_external_rom_boot(phy, params);
  6642. /*
  6643. * Need to call module detected on initialization since the module
  6644. * detection triggered by actual module insertion might occur before
  6645. * driver is loaded, and when driver is loaded, it reset all
  6646. * registers, including the transmitter
  6647. */
  6648. bnx2x_sfp_module_detection(phy, params);
  6649. if (phy->req_line_speed == SPEED_1000) {
  6650. DP(NETIF_MSG_LINK, "Setting 1G force\n");
  6651. bnx2x_cl45_write(bp, phy,
  6652. MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
  6653. bnx2x_cl45_write(bp, phy,
  6654. MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
  6655. bnx2x_cl45_write(bp, phy,
  6656. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
  6657. bnx2x_cl45_write(bp, phy,
  6658. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
  6659. 0x400);
  6660. } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
  6661. (phy->speed_cap_mask &
  6662. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
  6663. ((phy->speed_cap_mask &
  6664. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
  6665. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
  6666. DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
  6667. /* Set Flow control */
  6668. bnx2x_ext_phy_set_pause(params, phy, vars);
  6669. bnx2x_cl45_write(bp, phy,
  6670. MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
  6671. bnx2x_cl45_write(bp, phy,
  6672. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
  6673. bnx2x_cl45_write(bp, phy,
  6674. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
  6675. bnx2x_cl45_write(bp, phy,
  6676. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
  6677. bnx2x_cl45_write(bp, phy,
  6678. MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
  6679. /*
  6680. * Enable RX-ALARM control to receive interrupt for 1G speed
  6681. * change
  6682. */
  6683. bnx2x_cl45_write(bp, phy,
  6684. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
  6685. bnx2x_cl45_write(bp, phy,
  6686. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
  6687. 0x400);
  6688. } else { /* Default 10G. Set only LASI control */
  6689. bnx2x_cl45_write(bp, phy,
  6690. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
  6691. }
  6692. /* Set TX PreEmphasis if needed */
  6693. if ((params->feature_config_flags &
  6694. FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
  6695. DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
  6696. "TX_CTRL2 0x%x\n",
  6697. phy->tx_preemphasis[0],
  6698. phy->tx_preemphasis[1]);
  6699. bnx2x_cl45_write(bp, phy,
  6700. MDIO_PMA_DEVAD,
  6701. MDIO_PMA_REG_8726_TX_CTRL1,
  6702. phy->tx_preemphasis[0]);
  6703. bnx2x_cl45_write(bp, phy,
  6704. MDIO_PMA_DEVAD,
  6705. MDIO_PMA_REG_8726_TX_CTRL2,
  6706. phy->tx_preemphasis[1]);
  6707. }
  6708. return 0;
  6709. }
  6710. static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
  6711. struct link_params *params)
  6712. {
  6713. struct bnx2x *bp = params->bp;
  6714. DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
  6715. /* Set serial boot control for external load */
  6716. bnx2x_cl45_write(bp, phy,
  6717. MDIO_PMA_DEVAD,
  6718. MDIO_PMA_REG_GEN_CTRL, 0x0001);
  6719. }
  6720. /******************************************************************/
  6721. /* BCM8727 PHY SECTION */
  6722. /******************************************************************/
  6723. static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
  6724. struct link_params *params, u8 mode)
  6725. {
  6726. struct bnx2x *bp = params->bp;
  6727. u16 led_mode_bitmask = 0;
  6728. u16 gpio_pins_bitmask = 0;
  6729. u16 val;
  6730. /* Only NOC flavor requires to set the LED specifically */
  6731. if (!(phy->flags & FLAGS_NOC))
  6732. return;
  6733. switch (mode) {
  6734. case LED_MODE_FRONT_PANEL_OFF:
  6735. case LED_MODE_OFF:
  6736. led_mode_bitmask = 0;
  6737. gpio_pins_bitmask = 0x03;
  6738. break;
  6739. case LED_MODE_ON:
  6740. led_mode_bitmask = 0;
  6741. gpio_pins_bitmask = 0x02;
  6742. break;
  6743. case LED_MODE_OPER:
  6744. led_mode_bitmask = 0x60;
  6745. gpio_pins_bitmask = 0x11;
  6746. break;
  6747. }
  6748. bnx2x_cl45_read(bp, phy,
  6749. MDIO_PMA_DEVAD,
  6750. MDIO_PMA_REG_8727_PCS_OPT_CTRL,
  6751. &val);
  6752. val &= 0xff8f;
  6753. val |= led_mode_bitmask;
  6754. bnx2x_cl45_write(bp, phy,
  6755. MDIO_PMA_DEVAD,
  6756. MDIO_PMA_REG_8727_PCS_OPT_CTRL,
  6757. val);
  6758. bnx2x_cl45_read(bp, phy,
  6759. MDIO_PMA_DEVAD,
  6760. MDIO_PMA_REG_8727_GPIO_CTRL,
  6761. &val);
  6762. val &= 0xffe0;
  6763. val |= gpio_pins_bitmask;
  6764. bnx2x_cl45_write(bp, phy,
  6765. MDIO_PMA_DEVAD,
  6766. MDIO_PMA_REG_8727_GPIO_CTRL,
  6767. val);
  6768. }
  6769. static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
  6770. struct link_params *params) {
  6771. u32 swap_val, swap_override;
  6772. u8 port;
  6773. /*
  6774. * The PHY reset is controlled by GPIO 1. Fake the port number
  6775. * to cancel the swap done in set_gpio()
  6776. */
  6777. struct bnx2x *bp = params->bp;
  6778. swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
  6779. swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
  6780. port = (swap_val && swap_override) ^ 1;
  6781. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
  6782. MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
  6783. }
  6784. static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
  6785. struct link_params *params,
  6786. struct link_vars *vars)
  6787. {
  6788. u32 tx_en_mode;
  6789. u16 tmp1, val, mod_abs, tmp2;
  6790. u16 rx_alarm_ctrl_val;
  6791. u16 lasi_ctrl_val;
  6792. struct bnx2x *bp = params->bp;
  6793. /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
  6794. bnx2x_wait_reset_complete(bp, phy, params);
  6795. rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
  6796. /* Should be 0x6 to enable XS on Tx side. */
  6797. lasi_ctrl_val = 0x0006;
  6798. DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
  6799. /* enable LASI */
  6800. bnx2x_cl45_write(bp, phy,
  6801. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
  6802. rx_alarm_ctrl_val);
  6803. bnx2x_cl45_write(bp, phy,
  6804. MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
  6805. 0);
  6806. bnx2x_cl45_write(bp, phy,
  6807. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
  6808. /*
  6809. * Initially configure MOD_ABS to interrupt when module is
  6810. * presence( bit 8)
  6811. */
  6812. bnx2x_cl45_read(bp, phy,
  6813. MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
  6814. /*
  6815. * Set EDC off by setting OPTXLOS signal input to low (bit 9).
  6816. * When the EDC is off it locks onto a reference clock and avoids
  6817. * becoming 'lost'
  6818. */
  6819. mod_abs &= ~(1<<8);
  6820. if (!(phy->flags & FLAGS_NOC))
  6821. mod_abs &= ~(1<<9);
  6822. bnx2x_cl45_write(bp, phy,
  6823. MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
  6824. /* Make MOD_ABS give interrupt on change */
  6825. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
  6826. &val);
  6827. val |= (1<<12);
  6828. if (phy->flags & FLAGS_NOC)
  6829. val |= (3<<5);
  6830. /*
  6831. * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
  6832. * status which reflect SFP+ module over-current
  6833. */
  6834. if (!(phy->flags & FLAGS_NOC))
  6835. val &= 0xff8f; /* Reset bits 4-6 */
  6836. bnx2x_cl45_write(bp, phy,
  6837. MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
  6838. bnx2x_8727_power_module(bp, phy, 1);
  6839. bnx2x_cl45_read(bp, phy,
  6840. MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
  6841. bnx2x_cl45_read(bp, phy,
  6842. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
  6843. /* Set option 1G speed */
  6844. if (phy->req_line_speed == SPEED_1000) {
  6845. DP(NETIF_MSG_LINK, "Setting 1G force\n");
  6846. bnx2x_cl45_write(bp, phy,
  6847. MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
  6848. bnx2x_cl45_write(bp, phy,
  6849. MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
  6850. bnx2x_cl45_read(bp, phy,
  6851. MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
  6852. DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
  6853. /*
  6854. * Power down the XAUI until link is up in case of dual-media
  6855. * and 1G
  6856. */
  6857. if (DUAL_MEDIA(params)) {
  6858. bnx2x_cl45_read(bp, phy,
  6859. MDIO_PMA_DEVAD,
  6860. MDIO_PMA_REG_8727_PCS_GP, &val);
  6861. val |= (3<<10);
  6862. bnx2x_cl45_write(bp, phy,
  6863. MDIO_PMA_DEVAD,
  6864. MDIO_PMA_REG_8727_PCS_GP, val);
  6865. }
  6866. } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
  6867. ((phy->speed_cap_mask &
  6868. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
  6869. ((phy->speed_cap_mask &
  6870. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
  6871. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
  6872. DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
  6873. bnx2x_cl45_write(bp, phy,
  6874. MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
  6875. bnx2x_cl45_write(bp, phy,
  6876. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
  6877. } else {
  6878. /*
  6879. * Since the 8727 has only single reset pin, need to set the 10G
  6880. * registers although it is default
  6881. */
  6882. bnx2x_cl45_write(bp, phy,
  6883. MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
  6884. 0x0020);
  6885. bnx2x_cl45_write(bp, phy,
  6886. MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
  6887. bnx2x_cl45_write(bp, phy,
  6888. MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
  6889. bnx2x_cl45_write(bp, phy,
  6890. MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
  6891. 0x0008);
  6892. }
  6893. /*
  6894. * Set 2-wire transfer rate of SFP+ module EEPROM
  6895. * to 100Khz since some DACs(direct attached cables) do
  6896. * not work at 400Khz.
  6897. */
  6898. bnx2x_cl45_write(bp, phy,
  6899. MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
  6900. 0xa001);
  6901. /* Set TX PreEmphasis if needed */
  6902. if ((params->feature_config_flags &
  6903. FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
  6904. DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
  6905. phy->tx_preemphasis[0],
  6906. phy->tx_preemphasis[1]);
  6907. bnx2x_cl45_write(bp, phy,
  6908. MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
  6909. phy->tx_preemphasis[0]);
  6910. bnx2x_cl45_write(bp, phy,
  6911. MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
  6912. phy->tx_preemphasis[1]);
  6913. }
  6914. /*
  6915. * If TX Laser is controlled by GPIO_0, do not let PHY go into low
  6916. * power mode, if TX Laser is disabled
  6917. */
  6918. tx_en_mode = REG_RD(bp, params->shmem_base +
  6919. offsetof(struct shmem_region,
  6920. dev_info.port_hw_config[params->port].sfp_ctrl))
  6921. & PORT_HW_CFG_TX_LASER_MASK;
  6922. if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
  6923. DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
  6924. bnx2x_cl45_read(bp, phy,
  6925. MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
  6926. tmp2 |= 0x1000;
  6927. tmp2 &= 0xFFEF;
  6928. bnx2x_cl45_write(bp, phy,
  6929. MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
  6930. }
  6931. return 0;
  6932. }
  6933. static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
  6934. struct link_params *params)
  6935. {
  6936. struct bnx2x *bp = params->bp;
  6937. u16 mod_abs, rx_alarm_status;
  6938. u32 val = REG_RD(bp, params->shmem_base +
  6939. offsetof(struct shmem_region, dev_info.
  6940. port_feature_config[params->port].
  6941. config));
  6942. bnx2x_cl45_read(bp, phy,
  6943. MDIO_PMA_DEVAD,
  6944. MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
  6945. if (mod_abs & (1<<8)) {
  6946. /* Module is absent */
  6947. DP(NETIF_MSG_LINK, "MOD_ABS indication "
  6948. "show module is absent\n");
  6949. phy->media_type = ETH_PHY_NOT_PRESENT;
  6950. /*
  6951. * 1. Set mod_abs to detect next module
  6952. * presence event
  6953. * 2. Set EDC off by setting OPTXLOS signal input to low
  6954. * (bit 9).
  6955. * When the EDC is off it locks onto a reference clock and
  6956. * avoids becoming 'lost'.
  6957. */
  6958. mod_abs &= ~(1<<8);
  6959. if (!(phy->flags & FLAGS_NOC))
  6960. mod_abs &= ~(1<<9);
  6961. bnx2x_cl45_write(bp, phy,
  6962. MDIO_PMA_DEVAD,
  6963. MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
  6964. /*
  6965. * Clear RX alarm since it stays up as long as
  6966. * the mod_abs wasn't changed
  6967. */
  6968. bnx2x_cl45_read(bp, phy,
  6969. MDIO_PMA_DEVAD,
  6970. MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
  6971. } else {
  6972. /* Module is present */
  6973. DP(NETIF_MSG_LINK, "MOD_ABS indication "
  6974. "show module is present\n");
  6975. /*
  6976. * First disable transmitter, and if the module is ok, the
  6977. * module_detection will enable it
  6978. * 1. Set mod_abs to detect next module absent event ( bit 8)
  6979. * 2. Restore the default polarity of the OPRXLOS signal and
  6980. * this signal will then correctly indicate the presence or
  6981. * absence of the Rx signal. (bit 9)
  6982. */
  6983. mod_abs |= (1<<8);
  6984. if (!(phy->flags & FLAGS_NOC))
  6985. mod_abs |= (1<<9);
  6986. bnx2x_cl45_write(bp, phy,
  6987. MDIO_PMA_DEVAD,
  6988. MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
  6989. /*
  6990. * Clear RX alarm since it stays up as long as the mod_abs
  6991. * wasn't changed. This is need to be done before calling the
  6992. * module detection, otherwise it will clear* the link update
  6993. * alarm
  6994. */
  6995. bnx2x_cl45_read(bp, phy,
  6996. MDIO_PMA_DEVAD,
  6997. MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
  6998. if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
  6999. PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
  7000. bnx2x_sfp_set_transmitter(params, phy, 0);
  7001. if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
  7002. bnx2x_sfp_module_detection(phy, params);
  7003. else
  7004. DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
  7005. }
  7006. DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
  7007. rx_alarm_status);
  7008. /* No need to check link status in case of module plugged in/out */
  7009. }
  7010. static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
  7011. struct link_params *params,
  7012. struct link_vars *vars)
  7013. {
  7014. struct bnx2x *bp = params->bp;
  7015. u8 link_up = 0, oc_port = params->port;
  7016. u16 link_status = 0;
  7017. u16 rx_alarm_status, lasi_ctrl, val1;
  7018. /* If PHY is not initialized, do not check link status */
  7019. bnx2x_cl45_read(bp, phy,
  7020. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
  7021. &lasi_ctrl);
  7022. if (!lasi_ctrl)
  7023. return 0;
  7024. /* Check the LASI on Rx */
  7025. bnx2x_cl45_read(bp, phy,
  7026. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
  7027. &rx_alarm_status);
  7028. vars->line_speed = 0;
  7029. DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
  7030. bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
  7031. MDIO_PMA_REG_TX_ALARM_CTRL);
  7032. bnx2x_cl45_read(bp, phy,
  7033. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
  7034. DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
  7035. /* Clear MSG-OUT */
  7036. bnx2x_cl45_read(bp, phy,
  7037. MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
  7038. /*
  7039. * If a module is present and there is need to check
  7040. * for over current
  7041. */
  7042. if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
  7043. /* Check over-current using 8727 GPIO0 input*/
  7044. bnx2x_cl45_read(bp, phy,
  7045. MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
  7046. &val1);
  7047. if ((val1 & (1<<8)) == 0) {
  7048. if (!CHIP_IS_E1x(bp))
  7049. oc_port = BP_PATH(bp) + (params->port << 1);
  7050. DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
  7051. " on port %d\n", oc_port);
  7052. netdev_err(bp->dev, "Error: Power fault on Port %d has"
  7053. " been detected and the power to "
  7054. "that SFP+ module has been removed"
  7055. " to prevent failure of the card."
  7056. " Please remove the SFP+ module and"
  7057. " restart the system to clear this"
  7058. " error.\n",
  7059. oc_port);
  7060. /* Disable all RX_ALARMs except for mod_abs */
  7061. bnx2x_cl45_write(bp, phy,
  7062. MDIO_PMA_DEVAD,
  7063. MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
  7064. bnx2x_cl45_read(bp, phy,
  7065. MDIO_PMA_DEVAD,
  7066. MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
  7067. /* Wait for module_absent_event */
  7068. val1 |= (1<<8);
  7069. bnx2x_cl45_write(bp, phy,
  7070. MDIO_PMA_DEVAD,
  7071. MDIO_PMA_REG_PHY_IDENTIFIER, val1);
  7072. /* Clear RX alarm */
  7073. bnx2x_cl45_read(bp, phy,
  7074. MDIO_PMA_DEVAD,
  7075. MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
  7076. return 0;
  7077. }
  7078. } /* Over current check */
  7079. /* When module absent bit is set, check module */
  7080. if (rx_alarm_status & (1<<5)) {
  7081. bnx2x_8727_handle_mod_abs(phy, params);
  7082. /* Enable all mod_abs and link detection bits */
  7083. bnx2x_cl45_write(bp, phy,
  7084. MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
  7085. ((1<<5) | (1<<2)));
  7086. }
  7087. DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
  7088. bnx2x_8727_specific_func(phy, params, ENABLE_TX);
  7089. /* If transmitter is disabled, ignore false link up indication */
  7090. bnx2x_cl45_read(bp, phy,
  7091. MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
  7092. if (val1 & (1<<15)) {
  7093. DP(NETIF_MSG_LINK, "Tx is disabled\n");
  7094. return 0;
  7095. }
  7096. bnx2x_cl45_read(bp, phy,
  7097. MDIO_PMA_DEVAD,
  7098. MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
  7099. /*
  7100. * Bits 0..2 --> speed detected,
  7101. * Bits 13..15--> link is down
  7102. */
  7103. if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
  7104. link_up = 1;
  7105. vars->line_speed = SPEED_10000;
  7106. DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
  7107. params->port);
  7108. } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
  7109. link_up = 1;
  7110. vars->line_speed = SPEED_1000;
  7111. DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
  7112. params->port);
  7113. } else {
  7114. link_up = 0;
  7115. DP(NETIF_MSG_LINK, "port %x: External link is down\n",
  7116. params->port);
  7117. }
  7118. /* Capture 10G link fault. */
  7119. if (vars->line_speed == SPEED_10000) {
  7120. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
  7121. MDIO_PMA_REG_TX_ALARM, &val1);
  7122. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
  7123. MDIO_PMA_REG_TX_ALARM, &val1);
  7124. if (val1 & (1<<0)) {
  7125. vars->fault_detected = 1;
  7126. }
  7127. }
  7128. if (link_up) {
  7129. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  7130. vars->duplex = DUPLEX_FULL;
  7131. DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
  7132. }
  7133. if ((DUAL_MEDIA(params)) &&
  7134. (phy->req_line_speed == SPEED_1000)) {
  7135. bnx2x_cl45_read(bp, phy,
  7136. MDIO_PMA_DEVAD,
  7137. MDIO_PMA_REG_8727_PCS_GP, &val1);
  7138. /*
  7139. * In case of dual-media board and 1G, power up the XAUI side,
  7140. * otherwise power it down. For 10G it is done automatically
  7141. */
  7142. if (link_up)
  7143. val1 &= ~(3<<10);
  7144. else
  7145. val1 |= (3<<10);
  7146. bnx2x_cl45_write(bp, phy,
  7147. MDIO_PMA_DEVAD,
  7148. MDIO_PMA_REG_8727_PCS_GP, val1);
  7149. }
  7150. return link_up;
  7151. }
  7152. static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
  7153. struct link_params *params)
  7154. {
  7155. struct bnx2x *bp = params->bp;
  7156. /* Disable Transmitter */
  7157. bnx2x_sfp_set_transmitter(params, phy, 0);
  7158. /* Clear LASI */
  7159. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
  7160. }
  7161. /******************************************************************/
  7162. /* BCM8481/BCM84823/BCM84833 PHY SECTION */
  7163. /******************************************************************/
  7164. static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
  7165. struct link_params *params)
  7166. {
  7167. u16 val, fw_ver1, fw_ver2, cnt;
  7168. u8 port;
  7169. struct bnx2x *bp = params->bp;
  7170. port = params->port;
  7171. /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
  7172. /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
  7173. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
  7174. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
  7175. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
  7176. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
  7177. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
  7178. for (cnt = 0; cnt < 100; cnt++) {
  7179. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
  7180. if (val & 1)
  7181. break;
  7182. udelay(5);
  7183. }
  7184. if (cnt == 100) {
  7185. DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
  7186. bnx2x_save_spirom_version(bp, port, 0,
  7187. phy->ver_addr);
  7188. return;
  7189. }
  7190. /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
  7191. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
  7192. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
  7193. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
  7194. for (cnt = 0; cnt < 100; cnt++) {
  7195. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
  7196. if (val & 1)
  7197. break;
  7198. udelay(5);
  7199. }
  7200. if (cnt == 100) {
  7201. DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
  7202. bnx2x_save_spirom_version(bp, port, 0,
  7203. phy->ver_addr);
  7204. return;
  7205. }
  7206. /* lower 16 bits of the register SPI_FW_STATUS */
  7207. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
  7208. /* upper 16 bits of register SPI_FW_STATUS */
  7209. bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
  7210. bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
  7211. phy->ver_addr);
  7212. }
  7213. static void bnx2x_848xx_set_led(struct bnx2x *bp,
  7214. struct bnx2x_phy *phy)
  7215. {
  7216. u16 val;
  7217. /* PHYC_CTL_LED_CTL */
  7218. bnx2x_cl45_read(bp, phy,
  7219. MDIO_PMA_DEVAD,
  7220. MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
  7221. val &= 0xFE00;
  7222. val |= 0x0092;
  7223. bnx2x_cl45_write(bp, phy,
  7224. MDIO_PMA_DEVAD,
  7225. MDIO_PMA_REG_8481_LINK_SIGNAL, val);
  7226. bnx2x_cl45_write(bp, phy,
  7227. MDIO_PMA_DEVAD,
  7228. MDIO_PMA_REG_8481_LED1_MASK,
  7229. 0x80);
  7230. bnx2x_cl45_write(bp, phy,
  7231. MDIO_PMA_DEVAD,
  7232. MDIO_PMA_REG_8481_LED2_MASK,
  7233. 0x18);
  7234. /* Select activity source by Tx and Rx, as suggested by PHY AE */
  7235. bnx2x_cl45_write(bp, phy,
  7236. MDIO_PMA_DEVAD,
  7237. MDIO_PMA_REG_8481_LED3_MASK,
  7238. 0x0006);
  7239. /* Select the closest activity blink rate to that in 10/100/1000 */
  7240. bnx2x_cl45_write(bp, phy,
  7241. MDIO_PMA_DEVAD,
  7242. MDIO_PMA_REG_8481_LED3_BLINK,
  7243. 0);
  7244. bnx2x_cl45_read(bp, phy,
  7245. MDIO_PMA_DEVAD,
  7246. MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
  7247. val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
  7248. bnx2x_cl45_write(bp, phy,
  7249. MDIO_PMA_DEVAD,
  7250. MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
  7251. /* 'Interrupt Mask' */
  7252. bnx2x_cl45_write(bp, phy,
  7253. MDIO_AN_DEVAD,
  7254. 0xFFFB, 0xFFFD);
  7255. }
  7256. static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
  7257. struct link_params *params,
  7258. struct link_vars *vars)
  7259. {
  7260. struct bnx2x *bp = params->bp;
  7261. u16 autoneg_val, an_1000_val, an_10_100_val;
  7262. u16 tmp_req_line_speed;
  7263. tmp_req_line_speed = phy->req_line_speed;
  7264. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
  7265. if (phy->req_line_speed == SPEED_10000)
  7266. phy->req_line_speed = SPEED_AUTO_NEG;
  7267. /*
  7268. * This phy uses the NIG latch mechanism since link indication
  7269. * arrives through its LED4 and not via its LASI signal, so we
  7270. * get steady signal instead of clear on read
  7271. */
  7272. bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
  7273. 1 << NIG_LATCH_BC_ENABLE_MI_INT);
  7274. bnx2x_cl45_write(bp, phy,
  7275. MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
  7276. bnx2x_848xx_set_led(bp, phy);
  7277. /* set 1000 speed advertisement */
  7278. bnx2x_cl45_read(bp, phy,
  7279. MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
  7280. &an_1000_val);
  7281. bnx2x_ext_phy_set_pause(params, phy, vars);
  7282. bnx2x_cl45_read(bp, phy,
  7283. MDIO_AN_DEVAD,
  7284. MDIO_AN_REG_8481_LEGACY_AN_ADV,
  7285. &an_10_100_val);
  7286. bnx2x_cl45_read(bp, phy,
  7287. MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
  7288. &autoneg_val);
  7289. /* Disable forced speed */
  7290. autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
  7291. an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
  7292. if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
  7293. (phy->speed_cap_mask &
  7294. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
  7295. (phy->req_line_speed == SPEED_1000)) {
  7296. an_1000_val |= (1<<8);
  7297. autoneg_val |= (1<<9 | 1<<12);
  7298. if (phy->req_duplex == DUPLEX_FULL)
  7299. an_1000_val |= (1<<9);
  7300. DP(NETIF_MSG_LINK, "Advertising 1G\n");
  7301. } else
  7302. an_1000_val &= ~((1<<8) | (1<<9));
  7303. bnx2x_cl45_write(bp, phy,
  7304. MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
  7305. an_1000_val);
  7306. /* set 10 speed advertisement */
  7307. if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
  7308. (phy->speed_cap_mask &
  7309. (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
  7310. PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
  7311. an_10_100_val |= (1<<7);
  7312. /* Enable autoneg and restart autoneg for legacy speeds */
  7313. autoneg_val |= (1<<9 | 1<<12);
  7314. if (phy->req_duplex == DUPLEX_FULL)
  7315. an_10_100_val |= (1<<8);
  7316. DP(NETIF_MSG_LINK, "Advertising 100M\n");
  7317. }
  7318. /* set 10 speed advertisement */
  7319. if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
  7320. (phy->speed_cap_mask &
  7321. (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
  7322. PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
  7323. an_10_100_val |= (1<<5);
  7324. autoneg_val |= (1<<9 | 1<<12);
  7325. if (phy->req_duplex == DUPLEX_FULL)
  7326. an_10_100_val |= (1<<6);
  7327. DP(NETIF_MSG_LINK, "Advertising 10M\n");
  7328. }
  7329. /* Only 10/100 are allowed to work in FORCE mode */
  7330. if (phy->req_line_speed == SPEED_100) {
  7331. autoneg_val |= (1<<13);
  7332. /* Enabled AUTO-MDIX when autoneg is disabled */
  7333. bnx2x_cl45_write(bp, phy,
  7334. MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
  7335. (1<<15 | 1<<9 | 7<<0));
  7336. DP(NETIF_MSG_LINK, "Setting 100M force\n");
  7337. }
  7338. if (phy->req_line_speed == SPEED_10) {
  7339. /* Enabled AUTO-MDIX when autoneg is disabled */
  7340. bnx2x_cl45_write(bp, phy,
  7341. MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
  7342. (1<<15 | 1<<9 | 7<<0));
  7343. DP(NETIF_MSG_LINK, "Setting 10M force\n");
  7344. }
  7345. bnx2x_cl45_write(bp, phy,
  7346. MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
  7347. an_10_100_val);
  7348. if (phy->req_duplex == DUPLEX_FULL)
  7349. autoneg_val |= (1<<8);
  7350. bnx2x_cl45_write(bp, phy,
  7351. MDIO_AN_DEVAD,
  7352. MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
  7353. if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
  7354. (phy->speed_cap_mask &
  7355. PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
  7356. (phy->req_line_speed == SPEED_10000)) {
  7357. DP(NETIF_MSG_LINK, "Advertising 10G\n");
  7358. /* Restart autoneg for 10G*/
  7359. bnx2x_cl45_write(bp, phy,
  7360. MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
  7361. 0x3200);
  7362. } else if (phy->req_line_speed != SPEED_10 &&
  7363. phy->req_line_speed != SPEED_100) {
  7364. bnx2x_cl45_write(bp, phy,
  7365. MDIO_AN_DEVAD,
  7366. MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
  7367. 1);
  7368. }
  7369. /* Save spirom version */
  7370. bnx2x_save_848xx_spirom_version(phy, params);
  7371. phy->req_line_speed = tmp_req_line_speed;
  7372. return 0;
  7373. }
  7374. static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
  7375. struct link_params *params,
  7376. struct link_vars *vars)
  7377. {
  7378. struct bnx2x *bp = params->bp;
  7379. /* Restore normal power mode*/
  7380. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  7381. MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
  7382. /* HW reset */
  7383. bnx2x_ext_phy_hw_reset(bp, params->port);
  7384. bnx2x_wait_reset_complete(bp, phy, params);
  7385. bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
  7386. return bnx2x_848xx_cmn_config_init(phy, params, vars);
  7387. }
  7388. #define PHY84833_HDSHK_WAIT 300
  7389. static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
  7390. struct link_params *params,
  7391. struct link_vars *vars)
  7392. {
  7393. u32 idx;
  7394. u16 val;
  7395. u16 data = 0x01b1;
  7396. struct bnx2x *bp = params->bp;
  7397. /* Do pair swap */
  7398. /* Write CMD_OPEN_OVERRIDE to STATUS reg */
  7399. bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
  7400. MDIO_84833_TOP_CFG_SCRATCH_REG2,
  7401. PHY84833_CMD_OPEN_OVERRIDE);
  7402. for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
  7403. bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
  7404. MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
  7405. if (val == PHY84833_CMD_OPEN_FOR_CMDS)
  7406. break;
  7407. msleep(1);
  7408. }
  7409. if (idx >= PHY84833_HDSHK_WAIT) {
  7410. DP(NETIF_MSG_LINK, "Pairswap: FW not ready.\n");
  7411. return -EINVAL;
  7412. }
  7413. bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
  7414. MDIO_84833_TOP_CFG_SCRATCH_REG4,
  7415. data);
  7416. /* Issue pair swap command */
  7417. bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
  7418. MDIO_84833_TOP_CFG_SCRATCH_REG0,
  7419. PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE);
  7420. for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
  7421. bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
  7422. MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
  7423. if ((val == PHY84833_CMD_COMPLETE_PASS) ||
  7424. (val == PHY84833_CMD_COMPLETE_ERROR))
  7425. break;
  7426. msleep(1);
  7427. }
  7428. if ((idx >= PHY84833_HDSHK_WAIT) ||
  7429. (val == PHY84833_CMD_COMPLETE_ERROR)) {
  7430. DP(NETIF_MSG_LINK, "Pairswap: override failed.\n");
  7431. return -EINVAL;
  7432. }
  7433. bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
  7434. MDIO_84833_TOP_CFG_SCRATCH_REG2,
  7435. PHY84833_CMD_CLEAR_COMPLETE);
  7436. DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data);
  7437. return 0;
  7438. }
  7439. static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
  7440. struct link_params *params,
  7441. struct link_vars *vars)
  7442. {
  7443. struct bnx2x *bp = params->bp;
  7444. u8 port, initialize = 1;
  7445. u16 val;
  7446. u16 temp;
  7447. u32 actual_phy_selection, cms_enable;
  7448. int rc = 0;
  7449. msleep(1);
  7450. if (!(CHIP_IS_E1(bp)))
  7451. port = BP_PATH(bp);
  7452. else
  7453. port = params->port;
  7454. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
  7455. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
  7456. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  7457. port);
  7458. } else {
  7459. bnx2x_cl45_write(bp, phy,
  7460. MDIO_PMA_DEVAD,
  7461. MDIO_PMA_REG_CTRL, 0x8000);
  7462. }
  7463. bnx2x_wait_reset_complete(bp, phy, params);
  7464. /* Wait for GPHY to come out of reset */
  7465. msleep(50);
  7466. /* Bring PHY out of super isolate mode */
  7467. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
  7468. bnx2x_cl45_read(bp, phy,
  7469. MDIO_CTL_DEVAD,
  7470. MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
  7471. val &= ~MDIO_84833_SUPER_ISOLATE;
  7472. bnx2x_cl45_write(bp, phy,
  7473. MDIO_CTL_DEVAD,
  7474. MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
  7475. bnx2x_wait_reset_complete(bp, phy, params);
  7476. }
  7477. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
  7478. bnx2x_84833_pair_swap_cfg(phy, params, vars);
  7479. /*
  7480. * BCM84823 requires that XGXS links up first @ 10G for normal behavior
  7481. */
  7482. temp = vars->line_speed;
  7483. vars->line_speed = SPEED_10000;
  7484. bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
  7485. bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
  7486. vars->line_speed = temp;
  7487. /* Set dual-media configuration according to configuration */
  7488. bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
  7489. MDIO_CTL_REG_84823_MEDIA, &val);
  7490. val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
  7491. MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
  7492. MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
  7493. MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
  7494. MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
  7495. val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
  7496. MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
  7497. actual_phy_selection = bnx2x_phy_selection(params);
  7498. switch (actual_phy_selection) {
  7499. case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
  7500. /* Do nothing. Essentially this is like the priority copper */
  7501. break;
  7502. case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
  7503. val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
  7504. break;
  7505. case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
  7506. val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
  7507. break;
  7508. case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
  7509. /* Do nothing here. The first PHY won't be initialized at all */
  7510. break;
  7511. case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
  7512. val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
  7513. initialize = 0;
  7514. break;
  7515. }
  7516. if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
  7517. val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
  7518. bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
  7519. MDIO_CTL_REG_84823_MEDIA, val);
  7520. DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
  7521. params->multi_phy_config, val);
  7522. if (initialize)
  7523. rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
  7524. else
  7525. bnx2x_save_848xx_spirom_version(phy, params);
  7526. cms_enable = REG_RD(bp, params->shmem_base +
  7527. offsetof(struct shmem_region,
  7528. dev_info.port_hw_config[params->port].default_cfg)) &
  7529. PORT_HW_CFG_ENABLE_CMS_MASK;
  7530. bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
  7531. MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
  7532. if (cms_enable)
  7533. val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
  7534. else
  7535. val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
  7536. bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
  7537. MDIO_CTL_REG_84823_USER_CTRL_REG, val);
  7538. return rc;
  7539. }
  7540. static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
  7541. struct link_params *params,
  7542. struct link_vars *vars)
  7543. {
  7544. struct bnx2x *bp = params->bp;
  7545. u16 val, val1, val2;
  7546. u8 link_up = 0;
  7547. /* Check 10G-BaseT link status */
  7548. /* Check PMD signal ok */
  7549. bnx2x_cl45_read(bp, phy,
  7550. MDIO_AN_DEVAD, 0xFFFA, &val1);
  7551. bnx2x_cl45_read(bp, phy,
  7552. MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
  7553. &val2);
  7554. DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
  7555. /* Check link 10G */
  7556. if (val2 & (1<<11)) {
  7557. vars->line_speed = SPEED_10000;
  7558. vars->duplex = DUPLEX_FULL;
  7559. link_up = 1;
  7560. bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
  7561. } else { /* Check Legacy speed link */
  7562. u16 legacy_status, legacy_speed;
  7563. /* Enable expansion register 0x42 (Operation mode status) */
  7564. bnx2x_cl45_write(bp, phy,
  7565. MDIO_AN_DEVAD,
  7566. MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
  7567. /* Get legacy speed operation status */
  7568. bnx2x_cl45_read(bp, phy,
  7569. MDIO_AN_DEVAD,
  7570. MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
  7571. &legacy_status);
  7572. DP(NETIF_MSG_LINK, "Legacy speed status"
  7573. " = 0x%x\n", legacy_status);
  7574. link_up = ((legacy_status & (1<<11)) == (1<<11));
  7575. if (link_up) {
  7576. legacy_speed = (legacy_status & (3<<9));
  7577. if (legacy_speed == (0<<9))
  7578. vars->line_speed = SPEED_10;
  7579. else if (legacy_speed == (1<<9))
  7580. vars->line_speed = SPEED_100;
  7581. else if (legacy_speed == (2<<9))
  7582. vars->line_speed = SPEED_1000;
  7583. else /* Should not happen */
  7584. vars->line_speed = 0;
  7585. if (legacy_status & (1<<8))
  7586. vars->duplex = DUPLEX_FULL;
  7587. else
  7588. vars->duplex = DUPLEX_HALF;
  7589. DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
  7590. " is_duplex_full= %d\n", vars->line_speed,
  7591. (vars->duplex == DUPLEX_FULL));
  7592. /* Check legacy speed AN resolution */
  7593. bnx2x_cl45_read(bp, phy,
  7594. MDIO_AN_DEVAD,
  7595. MDIO_AN_REG_8481_LEGACY_MII_STATUS,
  7596. &val);
  7597. if (val & (1<<5))
  7598. vars->link_status |=
  7599. LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
  7600. bnx2x_cl45_read(bp, phy,
  7601. MDIO_AN_DEVAD,
  7602. MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
  7603. &val);
  7604. if ((val & (1<<0)) == 0)
  7605. vars->link_status |=
  7606. LINK_STATUS_PARALLEL_DETECTION_USED;
  7607. }
  7608. }
  7609. if (link_up) {
  7610. DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
  7611. vars->line_speed);
  7612. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  7613. }
  7614. return link_up;
  7615. }
  7616. static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
  7617. {
  7618. int status = 0;
  7619. u32 spirom_ver;
  7620. spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
  7621. status = bnx2x_format_ver(spirom_ver, str, len);
  7622. return status;
  7623. }
  7624. static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
  7625. struct link_params *params)
  7626. {
  7627. bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
  7628. MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
  7629. bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
  7630. MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
  7631. }
  7632. static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
  7633. struct link_params *params)
  7634. {
  7635. bnx2x_cl45_write(params->bp, phy,
  7636. MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
  7637. bnx2x_cl45_write(params->bp, phy,
  7638. MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
  7639. }
  7640. static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
  7641. struct link_params *params)
  7642. {
  7643. struct bnx2x *bp = params->bp;
  7644. u8 port;
  7645. if (!(CHIP_IS_E1(bp)))
  7646. port = BP_PATH(bp);
  7647. else
  7648. port = params->port;
  7649. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
  7650. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
  7651. MISC_REGISTERS_GPIO_OUTPUT_LOW,
  7652. port);
  7653. } else {
  7654. bnx2x_cl45_write(bp, phy,
  7655. MDIO_PMA_DEVAD,
  7656. MDIO_PMA_REG_CTRL, 0x800);
  7657. }
  7658. }
  7659. static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
  7660. struct link_params *params, u8 mode)
  7661. {
  7662. struct bnx2x *bp = params->bp;
  7663. u16 val;
  7664. u8 port;
  7665. if (!(CHIP_IS_E1(bp)))
  7666. port = BP_PATH(bp);
  7667. else
  7668. port = params->port;
  7669. switch (mode) {
  7670. case LED_MODE_OFF:
  7671. DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
  7672. if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
  7673. SHARED_HW_CFG_LED_EXTPHY1) {
  7674. /* Set LED masks */
  7675. bnx2x_cl45_write(bp, phy,
  7676. MDIO_PMA_DEVAD,
  7677. MDIO_PMA_REG_8481_LED1_MASK,
  7678. 0x0);
  7679. bnx2x_cl45_write(bp, phy,
  7680. MDIO_PMA_DEVAD,
  7681. MDIO_PMA_REG_8481_LED2_MASK,
  7682. 0x0);
  7683. bnx2x_cl45_write(bp, phy,
  7684. MDIO_PMA_DEVAD,
  7685. MDIO_PMA_REG_8481_LED3_MASK,
  7686. 0x0);
  7687. bnx2x_cl45_write(bp, phy,
  7688. MDIO_PMA_DEVAD,
  7689. MDIO_PMA_REG_8481_LED5_MASK,
  7690. 0x0);
  7691. } else {
  7692. bnx2x_cl45_write(bp, phy,
  7693. MDIO_PMA_DEVAD,
  7694. MDIO_PMA_REG_8481_LED1_MASK,
  7695. 0x0);
  7696. }
  7697. break;
  7698. case LED_MODE_FRONT_PANEL_OFF:
  7699. DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
  7700. port);
  7701. if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
  7702. SHARED_HW_CFG_LED_EXTPHY1) {
  7703. /* Set LED masks */
  7704. bnx2x_cl45_write(bp, phy,
  7705. MDIO_PMA_DEVAD,
  7706. MDIO_PMA_REG_8481_LED1_MASK,
  7707. 0x0);
  7708. bnx2x_cl45_write(bp, phy,
  7709. MDIO_PMA_DEVAD,
  7710. MDIO_PMA_REG_8481_LED2_MASK,
  7711. 0x0);
  7712. bnx2x_cl45_write(bp, phy,
  7713. MDIO_PMA_DEVAD,
  7714. MDIO_PMA_REG_8481_LED3_MASK,
  7715. 0x0);
  7716. bnx2x_cl45_write(bp, phy,
  7717. MDIO_PMA_DEVAD,
  7718. MDIO_PMA_REG_8481_LED5_MASK,
  7719. 0x20);
  7720. } else {
  7721. bnx2x_cl45_write(bp, phy,
  7722. MDIO_PMA_DEVAD,
  7723. MDIO_PMA_REG_8481_LED1_MASK,
  7724. 0x0);
  7725. }
  7726. break;
  7727. case LED_MODE_ON:
  7728. DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
  7729. if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
  7730. SHARED_HW_CFG_LED_EXTPHY1) {
  7731. /* Set control reg */
  7732. bnx2x_cl45_read(bp, phy,
  7733. MDIO_PMA_DEVAD,
  7734. MDIO_PMA_REG_8481_LINK_SIGNAL,
  7735. &val);
  7736. val &= 0x8000;
  7737. val |= 0x2492;
  7738. bnx2x_cl45_write(bp, phy,
  7739. MDIO_PMA_DEVAD,
  7740. MDIO_PMA_REG_8481_LINK_SIGNAL,
  7741. val);
  7742. /* Set LED masks */
  7743. bnx2x_cl45_write(bp, phy,
  7744. MDIO_PMA_DEVAD,
  7745. MDIO_PMA_REG_8481_LED1_MASK,
  7746. 0x0);
  7747. bnx2x_cl45_write(bp, phy,
  7748. MDIO_PMA_DEVAD,
  7749. MDIO_PMA_REG_8481_LED2_MASK,
  7750. 0x20);
  7751. bnx2x_cl45_write(bp, phy,
  7752. MDIO_PMA_DEVAD,
  7753. MDIO_PMA_REG_8481_LED3_MASK,
  7754. 0x20);
  7755. bnx2x_cl45_write(bp, phy,
  7756. MDIO_PMA_DEVAD,
  7757. MDIO_PMA_REG_8481_LED5_MASK,
  7758. 0x0);
  7759. } else {
  7760. bnx2x_cl45_write(bp, phy,
  7761. MDIO_PMA_DEVAD,
  7762. MDIO_PMA_REG_8481_LED1_MASK,
  7763. 0x20);
  7764. }
  7765. break;
  7766. case LED_MODE_OPER:
  7767. DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
  7768. if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
  7769. SHARED_HW_CFG_LED_EXTPHY1) {
  7770. /* Set control reg */
  7771. bnx2x_cl45_read(bp, phy,
  7772. MDIO_PMA_DEVAD,
  7773. MDIO_PMA_REG_8481_LINK_SIGNAL,
  7774. &val);
  7775. if (!((val &
  7776. MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
  7777. >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
  7778. DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
  7779. bnx2x_cl45_write(bp, phy,
  7780. MDIO_PMA_DEVAD,
  7781. MDIO_PMA_REG_8481_LINK_SIGNAL,
  7782. 0xa492);
  7783. }
  7784. /* Set LED masks */
  7785. bnx2x_cl45_write(bp, phy,
  7786. MDIO_PMA_DEVAD,
  7787. MDIO_PMA_REG_8481_LED1_MASK,
  7788. 0x10);
  7789. bnx2x_cl45_write(bp, phy,
  7790. MDIO_PMA_DEVAD,
  7791. MDIO_PMA_REG_8481_LED2_MASK,
  7792. 0x80);
  7793. bnx2x_cl45_write(bp, phy,
  7794. MDIO_PMA_DEVAD,
  7795. MDIO_PMA_REG_8481_LED3_MASK,
  7796. 0x98);
  7797. bnx2x_cl45_write(bp, phy,
  7798. MDIO_PMA_DEVAD,
  7799. MDIO_PMA_REG_8481_LED5_MASK,
  7800. 0x40);
  7801. } else {
  7802. bnx2x_cl45_write(bp, phy,
  7803. MDIO_PMA_DEVAD,
  7804. MDIO_PMA_REG_8481_LED1_MASK,
  7805. 0x80);
  7806. /* Tell LED3 to blink on source */
  7807. bnx2x_cl45_read(bp, phy,
  7808. MDIO_PMA_DEVAD,
  7809. MDIO_PMA_REG_8481_LINK_SIGNAL,
  7810. &val);
  7811. val &= ~(7<<6);
  7812. val |= (1<<6); /* A83B[8:6]= 1 */
  7813. bnx2x_cl45_write(bp, phy,
  7814. MDIO_PMA_DEVAD,
  7815. MDIO_PMA_REG_8481_LINK_SIGNAL,
  7816. val);
  7817. }
  7818. break;
  7819. }
  7820. }
  7821. /******************************************************************/
  7822. /* 54616S PHY SECTION */
  7823. /******************************************************************/
  7824. static int bnx2x_54616s_config_init(struct bnx2x_phy *phy,
  7825. struct link_params *params,
  7826. struct link_vars *vars)
  7827. {
  7828. struct bnx2x *bp = params->bp;
  7829. u8 port;
  7830. u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
  7831. u32 cfg_pin;
  7832. DP(NETIF_MSG_LINK, "54616S cfg init\n");
  7833. usleep_range(1000, 1000);
  7834. /* This works with E3 only, no need to check the chip
  7835. before determining the port. */
  7836. port = params->port;
  7837. cfg_pin = (REG_RD(bp, params->shmem_base +
  7838. offsetof(struct shmem_region,
  7839. dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
  7840. PORT_HW_CFG_E3_PHY_RESET_MASK) >>
  7841. PORT_HW_CFG_E3_PHY_RESET_SHIFT;
  7842. /* Drive pin high to bring the GPHY out of reset. */
  7843. bnx2x_set_cfg_pin(bp, cfg_pin, 1);
  7844. /* wait for GPHY to reset */
  7845. msleep(50);
  7846. /* reset phy */
  7847. bnx2x_cl22_write(bp, phy,
  7848. MDIO_PMA_REG_CTRL, 0x8000);
  7849. bnx2x_wait_reset_complete(bp, phy, params);
  7850. /*wait for GPHY to reset */
  7851. msleep(50);
  7852. /* Configure LED4: set to INTR (0x6). */
  7853. /* Accessing shadow register 0xe. */
  7854. bnx2x_cl22_write(bp, phy,
  7855. MDIO_REG_GPHY_SHADOW,
  7856. MDIO_REG_GPHY_SHADOW_LED_SEL2);
  7857. bnx2x_cl22_read(bp, phy,
  7858. MDIO_REG_GPHY_SHADOW,
  7859. &temp);
  7860. temp &= ~(0xf << 4);
  7861. temp |= (0x6 << 4);
  7862. bnx2x_cl22_write(bp, phy,
  7863. MDIO_REG_GPHY_SHADOW,
  7864. MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
  7865. /* Configure INTR based on link status change. */
  7866. bnx2x_cl22_write(bp, phy,
  7867. MDIO_REG_INTR_MASK,
  7868. ~MDIO_REG_INTR_MASK_LINK_STATUS);
  7869. /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
  7870. bnx2x_cl22_write(bp, phy,
  7871. MDIO_REG_GPHY_SHADOW,
  7872. MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
  7873. bnx2x_cl22_read(bp, phy,
  7874. MDIO_REG_GPHY_SHADOW,
  7875. &temp);
  7876. temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
  7877. bnx2x_cl22_write(bp, phy,
  7878. MDIO_REG_GPHY_SHADOW,
  7879. MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
  7880. /* Set up fc */
  7881. /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
  7882. bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
  7883. fc_val = 0;
  7884. if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
  7885. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
  7886. fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
  7887. if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
  7888. MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
  7889. fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
  7890. /* read all advertisement */
  7891. bnx2x_cl22_read(bp, phy,
  7892. 0x09,
  7893. &an_1000_val);
  7894. bnx2x_cl22_read(bp, phy,
  7895. 0x04,
  7896. &an_10_100_val);
  7897. bnx2x_cl22_read(bp, phy,
  7898. MDIO_PMA_REG_CTRL,
  7899. &autoneg_val);
  7900. /* Disable forced speed */
  7901. autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
  7902. an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
  7903. (1<<11));
  7904. if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
  7905. (phy->speed_cap_mask &
  7906. PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
  7907. (phy->req_line_speed == SPEED_1000)) {
  7908. an_1000_val |= (1<<8);
  7909. autoneg_val |= (1<<9 | 1<<12);
  7910. if (phy->req_duplex == DUPLEX_FULL)
  7911. an_1000_val |= (1<<9);
  7912. DP(NETIF_MSG_LINK, "Advertising 1G\n");
  7913. } else
  7914. an_1000_val &= ~((1<<8) | (1<<9));
  7915. bnx2x_cl22_write(bp, phy,
  7916. 0x09,
  7917. an_1000_val);
  7918. bnx2x_cl22_read(bp, phy,
  7919. 0x09,
  7920. &an_1000_val);
  7921. /* set 100 speed advertisement */
  7922. if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
  7923. (phy->speed_cap_mask &
  7924. (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
  7925. PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
  7926. an_10_100_val |= (1<<7);
  7927. /* Enable autoneg and restart autoneg for legacy speeds */
  7928. autoneg_val |= (1<<9 | 1<<12);
  7929. if (phy->req_duplex == DUPLEX_FULL)
  7930. an_10_100_val |= (1<<8);
  7931. DP(NETIF_MSG_LINK, "Advertising 100M\n");
  7932. }
  7933. /* set 10 speed advertisement */
  7934. if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
  7935. (phy->speed_cap_mask &
  7936. (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
  7937. PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
  7938. an_10_100_val |= (1<<5);
  7939. autoneg_val |= (1<<9 | 1<<12);
  7940. if (phy->req_duplex == DUPLEX_FULL)
  7941. an_10_100_val |= (1<<6);
  7942. DP(NETIF_MSG_LINK, "Advertising 10M\n");
  7943. }
  7944. /* Only 10/100 are allowed to work in FORCE mode */
  7945. if (phy->req_line_speed == SPEED_100) {
  7946. autoneg_val |= (1<<13);
  7947. /* Enabled AUTO-MDIX when autoneg is disabled */
  7948. bnx2x_cl22_write(bp, phy,
  7949. 0x18,
  7950. (1<<15 | 1<<9 | 7<<0));
  7951. DP(NETIF_MSG_LINK, "Setting 100M force\n");
  7952. }
  7953. if (phy->req_line_speed == SPEED_10) {
  7954. /* Enabled AUTO-MDIX when autoneg is disabled */
  7955. bnx2x_cl22_write(bp, phy,
  7956. 0x18,
  7957. (1<<15 | 1<<9 | 7<<0));
  7958. DP(NETIF_MSG_LINK, "Setting 10M force\n");
  7959. }
  7960. bnx2x_cl22_write(bp, phy,
  7961. 0x04,
  7962. an_10_100_val | fc_val);
  7963. if (phy->req_duplex == DUPLEX_FULL)
  7964. autoneg_val |= (1<<8);
  7965. bnx2x_cl22_write(bp, phy,
  7966. MDIO_PMA_REG_CTRL, autoneg_val);
  7967. return 0;
  7968. }
  7969. static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy,
  7970. struct link_params *params, u8 mode)
  7971. {
  7972. struct bnx2x *bp = params->bp;
  7973. DP(NETIF_MSG_LINK, "54616S set link led (mode=%x)\n", mode);
  7974. switch (mode) {
  7975. case LED_MODE_FRONT_PANEL_OFF:
  7976. case LED_MODE_OFF:
  7977. case LED_MODE_OPER:
  7978. case LED_MODE_ON:
  7979. default:
  7980. break;
  7981. }
  7982. return;
  7983. }
  7984. static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy,
  7985. struct link_params *params)
  7986. {
  7987. struct bnx2x *bp = params->bp;
  7988. u32 cfg_pin;
  7989. u8 port;
  7990. /* This works with E3 only, no need to check the chip
  7991. before determining the port. */
  7992. port = params->port;
  7993. cfg_pin = (REG_RD(bp, params->shmem_base +
  7994. offsetof(struct shmem_region,
  7995. dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
  7996. PORT_HW_CFG_E3_PHY_RESET_MASK) >>
  7997. PORT_HW_CFG_E3_PHY_RESET_SHIFT;
  7998. /* Drive pin low to put GPHY in reset. */
  7999. bnx2x_set_cfg_pin(bp, cfg_pin, 0);
  8000. }
  8001. static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy,
  8002. struct link_params *params,
  8003. struct link_vars *vars)
  8004. {
  8005. struct bnx2x *bp = params->bp;
  8006. u16 val;
  8007. u8 link_up = 0;
  8008. u16 legacy_status, legacy_speed;
  8009. /* Get speed operation status */
  8010. bnx2x_cl22_read(bp, phy,
  8011. 0x19,
  8012. &legacy_status);
  8013. DP(NETIF_MSG_LINK, "54616S read_status: 0x%x\n", legacy_status);
  8014. /* Read status to clear the PHY interrupt. */
  8015. bnx2x_cl22_read(bp, phy,
  8016. MDIO_REG_INTR_STATUS,
  8017. &val);
  8018. link_up = ((legacy_status & (1<<2)) == (1<<2));
  8019. if (link_up) {
  8020. legacy_speed = (legacy_status & (7<<8));
  8021. if (legacy_speed == (7<<8)) {
  8022. vars->line_speed = SPEED_1000;
  8023. vars->duplex = DUPLEX_FULL;
  8024. } else if (legacy_speed == (6<<8)) {
  8025. vars->line_speed = SPEED_1000;
  8026. vars->duplex = DUPLEX_HALF;
  8027. } else if (legacy_speed == (5<<8)) {
  8028. vars->line_speed = SPEED_100;
  8029. vars->duplex = DUPLEX_FULL;
  8030. }
  8031. /* Omitting 100Base-T4 for now */
  8032. else if (legacy_speed == (3<<8)) {
  8033. vars->line_speed = SPEED_100;
  8034. vars->duplex = DUPLEX_HALF;
  8035. } else if (legacy_speed == (2<<8)) {
  8036. vars->line_speed = SPEED_10;
  8037. vars->duplex = DUPLEX_FULL;
  8038. } else if (legacy_speed == (1<<8)) {
  8039. vars->line_speed = SPEED_10;
  8040. vars->duplex = DUPLEX_HALF;
  8041. } else /* Should not happen */
  8042. vars->line_speed = 0;
  8043. DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
  8044. " is_duplex_full= %d\n", vars->line_speed,
  8045. (vars->duplex == DUPLEX_FULL));
  8046. /* Check legacy speed AN resolution */
  8047. bnx2x_cl22_read(bp, phy,
  8048. 0x01,
  8049. &val);
  8050. if (val & (1<<5))
  8051. vars->link_status |=
  8052. LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
  8053. bnx2x_cl22_read(bp, phy,
  8054. 0x06,
  8055. &val);
  8056. if ((val & (1<<0)) == 0)
  8057. vars->link_status |=
  8058. LINK_STATUS_PARALLEL_DETECTION_USED;
  8059. DP(NETIF_MSG_LINK, "BCM54616S: link speed is %d\n",
  8060. vars->line_speed);
  8061. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  8062. }
  8063. return link_up;
  8064. }
  8065. static void bnx2x_54616s_config_loopback(struct bnx2x_phy *phy,
  8066. struct link_params *params)
  8067. {
  8068. struct bnx2x *bp = params->bp;
  8069. u16 val;
  8070. u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
  8071. DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54616s\n");
  8072. /* Enable master/slave manual mmode and set to master */
  8073. /* mii write 9 [bits set 11 12] */
  8074. bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
  8075. /* forced 1G and disable autoneg */
  8076. /* set val [mii read 0] */
  8077. /* set val [expr $val & [bits clear 6 12 13]] */
  8078. /* set val [expr $val | [bits set 6 8]] */
  8079. /* mii write 0 $val */
  8080. bnx2x_cl22_read(bp, phy, 0x00, &val);
  8081. val &= ~((1<<6) | (1<<12) | (1<<13));
  8082. val |= (1<<6) | (1<<8);
  8083. bnx2x_cl22_write(bp, phy, 0x00, val);
  8084. /* Set external loopback and Tx using 6dB coding */
  8085. /* mii write 0x18 7 */
  8086. /* set val [mii read 0x18] */
  8087. /* mii write 0x18 [expr $val | [bits set 10 15]] */
  8088. bnx2x_cl22_write(bp, phy, 0x18, 7);
  8089. bnx2x_cl22_read(bp, phy, 0x18, &val);
  8090. bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
  8091. /* This register opens the gate for the UMAC despite its name */
  8092. REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
  8093. /*
  8094. * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
  8095. * length used by the MAC receive logic to check frames.
  8096. */
  8097. REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
  8098. }
  8099. /******************************************************************/
  8100. /* SFX7101 PHY SECTION */
  8101. /******************************************************************/
  8102. static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
  8103. struct link_params *params)
  8104. {
  8105. struct bnx2x *bp = params->bp;
  8106. /* SFX7101_XGXS_TEST1 */
  8107. bnx2x_cl45_write(bp, phy,
  8108. MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
  8109. }
  8110. static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
  8111. struct link_params *params,
  8112. struct link_vars *vars)
  8113. {
  8114. u16 fw_ver1, fw_ver2, val;
  8115. struct bnx2x *bp = params->bp;
  8116. DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
  8117. /* Restore normal power mode*/
  8118. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  8119. MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
  8120. /* HW reset */
  8121. bnx2x_ext_phy_hw_reset(bp, params->port);
  8122. bnx2x_wait_reset_complete(bp, phy, params);
  8123. bnx2x_cl45_write(bp, phy,
  8124. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
  8125. DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
  8126. bnx2x_cl45_write(bp, phy,
  8127. MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
  8128. bnx2x_ext_phy_set_pause(params, phy, vars);
  8129. /* Restart autoneg */
  8130. bnx2x_cl45_read(bp, phy,
  8131. MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
  8132. val |= 0x200;
  8133. bnx2x_cl45_write(bp, phy,
  8134. MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
  8135. /* Save spirom version */
  8136. bnx2x_cl45_read(bp, phy,
  8137. MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
  8138. bnx2x_cl45_read(bp, phy,
  8139. MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
  8140. bnx2x_save_spirom_version(bp, params->port,
  8141. (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
  8142. return 0;
  8143. }
  8144. static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
  8145. struct link_params *params,
  8146. struct link_vars *vars)
  8147. {
  8148. struct bnx2x *bp = params->bp;
  8149. u8 link_up;
  8150. u16 val1, val2;
  8151. bnx2x_cl45_read(bp, phy,
  8152. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
  8153. bnx2x_cl45_read(bp, phy,
  8154. MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
  8155. DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
  8156. val2, val1);
  8157. bnx2x_cl45_read(bp, phy,
  8158. MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
  8159. bnx2x_cl45_read(bp, phy,
  8160. MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
  8161. DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
  8162. val2, val1);
  8163. link_up = ((val1 & 4) == 4);
  8164. /* if link is up print the AN outcome of the SFX7101 PHY */
  8165. if (link_up) {
  8166. bnx2x_cl45_read(bp, phy,
  8167. MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
  8168. &val2);
  8169. vars->line_speed = SPEED_10000;
  8170. vars->duplex = DUPLEX_FULL;
  8171. DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
  8172. val2, (val2 & (1<<14)));
  8173. bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
  8174. bnx2x_ext_phy_resolve_fc(phy, params, vars);
  8175. }
  8176. return link_up;
  8177. }
  8178. static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
  8179. {
  8180. if (*len < 5)
  8181. return -EINVAL;
  8182. str[0] = (spirom_ver & 0xFF);
  8183. str[1] = (spirom_ver & 0xFF00) >> 8;
  8184. str[2] = (spirom_ver & 0xFF0000) >> 16;
  8185. str[3] = (spirom_ver & 0xFF000000) >> 24;
  8186. str[4] = '\0';
  8187. *len -= 5;
  8188. return 0;
  8189. }
  8190. void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
  8191. {
  8192. u16 val, cnt;
  8193. bnx2x_cl45_read(bp, phy,
  8194. MDIO_PMA_DEVAD,
  8195. MDIO_PMA_REG_7101_RESET, &val);
  8196. for (cnt = 0; cnt < 10; cnt++) {
  8197. msleep(50);
  8198. /* Writes a self-clearing reset */
  8199. bnx2x_cl45_write(bp, phy,
  8200. MDIO_PMA_DEVAD,
  8201. MDIO_PMA_REG_7101_RESET,
  8202. (val | (1<<15)));
  8203. /* Wait for clear */
  8204. bnx2x_cl45_read(bp, phy,
  8205. MDIO_PMA_DEVAD,
  8206. MDIO_PMA_REG_7101_RESET, &val);
  8207. if ((val & (1<<15)) == 0)
  8208. break;
  8209. }
  8210. }
  8211. static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
  8212. struct link_params *params) {
  8213. /* Low power mode is controlled by GPIO 2 */
  8214. bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
  8215. MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
  8216. /* The PHY reset is controlled by GPIO 1 */
  8217. bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
  8218. MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
  8219. }
  8220. static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
  8221. struct link_params *params, u8 mode)
  8222. {
  8223. u16 val = 0;
  8224. struct bnx2x *bp = params->bp;
  8225. switch (mode) {
  8226. case LED_MODE_FRONT_PANEL_OFF:
  8227. case LED_MODE_OFF:
  8228. val = 2;
  8229. break;
  8230. case LED_MODE_ON:
  8231. val = 1;
  8232. break;
  8233. case LED_MODE_OPER:
  8234. val = 0;
  8235. break;
  8236. }
  8237. bnx2x_cl45_write(bp, phy,
  8238. MDIO_PMA_DEVAD,
  8239. MDIO_PMA_REG_7107_LINK_LED_CNTL,
  8240. val);
  8241. }
  8242. /******************************************************************/
  8243. /* STATIC PHY DECLARATION */
  8244. /******************************************************************/
  8245. static struct bnx2x_phy phy_null = {
  8246. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
  8247. .addr = 0,
  8248. .def_md_devad = 0,
  8249. .flags = FLAGS_INIT_XGXS_FIRST,
  8250. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8251. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8252. .mdio_ctrl = 0,
  8253. .supported = 0,
  8254. .media_type = ETH_PHY_NOT_PRESENT,
  8255. .ver_addr = 0,
  8256. .req_flow_ctrl = 0,
  8257. .req_line_speed = 0,
  8258. .speed_cap_mask = 0,
  8259. .req_duplex = 0,
  8260. .rsrv = 0,
  8261. .config_init = (config_init_t)NULL,
  8262. .read_status = (read_status_t)NULL,
  8263. .link_reset = (link_reset_t)NULL,
  8264. .config_loopback = (config_loopback_t)NULL,
  8265. .format_fw_ver = (format_fw_ver_t)NULL,
  8266. .hw_reset = (hw_reset_t)NULL,
  8267. .set_link_led = (set_link_led_t)NULL,
  8268. .phy_specific_func = (phy_specific_func_t)NULL
  8269. };
  8270. static struct bnx2x_phy phy_serdes = {
  8271. .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
  8272. .addr = 0xff,
  8273. .def_md_devad = 0,
  8274. .flags = 0,
  8275. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8276. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8277. .mdio_ctrl = 0,
  8278. .supported = (SUPPORTED_10baseT_Half |
  8279. SUPPORTED_10baseT_Full |
  8280. SUPPORTED_100baseT_Half |
  8281. SUPPORTED_100baseT_Full |
  8282. SUPPORTED_1000baseT_Full |
  8283. SUPPORTED_2500baseX_Full |
  8284. SUPPORTED_TP |
  8285. SUPPORTED_Autoneg |
  8286. SUPPORTED_Pause |
  8287. SUPPORTED_Asym_Pause),
  8288. .media_type = ETH_PHY_BASE_T,
  8289. .ver_addr = 0,
  8290. .req_flow_ctrl = 0,
  8291. .req_line_speed = 0,
  8292. .speed_cap_mask = 0,
  8293. .req_duplex = 0,
  8294. .rsrv = 0,
  8295. .config_init = (config_init_t)bnx2x_xgxs_config_init,
  8296. .read_status = (read_status_t)bnx2x_link_settings_status,
  8297. .link_reset = (link_reset_t)bnx2x_int_link_reset,
  8298. .config_loopback = (config_loopback_t)NULL,
  8299. .format_fw_ver = (format_fw_ver_t)NULL,
  8300. .hw_reset = (hw_reset_t)NULL,
  8301. .set_link_led = (set_link_led_t)NULL,
  8302. .phy_specific_func = (phy_specific_func_t)NULL
  8303. };
  8304. static struct bnx2x_phy phy_xgxs = {
  8305. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
  8306. .addr = 0xff,
  8307. .def_md_devad = 0,
  8308. .flags = 0,
  8309. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8310. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8311. .mdio_ctrl = 0,
  8312. .supported = (SUPPORTED_10baseT_Half |
  8313. SUPPORTED_10baseT_Full |
  8314. SUPPORTED_100baseT_Half |
  8315. SUPPORTED_100baseT_Full |
  8316. SUPPORTED_1000baseT_Full |
  8317. SUPPORTED_2500baseX_Full |
  8318. SUPPORTED_10000baseT_Full |
  8319. SUPPORTED_FIBRE |
  8320. SUPPORTED_Autoneg |
  8321. SUPPORTED_Pause |
  8322. SUPPORTED_Asym_Pause),
  8323. .media_type = ETH_PHY_CX4,
  8324. .ver_addr = 0,
  8325. .req_flow_ctrl = 0,
  8326. .req_line_speed = 0,
  8327. .speed_cap_mask = 0,
  8328. .req_duplex = 0,
  8329. .rsrv = 0,
  8330. .config_init = (config_init_t)bnx2x_xgxs_config_init,
  8331. .read_status = (read_status_t)bnx2x_link_settings_status,
  8332. .link_reset = (link_reset_t)bnx2x_int_link_reset,
  8333. .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
  8334. .format_fw_ver = (format_fw_ver_t)NULL,
  8335. .hw_reset = (hw_reset_t)NULL,
  8336. .set_link_led = (set_link_led_t)NULL,
  8337. .phy_specific_func = (phy_specific_func_t)NULL
  8338. };
  8339. static struct bnx2x_phy phy_warpcore = {
  8340. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
  8341. .addr = 0xff,
  8342. .def_md_devad = 0,
  8343. .flags = FLAGS_HW_LOCK_REQUIRED,
  8344. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8345. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8346. .mdio_ctrl = 0,
  8347. .supported = (SUPPORTED_10baseT_Half |
  8348. SUPPORTED_10baseT_Full |
  8349. SUPPORTED_100baseT_Half |
  8350. SUPPORTED_100baseT_Full |
  8351. SUPPORTED_1000baseT_Full |
  8352. SUPPORTED_10000baseT_Full |
  8353. SUPPORTED_20000baseKR2_Full |
  8354. SUPPORTED_20000baseMLD2_Full |
  8355. SUPPORTED_FIBRE |
  8356. SUPPORTED_Autoneg |
  8357. SUPPORTED_Pause |
  8358. SUPPORTED_Asym_Pause),
  8359. .media_type = ETH_PHY_UNSPECIFIED,
  8360. .ver_addr = 0,
  8361. .req_flow_ctrl = 0,
  8362. .req_line_speed = 0,
  8363. .speed_cap_mask = 0,
  8364. /* req_duplex = */0,
  8365. /* rsrv = */0,
  8366. .config_init = (config_init_t)bnx2x_warpcore_config_init,
  8367. .read_status = (read_status_t)bnx2x_warpcore_read_status,
  8368. .link_reset = (link_reset_t)bnx2x_warpcore_link_reset,
  8369. .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
  8370. .format_fw_ver = (format_fw_ver_t)NULL,
  8371. .hw_reset = (hw_reset_t)NULL,
  8372. .set_link_led = (set_link_led_t)NULL,
  8373. .phy_specific_func = (phy_specific_func_t)NULL
  8374. };
  8375. static struct bnx2x_phy phy_7101 = {
  8376. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
  8377. .addr = 0xff,
  8378. .def_md_devad = 0,
  8379. .flags = FLAGS_FAN_FAILURE_DET_REQ,
  8380. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8381. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8382. .mdio_ctrl = 0,
  8383. .supported = (SUPPORTED_10000baseT_Full |
  8384. SUPPORTED_TP |
  8385. SUPPORTED_Autoneg |
  8386. SUPPORTED_Pause |
  8387. SUPPORTED_Asym_Pause),
  8388. .media_type = ETH_PHY_BASE_T,
  8389. .ver_addr = 0,
  8390. .req_flow_ctrl = 0,
  8391. .req_line_speed = 0,
  8392. .speed_cap_mask = 0,
  8393. .req_duplex = 0,
  8394. .rsrv = 0,
  8395. .config_init = (config_init_t)bnx2x_7101_config_init,
  8396. .read_status = (read_status_t)bnx2x_7101_read_status,
  8397. .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
  8398. .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
  8399. .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
  8400. .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
  8401. .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led,
  8402. .phy_specific_func = (phy_specific_func_t)NULL
  8403. };
  8404. static struct bnx2x_phy phy_8073 = {
  8405. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
  8406. .addr = 0xff,
  8407. .def_md_devad = 0,
  8408. .flags = FLAGS_HW_LOCK_REQUIRED,
  8409. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8410. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8411. .mdio_ctrl = 0,
  8412. .supported = (SUPPORTED_10000baseT_Full |
  8413. SUPPORTED_2500baseX_Full |
  8414. SUPPORTED_1000baseT_Full |
  8415. SUPPORTED_FIBRE |
  8416. SUPPORTED_Autoneg |
  8417. SUPPORTED_Pause |
  8418. SUPPORTED_Asym_Pause),
  8419. .media_type = ETH_PHY_KR,
  8420. .ver_addr = 0,
  8421. .req_flow_ctrl = 0,
  8422. .req_line_speed = 0,
  8423. .speed_cap_mask = 0,
  8424. .req_duplex = 0,
  8425. .rsrv = 0,
  8426. .config_init = (config_init_t)bnx2x_8073_config_init,
  8427. .read_status = (read_status_t)bnx2x_8073_read_status,
  8428. .link_reset = (link_reset_t)bnx2x_8073_link_reset,
  8429. .config_loopback = (config_loopback_t)NULL,
  8430. .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
  8431. .hw_reset = (hw_reset_t)NULL,
  8432. .set_link_led = (set_link_led_t)NULL,
  8433. .phy_specific_func = (phy_specific_func_t)NULL
  8434. };
  8435. static struct bnx2x_phy phy_8705 = {
  8436. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
  8437. .addr = 0xff,
  8438. .def_md_devad = 0,
  8439. .flags = FLAGS_INIT_XGXS_FIRST,
  8440. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8441. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8442. .mdio_ctrl = 0,
  8443. .supported = (SUPPORTED_10000baseT_Full |
  8444. SUPPORTED_FIBRE |
  8445. SUPPORTED_Pause |
  8446. SUPPORTED_Asym_Pause),
  8447. .media_type = ETH_PHY_XFP_FIBER,
  8448. .ver_addr = 0,
  8449. .req_flow_ctrl = 0,
  8450. .req_line_speed = 0,
  8451. .speed_cap_mask = 0,
  8452. .req_duplex = 0,
  8453. .rsrv = 0,
  8454. .config_init = (config_init_t)bnx2x_8705_config_init,
  8455. .read_status = (read_status_t)bnx2x_8705_read_status,
  8456. .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
  8457. .config_loopback = (config_loopback_t)NULL,
  8458. .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
  8459. .hw_reset = (hw_reset_t)NULL,
  8460. .set_link_led = (set_link_led_t)NULL,
  8461. .phy_specific_func = (phy_specific_func_t)NULL
  8462. };
  8463. static struct bnx2x_phy phy_8706 = {
  8464. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
  8465. .addr = 0xff,
  8466. .def_md_devad = 0,
  8467. .flags = FLAGS_INIT_XGXS_FIRST,
  8468. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8469. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8470. .mdio_ctrl = 0,
  8471. .supported = (SUPPORTED_10000baseT_Full |
  8472. SUPPORTED_1000baseT_Full |
  8473. SUPPORTED_FIBRE |
  8474. SUPPORTED_Pause |
  8475. SUPPORTED_Asym_Pause),
  8476. .media_type = ETH_PHY_SFP_FIBER,
  8477. .ver_addr = 0,
  8478. .req_flow_ctrl = 0,
  8479. .req_line_speed = 0,
  8480. .speed_cap_mask = 0,
  8481. .req_duplex = 0,
  8482. .rsrv = 0,
  8483. .config_init = (config_init_t)bnx2x_8706_config_init,
  8484. .read_status = (read_status_t)bnx2x_8706_read_status,
  8485. .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
  8486. .config_loopback = (config_loopback_t)NULL,
  8487. .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
  8488. .hw_reset = (hw_reset_t)NULL,
  8489. .set_link_led = (set_link_led_t)NULL,
  8490. .phy_specific_func = (phy_specific_func_t)NULL
  8491. };
  8492. static struct bnx2x_phy phy_8726 = {
  8493. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
  8494. .addr = 0xff,
  8495. .def_md_devad = 0,
  8496. .flags = (FLAGS_HW_LOCK_REQUIRED |
  8497. FLAGS_INIT_XGXS_FIRST),
  8498. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8499. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8500. .mdio_ctrl = 0,
  8501. .supported = (SUPPORTED_10000baseT_Full |
  8502. SUPPORTED_1000baseT_Full |
  8503. SUPPORTED_Autoneg |
  8504. SUPPORTED_FIBRE |
  8505. SUPPORTED_Pause |
  8506. SUPPORTED_Asym_Pause),
  8507. .media_type = ETH_PHY_NOT_PRESENT,
  8508. .ver_addr = 0,
  8509. .req_flow_ctrl = 0,
  8510. .req_line_speed = 0,
  8511. .speed_cap_mask = 0,
  8512. .req_duplex = 0,
  8513. .rsrv = 0,
  8514. .config_init = (config_init_t)bnx2x_8726_config_init,
  8515. .read_status = (read_status_t)bnx2x_8726_read_status,
  8516. .link_reset = (link_reset_t)bnx2x_8726_link_reset,
  8517. .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
  8518. .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
  8519. .hw_reset = (hw_reset_t)NULL,
  8520. .set_link_led = (set_link_led_t)NULL,
  8521. .phy_specific_func = (phy_specific_func_t)NULL
  8522. };
  8523. static struct bnx2x_phy phy_8727 = {
  8524. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
  8525. .addr = 0xff,
  8526. .def_md_devad = 0,
  8527. .flags = FLAGS_FAN_FAILURE_DET_REQ,
  8528. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8529. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8530. .mdio_ctrl = 0,
  8531. .supported = (SUPPORTED_10000baseT_Full |
  8532. SUPPORTED_1000baseT_Full |
  8533. SUPPORTED_FIBRE |
  8534. SUPPORTED_Pause |
  8535. SUPPORTED_Asym_Pause),
  8536. .media_type = ETH_PHY_NOT_PRESENT,
  8537. .ver_addr = 0,
  8538. .req_flow_ctrl = 0,
  8539. .req_line_speed = 0,
  8540. .speed_cap_mask = 0,
  8541. .req_duplex = 0,
  8542. .rsrv = 0,
  8543. .config_init = (config_init_t)bnx2x_8727_config_init,
  8544. .read_status = (read_status_t)bnx2x_8727_read_status,
  8545. .link_reset = (link_reset_t)bnx2x_8727_link_reset,
  8546. .config_loopback = (config_loopback_t)NULL,
  8547. .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
  8548. .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
  8549. .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led,
  8550. .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
  8551. };
  8552. static struct bnx2x_phy phy_8481 = {
  8553. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
  8554. .addr = 0xff,
  8555. .def_md_devad = 0,
  8556. .flags = FLAGS_FAN_FAILURE_DET_REQ |
  8557. FLAGS_REARM_LATCH_SIGNAL,
  8558. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8559. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8560. .mdio_ctrl = 0,
  8561. .supported = (SUPPORTED_10baseT_Half |
  8562. SUPPORTED_10baseT_Full |
  8563. SUPPORTED_100baseT_Half |
  8564. SUPPORTED_100baseT_Full |
  8565. SUPPORTED_1000baseT_Full |
  8566. SUPPORTED_10000baseT_Full |
  8567. SUPPORTED_TP |
  8568. SUPPORTED_Autoneg |
  8569. SUPPORTED_Pause |
  8570. SUPPORTED_Asym_Pause),
  8571. .media_type = ETH_PHY_BASE_T,
  8572. .ver_addr = 0,
  8573. .req_flow_ctrl = 0,
  8574. .req_line_speed = 0,
  8575. .speed_cap_mask = 0,
  8576. .req_duplex = 0,
  8577. .rsrv = 0,
  8578. .config_init = (config_init_t)bnx2x_8481_config_init,
  8579. .read_status = (read_status_t)bnx2x_848xx_read_status,
  8580. .link_reset = (link_reset_t)bnx2x_8481_link_reset,
  8581. .config_loopback = (config_loopback_t)NULL,
  8582. .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
  8583. .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
  8584. .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
  8585. .phy_specific_func = (phy_specific_func_t)NULL
  8586. };
  8587. static struct bnx2x_phy phy_84823 = {
  8588. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
  8589. .addr = 0xff,
  8590. .def_md_devad = 0,
  8591. .flags = FLAGS_FAN_FAILURE_DET_REQ |
  8592. FLAGS_REARM_LATCH_SIGNAL,
  8593. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8594. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8595. .mdio_ctrl = 0,
  8596. .supported = (SUPPORTED_10baseT_Half |
  8597. SUPPORTED_10baseT_Full |
  8598. SUPPORTED_100baseT_Half |
  8599. SUPPORTED_100baseT_Full |
  8600. SUPPORTED_1000baseT_Full |
  8601. SUPPORTED_10000baseT_Full |
  8602. SUPPORTED_TP |
  8603. SUPPORTED_Autoneg |
  8604. SUPPORTED_Pause |
  8605. SUPPORTED_Asym_Pause),
  8606. .media_type = ETH_PHY_BASE_T,
  8607. .ver_addr = 0,
  8608. .req_flow_ctrl = 0,
  8609. .req_line_speed = 0,
  8610. .speed_cap_mask = 0,
  8611. .req_duplex = 0,
  8612. .rsrv = 0,
  8613. .config_init = (config_init_t)bnx2x_848x3_config_init,
  8614. .read_status = (read_status_t)bnx2x_848xx_read_status,
  8615. .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
  8616. .config_loopback = (config_loopback_t)NULL,
  8617. .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
  8618. .hw_reset = (hw_reset_t)NULL,
  8619. .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
  8620. .phy_specific_func = (phy_specific_func_t)NULL
  8621. };
  8622. static struct bnx2x_phy phy_84833 = {
  8623. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
  8624. .addr = 0xff,
  8625. .def_md_devad = 0,
  8626. .flags = FLAGS_FAN_FAILURE_DET_REQ |
  8627. FLAGS_REARM_LATCH_SIGNAL,
  8628. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8629. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8630. .mdio_ctrl = 0,
  8631. .supported = (SUPPORTED_10baseT_Half |
  8632. SUPPORTED_10baseT_Full |
  8633. SUPPORTED_100baseT_Half |
  8634. SUPPORTED_100baseT_Full |
  8635. SUPPORTED_1000baseT_Full |
  8636. SUPPORTED_10000baseT_Full |
  8637. SUPPORTED_TP |
  8638. SUPPORTED_Autoneg |
  8639. SUPPORTED_Pause |
  8640. SUPPORTED_Asym_Pause),
  8641. .media_type = ETH_PHY_BASE_T,
  8642. .ver_addr = 0,
  8643. .req_flow_ctrl = 0,
  8644. .req_line_speed = 0,
  8645. .speed_cap_mask = 0,
  8646. .req_duplex = 0,
  8647. .rsrv = 0,
  8648. .config_init = (config_init_t)bnx2x_848x3_config_init,
  8649. .read_status = (read_status_t)bnx2x_848xx_read_status,
  8650. .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
  8651. .config_loopback = (config_loopback_t)NULL,
  8652. .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
  8653. .hw_reset = (hw_reset_t)NULL,
  8654. .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
  8655. .phy_specific_func = (phy_specific_func_t)NULL
  8656. };
  8657. static struct bnx2x_phy phy_54616s = {
  8658. .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616,
  8659. .addr = 0xff,
  8660. .def_md_devad = 0,
  8661. .flags = FLAGS_INIT_XGXS_FIRST,
  8662. .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8663. .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
  8664. .mdio_ctrl = 0,
  8665. .supported = (SUPPORTED_10baseT_Half |
  8666. SUPPORTED_10baseT_Full |
  8667. SUPPORTED_100baseT_Half |
  8668. SUPPORTED_100baseT_Full |
  8669. SUPPORTED_1000baseT_Full |
  8670. SUPPORTED_TP |
  8671. SUPPORTED_Autoneg |
  8672. SUPPORTED_Pause |
  8673. SUPPORTED_Asym_Pause),
  8674. .media_type = ETH_PHY_BASE_T,
  8675. .ver_addr = 0,
  8676. .req_flow_ctrl = 0,
  8677. .req_line_speed = 0,
  8678. .speed_cap_mask = 0,
  8679. /* req_duplex = */0,
  8680. /* rsrv = */0,
  8681. .config_init = (config_init_t)bnx2x_54616s_config_init,
  8682. .read_status = (read_status_t)bnx2x_54616s_read_status,
  8683. .link_reset = (link_reset_t)bnx2x_54616s_link_reset,
  8684. .config_loopback = (config_loopback_t)bnx2x_54616s_config_loopback,
  8685. .format_fw_ver = (format_fw_ver_t)NULL,
  8686. .hw_reset = (hw_reset_t)NULL,
  8687. .set_link_led = (set_link_led_t)bnx2x_54616s_set_link_led,
  8688. .phy_specific_func = (phy_specific_func_t)NULL
  8689. };
  8690. /*****************************************************************/
  8691. /* */
  8692. /* Populate the phy according. Main function: bnx2x_populate_phy */
  8693. /* */
  8694. /*****************************************************************/
  8695. static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
  8696. struct bnx2x_phy *phy, u8 port,
  8697. u8 phy_index)
  8698. {
  8699. /* Get the 4 lanes xgxs config rx and tx */
  8700. u32 rx = 0, tx = 0, i;
  8701. for (i = 0; i < 2; i++) {
  8702. /*
  8703. * INT_PHY and EXT_PHY1 share the same value location in the
  8704. * shmem. When num_phys is greater than 1, than this value
  8705. * applies only to EXT_PHY1
  8706. */
  8707. if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
  8708. rx = REG_RD(bp, shmem_base +
  8709. offsetof(struct shmem_region,
  8710. dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
  8711. tx = REG_RD(bp, shmem_base +
  8712. offsetof(struct shmem_region,
  8713. dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
  8714. } else {
  8715. rx = REG_RD(bp, shmem_base +
  8716. offsetof(struct shmem_region,
  8717. dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
  8718. tx = REG_RD(bp, shmem_base +
  8719. offsetof(struct shmem_region,
  8720. dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
  8721. }
  8722. phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
  8723. phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
  8724. phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
  8725. phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
  8726. }
  8727. }
  8728. static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
  8729. u8 phy_index, u8 port)
  8730. {
  8731. u32 ext_phy_config = 0;
  8732. switch (phy_index) {
  8733. case EXT_PHY1:
  8734. ext_phy_config = REG_RD(bp, shmem_base +
  8735. offsetof(struct shmem_region,
  8736. dev_info.port_hw_config[port].external_phy_config));
  8737. break;
  8738. case EXT_PHY2:
  8739. ext_phy_config = REG_RD(bp, shmem_base +
  8740. offsetof(struct shmem_region,
  8741. dev_info.port_hw_config[port].external_phy_config2));
  8742. break;
  8743. default:
  8744. DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
  8745. return -EINVAL;
  8746. }
  8747. return ext_phy_config;
  8748. }
  8749. static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
  8750. struct bnx2x_phy *phy)
  8751. {
  8752. u32 phy_addr;
  8753. u32 chip_id;
  8754. u32 switch_cfg = (REG_RD(bp, shmem_base +
  8755. offsetof(struct shmem_region,
  8756. dev_info.port_feature_config[port].link_config)) &
  8757. PORT_FEATURE_CONNECTED_SWITCH_MASK);
  8758. chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
  8759. DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
  8760. if (USES_WARPCORE(bp)) {
  8761. u32 serdes_net_if;
  8762. phy_addr = REG_RD(bp,
  8763. MISC_REG_WC0_CTRL_PHY_ADDR);
  8764. *phy = phy_warpcore;
  8765. if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
  8766. phy->flags |= FLAGS_4_PORT_MODE;
  8767. else
  8768. phy->flags &= ~FLAGS_4_PORT_MODE;
  8769. /* Check Dual mode */
  8770. serdes_net_if = (REG_RD(bp, shmem_base +
  8771. offsetof(struct shmem_region, dev_info.
  8772. port_hw_config[port].default_cfg)) &
  8773. PORT_HW_CFG_NET_SERDES_IF_MASK);
  8774. /*
  8775. * Set the appropriate supported and flags indications per
  8776. * interface type of the chip
  8777. */
  8778. switch (serdes_net_if) {
  8779. case PORT_HW_CFG_NET_SERDES_IF_SGMII:
  8780. phy->supported &= (SUPPORTED_10baseT_Half |
  8781. SUPPORTED_10baseT_Full |
  8782. SUPPORTED_100baseT_Half |
  8783. SUPPORTED_100baseT_Full |
  8784. SUPPORTED_1000baseT_Full |
  8785. SUPPORTED_FIBRE |
  8786. SUPPORTED_Autoneg |
  8787. SUPPORTED_Pause |
  8788. SUPPORTED_Asym_Pause);
  8789. phy->media_type = ETH_PHY_BASE_T;
  8790. break;
  8791. case PORT_HW_CFG_NET_SERDES_IF_XFI:
  8792. phy->media_type = ETH_PHY_XFP_FIBER;
  8793. break;
  8794. case PORT_HW_CFG_NET_SERDES_IF_SFI:
  8795. phy->supported &= (SUPPORTED_1000baseT_Full |
  8796. SUPPORTED_10000baseT_Full |
  8797. SUPPORTED_FIBRE |
  8798. SUPPORTED_Pause |
  8799. SUPPORTED_Asym_Pause);
  8800. phy->media_type = ETH_PHY_SFP_FIBER;
  8801. break;
  8802. case PORT_HW_CFG_NET_SERDES_IF_KR:
  8803. phy->media_type = ETH_PHY_KR;
  8804. phy->supported &= (SUPPORTED_1000baseT_Full |
  8805. SUPPORTED_10000baseT_Full |
  8806. SUPPORTED_FIBRE |
  8807. SUPPORTED_Autoneg |
  8808. SUPPORTED_Pause |
  8809. SUPPORTED_Asym_Pause);
  8810. break;
  8811. case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
  8812. phy->media_type = ETH_PHY_KR;
  8813. phy->flags |= FLAGS_WC_DUAL_MODE;
  8814. phy->supported &= (SUPPORTED_20000baseMLD2_Full |
  8815. SUPPORTED_FIBRE |
  8816. SUPPORTED_Pause |
  8817. SUPPORTED_Asym_Pause);
  8818. break;
  8819. case PORT_HW_CFG_NET_SERDES_IF_KR2:
  8820. phy->media_type = ETH_PHY_KR;
  8821. phy->flags |= FLAGS_WC_DUAL_MODE;
  8822. phy->supported &= (SUPPORTED_20000baseKR2_Full |
  8823. SUPPORTED_FIBRE |
  8824. SUPPORTED_Pause |
  8825. SUPPORTED_Asym_Pause);
  8826. break;
  8827. default:
  8828. DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
  8829. serdes_net_if);
  8830. break;
  8831. }
  8832. /*
  8833. * Enable MDC/MDIO work-around for E3 A0 since free running MDC
  8834. * was not set as expected. For B0, ECO will be enabled so there
  8835. * won't be an issue there
  8836. */
  8837. if (CHIP_REV(bp) == CHIP_REV_Ax)
  8838. phy->flags |= FLAGS_MDC_MDIO_WA;
  8839. } else {
  8840. switch (switch_cfg) {
  8841. case SWITCH_CFG_1G:
  8842. phy_addr = REG_RD(bp,
  8843. NIG_REG_SERDES0_CTRL_PHY_ADDR +
  8844. port * 0x10);
  8845. *phy = phy_serdes;
  8846. break;
  8847. case SWITCH_CFG_10G:
  8848. phy_addr = REG_RD(bp,
  8849. NIG_REG_XGXS0_CTRL_PHY_ADDR +
  8850. port * 0x18);
  8851. *phy = phy_xgxs;
  8852. break;
  8853. default:
  8854. DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
  8855. return -EINVAL;
  8856. }
  8857. }
  8858. phy->addr = (u8)phy_addr;
  8859. phy->mdio_ctrl = bnx2x_get_emac_base(bp,
  8860. SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
  8861. port);
  8862. if (CHIP_IS_E2(bp))
  8863. phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
  8864. else
  8865. phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
  8866. DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
  8867. port, phy->addr, phy->mdio_ctrl);
  8868. bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
  8869. return 0;
  8870. }
  8871. static int bnx2x_populate_ext_phy(struct bnx2x *bp,
  8872. u8 phy_index,
  8873. u32 shmem_base,
  8874. u32 shmem2_base,
  8875. u8 port,
  8876. struct bnx2x_phy *phy)
  8877. {
  8878. u32 ext_phy_config, phy_type, config2;
  8879. u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
  8880. ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
  8881. phy_index, port);
  8882. phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
  8883. /* Select the phy type */
  8884. switch (phy_type) {
  8885. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  8886. mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
  8887. *phy = phy_8073;
  8888. break;
  8889. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
  8890. *phy = phy_8705;
  8891. break;
  8892. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
  8893. *phy = phy_8706;
  8894. break;
  8895. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  8896. mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
  8897. *phy = phy_8726;
  8898. break;
  8899. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
  8900. /* BCM8727_NOC => BCM8727 no over current */
  8901. mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
  8902. *phy = phy_8727;
  8903. phy->flags |= FLAGS_NOC;
  8904. break;
  8905. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
  8906. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
  8907. mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
  8908. *phy = phy_8727;
  8909. break;
  8910. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
  8911. *phy = phy_8481;
  8912. break;
  8913. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
  8914. *phy = phy_84823;
  8915. break;
  8916. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
  8917. *phy = phy_84833;
  8918. break;
  8919. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
  8920. *phy = phy_54616s;
  8921. break;
  8922. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
  8923. *phy = phy_7101;
  8924. break;
  8925. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
  8926. *phy = phy_null;
  8927. return -EINVAL;
  8928. default:
  8929. *phy = phy_null;
  8930. return 0;
  8931. }
  8932. phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
  8933. bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
  8934. /*
  8935. * The shmem address of the phy version is located on different
  8936. * structures. In case this structure is too old, do not set
  8937. * the address
  8938. */
  8939. config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
  8940. dev_info.shared_hw_config.config2));
  8941. if (phy_index == EXT_PHY1) {
  8942. phy->ver_addr = shmem_base + offsetof(struct shmem_region,
  8943. port_mb[port].ext_phy_fw_version);
  8944. /* Check specific mdc mdio settings */
  8945. if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
  8946. mdc_mdio_access = config2 &
  8947. SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
  8948. } else {
  8949. u32 size = REG_RD(bp, shmem2_base);
  8950. if (size >
  8951. offsetof(struct shmem2_region, ext_phy_fw_version2)) {
  8952. phy->ver_addr = shmem2_base +
  8953. offsetof(struct shmem2_region,
  8954. ext_phy_fw_version2[port]);
  8955. }
  8956. /* Check specific mdc mdio settings */
  8957. if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
  8958. mdc_mdio_access = (config2 &
  8959. SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
  8960. (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
  8961. SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
  8962. }
  8963. phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
  8964. /*
  8965. * In case mdc/mdio_access of the external phy is different than the
  8966. * mdc/mdio access of the XGXS, a HW lock must be taken in each access
  8967. * to prevent one port interfere with another port's CL45 operations.
  8968. */
  8969. if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
  8970. phy->flags |= FLAGS_HW_LOCK_REQUIRED;
  8971. DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
  8972. phy_type, port, phy_index);
  8973. DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n",
  8974. phy->addr, phy->mdio_ctrl);
  8975. return 0;
  8976. }
  8977. static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
  8978. u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
  8979. {
  8980. int status = 0;
  8981. phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
  8982. if (phy_index == INT_PHY)
  8983. return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
  8984. status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
  8985. port, phy);
  8986. return status;
  8987. }
  8988. static void bnx2x_phy_def_cfg(struct link_params *params,
  8989. struct bnx2x_phy *phy,
  8990. u8 phy_index)
  8991. {
  8992. struct bnx2x *bp = params->bp;
  8993. u32 link_config;
  8994. /* Populate the default phy configuration for MF mode */
  8995. if (phy_index == EXT_PHY2) {
  8996. link_config = REG_RD(bp, params->shmem_base +
  8997. offsetof(struct shmem_region, dev_info.
  8998. port_feature_config[params->port].link_config2));
  8999. phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
  9000. offsetof(struct shmem_region,
  9001. dev_info.
  9002. port_hw_config[params->port].speed_capability_mask2));
  9003. } else {
  9004. link_config = REG_RD(bp, params->shmem_base +
  9005. offsetof(struct shmem_region, dev_info.
  9006. port_feature_config[params->port].link_config));
  9007. phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
  9008. offsetof(struct shmem_region,
  9009. dev_info.
  9010. port_hw_config[params->port].speed_capability_mask));
  9011. }
  9012. DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
  9013. " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
  9014. phy->req_duplex = DUPLEX_FULL;
  9015. switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
  9016. case PORT_FEATURE_LINK_SPEED_10M_HALF:
  9017. phy->req_duplex = DUPLEX_HALF;
  9018. case PORT_FEATURE_LINK_SPEED_10M_FULL:
  9019. phy->req_line_speed = SPEED_10;
  9020. break;
  9021. case PORT_FEATURE_LINK_SPEED_100M_HALF:
  9022. phy->req_duplex = DUPLEX_HALF;
  9023. case PORT_FEATURE_LINK_SPEED_100M_FULL:
  9024. phy->req_line_speed = SPEED_100;
  9025. break;
  9026. case PORT_FEATURE_LINK_SPEED_1G:
  9027. phy->req_line_speed = SPEED_1000;
  9028. break;
  9029. case PORT_FEATURE_LINK_SPEED_2_5G:
  9030. phy->req_line_speed = SPEED_2500;
  9031. break;
  9032. case PORT_FEATURE_LINK_SPEED_10G_CX4:
  9033. phy->req_line_speed = SPEED_10000;
  9034. break;
  9035. default:
  9036. phy->req_line_speed = SPEED_AUTO_NEG;
  9037. break;
  9038. }
  9039. switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
  9040. case PORT_FEATURE_FLOW_CONTROL_AUTO:
  9041. phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
  9042. break;
  9043. case PORT_FEATURE_FLOW_CONTROL_TX:
  9044. phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
  9045. break;
  9046. case PORT_FEATURE_FLOW_CONTROL_RX:
  9047. phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
  9048. break;
  9049. case PORT_FEATURE_FLOW_CONTROL_BOTH:
  9050. phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
  9051. break;
  9052. default:
  9053. phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  9054. break;
  9055. }
  9056. }
  9057. u32 bnx2x_phy_selection(struct link_params *params)
  9058. {
  9059. u32 phy_config_swapped, prio_cfg;
  9060. u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
  9061. phy_config_swapped = params->multi_phy_config &
  9062. PORT_HW_CFG_PHY_SWAPPED_ENABLED;
  9063. prio_cfg = params->multi_phy_config &
  9064. PORT_HW_CFG_PHY_SELECTION_MASK;
  9065. if (phy_config_swapped) {
  9066. switch (prio_cfg) {
  9067. case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
  9068. return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
  9069. break;
  9070. case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
  9071. return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
  9072. break;
  9073. case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
  9074. return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
  9075. break;
  9076. case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
  9077. return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
  9078. break;
  9079. }
  9080. } else
  9081. return_cfg = prio_cfg;
  9082. return return_cfg;
  9083. }
  9084. int bnx2x_phy_probe(struct link_params *params)
  9085. {
  9086. u8 phy_index, actual_phy_idx, link_cfg_idx;
  9087. u32 phy_config_swapped, sync_offset, media_types;
  9088. struct bnx2x *bp = params->bp;
  9089. struct bnx2x_phy *phy;
  9090. params->num_phys = 0;
  9091. DP(NETIF_MSG_LINK, "Begin phy probe\n");
  9092. phy_config_swapped = params->multi_phy_config &
  9093. PORT_HW_CFG_PHY_SWAPPED_ENABLED;
  9094. for (phy_index = INT_PHY; phy_index < MAX_PHYS;
  9095. phy_index++) {
  9096. link_cfg_idx = LINK_CONFIG_IDX(phy_index);
  9097. actual_phy_idx = phy_index;
  9098. if (phy_config_swapped) {
  9099. if (phy_index == EXT_PHY1)
  9100. actual_phy_idx = EXT_PHY2;
  9101. else if (phy_index == EXT_PHY2)
  9102. actual_phy_idx = EXT_PHY1;
  9103. }
  9104. DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
  9105. " actual_phy_idx %x\n", phy_config_swapped,
  9106. phy_index, actual_phy_idx);
  9107. phy = &params->phy[actual_phy_idx];
  9108. if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
  9109. params->shmem2_base, params->port,
  9110. phy) != 0) {
  9111. params->num_phys = 0;
  9112. DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
  9113. phy_index);
  9114. for (phy_index = INT_PHY;
  9115. phy_index < MAX_PHYS;
  9116. phy_index++)
  9117. *phy = phy_null;
  9118. return -EINVAL;
  9119. }
  9120. if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
  9121. break;
  9122. sync_offset = params->shmem_base +
  9123. offsetof(struct shmem_region,
  9124. dev_info.port_hw_config[params->port].media_type);
  9125. media_types = REG_RD(bp, sync_offset);
  9126. /*
  9127. * Update media type for non-PMF sync only for the first time
  9128. * In case the media type changes afterwards, it will be updated
  9129. * using the update_status function
  9130. */
  9131. if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
  9132. (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
  9133. actual_phy_idx))) == 0) {
  9134. media_types |= ((phy->media_type &
  9135. PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
  9136. (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
  9137. actual_phy_idx));
  9138. }
  9139. REG_WR(bp, sync_offset, media_types);
  9140. bnx2x_phy_def_cfg(params, phy, phy_index);
  9141. params->num_phys++;
  9142. }
  9143. DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
  9144. return 0;
  9145. }
  9146. void bnx2x_init_bmac_loopback(struct link_params *params,
  9147. struct link_vars *vars)
  9148. {
  9149. struct bnx2x *bp = params->bp;
  9150. vars->link_up = 1;
  9151. vars->line_speed = SPEED_10000;
  9152. vars->duplex = DUPLEX_FULL;
  9153. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  9154. vars->mac_type = MAC_TYPE_BMAC;
  9155. vars->phy_flags = PHY_XGXS_FLAG;
  9156. bnx2x_xgxs_deassert(params);
  9157. /* set bmac loopback */
  9158. bnx2x_bmac_enable(params, vars, 1);
  9159. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
  9160. }
  9161. void bnx2x_init_emac_loopback(struct link_params *params,
  9162. struct link_vars *vars)
  9163. {
  9164. struct bnx2x *bp = params->bp;
  9165. vars->link_up = 1;
  9166. vars->line_speed = SPEED_1000;
  9167. vars->duplex = DUPLEX_FULL;
  9168. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  9169. vars->mac_type = MAC_TYPE_EMAC;
  9170. vars->phy_flags = PHY_XGXS_FLAG;
  9171. bnx2x_xgxs_deassert(params);
  9172. /* set bmac loopback */
  9173. bnx2x_emac_enable(params, vars, 1);
  9174. bnx2x_emac_program(params, vars);
  9175. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
  9176. }
  9177. void bnx2x_init_xmac_loopback(struct link_params *params,
  9178. struct link_vars *vars)
  9179. {
  9180. struct bnx2x *bp = params->bp;
  9181. vars->link_up = 1;
  9182. if (!params->req_line_speed[0])
  9183. vars->line_speed = SPEED_10000;
  9184. else
  9185. vars->line_speed = params->req_line_speed[0];
  9186. vars->duplex = DUPLEX_FULL;
  9187. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  9188. vars->mac_type = MAC_TYPE_XMAC;
  9189. vars->phy_flags = PHY_XGXS_FLAG;
  9190. /*
  9191. * Set WC to loopback mode since link is required to provide clock
  9192. * to the XMAC in 20G mode
  9193. */
  9194. if (vars->line_speed == SPEED_20000) {
  9195. bnx2x_set_aer_mmd(params, &params->phy[0]);
  9196. bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0);
  9197. params->phy[INT_PHY].config_loopback(
  9198. &params->phy[INT_PHY],
  9199. params);
  9200. }
  9201. bnx2x_xmac_enable(params, vars, 1);
  9202. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
  9203. }
  9204. void bnx2x_init_umac_loopback(struct link_params *params,
  9205. struct link_vars *vars)
  9206. {
  9207. struct bnx2x *bp = params->bp;
  9208. vars->link_up = 1;
  9209. vars->line_speed = SPEED_1000;
  9210. vars->duplex = DUPLEX_FULL;
  9211. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  9212. vars->mac_type = MAC_TYPE_UMAC;
  9213. vars->phy_flags = PHY_XGXS_FLAG;
  9214. bnx2x_umac_enable(params, vars, 1);
  9215. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
  9216. }
  9217. void bnx2x_init_xgxs_loopback(struct link_params *params,
  9218. struct link_vars *vars)
  9219. {
  9220. struct bnx2x *bp = params->bp;
  9221. vars->link_up = 1;
  9222. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  9223. vars->duplex = DUPLEX_FULL;
  9224. if (params->req_line_speed[0] == SPEED_1000)
  9225. vars->line_speed = SPEED_1000;
  9226. else
  9227. vars->line_speed = SPEED_10000;
  9228. if (!USES_WARPCORE(bp))
  9229. bnx2x_xgxs_deassert(params);
  9230. bnx2x_link_initialize(params, vars);
  9231. if (params->req_line_speed[0] == SPEED_1000) {
  9232. if (USES_WARPCORE(bp))
  9233. bnx2x_umac_enable(params, vars, 0);
  9234. else {
  9235. bnx2x_emac_program(params, vars);
  9236. bnx2x_emac_enable(params, vars, 0);
  9237. }
  9238. } else {
  9239. if (USES_WARPCORE(bp))
  9240. bnx2x_xmac_enable(params, vars, 0);
  9241. else
  9242. bnx2x_bmac_enable(params, vars, 0);
  9243. }
  9244. if (params->loopback_mode == LOOPBACK_XGXS) {
  9245. /* set 10G XGXS loopback */
  9246. params->phy[INT_PHY].config_loopback(
  9247. &params->phy[INT_PHY],
  9248. params);
  9249. } else {
  9250. /* set external phy loopback */
  9251. u8 phy_index;
  9252. for (phy_index = EXT_PHY1;
  9253. phy_index < params->num_phys; phy_index++) {
  9254. if (params->phy[phy_index].config_loopback)
  9255. params->phy[phy_index].config_loopback(
  9256. &params->phy[phy_index],
  9257. params);
  9258. }
  9259. }
  9260. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
  9261. bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
  9262. }
  9263. int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
  9264. {
  9265. struct bnx2x *bp = params->bp;
  9266. DP(NETIF_MSG_LINK, "Phy Initialization started\n");
  9267. DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
  9268. params->req_line_speed[0], params->req_flow_ctrl[0]);
  9269. DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
  9270. params->req_line_speed[1], params->req_flow_ctrl[1]);
  9271. vars->link_status = 0;
  9272. vars->phy_link_up = 0;
  9273. vars->link_up = 0;
  9274. vars->line_speed = 0;
  9275. vars->duplex = DUPLEX_FULL;
  9276. vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
  9277. vars->mac_type = MAC_TYPE_NONE;
  9278. vars->phy_flags = 0;
  9279. /* disable attentions */
  9280. bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
  9281. (NIG_MASK_XGXS0_LINK_STATUS |
  9282. NIG_MASK_XGXS0_LINK10G |
  9283. NIG_MASK_SERDES0_LINK_STATUS |
  9284. NIG_MASK_MI_INT));
  9285. bnx2x_emac_init(params, vars);
  9286. if (params->num_phys == 0) {
  9287. DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
  9288. return -EINVAL;
  9289. }
  9290. set_phy_vars(params, vars);
  9291. DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
  9292. switch (params->loopback_mode) {
  9293. case LOOPBACK_BMAC:
  9294. bnx2x_init_bmac_loopback(params, vars);
  9295. break;
  9296. case LOOPBACK_EMAC:
  9297. bnx2x_init_emac_loopback(params, vars);
  9298. break;
  9299. case LOOPBACK_XMAC:
  9300. bnx2x_init_xmac_loopback(params, vars);
  9301. break;
  9302. case LOOPBACK_UMAC:
  9303. bnx2x_init_umac_loopback(params, vars);
  9304. break;
  9305. case LOOPBACK_XGXS:
  9306. case LOOPBACK_EXT_PHY:
  9307. bnx2x_init_xgxs_loopback(params, vars);
  9308. break;
  9309. default:
  9310. if (!CHIP_IS_E3(bp)) {
  9311. if (params->switch_cfg == SWITCH_CFG_10G)
  9312. bnx2x_xgxs_deassert(params);
  9313. else
  9314. bnx2x_serdes_deassert(bp, params->port);
  9315. }
  9316. bnx2x_link_initialize(params, vars);
  9317. msleep(30);
  9318. bnx2x_link_int_enable(params);
  9319. break;
  9320. }
  9321. return 0;
  9322. }
  9323. int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
  9324. u8 reset_ext_phy)
  9325. {
  9326. struct bnx2x *bp = params->bp;
  9327. u8 phy_index, port = params->port, clear_latch_ind = 0;
  9328. DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
  9329. /* disable attentions */
  9330. vars->link_status = 0;
  9331. bnx2x_update_mng(params, vars->link_status);
  9332. bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
  9333. (NIG_MASK_XGXS0_LINK_STATUS |
  9334. NIG_MASK_XGXS0_LINK10G |
  9335. NIG_MASK_SERDES0_LINK_STATUS |
  9336. NIG_MASK_MI_INT));
  9337. /* activate nig drain */
  9338. REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
  9339. /* disable nig egress interface */
  9340. if (!CHIP_IS_E3(bp)) {
  9341. REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
  9342. REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
  9343. }
  9344. /* Stop BigMac rx */
  9345. if (!CHIP_IS_E3(bp))
  9346. bnx2x_bmac_rx_disable(bp, port);
  9347. else
  9348. bnx2x_xmac_disable(params);
  9349. /* disable emac */
  9350. if (!CHIP_IS_E3(bp))
  9351. REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
  9352. msleep(10);
  9353. /* The PHY reset is controlled by GPIO 1
  9354. * Hold it as vars low
  9355. */
  9356. /* clear link led */
  9357. bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
  9358. if (reset_ext_phy) {
  9359. for (phy_index = EXT_PHY1; phy_index < params->num_phys;
  9360. phy_index++) {
  9361. if (params->phy[phy_index].link_reset)
  9362. params->phy[phy_index].link_reset(
  9363. &params->phy[phy_index],
  9364. params);
  9365. if (params->phy[phy_index].flags &
  9366. FLAGS_REARM_LATCH_SIGNAL)
  9367. clear_latch_ind = 1;
  9368. }
  9369. }
  9370. if (clear_latch_ind) {
  9371. /* Clear latching indication */
  9372. bnx2x_rearm_latch_signal(bp, port, 0);
  9373. bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
  9374. 1 << NIG_LATCH_BC_ENABLE_MI_INT);
  9375. }
  9376. if (params->phy[INT_PHY].link_reset)
  9377. params->phy[INT_PHY].link_reset(
  9378. &params->phy[INT_PHY], params);
  9379. /* reset BigMac */
  9380. REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
  9381. (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
  9382. /* disable nig ingress interface */
  9383. if (!CHIP_IS_E3(bp)) {
  9384. REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
  9385. REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
  9386. }
  9387. vars->link_up = 0;
  9388. vars->phy_flags = 0;
  9389. return 0;
  9390. }
  9391. /****************************************************************************/
  9392. /* Common function */
  9393. /****************************************************************************/
  9394. static int bnx2x_8073_common_init_phy(struct bnx2x *bp,
  9395. u32 shmem_base_path[],
  9396. u32 shmem2_base_path[], u8 phy_index,
  9397. u32 chip_id)
  9398. {
  9399. struct bnx2x_phy phy[PORT_MAX];
  9400. struct bnx2x_phy *phy_blk[PORT_MAX];
  9401. u16 val;
  9402. s8 port = 0;
  9403. s8 port_of_path = 0;
  9404. u32 swap_val, swap_override;
  9405. swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
  9406. swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
  9407. port ^= (swap_val && swap_override);
  9408. bnx2x_ext_phy_hw_reset(bp, port);
  9409. /* PART1 - Reset both phys */
  9410. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  9411. u32 shmem_base, shmem2_base;
  9412. /* In E2, same phy is using for port0 of the two paths */
  9413. if (CHIP_IS_E1x(bp)) {
  9414. shmem_base = shmem_base_path[0];
  9415. shmem2_base = shmem2_base_path[0];
  9416. port_of_path = port;
  9417. } else {
  9418. shmem_base = shmem_base_path[port];
  9419. shmem2_base = shmem2_base_path[port];
  9420. port_of_path = 0;
  9421. }
  9422. /* Extract the ext phy address for the port */
  9423. if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
  9424. port_of_path, &phy[port]) !=
  9425. 0) {
  9426. DP(NETIF_MSG_LINK, "populate_phy failed\n");
  9427. return -EINVAL;
  9428. }
  9429. /* disable attentions */
  9430. bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
  9431. port_of_path*4,
  9432. (NIG_MASK_XGXS0_LINK_STATUS |
  9433. NIG_MASK_XGXS0_LINK10G |
  9434. NIG_MASK_SERDES0_LINK_STATUS |
  9435. NIG_MASK_MI_INT));
  9436. /* Need to take the phy out of low power mode in order
  9437. to write to access its registers */
  9438. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  9439. MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  9440. port);
  9441. /* Reset the phy */
  9442. bnx2x_cl45_write(bp, &phy[port],
  9443. MDIO_PMA_DEVAD,
  9444. MDIO_PMA_REG_CTRL,
  9445. 1<<15);
  9446. }
  9447. /* Add delay of 150ms after reset */
  9448. msleep(150);
  9449. if (phy[PORT_0].addr & 0x1) {
  9450. phy_blk[PORT_0] = &(phy[PORT_1]);
  9451. phy_blk[PORT_1] = &(phy[PORT_0]);
  9452. } else {
  9453. phy_blk[PORT_0] = &(phy[PORT_0]);
  9454. phy_blk[PORT_1] = &(phy[PORT_1]);
  9455. }
  9456. /* PART2 - Download firmware to both phys */
  9457. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  9458. if (CHIP_IS_E1x(bp))
  9459. port_of_path = port;
  9460. else
  9461. port_of_path = 0;
  9462. DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
  9463. phy_blk[port]->addr);
  9464. if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
  9465. port_of_path))
  9466. return -EINVAL;
  9467. /* Only set bit 10 = 1 (Tx power down) */
  9468. bnx2x_cl45_read(bp, phy_blk[port],
  9469. MDIO_PMA_DEVAD,
  9470. MDIO_PMA_REG_TX_POWER_DOWN, &val);
  9471. /* Phase1 of TX_POWER_DOWN reset */
  9472. bnx2x_cl45_write(bp, phy_blk[port],
  9473. MDIO_PMA_DEVAD,
  9474. MDIO_PMA_REG_TX_POWER_DOWN,
  9475. (val | 1<<10));
  9476. }
  9477. /*
  9478. * Toggle Transmitter: Power down and then up with 600ms delay
  9479. * between
  9480. */
  9481. msleep(600);
  9482. /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
  9483. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  9484. /* Phase2 of POWER_DOWN_RESET */
  9485. /* Release bit 10 (Release Tx power down) */
  9486. bnx2x_cl45_read(bp, phy_blk[port],
  9487. MDIO_PMA_DEVAD,
  9488. MDIO_PMA_REG_TX_POWER_DOWN, &val);
  9489. bnx2x_cl45_write(bp, phy_blk[port],
  9490. MDIO_PMA_DEVAD,
  9491. MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
  9492. msleep(15);
  9493. /* Read modify write the SPI-ROM version select register */
  9494. bnx2x_cl45_read(bp, phy_blk[port],
  9495. MDIO_PMA_DEVAD,
  9496. MDIO_PMA_REG_EDC_FFE_MAIN, &val);
  9497. bnx2x_cl45_write(bp, phy_blk[port],
  9498. MDIO_PMA_DEVAD,
  9499. MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
  9500. /* set GPIO2 back to LOW */
  9501. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
  9502. MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
  9503. }
  9504. return 0;
  9505. }
  9506. static int bnx2x_8726_common_init_phy(struct bnx2x *bp,
  9507. u32 shmem_base_path[],
  9508. u32 shmem2_base_path[], u8 phy_index,
  9509. u32 chip_id)
  9510. {
  9511. u32 val;
  9512. s8 port;
  9513. struct bnx2x_phy phy;
  9514. /* Use port1 because of the static port-swap */
  9515. /* Enable the module detection interrupt */
  9516. val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
  9517. val |= ((1<<MISC_REGISTERS_GPIO_3)|
  9518. (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
  9519. REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
  9520. bnx2x_ext_phy_hw_reset(bp, 0);
  9521. msleep(5);
  9522. for (port = 0; port < PORT_MAX; port++) {
  9523. u32 shmem_base, shmem2_base;
  9524. /* In E2, same phy is using for port0 of the two paths */
  9525. if (CHIP_IS_E1x(bp)) {
  9526. shmem_base = shmem_base_path[0];
  9527. shmem2_base = shmem2_base_path[0];
  9528. } else {
  9529. shmem_base = shmem_base_path[port];
  9530. shmem2_base = shmem2_base_path[port];
  9531. }
  9532. /* Extract the ext phy address for the port */
  9533. if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
  9534. port, &phy) !=
  9535. 0) {
  9536. DP(NETIF_MSG_LINK, "populate phy failed\n");
  9537. return -EINVAL;
  9538. }
  9539. /* Reset phy*/
  9540. bnx2x_cl45_write(bp, &phy,
  9541. MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
  9542. /* Set fault module detected LED on */
  9543. bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
  9544. MISC_REGISTERS_GPIO_HIGH,
  9545. port);
  9546. }
  9547. return 0;
  9548. }
  9549. static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
  9550. u8 *io_gpio, u8 *io_port)
  9551. {
  9552. u32 phy_gpio_reset = REG_RD(bp, shmem_base +
  9553. offsetof(struct shmem_region,
  9554. dev_info.port_hw_config[PORT_0].default_cfg));
  9555. switch (phy_gpio_reset) {
  9556. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
  9557. *io_gpio = 0;
  9558. *io_port = 0;
  9559. break;
  9560. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
  9561. *io_gpio = 1;
  9562. *io_port = 0;
  9563. break;
  9564. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
  9565. *io_gpio = 2;
  9566. *io_port = 0;
  9567. break;
  9568. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
  9569. *io_gpio = 3;
  9570. *io_port = 0;
  9571. break;
  9572. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
  9573. *io_gpio = 0;
  9574. *io_port = 1;
  9575. break;
  9576. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
  9577. *io_gpio = 1;
  9578. *io_port = 1;
  9579. break;
  9580. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
  9581. *io_gpio = 2;
  9582. *io_port = 1;
  9583. break;
  9584. case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
  9585. *io_gpio = 3;
  9586. *io_port = 1;
  9587. break;
  9588. default:
  9589. /* Don't override the io_gpio and io_port */
  9590. break;
  9591. }
  9592. }
  9593. static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
  9594. u32 shmem_base_path[],
  9595. u32 shmem2_base_path[], u8 phy_index,
  9596. u32 chip_id)
  9597. {
  9598. s8 port, reset_gpio;
  9599. u32 swap_val, swap_override;
  9600. struct bnx2x_phy phy[PORT_MAX];
  9601. struct bnx2x_phy *phy_blk[PORT_MAX];
  9602. s8 port_of_path;
  9603. swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
  9604. swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
  9605. reset_gpio = MISC_REGISTERS_GPIO_1;
  9606. port = 1;
  9607. /*
  9608. * Retrieve the reset gpio/port which control the reset.
  9609. * Default is GPIO1, PORT1
  9610. */
  9611. bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
  9612. (u8 *)&reset_gpio, (u8 *)&port);
  9613. /* Calculate the port based on port swap */
  9614. port ^= (swap_val && swap_override);
  9615. /* Initiate PHY reset*/
  9616. bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
  9617. port);
  9618. msleep(1);
  9619. bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
  9620. port);
  9621. msleep(5);
  9622. /* PART1 - Reset both phys */
  9623. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  9624. u32 shmem_base, shmem2_base;
  9625. /* In E2, same phy is using for port0 of the two paths */
  9626. if (CHIP_IS_E1x(bp)) {
  9627. shmem_base = shmem_base_path[0];
  9628. shmem2_base = shmem2_base_path[0];
  9629. port_of_path = port;
  9630. } else {
  9631. shmem_base = shmem_base_path[port];
  9632. shmem2_base = shmem2_base_path[port];
  9633. port_of_path = 0;
  9634. }
  9635. /* Extract the ext phy address for the port */
  9636. if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
  9637. port_of_path, &phy[port]) !=
  9638. 0) {
  9639. DP(NETIF_MSG_LINK, "populate phy failed\n");
  9640. return -EINVAL;
  9641. }
  9642. /* disable attentions */
  9643. bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
  9644. port_of_path*4,
  9645. (NIG_MASK_XGXS0_LINK_STATUS |
  9646. NIG_MASK_XGXS0_LINK10G |
  9647. NIG_MASK_SERDES0_LINK_STATUS |
  9648. NIG_MASK_MI_INT));
  9649. /* Reset the phy */
  9650. bnx2x_cl45_write(bp, &phy[port],
  9651. MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
  9652. }
  9653. /* Add delay of 150ms after reset */
  9654. msleep(150);
  9655. if (phy[PORT_0].addr & 0x1) {
  9656. phy_blk[PORT_0] = &(phy[PORT_1]);
  9657. phy_blk[PORT_1] = &(phy[PORT_0]);
  9658. } else {
  9659. phy_blk[PORT_0] = &(phy[PORT_0]);
  9660. phy_blk[PORT_1] = &(phy[PORT_1]);
  9661. }
  9662. /* PART2 - Download firmware to both phys */
  9663. for (port = PORT_MAX - 1; port >= PORT_0; port--) {
  9664. if (CHIP_IS_E1x(bp))
  9665. port_of_path = port;
  9666. else
  9667. port_of_path = 0;
  9668. DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
  9669. phy_blk[port]->addr);
  9670. if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
  9671. port_of_path))
  9672. return -EINVAL;
  9673. }
  9674. return 0;
  9675. }
  9676. static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
  9677. u32 shmem2_base_path[], u8 phy_index,
  9678. u32 ext_phy_type, u32 chip_id)
  9679. {
  9680. int rc = 0;
  9681. switch (ext_phy_type) {
  9682. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
  9683. rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
  9684. shmem2_base_path,
  9685. phy_index, chip_id);
  9686. break;
  9687. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
  9688. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
  9689. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
  9690. rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
  9691. shmem2_base_path,
  9692. phy_index, chip_id);
  9693. break;
  9694. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
  9695. /*
  9696. * GPIO1 affects both ports, so there's need to pull
  9697. * it for single port alone
  9698. */
  9699. rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
  9700. shmem2_base_path,
  9701. phy_index, chip_id);
  9702. break;
  9703. case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
  9704. rc = -EINVAL;
  9705. break;
  9706. default:
  9707. DP(NETIF_MSG_LINK,
  9708. "ext_phy 0x%x common init not required\n",
  9709. ext_phy_type);
  9710. break;
  9711. }
  9712. if (rc != 0)
  9713. netdev_err(bp->dev, "Warning: PHY was not initialized,"
  9714. " Port %d\n",
  9715. 0);
  9716. return rc;
  9717. }
  9718. int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
  9719. u32 shmem2_base_path[], u32 chip_id)
  9720. {
  9721. int rc = 0;
  9722. u32 phy_ver, val;
  9723. u8 phy_index = 0;
  9724. u32 ext_phy_type, ext_phy_config;
  9725. bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
  9726. bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
  9727. DP(NETIF_MSG_LINK, "Begin common phy init\n");
  9728. if (CHIP_IS_E3(bp)) {
  9729. /* Enable EPIO */
  9730. val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
  9731. REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
  9732. }
  9733. /* Check if common init was already done */
  9734. phy_ver = REG_RD(bp, shmem_base_path[0] +
  9735. offsetof(struct shmem_region,
  9736. port_mb[PORT_0].ext_phy_fw_version));
  9737. if (phy_ver) {
  9738. DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
  9739. phy_ver);
  9740. return 0;
  9741. }
  9742. /* Read the ext_phy_type for arbitrary port(0) */
  9743. for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
  9744. phy_index++) {
  9745. ext_phy_config = bnx2x_get_ext_phy_config(bp,
  9746. shmem_base_path[0],
  9747. phy_index, 0);
  9748. ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
  9749. rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
  9750. shmem2_base_path,
  9751. phy_index, ext_phy_type,
  9752. chip_id);
  9753. }
  9754. return rc;
  9755. }
  9756. u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
  9757. {
  9758. u8 phy_index;
  9759. struct bnx2x_phy phy;
  9760. for (phy_index = INT_PHY; phy_index < MAX_PHYS;
  9761. phy_index++) {
  9762. if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
  9763. 0, &phy) != 0) {
  9764. DP(NETIF_MSG_LINK, "populate phy failed\n");
  9765. return 0;
  9766. }
  9767. if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
  9768. return 1;
  9769. }
  9770. return 0;
  9771. }
  9772. u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
  9773. u32 shmem_base,
  9774. u32 shmem2_base,
  9775. u8 port)
  9776. {
  9777. u8 phy_index, fan_failure_det_req = 0;
  9778. struct bnx2x_phy phy;
  9779. for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
  9780. phy_index++) {
  9781. if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
  9782. port, &phy)
  9783. != 0) {
  9784. DP(NETIF_MSG_LINK, "populate phy failed\n");
  9785. return 0;
  9786. }
  9787. fan_failure_det_req |= (phy.flags &
  9788. FLAGS_FAN_FAILURE_DET_REQ);
  9789. }
  9790. return fan_failure_det_req;
  9791. }
  9792. void bnx2x_hw_reset_phy(struct link_params *params)
  9793. {
  9794. u8 phy_index;
  9795. for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
  9796. phy_index++) {
  9797. if (params->phy[phy_index].hw_reset) {
  9798. params->phy[phy_index].hw_reset(
  9799. &params->phy[phy_index],
  9800. params);
  9801. params->phy[phy_index] = phy_null;
  9802. }
  9803. }
  9804. }
  9805. void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
  9806. u32 chip_id, u32 shmem_base, u32 shmem2_base,
  9807. u8 port)
  9808. {
  9809. u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
  9810. u32 val;
  9811. u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
  9812. if (CHIP_IS_E3(bp)) {
  9813. if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
  9814. shmem_base,
  9815. port,
  9816. &gpio_num,
  9817. &gpio_port) != 0)
  9818. return;
  9819. } else {
  9820. struct bnx2x_phy phy;
  9821. for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
  9822. phy_index++) {
  9823. if (bnx2x_populate_phy(bp, phy_index, shmem_base,
  9824. shmem2_base, port, &phy)
  9825. != 0) {
  9826. DP(NETIF_MSG_LINK, "populate phy failed\n");
  9827. return;
  9828. }
  9829. if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
  9830. gpio_num = MISC_REGISTERS_GPIO_3;
  9831. gpio_port = port;
  9832. break;
  9833. }
  9834. }
  9835. }
  9836. if (gpio_num == 0xff)
  9837. return;
  9838. /* Set GPIO3 to trigger SFP+ module insertion/removal */
  9839. bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
  9840. swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
  9841. swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
  9842. gpio_port ^= (swap_val && swap_override);
  9843. vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
  9844. (gpio_num + (gpio_port << 2));
  9845. sync_offset = shmem_base +
  9846. offsetof(struct shmem_region,
  9847. dev_info.port_hw_config[port].aeu_int_mask);
  9848. REG_WR(bp, sync_offset, vars->aeu_int_mask);
  9849. DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
  9850. gpio_num, gpio_port, vars->aeu_int_mask);
  9851. if (port == 0)
  9852. offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
  9853. else
  9854. offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
  9855. /* Open appropriate AEU for interrupts */
  9856. aeu_mask = REG_RD(bp, offset);
  9857. aeu_mask |= vars->aeu_int_mask;
  9858. REG_WR(bp, offset, aeu_mask);
  9859. /* Enable the GPIO to trigger interrupt */
  9860. val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
  9861. val |= 1 << (gpio_num + (gpio_port << 2));
  9862. REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
  9863. }