skgepnmi.c 216 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359
  1. /*****************************************************************************
  2. *
  3. * Name: skgepnmi.c
  4. * Project: GEnesis, PCI Gigabit Ethernet Adapter
  5. * Version: $Revision: 1.111 $
  6. * Date: $Date: 2003/09/15 13:35:35 $
  7. * Purpose: Private Network Management Interface
  8. *
  9. ****************************************************************************/
  10. /******************************************************************************
  11. *
  12. * (C)Copyright 1998-2002 SysKonnect GmbH.
  13. * (C)Copyright 2002-2003 Marvell.
  14. *
  15. * This program is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License as published by
  17. * the Free Software Foundation; either version 2 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * The information in this file is provided "AS IS" without warranty.
  21. *
  22. ******************************************************************************/
  23. #ifndef _lint
  24. static const char SysKonnectFileId[] =
  25. "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
  26. #endif /* !_lint */
  27. #include "h/skdrv1st.h"
  28. #include "h/sktypes.h"
  29. #include "h/xmac_ii.h"
  30. #include "h/skdebug.h"
  31. #include "h/skqueue.h"
  32. #include "h/skgepnmi.h"
  33. #include "h/skgesirq.h"
  34. #include "h/skcsum.h"
  35. #include "h/skvpd.h"
  36. #include "h/skgehw.h"
  37. #include "h/skgeinit.h"
  38. #include "h/skdrv2nd.h"
  39. #include "h/skgepnm2.h"
  40. #ifdef SK_POWER_MGMT
  41. #include "h/skgepmgt.h"
  42. #endif
  43. /* defines *******************************************************************/
  44. #ifndef DEBUG
  45. #define PNMI_STATIC static
  46. #else /* DEBUG */
  47. #define PNMI_STATIC
  48. #endif /* DEBUG */
  49. /*
  50. * Public Function prototypes
  51. */
  52. int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
  53. int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
  54. unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
  55. int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
  56. unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
  57. int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
  58. unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
  59. int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
  60. unsigned int *pLen, SK_U32 NetIndex);
  61. int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
  62. unsigned int *pLen, SK_U32 NetIndex);
  63. int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
  64. unsigned int *pLen, SK_U32 NetIndex);
  65. int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
  66. int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
  67. unsigned int * pLen, SK_U32 NetIndex);
  68. /*
  69. * Private Function prototypes
  70. */
  71. PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
  72. PhysPortIndex);
  73. PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
  74. PhysPortIndex);
  75. PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
  76. PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
  77. PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
  78. unsigned int PhysPortIndex, unsigned int StatIndex);
  79. PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
  80. unsigned int StatIndex, SK_U32 NetIndex);
  81. PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
  82. PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
  83. unsigned int *pEntries);
  84. PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
  85. unsigned int KeyArrLen, unsigned int *pKeyNo);
  86. PNMI_STATIC int LookupId(SK_U32 Id);
  87. PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
  88. unsigned int LastMac);
  89. PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
  90. unsigned int *pLen, SK_U32 NetIndex);
  91. PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
  92. char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
  93. PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
  94. PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
  95. unsigned int PortIndex);
  96. PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
  97. unsigned int SensorIndex);
  98. PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
  99. PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
  100. PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
  101. PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
  102. PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
  103. PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
  104. unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
  105. PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
  106. /*
  107. * Table to correlate OID with handler function and index to
  108. * hardware register stored in StatAddress if applicable.
  109. */
  110. #include "skgemib.c"
  111. /* global variables **********************************************************/
  112. /*
  113. * Overflow status register bit table and corresponding counter
  114. * dependent on MAC type - the number relates to the size of overflow
  115. * mask returned by the pFnMacOverflow function
  116. */
  117. PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
  118. /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
  119. /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
  120. /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
  121. /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
  122. /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
  123. /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
  124. /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
  125. /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
  126. /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
  127. /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
  128. /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
  129. /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
  130. /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
  131. /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
  132. /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
  133. /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
  134. /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
  135. /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
  136. /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
  137. /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
  138. /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
  139. /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
  140. /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
  141. /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
  142. /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
  143. /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
  144. /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
  145. /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
  146. /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
  147. /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
  148. /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
  149. /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
  150. /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
  151. /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
  152. /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
  153. /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
  154. /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
  155. /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
  156. /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
  157. /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
  158. /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
  159. /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
  160. /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
  161. /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
  162. /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
  163. /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
  164. /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
  165. /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
  166. /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
  167. /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
  168. /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
  169. /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
  170. /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
  171. /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
  172. /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
  173. /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
  174. /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
  175. /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
  176. /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
  177. /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
  178. /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
  179. /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
  180. /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
  181. /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
  182. };
  183. /*
  184. * Table for hardware register saving on resets and port switches
  185. */
  186. PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
  187. /* SK_PNMI_HTX */
  188. {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
  189. /* SK_PNMI_HTX_OCTETHIGH */
  190. {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
  191. /* SK_PNMI_HTX_OCTETLOW */
  192. {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
  193. /* SK_PNMI_HTX_BROADCAST */
  194. {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
  195. /* SK_PNMI_HTX_MULTICAST */
  196. {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
  197. /* SK_PNMI_HTX_UNICAST */
  198. {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
  199. /* SK_PNMI_HTX_BURST */
  200. {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
  201. /* SK_PNMI_HTX_PMACC */
  202. {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
  203. /* SK_PNMI_HTX_MACC */
  204. {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
  205. /* SK_PNMI_HTX_COL */
  206. {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
  207. /* SK_PNMI_HTX_SINGLE_COL */
  208. {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
  209. /* SK_PNMI_HTX_MULTI_COL */
  210. {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
  211. /* SK_PNMI_HTX_EXCESS_COL */
  212. {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
  213. /* SK_PNMI_HTX_LATE_COL */
  214. {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
  215. /* SK_PNMI_HTX_DEFFERAL */
  216. {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
  217. /* SK_PNMI_HTX_EXCESS_DEF */
  218. {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
  219. /* SK_PNMI_HTX_UNDERRUN */
  220. {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
  221. /* SK_PNMI_HTX_CARRIER */
  222. {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
  223. /* SK_PNMI_HTX_UTILUNDER */
  224. {{0, SK_FALSE}, {0, SK_FALSE}},
  225. /* SK_PNMI_HTX_UTILOVER */
  226. {{0, SK_FALSE}, {0, SK_FALSE}},
  227. /* SK_PNMI_HTX_64 */
  228. {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
  229. /* SK_PNMI_HTX_127 */
  230. {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
  231. /* SK_PNMI_HTX_255 */
  232. {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
  233. /* SK_PNMI_HTX_511 */
  234. {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
  235. /* SK_PNMI_HTX_1023 */
  236. {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
  237. /* SK_PNMI_HTX_MAX */
  238. {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
  239. /* SK_PNMI_HTX_LONGFRAMES */
  240. {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
  241. /* SK_PNMI_HTX_SYNC */
  242. {{0, SK_FALSE}, {0, SK_FALSE}},
  243. /* SK_PNMI_HTX_SYNC_OCTET */
  244. {{0, SK_FALSE}, {0, SK_FALSE}},
  245. /* SK_PNMI_HTX_RESERVED */
  246. {{0, SK_FALSE}, {0, SK_FALSE}},
  247. /* SK_PNMI_HRX */
  248. {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
  249. /* SK_PNMI_HRX_OCTETHIGH */
  250. {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
  251. /* SK_PNMI_HRX_OCTETLOW */
  252. {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
  253. /* SK_PNMI_HRX_BADOCTETHIGH */
  254. {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
  255. /* SK_PNMI_HRX_BADOCTETLOW */
  256. {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
  257. /* SK_PNMI_HRX_BROADCAST */
  258. {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
  259. /* SK_PNMI_HRX_MULTICAST */
  260. {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
  261. /* SK_PNMI_HRX_UNICAST */
  262. {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
  263. /* SK_PNMI_HRX_PMACC */
  264. {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
  265. /* SK_PNMI_HRX_MACC */
  266. {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
  267. /* SK_PNMI_HRX_PMACC_ERR */
  268. {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
  269. /* SK_PNMI_HRX_MACC_UNKWN */
  270. {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
  271. /* SK_PNMI_HRX_BURST */
  272. {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
  273. /* SK_PNMI_HRX_MISSED */
  274. {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
  275. /* SK_PNMI_HRX_FRAMING */
  276. {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
  277. /* SK_PNMI_HRX_UNDERSIZE */
  278. {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
  279. /* SK_PNMI_HRX_OVERFLOW */
  280. {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
  281. /* SK_PNMI_HRX_JABBER */
  282. {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
  283. /* SK_PNMI_HRX_CARRIER */
  284. {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
  285. /* SK_PNMI_HRX_IRLENGTH */
  286. {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
  287. /* SK_PNMI_HRX_SYMBOL */
  288. {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
  289. /* SK_PNMI_HRX_SHORTS */
  290. {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
  291. /* SK_PNMI_HRX_RUNT */
  292. {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
  293. /* SK_PNMI_HRX_TOO_LONG */
  294. {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
  295. /* SK_PNMI_HRX_FCS */
  296. {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
  297. /* SK_PNMI_HRX_CEXT */
  298. {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
  299. /* SK_PNMI_HRX_UTILUNDER */
  300. {{0, SK_FALSE}, {0, SK_FALSE}},
  301. /* SK_PNMI_HRX_UTILOVER */
  302. {{0, SK_FALSE}, {0, SK_FALSE}},
  303. /* SK_PNMI_HRX_64 */
  304. {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
  305. /* SK_PNMI_HRX_127 */
  306. {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
  307. /* SK_PNMI_HRX_255 */
  308. {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
  309. /* SK_PNMI_HRX_511 */
  310. {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
  311. /* SK_PNMI_HRX_1023 */
  312. {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
  313. /* SK_PNMI_HRX_MAX */
  314. {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
  315. /* SK_PNMI_HRX_LONGFRAMES */
  316. {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
  317. /* SK_PNMI_HRX_RESERVED */
  318. {{0, SK_FALSE}, {0, SK_FALSE}}
  319. };
  320. /*****************************************************************************
  321. *
  322. * Public functions
  323. *
  324. */
  325. /*****************************************************************************
  326. *
  327. * SkPnmiInit - Init function of PNMI
  328. *
  329. * Description:
  330. * SK_INIT_DATA: Initialises the data structures
  331. * SK_INIT_IO: Resets the XMAC statistics, determines the device and
  332. * connector type.
  333. * SK_INIT_RUN: Starts a timer event for port switch per hour
  334. * calculation.
  335. *
  336. * Returns:
  337. * Always 0
  338. */
  339. int SkPnmiInit(
  340. SK_AC *pAC, /* Pointer to adapter context */
  341. SK_IOC IoC, /* IO context handle */
  342. int Level) /* Initialization level */
  343. {
  344. unsigned int PortMax; /* Number of ports */
  345. unsigned int PortIndex; /* Current port index in loop */
  346. SK_U16 Val16; /* Multiple purpose 16 bit variable */
  347. SK_U8 Val8; /* Mulitple purpose 8 bit variable */
  348. SK_EVPARA EventParam; /* Event struct for timer event */
  349. SK_PNMI_VCT *pVctBackupData;
  350. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  351. ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
  352. switch (Level) {
  353. case SK_INIT_DATA:
  354. SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
  355. pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
  356. pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
  357. pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
  358. for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
  359. pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
  360. pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
  361. }
  362. #ifdef SK_PNMI_CHECK
  363. if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
  364. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
  365. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
  366. ("CounterOffset struct size (%d) differs from"
  367. "SK_PNMI_MAX_IDX (%d)\n",
  368. SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
  369. }
  370. if (SK_PNMI_MAX_IDX !=
  371. (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
  372. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
  373. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
  374. ("StatAddr table size (%d) differs from "
  375. "SK_PNMI_MAX_IDX (%d)\n",
  376. (sizeof(StatAddr) /
  377. (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
  378. SK_PNMI_MAX_IDX));
  379. }
  380. #endif /* SK_PNMI_CHECK */
  381. break;
  382. case SK_INIT_IO:
  383. /*
  384. * Reset MAC counters
  385. */
  386. PortMax = pAC->GIni.GIMacsFound;
  387. for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
  388. pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
  389. }
  390. /* Initialize DSP variables for Vct() to 0xff => Never written! */
  391. for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
  392. pAC->GIni.GP[PortIndex].PCableLen = 0xff;
  393. pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
  394. pVctBackupData->PCableLen = 0xff;
  395. }
  396. /*
  397. * Get pci bus speed
  398. */
  399. SK_IN16(IoC, B0_CTST, &Val16);
  400. if ((Val16 & CS_BUS_CLOCK) == 0) {
  401. pAC->Pnmi.PciBusSpeed = 33;
  402. }
  403. else {
  404. pAC->Pnmi.PciBusSpeed = 66;
  405. }
  406. /*
  407. * Get pci bus width
  408. */
  409. SK_IN16(IoC, B0_CTST, &Val16);
  410. if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
  411. pAC->Pnmi.PciBusWidth = 32;
  412. }
  413. else {
  414. pAC->Pnmi.PciBusWidth = 64;
  415. }
  416. /*
  417. * Get chipset
  418. */
  419. switch (pAC->GIni.GIChipId) {
  420. case CHIP_ID_GENESIS:
  421. pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
  422. break;
  423. case CHIP_ID_YUKON:
  424. pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
  425. break;
  426. default:
  427. break;
  428. }
  429. /*
  430. * Get PMD and DeviceType
  431. */
  432. SK_IN8(IoC, B2_PMD_TYP, &Val8);
  433. switch (Val8) {
  434. case 'S':
  435. pAC->Pnmi.PMD = 3;
  436. if (pAC->GIni.GIMacsFound > 1) {
  437. pAC->Pnmi.DeviceType = 0x00020002;
  438. }
  439. else {
  440. pAC->Pnmi.DeviceType = 0x00020001;
  441. }
  442. break;
  443. case 'L':
  444. pAC->Pnmi.PMD = 2;
  445. if (pAC->GIni.GIMacsFound > 1) {
  446. pAC->Pnmi.DeviceType = 0x00020004;
  447. }
  448. else {
  449. pAC->Pnmi.DeviceType = 0x00020003;
  450. }
  451. break;
  452. case 'C':
  453. pAC->Pnmi.PMD = 4;
  454. if (pAC->GIni.GIMacsFound > 1) {
  455. pAC->Pnmi.DeviceType = 0x00020006;
  456. }
  457. else {
  458. pAC->Pnmi.DeviceType = 0x00020005;
  459. }
  460. break;
  461. case 'T':
  462. pAC->Pnmi.PMD = 5;
  463. if (pAC->GIni.GIMacsFound > 1) {
  464. pAC->Pnmi.DeviceType = 0x00020008;
  465. }
  466. else {
  467. pAC->Pnmi.DeviceType = 0x00020007;
  468. }
  469. break;
  470. default :
  471. pAC->Pnmi.PMD = 1;
  472. pAC->Pnmi.DeviceType = 0;
  473. break;
  474. }
  475. /*
  476. * Get connector
  477. */
  478. SK_IN8(IoC, B2_CONN_TYP, &Val8);
  479. switch (Val8) {
  480. case 'C':
  481. pAC->Pnmi.Connector = 2;
  482. break;
  483. case 'D':
  484. pAC->Pnmi.Connector = 3;
  485. break;
  486. case 'F':
  487. pAC->Pnmi.Connector = 4;
  488. break;
  489. case 'J':
  490. pAC->Pnmi.Connector = 5;
  491. break;
  492. case 'V':
  493. pAC->Pnmi.Connector = 6;
  494. break;
  495. default:
  496. pAC->Pnmi.Connector = 1;
  497. break;
  498. }
  499. break;
  500. case SK_INIT_RUN:
  501. /*
  502. * Start timer for RLMT change counter
  503. */
  504. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  505. SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
  506. 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
  507. EventParam);
  508. break;
  509. default:
  510. break; /* Nothing todo */
  511. }
  512. return (0);
  513. }
  514. /*****************************************************************************
  515. *
  516. * SkPnmiGetVar - Retrieves the value of a single OID
  517. *
  518. * Description:
  519. * Calls a general sub-function for all this stuff. If the instance
  520. * -1 is passed, the values of all instances are returned in an
  521. * array of values.
  522. *
  523. * Returns:
  524. * SK_PNMI_ERR_OK The request was successfully performed
  525. * SK_PNMI_ERR_GENERAL A general severe internal error occured
  526. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
  527. * the data.
  528. * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
  529. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  530. * exist (e.g. port instance 3 on a two port
  531. * adapter.
  532. */
  533. int SkPnmiGetVar(
  534. SK_AC *pAC, /* Pointer to adapter context */
  535. SK_IOC IoC, /* IO context handle */
  536. SK_U32 Id, /* Object ID that is to be processed */
  537. void *pBuf, /* Buffer to which the management data will be copied */
  538. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  539. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  540. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  541. {
  542. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  543. ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
  544. Id, *pLen, Instance, NetIndex));
  545. return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
  546. Instance, NetIndex));
  547. }
  548. /*****************************************************************************
  549. *
  550. * SkPnmiPreSetVar - Presets the value of a single OID
  551. *
  552. * Description:
  553. * Calls a general sub-function for all this stuff. The preset does
  554. * the same as a set, but returns just before finally setting the
  555. * new value. This is useful to check if a set might be successfull.
  556. * If the instance -1 is passed, an array of values is supposed and
  557. * all instances of the OID will be set.
  558. *
  559. * Returns:
  560. * SK_PNMI_ERR_OK The request was successfully performed.
  561. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  562. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  563. * the correct data (e.g. a 32bit value is
  564. * needed, but a 16 bit value was passed).
  565. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  566. * value range.
  567. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  568. * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
  569. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  570. * exist (e.g. port instance 3 on a two port
  571. * adapter.
  572. */
  573. int SkPnmiPreSetVar(
  574. SK_AC *pAC, /* Pointer to adapter context */
  575. SK_IOC IoC, /* IO context handle */
  576. SK_U32 Id, /* Object ID that is to be processed */
  577. void *pBuf, /* Buffer to which the management data will be copied */
  578. unsigned int *pLen, /* Total length of management data */
  579. SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
  580. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  581. {
  582. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  583. ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
  584. Id, *pLen, Instance, NetIndex));
  585. return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
  586. Instance, NetIndex));
  587. }
  588. /*****************************************************************************
  589. *
  590. * SkPnmiSetVar - Sets the value of a single OID
  591. *
  592. * Description:
  593. * Calls a general sub-function for all this stuff. The preset does
  594. * the same as a set, but returns just before finally setting the
  595. * new value. This is useful to check if a set might be successfull.
  596. * If the instance -1 is passed, an array of values is supposed and
  597. * all instances of the OID will be set.
  598. *
  599. * Returns:
  600. * SK_PNMI_ERR_OK The request was successfully performed.
  601. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  602. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  603. * the correct data (e.g. a 32bit value is
  604. * needed, but a 16 bit value was passed).
  605. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  606. * value range.
  607. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  608. * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
  609. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  610. * exist (e.g. port instance 3 on a two port
  611. * adapter.
  612. */
  613. int SkPnmiSetVar(
  614. SK_AC *pAC, /* Pointer to adapter context */
  615. SK_IOC IoC, /* IO context handle */
  616. SK_U32 Id, /* Object ID that is to be processed */
  617. void *pBuf, /* Buffer to which the management data will be copied */
  618. unsigned int *pLen, /* Total length of management data */
  619. SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
  620. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  621. {
  622. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  623. ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
  624. Id, *pLen, Instance, NetIndex));
  625. return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
  626. Instance, NetIndex));
  627. }
  628. /*****************************************************************************
  629. *
  630. * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
  631. *
  632. * Description:
  633. * Runs through the IdTable, queries the single OIDs and stores the
  634. * returned data into the management database structure
  635. * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
  636. * is stored in the IdTable. The return value of the function will also
  637. * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
  638. * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
  639. *
  640. * Returns:
  641. * SK_PNMI_ERR_OK The request was successfully performed
  642. * SK_PNMI_ERR_GENERAL A general severe internal error occured
  643. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
  644. * the data.
  645. * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
  646. */
  647. int SkPnmiGetStruct(
  648. SK_AC *pAC, /* Pointer to adapter context */
  649. SK_IOC IoC, /* IO context handle */
  650. void *pBuf, /* Buffer to which the management data will be copied. */
  651. unsigned int *pLen, /* Length of buffer */
  652. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  653. {
  654. int Ret;
  655. unsigned int TableIndex;
  656. unsigned int DstOffset;
  657. unsigned int InstanceNo;
  658. unsigned int InstanceCnt;
  659. SK_U32 Instance;
  660. unsigned int TmpLen;
  661. char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
  662. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  663. ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
  664. *pLen, NetIndex));
  665. if (*pLen < SK_PNMI_STRUCT_SIZE) {
  666. if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
  667. SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
  668. (SK_U32)(-1));
  669. }
  670. *pLen = SK_PNMI_STRUCT_SIZE;
  671. return (SK_PNMI_ERR_TOO_SHORT);
  672. }
  673. /*
  674. * Check NetIndex
  675. */
  676. if (NetIndex >= pAC->Rlmt.NumNets) {
  677. return (SK_PNMI_ERR_UNKNOWN_NET);
  678. }
  679. /* Update statistic */
  680. SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
  681. if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
  682. SK_PNMI_ERR_OK) {
  683. SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
  684. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  685. return (Ret);
  686. }
  687. if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
  688. SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
  689. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  690. return (Ret);
  691. }
  692. if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
  693. SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
  694. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  695. return (Ret);
  696. }
  697. /*
  698. * Increment semaphores to indicate that an update was
  699. * already done
  700. */
  701. pAC->Pnmi.MacUpdatedFlag ++;
  702. pAC->Pnmi.RlmtUpdatedFlag ++;
  703. pAC->Pnmi.SirqUpdatedFlag ++;
  704. /* Get vpd keys for instance calculation */
  705. Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
  706. if (Ret != SK_PNMI_ERR_OK) {
  707. pAC->Pnmi.MacUpdatedFlag --;
  708. pAC->Pnmi.RlmtUpdatedFlag --;
  709. pAC->Pnmi.SirqUpdatedFlag --;
  710. SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
  711. SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
  712. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  713. return (SK_PNMI_ERR_GENERAL);
  714. }
  715. /* Retrieve values */
  716. SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
  717. for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
  718. InstanceNo = IdTable[TableIndex].InstanceNo;
  719. for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
  720. InstanceCnt ++) {
  721. DstOffset = IdTable[TableIndex].Offset +
  722. (InstanceCnt - 1) *
  723. IdTable[TableIndex].StructSize;
  724. /*
  725. * For the VPD the instance is not an index number
  726. * but the key itself. Determin with the instance
  727. * counter the VPD key to be used.
  728. */
  729. if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
  730. IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
  731. IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
  732. IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
  733. SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
  734. }
  735. else {
  736. Instance = (SK_U32)InstanceCnt;
  737. }
  738. TmpLen = *pLen - DstOffset;
  739. Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
  740. IdTable[TableIndex].Id, (char *)pBuf +
  741. DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
  742. /*
  743. * An unknown instance error means that we reached
  744. * the last instance of that variable. Proceed with
  745. * the next OID in the table and ignore the return
  746. * code.
  747. */
  748. if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
  749. break;
  750. }
  751. if (Ret != SK_PNMI_ERR_OK) {
  752. pAC->Pnmi.MacUpdatedFlag --;
  753. pAC->Pnmi.RlmtUpdatedFlag --;
  754. pAC->Pnmi.SirqUpdatedFlag --;
  755. SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
  756. SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
  757. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  758. return (Ret);
  759. }
  760. }
  761. }
  762. pAC->Pnmi.MacUpdatedFlag --;
  763. pAC->Pnmi.RlmtUpdatedFlag --;
  764. pAC->Pnmi.SirqUpdatedFlag --;
  765. *pLen = SK_PNMI_STRUCT_SIZE;
  766. SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
  767. SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
  768. return (SK_PNMI_ERR_OK);
  769. }
  770. /*****************************************************************************
  771. *
  772. * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
  773. *
  774. * Description:
  775. * Calls a general sub-function for all this set stuff. The preset does
  776. * the same as a set, but returns just before finally setting the
  777. * new value. This is useful to check if a set might be successfull.
  778. * The sub-function runs through the IdTable, checks which OIDs are able
  779. * to set, and calls the handler function of the OID to perform the
  780. * preset. The return value of the function will also be stored in
  781. * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
  782. * SK_PNMI_MIN_STRUCT_SIZE.
  783. *
  784. * Returns:
  785. * SK_PNMI_ERR_OK The request was successfully performed.
  786. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  787. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  788. * the correct data (e.g. a 32bit value is
  789. * needed, but a 16 bit value was passed).
  790. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  791. * value range.
  792. */
  793. int SkPnmiPreSetStruct(
  794. SK_AC *pAC, /* Pointer to adapter context */
  795. SK_IOC IoC, /* IO context handle */
  796. void *pBuf, /* Buffer which contains the data to be set */
  797. unsigned int *pLen, /* Length of buffer */
  798. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  799. {
  800. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  801. ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
  802. *pLen, NetIndex));
  803. return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
  804. pLen, NetIndex));
  805. }
  806. /*****************************************************************************
  807. *
  808. * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
  809. *
  810. * Description:
  811. * Calls a general sub-function for all this set stuff. The return value
  812. * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
  813. * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
  814. * The sub-function runs through the IdTable, checks which OIDs are able
  815. * to set, and calls the handler function of the OID to perform the
  816. * set. The return value of the function will also be stored in
  817. * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
  818. * SK_PNMI_MIN_STRUCT_SIZE.
  819. *
  820. * Returns:
  821. * SK_PNMI_ERR_OK The request was successfully performed.
  822. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  823. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  824. * the correct data (e.g. a 32bit value is
  825. * needed, but a 16 bit value was passed).
  826. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  827. * value range.
  828. */
  829. int SkPnmiSetStruct(
  830. SK_AC *pAC, /* Pointer to adapter context */
  831. SK_IOC IoC, /* IO context handle */
  832. void *pBuf, /* Buffer which contains the data to be set */
  833. unsigned int *pLen, /* Length of buffer */
  834. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  835. {
  836. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  837. ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
  838. *pLen, NetIndex));
  839. return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
  840. pLen, NetIndex));
  841. }
  842. /*****************************************************************************
  843. *
  844. * SkPnmiEvent - Event handler
  845. *
  846. * Description:
  847. * Handles the following events:
  848. * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
  849. * interrupt will be generated which is
  850. * first handled by SIRQ which generates a
  851. * this event. The event increments the
  852. * upper 32 bit of the 64 bit counter.
  853. * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
  854. * when a sensor reports a warning or
  855. * error. The event will store a trap
  856. * message in the trap buffer.
  857. * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
  858. * module and is used to calculate the
  859. * port switches per hour.
  860. * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
  861. * timestamps.
  862. * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
  863. * before a hard reset of the XMAC is
  864. * performed. All counters will be saved
  865. * and added to the hardware counter
  866. * values after reset to grant continuous
  867. * counter values.
  868. * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
  869. * went logically up. A trap message will
  870. * be stored to the trap buffer.
  871. * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
  872. * went logically down. A trap message will
  873. * be stored to the trap buffer.
  874. * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
  875. * spanning tree root bridges were
  876. * detected. A trap message will be stored
  877. * to the trap buffer.
  878. * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
  879. * down. PNMI will not further add the
  880. * statistic values to the virtual port.
  881. * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
  882. * is now an active port. PNMI will now
  883. * add the statistic data of this port to
  884. * the virtual port.
  885. * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
  886. * contains the number of nets. 1 means single net, 2 means
  887. * dual net. The second parameter is -1
  888. *
  889. * Returns:
  890. * Always 0
  891. */
  892. int SkPnmiEvent(
  893. SK_AC *pAC, /* Pointer to adapter context */
  894. SK_IOC IoC, /* IO context handle */
  895. SK_U32 Event, /* Event-Id */
  896. SK_EVPARA Param) /* Event dependent parameter */
  897. {
  898. unsigned int PhysPortIndex;
  899. unsigned int MaxNetNumber;
  900. int CounterIndex;
  901. int Ret;
  902. SK_U16 MacStatus;
  903. SK_U64 OverflowStatus;
  904. SK_U64 Mask;
  905. int MacType;
  906. SK_U64 Value;
  907. SK_U32 Val32;
  908. SK_U16 Register;
  909. SK_EVPARA EventParam;
  910. SK_U64 NewestValue;
  911. SK_U64 OldestValue;
  912. SK_U64 Delta;
  913. SK_PNMI_ESTIMATE *pEst;
  914. SK_U32 NetIndex;
  915. SK_GEPORT *pPrt;
  916. SK_PNMI_VCT *pVctBackupData;
  917. SK_U32 RetCode;
  918. int i;
  919. SK_U32 CableLength;
  920. #ifdef DEBUG
  921. if (Event != SK_PNMI_EVT_XMAC_RESET) {
  922. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  923. ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
  924. (unsigned int)Event, (unsigned int)Param.Para64));
  925. }
  926. #endif /* DEBUG */
  927. SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
  928. MacType = pAC->GIni.GIMacType;
  929. switch (Event) {
  930. case SK_PNMI_EVT_SIRQ_OVERFLOW:
  931. PhysPortIndex = (int)Param.Para32[0];
  932. MacStatus = (SK_U16)Param.Para32[1];
  933. #ifdef DEBUG
  934. if (PhysPortIndex >= SK_MAX_MACS) {
  935. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  936. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
  937. " wrong, PhysPortIndex=0x%x\n",
  938. PhysPortIndex));
  939. return (0);
  940. }
  941. #endif /* DEBUG */
  942. OverflowStatus = 0;
  943. /*
  944. * Check which source caused an overflow interrupt.
  945. */
  946. if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
  947. MacStatus, &OverflowStatus) != 0) ||
  948. (OverflowStatus == 0)) {
  949. SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
  950. return (0);
  951. }
  952. /*
  953. * Check the overflow status register and increment
  954. * the upper dword of corresponding counter.
  955. */
  956. for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
  957. CounterIndex ++) {
  958. Mask = (SK_U64)1 << CounterIndex;
  959. if ((OverflowStatus & Mask) == 0) {
  960. continue;
  961. }
  962. switch (StatOvrflwBit[CounterIndex][MacType]) {
  963. case SK_PNMI_HTX_UTILUNDER:
  964. case SK_PNMI_HTX_UTILOVER:
  965. if (MacType == SK_MAC_XMAC) {
  966. XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
  967. Register |= XM_TX_SAM_LINE;
  968. XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
  969. }
  970. break;
  971. case SK_PNMI_HRX_UTILUNDER:
  972. case SK_PNMI_HRX_UTILOVER:
  973. if (MacType == SK_MAC_XMAC) {
  974. XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
  975. Register |= XM_RX_SAM_LINE;
  976. XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
  977. }
  978. break;
  979. case SK_PNMI_HTX_OCTETHIGH:
  980. case SK_PNMI_HTX_OCTETLOW:
  981. case SK_PNMI_HTX_RESERVED:
  982. case SK_PNMI_HRX_OCTETHIGH:
  983. case SK_PNMI_HRX_OCTETLOW:
  984. case SK_PNMI_HRX_IRLENGTH:
  985. case SK_PNMI_HRX_RESERVED:
  986. /*
  987. * the following counters aren't be handled (id > 63)
  988. */
  989. case SK_PNMI_HTX_SYNC:
  990. case SK_PNMI_HTX_SYNC_OCTET:
  991. break;
  992. case SK_PNMI_HRX_LONGFRAMES:
  993. if (MacType == SK_MAC_GMAC) {
  994. pAC->Pnmi.Port[PhysPortIndex].
  995. CounterHigh[CounterIndex] ++;
  996. }
  997. break;
  998. default:
  999. pAC->Pnmi.Port[PhysPortIndex].
  1000. CounterHigh[CounterIndex] ++;
  1001. }
  1002. }
  1003. break;
  1004. case SK_PNMI_EVT_SEN_WAR_LOW:
  1005. #ifdef DEBUG
  1006. if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
  1007. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1008. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
  1009. (unsigned int)Param.Para64));
  1010. return (0);
  1011. }
  1012. #endif /* DEBUG */
  1013. /*
  1014. * Store a trap message in the trap buffer and generate
  1015. * an event for user space applications with the
  1016. * SK_DRIVER_SENDEVENT macro.
  1017. */
  1018. QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
  1019. (unsigned int)Param.Para64);
  1020. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1021. break;
  1022. case SK_PNMI_EVT_SEN_WAR_UPP:
  1023. #ifdef DEBUG
  1024. if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
  1025. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1026. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
  1027. (unsigned int)Param.Para64));
  1028. return (0);
  1029. }
  1030. #endif /* DEBUG */
  1031. /*
  1032. * Store a trap message in the trap buffer and generate
  1033. * an event for user space applications with the
  1034. * SK_DRIVER_SENDEVENT macro.
  1035. */
  1036. QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
  1037. (unsigned int)Param.Para64);
  1038. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1039. break;
  1040. case SK_PNMI_EVT_SEN_ERR_LOW:
  1041. #ifdef DEBUG
  1042. if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
  1043. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1044. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
  1045. (unsigned int)Param.Para64));
  1046. return (0);
  1047. }
  1048. #endif /* DEBUG */
  1049. /*
  1050. * Store a trap message in the trap buffer and generate
  1051. * an event for user space applications with the
  1052. * SK_DRIVER_SENDEVENT macro.
  1053. */
  1054. QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
  1055. (unsigned int)Param.Para64);
  1056. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1057. break;
  1058. case SK_PNMI_EVT_SEN_ERR_UPP:
  1059. #ifdef DEBUG
  1060. if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
  1061. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1062. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
  1063. (unsigned int)Param.Para64));
  1064. return (0);
  1065. }
  1066. #endif /* DEBUG */
  1067. /*
  1068. * Store a trap message in the trap buffer and generate
  1069. * an event for user space applications with the
  1070. * SK_DRIVER_SENDEVENT macro.
  1071. */
  1072. QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
  1073. (unsigned int)Param.Para64);
  1074. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1075. break;
  1076. case SK_PNMI_EVT_CHG_EST_TIMER:
  1077. /*
  1078. * Calculate port switch average on a per hour basis
  1079. * Time interval for check : 28125 ms
  1080. * Number of values for average : 8
  1081. *
  1082. * Be careful in changing these values, on change check
  1083. * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
  1084. * array one less than value number)
  1085. * - Timer initialization SkTimerStart() in SkPnmiInit
  1086. * - Delta value below must be multiplicated with
  1087. * power of 2
  1088. *
  1089. */
  1090. pEst = &pAC->Pnmi.RlmtChangeEstimate;
  1091. CounterIndex = pEst->EstValueIndex + 1;
  1092. if (CounterIndex == 7) {
  1093. CounterIndex = 0;
  1094. }
  1095. pEst->EstValueIndex = CounterIndex;
  1096. NewestValue = pAC->Pnmi.RlmtChangeCts;
  1097. OldestValue = pEst->EstValue[CounterIndex];
  1098. pEst->EstValue[CounterIndex] = NewestValue;
  1099. /*
  1100. * Calculate average. Delta stores the number of
  1101. * port switches per 28125 * 8 = 225000 ms
  1102. */
  1103. if (NewestValue >= OldestValue) {
  1104. Delta = NewestValue - OldestValue;
  1105. }
  1106. else {
  1107. /* Overflow situation */
  1108. Delta = (SK_U64)(0 - OldestValue) + NewestValue;
  1109. }
  1110. /*
  1111. * Extrapolate delta to port switches per hour.
  1112. * Estimate = Delta * (3600000 / 225000)
  1113. * = Delta * 16
  1114. * = Delta << 4
  1115. */
  1116. pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
  1117. /*
  1118. * Check if threshold is exceeded. If the threshold is
  1119. * permanently exceeded every 28125 ms an event will be
  1120. * generated to remind the user of this condition.
  1121. */
  1122. if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
  1123. (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
  1124. pAC->Pnmi.RlmtChangeThreshold)) {
  1125. QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
  1126. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1127. }
  1128. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  1129. SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
  1130. 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
  1131. EventParam);
  1132. break;
  1133. case SK_PNMI_EVT_CLEAR_COUNTER:
  1134. /*
  1135. * Param.Para32[0] contains the NetIndex (0 ..1).
  1136. * Param.Para32[1] is reserved, contains -1.
  1137. */
  1138. NetIndex = (SK_U32)Param.Para32[0];
  1139. #ifdef DEBUG
  1140. if (NetIndex >= pAC->Rlmt.NumNets) {
  1141. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1142. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
  1143. NetIndex));
  1144. return (0);
  1145. }
  1146. #endif /* DEBUG */
  1147. /*
  1148. * Set all counters and timestamps to zero.
  1149. * The according NetIndex is required as a
  1150. * parameter of the event.
  1151. */
  1152. ResetCounter(pAC, IoC, NetIndex);
  1153. break;
  1154. case SK_PNMI_EVT_XMAC_RESET:
  1155. /*
  1156. * To grant continuous counter values store the current
  1157. * XMAC statistic values to the entries 1..n of the
  1158. * CounterOffset array. XMAC Errata #2
  1159. */
  1160. #ifdef DEBUG
  1161. if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
  1162. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1163. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
  1164. (unsigned int)Param.Para64));
  1165. return (0);
  1166. }
  1167. #endif
  1168. PhysPortIndex = (unsigned int)Param.Para64;
  1169. /*
  1170. * Update XMAC statistic to get fresh values
  1171. */
  1172. Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
  1173. if (Ret != SK_PNMI_ERR_OK) {
  1174. SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
  1175. return (0);
  1176. }
  1177. /*
  1178. * Increment semaphore to indicate that an update was
  1179. * already done
  1180. */
  1181. pAC->Pnmi.MacUpdatedFlag ++;
  1182. for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
  1183. CounterIndex ++) {
  1184. if (!StatAddr[CounterIndex][MacType].GetOffset) {
  1185. continue;
  1186. }
  1187. pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
  1188. GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
  1189. pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
  1190. }
  1191. pAC->Pnmi.MacUpdatedFlag --;
  1192. break;
  1193. case SK_PNMI_EVT_RLMT_PORT_UP:
  1194. PhysPortIndex = (unsigned int)Param.Para32[0];
  1195. #ifdef DEBUG
  1196. if (PhysPortIndex >= SK_MAX_MACS) {
  1197. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1198. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
  1199. " wrong, PhysPortIndex=%d\n", PhysPortIndex));
  1200. return (0);
  1201. }
  1202. #endif /* DEBUG */
  1203. /*
  1204. * Store a trap message in the trap buffer and generate an event for
  1205. * user space applications with the SK_DRIVER_SENDEVENT macro.
  1206. */
  1207. QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
  1208. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1209. /* Bugfix for XMAC errata (#10620)*/
  1210. if (MacType == SK_MAC_XMAC) {
  1211. /* Add incremental difference to offset (#10620)*/
  1212. (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
  1213. XM_RXE_SHT_ERR, &Val32);
  1214. Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
  1215. CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
  1216. pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
  1217. Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
  1218. }
  1219. /* Tell VctStatus() that a link was up meanwhile. */
  1220. pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
  1221. break;
  1222. case SK_PNMI_EVT_RLMT_PORT_DOWN:
  1223. PhysPortIndex = (unsigned int)Param.Para32[0];
  1224. #ifdef DEBUG
  1225. if (PhysPortIndex >= SK_MAX_MACS) {
  1226. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1227. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
  1228. " wrong, PhysPortIndex=%d\n", PhysPortIndex));
  1229. return (0);
  1230. }
  1231. #endif /* DEBUG */
  1232. /*
  1233. * Store a trap message in the trap buffer and generate an event for
  1234. * user space applications with the SK_DRIVER_SENDEVENT macro.
  1235. */
  1236. QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
  1237. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1238. /* Bugfix #10620 - get zero level for incremental difference */
  1239. if (MacType == SK_MAC_XMAC) {
  1240. (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
  1241. XM_RXE_SHT_ERR, &Val32);
  1242. pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
  1243. (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
  1244. CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
  1245. }
  1246. break;
  1247. case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
  1248. PhysPortIndex = (unsigned int)Param.Para32[0];
  1249. NetIndex = (SK_U32)Param.Para32[1];
  1250. #ifdef DEBUG
  1251. if (PhysPortIndex >= SK_MAX_MACS) {
  1252. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1253. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
  1254. PhysPortIndex));
  1255. }
  1256. if (NetIndex >= pAC->Rlmt.NumNets) {
  1257. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1258. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
  1259. NetIndex));
  1260. }
  1261. #endif /* DEBUG */
  1262. /*
  1263. * For now, ignore event if NetIndex != 0.
  1264. */
  1265. if (Param.Para32[1] != 0) {
  1266. return (0);
  1267. }
  1268. /*
  1269. * Nothing to do if port is already inactive
  1270. */
  1271. if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  1272. return (0);
  1273. }
  1274. /*
  1275. * Update statistic counters to calculate new offset for the virtual
  1276. * port and increment semaphore to indicate that an update was already
  1277. * done.
  1278. */
  1279. if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
  1280. SK_PNMI_ERR_OK) {
  1281. SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
  1282. return (0);
  1283. }
  1284. pAC->Pnmi.MacUpdatedFlag ++;
  1285. /*
  1286. * Calculate new counter offset for virtual port to grant continous
  1287. * counting on port switches. The virtual port consists of all currently
  1288. * active ports. The port down event indicates that a port is removed
  1289. * from the virtual port. Therefore add the counter value of the removed
  1290. * port to the CounterOffset for the virtual port to grant the same
  1291. * counter value.
  1292. */
  1293. for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
  1294. CounterIndex ++) {
  1295. if (!StatAddr[CounterIndex][MacType].GetOffset) {
  1296. continue;
  1297. }
  1298. Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
  1299. pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
  1300. }
  1301. /*
  1302. * Set port to inactive
  1303. */
  1304. pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
  1305. pAC->Pnmi.MacUpdatedFlag --;
  1306. break;
  1307. case SK_PNMI_EVT_RLMT_ACTIVE_UP:
  1308. PhysPortIndex = (unsigned int)Param.Para32[0];
  1309. NetIndex = (SK_U32)Param.Para32[1];
  1310. #ifdef DEBUG
  1311. if (PhysPortIndex >= SK_MAX_MACS) {
  1312. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1313. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
  1314. PhysPortIndex));
  1315. }
  1316. if (NetIndex >= pAC->Rlmt.NumNets) {
  1317. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
  1318. ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
  1319. NetIndex));
  1320. }
  1321. #endif /* DEBUG */
  1322. /*
  1323. * For now, ignore event if NetIndex != 0.
  1324. */
  1325. if (Param.Para32[1] != 0) {
  1326. return (0);
  1327. }
  1328. /*
  1329. * Nothing to do if port is already active
  1330. */
  1331. if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  1332. return (0);
  1333. }
  1334. /*
  1335. * Statistic maintenance
  1336. */
  1337. pAC->Pnmi.RlmtChangeCts ++;
  1338. pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
  1339. /*
  1340. * Store a trap message in the trap buffer and generate an event for
  1341. * user space applications with the SK_DRIVER_SENDEVENT macro.
  1342. */
  1343. QueueRlmtNewMacTrap(pAC, PhysPortIndex);
  1344. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1345. /*
  1346. * Update statistic counters to calculate new offset for the virtual
  1347. * port and increment semaphore to indicate that an update was
  1348. * already done.
  1349. */
  1350. if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
  1351. SK_PNMI_ERR_OK) {
  1352. SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
  1353. return (0);
  1354. }
  1355. pAC->Pnmi.MacUpdatedFlag ++;
  1356. /*
  1357. * Calculate new counter offset for virtual port to grant continous
  1358. * counting on port switches. A new port is added to the virtual port.
  1359. * Therefore substract the counter value of the new port from the
  1360. * CounterOffset for the virtual port to grant the same value.
  1361. */
  1362. for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
  1363. CounterIndex ++) {
  1364. if (!StatAddr[CounterIndex][MacType].GetOffset) {
  1365. continue;
  1366. }
  1367. Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
  1368. pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
  1369. }
  1370. /* Set port to active */
  1371. pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
  1372. pAC->Pnmi.MacUpdatedFlag --;
  1373. break;
  1374. case SK_PNMI_EVT_RLMT_SEGMENTATION:
  1375. /*
  1376. * Para.Para32[0] contains the NetIndex.
  1377. */
  1378. /*
  1379. * Store a trap message in the trap buffer and generate an event for
  1380. * user space applications with the SK_DRIVER_SENDEVENT macro.
  1381. */
  1382. QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
  1383. (void)SK_DRIVER_SENDEVENT(pAC, IoC);
  1384. break;
  1385. case SK_PNMI_EVT_RLMT_SET_NETS:
  1386. /*
  1387. * Param.Para32[0] contains the number of Nets.
  1388. * Param.Para32[1] is reserved, contains -1.
  1389. */
  1390. /*
  1391. * Check number of nets
  1392. */
  1393. MaxNetNumber = pAC->GIni.GIMacsFound;
  1394. if (((unsigned int)Param.Para32[0] < 1)
  1395. || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
  1396. return (SK_PNMI_ERR_UNKNOWN_NET);
  1397. }
  1398. if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
  1399. pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
  1400. }
  1401. else { /* dual net mode */
  1402. pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
  1403. }
  1404. break;
  1405. case SK_PNMI_EVT_VCT_RESET:
  1406. PhysPortIndex = Param.Para32[0];
  1407. pPrt = &pAC->GIni.GP[PhysPortIndex];
  1408. pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
  1409. if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
  1410. RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
  1411. if (RetCode == 2) {
  1412. /*
  1413. * VCT test is still running.
  1414. * Start VCT timer counter again.
  1415. */
  1416. SK_MEMSET((char *) &Param, 0, sizeof(Param));
  1417. Param.Para32[0] = PhysPortIndex;
  1418. Param.Para32[1] = -1;
  1419. SkTimerStart(pAC, IoC,
  1420. &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
  1421. 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
  1422. break;
  1423. }
  1424. pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
  1425. pAC->Pnmi.VctStatus[PhysPortIndex] |=
  1426. (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
  1427. /* Copy results for later use to PNMI struct. */
  1428. for (i = 0; i < 4; i++) {
  1429. if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
  1430. if ((pPrt->PMdiPairLen[i] > 35) &&
  1431. (pPrt->PMdiPairLen[i] < 0xff)) {
  1432. pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
  1433. }
  1434. }
  1435. if ((pPrt->PMdiPairLen[i] > 35) &&
  1436. (pPrt->PMdiPairLen[i] != 0xff)) {
  1437. CableLength = 1000 *
  1438. (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
  1439. }
  1440. else {
  1441. CableLength = 0;
  1442. }
  1443. pVctBackupData->PMdiPairLen[i] = CableLength;
  1444. pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
  1445. }
  1446. Param.Para32[0] = PhysPortIndex;
  1447. Param.Para32[1] = -1;
  1448. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
  1449. SkEventDispatcher(pAC, IoC);
  1450. }
  1451. break;
  1452. default:
  1453. break;
  1454. }
  1455. SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
  1456. return (0);
  1457. }
  1458. /******************************************************************************
  1459. *
  1460. * Private functions
  1461. *
  1462. */
  1463. /*****************************************************************************
  1464. *
  1465. * PnmiVar - Gets, presets, and sets single OIDs
  1466. *
  1467. * Description:
  1468. * Looks up the requested OID, calls the corresponding handler
  1469. * function, and passes the parameters with the get, preset, or
  1470. * set command. The function is called by SkGePnmiGetVar,
  1471. * SkGePnmiPreSetVar, or SkGePnmiSetVar.
  1472. *
  1473. * Returns:
  1474. * SK_PNMI_ERR_XXX. For details have a look at the description of the
  1475. * calling functions.
  1476. * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
  1477. */
  1478. PNMI_STATIC int PnmiVar(
  1479. SK_AC *pAC, /* Pointer to adapter context */
  1480. SK_IOC IoC, /* IO context handle */
  1481. int Action, /* GET/PRESET/SET action */
  1482. SK_U32 Id, /* Object ID that is to be processed */
  1483. char *pBuf, /* Buffer used for the management data transfer */
  1484. unsigned int *pLen, /* Total length of pBuf management data */
  1485. SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
  1486. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  1487. {
  1488. unsigned int TableIndex;
  1489. int Ret;
  1490. if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
  1491. *pLen = 0;
  1492. return (SK_PNMI_ERR_UNKNOWN_OID);
  1493. }
  1494. /* Check NetIndex */
  1495. if (NetIndex >= pAC->Rlmt.NumNets) {
  1496. return (SK_PNMI_ERR_UNKNOWN_NET);
  1497. }
  1498. SK_PNMI_CHECKFLAGS("PnmiVar: On call");
  1499. Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
  1500. Instance, TableIndex, NetIndex);
  1501. SK_PNMI_CHECKFLAGS("PnmiVar: On return");
  1502. return (Ret);
  1503. }
  1504. /*****************************************************************************
  1505. *
  1506. * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
  1507. *
  1508. * Description:
  1509. * The return value of the function will also be stored in
  1510. * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
  1511. * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
  1512. * checks which OIDs are able to set, and calls the handler function of
  1513. * the OID to perform the set. The return value of the function will
  1514. * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
  1515. * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
  1516. * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
  1517. *
  1518. * Returns:
  1519. * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
  1520. * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
  1521. */
  1522. PNMI_STATIC int PnmiStruct(
  1523. SK_AC *pAC, /* Pointer to adapter context */
  1524. SK_IOC IoC, /* IO context handle */
  1525. int Action, /* PRESET/SET action to be performed */
  1526. char *pBuf, /* Buffer used for the management data transfer */
  1527. unsigned int *pLen, /* Length of pBuf management data buffer */
  1528. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  1529. {
  1530. int Ret;
  1531. unsigned int TableIndex;
  1532. unsigned int DstOffset;
  1533. unsigned int Len;
  1534. unsigned int InstanceNo;
  1535. unsigned int InstanceCnt;
  1536. SK_U32 Instance;
  1537. SK_U32 Id;
  1538. /* Check if the passed buffer has the right size */
  1539. if (*pLen < SK_PNMI_STRUCT_SIZE) {
  1540. /* Check if we can return the error within the buffer */
  1541. if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
  1542. SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
  1543. (SK_U32)(-1));
  1544. }
  1545. *pLen = SK_PNMI_STRUCT_SIZE;
  1546. return (SK_PNMI_ERR_TOO_SHORT);
  1547. }
  1548. /* Check NetIndex */
  1549. if (NetIndex >= pAC->Rlmt.NumNets) {
  1550. return (SK_PNMI_ERR_UNKNOWN_NET);
  1551. }
  1552. SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
  1553. /*
  1554. * Update the values of RLMT and SIRQ and increment semaphores to
  1555. * indicate that an update was already done.
  1556. */
  1557. if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
  1558. SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
  1559. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  1560. return (Ret);
  1561. }
  1562. if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
  1563. SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
  1564. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  1565. return (Ret);
  1566. }
  1567. pAC->Pnmi.RlmtUpdatedFlag ++;
  1568. pAC->Pnmi.SirqUpdatedFlag ++;
  1569. /* Preset/Set values */
  1570. for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
  1571. if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
  1572. (IdTable[TableIndex].Access != SK_PNMI_WO)) {
  1573. continue;
  1574. }
  1575. InstanceNo = IdTable[TableIndex].InstanceNo;
  1576. Id = IdTable[TableIndex].Id;
  1577. for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
  1578. InstanceCnt ++) {
  1579. DstOffset = IdTable[TableIndex].Offset +
  1580. (InstanceCnt - 1) *
  1581. IdTable[TableIndex].StructSize;
  1582. /*
  1583. * Because VPD multiple instance variables are
  1584. * not setable we do not need to evaluate VPD
  1585. * instances. Have a look to VPD instance
  1586. * calculation in SkPnmiGetStruct().
  1587. */
  1588. Instance = (SK_U32)InstanceCnt;
  1589. /*
  1590. * Evaluate needed buffer length
  1591. */
  1592. Len = 0;
  1593. Ret = IdTable[TableIndex].Func(pAC, IoC,
  1594. SK_PNMI_GET, IdTable[TableIndex].Id,
  1595. NULL, &Len, Instance, TableIndex, NetIndex);
  1596. if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
  1597. break;
  1598. }
  1599. if (Ret != SK_PNMI_ERR_TOO_SHORT) {
  1600. pAC->Pnmi.RlmtUpdatedFlag --;
  1601. pAC->Pnmi.SirqUpdatedFlag --;
  1602. SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
  1603. SK_PNMI_SET_STAT(pBuf,
  1604. SK_PNMI_ERR_GENERAL, DstOffset);
  1605. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  1606. return (SK_PNMI_ERR_GENERAL);
  1607. }
  1608. if (Id == OID_SKGE_VPD_ACTION) {
  1609. switch (*(pBuf + DstOffset)) {
  1610. case SK_PNMI_VPD_CREATE:
  1611. Len = 3 + *(pBuf + DstOffset + 3);
  1612. break;
  1613. case SK_PNMI_VPD_DELETE:
  1614. Len = 3;
  1615. break;
  1616. default:
  1617. Len = 1;
  1618. break;
  1619. }
  1620. }
  1621. /* Call the OID handler function */
  1622. Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
  1623. IdTable[TableIndex].Id, pBuf + DstOffset,
  1624. &Len, Instance, TableIndex, NetIndex);
  1625. if (Ret != SK_PNMI_ERR_OK) {
  1626. pAC->Pnmi.RlmtUpdatedFlag --;
  1627. pAC->Pnmi.SirqUpdatedFlag --;
  1628. SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
  1629. SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
  1630. DstOffset);
  1631. *pLen = SK_PNMI_MIN_STRUCT_SIZE;
  1632. return (SK_PNMI_ERR_BAD_VALUE);
  1633. }
  1634. }
  1635. }
  1636. pAC->Pnmi.RlmtUpdatedFlag --;
  1637. pAC->Pnmi.SirqUpdatedFlag --;
  1638. SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
  1639. SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
  1640. return (SK_PNMI_ERR_OK);
  1641. }
  1642. /*****************************************************************************
  1643. *
  1644. * LookupId - Lookup an OID in the IdTable
  1645. *
  1646. * Description:
  1647. * Scans the IdTable to find the table entry of an OID.
  1648. *
  1649. * Returns:
  1650. * The table index or -1 if not found.
  1651. */
  1652. PNMI_STATIC int LookupId(
  1653. SK_U32 Id) /* Object identifier to be searched */
  1654. {
  1655. int i;
  1656. for (i = 0; i < ID_TABLE_SIZE; i++) {
  1657. if (IdTable[i].Id == Id) {
  1658. return i;
  1659. }
  1660. }
  1661. return (-1);
  1662. }
  1663. /*****************************************************************************
  1664. *
  1665. * OidStruct - Handler of OID_SKGE_ALL_DATA
  1666. *
  1667. * Description:
  1668. * This OID performs a Get/Preset/SetStruct call and returns all data
  1669. * in a SK_PNMI_STRUCT_DATA structure.
  1670. *
  1671. * Returns:
  1672. * SK_PNMI_ERR_OK The request was successfully performed.
  1673. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  1674. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  1675. * the correct data (e.g. a 32bit value is
  1676. * needed, but a 16 bit value was passed).
  1677. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  1678. * value range.
  1679. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  1680. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  1681. * exist (e.g. port instance 3 on a two port
  1682. * adapter.
  1683. */
  1684. PNMI_STATIC int OidStruct(
  1685. SK_AC *pAC, /* Pointer to adapter context */
  1686. SK_IOC IoC, /* IO context handle */
  1687. int Action, /* GET/PRESET/SET action */
  1688. SK_U32 Id, /* Object ID that is to be processed */
  1689. char *pBuf, /* Buffer used for the management data transfer */
  1690. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  1691. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  1692. unsigned int TableIndex, /* Index to the Id table */
  1693. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  1694. {
  1695. if (Id != OID_SKGE_ALL_DATA) {
  1696. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
  1697. SK_PNMI_ERR003MSG);
  1698. *pLen = 0;
  1699. return (SK_PNMI_ERR_GENERAL);
  1700. }
  1701. /*
  1702. * Check instance. We only handle single instance variables
  1703. */
  1704. if (Instance != (SK_U32)(-1) && Instance != 1) {
  1705. *pLen = 0;
  1706. return (SK_PNMI_ERR_UNKNOWN_INST);
  1707. }
  1708. switch (Action) {
  1709. case SK_PNMI_GET:
  1710. return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
  1711. case SK_PNMI_PRESET:
  1712. return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
  1713. case SK_PNMI_SET:
  1714. return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
  1715. }
  1716. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
  1717. *pLen = 0;
  1718. return (SK_PNMI_ERR_GENERAL);
  1719. }
  1720. /*****************************************************************************
  1721. *
  1722. * Perform - OID handler of OID_SKGE_ACTION
  1723. *
  1724. * Description:
  1725. * None.
  1726. *
  1727. * Returns:
  1728. * SK_PNMI_ERR_OK The request was successfully performed.
  1729. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  1730. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  1731. * the correct data (e.g. a 32bit value is
  1732. * needed, but a 16 bit value was passed).
  1733. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  1734. * value range.
  1735. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  1736. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  1737. * exist (e.g. port instance 3 on a two port
  1738. * adapter.
  1739. */
  1740. PNMI_STATIC int Perform(
  1741. SK_AC *pAC, /* Pointer to adapter context */
  1742. SK_IOC IoC, /* IO context handle */
  1743. int Action, /* GET/PRESET/SET action */
  1744. SK_U32 Id, /* Object ID that is to be processed */
  1745. char *pBuf, /* Buffer used for the management data transfer */
  1746. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  1747. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  1748. unsigned int TableIndex, /* Index to the Id table */
  1749. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  1750. {
  1751. int Ret;
  1752. SK_U32 ActionOp;
  1753. /*
  1754. * Check instance. We only handle single instance variables
  1755. */
  1756. if (Instance != (SK_U32)(-1) && Instance != 1) {
  1757. *pLen = 0;
  1758. return (SK_PNMI_ERR_UNKNOWN_INST);
  1759. }
  1760. if (*pLen < sizeof(SK_U32)) {
  1761. *pLen = sizeof(SK_U32);
  1762. return (SK_PNMI_ERR_TOO_SHORT);
  1763. }
  1764. /* Check if a get should be performed */
  1765. if (Action == SK_PNMI_GET) {
  1766. /* A get is easy. We always return the same value */
  1767. ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
  1768. SK_PNMI_STORE_U32(pBuf, ActionOp);
  1769. *pLen = sizeof(SK_U32);
  1770. return (SK_PNMI_ERR_OK);
  1771. }
  1772. /* Continue with PRESET/SET action */
  1773. if (*pLen > sizeof(SK_U32)) {
  1774. return (SK_PNMI_ERR_BAD_VALUE);
  1775. }
  1776. /* Check if the command is a known one */
  1777. SK_PNMI_READ_U32(pBuf, ActionOp);
  1778. if (*pLen > sizeof(SK_U32) ||
  1779. (ActionOp != SK_PNMI_ACT_IDLE &&
  1780. ActionOp != SK_PNMI_ACT_RESET &&
  1781. ActionOp != SK_PNMI_ACT_SELFTEST &&
  1782. ActionOp != SK_PNMI_ACT_RESETCNT)) {
  1783. *pLen = 0;
  1784. return (SK_PNMI_ERR_BAD_VALUE);
  1785. }
  1786. /* A preset ends here */
  1787. if (Action == SK_PNMI_PRESET) {
  1788. return (SK_PNMI_ERR_OK);
  1789. }
  1790. switch (ActionOp) {
  1791. case SK_PNMI_ACT_IDLE:
  1792. /* Nothing to do */
  1793. break;
  1794. case SK_PNMI_ACT_RESET:
  1795. /*
  1796. * Perform a driver reset or something that comes near
  1797. * to this.
  1798. */
  1799. Ret = SK_DRIVER_RESET(pAC, IoC);
  1800. if (Ret != 0) {
  1801. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
  1802. SK_PNMI_ERR005MSG);
  1803. return (SK_PNMI_ERR_GENERAL);
  1804. }
  1805. break;
  1806. case SK_PNMI_ACT_SELFTEST:
  1807. /*
  1808. * Perform a driver selftest or something similar to this.
  1809. * Currently this feature is not used and will probably
  1810. * implemented in another way.
  1811. */
  1812. Ret = SK_DRIVER_SELFTEST(pAC, IoC);
  1813. pAC->Pnmi.TestResult = Ret;
  1814. break;
  1815. case SK_PNMI_ACT_RESETCNT:
  1816. /* Set all counters and timestamps to zero */
  1817. ResetCounter(pAC, IoC, NetIndex);
  1818. break;
  1819. default:
  1820. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
  1821. SK_PNMI_ERR006MSG);
  1822. return (SK_PNMI_ERR_GENERAL);
  1823. }
  1824. return (SK_PNMI_ERR_OK);
  1825. }
  1826. /*****************************************************************************
  1827. *
  1828. * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
  1829. *
  1830. * Description:
  1831. * Retrieves the statistic values of the virtual port (logical
  1832. * index 0). Only special OIDs of NDIS are handled which consist
  1833. * of a 32 bit instead of a 64 bit value. The OIDs are public
  1834. * because perhaps some other platform can use them too.
  1835. *
  1836. * Returns:
  1837. * SK_PNMI_ERR_OK The request was successfully performed.
  1838. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  1839. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  1840. * the correct data (e.g. a 32bit value is
  1841. * needed, but a 16 bit value was passed).
  1842. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  1843. * exist (e.g. port instance 3 on a two port
  1844. * adapter.
  1845. */
  1846. PNMI_STATIC int Mac8023Stat(
  1847. SK_AC *pAC, /* Pointer to adapter context */
  1848. SK_IOC IoC, /* IO context handle */
  1849. int Action, /* GET/PRESET/SET action */
  1850. SK_U32 Id, /* Object ID that is to be processed */
  1851. char *pBuf, /* Buffer used for the management data transfer */
  1852. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  1853. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  1854. unsigned int TableIndex, /* Index to the Id table */
  1855. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  1856. {
  1857. int Ret;
  1858. SK_U64 StatVal;
  1859. SK_U32 StatVal32;
  1860. SK_BOOL Is64BitReq = SK_FALSE;
  1861. /*
  1862. * Only the active Mac is returned
  1863. */
  1864. if (Instance != (SK_U32)(-1) && Instance != 1) {
  1865. *pLen = 0;
  1866. return (SK_PNMI_ERR_UNKNOWN_INST);
  1867. }
  1868. /*
  1869. * Check action type
  1870. */
  1871. if (Action != SK_PNMI_GET) {
  1872. *pLen = 0;
  1873. return (SK_PNMI_ERR_READ_ONLY);
  1874. }
  1875. /* Check length */
  1876. switch (Id) {
  1877. case OID_802_3_PERMANENT_ADDRESS:
  1878. case OID_802_3_CURRENT_ADDRESS:
  1879. if (*pLen < sizeof(SK_MAC_ADDR)) {
  1880. *pLen = sizeof(SK_MAC_ADDR);
  1881. return (SK_PNMI_ERR_TOO_SHORT);
  1882. }
  1883. break;
  1884. default:
  1885. #ifndef SK_NDIS_64BIT_CTR
  1886. if (*pLen < sizeof(SK_U32)) {
  1887. *pLen = sizeof(SK_U32);
  1888. return (SK_PNMI_ERR_TOO_SHORT);
  1889. }
  1890. #else /* SK_NDIS_64BIT_CTR */
  1891. /* for compatibility, at least 32bit are required for OID */
  1892. if (*pLen < sizeof(SK_U32)) {
  1893. /*
  1894. * but indicate handling for 64bit values,
  1895. * if insufficient space is provided
  1896. */
  1897. *pLen = sizeof(SK_U64);
  1898. return (SK_PNMI_ERR_TOO_SHORT);
  1899. }
  1900. Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
  1901. #endif /* SK_NDIS_64BIT_CTR */
  1902. break;
  1903. }
  1904. /*
  1905. * Update all statistics, because we retrieve virtual MAC, which
  1906. * consists of multiple physical statistics and increment semaphore
  1907. * to indicate that an update was already done.
  1908. */
  1909. Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
  1910. if ( Ret != SK_PNMI_ERR_OK) {
  1911. *pLen = 0;
  1912. return (Ret);
  1913. }
  1914. pAC->Pnmi.MacUpdatedFlag ++;
  1915. /*
  1916. * Get value (MAC Index 0 identifies the virtual MAC)
  1917. */
  1918. switch (Id) {
  1919. case OID_802_3_PERMANENT_ADDRESS:
  1920. CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
  1921. *pLen = sizeof(SK_MAC_ADDR);
  1922. break;
  1923. case OID_802_3_CURRENT_ADDRESS:
  1924. CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
  1925. *pLen = sizeof(SK_MAC_ADDR);
  1926. break;
  1927. default:
  1928. StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
  1929. /* by default 32bit values are evaluated */
  1930. if (!Is64BitReq) {
  1931. StatVal32 = (SK_U32)StatVal;
  1932. SK_PNMI_STORE_U32(pBuf, StatVal32);
  1933. *pLen = sizeof(SK_U32);
  1934. }
  1935. else {
  1936. SK_PNMI_STORE_U64(pBuf, StatVal);
  1937. *pLen = sizeof(SK_U64);
  1938. }
  1939. break;
  1940. }
  1941. pAC->Pnmi.MacUpdatedFlag --;
  1942. return (SK_PNMI_ERR_OK);
  1943. }
  1944. /*****************************************************************************
  1945. *
  1946. * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
  1947. *
  1948. * Description:
  1949. * Retrieves the MAC statistic data.
  1950. *
  1951. * Returns:
  1952. * SK_PNMI_ERR_OK The request was successfully performed.
  1953. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  1954. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  1955. * the correct data (e.g. a 32bit value is
  1956. * needed, but a 16 bit value was passed).
  1957. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  1958. * exist (e.g. port instance 3 on a two port
  1959. * adapter.
  1960. */
  1961. PNMI_STATIC int MacPrivateStat(
  1962. SK_AC *pAC, /* Pointer to adapter context */
  1963. SK_IOC IoC, /* IO context handle */
  1964. int Action, /* GET/PRESET/SET action */
  1965. SK_U32 Id, /* Object ID that is to be processed */
  1966. char *pBuf, /* Buffer used for the management data transfer */
  1967. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  1968. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  1969. unsigned int TableIndex, /* Index to the Id table */
  1970. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  1971. {
  1972. unsigned int LogPortMax;
  1973. unsigned int LogPortIndex;
  1974. unsigned int PhysPortMax;
  1975. unsigned int Limit;
  1976. unsigned int Offset;
  1977. int MacType;
  1978. int Ret;
  1979. SK_U64 StatVal;
  1980. /* Calculate instance if wished. MAC index 0 is the virtual MAC */
  1981. PhysPortMax = pAC->GIni.GIMacsFound;
  1982. LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
  1983. MacType = pAC->GIni.GIMacType;
  1984. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
  1985. LogPortMax--;
  1986. }
  1987. if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
  1988. /* Check instance range */
  1989. if ((Instance < 1) || (Instance > LogPortMax)) {
  1990. *pLen = 0;
  1991. return (SK_PNMI_ERR_UNKNOWN_INST);
  1992. }
  1993. LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
  1994. Limit = LogPortIndex + 1;
  1995. }
  1996. else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
  1997. LogPortIndex = 0;
  1998. Limit = LogPortMax;
  1999. }
  2000. /* Check action */
  2001. if (Action != SK_PNMI_GET) {
  2002. *pLen = 0;
  2003. return (SK_PNMI_ERR_READ_ONLY);
  2004. }
  2005. /* Check length */
  2006. if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
  2007. *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
  2008. return (SK_PNMI_ERR_TOO_SHORT);
  2009. }
  2010. /*
  2011. * Update MAC statistic and increment semaphore to indicate that
  2012. * an update was already done.
  2013. */
  2014. Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
  2015. if (Ret != SK_PNMI_ERR_OK) {
  2016. *pLen = 0;
  2017. return (Ret);
  2018. }
  2019. pAC->Pnmi.MacUpdatedFlag ++;
  2020. /* Get value */
  2021. Offset = 0;
  2022. for (; LogPortIndex < Limit; LogPortIndex ++) {
  2023. switch (Id) {
  2024. /* XXX not yet implemented due to XMAC problems
  2025. case OID_SKGE_STAT_TX_UTIL:
  2026. return (SK_PNMI_ERR_GENERAL);
  2027. */
  2028. /* XXX not yet implemented due to XMAC problems
  2029. case OID_SKGE_STAT_RX_UTIL:
  2030. return (SK_PNMI_ERR_GENERAL);
  2031. */
  2032. case OID_SKGE_STAT_RX:
  2033. if (MacType == SK_MAC_GMAC) {
  2034. StatVal =
  2035. GetStatVal(pAC, IoC, LogPortIndex,
  2036. SK_PNMI_HRX_BROADCAST, NetIndex) +
  2037. GetStatVal(pAC, IoC, LogPortIndex,
  2038. SK_PNMI_HRX_MULTICAST, NetIndex) +
  2039. GetStatVal(pAC, IoC, LogPortIndex,
  2040. SK_PNMI_HRX_UNICAST, NetIndex) +
  2041. GetStatVal(pAC, IoC, LogPortIndex,
  2042. SK_PNMI_HRX_UNDERSIZE, NetIndex);
  2043. }
  2044. else {
  2045. StatVal = GetStatVal(pAC, IoC, LogPortIndex,
  2046. IdTable[TableIndex].Param, NetIndex);
  2047. }
  2048. break;
  2049. case OID_SKGE_STAT_TX:
  2050. if (MacType == SK_MAC_GMAC) {
  2051. StatVal =
  2052. GetStatVal(pAC, IoC, LogPortIndex,
  2053. SK_PNMI_HTX_BROADCAST, NetIndex) +
  2054. GetStatVal(pAC, IoC, LogPortIndex,
  2055. SK_PNMI_HTX_MULTICAST, NetIndex) +
  2056. GetStatVal(pAC, IoC, LogPortIndex,
  2057. SK_PNMI_HTX_UNICAST, NetIndex);
  2058. }
  2059. else {
  2060. StatVal = GetStatVal(pAC, IoC, LogPortIndex,
  2061. IdTable[TableIndex].Param, NetIndex);
  2062. }
  2063. break;
  2064. default:
  2065. StatVal = GetStatVal(pAC, IoC, LogPortIndex,
  2066. IdTable[TableIndex].Param, NetIndex);
  2067. }
  2068. SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
  2069. Offset += sizeof(SK_U64);
  2070. }
  2071. *pLen = Offset;
  2072. pAC->Pnmi.MacUpdatedFlag --;
  2073. return (SK_PNMI_ERR_OK);
  2074. }
  2075. /*****************************************************************************
  2076. *
  2077. * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
  2078. *
  2079. * Description:
  2080. * Get/Presets/Sets the current and factory MAC address. The MAC
  2081. * address of the virtual port, which is reported to the OS, may
  2082. * not be changed, but the physical ones. A set to the virtual port
  2083. * will be ignored. No error should be reported because otherwise
  2084. * a multiple instance set (-1) would always fail.
  2085. *
  2086. * Returns:
  2087. * SK_PNMI_ERR_OK The request was successfully performed.
  2088. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  2089. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  2090. * the correct data (e.g. a 32bit value is
  2091. * needed, but a 16 bit value was passed).
  2092. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  2093. * value range.
  2094. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  2095. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  2096. * exist (e.g. port instance 3 on a two port
  2097. * adapter.
  2098. */
  2099. PNMI_STATIC int Addr(
  2100. SK_AC *pAC, /* Pointer to adapter context */
  2101. SK_IOC IoC, /* IO context handle */
  2102. int Action, /* GET/PRESET/SET action */
  2103. SK_U32 Id, /* Object ID that is to be processed */
  2104. char *pBuf, /* Buffer used for the management data transfer */
  2105. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  2106. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  2107. unsigned int TableIndex, /* Index to the Id table */
  2108. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  2109. {
  2110. int Ret;
  2111. unsigned int LogPortMax;
  2112. unsigned int PhysPortMax;
  2113. unsigned int LogPortIndex;
  2114. unsigned int PhysPortIndex;
  2115. unsigned int Limit;
  2116. unsigned int Offset = 0;
  2117. /*
  2118. * Calculate instance if wished. MAC index 0 is the virtual
  2119. * MAC.
  2120. */
  2121. PhysPortMax = pAC->GIni.GIMacsFound;
  2122. LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
  2123. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
  2124. LogPortMax--;
  2125. }
  2126. if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
  2127. /* Check instance range */
  2128. if ((Instance < 1) || (Instance > LogPortMax)) {
  2129. *pLen = 0;
  2130. return (SK_PNMI_ERR_UNKNOWN_INST);
  2131. }
  2132. LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
  2133. Limit = LogPortIndex + 1;
  2134. }
  2135. else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
  2136. LogPortIndex = 0;
  2137. Limit = LogPortMax;
  2138. }
  2139. /*
  2140. * Perform Action
  2141. */
  2142. if (Action == SK_PNMI_GET) {
  2143. /* Check length */
  2144. if (*pLen < (Limit - LogPortIndex) * 6) {
  2145. *pLen = (Limit - LogPortIndex) * 6;
  2146. return (SK_PNMI_ERR_TOO_SHORT);
  2147. }
  2148. /*
  2149. * Get value
  2150. */
  2151. for (; LogPortIndex < Limit; LogPortIndex ++) {
  2152. switch (Id) {
  2153. case OID_SKGE_PHYS_CUR_ADDR:
  2154. if (LogPortIndex == 0) {
  2155. CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
  2156. }
  2157. else {
  2158. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
  2159. CopyMac(pBuf + Offset,
  2160. &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
  2161. }
  2162. Offset += 6;
  2163. break;
  2164. case OID_SKGE_PHYS_FAC_ADDR:
  2165. if (LogPortIndex == 0) {
  2166. CopyMac(pBuf + Offset,
  2167. &pAC->Addr.Net[NetIndex].PermanentMacAddress);
  2168. }
  2169. else {
  2170. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  2171. pAC, LogPortIndex);
  2172. CopyMac(pBuf + Offset,
  2173. &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
  2174. }
  2175. Offset += 6;
  2176. break;
  2177. default:
  2178. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
  2179. SK_PNMI_ERR008MSG);
  2180. *pLen = 0;
  2181. return (SK_PNMI_ERR_GENERAL);
  2182. }
  2183. }
  2184. *pLen = Offset;
  2185. }
  2186. else {
  2187. /*
  2188. * The logical MAC address may not be changed only
  2189. * the physical ones
  2190. */
  2191. if (Id == OID_SKGE_PHYS_FAC_ADDR) {
  2192. *pLen = 0;
  2193. return (SK_PNMI_ERR_READ_ONLY);
  2194. }
  2195. /*
  2196. * Only the current address may be changed
  2197. */
  2198. if (Id != OID_SKGE_PHYS_CUR_ADDR) {
  2199. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
  2200. SK_PNMI_ERR009MSG);
  2201. *pLen = 0;
  2202. return (SK_PNMI_ERR_GENERAL);
  2203. }
  2204. /* Check length */
  2205. if (*pLen < (Limit - LogPortIndex) * 6) {
  2206. *pLen = (Limit - LogPortIndex) * 6;
  2207. return (SK_PNMI_ERR_TOO_SHORT);
  2208. }
  2209. if (*pLen > (Limit - LogPortIndex) * 6) {
  2210. *pLen = 0;
  2211. return (SK_PNMI_ERR_BAD_VALUE);
  2212. }
  2213. /*
  2214. * Check Action
  2215. */
  2216. if (Action == SK_PNMI_PRESET) {
  2217. *pLen = 0;
  2218. return (SK_PNMI_ERR_OK);
  2219. }
  2220. /*
  2221. * Set OID_SKGE_MAC_CUR_ADDR
  2222. */
  2223. for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
  2224. /*
  2225. * A set to virtual port and set of broadcast
  2226. * address will be ignored
  2227. */
  2228. if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
  2229. "\xff\xff\xff\xff\xff\xff", 6) == 0) {
  2230. continue;
  2231. }
  2232. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
  2233. LogPortIndex);
  2234. Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
  2235. (SK_MAC_ADDR *)(pBuf + Offset),
  2236. (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
  2237. SK_ADDR_PHYSICAL_ADDRESS));
  2238. if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
  2239. return (SK_PNMI_ERR_GENERAL);
  2240. }
  2241. }
  2242. *pLen = Offset;
  2243. }
  2244. return (SK_PNMI_ERR_OK);
  2245. }
  2246. /*****************************************************************************
  2247. *
  2248. * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
  2249. *
  2250. * Description:
  2251. * Retrieves the statistic values of the CSUM module. The CSUM data
  2252. * structure must be available in the SK_AC even if the CSUM module
  2253. * is not included, because PNMI reads the statistic data from the
  2254. * CSUM part of SK_AC directly.
  2255. *
  2256. * Returns:
  2257. * SK_PNMI_ERR_OK The request was successfully performed.
  2258. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  2259. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  2260. * the correct data (e.g. a 32bit value is
  2261. * needed, but a 16 bit value was passed).
  2262. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  2263. * exist (e.g. port instance 3 on a two port
  2264. * adapter.
  2265. */
  2266. PNMI_STATIC int CsumStat(
  2267. SK_AC *pAC, /* Pointer to adapter context */
  2268. SK_IOC IoC, /* IO context handle */
  2269. int Action, /* GET/PRESET/SET action */
  2270. SK_U32 Id, /* Object ID that is to be processed */
  2271. char *pBuf, /* Buffer used for the management data transfer */
  2272. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  2273. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  2274. unsigned int TableIndex, /* Index to the Id table */
  2275. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  2276. {
  2277. unsigned int Index;
  2278. unsigned int Limit;
  2279. unsigned int Offset = 0;
  2280. SK_U64 StatVal;
  2281. /*
  2282. * Calculate instance if wished
  2283. */
  2284. if (Instance != (SK_U32)(-1)) {
  2285. if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
  2286. *pLen = 0;
  2287. return (SK_PNMI_ERR_UNKNOWN_INST);
  2288. }
  2289. Index = (unsigned int)Instance - 1;
  2290. Limit = Index + 1;
  2291. }
  2292. else {
  2293. Index = 0;
  2294. Limit = SKCS_NUM_PROTOCOLS;
  2295. }
  2296. /*
  2297. * Check action
  2298. */
  2299. if (Action != SK_PNMI_GET) {
  2300. *pLen = 0;
  2301. return (SK_PNMI_ERR_READ_ONLY);
  2302. }
  2303. /* Check length */
  2304. if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
  2305. *pLen = (Limit - Index) * sizeof(SK_U64);
  2306. return (SK_PNMI_ERR_TOO_SHORT);
  2307. }
  2308. /*
  2309. * Get value
  2310. */
  2311. for (; Index < Limit; Index ++) {
  2312. switch (Id) {
  2313. case OID_SKGE_CHKSM_RX_OK_CTS:
  2314. StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
  2315. break;
  2316. case OID_SKGE_CHKSM_RX_UNABLE_CTS:
  2317. StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
  2318. break;
  2319. case OID_SKGE_CHKSM_RX_ERR_CTS:
  2320. StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
  2321. break;
  2322. case OID_SKGE_CHKSM_TX_OK_CTS:
  2323. StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
  2324. break;
  2325. case OID_SKGE_CHKSM_TX_UNABLE_CTS:
  2326. StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
  2327. break;
  2328. default:
  2329. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
  2330. SK_PNMI_ERR010MSG);
  2331. *pLen = 0;
  2332. return (SK_PNMI_ERR_GENERAL);
  2333. }
  2334. SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
  2335. Offset += sizeof(SK_U64);
  2336. }
  2337. /*
  2338. * Store used buffer space
  2339. */
  2340. *pLen = Offset;
  2341. return (SK_PNMI_ERR_OK);
  2342. }
  2343. /*****************************************************************************
  2344. *
  2345. * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
  2346. *
  2347. * Description:
  2348. * Retrieves the statistic values of the I2C module, which handles
  2349. * the temperature and voltage sensors.
  2350. *
  2351. * Returns:
  2352. * SK_PNMI_ERR_OK The request was successfully performed.
  2353. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  2354. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  2355. * the correct data (e.g. a 32bit value is
  2356. * needed, but a 16 bit value was passed).
  2357. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  2358. * exist (e.g. port instance 3 on a two port
  2359. * adapter.
  2360. */
  2361. PNMI_STATIC int SensorStat(
  2362. SK_AC *pAC, /* Pointer to adapter context */
  2363. SK_IOC IoC, /* IO context handle */
  2364. int Action, /* GET/PRESET/SET action */
  2365. SK_U32 Id, /* Object ID that is to be processed */
  2366. char *pBuf, /* Buffer used for the management data transfer */
  2367. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  2368. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  2369. unsigned int TableIndex, /* Index to the Id table */
  2370. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  2371. {
  2372. unsigned int i;
  2373. unsigned int Index;
  2374. unsigned int Limit;
  2375. unsigned int Offset;
  2376. unsigned int Len;
  2377. SK_U32 Val32;
  2378. SK_U64 Val64;
  2379. /*
  2380. * Calculate instance if wished
  2381. */
  2382. if ((Instance != (SK_U32)(-1))) {
  2383. if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
  2384. *pLen = 0;
  2385. return (SK_PNMI_ERR_UNKNOWN_INST);
  2386. }
  2387. Index = (unsigned int)Instance -1;
  2388. Limit = (unsigned int)Instance;
  2389. }
  2390. else {
  2391. Index = 0;
  2392. Limit = (unsigned int) pAC->I2c.MaxSens;
  2393. }
  2394. /*
  2395. * Check action
  2396. */
  2397. if (Action != SK_PNMI_GET) {
  2398. *pLen = 0;
  2399. return (SK_PNMI_ERR_READ_ONLY);
  2400. }
  2401. /* Check length */
  2402. switch (Id) {
  2403. case OID_SKGE_SENSOR_VALUE:
  2404. case OID_SKGE_SENSOR_WAR_THRES_LOW:
  2405. case OID_SKGE_SENSOR_WAR_THRES_UPP:
  2406. case OID_SKGE_SENSOR_ERR_THRES_LOW:
  2407. case OID_SKGE_SENSOR_ERR_THRES_UPP:
  2408. if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
  2409. *pLen = (Limit - Index) * sizeof(SK_U32);
  2410. return (SK_PNMI_ERR_TOO_SHORT);
  2411. }
  2412. break;
  2413. case OID_SKGE_SENSOR_DESCR:
  2414. for (Offset = 0, i = Index; i < Limit; i ++) {
  2415. Len = (unsigned int)
  2416. SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
  2417. if (Len >= SK_PNMI_STRINGLEN2) {
  2418. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
  2419. SK_PNMI_ERR011MSG);
  2420. *pLen = 0;
  2421. return (SK_PNMI_ERR_GENERAL);
  2422. }
  2423. Offset += Len;
  2424. }
  2425. if (*pLen < Offset) {
  2426. *pLen = Offset;
  2427. return (SK_PNMI_ERR_TOO_SHORT);
  2428. }
  2429. break;
  2430. case OID_SKGE_SENSOR_INDEX:
  2431. case OID_SKGE_SENSOR_TYPE:
  2432. case OID_SKGE_SENSOR_STATUS:
  2433. if (*pLen < Limit - Index) {
  2434. *pLen = Limit - Index;
  2435. return (SK_PNMI_ERR_TOO_SHORT);
  2436. }
  2437. break;
  2438. case OID_SKGE_SENSOR_WAR_CTS:
  2439. case OID_SKGE_SENSOR_WAR_TIME:
  2440. case OID_SKGE_SENSOR_ERR_CTS:
  2441. case OID_SKGE_SENSOR_ERR_TIME:
  2442. if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
  2443. *pLen = (Limit - Index) * sizeof(SK_U64);
  2444. return (SK_PNMI_ERR_TOO_SHORT);
  2445. }
  2446. break;
  2447. default:
  2448. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
  2449. SK_PNMI_ERR012MSG);
  2450. *pLen = 0;
  2451. return (SK_PNMI_ERR_GENERAL);
  2452. }
  2453. /*
  2454. * Get value
  2455. */
  2456. for (Offset = 0; Index < Limit; Index ++) {
  2457. switch (Id) {
  2458. case OID_SKGE_SENSOR_INDEX:
  2459. *(pBuf + Offset) = (char)Index;
  2460. Offset += sizeof(char);
  2461. break;
  2462. case OID_SKGE_SENSOR_DESCR:
  2463. Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
  2464. SK_MEMCPY(pBuf + Offset + 1,
  2465. pAC->I2c.SenTable[Index].SenDesc, Len);
  2466. *(pBuf + Offset) = (char)Len;
  2467. Offset += Len + 1;
  2468. break;
  2469. case OID_SKGE_SENSOR_TYPE:
  2470. *(pBuf + Offset) =
  2471. (char)pAC->I2c.SenTable[Index].SenType;
  2472. Offset += sizeof(char);
  2473. break;
  2474. case OID_SKGE_SENSOR_VALUE:
  2475. Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
  2476. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  2477. Offset += sizeof(SK_U32);
  2478. break;
  2479. case OID_SKGE_SENSOR_WAR_THRES_LOW:
  2480. Val32 = (SK_U32)pAC->I2c.SenTable[Index].
  2481. SenThreWarnLow;
  2482. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  2483. Offset += sizeof(SK_U32);
  2484. break;
  2485. case OID_SKGE_SENSOR_WAR_THRES_UPP:
  2486. Val32 = (SK_U32)pAC->I2c.SenTable[Index].
  2487. SenThreWarnHigh;
  2488. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  2489. Offset += sizeof(SK_U32);
  2490. break;
  2491. case OID_SKGE_SENSOR_ERR_THRES_LOW:
  2492. Val32 = (SK_U32)pAC->I2c.SenTable[Index].
  2493. SenThreErrLow;
  2494. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  2495. Offset += sizeof(SK_U32);
  2496. break;
  2497. case OID_SKGE_SENSOR_ERR_THRES_UPP:
  2498. Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
  2499. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  2500. Offset += sizeof(SK_U32);
  2501. break;
  2502. case OID_SKGE_SENSOR_STATUS:
  2503. *(pBuf + Offset) =
  2504. (char)pAC->I2c.SenTable[Index].SenErrFlag;
  2505. Offset += sizeof(char);
  2506. break;
  2507. case OID_SKGE_SENSOR_WAR_CTS:
  2508. Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
  2509. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  2510. Offset += sizeof(SK_U64);
  2511. break;
  2512. case OID_SKGE_SENSOR_ERR_CTS:
  2513. Val64 = pAC->I2c.SenTable[Index].SenErrCts;
  2514. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  2515. Offset += sizeof(SK_U64);
  2516. break;
  2517. case OID_SKGE_SENSOR_WAR_TIME:
  2518. Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
  2519. SenBegWarnTS);
  2520. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  2521. Offset += sizeof(SK_U64);
  2522. break;
  2523. case OID_SKGE_SENSOR_ERR_TIME:
  2524. Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
  2525. SenBegErrTS);
  2526. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  2527. Offset += sizeof(SK_U64);
  2528. break;
  2529. default:
  2530. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
  2531. ("SensorStat: Unknown OID should be handled before"));
  2532. return (SK_PNMI_ERR_GENERAL);
  2533. }
  2534. }
  2535. /*
  2536. * Store used buffer space
  2537. */
  2538. *pLen = Offset;
  2539. return (SK_PNMI_ERR_OK);
  2540. }
  2541. /*****************************************************************************
  2542. *
  2543. * Vpd - OID handler function of OID_SKGE_VPD_XXX
  2544. *
  2545. * Description:
  2546. * Get/preset/set of VPD data. As instance the name of a VPD key
  2547. * can be passed. The Instance parameter is a SK_U32 and can be
  2548. * used as a string buffer for the VPD key, because their maximum
  2549. * length is 4 byte.
  2550. *
  2551. * Returns:
  2552. * SK_PNMI_ERR_OK The request was successfully performed.
  2553. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  2554. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  2555. * the correct data (e.g. a 32bit value is
  2556. * needed, but a 16 bit value was passed).
  2557. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  2558. * value range.
  2559. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  2560. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  2561. * exist (e.g. port instance 3 on a two port
  2562. * adapter.
  2563. */
  2564. PNMI_STATIC int Vpd(
  2565. SK_AC *pAC, /* Pointer to adapter context */
  2566. SK_IOC IoC, /* IO context handle */
  2567. int Action, /* GET/PRESET/SET action */
  2568. SK_U32 Id, /* Object ID that is to be processed */
  2569. char *pBuf, /* Buffer used for the management data transfer */
  2570. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  2571. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  2572. unsigned int TableIndex, /* Index to the Id table */
  2573. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  2574. {
  2575. SK_VPD_STATUS *pVpdStatus;
  2576. unsigned int BufLen;
  2577. char Buf[256];
  2578. char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
  2579. char KeyStr[SK_PNMI_VPD_KEY_SIZE];
  2580. unsigned int KeyNo;
  2581. unsigned int Offset;
  2582. unsigned int Index;
  2583. unsigned int FirstIndex;
  2584. unsigned int LastIndex;
  2585. unsigned int Len;
  2586. int Ret;
  2587. SK_U32 Val32;
  2588. /*
  2589. * Get array of all currently stored VPD keys
  2590. */
  2591. Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
  2592. if (Ret != SK_PNMI_ERR_OK) {
  2593. *pLen = 0;
  2594. return (Ret);
  2595. }
  2596. /*
  2597. * If instance is not -1, try to find the requested VPD key for
  2598. * the multiple instance variables. The other OIDs as for example
  2599. * OID VPD_ACTION are single instance variables and must be
  2600. * handled separatly.
  2601. */
  2602. FirstIndex = 0;
  2603. LastIndex = KeyNo;
  2604. if ((Instance != (SK_U32)(-1))) {
  2605. if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
  2606. Id == OID_SKGE_VPD_ACCESS) {
  2607. SK_STRNCPY(KeyStr, (char *)&Instance, 4);
  2608. KeyStr[4] = 0;
  2609. for (Index = 0; Index < KeyNo; Index ++) {
  2610. if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
  2611. FirstIndex = Index;
  2612. LastIndex = Index+1;
  2613. break;
  2614. }
  2615. }
  2616. if (Index == KeyNo) {
  2617. *pLen = 0;
  2618. return (SK_PNMI_ERR_UNKNOWN_INST);
  2619. }
  2620. }
  2621. else if (Instance != 1) {
  2622. *pLen = 0;
  2623. return (SK_PNMI_ERR_UNKNOWN_INST);
  2624. }
  2625. }
  2626. /*
  2627. * Get value, if a query should be performed
  2628. */
  2629. if (Action == SK_PNMI_GET) {
  2630. switch (Id) {
  2631. case OID_SKGE_VPD_FREE_BYTES:
  2632. /* Check length of buffer */
  2633. if (*pLen < sizeof(SK_U32)) {
  2634. *pLen = sizeof(SK_U32);
  2635. return (SK_PNMI_ERR_TOO_SHORT);
  2636. }
  2637. /* Get number of free bytes */
  2638. pVpdStatus = VpdStat(pAC, IoC);
  2639. if (pVpdStatus == NULL) {
  2640. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
  2641. SK_PNMI_ERR017MSG);
  2642. *pLen = 0;
  2643. return (SK_PNMI_ERR_GENERAL);
  2644. }
  2645. if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
  2646. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
  2647. SK_PNMI_ERR018MSG);
  2648. *pLen = 0;
  2649. return (SK_PNMI_ERR_GENERAL);
  2650. }
  2651. Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
  2652. SK_PNMI_STORE_U32(pBuf, Val32);
  2653. *pLen = sizeof(SK_U32);
  2654. break;
  2655. case OID_SKGE_VPD_ENTRIES_LIST:
  2656. /* Check length */
  2657. for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
  2658. Len += SK_STRLEN(KeyArr[Index]) + 1;
  2659. }
  2660. if (*pLen < Len) {
  2661. *pLen = Len;
  2662. return (SK_PNMI_ERR_TOO_SHORT);
  2663. }
  2664. /* Get value */
  2665. *(pBuf) = (char)Len - 1;
  2666. for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
  2667. Len = SK_STRLEN(KeyArr[Index]);
  2668. SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
  2669. Offset += Len;
  2670. if (Index < KeyNo - 1) {
  2671. *(pBuf + Offset) = ' ';
  2672. Offset ++;
  2673. }
  2674. }
  2675. *pLen = Offset;
  2676. break;
  2677. case OID_SKGE_VPD_ENTRIES_NUMBER:
  2678. /* Check length */
  2679. if (*pLen < sizeof(SK_U32)) {
  2680. *pLen = sizeof(SK_U32);
  2681. return (SK_PNMI_ERR_TOO_SHORT);
  2682. }
  2683. Val32 = (SK_U32)KeyNo;
  2684. SK_PNMI_STORE_U32(pBuf, Val32);
  2685. *pLen = sizeof(SK_U32);
  2686. break;
  2687. case OID_SKGE_VPD_KEY:
  2688. /* Check buffer length, if it is large enough */
  2689. for (Len = 0, Index = FirstIndex;
  2690. Index < LastIndex; Index ++) {
  2691. Len += SK_STRLEN(KeyArr[Index]) + 1;
  2692. }
  2693. if (*pLen < Len) {
  2694. *pLen = Len;
  2695. return (SK_PNMI_ERR_TOO_SHORT);
  2696. }
  2697. /*
  2698. * Get the key to an intermediate buffer, because
  2699. * we have to prepend a length byte.
  2700. */
  2701. for (Offset = 0, Index = FirstIndex;
  2702. Index < LastIndex; Index ++) {
  2703. Len = SK_STRLEN(KeyArr[Index]);
  2704. *(pBuf + Offset) = (char)Len;
  2705. SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
  2706. Len);
  2707. Offset += Len + 1;
  2708. }
  2709. *pLen = Offset;
  2710. break;
  2711. case OID_SKGE_VPD_VALUE:
  2712. /* Check the buffer length if it is large enough */
  2713. for (Offset = 0, Index = FirstIndex;
  2714. Index < LastIndex; Index ++) {
  2715. BufLen = 256;
  2716. if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
  2717. (int *)&BufLen) > 0 ||
  2718. BufLen >= SK_PNMI_VPD_DATALEN) {
  2719. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  2720. SK_PNMI_ERR021,
  2721. SK_PNMI_ERR021MSG);
  2722. return (SK_PNMI_ERR_GENERAL);
  2723. }
  2724. Offset += BufLen + 1;
  2725. }
  2726. if (*pLen < Offset) {
  2727. *pLen = Offset;
  2728. return (SK_PNMI_ERR_TOO_SHORT);
  2729. }
  2730. /*
  2731. * Get the value to an intermediate buffer, because
  2732. * we have to prepend a length byte.
  2733. */
  2734. for (Offset = 0, Index = FirstIndex;
  2735. Index < LastIndex; Index ++) {
  2736. BufLen = 256;
  2737. if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
  2738. (int *)&BufLen) > 0 ||
  2739. BufLen >= SK_PNMI_VPD_DATALEN) {
  2740. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  2741. SK_PNMI_ERR022,
  2742. SK_PNMI_ERR022MSG);
  2743. *pLen = 0;
  2744. return (SK_PNMI_ERR_GENERAL);
  2745. }
  2746. *(pBuf + Offset) = (char)BufLen;
  2747. SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
  2748. Offset += BufLen + 1;
  2749. }
  2750. *pLen = Offset;
  2751. break;
  2752. case OID_SKGE_VPD_ACCESS:
  2753. if (*pLen < LastIndex - FirstIndex) {
  2754. *pLen = LastIndex - FirstIndex;
  2755. return (SK_PNMI_ERR_TOO_SHORT);
  2756. }
  2757. for (Offset = 0, Index = FirstIndex;
  2758. Index < LastIndex; Index ++) {
  2759. if (VpdMayWrite(KeyArr[Index])) {
  2760. *(pBuf + Offset) = SK_PNMI_VPD_RW;
  2761. }
  2762. else {
  2763. *(pBuf + Offset) = SK_PNMI_VPD_RO;
  2764. }
  2765. Offset ++;
  2766. }
  2767. *pLen = Offset;
  2768. break;
  2769. case OID_SKGE_VPD_ACTION:
  2770. Offset = LastIndex - FirstIndex;
  2771. if (*pLen < Offset) {
  2772. *pLen = Offset;
  2773. return (SK_PNMI_ERR_TOO_SHORT);
  2774. }
  2775. SK_MEMSET(pBuf, 0, Offset);
  2776. *pLen = Offset;
  2777. break;
  2778. default:
  2779. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
  2780. SK_PNMI_ERR023MSG);
  2781. *pLen = 0;
  2782. return (SK_PNMI_ERR_GENERAL);
  2783. }
  2784. }
  2785. else {
  2786. /* The only OID which can be set is VPD_ACTION */
  2787. if (Id != OID_SKGE_VPD_ACTION) {
  2788. if (Id == OID_SKGE_VPD_FREE_BYTES ||
  2789. Id == OID_SKGE_VPD_ENTRIES_LIST ||
  2790. Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
  2791. Id == OID_SKGE_VPD_KEY ||
  2792. Id == OID_SKGE_VPD_VALUE ||
  2793. Id == OID_SKGE_VPD_ACCESS) {
  2794. *pLen = 0;
  2795. return (SK_PNMI_ERR_READ_ONLY);
  2796. }
  2797. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
  2798. SK_PNMI_ERR024MSG);
  2799. *pLen = 0;
  2800. return (SK_PNMI_ERR_GENERAL);
  2801. }
  2802. /*
  2803. * From this point we handle VPD_ACTION. Check the buffer
  2804. * length. It should at least have the size of one byte.
  2805. */
  2806. if (*pLen < 1) {
  2807. *pLen = 1;
  2808. return (SK_PNMI_ERR_TOO_SHORT);
  2809. }
  2810. /*
  2811. * The first byte contains the VPD action type we should
  2812. * perform.
  2813. */
  2814. switch (*pBuf) {
  2815. case SK_PNMI_VPD_IGNORE:
  2816. /* Nothing to do */
  2817. break;
  2818. case SK_PNMI_VPD_CREATE:
  2819. /*
  2820. * We have to create a new VPD entry or we modify
  2821. * an existing one. Check first the buffer length.
  2822. */
  2823. if (*pLen < 4) {
  2824. *pLen = 4;
  2825. return (SK_PNMI_ERR_TOO_SHORT);
  2826. }
  2827. KeyStr[0] = pBuf[1];
  2828. KeyStr[1] = pBuf[2];
  2829. KeyStr[2] = 0;
  2830. /*
  2831. * Is the entry writable or does it belong to the
  2832. * read-only area?
  2833. */
  2834. if (!VpdMayWrite(KeyStr)) {
  2835. *pLen = 0;
  2836. return (SK_PNMI_ERR_BAD_VALUE);
  2837. }
  2838. Offset = (int)pBuf[3] & 0xFF;
  2839. SK_MEMCPY(Buf, pBuf + 4, Offset);
  2840. Buf[Offset] = 0;
  2841. /* A preset ends here */
  2842. if (Action == SK_PNMI_PRESET) {
  2843. return (SK_PNMI_ERR_OK);
  2844. }
  2845. /* Write the new entry or modify an existing one */
  2846. Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
  2847. if (Ret == SK_PNMI_VPD_NOWRITE ) {
  2848. *pLen = 0;
  2849. return (SK_PNMI_ERR_BAD_VALUE);
  2850. }
  2851. else if (Ret != SK_PNMI_VPD_OK) {
  2852. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
  2853. SK_PNMI_ERR025MSG);
  2854. *pLen = 0;
  2855. return (SK_PNMI_ERR_GENERAL);
  2856. }
  2857. /*
  2858. * Perform an update of the VPD data. This is
  2859. * not mandantory, but just to be sure.
  2860. */
  2861. Ret = VpdUpdate(pAC, IoC);
  2862. if (Ret != SK_PNMI_VPD_OK) {
  2863. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
  2864. SK_PNMI_ERR026MSG);
  2865. *pLen = 0;
  2866. return (SK_PNMI_ERR_GENERAL);
  2867. }
  2868. break;
  2869. case SK_PNMI_VPD_DELETE:
  2870. /* Check if the buffer size is plausible */
  2871. if (*pLen < 3) {
  2872. *pLen = 3;
  2873. return (SK_PNMI_ERR_TOO_SHORT);
  2874. }
  2875. if (*pLen > 3) {
  2876. *pLen = 0;
  2877. return (SK_PNMI_ERR_BAD_VALUE);
  2878. }
  2879. KeyStr[0] = pBuf[1];
  2880. KeyStr[1] = pBuf[2];
  2881. KeyStr[2] = 0;
  2882. /* Find the passed key in the array */
  2883. for (Index = 0; Index < KeyNo; Index ++) {
  2884. if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
  2885. break;
  2886. }
  2887. }
  2888. /*
  2889. * If we cannot find the key it is wrong, so we
  2890. * return an appropriate error value.
  2891. */
  2892. if (Index == KeyNo) {
  2893. *pLen = 0;
  2894. return (SK_PNMI_ERR_BAD_VALUE);
  2895. }
  2896. if (Action == SK_PNMI_PRESET) {
  2897. return (SK_PNMI_ERR_OK);
  2898. }
  2899. /* Ok, you wanted it and you will get it */
  2900. Ret = VpdDelete(pAC, IoC, KeyStr);
  2901. if (Ret != SK_PNMI_VPD_OK) {
  2902. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
  2903. SK_PNMI_ERR027MSG);
  2904. *pLen = 0;
  2905. return (SK_PNMI_ERR_GENERAL);
  2906. }
  2907. /*
  2908. * Perform an update of the VPD data. This is
  2909. * not mandantory, but just to be sure.
  2910. */
  2911. Ret = VpdUpdate(pAC, IoC);
  2912. if (Ret != SK_PNMI_VPD_OK) {
  2913. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
  2914. SK_PNMI_ERR028MSG);
  2915. *pLen = 0;
  2916. return (SK_PNMI_ERR_GENERAL);
  2917. }
  2918. break;
  2919. default:
  2920. *pLen = 0;
  2921. return (SK_PNMI_ERR_BAD_VALUE);
  2922. }
  2923. }
  2924. return (SK_PNMI_ERR_OK);
  2925. }
  2926. /*****************************************************************************
  2927. *
  2928. * General - OID handler function of various single instance OIDs
  2929. *
  2930. * Description:
  2931. * The code is simple. No description necessary.
  2932. *
  2933. * Returns:
  2934. * SK_PNMI_ERR_OK The request was successfully performed.
  2935. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  2936. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  2937. * the correct data (e.g. a 32bit value is
  2938. * needed, but a 16 bit value was passed).
  2939. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  2940. * exist (e.g. port instance 3 on a two port
  2941. * adapter.
  2942. */
  2943. PNMI_STATIC int General(
  2944. SK_AC *pAC, /* Pointer to adapter context */
  2945. SK_IOC IoC, /* IO context handle */
  2946. int Action, /* GET/PRESET/SET action */
  2947. SK_U32 Id, /* Object ID that is to be processed */
  2948. char *pBuf, /* Buffer used for the management data transfer */
  2949. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  2950. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  2951. unsigned int TableIndex, /* Index to the Id table */
  2952. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  2953. {
  2954. int Ret;
  2955. unsigned int Index;
  2956. unsigned int Len;
  2957. unsigned int Offset;
  2958. unsigned int Val;
  2959. SK_U8 Val8;
  2960. SK_U16 Val16;
  2961. SK_U32 Val32;
  2962. SK_U64 Val64;
  2963. SK_U64 Val64RxHwErrs = 0;
  2964. SK_U64 Val64TxHwErrs = 0;
  2965. SK_BOOL Is64BitReq = SK_FALSE;
  2966. char Buf[256];
  2967. int MacType;
  2968. /*
  2969. * Check instance. We only handle single instance variables.
  2970. */
  2971. if (Instance != (SK_U32)(-1) && Instance != 1) {
  2972. *pLen = 0;
  2973. return (SK_PNMI_ERR_UNKNOWN_INST);
  2974. }
  2975. /*
  2976. * Check action. We only allow get requests.
  2977. */
  2978. if (Action != SK_PNMI_GET) {
  2979. *pLen = 0;
  2980. return (SK_PNMI_ERR_READ_ONLY);
  2981. }
  2982. MacType = pAC->GIni.GIMacType;
  2983. /*
  2984. * Check length for the various supported OIDs
  2985. */
  2986. switch (Id) {
  2987. case OID_GEN_XMIT_ERROR:
  2988. case OID_GEN_RCV_ERROR:
  2989. case OID_GEN_RCV_NO_BUFFER:
  2990. #ifndef SK_NDIS_64BIT_CTR
  2991. if (*pLen < sizeof(SK_U32)) {
  2992. *pLen = sizeof(SK_U32);
  2993. return (SK_PNMI_ERR_TOO_SHORT);
  2994. }
  2995. #else /* SK_NDIS_64BIT_CTR */
  2996. /*
  2997. * for compatibility, at least 32bit are required for oid
  2998. */
  2999. if (*pLen < sizeof(SK_U32)) {
  3000. /*
  3001. * but indicate handling for 64bit values,
  3002. * if insufficient space is provided
  3003. */
  3004. *pLen = sizeof(SK_U64);
  3005. return (SK_PNMI_ERR_TOO_SHORT);
  3006. }
  3007. Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
  3008. #endif /* SK_NDIS_64BIT_CTR */
  3009. break;
  3010. case OID_SKGE_PORT_NUMBER:
  3011. case OID_SKGE_DEVICE_TYPE:
  3012. case OID_SKGE_RESULT:
  3013. case OID_SKGE_RLMT_MONITOR_NUMBER:
  3014. case OID_GEN_TRANSMIT_QUEUE_LENGTH:
  3015. case OID_SKGE_TRAP_NUMBER:
  3016. case OID_SKGE_MDB_VERSION:
  3017. case OID_SKGE_BOARDLEVEL:
  3018. case OID_SKGE_CHIPID:
  3019. case OID_SKGE_RAMSIZE:
  3020. if (*pLen < sizeof(SK_U32)) {
  3021. *pLen = sizeof(SK_U32);
  3022. return (SK_PNMI_ERR_TOO_SHORT);
  3023. }
  3024. break;
  3025. case OID_SKGE_CHIPSET:
  3026. if (*pLen < sizeof(SK_U16)) {
  3027. *pLen = sizeof(SK_U16);
  3028. return (SK_PNMI_ERR_TOO_SHORT);
  3029. }
  3030. break;
  3031. case OID_SKGE_BUS_TYPE:
  3032. case OID_SKGE_BUS_SPEED:
  3033. case OID_SKGE_BUS_WIDTH:
  3034. case OID_SKGE_SENSOR_NUMBER:
  3035. case OID_SKGE_CHKSM_NUMBER:
  3036. case OID_SKGE_VAUXAVAIL:
  3037. if (*pLen < sizeof(SK_U8)) {
  3038. *pLen = sizeof(SK_U8);
  3039. return (SK_PNMI_ERR_TOO_SHORT);
  3040. }
  3041. break;
  3042. case OID_SKGE_TX_SW_QUEUE_LEN:
  3043. case OID_SKGE_TX_SW_QUEUE_MAX:
  3044. case OID_SKGE_TX_RETRY:
  3045. case OID_SKGE_RX_INTR_CTS:
  3046. case OID_SKGE_TX_INTR_CTS:
  3047. case OID_SKGE_RX_NO_BUF_CTS:
  3048. case OID_SKGE_TX_NO_BUF_CTS:
  3049. case OID_SKGE_TX_USED_DESCR_NO:
  3050. case OID_SKGE_RX_DELIVERED_CTS:
  3051. case OID_SKGE_RX_OCTETS_DELIV_CTS:
  3052. case OID_SKGE_RX_HW_ERROR_CTS:
  3053. case OID_SKGE_TX_HW_ERROR_CTS:
  3054. case OID_SKGE_IN_ERRORS_CTS:
  3055. case OID_SKGE_OUT_ERROR_CTS:
  3056. case OID_SKGE_ERR_RECOVERY_CTS:
  3057. case OID_SKGE_SYSUPTIME:
  3058. if (*pLen < sizeof(SK_U64)) {
  3059. *pLen = sizeof(SK_U64);
  3060. return (SK_PNMI_ERR_TOO_SHORT);
  3061. }
  3062. break;
  3063. default:
  3064. /* Checked later */
  3065. break;
  3066. }
  3067. /* Update statistic */
  3068. if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
  3069. Id == OID_SKGE_TX_HW_ERROR_CTS ||
  3070. Id == OID_SKGE_IN_ERRORS_CTS ||
  3071. Id == OID_SKGE_OUT_ERROR_CTS ||
  3072. Id == OID_GEN_XMIT_ERROR ||
  3073. Id == OID_GEN_RCV_ERROR) {
  3074. /* Force the XMAC to update its statistic counters and
  3075. * Increment semaphore to indicate that an update was
  3076. * already done.
  3077. */
  3078. Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
  3079. if (Ret != SK_PNMI_ERR_OK) {
  3080. *pLen = 0;
  3081. return (Ret);
  3082. }
  3083. pAC->Pnmi.MacUpdatedFlag ++;
  3084. /*
  3085. * Some OIDs consist of multiple hardware counters. Those
  3086. * values which are contained in all of them will be added
  3087. * now.
  3088. */
  3089. switch (Id) {
  3090. case OID_SKGE_RX_HW_ERROR_CTS:
  3091. case OID_SKGE_IN_ERRORS_CTS:
  3092. case OID_GEN_RCV_ERROR:
  3093. Val64RxHwErrs =
  3094. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
  3095. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
  3096. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
  3097. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
  3098. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
  3099. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
  3100. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
  3101. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
  3102. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
  3103. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
  3104. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
  3105. GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
  3106. break;
  3107. case OID_SKGE_TX_HW_ERROR_CTS:
  3108. case OID_SKGE_OUT_ERROR_CTS:
  3109. case OID_GEN_XMIT_ERROR:
  3110. Val64TxHwErrs =
  3111. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
  3112. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
  3113. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
  3114. GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
  3115. break;
  3116. }
  3117. }
  3118. /*
  3119. * Retrieve value
  3120. */
  3121. switch (Id) {
  3122. case OID_SKGE_SUPPORTED_LIST:
  3123. Len = ID_TABLE_SIZE * sizeof(SK_U32);
  3124. if (*pLen < Len) {
  3125. *pLen = Len;
  3126. return (SK_PNMI_ERR_TOO_SHORT);
  3127. }
  3128. for (Offset = 0, Index = 0; Offset < Len;
  3129. Offset += sizeof(SK_U32), Index ++) {
  3130. Val32 = (SK_U32)IdTable[Index].Id;
  3131. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  3132. }
  3133. *pLen = Len;
  3134. break;
  3135. case OID_SKGE_BOARDLEVEL:
  3136. Val32 = (SK_U32)pAC->GIni.GILevel;
  3137. SK_PNMI_STORE_U32(pBuf, Val32);
  3138. *pLen = sizeof(SK_U32);
  3139. break;
  3140. case OID_SKGE_PORT_NUMBER:
  3141. Val32 = (SK_U32)pAC->GIni.GIMacsFound;
  3142. SK_PNMI_STORE_U32(pBuf, Val32);
  3143. *pLen = sizeof(SK_U32);
  3144. break;
  3145. case OID_SKGE_DEVICE_TYPE:
  3146. Val32 = (SK_U32)pAC->Pnmi.DeviceType;
  3147. SK_PNMI_STORE_U32(pBuf, Val32);
  3148. *pLen = sizeof(SK_U32);
  3149. break;
  3150. case OID_SKGE_DRIVER_DESCR:
  3151. if (pAC->Pnmi.pDriverDescription == NULL) {
  3152. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
  3153. SK_PNMI_ERR007MSG);
  3154. *pLen = 0;
  3155. return (SK_PNMI_ERR_GENERAL);
  3156. }
  3157. Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
  3158. if (Len > SK_PNMI_STRINGLEN1) {
  3159. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
  3160. SK_PNMI_ERR029MSG);
  3161. *pLen = 0;
  3162. return (SK_PNMI_ERR_GENERAL);
  3163. }
  3164. if (*pLen < Len) {
  3165. *pLen = Len;
  3166. return (SK_PNMI_ERR_TOO_SHORT);
  3167. }
  3168. *pBuf = (char)(Len - 1);
  3169. SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
  3170. *pLen = Len;
  3171. break;
  3172. case OID_SKGE_DRIVER_VERSION:
  3173. if (pAC->Pnmi.pDriverVersion == NULL) {
  3174. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
  3175. SK_PNMI_ERR030MSG);
  3176. *pLen = 0;
  3177. return (SK_PNMI_ERR_GENERAL);
  3178. }
  3179. Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
  3180. if (Len > SK_PNMI_STRINGLEN1) {
  3181. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
  3182. SK_PNMI_ERR031MSG);
  3183. *pLen = 0;
  3184. return (SK_PNMI_ERR_GENERAL);
  3185. }
  3186. if (*pLen < Len) {
  3187. *pLen = Len;
  3188. return (SK_PNMI_ERR_TOO_SHORT);
  3189. }
  3190. *pBuf = (char)(Len - 1);
  3191. SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
  3192. *pLen = Len;
  3193. break;
  3194. case OID_SKGE_DRIVER_RELDATE:
  3195. if (pAC->Pnmi.pDriverReleaseDate == NULL) {
  3196. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
  3197. SK_PNMI_ERR053MSG);
  3198. *pLen = 0;
  3199. return (SK_PNMI_ERR_GENERAL);
  3200. }
  3201. Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
  3202. if (Len > SK_PNMI_STRINGLEN1) {
  3203. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
  3204. SK_PNMI_ERR054MSG);
  3205. *pLen = 0;
  3206. return (SK_PNMI_ERR_GENERAL);
  3207. }
  3208. if (*pLen < Len) {
  3209. *pLen = Len;
  3210. return (SK_PNMI_ERR_TOO_SHORT);
  3211. }
  3212. *pBuf = (char)(Len - 1);
  3213. SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
  3214. *pLen = Len;
  3215. break;
  3216. case OID_SKGE_DRIVER_FILENAME:
  3217. if (pAC->Pnmi.pDriverFileName == NULL) {
  3218. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
  3219. SK_PNMI_ERR055MSG);
  3220. *pLen = 0;
  3221. return (SK_PNMI_ERR_GENERAL);
  3222. }
  3223. Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
  3224. if (Len > SK_PNMI_STRINGLEN1) {
  3225. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
  3226. SK_PNMI_ERR056MSG);
  3227. *pLen = 0;
  3228. return (SK_PNMI_ERR_GENERAL);
  3229. }
  3230. if (*pLen < Len) {
  3231. *pLen = Len;
  3232. return (SK_PNMI_ERR_TOO_SHORT);
  3233. }
  3234. *pBuf = (char)(Len - 1);
  3235. SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
  3236. *pLen = Len;
  3237. break;
  3238. case OID_SKGE_HW_DESCR:
  3239. /*
  3240. * The hardware description is located in the VPD. This
  3241. * query may move to the initialisation routine. But
  3242. * the VPD data is cached and therefore a call here
  3243. * will not make much difference.
  3244. */
  3245. Len = 256;
  3246. if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
  3247. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
  3248. SK_PNMI_ERR032MSG);
  3249. *pLen = 0;
  3250. return (SK_PNMI_ERR_GENERAL);
  3251. }
  3252. Len ++;
  3253. if (Len > SK_PNMI_STRINGLEN1) {
  3254. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
  3255. SK_PNMI_ERR033MSG);
  3256. *pLen = 0;
  3257. return (SK_PNMI_ERR_GENERAL);
  3258. }
  3259. if (*pLen < Len) {
  3260. *pLen = Len;
  3261. return (SK_PNMI_ERR_TOO_SHORT);
  3262. }
  3263. *pBuf = (char)(Len - 1);
  3264. SK_MEMCPY(pBuf + 1, Buf, Len - 1);
  3265. *pLen = Len;
  3266. break;
  3267. case OID_SKGE_HW_VERSION:
  3268. /* Oh, I love to do some string manipulation */
  3269. if (*pLen < 5) {
  3270. *pLen = 5;
  3271. return (SK_PNMI_ERR_TOO_SHORT);
  3272. }
  3273. Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
  3274. pBuf[0] = 4;
  3275. pBuf[1] = 'v';
  3276. pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
  3277. pBuf[3] = '.';
  3278. pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
  3279. *pLen = 5;
  3280. break;
  3281. case OID_SKGE_CHIPSET:
  3282. Val16 = pAC->Pnmi.Chipset;
  3283. SK_PNMI_STORE_U16(pBuf, Val16);
  3284. *pLen = sizeof(SK_U16);
  3285. break;
  3286. case OID_SKGE_CHIPID:
  3287. Val32 = pAC->GIni.GIChipId;
  3288. SK_PNMI_STORE_U32(pBuf, Val32);
  3289. *pLen = sizeof(SK_U32);
  3290. break;
  3291. case OID_SKGE_RAMSIZE:
  3292. Val32 = pAC->GIni.GIRamSize;
  3293. SK_PNMI_STORE_U32(pBuf, Val32);
  3294. *pLen = sizeof(SK_U32);
  3295. break;
  3296. case OID_SKGE_VAUXAVAIL:
  3297. *pBuf = (char) pAC->GIni.GIVauxAvail;
  3298. *pLen = sizeof(char);
  3299. break;
  3300. case OID_SKGE_BUS_TYPE:
  3301. *pBuf = (char) SK_PNMI_BUS_PCI;
  3302. *pLen = sizeof(char);
  3303. break;
  3304. case OID_SKGE_BUS_SPEED:
  3305. *pBuf = pAC->Pnmi.PciBusSpeed;
  3306. *pLen = sizeof(char);
  3307. break;
  3308. case OID_SKGE_BUS_WIDTH:
  3309. *pBuf = pAC->Pnmi.PciBusWidth;
  3310. *pLen = sizeof(char);
  3311. break;
  3312. case OID_SKGE_RESULT:
  3313. Val32 = pAC->Pnmi.TestResult;
  3314. SK_PNMI_STORE_U32(pBuf, Val32);
  3315. *pLen = sizeof(SK_U32);
  3316. break;
  3317. case OID_SKGE_SENSOR_NUMBER:
  3318. *pBuf = (char)pAC->I2c.MaxSens;
  3319. *pLen = sizeof(char);
  3320. break;
  3321. case OID_SKGE_CHKSM_NUMBER:
  3322. *pBuf = SKCS_NUM_PROTOCOLS;
  3323. *pLen = sizeof(char);
  3324. break;
  3325. case OID_SKGE_TRAP_NUMBER:
  3326. GetTrapQueueLen(pAC, &Len, &Val);
  3327. Val32 = (SK_U32)Val;
  3328. SK_PNMI_STORE_U32(pBuf, Val32);
  3329. *pLen = sizeof(SK_U32);
  3330. break;
  3331. case OID_SKGE_TRAP:
  3332. GetTrapQueueLen(pAC, &Len, &Val);
  3333. if (*pLen < Len) {
  3334. *pLen = Len;
  3335. return (SK_PNMI_ERR_TOO_SHORT);
  3336. }
  3337. CopyTrapQueue(pAC, pBuf);
  3338. *pLen = Len;
  3339. break;
  3340. case OID_SKGE_RLMT_MONITOR_NUMBER:
  3341. /* XXX Not yet implemented by RLMT therefore we return zero elements */
  3342. Val32 = 0;
  3343. SK_PNMI_STORE_U32(pBuf, Val32);
  3344. *pLen = sizeof(SK_U32);
  3345. break;
  3346. case OID_SKGE_TX_SW_QUEUE_LEN:
  3347. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3348. if (MacType == SK_MAC_XMAC) {
  3349. /* Dual net mode */
  3350. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3351. Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
  3352. }
  3353. /* Single net mode */
  3354. else {
  3355. Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
  3356. pAC->Pnmi.BufPort[1].TxSwQueueLen;
  3357. }
  3358. }
  3359. else {
  3360. /* Dual net mode */
  3361. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3362. Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
  3363. }
  3364. /* Single net mode */
  3365. else {
  3366. Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
  3367. pAC->Pnmi.Port[1].TxSwQueueLen;
  3368. }
  3369. }
  3370. SK_PNMI_STORE_U64(pBuf, Val64);
  3371. *pLen = sizeof(SK_U64);
  3372. break;
  3373. case OID_SKGE_TX_SW_QUEUE_MAX:
  3374. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3375. if (MacType == SK_MAC_XMAC) {
  3376. /* Dual net mode */
  3377. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3378. Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
  3379. }
  3380. /* Single net mode */
  3381. else {
  3382. Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
  3383. pAC->Pnmi.BufPort[1].TxSwQueueMax;
  3384. }
  3385. }
  3386. else {
  3387. /* Dual net mode */
  3388. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3389. Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
  3390. }
  3391. /* Single net mode */
  3392. else {
  3393. Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
  3394. pAC->Pnmi.Port[1].TxSwQueueMax;
  3395. }
  3396. }
  3397. SK_PNMI_STORE_U64(pBuf, Val64);
  3398. *pLen = sizeof(SK_U64);
  3399. break;
  3400. case OID_SKGE_TX_RETRY:
  3401. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3402. if (MacType == SK_MAC_XMAC) {
  3403. /* Dual net mode */
  3404. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3405. Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
  3406. }
  3407. /* Single net mode */
  3408. else {
  3409. Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
  3410. pAC->Pnmi.BufPort[1].TxRetryCts;
  3411. }
  3412. }
  3413. else {
  3414. /* Dual net mode */
  3415. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3416. Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
  3417. }
  3418. /* Single net mode */
  3419. else {
  3420. Val64 = pAC->Pnmi.Port[0].TxRetryCts +
  3421. pAC->Pnmi.Port[1].TxRetryCts;
  3422. }
  3423. }
  3424. SK_PNMI_STORE_U64(pBuf, Val64);
  3425. *pLen = sizeof(SK_U64);
  3426. break;
  3427. case OID_SKGE_RX_INTR_CTS:
  3428. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3429. if (MacType == SK_MAC_XMAC) {
  3430. /* Dual net mode */
  3431. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3432. Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
  3433. }
  3434. /* Single net mode */
  3435. else {
  3436. Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
  3437. pAC->Pnmi.BufPort[1].RxIntrCts;
  3438. }
  3439. }
  3440. else {
  3441. /* Dual net mode */
  3442. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3443. Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
  3444. }
  3445. /* Single net mode */
  3446. else {
  3447. Val64 = pAC->Pnmi.Port[0].RxIntrCts +
  3448. pAC->Pnmi.Port[1].RxIntrCts;
  3449. }
  3450. }
  3451. SK_PNMI_STORE_U64(pBuf, Val64);
  3452. *pLen = sizeof(SK_U64);
  3453. break;
  3454. case OID_SKGE_TX_INTR_CTS:
  3455. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3456. if (MacType == SK_MAC_XMAC) {
  3457. /* Dual net mode */
  3458. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3459. Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
  3460. }
  3461. /* Single net mode */
  3462. else {
  3463. Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
  3464. pAC->Pnmi.BufPort[1].TxIntrCts;
  3465. }
  3466. }
  3467. else {
  3468. /* Dual net mode */
  3469. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3470. Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
  3471. }
  3472. /* Single net mode */
  3473. else {
  3474. Val64 = pAC->Pnmi.Port[0].TxIntrCts +
  3475. pAC->Pnmi.Port[1].TxIntrCts;
  3476. }
  3477. }
  3478. SK_PNMI_STORE_U64(pBuf, Val64);
  3479. *pLen = sizeof(SK_U64);
  3480. break;
  3481. case OID_SKGE_RX_NO_BUF_CTS:
  3482. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3483. if (MacType == SK_MAC_XMAC) {
  3484. /* Dual net mode */
  3485. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3486. Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
  3487. }
  3488. /* Single net mode */
  3489. else {
  3490. Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
  3491. pAC->Pnmi.BufPort[1].RxNoBufCts;
  3492. }
  3493. }
  3494. else {
  3495. /* Dual net mode */
  3496. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3497. Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  3498. }
  3499. /* Single net mode */
  3500. else {
  3501. Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
  3502. pAC->Pnmi.Port[1].RxNoBufCts;
  3503. }
  3504. }
  3505. SK_PNMI_STORE_U64(pBuf, Val64);
  3506. *pLen = sizeof(SK_U64);
  3507. break;
  3508. case OID_SKGE_TX_NO_BUF_CTS:
  3509. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3510. if (MacType == SK_MAC_XMAC) {
  3511. /* Dual net mode */
  3512. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3513. Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
  3514. }
  3515. /* Single net mode */
  3516. else {
  3517. Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
  3518. pAC->Pnmi.BufPort[1].TxNoBufCts;
  3519. }
  3520. }
  3521. else {
  3522. /* Dual net mode */
  3523. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3524. Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
  3525. }
  3526. /* Single net mode */
  3527. else {
  3528. Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
  3529. pAC->Pnmi.Port[1].TxNoBufCts;
  3530. }
  3531. }
  3532. SK_PNMI_STORE_U64(pBuf, Val64);
  3533. *pLen = sizeof(SK_U64);
  3534. break;
  3535. case OID_SKGE_TX_USED_DESCR_NO:
  3536. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3537. if (MacType == SK_MAC_XMAC) {
  3538. /* Dual net mode */
  3539. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3540. Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
  3541. }
  3542. /* Single net mode */
  3543. else {
  3544. Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
  3545. pAC->Pnmi.BufPort[1].TxUsedDescrNo;
  3546. }
  3547. }
  3548. else {
  3549. /* Dual net mode */
  3550. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3551. Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
  3552. }
  3553. /* Single net mode */
  3554. else {
  3555. Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
  3556. pAC->Pnmi.Port[1].TxUsedDescrNo;
  3557. }
  3558. }
  3559. SK_PNMI_STORE_U64(pBuf, Val64);
  3560. *pLen = sizeof(SK_U64);
  3561. break;
  3562. case OID_SKGE_RX_DELIVERED_CTS:
  3563. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3564. if (MacType == SK_MAC_XMAC) {
  3565. /* Dual net mode */
  3566. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3567. Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
  3568. }
  3569. /* Single net mode */
  3570. else {
  3571. Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
  3572. pAC->Pnmi.BufPort[1].RxDeliveredCts;
  3573. }
  3574. }
  3575. else {
  3576. /* Dual net mode */
  3577. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3578. Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
  3579. }
  3580. /* Single net mode */
  3581. else {
  3582. Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
  3583. pAC->Pnmi.Port[1].RxDeliveredCts;
  3584. }
  3585. }
  3586. SK_PNMI_STORE_U64(pBuf, Val64);
  3587. *pLen = sizeof(SK_U64);
  3588. break;
  3589. case OID_SKGE_RX_OCTETS_DELIV_CTS:
  3590. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3591. if (MacType == SK_MAC_XMAC) {
  3592. /* Dual net mode */
  3593. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3594. Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
  3595. }
  3596. /* Single net mode */
  3597. else {
  3598. Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
  3599. pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
  3600. }
  3601. }
  3602. else {
  3603. /* Dual net mode */
  3604. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3605. Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
  3606. }
  3607. /* Single net mode */
  3608. else {
  3609. Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
  3610. pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
  3611. }
  3612. }
  3613. SK_PNMI_STORE_U64(pBuf, Val64);
  3614. *pLen = sizeof(SK_U64);
  3615. break;
  3616. case OID_SKGE_RX_HW_ERROR_CTS:
  3617. SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
  3618. *pLen = sizeof(SK_U64);
  3619. break;
  3620. case OID_SKGE_TX_HW_ERROR_CTS:
  3621. SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
  3622. *pLen = sizeof(SK_U64);
  3623. break;
  3624. case OID_SKGE_IN_ERRORS_CTS:
  3625. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3626. if (MacType == SK_MAC_XMAC) {
  3627. /* Dual net mode */
  3628. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3629. Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
  3630. }
  3631. /* Single net mode */
  3632. else {
  3633. Val64 = Val64RxHwErrs +
  3634. pAC->Pnmi.BufPort[0].RxNoBufCts +
  3635. pAC->Pnmi.BufPort[1].RxNoBufCts;
  3636. }
  3637. }
  3638. else {
  3639. /* Dual net mode */
  3640. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3641. Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  3642. }
  3643. /* Single net mode */
  3644. else {
  3645. Val64 = Val64RxHwErrs +
  3646. pAC->Pnmi.Port[0].RxNoBufCts +
  3647. pAC->Pnmi.Port[1].RxNoBufCts;
  3648. }
  3649. }
  3650. SK_PNMI_STORE_U64(pBuf, Val64);
  3651. *pLen = sizeof(SK_U64);
  3652. break;
  3653. case OID_SKGE_OUT_ERROR_CTS:
  3654. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3655. if (MacType == SK_MAC_XMAC) {
  3656. /* Dual net mode */
  3657. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3658. Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
  3659. }
  3660. /* Single net mode */
  3661. else {
  3662. Val64 = Val64TxHwErrs +
  3663. pAC->Pnmi.BufPort[0].TxNoBufCts +
  3664. pAC->Pnmi.BufPort[1].TxNoBufCts;
  3665. }
  3666. }
  3667. else {
  3668. /* Dual net mode */
  3669. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3670. Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
  3671. }
  3672. /* Single net mode */
  3673. else {
  3674. Val64 = Val64TxHwErrs +
  3675. pAC->Pnmi.Port[0].TxNoBufCts +
  3676. pAC->Pnmi.Port[1].TxNoBufCts;
  3677. }
  3678. }
  3679. SK_PNMI_STORE_U64(pBuf, Val64);
  3680. *pLen = sizeof(SK_U64);
  3681. break;
  3682. case OID_SKGE_ERR_RECOVERY_CTS:
  3683. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3684. if (MacType == SK_MAC_XMAC) {
  3685. /* Dual net mode */
  3686. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3687. Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
  3688. }
  3689. /* Single net mode */
  3690. else {
  3691. Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
  3692. pAC->Pnmi.BufPort[1].ErrRecoveryCts;
  3693. }
  3694. }
  3695. else {
  3696. /* Dual net mode */
  3697. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  3698. Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
  3699. }
  3700. /* Single net mode */
  3701. else {
  3702. Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
  3703. pAC->Pnmi.Port[1].ErrRecoveryCts;
  3704. }
  3705. }
  3706. SK_PNMI_STORE_U64(pBuf, Val64);
  3707. *pLen = sizeof(SK_U64);
  3708. break;
  3709. case OID_SKGE_SYSUPTIME:
  3710. Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
  3711. Val64 -= pAC->Pnmi.StartUpTime;
  3712. SK_PNMI_STORE_U64(pBuf, Val64);
  3713. *pLen = sizeof(SK_U64);
  3714. break;
  3715. case OID_SKGE_MDB_VERSION:
  3716. Val32 = SK_PNMI_MDB_VERSION;
  3717. SK_PNMI_STORE_U32(pBuf, Val32);
  3718. *pLen = sizeof(SK_U32);
  3719. break;
  3720. case OID_GEN_RCV_ERROR:
  3721. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3722. if (MacType == SK_MAC_XMAC) {
  3723. Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
  3724. }
  3725. else {
  3726. Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  3727. }
  3728. /*
  3729. * by default 32bit values are evaluated
  3730. */
  3731. if (!Is64BitReq) {
  3732. Val32 = (SK_U32)Val64;
  3733. SK_PNMI_STORE_U32(pBuf, Val32);
  3734. *pLen = sizeof(SK_U32);
  3735. }
  3736. else {
  3737. SK_PNMI_STORE_U64(pBuf, Val64);
  3738. *pLen = sizeof(SK_U64);
  3739. }
  3740. break;
  3741. case OID_GEN_XMIT_ERROR:
  3742. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3743. if (MacType == SK_MAC_XMAC) {
  3744. Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
  3745. }
  3746. else {
  3747. Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
  3748. }
  3749. /*
  3750. * by default 32bit values are evaluated
  3751. */
  3752. if (!Is64BitReq) {
  3753. Val32 = (SK_U32)Val64;
  3754. SK_PNMI_STORE_U32(pBuf, Val32);
  3755. *pLen = sizeof(SK_U32);
  3756. }
  3757. else {
  3758. SK_PNMI_STORE_U64(pBuf, Val64);
  3759. *pLen = sizeof(SK_U64);
  3760. }
  3761. break;
  3762. case OID_GEN_RCV_NO_BUFFER:
  3763. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  3764. if (MacType == SK_MAC_XMAC) {
  3765. Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
  3766. }
  3767. else {
  3768. Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
  3769. }
  3770. /*
  3771. * by default 32bit values are evaluated
  3772. */
  3773. if (!Is64BitReq) {
  3774. Val32 = (SK_U32)Val64;
  3775. SK_PNMI_STORE_U32(pBuf, Val32);
  3776. *pLen = sizeof(SK_U32);
  3777. }
  3778. else {
  3779. SK_PNMI_STORE_U64(pBuf, Val64);
  3780. *pLen = sizeof(SK_U64);
  3781. }
  3782. break;
  3783. case OID_GEN_TRANSMIT_QUEUE_LENGTH:
  3784. Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
  3785. SK_PNMI_STORE_U32(pBuf, Val32);
  3786. *pLen = sizeof(SK_U32);
  3787. break;
  3788. default:
  3789. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
  3790. SK_PNMI_ERR034MSG);
  3791. *pLen = 0;
  3792. return (SK_PNMI_ERR_GENERAL);
  3793. }
  3794. if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
  3795. Id == OID_SKGE_TX_HW_ERROR_CTS ||
  3796. Id == OID_SKGE_IN_ERRORS_CTS ||
  3797. Id == OID_SKGE_OUT_ERROR_CTS ||
  3798. Id == OID_GEN_XMIT_ERROR ||
  3799. Id == OID_GEN_RCV_ERROR) {
  3800. pAC->Pnmi.MacUpdatedFlag --;
  3801. }
  3802. return (SK_PNMI_ERR_OK);
  3803. }
  3804. /*****************************************************************************
  3805. *
  3806. * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
  3807. *
  3808. * Description:
  3809. * Get/Presets/Sets the RLMT OIDs.
  3810. *
  3811. * Returns:
  3812. * SK_PNMI_ERR_OK The request was successfully performed.
  3813. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  3814. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  3815. * the correct data (e.g. a 32bit value is
  3816. * needed, but a 16 bit value was passed).
  3817. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  3818. * value range.
  3819. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  3820. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  3821. * exist (e.g. port instance 3 on a two port
  3822. * adapter.
  3823. */
  3824. PNMI_STATIC int Rlmt(
  3825. SK_AC *pAC, /* Pointer to adapter context */
  3826. SK_IOC IoC, /* IO context handle */
  3827. int Action, /* GET/PRESET/SET action */
  3828. SK_U32 Id, /* Object ID that is to be processed */
  3829. char *pBuf, /* Buffer used for the management data transfer */
  3830. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  3831. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  3832. unsigned int TableIndex, /* Index to the Id table */
  3833. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  3834. {
  3835. int Ret;
  3836. unsigned int PhysPortIndex;
  3837. unsigned int PhysPortMax;
  3838. SK_EVPARA EventParam;
  3839. SK_U32 Val32;
  3840. SK_U64 Val64;
  3841. /*
  3842. * Check instance. Only single instance OIDs are allowed here.
  3843. */
  3844. if (Instance != (SK_U32)(-1) && Instance != 1) {
  3845. *pLen = 0;
  3846. return (SK_PNMI_ERR_UNKNOWN_INST);
  3847. }
  3848. /*
  3849. * Perform the requested action.
  3850. */
  3851. if (Action == SK_PNMI_GET) {
  3852. /*
  3853. * Check if the buffer length is large enough.
  3854. */
  3855. switch (Id) {
  3856. case OID_SKGE_RLMT_MODE:
  3857. case OID_SKGE_RLMT_PORT_ACTIVE:
  3858. case OID_SKGE_RLMT_PORT_PREFERRED:
  3859. if (*pLen < sizeof(SK_U8)) {
  3860. *pLen = sizeof(SK_U8);
  3861. return (SK_PNMI_ERR_TOO_SHORT);
  3862. }
  3863. break;
  3864. case OID_SKGE_RLMT_PORT_NUMBER:
  3865. if (*pLen < sizeof(SK_U32)) {
  3866. *pLen = sizeof(SK_U32);
  3867. return (SK_PNMI_ERR_TOO_SHORT);
  3868. }
  3869. break;
  3870. case OID_SKGE_RLMT_CHANGE_CTS:
  3871. case OID_SKGE_RLMT_CHANGE_TIME:
  3872. case OID_SKGE_RLMT_CHANGE_ESTIM:
  3873. case OID_SKGE_RLMT_CHANGE_THRES:
  3874. if (*pLen < sizeof(SK_U64)) {
  3875. *pLen = sizeof(SK_U64);
  3876. return (SK_PNMI_ERR_TOO_SHORT);
  3877. }
  3878. break;
  3879. default:
  3880. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
  3881. SK_PNMI_ERR035MSG);
  3882. *pLen = 0;
  3883. return (SK_PNMI_ERR_GENERAL);
  3884. }
  3885. /*
  3886. * Update RLMT statistic and increment semaphores to indicate
  3887. * that an update was already done. Maybe RLMT will hold its
  3888. * statistic always up to date some time. Then we can
  3889. * remove this type of call.
  3890. */
  3891. if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
  3892. *pLen = 0;
  3893. return (Ret);
  3894. }
  3895. pAC->Pnmi.RlmtUpdatedFlag ++;
  3896. /*
  3897. * Retrieve Value
  3898. */
  3899. switch (Id) {
  3900. case OID_SKGE_RLMT_MODE:
  3901. *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
  3902. *pLen = sizeof(char);
  3903. break;
  3904. case OID_SKGE_RLMT_PORT_NUMBER:
  3905. Val32 = (SK_U32)pAC->GIni.GIMacsFound;
  3906. SK_PNMI_STORE_U32(pBuf, Val32);
  3907. *pLen = sizeof(SK_U32);
  3908. break;
  3909. case OID_SKGE_RLMT_PORT_ACTIVE:
  3910. *pBuf = 0;
  3911. /*
  3912. * If multiple ports may become active this OID
  3913. * doesn't make sense any more. A new variable in
  3914. * the port structure should be created. However,
  3915. * for this variable the first active port is
  3916. * returned.
  3917. */
  3918. PhysPortMax = pAC->GIni.GIMacsFound;
  3919. for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
  3920. PhysPortIndex ++) {
  3921. if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  3922. *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
  3923. break;
  3924. }
  3925. }
  3926. *pLen = sizeof(char);
  3927. break;
  3928. case OID_SKGE_RLMT_PORT_PREFERRED:
  3929. *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
  3930. *pLen = sizeof(char);
  3931. break;
  3932. case OID_SKGE_RLMT_CHANGE_CTS:
  3933. Val64 = pAC->Pnmi.RlmtChangeCts;
  3934. SK_PNMI_STORE_U64(pBuf, Val64);
  3935. *pLen = sizeof(SK_U64);
  3936. break;
  3937. case OID_SKGE_RLMT_CHANGE_TIME:
  3938. Val64 = pAC->Pnmi.RlmtChangeTime;
  3939. SK_PNMI_STORE_U64(pBuf, Val64);
  3940. *pLen = sizeof(SK_U64);
  3941. break;
  3942. case OID_SKGE_RLMT_CHANGE_ESTIM:
  3943. Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
  3944. SK_PNMI_STORE_U64(pBuf, Val64);
  3945. *pLen = sizeof(SK_U64);
  3946. break;
  3947. case OID_SKGE_RLMT_CHANGE_THRES:
  3948. Val64 = pAC->Pnmi.RlmtChangeThreshold;
  3949. SK_PNMI_STORE_U64(pBuf, Val64);
  3950. *pLen = sizeof(SK_U64);
  3951. break;
  3952. default:
  3953. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
  3954. ("Rlmt: Unknown OID should be handled before"));
  3955. pAC->Pnmi.RlmtUpdatedFlag --;
  3956. *pLen = 0;
  3957. return (SK_PNMI_ERR_GENERAL);
  3958. }
  3959. pAC->Pnmi.RlmtUpdatedFlag --;
  3960. }
  3961. else {
  3962. /* Perform a preset or set */
  3963. switch (Id) {
  3964. case OID_SKGE_RLMT_MODE:
  3965. /* Check if the buffer length is plausible */
  3966. if (*pLen < sizeof(char)) {
  3967. *pLen = sizeof(char);
  3968. return (SK_PNMI_ERR_TOO_SHORT);
  3969. }
  3970. /* Check if the value range is correct */
  3971. if (*pLen != sizeof(char) ||
  3972. (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
  3973. *(SK_U8 *)pBuf > 15) {
  3974. *pLen = 0;
  3975. return (SK_PNMI_ERR_BAD_VALUE);
  3976. }
  3977. /* The preset ends here */
  3978. if (Action == SK_PNMI_PRESET) {
  3979. *pLen = 0;
  3980. return (SK_PNMI_ERR_OK);
  3981. }
  3982. /* Send an event to RLMT to change the mode */
  3983. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  3984. EventParam.Para32[0] |= (SK_U32)(*pBuf);
  3985. EventParam.Para32[1] = 0;
  3986. if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
  3987. EventParam) > 0) {
  3988. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
  3989. SK_PNMI_ERR037MSG);
  3990. *pLen = 0;
  3991. return (SK_PNMI_ERR_GENERAL);
  3992. }
  3993. break;
  3994. case OID_SKGE_RLMT_PORT_PREFERRED:
  3995. /* Check if the buffer length is plausible */
  3996. if (*pLen < sizeof(char)) {
  3997. *pLen = sizeof(char);
  3998. return (SK_PNMI_ERR_TOO_SHORT);
  3999. }
  4000. /* Check if the value range is correct */
  4001. if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
  4002. (SK_U8)pAC->GIni.GIMacsFound) {
  4003. *pLen = 0;
  4004. return (SK_PNMI_ERR_BAD_VALUE);
  4005. }
  4006. /* The preset ends here */
  4007. if (Action == SK_PNMI_PRESET) {
  4008. *pLen = 0;
  4009. return (SK_PNMI_ERR_OK);
  4010. }
  4011. /*
  4012. * Send an event to RLMT change the preferred port.
  4013. * A param of -1 means automatic mode. RLMT will
  4014. * make the decision which is the preferred port.
  4015. */
  4016. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  4017. EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
  4018. EventParam.Para32[1] = NetIndex;
  4019. if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
  4020. EventParam) > 0) {
  4021. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
  4022. SK_PNMI_ERR038MSG);
  4023. *pLen = 0;
  4024. return (SK_PNMI_ERR_GENERAL);
  4025. }
  4026. break;
  4027. case OID_SKGE_RLMT_CHANGE_THRES:
  4028. /* Check if the buffer length is plausible */
  4029. if (*pLen < sizeof(SK_U64)) {
  4030. *pLen = sizeof(SK_U64);
  4031. return (SK_PNMI_ERR_TOO_SHORT);
  4032. }
  4033. /*
  4034. * There are not many restrictions to the
  4035. * value range.
  4036. */
  4037. if (*pLen != sizeof(SK_U64)) {
  4038. *pLen = 0;
  4039. return (SK_PNMI_ERR_BAD_VALUE);
  4040. }
  4041. /* A preset ends here */
  4042. if (Action == SK_PNMI_PRESET) {
  4043. *pLen = 0;
  4044. return (SK_PNMI_ERR_OK);
  4045. }
  4046. /*
  4047. * Store the new threshold, which will be taken
  4048. * on the next timer event.
  4049. */
  4050. SK_PNMI_READ_U64(pBuf, Val64);
  4051. pAC->Pnmi.RlmtChangeThreshold = Val64;
  4052. break;
  4053. default:
  4054. /* The other OIDs are not be able for set */
  4055. *pLen = 0;
  4056. return (SK_PNMI_ERR_READ_ONLY);
  4057. }
  4058. }
  4059. return (SK_PNMI_ERR_OK);
  4060. }
  4061. /*****************************************************************************
  4062. *
  4063. * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
  4064. *
  4065. * Description:
  4066. * Performs get requests on multiple instance variables.
  4067. *
  4068. * Returns:
  4069. * SK_PNMI_ERR_OK The request was successfully performed.
  4070. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  4071. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  4072. * the correct data (e.g. a 32bit value is
  4073. * needed, but a 16 bit value was passed).
  4074. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  4075. * exist (e.g. port instance 3 on a two port
  4076. * adapter.
  4077. */
  4078. PNMI_STATIC int RlmtStat(
  4079. SK_AC *pAC, /* Pointer to adapter context */
  4080. SK_IOC IoC, /* IO context handle */
  4081. int Action, /* GET/PRESET/SET action */
  4082. SK_U32 Id, /* Object ID that is to be processed */
  4083. char *pBuf, /* Buffer used for the management data transfer */
  4084. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  4085. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  4086. unsigned int TableIndex, /* Index to the Id table */
  4087. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  4088. {
  4089. unsigned int PhysPortMax;
  4090. unsigned int PhysPortIndex;
  4091. unsigned int Limit;
  4092. unsigned int Offset;
  4093. int Ret;
  4094. SK_U32 Val32;
  4095. SK_U64 Val64;
  4096. /*
  4097. * Calculate the port indexes from the instance.
  4098. */
  4099. PhysPortMax = pAC->GIni.GIMacsFound;
  4100. if ((Instance != (SK_U32)(-1))) {
  4101. /* Check instance range */
  4102. if ((Instance < 1) || (Instance > PhysPortMax)) {
  4103. *pLen = 0;
  4104. return (SK_PNMI_ERR_UNKNOWN_INST);
  4105. }
  4106. /* Single net mode */
  4107. PhysPortIndex = Instance - 1;
  4108. /* Dual net mode */
  4109. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  4110. PhysPortIndex = NetIndex;
  4111. }
  4112. /* Both net modes */
  4113. Limit = PhysPortIndex + 1;
  4114. }
  4115. else {
  4116. /* Single net mode */
  4117. PhysPortIndex = 0;
  4118. Limit = PhysPortMax;
  4119. /* Dual net mode */
  4120. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  4121. PhysPortIndex = NetIndex;
  4122. Limit = PhysPortIndex + 1;
  4123. }
  4124. }
  4125. /*
  4126. * Currently only get requests are allowed.
  4127. */
  4128. if (Action != SK_PNMI_GET) {
  4129. *pLen = 0;
  4130. return (SK_PNMI_ERR_READ_ONLY);
  4131. }
  4132. /*
  4133. * Check if the buffer length is large enough.
  4134. */
  4135. switch (Id) {
  4136. case OID_SKGE_RLMT_PORT_INDEX:
  4137. case OID_SKGE_RLMT_STATUS:
  4138. if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
  4139. *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
  4140. return (SK_PNMI_ERR_TOO_SHORT);
  4141. }
  4142. break;
  4143. case OID_SKGE_RLMT_TX_HELLO_CTS:
  4144. case OID_SKGE_RLMT_RX_HELLO_CTS:
  4145. case OID_SKGE_RLMT_TX_SP_REQ_CTS:
  4146. case OID_SKGE_RLMT_RX_SP_CTS:
  4147. if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
  4148. *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
  4149. return (SK_PNMI_ERR_TOO_SHORT);
  4150. }
  4151. break;
  4152. default:
  4153. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
  4154. SK_PNMI_ERR039MSG);
  4155. *pLen = 0;
  4156. return (SK_PNMI_ERR_GENERAL);
  4157. }
  4158. /*
  4159. * Update statistic and increment semaphores to indicate that
  4160. * an update was already done.
  4161. */
  4162. if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
  4163. *pLen = 0;
  4164. return (Ret);
  4165. }
  4166. pAC->Pnmi.RlmtUpdatedFlag ++;
  4167. /*
  4168. * Get value
  4169. */
  4170. Offset = 0;
  4171. for (; PhysPortIndex < Limit; PhysPortIndex ++) {
  4172. switch (Id) {
  4173. case OID_SKGE_RLMT_PORT_INDEX:
  4174. Val32 = PhysPortIndex;
  4175. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  4176. Offset += sizeof(SK_U32);
  4177. break;
  4178. case OID_SKGE_RLMT_STATUS:
  4179. if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
  4180. SK_RLMT_PS_INIT ||
  4181. pAC->Rlmt.Port[PhysPortIndex].PortState ==
  4182. SK_RLMT_PS_DOWN) {
  4183. Val32 = SK_PNMI_RLMT_STATUS_ERROR;
  4184. }
  4185. else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  4186. Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
  4187. }
  4188. else {
  4189. Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
  4190. }
  4191. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  4192. Offset += sizeof(SK_U32);
  4193. break;
  4194. case OID_SKGE_RLMT_TX_HELLO_CTS:
  4195. Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
  4196. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  4197. Offset += sizeof(SK_U64);
  4198. break;
  4199. case OID_SKGE_RLMT_RX_HELLO_CTS:
  4200. Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
  4201. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  4202. Offset += sizeof(SK_U64);
  4203. break;
  4204. case OID_SKGE_RLMT_TX_SP_REQ_CTS:
  4205. Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
  4206. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  4207. Offset += sizeof(SK_U64);
  4208. break;
  4209. case OID_SKGE_RLMT_RX_SP_CTS:
  4210. Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
  4211. SK_PNMI_STORE_U64(pBuf + Offset, Val64);
  4212. Offset += sizeof(SK_U64);
  4213. break;
  4214. default:
  4215. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
  4216. ("RlmtStat: Unknown OID should be errored before"));
  4217. pAC->Pnmi.RlmtUpdatedFlag --;
  4218. *pLen = 0;
  4219. return (SK_PNMI_ERR_GENERAL);
  4220. }
  4221. }
  4222. *pLen = Offset;
  4223. pAC->Pnmi.RlmtUpdatedFlag --;
  4224. return (SK_PNMI_ERR_OK);
  4225. }
  4226. /*****************************************************************************
  4227. *
  4228. * MacPrivateConf - OID handler function of OIDs concerning the configuration
  4229. *
  4230. * Description:
  4231. * Get/Presets/Sets the OIDs concerning the configuration.
  4232. *
  4233. * Returns:
  4234. * SK_PNMI_ERR_OK The request was successfully performed.
  4235. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  4236. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  4237. * the correct data (e.g. a 32bit value is
  4238. * needed, but a 16 bit value was passed).
  4239. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  4240. * value range.
  4241. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  4242. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  4243. * exist (e.g. port instance 3 on a two port
  4244. * adapter.
  4245. */
  4246. PNMI_STATIC int MacPrivateConf(
  4247. SK_AC *pAC, /* Pointer to adapter context */
  4248. SK_IOC IoC, /* IO context handle */
  4249. int Action, /* GET/PRESET/SET action */
  4250. SK_U32 Id, /* Object ID that is to be processed */
  4251. char *pBuf, /* Buffer used for the management data transfer */
  4252. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  4253. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  4254. unsigned int TableIndex, /* Index to the Id table */
  4255. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  4256. {
  4257. unsigned int PhysPortMax;
  4258. unsigned int PhysPortIndex;
  4259. unsigned int LogPortMax;
  4260. unsigned int LogPortIndex;
  4261. unsigned int Limit;
  4262. unsigned int Offset;
  4263. char Val8;
  4264. char *pBufPtr;
  4265. int Ret;
  4266. SK_EVPARA EventParam;
  4267. SK_U32 Val32;
  4268. /*
  4269. * Calculate instance if wished. MAC index 0 is the virtual MAC.
  4270. */
  4271. PhysPortMax = pAC->GIni.GIMacsFound;
  4272. LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
  4273. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
  4274. LogPortMax--;
  4275. }
  4276. if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
  4277. /* Check instance range */
  4278. if ((Instance < 1) || (Instance > LogPortMax)) {
  4279. *pLen = 0;
  4280. return (SK_PNMI_ERR_UNKNOWN_INST);
  4281. }
  4282. LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
  4283. Limit = LogPortIndex + 1;
  4284. }
  4285. else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
  4286. LogPortIndex = 0;
  4287. Limit = LogPortMax;
  4288. }
  4289. /*
  4290. * Perform action
  4291. */
  4292. if (Action == SK_PNMI_GET) {
  4293. /* Check length */
  4294. switch (Id) {
  4295. case OID_SKGE_PMD:
  4296. case OID_SKGE_CONNECTOR:
  4297. case OID_SKGE_LINK_CAP:
  4298. case OID_SKGE_LINK_MODE:
  4299. case OID_SKGE_LINK_MODE_STATUS:
  4300. case OID_SKGE_LINK_STATUS:
  4301. case OID_SKGE_FLOWCTRL_CAP:
  4302. case OID_SKGE_FLOWCTRL_MODE:
  4303. case OID_SKGE_FLOWCTRL_STATUS:
  4304. case OID_SKGE_PHY_OPERATION_CAP:
  4305. case OID_SKGE_PHY_OPERATION_MODE:
  4306. case OID_SKGE_PHY_OPERATION_STATUS:
  4307. case OID_SKGE_SPEED_CAP:
  4308. case OID_SKGE_SPEED_MODE:
  4309. case OID_SKGE_SPEED_STATUS:
  4310. #ifdef SK_PHY_LP_MODE
  4311. case OID_SKGE_PHY_LP_MODE:
  4312. #endif
  4313. if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
  4314. *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
  4315. return (SK_PNMI_ERR_TOO_SHORT);
  4316. }
  4317. break;
  4318. case OID_SKGE_MTU:
  4319. case OID_SKGE_PHY_TYPE:
  4320. if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
  4321. *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
  4322. return (SK_PNMI_ERR_TOO_SHORT);
  4323. }
  4324. break;
  4325. default:
  4326. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
  4327. SK_PNMI_ERR041MSG);
  4328. *pLen = 0;
  4329. return (SK_PNMI_ERR_GENERAL);
  4330. }
  4331. /*
  4332. * Update statistic and increment semaphore to indicate
  4333. * that an update was already done.
  4334. */
  4335. if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
  4336. *pLen = 0;
  4337. return (Ret);
  4338. }
  4339. pAC->Pnmi.SirqUpdatedFlag ++;
  4340. /*
  4341. * Get value
  4342. */
  4343. Offset = 0;
  4344. for (; LogPortIndex < Limit; LogPortIndex ++) {
  4345. pBufPtr = pBuf + Offset;
  4346. switch (Id) {
  4347. case OID_SKGE_PMD:
  4348. *pBufPtr = pAC->Pnmi.PMD;
  4349. Offset += sizeof(char);
  4350. break;
  4351. case OID_SKGE_CONNECTOR:
  4352. *pBufPtr = pAC->Pnmi.Connector;
  4353. Offset += sizeof(char);
  4354. break;
  4355. case OID_SKGE_PHY_TYPE:
  4356. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4357. if (LogPortIndex == 0) {
  4358. continue;
  4359. }
  4360. else {
  4361. /* Get value for physical ports */
  4362. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4363. pAC, LogPortIndex);
  4364. Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
  4365. SK_PNMI_STORE_U32(pBufPtr, Val32);
  4366. }
  4367. }
  4368. else { /* DualNetMode */
  4369. Val32 = pAC->GIni.GP[NetIndex].PhyType;
  4370. SK_PNMI_STORE_U32(pBufPtr, Val32);
  4371. }
  4372. Offset += sizeof(SK_U32);
  4373. break;
  4374. #ifdef SK_PHY_LP_MODE
  4375. case OID_SKGE_PHY_LP_MODE:
  4376. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4377. if (LogPortIndex == 0) {
  4378. continue;
  4379. }
  4380. else {
  4381. /* Get value for physical ports */
  4382. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
  4383. Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
  4384. *pBufPtr = Val8;
  4385. }
  4386. }
  4387. else { /* DualNetMode */
  4388. Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
  4389. *pBufPtr = Val8;
  4390. }
  4391. Offset += sizeof(SK_U8);
  4392. break;
  4393. #endif
  4394. case OID_SKGE_LINK_CAP:
  4395. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4396. if (LogPortIndex == 0) {
  4397. /* Get value for virtual port */
  4398. VirtualConf(pAC, IoC, Id, pBufPtr);
  4399. }
  4400. else {
  4401. /* Get value for physical ports */
  4402. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4403. pAC, LogPortIndex);
  4404. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
  4405. }
  4406. }
  4407. else { /* DualNetMode */
  4408. *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
  4409. }
  4410. Offset += sizeof(char);
  4411. break;
  4412. case OID_SKGE_LINK_MODE:
  4413. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4414. if (LogPortIndex == 0) {
  4415. /* Get value for virtual port */
  4416. VirtualConf(pAC, IoC, Id, pBufPtr);
  4417. }
  4418. else {
  4419. /* Get value for physical ports */
  4420. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4421. pAC, LogPortIndex);
  4422. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
  4423. }
  4424. }
  4425. else { /* DualNetMode */
  4426. *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
  4427. }
  4428. Offset += sizeof(char);
  4429. break;
  4430. case OID_SKGE_LINK_MODE_STATUS:
  4431. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4432. if (LogPortIndex == 0) {
  4433. /* Get value for virtual port */
  4434. VirtualConf(pAC, IoC, Id, pBufPtr);
  4435. }
  4436. else {
  4437. /* Get value for physical port */
  4438. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4439. pAC, LogPortIndex);
  4440. *pBufPtr =
  4441. CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
  4442. }
  4443. }
  4444. else { /* DualNetMode */
  4445. *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
  4446. }
  4447. Offset += sizeof(char);
  4448. break;
  4449. case OID_SKGE_LINK_STATUS:
  4450. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4451. if (LogPortIndex == 0) {
  4452. /* Get value for virtual port */
  4453. VirtualConf(pAC, IoC, Id, pBufPtr);
  4454. }
  4455. else {
  4456. /* Get value for physical ports */
  4457. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4458. pAC, LogPortIndex);
  4459. *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
  4460. }
  4461. }
  4462. else { /* DualNetMode */
  4463. *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
  4464. }
  4465. Offset += sizeof(char);
  4466. break;
  4467. case OID_SKGE_FLOWCTRL_CAP:
  4468. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4469. if (LogPortIndex == 0) {
  4470. /* Get value for virtual port */
  4471. VirtualConf(pAC, IoC, Id, pBufPtr);
  4472. }
  4473. else {
  4474. /* Get value for physical ports */
  4475. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4476. pAC, LogPortIndex);
  4477. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
  4478. }
  4479. }
  4480. else { /* DualNetMode */
  4481. *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
  4482. }
  4483. Offset += sizeof(char);
  4484. break;
  4485. case OID_SKGE_FLOWCTRL_MODE:
  4486. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4487. if (LogPortIndex == 0) {
  4488. /* Get value for virtual port */
  4489. VirtualConf(pAC, IoC, Id, pBufPtr);
  4490. }
  4491. else {
  4492. /* Get value for physical port */
  4493. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4494. pAC, LogPortIndex);
  4495. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
  4496. }
  4497. }
  4498. else { /* DualNetMode */
  4499. *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
  4500. }
  4501. Offset += sizeof(char);
  4502. break;
  4503. case OID_SKGE_FLOWCTRL_STATUS:
  4504. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4505. if (LogPortIndex == 0) {
  4506. /* Get value for virtual port */
  4507. VirtualConf(pAC, IoC, Id, pBufPtr);
  4508. }
  4509. else {
  4510. /* Get value for physical port */
  4511. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4512. pAC, LogPortIndex);
  4513. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
  4514. }
  4515. }
  4516. else { /* DualNetMode */
  4517. *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
  4518. }
  4519. Offset += sizeof(char);
  4520. break;
  4521. case OID_SKGE_PHY_OPERATION_CAP:
  4522. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4523. if (LogPortIndex == 0) {
  4524. /* Get value for virtual port */
  4525. VirtualConf(pAC, IoC, Id, pBufPtr);
  4526. }
  4527. else {
  4528. /* Get value for physical ports */
  4529. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4530. pAC, LogPortIndex);
  4531. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
  4532. }
  4533. }
  4534. else { /* DualNetMode */
  4535. *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
  4536. }
  4537. Offset += sizeof(char);
  4538. break;
  4539. case OID_SKGE_PHY_OPERATION_MODE:
  4540. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4541. if (LogPortIndex == 0) {
  4542. /* Get value for virtual port */
  4543. VirtualConf(pAC, IoC, Id, pBufPtr);
  4544. }
  4545. else {
  4546. /* Get value for physical port */
  4547. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4548. pAC, LogPortIndex);
  4549. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
  4550. }
  4551. }
  4552. else { /* DualNetMode */
  4553. *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
  4554. }
  4555. Offset += sizeof(char);
  4556. break;
  4557. case OID_SKGE_PHY_OPERATION_STATUS:
  4558. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4559. if (LogPortIndex == 0) {
  4560. /* Get value for virtual port */
  4561. VirtualConf(pAC, IoC, Id, pBufPtr);
  4562. }
  4563. else {
  4564. /* Get value for physical port */
  4565. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4566. pAC, LogPortIndex);
  4567. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
  4568. }
  4569. }
  4570. else {
  4571. *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
  4572. }
  4573. Offset += sizeof(char);
  4574. break;
  4575. case OID_SKGE_SPEED_CAP:
  4576. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4577. if (LogPortIndex == 0) {
  4578. /* Get value for virtual port */
  4579. VirtualConf(pAC, IoC, Id, pBufPtr);
  4580. }
  4581. else {
  4582. /* Get value for physical ports */
  4583. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4584. pAC, LogPortIndex);
  4585. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
  4586. }
  4587. }
  4588. else { /* DualNetMode */
  4589. *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
  4590. }
  4591. Offset += sizeof(char);
  4592. break;
  4593. case OID_SKGE_SPEED_MODE:
  4594. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4595. if (LogPortIndex == 0) {
  4596. /* Get value for virtual port */
  4597. VirtualConf(pAC, IoC, Id, pBufPtr);
  4598. }
  4599. else {
  4600. /* Get value for physical port */
  4601. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4602. pAC, LogPortIndex);
  4603. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
  4604. }
  4605. }
  4606. else { /* DualNetMode */
  4607. *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
  4608. }
  4609. Offset += sizeof(char);
  4610. break;
  4611. case OID_SKGE_SPEED_STATUS:
  4612. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4613. if (LogPortIndex == 0) {
  4614. /* Get value for virtual port */
  4615. VirtualConf(pAC, IoC, Id, pBufPtr);
  4616. }
  4617. else {
  4618. /* Get value for physical port */
  4619. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
  4620. pAC, LogPortIndex);
  4621. *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
  4622. }
  4623. }
  4624. else { /* DualNetMode */
  4625. *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
  4626. }
  4627. Offset += sizeof(char);
  4628. break;
  4629. case OID_SKGE_MTU:
  4630. Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
  4631. SK_PNMI_STORE_U32(pBufPtr, Val32);
  4632. Offset += sizeof(SK_U32);
  4633. break;
  4634. default:
  4635. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
  4636. ("MacPrivateConf: Unknown OID should be handled before"));
  4637. pAC->Pnmi.SirqUpdatedFlag --;
  4638. return (SK_PNMI_ERR_GENERAL);
  4639. }
  4640. }
  4641. *pLen = Offset;
  4642. pAC->Pnmi.SirqUpdatedFlag --;
  4643. return (SK_PNMI_ERR_OK);
  4644. }
  4645. /*
  4646. * From here SET or PRESET action. Check if the passed
  4647. * buffer length is plausible.
  4648. */
  4649. switch (Id) {
  4650. case OID_SKGE_LINK_MODE:
  4651. case OID_SKGE_FLOWCTRL_MODE:
  4652. case OID_SKGE_PHY_OPERATION_MODE:
  4653. case OID_SKGE_SPEED_MODE:
  4654. if (*pLen < Limit - LogPortIndex) {
  4655. *pLen = Limit - LogPortIndex;
  4656. return (SK_PNMI_ERR_TOO_SHORT);
  4657. }
  4658. if (*pLen != Limit - LogPortIndex) {
  4659. *pLen = 0;
  4660. return (SK_PNMI_ERR_BAD_VALUE);
  4661. }
  4662. break;
  4663. #ifdef SK_PHY_LP_MODE
  4664. case OID_SKGE_PHY_LP_MODE:
  4665. if (*pLen < Limit - LogPortIndex) {
  4666. *pLen = Limit - LogPortIndex;
  4667. return (SK_PNMI_ERR_TOO_SHORT);
  4668. }
  4669. break;
  4670. #endif
  4671. case OID_SKGE_MTU:
  4672. if (*pLen < sizeof(SK_U32)) {
  4673. *pLen = sizeof(SK_U32);
  4674. return (SK_PNMI_ERR_TOO_SHORT);
  4675. }
  4676. if (*pLen != sizeof(SK_U32)) {
  4677. *pLen = 0;
  4678. return (SK_PNMI_ERR_BAD_VALUE);
  4679. }
  4680. break;
  4681. default:
  4682. *pLen = 0;
  4683. return (SK_PNMI_ERR_READ_ONLY);
  4684. }
  4685. /*
  4686. * Perform preset or set
  4687. */
  4688. Offset = 0;
  4689. for (; LogPortIndex < Limit; LogPortIndex ++) {
  4690. switch (Id) {
  4691. case OID_SKGE_LINK_MODE:
  4692. /* Check the value range */
  4693. Val8 = *(pBuf + Offset);
  4694. if (Val8 == 0) {
  4695. Offset += sizeof(char);
  4696. break;
  4697. }
  4698. if (Val8 < SK_LMODE_HALF ||
  4699. (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
  4700. (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
  4701. *pLen = 0;
  4702. return (SK_PNMI_ERR_BAD_VALUE);
  4703. }
  4704. /* The preset ends here */
  4705. if (Action == SK_PNMI_PRESET) {
  4706. return (SK_PNMI_ERR_OK);
  4707. }
  4708. if (LogPortIndex == 0) {
  4709. /*
  4710. * The virtual port consists of all currently
  4711. * active ports. Find them and send an event
  4712. * with the new link mode to SIRQ.
  4713. */
  4714. for (PhysPortIndex = 0;
  4715. PhysPortIndex < PhysPortMax;
  4716. PhysPortIndex ++) {
  4717. if (!pAC->Pnmi.Port[PhysPortIndex].
  4718. ActiveFlag) {
  4719. continue;
  4720. }
  4721. EventParam.Para32[0] = PhysPortIndex;
  4722. EventParam.Para32[1] = (SK_U32)Val8;
  4723. if (SkGeSirqEvent(pAC, IoC,
  4724. SK_HWEV_SET_LMODE,
  4725. EventParam) > 0) {
  4726. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4727. SK_PNMI_ERR043,
  4728. SK_PNMI_ERR043MSG);
  4729. *pLen = 0;
  4730. return (SK_PNMI_ERR_GENERAL);
  4731. }
  4732. }
  4733. }
  4734. else {
  4735. /*
  4736. * Send an event with the new link mode to
  4737. * the SIRQ module.
  4738. */
  4739. EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
  4740. pAC, LogPortIndex);
  4741. EventParam.Para32[1] = (SK_U32)Val8;
  4742. if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
  4743. EventParam) > 0) {
  4744. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4745. SK_PNMI_ERR043,
  4746. SK_PNMI_ERR043MSG);
  4747. *pLen = 0;
  4748. return (SK_PNMI_ERR_GENERAL);
  4749. }
  4750. }
  4751. Offset += sizeof(char);
  4752. break;
  4753. case OID_SKGE_FLOWCTRL_MODE:
  4754. /* Check the value range */
  4755. Val8 = *(pBuf + Offset);
  4756. if (Val8 == 0) {
  4757. Offset += sizeof(char);
  4758. break;
  4759. }
  4760. if (Val8 < SK_FLOW_MODE_NONE ||
  4761. (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
  4762. (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
  4763. *pLen = 0;
  4764. return (SK_PNMI_ERR_BAD_VALUE);
  4765. }
  4766. /* The preset ends here */
  4767. if (Action == SK_PNMI_PRESET) {
  4768. return (SK_PNMI_ERR_OK);
  4769. }
  4770. if (LogPortIndex == 0) {
  4771. /*
  4772. * The virtual port consists of all currently
  4773. * active ports. Find them and send an event
  4774. * with the new flow control mode to SIRQ.
  4775. */
  4776. for (PhysPortIndex = 0;
  4777. PhysPortIndex < PhysPortMax;
  4778. PhysPortIndex ++) {
  4779. if (!pAC->Pnmi.Port[PhysPortIndex].
  4780. ActiveFlag) {
  4781. continue;
  4782. }
  4783. EventParam.Para32[0] = PhysPortIndex;
  4784. EventParam.Para32[1] = (SK_U32)Val8;
  4785. if (SkGeSirqEvent(pAC, IoC,
  4786. SK_HWEV_SET_FLOWMODE,
  4787. EventParam) > 0) {
  4788. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4789. SK_PNMI_ERR044,
  4790. SK_PNMI_ERR044MSG);
  4791. *pLen = 0;
  4792. return (SK_PNMI_ERR_GENERAL);
  4793. }
  4794. }
  4795. }
  4796. else {
  4797. /*
  4798. * Send an event with the new flow control
  4799. * mode to the SIRQ module.
  4800. */
  4801. EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
  4802. pAC, LogPortIndex);
  4803. EventParam.Para32[1] = (SK_U32)Val8;
  4804. if (SkGeSirqEvent(pAC, IoC,
  4805. SK_HWEV_SET_FLOWMODE, EventParam)
  4806. > 0) {
  4807. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4808. SK_PNMI_ERR044,
  4809. SK_PNMI_ERR044MSG);
  4810. *pLen = 0;
  4811. return (SK_PNMI_ERR_GENERAL);
  4812. }
  4813. }
  4814. Offset += sizeof(char);
  4815. break;
  4816. case OID_SKGE_PHY_OPERATION_MODE :
  4817. /* Check the value range */
  4818. Val8 = *(pBuf + Offset);
  4819. if (Val8 == 0) {
  4820. /* mode of this port remains unchanged */
  4821. Offset += sizeof(char);
  4822. break;
  4823. }
  4824. if (Val8 < SK_MS_MODE_AUTO ||
  4825. (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
  4826. (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
  4827. *pLen = 0;
  4828. return (SK_PNMI_ERR_BAD_VALUE);
  4829. }
  4830. /* The preset ends here */
  4831. if (Action == SK_PNMI_PRESET) {
  4832. return (SK_PNMI_ERR_OK);
  4833. }
  4834. if (LogPortIndex == 0) {
  4835. /*
  4836. * The virtual port consists of all currently
  4837. * active ports. Find them and send an event
  4838. * with new master/slave (role) mode to SIRQ.
  4839. */
  4840. for (PhysPortIndex = 0;
  4841. PhysPortIndex < PhysPortMax;
  4842. PhysPortIndex ++) {
  4843. if (!pAC->Pnmi.Port[PhysPortIndex].
  4844. ActiveFlag) {
  4845. continue;
  4846. }
  4847. EventParam.Para32[0] = PhysPortIndex;
  4848. EventParam.Para32[1] = (SK_U32)Val8;
  4849. if (SkGeSirqEvent(pAC, IoC,
  4850. SK_HWEV_SET_ROLE,
  4851. EventParam) > 0) {
  4852. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4853. SK_PNMI_ERR042,
  4854. SK_PNMI_ERR042MSG);
  4855. *pLen = 0;
  4856. return (SK_PNMI_ERR_GENERAL);
  4857. }
  4858. }
  4859. }
  4860. else {
  4861. /*
  4862. * Send an event with the new master/slave
  4863. * (role) mode to the SIRQ module.
  4864. */
  4865. EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
  4866. pAC, LogPortIndex);
  4867. EventParam.Para32[1] = (SK_U32)Val8;
  4868. if (SkGeSirqEvent(pAC, IoC,
  4869. SK_HWEV_SET_ROLE, EventParam) > 0) {
  4870. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4871. SK_PNMI_ERR042,
  4872. SK_PNMI_ERR042MSG);
  4873. *pLen = 0;
  4874. return (SK_PNMI_ERR_GENERAL);
  4875. }
  4876. }
  4877. Offset += sizeof(char);
  4878. break;
  4879. case OID_SKGE_SPEED_MODE:
  4880. /* Check the value range */
  4881. Val8 = *(pBuf + Offset);
  4882. if (Val8 == 0) {
  4883. Offset += sizeof(char);
  4884. break;
  4885. }
  4886. if (Val8 < (SK_LSPEED_AUTO) ||
  4887. (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
  4888. (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
  4889. *pLen = 0;
  4890. return (SK_PNMI_ERR_BAD_VALUE);
  4891. }
  4892. /* The preset ends here */
  4893. if (Action == SK_PNMI_PRESET) {
  4894. return (SK_PNMI_ERR_OK);
  4895. }
  4896. if (LogPortIndex == 0) {
  4897. /*
  4898. * The virtual port consists of all currently
  4899. * active ports. Find them and send an event
  4900. * with the new flow control mode to SIRQ.
  4901. */
  4902. for (PhysPortIndex = 0;
  4903. PhysPortIndex < PhysPortMax;
  4904. PhysPortIndex ++) {
  4905. if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  4906. continue;
  4907. }
  4908. EventParam.Para32[0] = PhysPortIndex;
  4909. EventParam.Para32[1] = (SK_U32)Val8;
  4910. if (SkGeSirqEvent(pAC, IoC,
  4911. SK_HWEV_SET_SPEED,
  4912. EventParam) > 0) {
  4913. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4914. SK_PNMI_ERR045,
  4915. SK_PNMI_ERR045MSG);
  4916. *pLen = 0;
  4917. return (SK_PNMI_ERR_GENERAL);
  4918. }
  4919. }
  4920. }
  4921. else {
  4922. /*
  4923. * Send an event with the new flow control
  4924. * mode to the SIRQ module.
  4925. */
  4926. EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
  4927. pAC, LogPortIndex);
  4928. EventParam.Para32[1] = (SK_U32)Val8;
  4929. if (SkGeSirqEvent(pAC, IoC,
  4930. SK_HWEV_SET_SPEED,
  4931. EventParam) > 0) {
  4932. SK_ERR_LOG(pAC, SK_ERRCL_SW,
  4933. SK_PNMI_ERR045,
  4934. SK_PNMI_ERR045MSG);
  4935. *pLen = 0;
  4936. return (SK_PNMI_ERR_GENERAL);
  4937. }
  4938. }
  4939. Offset += sizeof(char);
  4940. break;
  4941. case OID_SKGE_MTU :
  4942. /* Check the value range */
  4943. Val32 = *(SK_U32*)(pBuf + Offset);
  4944. if (Val32 == 0) {
  4945. /* mtu of this port remains unchanged */
  4946. Offset += sizeof(SK_U32);
  4947. break;
  4948. }
  4949. if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
  4950. *pLen = 0;
  4951. return (SK_PNMI_ERR_BAD_VALUE);
  4952. }
  4953. /* The preset ends here */
  4954. if (Action == SK_PNMI_PRESET) {
  4955. return (SK_PNMI_ERR_OK);
  4956. }
  4957. if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
  4958. return (SK_PNMI_ERR_GENERAL);
  4959. }
  4960. Offset += sizeof(SK_U32);
  4961. break;
  4962. #ifdef SK_PHY_LP_MODE
  4963. case OID_SKGE_PHY_LP_MODE:
  4964. /* The preset ends here */
  4965. if (Action == SK_PNMI_PRESET) {
  4966. return (SK_PNMI_ERR_OK);
  4967. }
  4968. if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
  4969. if (LogPortIndex == 0) {
  4970. Offset = 0;
  4971. continue;
  4972. }
  4973. else {
  4974. /* Set value for physical ports */
  4975. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
  4976. switch (*(pBuf + Offset)) {
  4977. case 0:
  4978. /* If LowPowerMode is active, we can leave it. */
  4979. if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
  4980. Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
  4981. if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
  4982. SkDrvInitAdapter(pAC);
  4983. }
  4984. break;
  4985. }
  4986. else {
  4987. *pLen = 0;
  4988. return (SK_PNMI_ERR_GENERAL);
  4989. }
  4990. case 1:
  4991. case 2:
  4992. case 3:
  4993. case 4:
  4994. /* If no LowPowerMode is active, we can enter it. */
  4995. if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
  4996. if ((*(pBuf + Offset)) < 3) {
  4997. SkDrvDeInitAdapter(pAC);
  4998. }
  4999. Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
  5000. break;
  5001. }
  5002. else {
  5003. *pLen = 0;
  5004. return (SK_PNMI_ERR_GENERAL);
  5005. }
  5006. default:
  5007. *pLen = 0;
  5008. return (SK_PNMI_ERR_BAD_VALUE);
  5009. }
  5010. }
  5011. }
  5012. else { /* DualNetMode */
  5013. switch (*(pBuf + Offset)) {
  5014. case 0:
  5015. /* If we are in a LowPowerMode, we can leave it. */
  5016. if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
  5017. Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
  5018. if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
  5019. SkDrvInitAdapter(pAC);
  5020. }
  5021. break;
  5022. }
  5023. else {
  5024. *pLen = 0;
  5025. return (SK_PNMI_ERR_GENERAL);
  5026. }
  5027. case 1:
  5028. case 2:
  5029. case 3:
  5030. case 4:
  5031. /* If we are not already in LowPowerMode, we can enter it. */
  5032. if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
  5033. if ((*(pBuf + Offset)) < 3) {
  5034. SkDrvDeInitAdapter(pAC);
  5035. }
  5036. else {
  5037. Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
  5038. }
  5039. break;
  5040. }
  5041. else {
  5042. *pLen = 0;
  5043. return (SK_PNMI_ERR_GENERAL);
  5044. }
  5045. default:
  5046. *pLen = 0;
  5047. return (SK_PNMI_ERR_BAD_VALUE);
  5048. }
  5049. }
  5050. Offset += sizeof(SK_U8);
  5051. break;
  5052. #endif
  5053. default:
  5054. SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
  5055. ("MacPrivateConf: Unknown OID should be handled before set"));
  5056. *pLen = 0;
  5057. return (SK_PNMI_ERR_GENERAL);
  5058. }
  5059. }
  5060. return (SK_PNMI_ERR_OK);
  5061. }
  5062. /*****************************************************************************
  5063. *
  5064. * Monitor - OID handler function for RLMT_MONITOR_XXX
  5065. *
  5066. * Description:
  5067. * Because RLMT currently does not support the monitoring of
  5068. * remote adapter cards, we return always an empty table.
  5069. *
  5070. * Returns:
  5071. * SK_PNMI_ERR_OK The request was successfully performed.
  5072. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  5073. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  5074. * the correct data (e.g. a 32bit value is
  5075. * needed, but a 16 bit value was passed).
  5076. * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
  5077. * value range.
  5078. * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
  5079. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  5080. * exist (e.g. port instance 3 on a two port
  5081. * adapter.
  5082. */
  5083. PNMI_STATIC int Monitor(
  5084. SK_AC *pAC, /* Pointer to adapter context */
  5085. SK_IOC IoC, /* IO context handle */
  5086. int Action, /* GET/PRESET/SET action */
  5087. SK_U32 Id, /* Object ID that is to be processed */
  5088. char *pBuf, /* Buffer used for the management data transfer */
  5089. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  5090. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  5091. unsigned int TableIndex, /* Index to the Id table */
  5092. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  5093. {
  5094. unsigned int Index;
  5095. unsigned int Limit;
  5096. unsigned int Offset;
  5097. unsigned int Entries;
  5098. /*
  5099. * Calculate instance if wished.
  5100. */
  5101. /* XXX Not yet implemented. Return always an empty table. */
  5102. Entries = 0;
  5103. if ((Instance != (SK_U32)(-1))) {
  5104. if ((Instance < 1) || (Instance > Entries)) {
  5105. *pLen = 0;
  5106. return (SK_PNMI_ERR_UNKNOWN_INST);
  5107. }
  5108. Index = (unsigned int)Instance - 1;
  5109. Limit = (unsigned int)Instance;
  5110. }
  5111. else {
  5112. Index = 0;
  5113. Limit = Entries;
  5114. }
  5115. /*
  5116. * Get/Set value
  5117. */
  5118. if (Action == SK_PNMI_GET) {
  5119. for (Offset=0; Index < Limit; Index ++) {
  5120. switch (Id) {
  5121. case OID_SKGE_RLMT_MONITOR_INDEX:
  5122. case OID_SKGE_RLMT_MONITOR_ADDR:
  5123. case OID_SKGE_RLMT_MONITOR_ERRS:
  5124. case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
  5125. case OID_SKGE_RLMT_MONITOR_ADMIN:
  5126. break;
  5127. default:
  5128. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
  5129. SK_PNMI_ERR046MSG);
  5130. *pLen = 0;
  5131. return (SK_PNMI_ERR_GENERAL);
  5132. }
  5133. }
  5134. *pLen = Offset;
  5135. }
  5136. else {
  5137. /* Only MONITOR_ADMIN can be set */
  5138. if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
  5139. *pLen = 0;
  5140. return (SK_PNMI_ERR_READ_ONLY);
  5141. }
  5142. /* Check if the length is plausible */
  5143. if (*pLen < (Limit - Index)) {
  5144. return (SK_PNMI_ERR_TOO_SHORT);
  5145. }
  5146. /* Okay, we have a wide value range */
  5147. if (*pLen != (Limit - Index)) {
  5148. *pLen = 0;
  5149. return (SK_PNMI_ERR_BAD_VALUE);
  5150. }
  5151. /*
  5152. for (Offset=0; Index < Limit; Index ++) {
  5153. }
  5154. */
  5155. /*
  5156. * XXX Not yet implemented. Return always BAD_VALUE, because the table
  5157. * is empty.
  5158. */
  5159. *pLen = 0;
  5160. return (SK_PNMI_ERR_BAD_VALUE);
  5161. }
  5162. return (SK_PNMI_ERR_OK);
  5163. }
  5164. /*****************************************************************************
  5165. *
  5166. * VirtualConf - Calculates the values of configuration OIDs for virtual port
  5167. *
  5168. * Description:
  5169. * We handle here the get of the configuration group OIDs, which are
  5170. * a little bit complicated. The virtual port consists of all currently
  5171. * active physical ports. If multiple ports are active and configured
  5172. * differently we get in some trouble to return a single value. So we
  5173. * get the value of the first active port and compare it with that of
  5174. * the other active ports. If they are not the same, we return a value
  5175. * that indicates that the state is indeterminated.
  5176. *
  5177. * Returns:
  5178. * Nothing
  5179. */
  5180. PNMI_STATIC void VirtualConf(
  5181. SK_AC *pAC, /* Pointer to adapter context */
  5182. SK_IOC IoC, /* IO context handle */
  5183. SK_U32 Id, /* Object ID that is to be processed */
  5184. char *pBuf) /* Buffer used for the management data transfer */
  5185. {
  5186. unsigned int PhysPortMax;
  5187. unsigned int PhysPortIndex;
  5188. SK_U8 Val8;
  5189. SK_U32 Val32;
  5190. SK_BOOL PortActiveFlag;
  5191. SK_GEPORT *pPrt;
  5192. *pBuf = 0;
  5193. PortActiveFlag = SK_FALSE;
  5194. PhysPortMax = pAC->GIni.GIMacsFound;
  5195. for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
  5196. PhysPortIndex ++) {
  5197. pPrt = &pAC->GIni.GP[PhysPortIndex];
  5198. /* Check if the physical port is active */
  5199. if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  5200. continue;
  5201. }
  5202. PortActiveFlag = SK_TRUE;
  5203. switch (Id) {
  5204. case OID_SKGE_PHY_TYPE:
  5205. /* Check if it is the first active port */
  5206. if (*pBuf == 0) {
  5207. Val32 = pPrt->PhyType;
  5208. SK_PNMI_STORE_U32(pBuf, Val32);
  5209. continue;
  5210. }
  5211. case OID_SKGE_LINK_CAP:
  5212. /*
  5213. * Different capabilities should not happen, but
  5214. * in the case of the cases OR them all together.
  5215. * From a curious point of view the virtual port
  5216. * is capable of all found capabilities.
  5217. */
  5218. *pBuf |= pPrt->PLinkCap;
  5219. break;
  5220. case OID_SKGE_LINK_MODE:
  5221. /* Check if it is the first active port */
  5222. if (*pBuf == 0) {
  5223. *pBuf = pPrt->PLinkModeConf;
  5224. continue;
  5225. }
  5226. /*
  5227. * If we find an active port with a different link
  5228. * mode than the first one we return a value that
  5229. * indicates that the link mode is indeterminated.
  5230. */
  5231. if (*pBuf != pPrt->PLinkModeConf) {
  5232. *pBuf = SK_LMODE_INDETERMINATED;
  5233. }
  5234. break;
  5235. case OID_SKGE_LINK_MODE_STATUS:
  5236. /* Get the link mode of the physical port */
  5237. Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
  5238. /* Check if it is the first active port */
  5239. if (*pBuf == 0) {
  5240. *pBuf = Val8;
  5241. continue;
  5242. }
  5243. /*
  5244. * If we find an active port with a different link
  5245. * mode status than the first one we return a value
  5246. * that indicates that the link mode status is
  5247. * indeterminated.
  5248. */
  5249. if (*pBuf != Val8) {
  5250. *pBuf = SK_LMODE_STAT_INDETERMINATED;
  5251. }
  5252. break;
  5253. case OID_SKGE_LINK_STATUS:
  5254. /* Get the link status of the physical port */
  5255. Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
  5256. /* Check if it is the first active port */
  5257. if (*pBuf == 0) {
  5258. *pBuf = Val8;
  5259. continue;
  5260. }
  5261. /*
  5262. * If we find an active port with a different link
  5263. * status than the first one, we return a value
  5264. * that indicates that the link status is
  5265. * indeterminated.
  5266. */
  5267. if (*pBuf != Val8) {
  5268. *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
  5269. }
  5270. break;
  5271. case OID_SKGE_FLOWCTRL_CAP:
  5272. /* Check if it is the first active port */
  5273. if (*pBuf == 0) {
  5274. *pBuf = pPrt->PFlowCtrlCap;
  5275. continue;
  5276. }
  5277. /*
  5278. * From a curious point of view the virtual port
  5279. * is capable of all found capabilities.
  5280. */
  5281. *pBuf |= pPrt->PFlowCtrlCap;
  5282. break;
  5283. case OID_SKGE_FLOWCTRL_MODE:
  5284. /* Check if it is the first active port */
  5285. if (*pBuf == 0) {
  5286. *pBuf = pPrt->PFlowCtrlMode;
  5287. continue;
  5288. }
  5289. /*
  5290. * If we find an active port with a different flow
  5291. * control mode than the first one, we return a value
  5292. * that indicates that the mode is indeterminated.
  5293. */
  5294. if (*pBuf != pPrt->PFlowCtrlMode) {
  5295. *pBuf = SK_FLOW_MODE_INDETERMINATED;
  5296. }
  5297. break;
  5298. case OID_SKGE_FLOWCTRL_STATUS:
  5299. /* Check if it is the first active port */
  5300. if (*pBuf == 0) {
  5301. *pBuf = pPrt->PFlowCtrlStatus;
  5302. continue;
  5303. }
  5304. /*
  5305. * If we find an active port with a different flow
  5306. * control status than the first one, we return a
  5307. * value that indicates that the status is
  5308. * indeterminated.
  5309. */
  5310. if (*pBuf != pPrt->PFlowCtrlStatus) {
  5311. *pBuf = SK_FLOW_STAT_INDETERMINATED;
  5312. }
  5313. break;
  5314. case OID_SKGE_PHY_OPERATION_CAP:
  5315. /* Check if it is the first active port */
  5316. if (*pBuf == 0) {
  5317. *pBuf = pPrt->PMSCap;
  5318. continue;
  5319. }
  5320. /*
  5321. * From a curious point of view the virtual port
  5322. * is capable of all found capabilities.
  5323. */
  5324. *pBuf |= pPrt->PMSCap;
  5325. break;
  5326. case OID_SKGE_PHY_OPERATION_MODE:
  5327. /* Check if it is the first active port */
  5328. if (*pBuf == 0) {
  5329. *pBuf = pPrt->PMSMode;
  5330. continue;
  5331. }
  5332. /*
  5333. * If we find an active port with a different master/
  5334. * slave mode than the first one, we return a value
  5335. * that indicates that the mode is indeterminated.
  5336. */
  5337. if (*pBuf != pPrt->PMSMode) {
  5338. *pBuf = SK_MS_MODE_INDETERMINATED;
  5339. }
  5340. break;
  5341. case OID_SKGE_PHY_OPERATION_STATUS:
  5342. /* Check if it is the first active port */
  5343. if (*pBuf == 0) {
  5344. *pBuf = pPrt->PMSStatus;
  5345. continue;
  5346. }
  5347. /*
  5348. * If we find an active port with a different master/
  5349. * slave status than the first one, we return a
  5350. * value that indicates that the status is
  5351. * indeterminated.
  5352. */
  5353. if (*pBuf != pPrt->PMSStatus) {
  5354. *pBuf = SK_MS_STAT_INDETERMINATED;
  5355. }
  5356. break;
  5357. case OID_SKGE_SPEED_MODE:
  5358. /* Check if it is the first active port */
  5359. if (*pBuf == 0) {
  5360. *pBuf = pPrt->PLinkSpeed;
  5361. continue;
  5362. }
  5363. /*
  5364. * If we find an active port with a different flow
  5365. * control mode than the first one, we return a value
  5366. * that indicates that the mode is indeterminated.
  5367. */
  5368. if (*pBuf != pPrt->PLinkSpeed) {
  5369. *pBuf = SK_LSPEED_INDETERMINATED;
  5370. }
  5371. break;
  5372. case OID_SKGE_SPEED_STATUS:
  5373. /* Check if it is the first active port */
  5374. if (*pBuf == 0) {
  5375. *pBuf = pPrt->PLinkSpeedUsed;
  5376. continue;
  5377. }
  5378. /*
  5379. * If we find an active port with a different flow
  5380. * control status than the first one, we return a
  5381. * value that indicates that the status is
  5382. * indeterminated.
  5383. */
  5384. if (*pBuf != pPrt->PLinkSpeedUsed) {
  5385. *pBuf = SK_LSPEED_STAT_INDETERMINATED;
  5386. }
  5387. break;
  5388. }
  5389. }
  5390. /*
  5391. * If no port is active return an indeterminated answer
  5392. */
  5393. if (!PortActiveFlag) {
  5394. switch (Id) {
  5395. case OID_SKGE_LINK_CAP:
  5396. *pBuf = SK_LMODE_CAP_INDETERMINATED;
  5397. break;
  5398. case OID_SKGE_LINK_MODE:
  5399. *pBuf = SK_LMODE_INDETERMINATED;
  5400. break;
  5401. case OID_SKGE_LINK_MODE_STATUS:
  5402. *pBuf = SK_LMODE_STAT_INDETERMINATED;
  5403. break;
  5404. case OID_SKGE_LINK_STATUS:
  5405. *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
  5406. break;
  5407. case OID_SKGE_FLOWCTRL_CAP:
  5408. case OID_SKGE_FLOWCTRL_MODE:
  5409. *pBuf = SK_FLOW_MODE_INDETERMINATED;
  5410. break;
  5411. case OID_SKGE_FLOWCTRL_STATUS:
  5412. *pBuf = SK_FLOW_STAT_INDETERMINATED;
  5413. break;
  5414. case OID_SKGE_PHY_OPERATION_CAP:
  5415. *pBuf = SK_MS_CAP_INDETERMINATED;
  5416. break;
  5417. case OID_SKGE_PHY_OPERATION_MODE:
  5418. *pBuf = SK_MS_MODE_INDETERMINATED;
  5419. break;
  5420. case OID_SKGE_PHY_OPERATION_STATUS:
  5421. *pBuf = SK_MS_STAT_INDETERMINATED;
  5422. break;
  5423. case OID_SKGE_SPEED_CAP:
  5424. *pBuf = SK_LSPEED_CAP_INDETERMINATED;
  5425. break;
  5426. case OID_SKGE_SPEED_MODE:
  5427. *pBuf = SK_LSPEED_INDETERMINATED;
  5428. break;
  5429. case OID_SKGE_SPEED_STATUS:
  5430. *pBuf = SK_LSPEED_STAT_INDETERMINATED;
  5431. break;
  5432. }
  5433. }
  5434. }
  5435. /*****************************************************************************
  5436. *
  5437. * CalculateLinkStatus - Determins the link status of a physical port
  5438. *
  5439. * Description:
  5440. * Determins the link status the following way:
  5441. * LSTAT_PHY_DOWN: Link is down
  5442. * LSTAT_AUTONEG: Auto-negotiation failed
  5443. * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
  5444. * logically up.
  5445. * LSTAT_LOG_UP: RLMT marked the port as up
  5446. *
  5447. * Returns:
  5448. * Link status of physical port
  5449. */
  5450. PNMI_STATIC SK_U8 CalculateLinkStatus(
  5451. SK_AC *pAC, /* Pointer to adapter context */
  5452. SK_IOC IoC, /* IO context handle */
  5453. unsigned int PhysPortIndex) /* Physical port index */
  5454. {
  5455. SK_U8 Result;
  5456. if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
  5457. Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
  5458. }
  5459. else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
  5460. Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
  5461. }
  5462. else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
  5463. Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
  5464. }
  5465. else {
  5466. Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
  5467. }
  5468. return (Result);
  5469. }
  5470. /*****************************************************************************
  5471. *
  5472. * CalculateLinkModeStatus - Determins the link mode status of a phys. port
  5473. *
  5474. * Description:
  5475. * The COMMON module only tells us if the mode is half or full duplex.
  5476. * But in the decade of auto sensing it is useful for the user to
  5477. * know if the mode was negotiated or forced. Therefore we have a
  5478. * look to the mode, which was last used by the negotiation process.
  5479. *
  5480. * Returns:
  5481. * The link mode status
  5482. */
  5483. PNMI_STATIC SK_U8 CalculateLinkModeStatus(
  5484. SK_AC *pAC, /* Pointer to adapter context */
  5485. SK_IOC IoC, /* IO context handle */
  5486. unsigned int PhysPortIndex) /* Physical port index */
  5487. {
  5488. SK_U8 Result;
  5489. /* Get the current mode, which can be full or half duplex */
  5490. Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
  5491. /* Check if no valid mode could be found (link is down) */
  5492. if (Result < SK_LMODE_STAT_HALF) {
  5493. Result = SK_LMODE_STAT_UNKNOWN;
  5494. }
  5495. else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
  5496. /*
  5497. * Auto-negotiation was used to bring up the link. Change
  5498. * the already found duplex status that it indicates
  5499. * auto-negotiation was involved.
  5500. */
  5501. if (Result == SK_LMODE_STAT_HALF) {
  5502. Result = SK_LMODE_STAT_AUTOHALF;
  5503. }
  5504. else if (Result == SK_LMODE_STAT_FULL) {
  5505. Result = SK_LMODE_STAT_AUTOFULL;
  5506. }
  5507. }
  5508. return (Result);
  5509. }
  5510. /*****************************************************************************
  5511. *
  5512. * GetVpdKeyArr - Obtain an array of VPD keys
  5513. *
  5514. * Description:
  5515. * Read the VPD keys and build an array of VPD keys, which are
  5516. * easy to access.
  5517. *
  5518. * Returns:
  5519. * SK_PNMI_ERR_OK Task successfully performed.
  5520. * SK_PNMI_ERR_GENERAL Something went wrong.
  5521. */
  5522. PNMI_STATIC int GetVpdKeyArr(
  5523. SK_AC *pAC, /* Pointer to adapter context */
  5524. SK_IOC IoC, /* IO context handle */
  5525. char *pKeyArr, /* Ptr KeyArray */
  5526. unsigned int KeyArrLen, /* Length of array in bytes */
  5527. unsigned int *pKeyNo) /* Number of keys */
  5528. {
  5529. unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
  5530. char BufKeys[SK_PNMI_VPD_BUFSIZE];
  5531. unsigned int StartOffset;
  5532. unsigned int Offset;
  5533. int Index;
  5534. int Ret;
  5535. SK_MEMSET(pKeyArr, 0, KeyArrLen);
  5536. /*
  5537. * Get VPD key list
  5538. */
  5539. Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
  5540. (int *)pKeyNo);
  5541. if (Ret > 0) {
  5542. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
  5543. SK_PNMI_ERR014MSG);
  5544. return (SK_PNMI_ERR_GENERAL);
  5545. }
  5546. /* If no keys are available return now */
  5547. if (*pKeyNo == 0 || BufKeysLen == 0) {
  5548. return (SK_PNMI_ERR_OK);
  5549. }
  5550. /*
  5551. * If the key list is too long for us trunc it and give a
  5552. * errorlog notification. This case should not happen because
  5553. * the maximum number of keys is limited due to RAM limitations
  5554. */
  5555. if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
  5556. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
  5557. SK_PNMI_ERR015MSG);
  5558. *pKeyNo = SK_PNMI_VPD_ENTRIES;
  5559. }
  5560. /*
  5561. * Now build an array of fixed string length size and copy
  5562. * the keys together.
  5563. */
  5564. for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
  5565. Offset ++) {
  5566. if (BufKeys[Offset] != 0) {
  5567. continue;
  5568. }
  5569. if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
  5570. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
  5571. SK_PNMI_ERR016MSG);
  5572. return (SK_PNMI_ERR_GENERAL);
  5573. }
  5574. SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
  5575. &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
  5576. Index ++;
  5577. StartOffset = Offset + 1;
  5578. }
  5579. /* Last key not zero terminated? Get it anyway */
  5580. if (StartOffset < Offset) {
  5581. SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
  5582. &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
  5583. }
  5584. return (SK_PNMI_ERR_OK);
  5585. }
  5586. /*****************************************************************************
  5587. *
  5588. * SirqUpdate - Let the SIRQ update its internal values
  5589. *
  5590. * Description:
  5591. * Just to be sure that the SIRQ module holds its internal data
  5592. * structures up to date, we send an update event before we make
  5593. * any access.
  5594. *
  5595. * Returns:
  5596. * SK_PNMI_ERR_OK Task successfully performed.
  5597. * SK_PNMI_ERR_GENERAL Something went wrong.
  5598. */
  5599. PNMI_STATIC int SirqUpdate(
  5600. SK_AC *pAC, /* Pointer to adapter context */
  5601. SK_IOC IoC) /* IO context handle */
  5602. {
  5603. SK_EVPARA EventParam;
  5604. /* Was the module already updated during the current PNMI call? */
  5605. if (pAC->Pnmi.SirqUpdatedFlag > 0) {
  5606. return (SK_PNMI_ERR_OK);
  5607. }
  5608. /* Send an synchronuous update event to the module */
  5609. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  5610. if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
  5611. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
  5612. SK_PNMI_ERR047MSG);
  5613. return (SK_PNMI_ERR_GENERAL);
  5614. }
  5615. return (SK_PNMI_ERR_OK);
  5616. }
  5617. /*****************************************************************************
  5618. *
  5619. * RlmtUpdate - Let the RLMT update its internal values
  5620. *
  5621. * Description:
  5622. * Just to be sure that the RLMT module holds its internal data
  5623. * structures up to date, we send an update event before we make
  5624. * any access.
  5625. *
  5626. * Returns:
  5627. * SK_PNMI_ERR_OK Task successfully performed.
  5628. * SK_PNMI_ERR_GENERAL Something went wrong.
  5629. */
  5630. PNMI_STATIC int RlmtUpdate(
  5631. SK_AC *pAC, /* Pointer to adapter context */
  5632. SK_IOC IoC, /* IO context handle */
  5633. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  5634. {
  5635. SK_EVPARA EventParam;
  5636. /* Was the module already updated during the current PNMI call? */
  5637. if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
  5638. return (SK_PNMI_ERR_OK);
  5639. }
  5640. /* Send an synchronuous update event to the module */
  5641. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  5642. EventParam.Para32[0] = NetIndex;
  5643. EventParam.Para32[1] = (SK_U32)-1;
  5644. if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
  5645. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
  5646. SK_PNMI_ERR048MSG);
  5647. return (SK_PNMI_ERR_GENERAL);
  5648. }
  5649. return (SK_PNMI_ERR_OK);
  5650. }
  5651. /*****************************************************************************
  5652. *
  5653. * MacUpdate - Force the XMAC to output the current statistic
  5654. *
  5655. * Description:
  5656. * The XMAC holds its statistic internally. To obtain the current
  5657. * values we must send a command so that the statistic data will
  5658. * be written to a predefined memory area on the adapter.
  5659. *
  5660. * Returns:
  5661. * SK_PNMI_ERR_OK Task successfully performed.
  5662. * SK_PNMI_ERR_GENERAL Something went wrong.
  5663. */
  5664. PNMI_STATIC int MacUpdate(
  5665. SK_AC *pAC, /* Pointer to adapter context */
  5666. SK_IOC IoC, /* IO context handle */
  5667. unsigned int FirstMac, /* Index of the first Mac to be updated */
  5668. unsigned int LastMac) /* Index of the last Mac to be updated */
  5669. {
  5670. unsigned int MacIndex;
  5671. /*
  5672. * Were the statistics already updated during the
  5673. * current PNMI call?
  5674. */
  5675. if (pAC->Pnmi.MacUpdatedFlag > 0) {
  5676. return (SK_PNMI_ERR_OK);
  5677. }
  5678. /* Send an update command to all MACs specified */
  5679. for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
  5680. /*
  5681. * 2002-09-13 pweber: Freeze the current SW counters.
  5682. * (That should be done as close as
  5683. * possible to the update of the
  5684. * HW counters)
  5685. */
  5686. if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
  5687. pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
  5688. }
  5689. /* 2002-09-13 pweber: Update the HW counter */
  5690. if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
  5691. return (SK_PNMI_ERR_GENERAL);
  5692. }
  5693. }
  5694. return (SK_PNMI_ERR_OK);
  5695. }
  5696. /*****************************************************************************
  5697. *
  5698. * GetStatVal - Retrieve an XMAC statistic counter
  5699. *
  5700. * Description:
  5701. * Retrieves the statistic counter of a virtual or physical port. The
  5702. * virtual port is identified by the index 0. It consists of all
  5703. * currently active ports. To obtain the counter value for this port
  5704. * we must add the statistic counter of all active ports. To grant
  5705. * continuous counter values for the virtual port even when port
  5706. * switches occur we must additionally add a delta value, which was
  5707. * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
  5708. *
  5709. * Returns:
  5710. * Requested statistic value
  5711. */
  5712. PNMI_STATIC SK_U64 GetStatVal(
  5713. SK_AC *pAC, /* Pointer to adapter context */
  5714. SK_IOC IoC, /* IO context handle */
  5715. unsigned int LogPortIndex, /* Index of the logical Port to be processed */
  5716. unsigned int StatIndex, /* Index to statistic value */
  5717. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  5718. {
  5719. unsigned int PhysPortIndex;
  5720. unsigned int PhysPortMax;
  5721. SK_U64 Val = 0;
  5722. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
  5723. PhysPortIndex = NetIndex;
  5724. Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
  5725. }
  5726. else { /* Single Net mode */
  5727. if (LogPortIndex == 0) {
  5728. PhysPortMax = pAC->GIni.GIMacsFound;
  5729. /* Add counter of all active ports */
  5730. for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
  5731. PhysPortIndex ++) {
  5732. if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
  5733. Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
  5734. }
  5735. }
  5736. /* Correct value because of port switches */
  5737. Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
  5738. }
  5739. else {
  5740. /* Get counter value of physical port */
  5741. PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
  5742. Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
  5743. }
  5744. }
  5745. return (Val);
  5746. }
  5747. /*****************************************************************************
  5748. *
  5749. * GetPhysStatVal - Get counter value for physical port
  5750. *
  5751. * Description:
  5752. * Builds a 64bit counter value. Except for the octet counters
  5753. * the lower 32bit are counted in hardware and the upper 32bit
  5754. * in software by monitoring counter overflow interrupts in the
  5755. * event handler. To grant continous counter values during XMAC
  5756. * resets (caused by a workaround) we must add a delta value.
  5757. * The delta was calculated in the event handler when a
  5758. * SK_PNMI_EVT_XMAC_RESET was received.
  5759. *
  5760. * Returns:
  5761. * Counter value
  5762. */
  5763. PNMI_STATIC SK_U64 GetPhysStatVal(
  5764. SK_AC *pAC, /* Pointer to adapter context */
  5765. SK_IOC IoC, /* IO context handle */
  5766. unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
  5767. unsigned int StatIndex) /* Index to statistic value */
  5768. {
  5769. SK_U64 Val = 0;
  5770. SK_U32 LowVal = 0;
  5771. SK_U32 HighVal = 0;
  5772. SK_U16 Word;
  5773. int MacType;
  5774. unsigned int HelpIndex;
  5775. SK_GEPORT *pPrt;
  5776. SK_PNMI_PORT *pPnmiPrt;
  5777. SK_GEMACFUNC *pFnMac;
  5778. pPrt = &pAC->GIni.GP[PhysPortIndex];
  5779. MacType = pAC->GIni.GIMacType;
  5780. /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
  5781. if (MacType == SK_MAC_XMAC) {
  5782. pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
  5783. }
  5784. else {
  5785. pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
  5786. }
  5787. pFnMac = &pAC->GIni.GIFunc;
  5788. switch (StatIndex) {
  5789. case SK_PNMI_HTX:
  5790. if (MacType == SK_MAC_GMAC) {
  5791. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5792. StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
  5793. &LowVal);
  5794. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5795. StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
  5796. &HighVal);
  5797. LowVal += HighVal;
  5798. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5799. StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
  5800. &HighVal);
  5801. LowVal += HighVal;
  5802. }
  5803. else {
  5804. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5805. StatAddr[StatIndex][MacType].Reg,
  5806. &LowVal);
  5807. }
  5808. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5809. break;
  5810. case SK_PNMI_HRX:
  5811. if (MacType == SK_MAC_GMAC) {
  5812. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5813. StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
  5814. &LowVal);
  5815. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5816. StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
  5817. &HighVal);
  5818. LowVal += HighVal;
  5819. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5820. StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
  5821. &HighVal);
  5822. LowVal += HighVal;
  5823. }
  5824. else {
  5825. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5826. StatAddr[StatIndex][MacType].Reg,
  5827. &LowVal);
  5828. }
  5829. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5830. break;
  5831. case SK_PNMI_HTX_OCTET:
  5832. case SK_PNMI_HRX_OCTET:
  5833. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5834. StatAddr[StatIndex][MacType].Reg,
  5835. &HighVal);
  5836. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5837. StatAddr[StatIndex + 1][MacType].Reg,
  5838. &LowVal);
  5839. break;
  5840. case SK_PNMI_HTX_BURST:
  5841. case SK_PNMI_HTX_EXCESS_DEF:
  5842. case SK_PNMI_HTX_CARRIER:
  5843. /* Not supported by GMAC */
  5844. if (MacType == SK_MAC_GMAC) {
  5845. return (Val);
  5846. }
  5847. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5848. StatAddr[StatIndex][MacType].Reg,
  5849. &LowVal);
  5850. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5851. break;
  5852. case SK_PNMI_HTX_MACC:
  5853. /* GMAC only supports PAUSE MAC control frames */
  5854. if (MacType == SK_MAC_GMAC) {
  5855. HelpIndex = SK_PNMI_HTX_PMACC;
  5856. }
  5857. else {
  5858. HelpIndex = StatIndex;
  5859. }
  5860. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5861. StatAddr[HelpIndex][MacType].Reg,
  5862. &LowVal);
  5863. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5864. break;
  5865. case SK_PNMI_HTX_COL:
  5866. case SK_PNMI_HRX_UNDERSIZE:
  5867. /* Not supported by XMAC */
  5868. if (MacType == SK_MAC_XMAC) {
  5869. return (Val);
  5870. }
  5871. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5872. StatAddr[StatIndex][MacType].Reg,
  5873. &LowVal);
  5874. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5875. break;
  5876. case SK_PNMI_HTX_DEFFERAL:
  5877. /* Not supported by GMAC */
  5878. if (MacType == SK_MAC_GMAC) {
  5879. return (Val);
  5880. }
  5881. /*
  5882. * XMAC counts frames with deferred transmission
  5883. * even in full-duplex mode.
  5884. *
  5885. * In full-duplex mode the counter remains constant!
  5886. */
  5887. if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
  5888. (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
  5889. LowVal = 0;
  5890. HighVal = 0;
  5891. }
  5892. else {
  5893. /* Otherwise get contents of hardware register */
  5894. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5895. StatAddr[StatIndex][MacType].Reg,
  5896. &LowVal);
  5897. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5898. }
  5899. break;
  5900. case SK_PNMI_HRX_BADOCTET:
  5901. /* Not supported by XMAC */
  5902. if (MacType == SK_MAC_XMAC) {
  5903. return (Val);
  5904. }
  5905. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5906. StatAddr[StatIndex][MacType].Reg,
  5907. &HighVal);
  5908. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5909. StatAddr[StatIndex + 1][MacType].Reg,
  5910. &LowVal);
  5911. break;
  5912. case SK_PNMI_HTX_OCTETLOW:
  5913. case SK_PNMI_HRX_OCTETLOW:
  5914. case SK_PNMI_HRX_BADOCTETLOW:
  5915. return (Val);
  5916. case SK_PNMI_HRX_LONGFRAMES:
  5917. /* For XMAC the SW counter is managed by PNMI */
  5918. if (MacType == SK_MAC_XMAC) {
  5919. return (pPnmiPrt->StatRxLongFrameCts);
  5920. }
  5921. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5922. StatAddr[StatIndex][MacType].Reg,
  5923. &LowVal);
  5924. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5925. break;
  5926. case SK_PNMI_HRX_TOO_LONG:
  5927. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5928. StatAddr[StatIndex][MacType].Reg,
  5929. &LowVal);
  5930. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5931. Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
  5932. if (MacType == SK_MAC_GMAC) {
  5933. /* For GMAC the SW counter is additionally managed by PNMI */
  5934. Val += pPnmiPrt->StatRxFrameTooLongCts;
  5935. }
  5936. else {
  5937. /*
  5938. * Frames longer than IEEE 802.3 frame max size are counted
  5939. * by XMAC in frame_too_long counter even reception of long
  5940. * frames was enabled and the frame was correct.
  5941. * So correct the value by subtracting RxLongFrame counter.
  5942. */
  5943. Val -= pPnmiPrt->StatRxLongFrameCts;
  5944. }
  5945. LowVal = (SK_U32)Val;
  5946. HighVal = (SK_U32)(Val >> 32);
  5947. break;
  5948. case SK_PNMI_HRX_SHORTS:
  5949. /* Not supported by GMAC */
  5950. if (MacType == SK_MAC_GMAC) {
  5951. /* GM_RXE_FRAG?? */
  5952. return (Val);
  5953. }
  5954. /*
  5955. * XMAC counts short frame errors even if link down (#10620)
  5956. *
  5957. * If link-down the counter remains constant
  5958. */
  5959. if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
  5960. /* Otherwise get incremental difference */
  5961. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5962. StatAddr[StatIndex][MacType].Reg,
  5963. &LowVal);
  5964. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5965. Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
  5966. Val -= pPnmiPrt->RxShortZeroMark;
  5967. LowVal = (SK_U32)Val;
  5968. HighVal = (SK_U32)(Val >> 32);
  5969. }
  5970. break;
  5971. case SK_PNMI_HRX_MACC:
  5972. case SK_PNMI_HRX_MACC_UNKWN:
  5973. case SK_PNMI_HRX_BURST:
  5974. case SK_PNMI_HRX_MISSED:
  5975. case SK_PNMI_HRX_FRAMING:
  5976. case SK_PNMI_HRX_CARRIER:
  5977. case SK_PNMI_HRX_IRLENGTH:
  5978. case SK_PNMI_HRX_SYMBOL:
  5979. case SK_PNMI_HRX_CEXT:
  5980. /* Not supported by GMAC */
  5981. if (MacType == SK_MAC_GMAC) {
  5982. return (Val);
  5983. }
  5984. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5985. StatAddr[StatIndex][MacType].Reg,
  5986. &LowVal);
  5987. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5988. break;
  5989. case SK_PNMI_HRX_PMACC_ERR:
  5990. /* For GMAC the SW counter is managed by PNMI */
  5991. if (MacType == SK_MAC_GMAC) {
  5992. return (pPnmiPrt->StatRxPMaccErr);
  5993. }
  5994. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  5995. StatAddr[StatIndex][MacType].Reg,
  5996. &LowVal);
  5997. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  5998. break;
  5999. /* SW counter managed by PNMI */
  6000. case SK_PNMI_HTX_SYNC:
  6001. LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
  6002. HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
  6003. break;
  6004. /* SW counter managed by PNMI */
  6005. case SK_PNMI_HTX_SYNC_OCTET:
  6006. LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
  6007. HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
  6008. break;
  6009. case SK_PNMI_HRX_FCS:
  6010. /*
  6011. * Broadcom filters FCS errors and counts it in
  6012. * Receive Error Counter register
  6013. */
  6014. if (pPrt->PhyType == SK_PHY_BCOM) {
  6015. /* do not read while not initialized (PHY_READ hangs!)*/
  6016. if (pPrt->PState != SK_PRT_RESET) {
  6017. SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
  6018. LowVal = Word;
  6019. }
  6020. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  6021. }
  6022. else {
  6023. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  6024. StatAddr[StatIndex][MacType].Reg,
  6025. &LowVal);
  6026. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  6027. }
  6028. break;
  6029. default:
  6030. (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
  6031. StatAddr[StatIndex][MacType].Reg,
  6032. &LowVal);
  6033. HighVal = pPnmiPrt->CounterHigh[StatIndex];
  6034. break;
  6035. }
  6036. Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
  6037. /* Correct value because of possible XMAC reset. XMAC Errata #2 */
  6038. Val += pPnmiPrt->CounterOffset[StatIndex];
  6039. return (Val);
  6040. }
  6041. /*****************************************************************************
  6042. *
  6043. * ResetCounter - Set all counters and timestamps to zero
  6044. *
  6045. * Description:
  6046. * Notifies other common modules which store statistic data to
  6047. * reset their counters and finally reset our own counters.
  6048. *
  6049. * Returns:
  6050. * Nothing
  6051. */
  6052. PNMI_STATIC void ResetCounter(
  6053. SK_AC *pAC, /* Pointer to adapter context */
  6054. SK_IOC IoC, /* IO context handle */
  6055. SK_U32 NetIndex)
  6056. {
  6057. unsigned int PhysPortIndex;
  6058. SK_EVPARA EventParam;
  6059. SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
  6060. /* Notify sensor module */
  6061. SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
  6062. /* Notify RLMT module */
  6063. EventParam.Para32[0] = NetIndex;
  6064. EventParam.Para32[1] = (SK_U32)-1;
  6065. SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
  6066. EventParam.Para32[1] = 0;
  6067. /* Notify SIRQ module */
  6068. SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
  6069. /* Notify CSUM module */
  6070. #ifdef SK_USE_CSUM
  6071. EventParam.Para32[0] = NetIndex;
  6072. EventParam.Para32[1] = (SK_U32)-1;
  6073. SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
  6074. EventParam);
  6075. #endif /* SK_USE_CSUM */
  6076. /* Clear XMAC statistic */
  6077. for (PhysPortIndex = 0; PhysPortIndex <
  6078. (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
  6079. (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
  6080. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
  6081. 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
  6082. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  6083. CounterOffset, 0, sizeof(pAC->Pnmi.Port[
  6084. PhysPortIndex].CounterOffset));
  6085. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
  6086. 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
  6087. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  6088. StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
  6089. PhysPortIndex].StatSyncOctetsCts));
  6090. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  6091. StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
  6092. PhysPortIndex].StatRxLongFrameCts));
  6093. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  6094. StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
  6095. PhysPortIndex].StatRxFrameTooLongCts));
  6096. SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
  6097. StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
  6098. PhysPortIndex].StatRxPMaccErr));
  6099. }
  6100. /*
  6101. * Clear local statistics
  6102. */
  6103. SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
  6104. sizeof(pAC->Pnmi.VirtualCounterOffset));
  6105. pAC->Pnmi.RlmtChangeCts = 0;
  6106. pAC->Pnmi.RlmtChangeTime = 0;
  6107. SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
  6108. sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
  6109. pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
  6110. pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
  6111. pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
  6112. pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
  6113. pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
  6114. pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
  6115. pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
  6116. pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
  6117. pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
  6118. pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
  6119. pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
  6120. pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
  6121. }
  6122. /*****************************************************************************
  6123. *
  6124. * GetTrapEntry - Get an entry in the trap buffer
  6125. *
  6126. * Description:
  6127. * The trap buffer stores various events. A user application somehow
  6128. * gets notified that an event occured and retrieves the trap buffer
  6129. * contens (or simply polls the buffer). The buffer is organized as
  6130. * a ring which stores the newest traps at the beginning. The oldest
  6131. * traps are overwritten by the newest ones. Each trap entry has a
  6132. * unique number, so that applications may detect new trap entries.
  6133. *
  6134. * Returns:
  6135. * A pointer to the trap entry
  6136. */
  6137. PNMI_STATIC char* GetTrapEntry(
  6138. SK_AC *pAC, /* Pointer to adapter context */
  6139. SK_U32 TrapId, /* SNMP ID of the trap */
  6140. unsigned int Size) /* Space needed for trap entry */
  6141. {
  6142. unsigned int BufPad = pAC->Pnmi.TrapBufPad;
  6143. unsigned int BufFree = pAC->Pnmi.TrapBufFree;
  6144. unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
  6145. unsigned int End = pAC->Pnmi.TrapQueueEnd;
  6146. char *pBuf = &pAC->Pnmi.TrapBuf[0];
  6147. int Wrap;
  6148. unsigned int NeededSpace;
  6149. unsigned int EntrySize;
  6150. SK_U32 Val32;
  6151. SK_U64 Val64;
  6152. /* Last byte of entry will get a copy of the entry length */
  6153. Size ++;
  6154. /*
  6155. * Calculate needed buffer space */
  6156. if (Beg >= Size) {
  6157. NeededSpace = Size;
  6158. Wrap = SK_FALSE;
  6159. }
  6160. else {
  6161. NeededSpace = Beg + Size;
  6162. Wrap = SK_TRUE;
  6163. }
  6164. /*
  6165. * Check if enough buffer space is provided. Otherwise
  6166. * free some entries. Leave one byte space between begin
  6167. * and end of buffer to make it possible to detect whether
  6168. * the buffer is full or empty
  6169. */
  6170. while (BufFree < NeededSpace + 1) {
  6171. if (End == 0) {
  6172. End = SK_PNMI_TRAP_QUEUE_LEN;
  6173. }
  6174. EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
  6175. BufFree += EntrySize;
  6176. End -= EntrySize;
  6177. #ifdef DEBUG
  6178. SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
  6179. #endif /* DEBUG */
  6180. if (End == BufPad) {
  6181. #ifdef DEBUG
  6182. SK_MEMSET(pBuf, (char)(-1), End);
  6183. #endif /* DEBUG */
  6184. BufFree += End;
  6185. End = 0;
  6186. BufPad = 0;
  6187. }
  6188. }
  6189. /*
  6190. * Insert new entry as first entry. Newest entries are
  6191. * stored at the beginning of the queue.
  6192. */
  6193. if (Wrap) {
  6194. BufPad = Beg;
  6195. Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
  6196. }
  6197. else {
  6198. Beg = Beg - Size;
  6199. }
  6200. BufFree -= NeededSpace;
  6201. /* Save the current offsets */
  6202. pAC->Pnmi.TrapQueueBeg = Beg;
  6203. pAC->Pnmi.TrapQueueEnd = End;
  6204. pAC->Pnmi.TrapBufPad = BufPad;
  6205. pAC->Pnmi.TrapBufFree = BufFree;
  6206. /* Initialize the trap entry */
  6207. *(pBuf + Beg + Size - 1) = (char)Size;
  6208. *(pBuf + Beg) = (char)Size;
  6209. Val32 = (pAC->Pnmi.TrapUnique) ++;
  6210. SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
  6211. SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
  6212. Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
  6213. SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
  6214. return (pBuf + Beg);
  6215. }
  6216. /*****************************************************************************
  6217. *
  6218. * CopyTrapQueue - Copies the trap buffer for the TRAP OID
  6219. *
  6220. * Description:
  6221. * On a query of the TRAP OID the trap buffer contents will be
  6222. * copied continuously to the request buffer, which must be large
  6223. * enough. No length check is performed.
  6224. *
  6225. * Returns:
  6226. * Nothing
  6227. */
  6228. PNMI_STATIC void CopyTrapQueue(
  6229. SK_AC *pAC, /* Pointer to adapter context */
  6230. char *pDstBuf) /* Buffer to which the queued traps will be copied */
  6231. {
  6232. unsigned int BufPad = pAC->Pnmi.TrapBufPad;
  6233. unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
  6234. unsigned int End = pAC->Pnmi.TrapQueueEnd;
  6235. char *pBuf = &pAC->Pnmi.TrapBuf[0];
  6236. unsigned int Len;
  6237. unsigned int DstOff = 0;
  6238. while (Trap != End) {
  6239. Len = (unsigned int)*(pBuf + Trap);
  6240. /*
  6241. * Last byte containing a copy of the length will
  6242. * not be copied.
  6243. */
  6244. *(pDstBuf + DstOff) = (char)(Len - 1);
  6245. SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
  6246. DstOff += Len - 1;
  6247. Trap += Len;
  6248. if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
  6249. Trap = BufPad;
  6250. }
  6251. }
  6252. }
  6253. /*****************************************************************************
  6254. *
  6255. * GetTrapQueueLen - Get the length of the trap buffer
  6256. *
  6257. * Description:
  6258. * Evaluates the number of currently stored traps and the needed
  6259. * buffer size to retrieve them.
  6260. *
  6261. * Returns:
  6262. * Nothing
  6263. */
  6264. PNMI_STATIC void GetTrapQueueLen(
  6265. SK_AC *pAC, /* Pointer to adapter context */
  6266. unsigned int *pLen, /* Length in Bytes of all queued traps */
  6267. unsigned int *pEntries) /* Returns number of trapes stored in queue */
  6268. {
  6269. unsigned int BufPad = pAC->Pnmi.TrapBufPad;
  6270. unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
  6271. unsigned int End = pAC->Pnmi.TrapQueueEnd;
  6272. char *pBuf = &pAC->Pnmi.TrapBuf[0];
  6273. unsigned int Len;
  6274. unsigned int Entries = 0;
  6275. unsigned int TotalLen = 0;
  6276. while (Trap != End) {
  6277. Len = (unsigned int)*(pBuf + Trap);
  6278. TotalLen += Len - 1;
  6279. Entries ++;
  6280. Trap += Len;
  6281. if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
  6282. Trap = BufPad;
  6283. }
  6284. }
  6285. *pEntries = Entries;
  6286. *pLen = TotalLen;
  6287. }
  6288. /*****************************************************************************
  6289. *
  6290. * QueueSimpleTrap - Store a simple trap to the trap buffer
  6291. *
  6292. * Description:
  6293. * A simple trap is a trap with now additional data. It consists
  6294. * simply of a trap code.
  6295. *
  6296. * Returns:
  6297. * Nothing
  6298. */
  6299. PNMI_STATIC void QueueSimpleTrap(
  6300. SK_AC *pAC, /* Pointer to adapter context */
  6301. SK_U32 TrapId) /* Type of sensor trap */
  6302. {
  6303. GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
  6304. }
  6305. /*****************************************************************************
  6306. *
  6307. * QueueSensorTrap - Stores a sensor trap in the trap buffer
  6308. *
  6309. * Description:
  6310. * Gets an entry in the trap buffer and fills it with sensor related
  6311. * data.
  6312. *
  6313. * Returns:
  6314. * Nothing
  6315. */
  6316. PNMI_STATIC void QueueSensorTrap(
  6317. SK_AC *pAC, /* Pointer to adapter context */
  6318. SK_U32 TrapId, /* Type of sensor trap */
  6319. unsigned int SensorIndex) /* Index of sensor which caused the trap */
  6320. {
  6321. char *pBuf;
  6322. unsigned int Offset;
  6323. unsigned int DescrLen;
  6324. SK_U32 Val32;
  6325. /* Get trap buffer entry */
  6326. DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
  6327. pBuf = GetTrapEntry(pAC, TrapId,
  6328. SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
  6329. Offset = SK_PNMI_TRAP_SIMPLE_LEN;
  6330. /* Store additionally sensor trap related data */
  6331. Val32 = OID_SKGE_SENSOR_INDEX;
  6332. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  6333. *(pBuf + Offset + 4) = 4;
  6334. Val32 = (SK_U32)SensorIndex;
  6335. SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
  6336. Offset += 9;
  6337. Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
  6338. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  6339. *(pBuf + Offset + 4) = (char)DescrLen;
  6340. SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
  6341. DescrLen);
  6342. Offset += DescrLen + 5;
  6343. Val32 = OID_SKGE_SENSOR_TYPE;
  6344. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  6345. *(pBuf + Offset + 4) = 1;
  6346. *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
  6347. Offset += 6;
  6348. Val32 = OID_SKGE_SENSOR_VALUE;
  6349. SK_PNMI_STORE_U32(pBuf + Offset, Val32);
  6350. *(pBuf + Offset + 4) = 4;
  6351. Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
  6352. SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
  6353. }
  6354. /*****************************************************************************
  6355. *
  6356. * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
  6357. *
  6358. * Description:
  6359. * Nothing further to explain.
  6360. *
  6361. * Returns:
  6362. * Nothing
  6363. */
  6364. PNMI_STATIC void QueueRlmtNewMacTrap(
  6365. SK_AC *pAC, /* Pointer to adapter context */
  6366. unsigned int ActiveMac) /* Index (0..n) of the currently active port */
  6367. {
  6368. char *pBuf;
  6369. SK_U32 Val32;
  6370. pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
  6371. SK_PNMI_TRAP_RLMT_CHANGE_LEN);
  6372. Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
  6373. SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
  6374. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
  6375. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
  6376. }
  6377. /*****************************************************************************
  6378. *
  6379. * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
  6380. *
  6381. * Description:
  6382. * Nothing further to explain.
  6383. *
  6384. * Returns:
  6385. * Nothing
  6386. */
  6387. PNMI_STATIC void QueueRlmtPortTrap(
  6388. SK_AC *pAC, /* Pointer to adapter context */
  6389. SK_U32 TrapId, /* Type of RLMT port trap */
  6390. unsigned int PortIndex) /* Index of the port, which changed its state */
  6391. {
  6392. char *pBuf;
  6393. SK_U32 Val32;
  6394. pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
  6395. Val32 = OID_SKGE_RLMT_PORT_INDEX;
  6396. SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
  6397. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
  6398. *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
  6399. }
  6400. /*****************************************************************************
  6401. *
  6402. * CopyMac - Copies a MAC address
  6403. *
  6404. * Description:
  6405. * Nothing further to explain.
  6406. *
  6407. * Returns:
  6408. * Nothing
  6409. */
  6410. PNMI_STATIC void CopyMac(
  6411. char *pDst, /* Pointer to destination buffer */
  6412. SK_MAC_ADDR *pMac) /* Pointer of Source */
  6413. {
  6414. int i;
  6415. for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
  6416. *(pDst + i) = pMac->a[i];
  6417. }
  6418. }
  6419. #ifdef SK_POWER_MGMT
  6420. /*****************************************************************************
  6421. *
  6422. * PowerManagement - OID handler function of PowerManagement OIDs
  6423. *
  6424. * Description:
  6425. * The code is simple. No description necessary.
  6426. *
  6427. * Returns:
  6428. * SK_PNMI_ERR_OK The request was successfully performed.
  6429. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  6430. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  6431. * the correct data (e.g. a 32bit value is
  6432. * needed, but a 16 bit value was passed).
  6433. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  6434. * exist (e.g. port instance 3 on a two port
  6435. * adapter.
  6436. */
  6437. PNMI_STATIC int PowerManagement(
  6438. SK_AC *pAC, /* Pointer to adapter context */
  6439. SK_IOC IoC, /* IO context handle */
  6440. int Action, /* Get/PreSet/Set action */
  6441. SK_U32 Id, /* Object ID that is to be processed */
  6442. char *pBuf, /* Buffer to which to mgmt data will be retrieved */
  6443. unsigned int *pLen, /* On call: buffer length. On return: used buffer */
  6444. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  6445. unsigned int TableIndex, /* Index to the Id table */
  6446. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
  6447. {
  6448. SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
  6449. /*
  6450. * Check instance. We only handle single instance variables
  6451. */
  6452. if (Instance != (SK_U32)(-1) && Instance != 1) {
  6453. *pLen = 0;
  6454. return (SK_PNMI_ERR_UNKNOWN_INST);
  6455. }
  6456. /* Check length */
  6457. switch (Id) {
  6458. case OID_PNP_CAPABILITIES:
  6459. if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
  6460. *pLen = sizeof(SK_PNP_CAPABILITIES);
  6461. return (SK_PNMI_ERR_TOO_SHORT);
  6462. }
  6463. break;
  6464. case OID_PNP_SET_POWER:
  6465. case OID_PNP_QUERY_POWER:
  6466. if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
  6467. {
  6468. *pLen = sizeof(SK_DEVICE_POWER_STATE);
  6469. return (SK_PNMI_ERR_TOO_SHORT);
  6470. }
  6471. break;
  6472. case OID_PNP_ADD_WAKE_UP_PATTERN:
  6473. case OID_PNP_REMOVE_WAKE_UP_PATTERN:
  6474. if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
  6475. *pLen = sizeof(SK_PM_PACKET_PATTERN);
  6476. return (SK_PNMI_ERR_TOO_SHORT);
  6477. }
  6478. break;
  6479. case OID_PNP_ENABLE_WAKE_UP:
  6480. if (*pLen < sizeof(SK_U32)) {
  6481. *pLen = sizeof(SK_U32);
  6482. return (SK_PNMI_ERR_TOO_SHORT);
  6483. }
  6484. break;
  6485. }
  6486. /*
  6487. * Perform action
  6488. */
  6489. if (Action == SK_PNMI_GET) {
  6490. /*
  6491. * Get value
  6492. */
  6493. switch (Id) {
  6494. case OID_PNP_CAPABILITIES:
  6495. RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
  6496. break;
  6497. case OID_PNP_QUERY_POWER:
  6498. /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
  6499. the miniport to indicate whether it can transition its NIC
  6500. to the low-power state.
  6501. A miniport driver must always return NDIS_STATUS_SUCCESS
  6502. to a query of OID_PNP_QUERY_POWER. */
  6503. *pLen = sizeof(SK_DEVICE_POWER_STATE);
  6504. RetCode = SK_PNMI_ERR_OK;
  6505. break;
  6506. /* NDIS handles these OIDs as write-only.
  6507. * So in case of get action the buffer with written length = 0
  6508. * is returned
  6509. */
  6510. case OID_PNP_SET_POWER:
  6511. case OID_PNP_ADD_WAKE_UP_PATTERN:
  6512. case OID_PNP_REMOVE_WAKE_UP_PATTERN:
  6513. *pLen = 0;
  6514. RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
  6515. break;
  6516. case OID_PNP_ENABLE_WAKE_UP:
  6517. RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
  6518. break;
  6519. default:
  6520. RetCode = SK_PNMI_ERR_GENERAL;
  6521. break;
  6522. }
  6523. return (RetCode);
  6524. }
  6525. /*
  6526. * Perform preset or set
  6527. */
  6528. /* POWER module does not support PRESET action */
  6529. if (Action == SK_PNMI_PRESET) {
  6530. return (SK_PNMI_ERR_OK);
  6531. }
  6532. switch (Id) {
  6533. case OID_PNP_SET_POWER:
  6534. RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
  6535. break;
  6536. case OID_PNP_ADD_WAKE_UP_PATTERN:
  6537. RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
  6538. break;
  6539. case OID_PNP_REMOVE_WAKE_UP_PATTERN:
  6540. RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
  6541. break;
  6542. case OID_PNP_ENABLE_WAKE_UP:
  6543. RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
  6544. break;
  6545. default:
  6546. RetCode = SK_PNMI_ERR_READ_ONLY;
  6547. }
  6548. return (RetCode);
  6549. }
  6550. #endif /* SK_POWER_MGMT */
  6551. #ifdef SK_DIAG_SUPPORT
  6552. /*****************************************************************************
  6553. *
  6554. * DiagActions - OID handler function of Diagnostic driver
  6555. *
  6556. * Description:
  6557. * The code is simple. No description necessary.
  6558. *
  6559. * Returns:
  6560. * SK_PNMI_ERR_OK The request was successfully performed.
  6561. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  6562. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  6563. * the correct data (e.g. a 32bit value is
  6564. * needed, but a 16 bit value was passed).
  6565. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  6566. * exist (e.g. port instance 3 on a two port
  6567. * adapter.
  6568. */
  6569. PNMI_STATIC int DiagActions(
  6570. SK_AC *pAC, /* Pointer to adapter context */
  6571. SK_IOC IoC, /* IO context handle */
  6572. int Action, /* GET/PRESET/SET action */
  6573. SK_U32 Id, /* Object ID that is to be processed */
  6574. char *pBuf, /* Buffer used for the management data transfer */
  6575. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  6576. SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
  6577. unsigned int TableIndex, /* Index to the Id table */
  6578. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  6579. {
  6580. SK_U32 DiagStatus;
  6581. SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
  6582. /*
  6583. * Check instance. We only handle single instance variables.
  6584. */
  6585. if (Instance != (SK_U32)(-1) && Instance != 1) {
  6586. *pLen = 0;
  6587. return (SK_PNMI_ERR_UNKNOWN_INST);
  6588. }
  6589. /*
  6590. * Check length.
  6591. */
  6592. switch (Id) {
  6593. case OID_SKGE_DIAG_MODE:
  6594. if (*pLen < sizeof(SK_U32)) {
  6595. *pLen = sizeof(SK_U32);
  6596. return (SK_PNMI_ERR_TOO_SHORT);
  6597. }
  6598. break;
  6599. default:
  6600. SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
  6601. *pLen = 0;
  6602. return (SK_PNMI_ERR_GENERAL);
  6603. }
  6604. /* Perform action. */
  6605. /* GET value. */
  6606. if (Action == SK_PNMI_GET) {
  6607. switch (Id) {
  6608. case OID_SKGE_DIAG_MODE:
  6609. DiagStatus = pAC->Pnmi.DiagAttached;
  6610. SK_PNMI_STORE_U32(pBuf, DiagStatus);
  6611. *pLen = sizeof(SK_U32);
  6612. RetCode = SK_PNMI_ERR_OK;
  6613. break;
  6614. default:
  6615. *pLen = 0;
  6616. RetCode = SK_PNMI_ERR_GENERAL;
  6617. break;
  6618. }
  6619. return (RetCode);
  6620. }
  6621. /* From here SET or PRESET value. */
  6622. /* PRESET value is not supported. */
  6623. if (Action == SK_PNMI_PRESET) {
  6624. return (SK_PNMI_ERR_OK);
  6625. }
  6626. /* SET value. */
  6627. switch (Id) {
  6628. case OID_SKGE_DIAG_MODE:
  6629. /* Handle the SET. */
  6630. switch (*pBuf) {
  6631. /* Attach the DIAG to this adapter. */
  6632. case SK_DIAG_ATTACHED:
  6633. /* Check if we come from running */
  6634. if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
  6635. RetCode = SkDrvLeaveDiagMode(pAC);
  6636. }
  6637. else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
  6638. RetCode = SK_PNMI_ERR_OK;
  6639. }
  6640. else {
  6641. RetCode = SK_PNMI_ERR_GENERAL;
  6642. }
  6643. if (RetCode == SK_PNMI_ERR_OK) {
  6644. pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
  6645. }
  6646. break;
  6647. /* Enter the DIAG mode in the driver. */
  6648. case SK_DIAG_RUNNING:
  6649. RetCode = SK_PNMI_ERR_OK;
  6650. /*
  6651. * If DiagAttached is set, we can tell the driver
  6652. * to enter the DIAG mode.
  6653. */
  6654. if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
  6655. /* If DiagMode is not active, we can enter it. */
  6656. if (!pAC->DiagModeActive) {
  6657. RetCode = SkDrvEnterDiagMode(pAC);
  6658. }
  6659. else {
  6660. RetCode = SK_PNMI_ERR_GENERAL;
  6661. }
  6662. }
  6663. else {
  6664. RetCode = SK_PNMI_ERR_GENERAL;
  6665. }
  6666. if (RetCode == SK_PNMI_ERR_OK) {
  6667. pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
  6668. }
  6669. break;
  6670. case SK_DIAG_IDLE:
  6671. /* Check if we come from running */
  6672. if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
  6673. RetCode = SkDrvLeaveDiagMode(pAC);
  6674. }
  6675. else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
  6676. RetCode = SK_PNMI_ERR_OK;
  6677. }
  6678. else {
  6679. RetCode = SK_PNMI_ERR_GENERAL;
  6680. }
  6681. if (RetCode == SK_PNMI_ERR_OK) {
  6682. pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
  6683. }
  6684. break;
  6685. default:
  6686. RetCode = SK_PNMI_ERR_BAD_VALUE;
  6687. break;
  6688. }
  6689. break;
  6690. default:
  6691. RetCode = SK_PNMI_ERR_GENERAL;
  6692. }
  6693. if (RetCode == SK_PNMI_ERR_OK) {
  6694. *pLen = sizeof(SK_U32);
  6695. }
  6696. else {
  6697. *pLen = 0;
  6698. }
  6699. return (RetCode);
  6700. }
  6701. #endif /* SK_DIAG_SUPPORT */
  6702. /*****************************************************************************
  6703. *
  6704. * Vct - OID handler function of OIDs
  6705. *
  6706. * Description:
  6707. * The code is simple. No description necessary.
  6708. *
  6709. * Returns:
  6710. * SK_PNMI_ERR_OK The request was performed successfully.
  6711. * SK_PNMI_ERR_GENERAL A general severe internal error occured.
  6712. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
  6713. * the correct data (e.g. a 32bit value is
  6714. * needed, but a 16 bit value was passed).
  6715. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  6716. * exist (e.g. port instance 3 on a two port
  6717. * adapter).
  6718. * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
  6719. *
  6720. */
  6721. PNMI_STATIC int Vct(
  6722. SK_AC *pAC, /* Pointer to adapter context */
  6723. SK_IOC IoC, /* IO context handle */
  6724. int Action, /* GET/PRESET/SET action */
  6725. SK_U32 Id, /* Object ID that is to be processed */
  6726. char *pBuf, /* Buffer used for the management data transfer */
  6727. unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
  6728. SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
  6729. unsigned int TableIndex, /* Index to the Id table */
  6730. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  6731. {
  6732. SK_GEPORT *pPrt;
  6733. SK_PNMI_VCT *pVctBackupData;
  6734. SK_U32 LogPortMax;
  6735. SK_U32 PhysPortMax;
  6736. SK_U32 PhysPortIndex;
  6737. SK_U32 Limit;
  6738. SK_U32 Offset;
  6739. SK_BOOL Link;
  6740. SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
  6741. int i;
  6742. SK_EVPARA Para;
  6743. SK_U32 CableLength;
  6744. /*
  6745. * Calculate the port indexes from the instance.
  6746. */
  6747. PhysPortMax = pAC->GIni.GIMacsFound;
  6748. LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
  6749. /* Dual net mode? */
  6750. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  6751. LogPortMax--;
  6752. }
  6753. if ((Instance != (SK_U32) (-1))) {
  6754. /* Check instance range. */
  6755. if ((Instance < 2) || (Instance > LogPortMax)) {
  6756. *pLen = 0;
  6757. return (SK_PNMI_ERR_UNKNOWN_INST);
  6758. }
  6759. if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
  6760. PhysPortIndex = NetIndex;
  6761. }
  6762. else {
  6763. PhysPortIndex = Instance - 2;
  6764. }
  6765. Limit = PhysPortIndex + 1;
  6766. }
  6767. else {
  6768. /*
  6769. * Instance == (SK_U32) (-1), get all Instances of that OID.
  6770. *
  6771. * Not implemented yet. May be used in future releases.
  6772. */
  6773. PhysPortIndex = 0;
  6774. Limit = PhysPortMax;
  6775. }
  6776. pPrt = &pAC->GIni.GP[PhysPortIndex];
  6777. if (pPrt->PHWLinkUp) {
  6778. Link = SK_TRUE;
  6779. }
  6780. else {
  6781. Link = SK_FALSE;
  6782. }
  6783. /* Check MAC type */
  6784. if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
  6785. *pLen = 0;
  6786. return (SK_PNMI_ERR_GENERAL);
  6787. }
  6788. /* Initialize backup data pointer. */
  6789. pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
  6790. /* Check action type */
  6791. if (Action == SK_PNMI_GET) {
  6792. /* Check length */
  6793. switch (Id) {
  6794. case OID_SKGE_VCT_GET:
  6795. if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
  6796. *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
  6797. return (SK_PNMI_ERR_TOO_SHORT);
  6798. }
  6799. break;
  6800. case OID_SKGE_VCT_STATUS:
  6801. if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
  6802. *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
  6803. return (SK_PNMI_ERR_TOO_SHORT);
  6804. }
  6805. break;
  6806. default:
  6807. *pLen = 0;
  6808. return (SK_PNMI_ERR_GENERAL);
  6809. }
  6810. /* Get value */
  6811. Offset = 0;
  6812. for (; PhysPortIndex < Limit; PhysPortIndex++) {
  6813. switch (Id) {
  6814. case OID_SKGE_VCT_GET:
  6815. if ((Link == SK_FALSE) &&
  6816. (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
  6817. RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
  6818. if (RetCode == 0) {
  6819. pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
  6820. pAC->Pnmi.VctStatus[PhysPortIndex] |=
  6821. (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
  6822. /* Copy results for later use to PNMI struct. */
  6823. for (i = 0; i < 4; i++) {
  6824. if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
  6825. if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
  6826. pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
  6827. }
  6828. }
  6829. if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
  6830. CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
  6831. }
  6832. else {
  6833. CableLength = 0;
  6834. }
  6835. pVctBackupData->PMdiPairLen[i] = CableLength;
  6836. pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
  6837. }
  6838. Para.Para32[0] = PhysPortIndex;
  6839. Para.Para32[1] = -1;
  6840. SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
  6841. SkEventDispatcher(pAC, IoC);
  6842. }
  6843. else {
  6844. ; /* VCT test is running. */
  6845. }
  6846. }
  6847. /* Get all results. */
  6848. CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
  6849. Offset += sizeof(SK_U8);
  6850. *(pBuf + Offset) = pPrt->PCableLen;
  6851. Offset += sizeof(SK_U8);
  6852. for (i = 0; i < 4; i++) {
  6853. SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
  6854. Offset += sizeof(SK_U32);
  6855. }
  6856. for (i = 0; i < 4; i++) {
  6857. *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
  6858. Offset += sizeof(SK_U8);
  6859. }
  6860. RetCode = SK_PNMI_ERR_OK;
  6861. break;
  6862. case OID_SKGE_VCT_STATUS:
  6863. CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
  6864. Offset += sizeof(SK_U8);
  6865. RetCode = SK_PNMI_ERR_OK;
  6866. break;
  6867. default:
  6868. *pLen = 0;
  6869. return (SK_PNMI_ERR_GENERAL);
  6870. }
  6871. } /* for */
  6872. *pLen = Offset;
  6873. return (RetCode);
  6874. } /* if SK_PNMI_GET */
  6875. /*
  6876. * From here SET or PRESET action. Check if the passed
  6877. * buffer length is plausible.
  6878. */
  6879. /* Check length */
  6880. switch (Id) {
  6881. case OID_SKGE_VCT_SET:
  6882. if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
  6883. *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
  6884. return (SK_PNMI_ERR_TOO_SHORT);
  6885. }
  6886. break;
  6887. default:
  6888. *pLen = 0;
  6889. return (SK_PNMI_ERR_GENERAL);
  6890. }
  6891. /*
  6892. * Perform preset or set.
  6893. */
  6894. /* VCT does not support PRESET action. */
  6895. if (Action == SK_PNMI_PRESET) {
  6896. return (SK_PNMI_ERR_OK);
  6897. }
  6898. Offset = 0;
  6899. for (; PhysPortIndex < Limit; PhysPortIndex++) {
  6900. switch (Id) {
  6901. case OID_SKGE_VCT_SET: /* Start VCT test. */
  6902. if (Link == SK_FALSE) {
  6903. SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
  6904. RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
  6905. if (RetCode == 0) { /* RetCode: 0 => Start! */
  6906. pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
  6907. pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
  6908. pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
  6909. /*
  6910. * Start VCT timer counter.
  6911. */
  6912. SK_MEMSET((char *) &Para, 0, sizeof(Para));
  6913. Para.Para32[0] = PhysPortIndex;
  6914. Para.Para32[1] = -1;
  6915. SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
  6916. 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
  6917. SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
  6918. RetCode = SK_PNMI_ERR_OK;
  6919. }
  6920. else { /* RetCode: 2 => Running! */
  6921. SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
  6922. RetCode = SK_PNMI_ERR_OK;
  6923. }
  6924. }
  6925. else { /* RetCode: 4 => Link! */
  6926. RetCode = 4;
  6927. SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
  6928. RetCode = SK_PNMI_ERR_OK;
  6929. }
  6930. Offset += sizeof(SK_U32);
  6931. break;
  6932. default:
  6933. *pLen = 0;
  6934. return (SK_PNMI_ERR_GENERAL);
  6935. }
  6936. } /* for */
  6937. *pLen = Offset;
  6938. return (RetCode);
  6939. } /* Vct */
  6940. PNMI_STATIC void CheckVctStatus(
  6941. SK_AC *pAC,
  6942. SK_IOC IoC,
  6943. char *pBuf,
  6944. SK_U32 Offset,
  6945. SK_U32 PhysPortIndex)
  6946. {
  6947. SK_GEPORT *pPrt;
  6948. SK_PNMI_VCT *pVctData;
  6949. SK_U32 RetCode;
  6950. pPrt = &pAC->GIni.GP[PhysPortIndex];
  6951. pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
  6952. pVctData->VctStatus = SK_PNMI_VCT_NONE;
  6953. if (!pPrt->PHWLinkUp) {
  6954. /* Was a VCT test ever made before? */
  6955. if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
  6956. if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
  6957. pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
  6958. }
  6959. else {
  6960. pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
  6961. }
  6962. }
  6963. /* Check VCT test status. */
  6964. RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
  6965. if (RetCode == 2) { /* VCT test is running. */
  6966. pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
  6967. }
  6968. else { /* VCT data was copied to pAC here. Check PENDING state. */
  6969. if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
  6970. pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
  6971. }
  6972. }
  6973. if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
  6974. pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
  6975. }
  6976. }
  6977. else {
  6978. /* Was a VCT test ever made before? */
  6979. if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
  6980. pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
  6981. pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
  6982. }
  6983. /* DSP only valid in 100/1000 modes. */
  6984. if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
  6985. SK_LSPEED_STAT_10MBPS) {
  6986. pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
  6987. }
  6988. }
  6989. } /* CheckVctStatus */
  6990. /*****************************************************************************
  6991. *
  6992. * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
  6993. * PNMI function depending on the subcommand and
  6994. * returns all data belonging to the complete database
  6995. * or OID request.
  6996. *
  6997. * Description:
  6998. * Looks up the requested subcommand, calls the corresponding handler
  6999. * function and passes all required parameters to it.
  7000. * The function is called by the driver. It is needed to handle the new
  7001. * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
  7002. * the OID and a subcommand to decide what kind of request has to be done.
  7003. *
  7004. * Returns:
  7005. * SK_PNMI_ERR_OK The request was successfully performed
  7006. * SK_PNMI_ERR_GENERAL A general severe internal error occured
  7007. * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
  7008. * the data.
  7009. * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
  7010. * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
  7011. * exist (e.g. port instance 3 on a two port
  7012. * adapter.
  7013. */
  7014. int SkPnmiGenIoctl(
  7015. SK_AC *pAC, /* Pointer to adapter context struct */
  7016. SK_IOC IoC, /* I/O context */
  7017. void *pBuf, /* Buffer used for the management data transfer */
  7018. unsigned int *pLen, /* Length of buffer */
  7019. SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
  7020. {
  7021. SK_I32 Mode; /* Store value of subcommand. */
  7022. SK_U32 Oid; /* Store value of OID. */
  7023. int ReturnCode; /* Store return value to show status of PNMI action. */
  7024. int HeaderLength; /* Length of desired action plus OID. */
  7025. ReturnCode = SK_PNMI_ERR_GENERAL;
  7026. SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
  7027. SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
  7028. HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
  7029. *pLen = *pLen - HeaderLength;
  7030. SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
  7031. switch(Mode) {
  7032. case SK_GET_SINGLE_VAR:
  7033. ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
  7034. (char *) pBuf + sizeof(SK_I32), pLen,
  7035. ((SK_U32) (-1)), NetIndex);
  7036. SK_PNMI_STORE_U32(pBuf, ReturnCode);
  7037. *pLen = *pLen + sizeof(SK_I32);
  7038. break;
  7039. case SK_PRESET_SINGLE_VAR:
  7040. ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
  7041. (char *) pBuf + sizeof(SK_I32), pLen,
  7042. ((SK_U32) (-1)), NetIndex);
  7043. SK_PNMI_STORE_U32(pBuf, ReturnCode);
  7044. *pLen = *pLen + sizeof(SK_I32);
  7045. break;
  7046. case SK_SET_SINGLE_VAR:
  7047. ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
  7048. (char *) pBuf + sizeof(SK_I32), pLen,
  7049. ((SK_U32) (-1)), NetIndex);
  7050. SK_PNMI_STORE_U32(pBuf, ReturnCode);
  7051. *pLen = *pLen + sizeof(SK_I32);
  7052. break;
  7053. case SK_GET_FULL_MIB:
  7054. ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
  7055. break;
  7056. case SK_PRESET_FULL_MIB:
  7057. ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
  7058. break;
  7059. case SK_SET_FULL_MIB:
  7060. ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
  7061. break;
  7062. default:
  7063. break;
  7064. }
  7065. return (ReturnCode);
  7066. } /* SkGeIocGen */