ipmi_delloem.c 126 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247
  1. /*
  2. * Copyright (c) 2008, Dell Inc
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. * - Redistributions of source code must retain the above copyright notice,
  7. * this list of conditions and the following disclaimer.
  8. *
  9. * - Redistributions in binary form must reproduce the above copyright notice,
  10. * this list of conditions and the following disclaimer in the documentation
  11. * and/or other materials provided with the distribution.
  12. * - Neither the name of Dell Inc nor the names of its contributors
  13. * may be used to endorse or promote products derived from this software
  14. * without specific prior written permission.
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  19. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. /*
  28. * Thursday Oct 7 17:30:12 2009
  29. * <deepaganesh_paulraj@dell.com>
  30. *
  31. * This code implements a dell OEM proprietary commands.
  32. * This Code is edited and Implemented the License feature for Delloem
  33. * Author Harsha S <Harsha_S1@dell.com>
  34. */
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <sys/types.h>
  39. #include <sys/socket.h>
  40. #include <netinet/in.h>
  41. #include <arpa/inet.h>
  42. #include <errno.h>
  43. #include <unistd.h>
  44. #include <signal.h>
  45. #include <ctype.h>
  46. #include <limits.h>
  47. #include <time.h>
  48. #include <ipmitool/ipmi.h>
  49. #include <ipmitool/ipmi_intf.h>
  50. #include <ipmitool/helper.h>
  51. #include <ipmitool/log.h>
  52. #include <ipmitool/ipmi_sel.h>
  53. #include <ipmitool/ipmi_delloem.h>
  54. #include <ipmitool/ipmi_fru.h>
  55. #include <ipmitool/ipmi_sdr.h>
  56. #include <ipmitool/ipmi_mc.h>
  57. #include <ipmitool/ipmi_sensor.h>
  58. #include <ipmitool/ipmi_sel.h>
  59. #include <ipmitool/bswap.h>
  60. #include <ipmitool/ipmi_sdr.h>
  61. #include <ipmitool/ipmi_entity.h>
  62. #include <ipmitool/ipmi_fru.h>
  63. #include <ipmitool/ipmi_sensor.h>
  64. #define DELL_OEM_NETFN (uint8_t)(0x30)
  65. #define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9)
  66. /* 11g Support Macros */
  67. #define INVALID (-1)
  68. #define SHARED 0
  69. #define SHARED_WITH_FAILOVER_LOM2 1
  70. #define DEDICATED 2
  71. #define SHARED_WITH_FAILOVER_ALL_LOMS 3
  72. /* 11g Support Macros */
  73. #define SHARED 0
  74. #define SHARED_WITH_FAILOVER_LOM2 1
  75. #define DEDICATED 2
  76. #define SHARED_WITH_FAILOVER_ALL_LOMS 3
  77. /* 12g Support Strings for nic selection */
  78. #define INVAILD_FAILOVER_MODE -2
  79. #define INVAILD_FAILOVER_MODE_SETTINGS -3
  80. #define INVAILD_SHARED_MODE -4
  81. #define INVAILD_FAILOVER_MODE_STRING "ERROR: Cannot set shared with failover lom same as current shared lom."
  82. #define INVAILD_FAILOVER_MODE_SET "ERROR: Cannot set shared with failover loms when NIC is set to dedicated Mode."
  83. #define INVAILD_SHARED_MODE_SET_STRING "ERROR: Cannot set shared Mode for Blades."
  84. char AciveLOM_String [6] [10] = {
  85. "None",
  86. "LOM1",
  87. "LOM2",
  88. "LOM3",
  89. "LOM4",
  90. "dedicated"
  91. };
  92. /* 11g Support Strings for nic selection */
  93. char NIC_Selection_Mode_String [4] [50] = {
  94. "shared",
  95. "shared with failover lom2",
  96. "dedicated",
  97. "shared with Failover all loms"
  98. };
  99. char NIC_Selection_Mode_String_12g[] [50] = {
  100. "dedicated",
  101. "shared with lom1",
  102. "shared with lom2",
  103. "shared with lom3",
  104. "shared with lom4",
  105. "shared with failover lom1",
  106. "shared with failover lom2",
  107. "shared with failover lom3",
  108. "shared with failover lom4",
  109. "shared with failover all loms"
  110. };
  111. const struct vFlashstr vFlash_completion_code_vals[] = {
  112. {0x00, "SUCCESS"},
  113. {0x01, "NO_SD_CARD"},
  114. {0x63, "UNKNOWN_ERROR"},
  115. {0x00, NULL}
  116. };
  117. static int current_arg =0;
  118. uint8_t iDRAC_FLAG=0;
  119. /*
  120. * new flags for
  121. * 11G || 12G || 13G -> _ALL
  122. * 12G || 13G -> _12_13
  123. *
  124. */
  125. uint8_t iDRAC_FLAG_ALL=0;
  126. uint8_t iDRAC_FLAG_12_13=0;
  127. LCD_MODE lcd_mode;
  128. static uint8_t LcdSupported=0;
  129. static uint8_t SetLEDSupported=0;
  130. volatile uint8_t IMC_Type = IMC_IDRAC_10G;
  131. POWER_HEADROOM powerheadroom;
  132. uint8_t PowercapSetable_flag=0;
  133. uint8_t PowercapstatusFlag=0;
  134. static void usage(void);
  135. /* LCD Function prototypes */
  136. static int ipmi_delloem_lcd_main(struct ipmi_intf *intf, int argc,
  137. char **argv);
  138. int ipmi_lcd_get_platform_model_name(struct ipmi_intf *intf, char *lcdstring,
  139. uint8_t max_length, uint8_t field_type);
  140. static int ipmi_idracvalidator_command(struct ipmi_intf *intf);
  141. static int ipmi_lcd_get_configure_command_wh(struct ipmi_intf *intf);
  142. static int ipmi_lcd_get_configure_command(struct ipmi_intf *intf,
  143. uint8_t *command);
  144. static int ipmi_lcd_set_configure_command(struct ipmi_intf *intf, int command);
  145. static int ipmi_lcd_set_configure_command_wh(struct ipmi_intf *intf, uint32_t mode,
  146. uint16_t lcdquallifier,uint8_t errordisp);
  147. static int ipmi_lcd_get_single_line_text(struct ipmi_intf *intf,
  148. char *lcdstring, uint8_t max_length);
  149. static int ipmi_lcd_get_info_wh(struct ipmi_intf *intf);
  150. static int ipmi_lcd_get_info(struct ipmi_intf *intf);
  151. static int ipmi_lcd_get_status_val(struct ipmi_intf *intf,
  152. LCD_STATUS *lcdstatus);
  153. static int IsLCDSupported();
  154. static void CheckLCDSupport(struct ipmi_intf *intf);
  155. static void ipmi_lcd_status_print(LCD_STATUS lcdstatus);
  156. static int ipmi_lcd_get_status(struct ipmi_intf *intf);
  157. static int ipmi_lcd_set_kvm(struct ipmi_intf *intf, char status);
  158. static int ipmi_lcd_set_lock(struct ipmi_intf *intf, char lock);
  159. static int ipmi_lcd_set_single_line_text(struct ipmi_intf *intf, char *text);
  160. static int ipmi_lcd_set_text(struct ipmi_intf *intf, char *text,
  161. int line_number);
  162. static int ipmi_lcd_configure_wh(struct ipmi_intf *intf, uint32_t mode,
  163. uint16_t lcdquallifier, uint8_t errordisp, int8_t line_number, char *text);
  164. static int ipmi_lcd_configure(struct ipmi_intf *intf, int command,
  165. int8_t line_number, char *text);
  166. static void ipmi_lcd_usage(void);
  167. /* MAC Function prototypes */
  168. static int ipmi_delloem_mac_main(struct ipmi_intf *intf, int argc, char **argv);
  169. static void InitEmbeddedNICMacAddressValues();
  170. static int ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf *intf,
  171. uint8_t NicNum);
  172. static int ipmi_macinfo_drac_idrac_mac(struct ipmi_intf *intf,uint8_t NicNum);
  173. static int ipmi_macinfo_10g(struct ipmi_intf *intf, uint8_t NicNum);
  174. static int ipmi_macinfo_11g(struct ipmi_intf *intf, uint8_t NicNum);
  175. static int ipmi_macinfo(struct ipmi_intf *intf, uint8_t NicNum);
  176. static void ipmi_mac_usage(void);
  177. /* LAN Function prototypes */
  178. static int ipmi_delloem_lan_main(struct ipmi_intf *intf, int argc, char **argv);
  179. static int IsLANSupported();
  180. static int get_nic_selection_mode(int current_arg, char **argv);
  181. static int ipmi_lan_set_nic_selection(struct ipmi_intf *intf,
  182. uint8_t nic_selection);
  183. static int ipmi_lan_get_nic_selection(struct ipmi_intf *intf);
  184. static int ipmi_lan_get_active_nic(struct ipmi_intf *intf);
  185. static void ipmi_lan_usage(void);
  186. static int ipmi_lan_set_nic_selection_12g(struct ipmi_intf *intf,
  187. uint8_t *nic_selection);
  188. /* Power monitor Function prototypes */
  189. static int ipmi_delloem_powermonitor_main(struct ipmi_intf *intf, int argc,
  190. char **argv);
  191. static void ipmi_time_to_str(time_t rawTime, char *strTime);
  192. static int ipmi_get_sensor_reading(struct ipmi_intf *intf,
  193. unsigned char sensorNumber, SensorReadingType *pSensorReadingData);
  194. static int ipmi_get_power_capstatus_command(struct ipmi_intf *intf);
  195. static int ipmi_set_power_capstatus_command(struct ipmi_intf *intf,
  196. uint8_t val);
  197. static int ipmi_powermgmt(struct ipmi_intf *intf);
  198. static int ipmi_powermgmt_clear(struct ipmi_intf *intf, uint8_t clearValue);
  199. static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt);
  200. static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr);
  201. static int ipmi_get_power_headroom_command(struct ipmi_intf *intf, uint8_t unit);
  202. static int ipmi_get_power_consumption_data(struct ipmi_intf *intf, uint8_t unit);
  203. static int ipmi_get_instan_power_consmpt_data(struct ipmi_intf *intf,
  204. IPMI_INST_POWER_CONSUMPTION_DATA *instpowerconsumptiondata);
  205. static void ipmi_print_get_instan_power_Amps_data(
  206. IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata);
  207. static int ipmi_print_get_power_consmpt_data(struct ipmi_intf *intf,
  208. uint8_t unit);
  209. static int ipmi_get_avgpower_consmpt_history(struct ipmi_intf *intf,
  210. IPMI_AVGPOWER_CONSUMP_HISTORY *pavgpower);
  211. static int ipmi_get_peakpower_consmpt_history(struct ipmi_intf *intf,
  212. IPMI_POWER_CONSUMP_HISTORY *pstPeakpower);
  213. static int ipmi_get_minpower_consmpt_history(struct ipmi_intf *intf,
  214. IPMI_POWER_CONSUMP_HISTORY *pstMinpower);
  215. static int ipmi_print_power_consmpt_history(struct ipmi_intf *intf, int unit);
  216. static int ipmi_get_power_cap(struct ipmi_intf *intf,
  217. IPMI_POWER_CAP *ipmipowercap);
  218. static int ipmi_print_power_cap(struct ipmi_intf *intf, uint8_t unit);
  219. static int ipmi_set_power_cap(struct ipmi_intf *intf, int unit, int val);
  220. static void ipmi_powermonitor_usage(void);
  221. /* vFlash Function prototypes */
  222. static int ipmi_delloem_vFlash_main(struct ipmi_intf *intf, int argc,
  223. char **argv);
  224. const char *get_vFlash_compcode_str(uint8_t vflashcompcode,
  225. const struct vFlashstr *vs);
  226. static int ipmi_get_sd_card_info(struct ipmi_intf *intf);
  227. static int ipmi_delloem_vFlash_process(struct ipmi_intf *intf, int current_arg,
  228. char **argv);
  229. static void ipmi_vFlash_usage(void);
  230. /* LED Function prototypes */
  231. static int ipmi_getsesmask(int, char **argv);
  232. static void CheckSetLEDSupport(struct ipmi_intf *intf);
  233. static int IsSetLEDSupported(void);
  234. static void ipmi_setled_usage(void);
  235. static int ipmi_delloem_setled_main(struct ipmi_intf *intf, int argc,
  236. char **argv);
  237. static int ipmi_setled_state(struct ipmi_intf *intf, int bayId, int slotId,
  238. int state);
  239. static int ipmi_getdrivemap(struct ipmi_intf *intf, int b, int d, int f,
  240. int *bayId, int *slotId);
  241. static int
  242. get_nic_selection_mode_12g(struct ipmi_intf* intf,int current_arg,
  243. char ** argv, char *nic_set);
  244. /* Function Name: ipmi_delloem_main
  245. *
  246. * Description: This function processes the delloem command
  247. * Input: intf - ipmi interface
  248. * argc - no of arguments
  249. * argv - argument string array
  250. * Output:
  251. *
  252. * Return: return code 0 - success
  253. * -1 - failure
  254. */
  255. int
  256. ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv)
  257. {
  258. int rc = 0;
  259. current_arg = 0;
  260. if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) {
  261. usage();
  262. return 0;
  263. }
  264. if (0 ==strncmp(argv[current_arg], "lcd\0", 4)) {
  265. rc = ipmi_delloem_lcd_main(intf,argc,argv);
  266. } else if (strncmp(argv[current_arg], "mac\0", 4) == 0) {
  267. /* mac address*/
  268. rc = ipmi_delloem_mac_main(intf,argc,argv);
  269. } else if (strncmp(argv[current_arg], "lan\0", 4) == 0) {
  270. /* lan address*/
  271. rc = ipmi_delloem_lan_main(intf,argc,argv);
  272. } else if (strncmp(argv[current_arg], "setled\0", 7) == 0) {
  273. /* SetLED support */
  274. rc = ipmi_delloem_setled_main(intf,argc,argv);
  275. } else if (strncmp(argv[current_arg], "powermonitor\0", 13) == 0) {
  276. /*Powermanagement report processing*/
  277. rc = ipmi_delloem_powermonitor_main(intf,argc,argv);
  278. } else if (strncmp(argv[current_arg], "vFlash\0", 7) == 0) {
  279. /* vFlash Support */
  280. rc = ipmi_delloem_vFlash_main(intf,argc,argv);
  281. } else {
  282. usage();
  283. return -1;
  284. }
  285. return rc;
  286. }
  287. /*
  288. * Function Name: usage
  289. *
  290. * Description: This function prints help message for delloem command
  291. * Input:
  292. * Output:
  293. *
  294. * Return:
  295. *
  296. */
  297. static void
  298. usage(void)
  299. {
  300. lprintf(LOG_NOTICE,
  301. "");
  302. lprintf(LOG_NOTICE,
  303. "usage: delloem <command> [option...]");
  304. lprintf(LOG_NOTICE,
  305. "");
  306. lprintf(LOG_NOTICE,
  307. "commands:");
  308. lprintf(LOG_NOTICE,
  309. " lcd");
  310. lprintf(LOG_NOTICE,
  311. " mac");
  312. lprintf(LOG_NOTICE,
  313. " lan");
  314. lprintf(LOG_NOTICE,
  315. " setled");
  316. lprintf(LOG_NOTICE,
  317. " powermonitor");
  318. lprintf(LOG_NOTICE,
  319. " vFlash");
  320. lprintf(LOG_NOTICE,
  321. "");
  322. lprintf(LOG_NOTICE,
  323. "For help on individual commands type:");
  324. lprintf(LOG_NOTICE,
  325. "delloem <command> help");
  326. }
  327. /*
  328. * Function Name: ipmi_delloem_lcd_main
  329. *
  330. * Description: This function processes the delloem lcd command
  331. * Input: intf - ipmi interface
  332. * argc - no of arguments
  333. * argv - argument string array
  334. * Output:
  335. *
  336. * Return: return code 0 - success
  337. * -1 - failure
  338. *
  339. */
  340. static int
  341. ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv)
  342. {
  343. int rc = 0;
  344. current_arg++;
  345. if (argc < current_arg) {
  346. usage();
  347. return -1;
  348. }
  349. /* ipmitool delloem lcd info*/
  350. if (argc == 1 || strcmp(argv[current_arg], "help") == 0) {
  351. ipmi_lcd_usage();
  352. return 0;
  353. }
  354. CheckLCDSupport(intf);
  355. ipmi_idracvalidator_command(intf);
  356. if (!IsLCDSupported()) {
  357. lprintf(LOG_ERR, "lcd is not supported on this system.");
  358. return -1;
  359. } else if (strncmp(argv[current_arg], "info\0", 5) == 0) {
  360. if (iDRAC_FLAG_ALL) {
  361. rc = ipmi_lcd_get_info_wh(intf);
  362. } else {
  363. rc = ipmi_lcd_get_info(intf);
  364. }
  365. } else if (strncmp(argv[current_arg], "status\0", 7) == 0) {
  366. rc = ipmi_lcd_get_status(intf);
  367. } else if (strncmp(argv[current_arg], "set\0", 4) == 0) {
  368. /* ipmitool delloem lcd set*/
  369. uint8_t line_number = 0;
  370. current_arg++;
  371. if (argc <= current_arg) {
  372. ipmi_lcd_usage();
  373. return -1;
  374. }
  375. if (strncmp(argv[current_arg], "line\0", 5) == 0) {
  376. current_arg++;
  377. if (argc <= current_arg) {
  378. usage();
  379. return -1;
  380. }
  381. if (str2uchar(argv[current_arg], &line_number) != 0) {
  382. lprintf(LOG_ERR,
  383. "Argument '%s' is either not a number or out of range.",
  384. argv[current_arg]);
  385. return (-1);
  386. }
  387. current_arg++;
  388. if (argc <= current_arg) {
  389. usage();
  390. return -1;
  391. }
  392. }
  393. if ((strncmp(argv[current_arg], "mode\0", 5) == 0)
  394. && (iDRAC_FLAG_ALL)) {
  395. current_arg++;
  396. if (argc <= current_arg) {
  397. ipmi_lcd_usage();
  398. return -1;
  399. }
  400. if (argv[current_arg] == NULL) {
  401. ipmi_lcd_usage();
  402. return -1;
  403. }
  404. if (strncmp(argv[current_arg], "none\0", 5) == 0) {
  405. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_NONE, 0xFF,
  406. 0XFF, 0, NULL);
  407. } else if (strncmp(argv[current_arg], "modelname\0", 10) == 0) {
  408. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0xFF,
  409. 0XFF, 0, NULL);
  410. } else if (strncmp(argv[current_arg], "userdefined\0", 12) == 0) {
  411. current_arg++;
  412. if (argc <= current_arg) {
  413. ipmi_lcd_usage();
  414. return -1;
  415. }
  416. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED,
  417. 0xFF, 0XFF, line_number, argv[current_arg]);
  418. } else if (strncmp(argv[current_arg], "ipv4address\0", 12) == 0) {
  419. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_iDRAC_IPV4ADRESS,
  420. 0xFF, 0XFF, 0, NULL);
  421. } else if (strncmp(argv[current_arg], "macaddress\0", 11) == 0) {
  422. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_IDRAC_MAC_ADDRESS,
  423. 0xFF, 0XFF, 0, NULL);
  424. } else if (strncmp(argv[current_arg], "systemname\0", 11) == 0) {
  425. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_OS_SYSTEM_NAME, 0xFF,
  426. 0XFF, 0, NULL);
  427. } else if (strncmp(argv[current_arg], "servicetag\0", 11) == 0) {
  428. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_SERVICE_TAG, 0xFF,
  429. 0XFF, 0, NULL);
  430. } else if (strncmp(argv[current_arg], "ipv6address\0", 12) == 0) {
  431. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_iDRAC_IPV6ADRESS,
  432. 0xFF, 0XFF, 0, NULL);
  433. } else if (strncmp(argv[current_arg], "ambienttemp\0", 12) == 0) {
  434. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_AMBEINT_TEMP, 0xFF,
  435. 0XFF, 0, NULL);
  436. } else if (strncmp(argv[current_arg], "systemwatt\0", 11) == 0) {
  437. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_SYSTEM_WATTS, 0xFF,
  438. 0XFF, 0, NULL);
  439. } else if (strncmp(argv[current_arg], "assettag\0", 9) == 0) {
  440. rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_ASSET_TAG, 0xFF,
  441. 0XFF, 0, NULL);
  442. } else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
  443. ipmi_lcd_usage();
  444. } else {
  445. lprintf(LOG_ERR, "Invalid DellOEM command: %s",
  446. argv[current_arg]);
  447. ipmi_lcd_usage();
  448. }
  449. } else if ((strncmp(argv[current_arg], "lcdqualifier\0", 13) == 0)
  450. && (iDRAC_FLAG_ALL)) {
  451. current_arg++;
  452. if (argc <= current_arg) {
  453. ipmi_lcd_usage();
  454. return -1;
  455. }
  456. if (argv[current_arg] == NULL) {
  457. ipmi_lcd_usage();
  458. return -1;
  459. }
  460. if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
  461. rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x00, 0XFF, 0, NULL);
  462. } else if (strncmp(argv[current_arg], "btuphr\0",7) == 0) {
  463. rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x01, 0XFF, 0, NULL);
  464. } else if (strncmp(argv[current_arg], "celsius\0", 8) == 0) {
  465. rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x02, 0xFF, 0, NULL);
  466. } else if (strncmp(argv[current_arg], "fahrenheit", 11) == 0) {
  467. rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x03, 0xFF, 0, NULL);
  468. } else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
  469. ipmi_lcd_usage();
  470. } else {
  471. lprintf(LOG_ERR, "Invalid DellOEM command: %s",
  472. argv[current_arg]);
  473. ipmi_lcd_usage();
  474. }
  475. } else if ((strncmp(argv[current_arg], "errordisplay\0", 13) == 0)
  476. && (iDRAC_FLAG_ALL)) {
  477. current_arg++;
  478. if (argc <= current_arg) {
  479. ipmi_lcd_usage();
  480. return -1;
  481. }
  482. if (argv[current_arg] == NULL) {
  483. ipmi_lcd_usage();
  484. return -1;
  485. }
  486. if (strncmp(argv[current_arg], "sel\0", 4) == 0) {
  487. rc = ipmi_lcd_configure_wh(intf, 0xFF, 0xFF,
  488. IPMI_DELL_LCD_ERROR_DISP_SEL, 0, NULL);
  489. } else if (strncmp(argv[current_arg], "simple\0", 7) == 0) {
  490. rc = ipmi_lcd_configure_wh(intf, 0xFF, 0xFF,
  491. IPMI_DELL_LCD_ERROR_DISP_VERBOSE, 0, NULL);
  492. } else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
  493. ipmi_lcd_usage();
  494. } else {
  495. lprintf(LOG_ERR, "Invalid DellOEM command: %s",
  496. argv[current_arg]);
  497. ipmi_lcd_usage();
  498. }
  499. } else if ((strncmp(argv[current_arg], "none\0", 5) == 0)
  500. && (iDRAC_FLAG==0)) {
  501. rc = ipmi_lcd_configure(intf, IPMI_DELL_LCD_CONFIG_NONE, 0, NULL);
  502. } else if ((strncmp(argv[current_arg], "default\0", 8) == 0)
  503. && (iDRAC_FLAG==0)) {
  504. rc = ipmi_lcd_configure(intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0, NULL);
  505. } else if ((strncmp(argv[current_arg], "custom\0", 7) == 0)
  506. && (iDRAC_FLAG==0)) {
  507. current_arg++;
  508. if (argc <= current_arg) {
  509. ipmi_lcd_usage();
  510. return -1;
  511. }
  512. rc = ipmi_lcd_configure(intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED,
  513. line_number, argv[current_arg]);
  514. } else if (strncmp(argv[current_arg], "vkvm\0", 5) == 0) {
  515. current_arg++;
  516. if (argc <= current_arg) {
  517. ipmi_lcd_usage();
  518. return -1;
  519. }
  520. if (strncmp(argv[current_arg], "active\0", 7) == 0) {
  521. rc = ipmi_lcd_set_kvm(intf, 1);
  522. } else if (strncmp(argv[current_arg], "inactive\0", 9) == 0) {
  523. rc = ipmi_lcd_set_kvm(intf, 0);
  524. } else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
  525. ipmi_lcd_usage();
  526. } else {
  527. lprintf(LOG_ERR, "Invalid DellOEM command: %s",
  528. argv[current_arg]);
  529. ipmi_lcd_usage();
  530. }
  531. } else if (strncmp(argv[current_arg], "frontpanelaccess\0", 17) == 0) {
  532. current_arg++;
  533. if (argc <= current_arg) {
  534. ipmi_lcd_usage();
  535. return -1;
  536. }
  537. if (strncmp(argv[current_arg], "viewandmodify\0", 14) == 0) {
  538. rc = ipmi_lcd_set_lock(intf, 0);
  539. } else if (strncmp(argv[current_arg], "viewonly\0", 9)==0) {
  540. rc = ipmi_lcd_set_lock(intf, 1);
  541. } else if (strncmp(argv[current_arg], "disabled\0", 9)==0) {
  542. rc = ipmi_lcd_set_lock(intf, 2);
  543. } else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
  544. ipmi_lcd_usage();
  545. } else {
  546. lprintf(LOG_ERR, "Invalid DellOEM command: %s",
  547. argv[current_arg]);
  548. ipmi_lcd_usage();
  549. }
  550. } else if( (strncmp(argv[current_arg], "help\0", 5) == 0)
  551. && (iDRAC_FLAG==0)) {
  552. ipmi_lcd_usage();
  553. } else {
  554. lprintf(LOG_ERR, "Invalid DellOEM command: %s",
  555. argv[current_arg]);
  556. ipmi_lcd_usage();
  557. return -1;
  558. }
  559. } else {
  560. lprintf(LOG_ERR, "Invalid DellOEM command: %s",
  561. argv[current_arg]);
  562. ipmi_lcd_usage();
  563. return -1;
  564. }
  565. return rc;
  566. }
  567. /* ipmi_lcd_get_platform_model_name - This function retrieves the platform model
  568. * name, or any other parameter which stores data in the same format
  569. *
  570. * @intf: pointer to interface
  571. * @lcdstring: hostname/platform model string(output)
  572. * @max_length: length of the platform model string
  573. * @field_type: either hostname/platform model
  574. *
  575. * returns: 0 => success, other value means error
  576. */
  577. int
  578. ipmi_lcd_get_platform_model_name(struct ipmi_intf * intf, char* lcdstring,
  579. uint8_t max_length, uint8_t field_type)
  580. {
  581. int bytes_copied = 0;
  582. int ii = 0;
  583. int lcdstring_len = 0;
  584. int rc = 0;
  585. IPMI_DELL_LCD_STRING lcdstringblock;
  586. for (ii = 0; ii < 4; ii++) {
  587. int bytes_to_copy;
  588. rc = ipmi_mc_getsysinfo(intf, field_type, ii, 0, sizeof(lcdstringblock),
  589. &lcdstringblock);
  590. if (rc < 0) {
  591. lprintf(LOG_ERR, "Error getting platform model name");
  592. break;
  593. } else if (rc > 0) {
  594. lprintf(LOG_ERR, "Error getting platform model name: %s",
  595. val2str(rc, completion_code_vals));
  596. break;
  597. }
  598. /* first block is different - 14 bytes*/
  599. if (ii == 0) {
  600. lcdstring_len = lcdstringblock.lcd_string.selector_0_string.length;
  601. lcdstring_len = MIN(lcdstring_len,max_length);
  602. bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE);
  603. memcpy(lcdstring, lcdstringblock.lcd_string.selector_0_string.data,
  604. bytes_to_copy);
  605. } else {
  606. int string_offset;
  607. bytes_to_copy = MIN(lcdstring_len - bytes_copied,
  608. IPMI_DELL_LCD_STRINGN_SIZE);
  609. if (bytes_to_copy < 1) {
  610. break;
  611. }
  612. string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE
  613. * (ii-1);
  614. memcpy(lcdstring + string_offset,
  615. lcdstringblock.lcd_string.selector_n_data, bytes_to_copy);
  616. }
  617. bytes_copied += bytes_to_copy;
  618. if (bytes_copied >= lcdstring_len) {
  619. break;
  620. }
  621. }
  622. return rc;
  623. }
  624. /*
  625. * Function Name: ipmi_idracvalidator_command
  626. *
  627. * Description: This function returns the iDRAC6 type
  628. * Input: intf - ipmi interface
  629. * Output:
  630. *
  631. * Return: iDRAC6 type 1 - whoville
  632. * 0 - others
  633. */
  634. static int
  635. ipmi_idracvalidator_command(struct ipmi_intf * intf)
  636. {
  637. int rc;
  638. uint8_t data[11];
  639. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_IDRAC_VALIDATOR, 2, 0, sizeof(data),
  640. data);
  641. if (rc < 0) {
  642. /*lprintf(LOG_ERR, " Error getting IMC type"); */
  643. return -1;
  644. } else if (rc > 0) {
  645. /*lprintf(LOG_ERR, " Error getting IMC type: %s",
  646. val2str(rsp->ccode, completion_code_vals)); */
  647. return -1;
  648. }
  649. /*
  650. * Set the new flags to 0
  651. */
  652. iDRAC_FLAG_ALL = 0;
  653. iDRAC_FLAG_12_13 = 0;
  654. /* Support the 11G Monolithic, modular, Maisy and Coaster */
  655. if ((IMC_IDRAC_11G_MONOLITHIC == data[10])
  656. || (IMC_IDRAC_11G_MODULAR == data[10])
  657. || (IMC_MASER_LITE_BMC == data[10])
  658. || (IMC_MASER_LITE_NU == data[10])) {
  659. iDRAC_FLAG=IDRAC_11G;
  660. iDRAC_FLAG_ALL = 1;
  661. } else if((IMC_IDRAC_12G_MONOLITHIC == data[10])
  662. || (IMC_IDRAC_12G_MODULAR == data[10])) {
  663. iDRAC_FLAG = IDRAC_12G;
  664. iDRAC_FLAG_ALL = 1;
  665. iDRAC_FLAG_12_13 = 1;
  666. } else if ((IMC_IDRAC_13G_MONOLITHIC == data[10])
  667. || (IMC_IDRAC_13G_MODULAR == data[10])
  668. || (IMC_IDRAC_13G_DCS == data[10])) {
  669. iDRAC_FLAG=IDRAC_13G;
  670. iDRAC_FLAG_ALL = 1;
  671. iDRAC_FLAG_12_13 = 1;
  672. } else {
  673. iDRAC_FLAG = 0;
  674. iDRAC_FLAG_ALL = 0;
  675. iDRAC_FLAG_12_13 = 0;
  676. }
  677. IMC_Type = data[10];
  678. return 0;
  679. }
  680. /*
  681. * Function Name: ipmi_lcd_get_configure_command_wh
  682. *
  683. * Description: This function returns current lcd configuration for Dell OEM LCD command
  684. * Input: intf - ipmi interface
  685. * Global: lcd_mode - lcd mode setting
  686. * Output:
  687. *
  688. * Return: returns the current lcd configuration
  689. * 0 = User defined
  690. * 1 = Default
  691. * 2 = None
  692. */
  693. static int
  694. ipmi_lcd_get_configure_command_wh(struct ipmi_intf * intf)
  695. {
  696. int rc;
  697. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_CONFIG_SELECTOR, 0, 0,
  698. sizeof(lcd_mode), &lcd_mode);
  699. if (rc < 0) {
  700. lprintf(LOG_ERR, "Error getting LCD configuration");
  701. return -1;
  702. } else if ((rc == 0xc1) || (rc == 0xcb)){
  703. lprintf(LOG_ERR, "Error getting LCD configuration: "
  704. "Command not supported on this system.");
  705. } else if (rc > 0) {
  706. lprintf(LOG_ERR, "Error getting LCD configuration: %s",
  707. val2str(rc, completion_code_vals));
  708. return -1;
  709. }
  710. return 0;
  711. }
  712. /*
  713. * Function Name: ipmi_lcd_get_configure_command
  714. *
  715. * Description: This function returns current lcd configuration for Dell OEM
  716. * LCD command
  717. * Input: intf - ipmi interface
  718. * Output: command - user defined / default / none / ipv4 / mac address /
  719. * system name / service tag / ipv6 / temp / system watt / asset tag
  720. *
  721. * Return:
  722. */
  723. static int
  724. ipmi_lcd_get_configure_command(struct ipmi_intf * intf, uint8_t *command)
  725. {
  726. uint8_t data[4];
  727. int rc;
  728. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_CONFIG_SELECTOR, 0, 0,
  729. sizeof(data), data);
  730. if (rc < 0) {
  731. lprintf(LOG_ERR, "Error getting LCD configuration");
  732. return -1;
  733. } else if ((rc == 0xc1)||(rc == 0xcb)) {
  734. lprintf(LOG_ERR, "Error getting LCD configuration: "
  735. "Command not supported on this system.");
  736. return -1;
  737. } else if (rc > 0) {
  738. lprintf(LOG_ERR, "Error getting LCD configuration: %s",
  739. val2str(rc, completion_code_vals));
  740. return -1;
  741. }
  742. /* rsp->data[0] is the rev */
  743. *command = data[1];
  744. return 0;
  745. }
  746. /*
  747. * Function Name: ipmi_lcd_set_configure_command
  748. *
  749. * Description: This function updates current lcd configuration
  750. * Input: intf - ipmi interface
  751. * command - user defined / default / none / ipv4 / mac address /
  752. * system name / service tag / ipv6 / temp / system watt / asset tag
  753. * Output:
  754. * Return:
  755. */
  756. static int
  757. ipmi_lcd_set_configure_command(struct ipmi_intf * intf, int command)
  758. {
  759. #define LSCC_DATA_LEN 2
  760. uint8_t data[2];
  761. int rc;
  762. data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR;
  763. data[1] = command; /* command - custom, default, none */
  764. rc = ipmi_mc_setsysinfo(intf, 2, data);
  765. if (rc < 0) {
  766. lprintf(LOG_ERR, "Error setting LCD configuration");
  767. return -1;
  768. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  769. lprintf(LOG_ERR, "Error setting LCD configuration: "
  770. "Command not supported on this system.");
  771. } else if (rc > 0) {
  772. lprintf(LOG_ERR, "Error setting LCD configuration: %s",
  773. val2str(rc, completion_code_vals));
  774. return -1;
  775. }
  776. return 0;
  777. }
  778. /*
  779. * Function Name: ipmi_lcd_set_configure_command
  780. *
  781. * Description: This function updates current lcd configuration
  782. * Input: intf - ipmi interface
  783. * mode - user defined / default / none
  784. * lcdquallifier - lcd quallifier id
  785. * errordisp - error number
  786. * Output:
  787. * Return:
  788. */
  789. static int
  790. ipmi_lcd_set_configure_command_wh(struct ipmi_intf * intf, uint32_t mode,
  791. uint16_t lcdquallifier, uint8_t errordisp)
  792. {
  793. #define LSCC_DATA_LEN 2
  794. uint8_t data[13];
  795. int rc;
  796. ipmi_lcd_get_configure_command_wh(intf);
  797. data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR;
  798. if (mode != 0xFF) {
  799. data[1] = mode & 0xFF; /* command - custom, default, none*/
  800. data[2] = (mode & 0xFF00) >> 8;
  801. data[3] = (mode & 0xFF0000) >> 16;
  802. data[4] = (mode & 0xFF000000) >> 24;
  803. } else {
  804. data[1] = (lcd_mode.lcdmode) & 0xFF; /* command - custom, default, none*/
  805. data[2] = ((lcd_mode.lcdmode) & 0xFF00) >> 8;
  806. data[3] = ((lcd_mode.lcdmode) & 0xFF0000) >> 16;
  807. data[4] = ((lcd_mode.lcdmode) & 0xFF000000) >> 24;
  808. }
  809. if (lcdquallifier != 0xFF) {
  810. if(lcdquallifier == 0x01) {
  811. data[5] = (lcd_mode.lcdquallifier) | 0x01; /* command - custom, default, none*/
  812. } else if (lcdquallifier == 0x00) {
  813. data[5] = (lcd_mode.lcdquallifier) & 0xFE; /* command - custom, default, none*/
  814. } else if (lcdquallifier == 0x03) {
  815. data[5] = (lcd_mode.lcdquallifier) | 0x02; /* command - custom, default, none*/
  816. } else if (lcdquallifier == 0x02) {
  817. data[5] = (lcd_mode.lcdquallifier) & 0xFD;
  818. }
  819. } else {
  820. data[5] = lcd_mode.lcdquallifier;
  821. }
  822. if (errordisp != 0xFF) {
  823. data[11] = errordisp;
  824. } else {
  825. data[11] = lcd_mode.error_display;
  826. }
  827. rc = ipmi_mc_setsysinfo(intf, 13, data);
  828. if (rc < 0) {
  829. lprintf(LOG_ERR, "Error setting LCD configuration");
  830. return -1;
  831. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  832. lprintf(LOG_ERR, "Error setting LCD configuration: "
  833. "Command not supported on this system.");
  834. } else if (rc > 0) {
  835. lprintf(LOG_ERR, "Error setting LCD configuration: %s",
  836. val2str(rc, completion_code_vals));
  837. return -1;
  838. }
  839. return 0;
  840. }
  841. /*
  842. * Function Name: ipmi_lcd_get_single_line_text
  843. *
  844. * Description: This function updates current lcd configuration
  845. * Input: intf - ipmi interface
  846. * lcdstring - new string to be updated
  847. * max_length - length of the string
  848. * Output:
  849. * Return:
  850. */
  851. static int
  852. ipmi_lcd_get_single_line_text(struct ipmi_intf * intf, char* lcdstring,
  853. uint8_t max_length)
  854. {
  855. IPMI_DELL_LCD_STRING lcdstringblock;
  856. int lcdstring_len = 0;
  857. int bytes_copied = 0;
  858. int ii, rc;
  859. for (ii = 0; ii < 4; ii++) {
  860. int bytes_to_copy;
  861. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_STRING_SELECTOR, ii, 0,
  862. sizeof(lcdstringblock), &lcdstringblock);
  863. if (rc < 0) {
  864. lprintf(LOG_ERR, "Error getting text data");
  865. return -1;
  866. } else if (rc > 0) {
  867. lprintf(LOG_ERR, "Error getting text data: %s",
  868. val2str(rc, completion_code_vals));
  869. return -1;
  870. }
  871. /* first block is different - 14 bytes*/
  872. if (0 == ii) {
  873. lcdstring_len = lcdstringblock.lcd_string.selector_0_string.length;
  874. if (lcdstring_len < 1 || lcdstring_len > max_length) {
  875. break;
  876. }
  877. bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE);
  878. memcpy(lcdstring, lcdstringblock.lcd_string.selector_0_string.data,
  879. bytes_to_copy);
  880. } else {
  881. int string_offset;
  882. bytes_to_copy = MIN(lcdstring_len - bytes_copied,
  883. IPMI_DELL_LCD_STRINGN_SIZE);
  884. if (bytes_to_copy < 1) {
  885. break;
  886. }
  887. string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE
  888. * (ii-1);
  889. memcpy(lcdstring+string_offset,
  890. lcdstringblock.lcd_string.selector_n_data, bytes_to_copy);
  891. }
  892. bytes_copied += bytes_to_copy;
  893. if (bytes_copied >= lcdstring_len) {
  894. break;
  895. }
  896. }
  897. return 0;
  898. }
  899. /*
  900. * Function Name: ipmi_lcd_get_info_wh
  901. *
  902. * Description: This function prints current lcd configuration for whoville platform
  903. * Input: intf - ipmi interface
  904. * Output:
  905. * Return:
  906. */
  907. static int
  908. ipmi_lcd_get_info_wh(struct ipmi_intf * intf)
  909. {
  910. IPMI_DELL_LCD_CAPS lcd_caps;
  911. char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0};
  912. int rc;
  913. printf("LCD info\n");
  914. if (ipmi_lcd_get_configure_command_wh(intf) != 0) {
  915. return -1;
  916. }
  917. if (lcd_mode.lcdmode== IPMI_DELL_LCD_CONFIG_DEFAULT) {
  918. char text[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0};
  919. if (ipmi_lcd_get_platform_model_name(intf, text,
  920. IPMI_DELL_LCD_STRING_LENGTH_MAX,
  921. IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR) != 0) {
  922. return (-1);
  923. }
  924. printf(" Setting:Model name\n");
  925. printf(" Line 1: %s\n", text);
  926. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_NONE) {
  927. printf(" Setting: none\n");
  928. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_USER_DEFINED) {
  929. printf(" Setting: User defined\n");
  930. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_GET_CAPS_SELECTOR, 0, 0,
  931. sizeof(lcd_caps), &lcd_caps);
  932. if (rc < 0) {
  933. lprintf(LOG_ERR, "Error getting LCD capabilities.");
  934. return -1;
  935. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  936. lprintf(LOG_ERR, "Error getting LCD capabilities: "
  937. "Command not supported on this system.");
  938. } else if (rc > 0) {
  939. lprintf(LOG_ERR, "Error getting LCD capabilities: %s",
  940. val2str(rc, completion_code_vals));
  941. return -1;
  942. }
  943. if (lcd_caps.number_lines > 0) {
  944. memset(lcdstring, 0, IPMI_DELL_LCD_STRING_LENGTH_MAX + 1);
  945. rc = ipmi_lcd_get_single_line_text(intf, lcdstring,
  946. lcd_caps.max_chars[0]);
  947. printf(" Text: %s\n", lcdstring);
  948. } else {
  949. printf(" No lines to show\n");
  950. }
  951. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV4ADRESS) {
  952. printf(" Setting: IPV4 Address\n");
  953. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_IDRAC_MAC_ADDRESS) {
  954. printf(" Setting: MAC Address\n");
  955. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_OS_SYSTEM_NAME) {
  956. printf(" Setting: OS System Name\n");
  957. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SERVICE_TAG) {
  958. printf(" Setting: System Tag\n");
  959. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV6ADRESS) {
  960. printf(" Setting: IPV6 Address\n");
  961. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_ASSET_TAG) {
  962. printf(" Setting: Asset Tag\n");
  963. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_AMBEINT_TEMP) {
  964. printf(" Setting: Ambient Temp\n");
  965. if (lcd_mode.lcdquallifier & 0x02) {
  966. printf(" Unit: F\n");
  967. } else {
  968. printf(" Unit: C\n");
  969. }
  970. } else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SYSTEM_WATTS) {
  971. printf(" Setting: System Watts\n");
  972. if (lcd_mode.lcdquallifier & 0x01) {
  973. printf(" Unit: BTU/hr\n");
  974. } else {
  975. printf(" Unit: Watt\n");
  976. }
  977. }
  978. if (lcd_mode.error_display == IPMI_DELL_LCD_ERROR_DISP_SEL) {
  979. printf(" Error Display: SEL\n");
  980. } else if (lcd_mode.error_display == IPMI_DELL_LCD_ERROR_DISP_VERBOSE) {
  981. printf(" Error Display: Simple\n");
  982. }
  983. return 0;
  984. }
  985. /*
  986. * Function Name: ipmi_lcd_get_info
  987. *
  988. * Description: This function prints current lcd configuration for platform other than whoville
  989. * Input: intf - ipmi interface
  990. * Output:
  991. * Return:
  992. */
  993. static int
  994. ipmi_lcd_get_info(struct ipmi_intf * intf)
  995. {
  996. IPMI_DELL_LCD_CAPS lcd_caps;
  997. uint8_t command = 0;
  998. char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0};
  999. int rc;
  1000. printf("LCD info\n");
  1001. if (ipmi_lcd_get_configure_command(intf, &command) != 0) {
  1002. return -1;
  1003. }
  1004. if (command == IPMI_DELL_LCD_CONFIG_DEFAULT) {
  1005. memset(lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1);
  1006. if (ipmi_lcd_get_platform_model_name(intf, lcdstring,
  1007. IPMI_DELL_LCD_STRING_LENGTH_MAX,
  1008. IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR) != 0) {
  1009. return (-1);
  1010. }
  1011. printf(" Setting: default\n");
  1012. printf(" Line 1: %s\n", lcdstring);
  1013. } else if (command == IPMI_DELL_LCD_CONFIG_NONE) {
  1014. printf(" Setting: none\n");
  1015. } else if (command == IPMI_DELL_LCD_CONFIG_USER_DEFINED) {
  1016. printf(" Setting: custom\n");
  1017. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_GET_CAPS_SELECTOR, 0, 0,
  1018. sizeof(lcd_caps), &lcd_caps);
  1019. if (rc < 0) {
  1020. lprintf(LOG_ERR, "Error getting LCD capabilities.");
  1021. return -1;
  1022. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  1023. lprintf(LOG_ERR, "Error getting LCD capabilities: "
  1024. "Command not supported on this system.");
  1025. } else if (rc > 0) {
  1026. lprintf(LOG_ERR, "Error getting LCD capabilities: %s",
  1027. val2str(rc, completion_code_vals));
  1028. return -1;
  1029. }
  1030. if (lcd_caps.number_lines > 0) {
  1031. memset(lcdstring, 0, IPMI_DELL_LCD_STRING_LENGTH_MAX + 1);
  1032. rc = ipmi_lcd_get_single_line_text(intf, lcdstring,
  1033. lcd_caps.max_chars[0]);
  1034. printf(" Text: %s\n", lcdstring);
  1035. } else {
  1036. printf(" No lines to show\n");
  1037. }
  1038. }
  1039. return 0;
  1040. }
  1041. /*
  1042. * Function Name: ipmi_lcd_get_status_val
  1043. *
  1044. * Description: This function gets current lcd configuration
  1045. * Input: intf - ipmi interface
  1046. * Output: lcdstatus - KVM Status & Lock Status
  1047. * Return:
  1048. */
  1049. static int
  1050. ipmi_lcd_get_status_val(struct ipmi_intf * intf, LCD_STATUS* lcdstatus)
  1051. {
  1052. int rc;
  1053. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_STATUS_SELECTOR, 0, 0,
  1054. sizeof(*lcdstatus), lcdstatus);
  1055. if (rc < 0) {
  1056. lprintf(LOG_ERR, "Error getting LCD Status");
  1057. return -1;
  1058. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  1059. lprintf(LOG_ERR, "Error getting LCD status: "
  1060. "Command not supported on this system.");
  1061. return -1;
  1062. } else if (rc > 0) {
  1063. lprintf(LOG_ERR, "Error getting LCD Status: %s",
  1064. val2str(rc, completion_code_vals));
  1065. return -1;
  1066. }
  1067. return 0;
  1068. }
  1069. /*
  1070. * Function Name: IsLCDSupported
  1071. *
  1072. * Description: This function returns whether lcd supported or not
  1073. * Input:
  1074. * Output:
  1075. * Return:
  1076. */
  1077. static int
  1078. IsLCDSupported()
  1079. {
  1080. return LcdSupported;
  1081. }
  1082. /*
  1083. * Function Name: CheckLCDSupport
  1084. *
  1085. * Description: This function checks whether lcd supported or not
  1086. * Input: intf - ipmi interface
  1087. * Output:
  1088. * Return:
  1089. */
  1090. static void
  1091. CheckLCDSupport(struct ipmi_intf * intf)
  1092. {
  1093. int rc;
  1094. LcdSupported = 0;
  1095. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_STATUS_SELECTOR, 0, 0, 0, NULL);
  1096. if (rc == 0) {
  1097. LcdSupported = 1;
  1098. }
  1099. }
  1100. /*
  1101. * Function Name: ipmi_lcd_status_print
  1102. *
  1103. * Description: This function prints current lcd configuration KVM Status & Lock Status
  1104. * Input: lcdstatus - KVM Status & Lock Status
  1105. * Output:
  1106. * Return:
  1107. */
  1108. static void
  1109. ipmi_lcd_status_print(LCD_STATUS lcdstatus)
  1110. {
  1111. switch (lcdstatus.vKVM_status) {
  1112. case 0x00:
  1113. printf("LCD KVM Status :Inactive\n");
  1114. break;
  1115. case 0x01:
  1116. printf("LCD KVM Status :Active\n");
  1117. break;
  1118. default:
  1119. printf("LCD KVM Status :Invalid Status\n");
  1120. break;
  1121. }
  1122. switch (lcdstatus.lock_status) {
  1123. case 0x00:
  1124. printf("LCD lock Status :View and modify\n");
  1125. break;
  1126. case 0x01:
  1127. printf("LCD lock Status :View only\n");
  1128. break;
  1129. case 0x02:
  1130. printf("LCD lock Status :disabled\n");
  1131. break;
  1132. default:
  1133. printf("LCD lock Status :Invalid\n");
  1134. break;
  1135. }
  1136. }
  1137. /*
  1138. * Function Name: ipmi_lcd_get_status
  1139. *
  1140. * Description: This function gets current lcd KVM active status & lcd access mode
  1141. * Input: intf - ipmi interface
  1142. * Output:
  1143. * Return: -1 on error
  1144. * 0 if successful
  1145. */
  1146. static int
  1147. ipmi_lcd_get_status(struct ipmi_intf * intf)
  1148. {
  1149. int rc=0;
  1150. LCD_STATUS lcdstatus;
  1151. rc =ipmi_lcd_get_status_val( intf, &lcdstatus);
  1152. if (rc < 0) {
  1153. return -1;
  1154. }
  1155. ipmi_lcd_status_print(lcdstatus);
  1156. return rc;
  1157. }
  1158. /*
  1159. * Function Name: ipmi_lcd_set_kvm
  1160. *
  1161. * Description: This function sets lcd KVM active status
  1162. * Input: intf - ipmi interface
  1163. * status - Inactive / Active
  1164. * Output:
  1165. * Return: -1 on error
  1166. * 0 if successful
  1167. */
  1168. static int
  1169. ipmi_lcd_set_kvm(struct ipmi_intf * intf, char status)
  1170. {
  1171. #define LSCC_DATA_LEN 2
  1172. LCD_STATUS lcdstatus;
  1173. int rc=0;
  1174. struct ipmi_rs * rsp = NULL;
  1175. struct ipmi_rq req = {0};
  1176. uint8_t data[5];
  1177. rc = ipmi_lcd_get_status_val(intf,&lcdstatus);
  1178. if (rc < 0) {
  1179. return -1;
  1180. }
  1181. req.msg.netfn = IPMI_NETFN_APP;
  1182. req.msg.lun = 0;
  1183. req.msg.cmd = IPMI_SET_SYS_INFO;
  1184. req.msg.data_len = 5;
  1185. req.msg.data = data;
  1186. data[0] = IPMI_DELL_LCD_STATUS_SELECTOR;
  1187. data[1] = status; /* active- incative*/
  1188. data[2] = lcdstatus.lock_status; /* full-veiw-locked */
  1189. rsp = intf->sendrecv(intf, &req);
  1190. if (rsp == NULL) {
  1191. lprintf(LOG_ERR, "Error setting LCD status");
  1192. rc= -1;
  1193. } else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
  1194. lprintf(LOG_ERR, "Error getting LCD status: "
  1195. "Command not supported on this system.");
  1196. return -1;
  1197. } else if (rsp->ccode > 0) {
  1198. lprintf(LOG_ERR, "Error setting LCD status: %s",
  1199. val2str(rsp->ccode, completion_code_vals));
  1200. rc= -1;
  1201. }
  1202. return rc;
  1203. }
  1204. /*
  1205. * Function Name: ipmi_lcd_set_lock
  1206. *
  1207. * Description: This function sets lcd access mode
  1208. * Input: intf - ipmi interface
  1209. * lock - View and modify / View only / Diabled
  1210. * Output:
  1211. * Return: -1 on error
  1212. * 0 if successful
  1213. */
  1214. static int
  1215. ipmi_lcd_set_lock(struct ipmi_intf * intf, char lock)
  1216. {
  1217. #define LSCC_DATA_LEN 2
  1218. LCD_STATUS lcdstatus;
  1219. int rc =0;
  1220. struct ipmi_rs * rsp = NULL;
  1221. struct ipmi_rq req = {0};
  1222. uint8_t data[5];
  1223. rc = ipmi_lcd_get_status_val(intf,&lcdstatus);
  1224. if (rc < 0) {
  1225. return -1;
  1226. }
  1227. req.msg.netfn = IPMI_NETFN_APP;
  1228. req.msg.lun = 0;
  1229. req.msg.cmd = IPMI_SET_SYS_INFO;
  1230. req.msg.data_len = 5;
  1231. req.msg.data = data;
  1232. data[0] = IPMI_DELL_LCD_STATUS_SELECTOR;
  1233. data[1] = lcdstatus.vKVM_status; /* active- incative */
  1234. data[2] = lock; /* full- veiw-locked */
  1235. rsp = intf->sendrecv(intf, &req);
  1236. if (rsp == NULL) {
  1237. lprintf(LOG_ERR, "Error setting LCD status");
  1238. rc = -1;
  1239. } else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
  1240. lprintf(LOG_ERR, "Error getting LCD status: "
  1241. "Command not supported on this system.");
  1242. rc = -1;
  1243. } else if (rsp->ccode > 0) {
  1244. lprintf(LOG_ERR, "Error setting LCD status: %s",
  1245. val2str(rsp->ccode, completion_code_vals));
  1246. rc= -1;
  1247. }
  1248. return rc;
  1249. }
  1250. /*
  1251. * Function Name: ipmi_lcd_set_single_line_text
  1252. *
  1253. * Description: This function sets lcd line text
  1254. * Input: intf - ipmi interface
  1255. * text - lcd string
  1256. * Output:
  1257. * Return: -1 on error
  1258. * 0 if successful
  1259. */
  1260. static int
  1261. ipmi_lcd_set_single_line_text(struct ipmi_intf * intf, char * text)
  1262. {
  1263. uint8_t data[18];
  1264. int bytes_to_store = strlen(text);
  1265. int bytes_stored = 0;
  1266. int ii;
  1267. int rc = 0;
  1268. if (bytes_to_store > IPMI_DELL_LCD_STRING_LENGTH_MAX) {
  1269. lprintf(LOG_ERR, "Out of range Max limit is 62 characters");
  1270. return (-1);
  1271. } else {
  1272. bytes_to_store = MIN(bytes_to_store, IPMI_DELL_LCD_STRING_LENGTH_MAX);
  1273. for (ii = 0; ii < 4; ii++) {
  1274. /*first block, 2 bytes parms and 14 bytes data*/
  1275. if (0 == ii) {
  1276. int size_of_copy = MIN((bytes_to_store - bytes_stored),
  1277. IPMI_DELL_LCD_STRING1_SIZE);
  1278. if (size_of_copy < 0) {
  1279. /* allow 0 string length*/
  1280. break;
  1281. }
  1282. data[0] = IPMI_DELL_LCD_STRING_SELECTOR;
  1283. data[1] = ii; /* block number to use (0)*/
  1284. data[2] = 0; /*string encoding*/
  1285. data[3] = bytes_to_store; /* total string length*/
  1286. memcpy(data + 4, text+bytes_stored, size_of_copy);
  1287. bytes_stored += size_of_copy;
  1288. } else {
  1289. int size_of_copy = MIN((bytes_to_store - bytes_stored),
  1290. IPMI_DELL_LCD_STRINGN_SIZE);
  1291. if (size_of_copy <= 0) {
  1292. break;
  1293. }
  1294. data[0] = IPMI_DELL_LCD_STRING_SELECTOR;
  1295. data[1] = ii; /* block number to use (1,2,3)*/
  1296. memcpy(data + 2, text+bytes_stored, size_of_copy);
  1297. bytes_stored += size_of_copy;
  1298. }
  1299. rc = ipmi_mc_setsysinfo(intf, 18, data);
  1300. if (rc < 0) {
  1301. lprintf(LOG_ERR, "Error setting text data");
  1302. rc = -1;
  1303. } else if (rc > 0) {
  1304. lprintf(LOG_ERR, "Error setting text data: %s",
  1305. val2str(rc, completion_code_vals));
  1306. rc = -1;
  1307. }
  1308. }
  1309. }
  1310. return rc;
  1311. }
  1312. /*
  1313. * Function Name: ipmi_lcd_set_text
  1314. *
  1315. * Description: This function sets lcd line text
  1316. * Input: intf - ipmi interface
  1317. * text - lcd string
  1318. * line_number- line number
  1319. * Output:
  1320. * Return: -1 on error
  1321. * 0 if successful
  1322. */
  1323. static int
  1324. ipmi_lcd_set_text(struct ipmi_intf * intf, char * text, int line_number)
  1325. {
  1326. int rc = 0;
  1327. IPMI_DELL_LCD_CAPS lcd_caps;
  1328. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_GET_CAPS_SELECTOR, 0, 0,
  1329. sizeof(lcd_caps), &lcd_caps);
  1330. if (rc < 0) {
  1331. lprintf(LOG_ERR, "Error getting LCD capabilities");
  1332. return -1;
  1333. } else if (rc > 0) {
  1334. lprintf(LOG_ERR, "Error getting LCD capabilities: %s",
  1335. val2str(rc, completion_code_vals));
  1336. return -1;
  1337. }
  1338. if (lcd_caps.number_lines > 0) {
  1339. rc = ipmi_lcd_set_single_line_text(intf, text);
  1340. } else {
  1341. lprintf(LOG_ERR, "LCD does not have any lines that can be set");
  1342. rc = -1;
  1343. }
  1344. return rc;
  1345. }
  1346. /*
  1347. * Function Name: ipmi_lcd_configure_wh
  1348. *
  1349. * Description: This function updates the current lcd configuration
  1350. * Input: intf - ipmi interface
  1351. * lcdquallifier- lcd quallifier
  1352. * errordisp - error number
  1353. * line_number-line number
  1354. * text - lcd string
  1355. * Output:
  1356. * Return: -1 on error
  1357. * 0 if successful
  1358. */
  1359. static int
  1360. ipmi_lcd_configure_wh(struct ipmi_intf * intf, uint32_t mode,
  1361. uint16_t lcdquallifier, uint8_t errordisp, int8_t line_number, char * text)
  1362. {
  1363. int rc = 0;
  1364. if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == mode) {
  1365. /* Any error was reported earlier. */
  1366. rc = ipmi_lcd_set_text(intf, text, line_number);
  1367. }
  1368. if (rc == 0) {
  1369. rc = ipmi_lcd_set_configure_command_wh(intf, mode ,lcdquallifier,errordisp);
  1370. }
  1371. return rc;
  1372. }
  1373. /*
  1374. * Function Name: ipmi_lcd_configure
  1375. *
  1376. * Description: This function updates the current lcd configuration
  1377. * Input: intf - ipmi interface
  1378. * command- lcd command
  1379. * line_number-line number
  1380. * text - lcd string
  1381. * Output:
  1382. * Return: -1 on error
  1383. * 0 if successful
  1384. */
  1385. static int
  1386. ipmi_lcd_configure(struct ipmi_intf * intf, int command,
  1387. int8_t line_number, char * text)
  1388. {
  1389. int rc = 0;
  1390. if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == command) {
  1391. rc = ipmi_lcd_set_text(intf, text, line_number);
  1392. }
  1393. if (rc == 0) {
  1394. rc = ipmi_lcd_set_configure_command(intf, command);
  1395. }
  1396. return rc;
  1397. }
  1398. /*
  1399. * Function Name: ipmi_lcd_usage
  1400. *
  1401. * Description: This function prints help message for lcd command
  1402. * Input:
  1403. * Output:
  1404. *
  1405. * Return:
  1406. */
  1407. static void
  1408. ipmi_lcd_usage(void)
  1409. {
  1410. lprintf(LOG_NOTICE,
  1411. "");
  1412. lprintf(LOG_NOTICE,
  1413. "Generic DELL HW:");
  1414. lprintf(LOG_NOTICE,
  1415. " lcd set {none}|{default}|{custom <text>}");
  1416. lprintf(LOG_NOTICE,
  1417. " Set LCD text displayed during non-fault conditions");
  1418. lprintf(LOG_NOTICE,
  1419. "");
  1420. lprintf(LOG_NOTICE,
  1421. "iDRAC 11g or iDRAC 12g or iDRAC 13g :");
  1422. lprintf(LOG_NOTICE,
  1423. " lcd set {mode}|{lcdqualifier}|{errordisplay}");
  1424. lprintf(LOG_NOTICE,
  1425. " Allows you to set the LCD mode and user-defined string.");
  1426. lprintf(LOG_NOTICE,
  1427. "");
  1428. lprintf(LOG_NOTICE,
  1429. " lcd set mode {none}|{modelname}|{ipv4address}|{macaddress}|");
  1430. lprintf(LOG_NOTICE,
  1431. " {systemname}|{servicetag}|{ipv6address}|{ambienttemp}");
  1432. lprintf(LOG_NOTICE,
  1433. " {systemwatt }|{assettag}|{userdefined}<text>");
  1434. lprintf(LOG_NOTICE,
  1435. " Allows you to set the LCD display mode to any of the preceding");
  1436. lprintf(LOG_NOTICE,
  1437. " parameters");
  1438. lprintf(LOG_NOTICE,
  1439. "");
  1440. lprintf(LOG_NOTICE,
  1441. " lcd set lcdqualifier {watt}|{btuphr}|{celsius}|{fahrenheit}");
  1442. lprintf(LOG_NOTICE,
  1443. " Allows you to set the unit for the system ambient temperature mode.");
  1444. lprintf(LOG_NOTICE,
  1445. "");
  1446. lprintf(LOG_NOTICE,
  1447. " lcd set errordisplay {sel}|{simple}");
  1448. lprintf(LOG_NOTICE,
  1449. " Allows you to set the error display.");
  1450. lprintf(LOG_NOTICE,
  1451. "");
  1452. lprintf(LOG_NOTICE,
  1453. " lcd info");
  1454. lprintf(LOG_NOTICE,
  1455. " Show LCD text that is displayed during non-fault conditions");
  1456. lprintf(LOG_NOTICE,
  1457. "");
  1458. lprintf(LOG_NOTICE,
  1459. "");
  1460. lprintf(LOG_NOTICE,
  1461. " lcd set vkvm{active}|{inactive}");
  1462. lprintf(LOG_NOTICE,
  1463. " Set vKVM active and inactive, message will be displayed on lcd");
  1464. lprintf(LOG_NOTICE,
  1465. " when vKVM is active and vKVM session is in progress");
  1466. lprintf(LOG_NOTICE,
  1467. "");
  1468. lprintf(LOG_NOTICE,
  1469. " lcd set frontpanelaccess {viewandmodify}|{viewonly}|{disabled}");
  1470. lprintf(LOG_NOTICE,
  1471. " Set LCD mode to view and modify, view only or disabled ");
  1472. lprintf(LOG_NOTICE,
  1473. "");
  1474. lprintf(LOG_NOTICE,
  1475. " lcd status");
  1476. lprintf(LOG_NOTICE,
  1477. " Show LCD Status for vKVM display<active|inactive>");
  1478. lprintf(LOG_NOTICE,
  1479. " and Front Panel access mode {viewandmodify}|{viewonly}|{disabled}");
  1480. lprintf(LOG_NOTICE,
  1481. "");
  1482. }
  1483. /*
  1484. * Function Name: ipmi_delloem_mac_main
  1485. *
  1486. * Description: This function processes the delloem mac command
  1487. * Input: intf - ipmi interface
  1488. * argc - no of arguments
  1489. * argv - argument string array
  1490. * Output:
  1491. *
  1492. * Return: return code 0 - success
  1493. * -1 - failure
  1494. */
  1495. static int
  1496. ipmi_delloem_mac_main(struct ipmi_intf * intf, int argc, char ** argv)
  1497. {
  1498. int rc = 0;
  1499. int currIdInt = -1;
  1500. current_arg++;
  1501. if (argc > 1 && strcmp(argv[current_arg], "help") == 0) {
  1502. ipmi_mac_usage();
  1503. return 0;
  1504. }
  1505. ipmi_idracvalidator_command(intf);
  1506. if (argc == 1) {
  1507. rc = ipmi_macinfo(intf, 0xff);
  1508. } else if (strncmp(argv[current_arg], "list\0", 5) == 0) {
  1509. rc = ipmi_macinfo(intf, 0xff);
  1510. } else if (strncmp(argv[current_arg], "get\0", 4) == 0) {
  1511. current_arg++;
  1512. if (argv[current_arg] == NULL) {
  1513. ipmi_mac_usage();
  1514. return -1;
  1515. }
  1516. if (str2int(argv[current_arg],&currIdInt) != 0) {
  1517. lprintf(LOG_ERR,
  1518. "Invalid NIC number. The NIC number should be between 0-8");
  1519. return -1;
  1520. }
  1521. if ((currIdInt > 8) || (currIdInt < 0)) {
  1522. lprintf(LOG_ERR,
  1523. "Invalid NIC number. The NIC number should be between 0-8");
  1524. return -1;
  1525. }
  1526. rc = ipmi_macinfo(intf, currIdInt);
  1527. } else {
  1528. ipmi_mac_usage();
  1529. }
  1530. return rc;
  1531. }
  1532. EmbeddedNICMacAddressType EmbeddedNICMacAddress;
  1533. EmbeddedNICMacAddressType_10G EmbeddedNICMacAddress_10G;
  1534. static void
  1535. InitEmbeddedNICMacAddressValues()
  1536. {
  1537. uint8_t i;
  1538. uint8_t j;
  1539. for (i = 0; i < MAX_LOM; i++) {
  1540. EmbeddedNICMacAddress.LOMMacAddress[i].BladSlotNumber = 0;
  1541. EmbeddedNICMacAddress.LOMMacAddress[i].MacType = LOM_MACTYPE_RESERVED;
  1542. EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus =
  1543. LOM_ETHERNET_RESERVED;
  1544. EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber = 0;
  1545. EmbeddedNICMacAddress.LOMMacAddress[i].Reserved = 0;
  1546. for (j = 0; j < MACADDRESSLENGH; j++) {
  1547. EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j] = 0;
  1548. EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j] = 0;
  1549. }
  1550. }
  1551. }
  1552. uint8_t UseVirtualMacAddress = 0;
  1553. static int
  1554. ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf* intf,uint8_t NicNum)
  1555. {
  1556. struct ipmi_rs * rsp;
  1557. struct ipmi_rq req;
  1558. uint8_t msg_data[30];
  1559. uint8_t VirtualMacAddress [MACADDRESSLENGH];
  1560. uint8_t input_length=0;
  1561. uint8_t j;
  1562. uint8_t i;
  1563. if (NicNum != 0xff && NicNum != IDRAC_NIC_NUMBER) {
  1564. return 0;
  1565. }
  1566. UseVirtualMacAddress = 0;
  1567. input_length = 0;
  1568. msg_data[input_length++] = 1; /*Get*/
  1569. req.msg.netfn = DELL_OEM_NETFN;
  1570. req.msg.lun = 0;
  1571. req.msg.cmd = GET_IDRAC_VIRTUAL_MAC;
  1572. req.msg.data = msg_data;
  1573. req.msg.data_len = input_length;
  1574. rsp = intf->sendrecv(intf, &req);
  1575. if (rsp == NULL) {
  1576. return -1;
  1577. }
  1578. if (rsp->ccode > 0) {
  1579. return -1;
  1580. }
  1581. if ((IMC_IDRAC_12G_MODULAR == IMC_Type)
  1582. || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)
  1583. || (IMC_IDRAC_13G_MODULAR == IMC_Type)
  1584. || (IMC_IDRAC_13G_MONOLITHIC== IMC_Type)) {
  1585. /* Get the Chasiss Assigned MAC Addresss for 12g Only */
  1586. memcpy(VirtualMacAddress, ((rsp->data) + 1), MACADDRESSLENGH);
  1587. for (i = 0; i < MACADDRESSLENGH; i++) {
  1588. if (VirtualMacAddress[i] != 0) {
  1589. UseVirtualMacAddress = 1;
  1590. }
  1591. }
  1592. /* Get the Server Assigned MAC Addresss for 12g Only */
  1593. if (!UseVirtualMacAddress) {
  1594. memcpy(VirtualMacAddress, ((rsp->data) + 1 + MACADDRESSLENGH),
  1595. MACADDRESSLENGH);
  1596. for (i = 0; i < MACADDRESSLENGH; i++) {
  1597. if (VirtualMacAddress[i] != 0) {
  1598. UseVirtualMacAddress = 1;
  1599. }
  1600. }
  1601. }
  1602. } else {
  1603. memcpy(VirtualMacAddress, ((rsp->data) + VIRTUAL_MAC_OFFSET),
  1604. MACADDRESSLENGH);
  1605. for (i = 0; i < MACADDRESSLENGH; i++) {
  1606. if (VirtualMacAddress[i] != 0) {
  1607. UseVirtualMacAddress = 1;
  1608. }
  1609. }
  1610. }
  1611. if (UseVirtualMacAddress == 0) {
  1612. return -1;
  1613. }
  1614. if (IMC_IDRAC_10G == IMC_Type) {
  1615. printf("\nDRAC MAC Address ");
  1616. } else if ((IMC_IDRAC_11G_MODULAR == IMC_Type)
  1617. || (IMC_IDRAC_11G_MONOLITHIC== IMC_Type)) {
  1618. printf("\niDRAC6 MAC Address ");
  1619. } else if ((IMC_IDRAC_12G_MODULAR == IMC_Type)
  1620. || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)) {
  1621. printf("\niDRAC7 MAC Address ");
  1622. } else if ((IMC_IDRAC_13G_MODULAR == IMC_Type)
  1623. || (IMC_IDRAC_13G_MONOLITHIC== IMC_Type)) {
  1624. printf ("\niDRAC8 MAC Address ");
  1625. } else if ((IMC_MASER_LITE_BMC== IMC_Type)
  1626. || (IMC_MASER_LITE_NU== IMC_Type)) {
  1627. printf("\nBMC MAC Address ");
  1628. } else {
  1629. printf("\niDRAC6 MAC Address ");
  1630. }
  1631. printf("%s\n", mac2str(VirtualMacAddress));
  1632. return 0;
  1633. }
  1634. /*
  1635. * Function Name: ipmi_macinfo_drac_idrac_mac
  1636. *
  1637. * Description: This function retrieves the mac address of DRAC or iDRAC
  1638. * Input: NicNum
  1639. * Output:
  1640. * Return:
  1641. */
  1642. static int
  1643. ipmi_macinfo_drac_idrac_mac(struct ipmi_intf* intf,uint8_t NicNum)
  1644. {
  1645. struct ipmi_rs * rsp;
  1646. struct ipmi_rq req;
  1647. uint8_t msg_data[30];
  1648. uint8_t input_length=0;
  1649. uint8_t iDRAC6MacAddressByte[MACADDRESSLENGH];
  1650. uint8_t j;
  1651. ipmi_macinfo_drac_idrac_virtual_mac(intf,NicNum);
  1652. if ((NicNum != 0xff && NicNum != IDRAC_NIC_NUMBER)
  1653. || UseVirtualMacAddress != 0) {
  1654. return 0;
  1655. }
  1656. input_length = 0;
  1657. msg_data[input_length++] = LAN_CHANNEL_NUMBER;
  1658. msg_data[input_length++] = MAC_ADDR_PARAM;
  1659. msg_data[input_length++] = 0x00;
  1660. msg_data[input_length++] = 0x00;
  1661. req.msg.netfn = TRANSPORT_NETFN;
  1662. req.msg.lun = 0;
  1663. req.msg.cmd = GET_LAN_PARAM_CMD;
  1664. req.msg.data = msg_data;
  1665. req.msg.data_len = input_length;
  1666. rsp = intf->sendrecv(intf, &req);
  1667. if (rsp == NULL) {
  1668. lprintf(LOG_ERR, "Error in getting MAC Address");
  1669. return -1;
  1670. }
  1671. if (rsp->ccode > 0) {
  1672. lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
  1673. val2str(rsp->ccode, completion_code_vals));
  1674. return -1;
  1675. }
  1676. memcpy(iDRAC6MacAddressByte, ((rsp->data) + PARAM_REV_OFFSET),
  1677. MACADDRESSLENGH);
  1678. if (IMC_IDRAC_10G == IMC_Type) {
  1679. printf("\nDRAC MAC Address ");
  1680. } else if ((IMC_IDRAC_11G_MODULAR == IMC_Type)
  1681. || (IMC_IDRAC_11G_MONOLITHIC== IMC_Type)) {
  1682. printf("\niDRAC6 MAC Address ");
  1683. } else if ((IMC_IDRAC_12G_MODULAR == IMC_Type)
  1684. || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)) {
  1685. printf("\niDRAC7 MAC Address ");
  1686. } else if ((IMC_IDRAC_13G_MODULAR == IMC_Type)
  1687. || (IMC_IDRAC_13G_MONOLITHIC== IMC_Type)) {
  1688. printf ("\niDRAC8 MAC Address ");
  1689. } else if ((IMC_MASER_LITE_BMC== IMC_Type)
  1690. || (IMC_MASER_LITE_NU== IMC_Type)) {
  1691. printf("\n\rBMC MAC Address ");
  1692. } else {
  1693. printf("\niDRAC6 MAC Address ");
  1694. }
  1695. printf("%s\n", mac2str(iDRAC6MacAddressByte));
  1696. return 0;
  1697. }
  1698. /*
  1699. * Function Name: ipmi_macinfo_10g
  1700. *
  1701. * Description: This function retrieves the mac address of LOMs
  1702. * Input: intf - ipmi interface
  1703. * NicNum - NIC number
  1704. * Output:
  1705. * Return:
  1706. */
  1707. static int
  1708. ipmi_macinfo_10g(struct ipmi_intf* intf, uint8_t NicNum)
  1709. {
  1710. struct ipmi_rs * rsp;
  1711. struct ipmi_rq req;
  1712. uint8_t msg_data[30];
  1713. uint8_t input_length=0;
  1714. uint8_t j;
  1715. uint8_t i;
  1716. uint8_t Total_No_NICs = 0;
  1717. InitEmbeddedNICMacAddressValues();
  1718. memset(msg_data, 0, sizeof(msg_data));
  1719. input_length = 0;
  1720. msg_data[input_length++] = 0x00; /* Get Parameter Command */
  1721. msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_9G_10G; /* OEM Param */
  1722. msg_data[input_length++] = 0x00;
  1723. msg_data[input_length++] = 0x00;
  1724. memset(&req, 0, sizeof(req));
  1725. req.msg.netfn = IPMI_NETFN_APP;
  1726. req.msg.lun = 0;
  1727. req.msg.cmd = IPMI_GET_SYS_INFO;
  1728. req.msg.data = msg_data;
  1729. req.msg.data_len = input_length;
  1730. rsp = intf->sendrecv(intf, &req);
  1731. if (rsp == NULL) {
  1732. lprintf(LOG_ERR, "Error in getting MAC Address");
  1733. return -1;
  1734. }
  1735. if (rsp->ccode > 0) {
  1736. lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
  1737. val2str(rsp->ccode, completion_code_vals));
  1738. return -1;
  1739. }
  1740. Total_No_NICs = (uint8_t)rsp->data[0 + PARAM_REV_OFFSET]; /* Byte 1: Total Number of Embedded NICs */
  1741. if (IDRAC_NIC_NUMBER != NicNum) {
  1742. if (0xff == NicNum) {
  1743. printf("\nSystem LOMs");
  1744. }
  1745. printf("\nNIC Number\tMAC Address\n");
  1746. memcpy(&EmbeddedNICMacAddress_10G,
  1747. ((rsp->data) + PARAM_REV_OFFSET+TOTAL_N0_NICS_INDEX),
  1748. Total_No_NICs* MACADDRESSLENGH);
  1749. /*Read the LOM type and Mac Addresses */
  1750. for (i = 0; i < Total_No_NICs; i++) {
  1751. if ((0xff == NicNum) || (i == NicNum)) {
  1752. printf("\n%d",i);
  1753. printf("\t\t%s",
  1754. mac2str(EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte));
  1755. }
  1756. }
  1757. printf("\n");
  1758. }
  1759. ipmi_macinfo_drac_idrac_mac(intf,NicNum);
  1760. return 0;
  1761. }
  1762. /*
  1763. * Function Name: ipmi_macinfo_11g
  1764. *
  1765. * Description: This function retrieves the mac address of LOMs
  1766. * Input: intf - ipmi interface
  1767. * Output:
  1768. * Return:
  1769. */
  1770. static int
  1771. ipmi_macinfo_11g(struct ipmi_intf* intf, uint8_t NicNum)
  1772. {
  1773. struct ipmi_rs * rsp;
  1774. struct ipmi_rq req;
  1775. uint8_t input_length = 0;
  1776. uint8_t i;
  1777. uint8_t j;
  1778. uint8_t len;
  1779. uint8_t loop_count;
  1780. uint8_t maxlen;
  1781. uint8_t msg_data[30];
  1782. uint8_t offset;
  1783. offset = 0;
  1784. len = 8; /*eigher 8 or 16 */
  1785. maxlen = 64;
  1786. loop_count = maxlen / len;
  1787. InitEmbeddedNICMacAddressValues();
  1788. memset(msg_data, 0, sizeof(msg_data));
  1789. input_length = 0;
  1790. msg_data[input_length++] = 0x00; /* Get Parameter Command */
  1791. msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_11G; /* OEM Param */
  1792. msg_data[input_length++] = 0x00;
  1793. msg_data[input_length++] = 0x00;
  1794. msg_data[input_length++] = 0x00;
  1795. msg_data[input_length++] = 0x00;
  1796. memset(&req, 0, sizeof(req));
  1797. req.msg.netfn = IPMI_NETFN_APP;
  1798. req.msg.lun = 0;
  1799. req.msg.cmd = IPMI_GET_SYS_INFO;
  1800. req.msg.data = msg_data;
  1801. req.msg.data_len = input_length;
  1802. rsp = intf->sendrecv(intf, &req);
  1803. if (rsp == NULL) {
  1804. lprintf(LOG_ERR, "Error in getting MAC Address");
  1805. return -1;
  1806. }
  1807. if (rsp->ccode > 0) {
  1808. lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
  1809. val2str(rsp->ccode, completion_code_vals));
  1810. return -1;
  1811. }
  1812. len = 8; /*eigher 8 or 16 */
  1813. maxlen = (uint8_t)rsp->data[0 + PARAM_REV_OFFSET];
  1814. loop_count = maxlen / len;
  1815. if (IDRAC_NIC_NUMBER != NicNum) {
  1816. if (0xff == NicNum) {
  1817. printf("\nSystem LOMs");
  1818. }
  1819. printf("\nNIC Number\tMAC Address\t\tStatus\n");
  1820. /*Read the LOM type and Mac Addresses */
  1821. offset=0;
  1822. for (i = 0; i < loop_count; i++, offset = offset + len) {
  1823. input_length = 4;
  1824. msg_data[input_length++] = offset;
  1825. msg_data[input_length++] = len;
  1826. req.msg.netfn = IPMI_NETFN_APP;
  1827. req.msg.lun = 0;
  1828. req.msg.cmd = IPMI_GET_SYS_INFO;
  1829. req.msg.data = msg_data;
  1830. req.msg.data_len = input_length;
  1831. rsp = intf->sendrecv(intf, &req);
  1832. if (rsp == NULL) {
  1833. lprintf(LOG_ERR, "Error in getting MAC Address");
  1834. return -1;
  1835. }
  1836. if (rsp->ccode > 0) {
  1837. lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
  1838. val2str(rsp->ccode, completion_code_vals));
  1839. return -1;
  1840. }
  1841. memcpy(&(EmbeddedNICMacAddress.LOMMacAddress[i]),
  1842. ((rsp->data)+PARAM_REV_OFFSET), len);
  1843. if (LOM_MACTYPE_ETHERNET == EmbeddedNICMacAddress.LOMMacAddress[i].MacType) {
  1844. if ((0xff==NicNum)
  1845. || (NicNum == EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber)) {
  1846. printf("\n%d",EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber);
  1847. printf("\t\t%s", mac2str(EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte));
  1848. if (LOM_ETHERNET_ENABLED
  1849. == EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus) {
  1850. printf("\tEnabled");
  1851. } else {
  1852. printf("\tDisabled");
  1853. }
  1854. }
  1855. }
  1856. }
  1857. printf("\n");
  1858. }
  1859. ipmi_macinfo_drac_idrac_mac(intf,NicNum);
  1860. return 0;
  1861. }
  1862. /*
  1863. * Function Name: ipmi_macinfo
  1864. *
  1865. * Description: This function retrieves the mac address of LOMs
  1866. * Input: intf - ipmi interface
  1867. * Output:
  1868. * Return:
  1869. */
  1870. static int
  1871. ipmi_macinfo(struct ipmi_intf* intf, uint8_t NicNum)
  1872. {
  1873. if (IMC_IDRAC_10G == IMC_Type) {
  1874. return ipmi_macinfo_10g(intf,NicNum);
  1875. } else if ((IMC_IDRAC_11G_MODULAR == IMC_Type
  1876. || IMC_IDRAC_11G_MONOLITHIC == IMC_Type)
  1877. || (IMC_IDRAC_12G_MODULAR == IMC_Type
  1878. || IMC_IDRAC_12G_MONOLITHIC == IMC_Type)
  1879. || (IMC_IDRAC_13G_MODULAR == IMC_Type
  1880. || IMC_IDRAC_13G_MONOLITHIC == IMC_Type)
  1881. || (IMC_MASER_LITE_NU == IMC_Type || IMC_MASER_LITE_BMC== IMC_Type)) {
  1882. return ipmi_macinfo_11g(intf,NicNum);
  1883. } else {
  1884. lprintf(LOG_ERR, "Error in getting MAC Address : Not supported platform");
  1885. return (-1);
  1886. }
  1887. }
  1888. /*
  1889. * Function Name: ipmi_mac_usage
  1890. *
  1891. * Description: This function prints help message for mac command
  1892. * Input:
  1893. * Output:
  1894. *
  1895. * Return:
  1896. */
  1897. static void
  1898. ipmi_mac_usage(void)
  1899. {
  1900. lprintf(LOG_NOTICE,
  1901. "");
  1902. lprintf(LOG_NOTICE,
  1903. " mac list");
  1904. lprintf(LOG_NOTICE,
  1905. " Lists the MAC address of LOMs");
  1906. lprintf(LOG_NOTICE,
  1907. "");
  1908. lprintf(LOG_NOTICE,
  1909. " mac get <NIC number>");
  1910. lprintf(LOG_NOTICE,
  1911. " Shows the MAC address of specified LOM. 0-7 System LOM, 8- DRAC/iDRAC.");
  1912. lprintf(LOG_NOTICE,
  1913. "");
  1914. }
  1915. /*
  1916. * Function Name: ipmi_delloem_lan_main
  1917. *
  1918. * Description: This function processes the delloem lan command
  1919. * Input: intf - ipmi interface
  1920. * argc - no of arguments
  1921. * argv - argument string array
  1922. * Output:
  1923. *
  1924. * Return: return code 0 - success
  1925. * -1 - failure
  1926. */
  1927. static int
  1928. ipmi_delloem_lan_main(struct ipmi_intf * intf, int argc, char ** argv)
  1929. {
  1930. int rc = 0;
  1931. int nic_selection = 0;
  1932. char nic_set[2] = {0};
  1933. current_arg++;
  1934. if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) {
  1935. ipmi_lan_usage();
  1936. return 0;
  1937. }
  1938. ipmi_idracvalidator_command(intf);
  1939. if (!IsLANSupported()) {
  1940. lprintf(LOG_ERR, "lan is not supported on this system.");
  1941. return -1;
  1942. } else if (strncmp(argv[current_arg], "set\0", 4) == 0) {
  1943. current_arg++;
  1944. if (argv[current_arg] == NULL) {
  1945. ipmi_lan_usage();
  1946. return -1;
  1947. }
  1948. if (iDRAC_FLAG_12_13) {
  1949. nic_selection = get_nic_selection_mode_12g(intf, current_arg, argv,
  1950. nic_set);
  1951. if (INVALID == nic_selection) {
  1952. ipmi_lan_usage();
  1953. return -1;
  1954. } else if (INVAILD_FAILOVER_MODE == nic_selection) {
  1955. lprintf(LOG_ERR, INVAILD_FAILOVER_MODE_STRING);
  1956. return (-1);
  1957. } else if (INVAILD_FAILOVER_MODE_SETTINGS == nic_selection) {
  1958. lprintf(LOG_ERR, INVAILD_FAILOVER_MODE_SET);
  1959. return (-1);
  1960. } else if (INVAILD_SHARED_MODE == nic_selection) {
  1961. lprintf(LOG_ERR, INVAILD_SHARED_MODE_SET_STRING);
  1962. return (-1);
  1963. }
  1964. rc = ipmi_lan_set_nic_selection_12g(intf,nic_set);
  1965. } else {
  1966. nic_selection = get_nic_selection_mode(current_arg, argv);
  1967. if (INVALID == nic_selection) {
  1968. ipmi_lan_usage();
  1969. return -1;
  1970. }
  1971. if (IMC_IDRAC_11G_MODULAR == IMC_Type) {
  1972. lprintf(LOG_ERR, INVAILD_SHARED_MODE_SET_STRING);
  1973. return (-1);
  1974. }
  1975. rc = ipmi_lan_set_nic_selection(intf,nic_selection);
  1976. }
  1977. return 0;
  1978. } else if (strncmp(argv[current_arg], "get\0", 4) == 0) {
  1979. current_arg++;
  1980. if (argv[current_arg] == NULL) {
  1981. rc = ipmi_lan_get_nic_selection(intf);
  1982. return rc;
  1983. } else if (strncmp(argv[current_arg], "active\0", 7) == 0) {
  1984. rc = ipmi_lan_get_active_nic(intf);
  1985. return rc;
  1986. } else {
  1987. ipmi_lan_usage();
  1988. }
  1989. } else {
  1990. ipmi_lan_usage();
  1991. return -1;
  1992. }
  1993. return rc;
  1994. }
  1995. static int
  1996. IsLANSupported()
  1997. {
  1998. if (IMC_IDRAC_11G_MODULAR == IMC_Type) {
  1999. return 0;
  2000. }
  2001. return 1;
  2002. }
  2003. static int
  2004. get_nic_selection_mode_12g(struct ipmi_intf* intf,int current_arg,
  2005. char ** argv, char *nic_set)
  2006. {
  2007. /* First get the current settings. */
  2008. struct ipmi_rs * rsp;
  2009. struct ipmi_rq req;
  2010. int failover = 0;
  2011. uint8_t input_length = 0;
  2012. uint8_t msg_data[30];
  2013. input_length = 0;
  2014. req.msg.netfn = DELL_OEM_NETFN;
  2015. req.msg.lun = 0;
  2016. req.msg.cmd = GET_NIC_SELECTION_12G_CMD;
  2017. req.msg.data = msg_data;
  2018. req.msg.data_len = input_length;
  2019. rsp = intf->sendrecv(intf, &req);
  2020. if (rsp == NULL) {
  2021. lprintf(LOG_ERR, "Error in getting nic selection");
  2022. return -1;
  2023. } else if (rsp->ccode > 0) {
  2024. lprintf(LOG_ERR, "Error in getting nic selection (%s)",
  2025. val2str(rsp->ccode, completion_code_vals));
  2026. return -1;
  2027. }
  2028. nic_set[0] = rsp->data[0];
  2029. nic_set[1] = rsp->data[1];
  2030. if (argv[current_arg] != NULL
  2031. && strncmp(argv[current_arg], "dedicated\0", 10) == 0) {
  2032. nic_set[0] = 1;
  2033. nic_set[1] = 0;
  2034. return 0;
  2035. }
  2036. if (argv[current_arg] != NULL
  2037. && strncmp(argv[current_arg], "shared\0", 7) == 0) {
  2038. /* placeholder */
  2039. } else {
  2040. return INVALID;
  2041. }
  2042. current_arg++;
  2043. if (argv[current_arg] != NULL
  2044. && strncmp(argv[current_arg], "with\0", 5) == 0) {
  2045. /* placeholder */
  2046. } else {
  2047. return INVALID;
  2048. }
  2049. current_arg++;
  2050. if (argv[current_arg] != NULL
  2051. && strncmp(argv[current_arg], "failover\0", 9) == 0) {
  2052. failover = 1;
  2053. }
  2054. if (failover) {
  2055. current_arg++;
  2056. }
  2057. if (argv[current_arg] != NULL
  2058. && strncmp(argv[current_arg], "lom1\0", 5) == 0) {
  2059. if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
  2060. return INVAILD_SHARED_MODE;
  2061. }
  2062. if (failover) {
  2063. if (nic_set[0] == 2) {
  2064. return INVAILD_FAILOVER_MODE;
  2065. } else if (nic_set[0] == 1) {
  2066. return INVAILD_FAILOVER_MODE_SETTINGS;
  2067. }
  2068. nic_set[1] = 2;
  2069. } else {
  2070. nic_set[0] = 2;
  2071. if (nic_set[1] == 2) {
  2072. nic_set[1] = 0;
  2073. }
  2074. }
  2075. return 0;
  2076. } else if (argv[current_arg] != NULL
  2077. && strncmp(argv[current_arg], "lom2\0", 5) == 0) {
  2078. if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
  2079. return INVAILD_SHARED_MODE;
  2080. }
  2081. if (failover) {
  2082. if (nic_set[0] == 3) {
  2083. return INVAILD_FAILOVER_MODE;
  2084. } else if(nic_set[0] == 1) {
  2085. return INVAILD_FAILOVER_MODE_SETTINGS;
  2086. }
  2087. nic_set[1] = 3;
  2088. } else {
  2089. nic_set[0] = 3;
  2090. if (nic_set[1] == 3) {
  2091. nic_set[1] = 0;
  2092. }
  2093. }
  2094. return 0;
  2095. } else if (argv[current_arg] != NULL
  2096. && strncmp(argv[current_arg], "lom3\0", 5) == 0) {
  2097. if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
  2098. return INVAILD_SHARED_MODE;
  2099. }
  2100. if (failover) {
  2101. if (nic_set[0] == 4) {
  2102. return INVAILD_FAILOVER_MODE;
  2103. } else if(nic_set[0] == 1) {
  2104. return INVAILD_FAILOVER_MODE_SETTINGS;
  2105. }
  2106. nic_set[1] = 4;
  2107. } else {
  2108. nic_set[0] = 4;
  2109. if (nic_set[1] == 4) {
  2110. nic_set[1] = 0;
  2111. }
  2112. }
  2113. return 0;
  2114. } else if (argv[current_arg] != NULL
  2115. && strncmp(argv[current_arg], "lom4\0", 5) == 0) {
  2116. if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
  2117. return INVAILD_SHARED_MODE;
  2118. }
  2119. if (failover) {
  2120. if (nic_set[0] == 5) {
  2121. return INVAILD_FAILOVER_MODE;
  2122. } else if(nic_set[0] == 1) {
  2123. return INVAILD_FAILOVER_MODE_SETTINGS;
  2124. }
  2125. nic_set[1] = 5;
  2126. } else {
  2127. nic_set[0] = 5;
  2128. if (nic_set[1] == 5) {
  2129. nic_set[1] = 0;
  2130. }
  2131. }
  2132. return 0;
  2133. } else if (failover && argv[current_arg] != NULL
  2134. && strncmp(argv[current_arg], "none\0", 5) == 0) {
  2135. if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type) ) {
  2136. return INVAILD_SHARED_MODE;
  2137. }
  2138. if (failover) {
  2139. if (nic_set[0] == 1) {
  2140. return INVAILD_FAILOVER_MODE_SETTINGS;
  2141. }
  2142. nic_set[1] = 0;
  2143. }
  2144. return 0;
  2145. } else if (failover && argv[current_arg] != NULL
  2146. && strncmp(argv[current_arg], "all\0", 4) == 0) {
  2147. /* placeholder */
  2148. } else {
  2149. return INVALID;
  2150. }
  2151. current_arg++;
  2152. if (failover && argv[current_arg] != NULL
  2153. && strncmp(argv[current_arg], "loms\0", 5) == 0) {
  2154. if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
  2155. return INVAILD_SHARED_MODE;
  2156. }
  2157. if (nic_set[0] == 1) {
  2158. return INVAILD_FAILOVER_MODE_SETTINGS;
  2159. }
  2160. nic_set[1] = 6;
  2161. return 0;
  2162. }
  2163. return INVALID;
  2164. }
  2165. static int
  2166. get_nic_selection_mode(int current_arg, char ** argv)
  2167. {
  2168. if (argv[current_arg] != NULL
  2169. && strncmp(argv[current_arg], "dedicated\0", 10) == 0) {
  2170. return DEDICATED;
  2171. }
  2172. if (argv[current_arg] != NULL
  2173. && strncmp(argv[current_arg], "shared\0", 7) == 0) {
  2174. if (argv[current_arg+1] == NULL) {
  2175. return SHARED;
  2176. }
  2177. }
  2178. current_arg++;
  2179. if (argv[current_arg] != NULL
  2180. && strncmp(argv[current_arg], "with\0", 5) == 0) {
  2181. /* place holder */
  2182. } else {
  2183. return INVALID;
  2184. }
  2185. current_arg++;
  2186. if (argv[current_arg] != NULL
  2187. && strncmp(argv[current_arg], "failover\0", 9) == 0) {
  2188. /* place holder */
  2189. } else {
  2190. return INVALID;
  2191. }
  2192. current_arg++;
  2193. if (argv[current_arg] != NULL
  2194. && strncmp(argv[current_arg], "lom2\0", 5) == 0) {
  2195. return SHARED_WITH_FAILOVER_LOM2;
  2196. } else if (argv[current_arg] != NULL
  2197. && strncmp(argv[current_arg], "all\0", 4) == 0) {
  2198. /* place holder */
  2199. } else {
  2200. return INVALID;
  2201. }
  2202. current_arg++;
  2203. if (argv[current_arg] != NULL
  2204. && strncmp(argv[current_arg], "loms\0", 5) == 0) {
  2205. return SHARED_WITH_FAILOVER_ALL_LOMS;
  2206. }
  2207. return INVALID;
  2208. }
  2209. static int
  2210. ipmi_lan_set_nic_selection_12g(struct ipmi_intf * intf, uint8_t * nic_selection)
  2211. {
  2212. struct ipmi_rs * rsp;
  2213. struct ipmi_rq req;
  2214. uint8_t input_length = 0;
  2215. uint8_t msg_data[30];
  2216. input_length = 0;
  2217. msg_data[input_length++] = nic_selection[0];
  2218. msg_data[input_length++] = nic_selection[1];
  2219. req.msg.netfn = DELL_OEM_NETFN;
  2220. req.msg.lun = 0;
  2221. req.msg.cmd = SET_NIC_SELECTION_12G_CMD;
  2222. req.msg.data = msg_data;
  2223. req.msg.data_len = input_length;
  2224. rsp = intf->sendrecv(intf, &req);
  2225. if (rsp == NULL) {
  2226. lprintf(LOG_ERR, "Error in setting nic selection");
  2227. return -1;
  2228. } else if( (nic_selection[0] == 1)
  2229. && (( iDRAC_FLAG_12_13 )
  2230. && (rsp->ccode == LICENSE_NOT_SUPPORTED))) {
  2231. /* Check license only for setting the dedicated nic. */
  2232. lprintf(LOG_ERR,
  2233. "FM001 : A required license is missing or expired");
  2234. return -1;
  2235. } else if (rsp->ccode > 0) {
  2236. lprintf(LOG_ERR, "Error in setting nic selection (%s)",
  2237. val2str(rsp->ccode, completion_code_vals));
  2238. return -1;
  2239. }
  2240. printf("configured successfully");
  2241. return 0;
  2242. }
  2243. static int
  2244. ipmi_lan_set_nic_selection(struct ipmi_intf * intf, uint8_t nic_selection)
  2245. {
  2246. struct ipmi_rs * rsp;
  2247. struct ipmi_rq req;
  2248. uint8_t input_length = 0;
  2249. uint8_t msg_data[30];
  2250. input_length = 0;
  2251. msg_data[input_length++] = nic_selection;
  2252. req.msg.netfn = DELL_OEM_NETFN;
  2253. req.msg.lun = 0;
  2254. req.msg.cmd = SET_NIC_SELECTION_CMD;
  2255. req.msg.data = msg_data;
  2256. req.msg.data_len = input_length;
  2257. rsp = intf->sendrecv(intf, &req);
  2258. if (rsp == NULL) {
  2259. lprintf(LOG_ERR, "Error in setting nic selection");
  2260. return -1;
  2261. } else if (rsp->ccode > 0) {
  2262. lprintf(LOG_ERR, "Error in setting nic selection (%s)",
  2263. val2str(rsp->ccode, completion_code_vals));
  2264. return -1;
  2265. }
  2266. printf("configured successfully");
  2267. return 0;
  2268. }
  2269. static int
  2270. ipmi_lan_get_nic_selection(struct ipmi_intf * intf)
  2271. {
  2272. struct ipmi_rs * rsp;
  2273. struct ipmi_rq req;
  2274. uint8_t input_length=0;
  2275. uint8_t msg_data[30];
  2276. uint8_t nic_selection=-1;
  2277. uint8_t nic_selection_failover = 0;
  2278. input_length = 0;
  2279. req.msg.netfn = DELL_OEM_NETFN;
  2280. req.msg.lun = 0;
  2281. if( iDRAC_FLAG_12_13 ) {
  2282. req.msg.cmd = GET_NIC_SELECTION_12G_CMD;
  2283. } else {
  2284. req.msg.cmd = GET_NIC_SELECTION_CMD;
  2285. }
  2286. req.msg.data = msg_data;
  2287. req.msg.data_len = input_length;
  2288. rsp = intf->sendrecv(intf, &req);
  2289. if (rsp == NULL) {
  2290. lprintf(LOG_ERR, "Error in getting nic selection");
  2291. return -1;
  2292. } else if (rsp->ccode > 0) {
  2293. lprintf(LOG_ERR, "Error in getting nic selection (%s)",
  2294. val2str(rsp->ccode, completion_code_vals));
  2295. return -1;
  2296. }
  2297. nic_selection = rsp->data[0];
  2298. if( iDRAC_FLAG_12_13 ) {
  2299. nic_selection_failover = rsp->data[1];
  2300. if ((nic_selection < 6) && (nic_selection > 0)
  2301. && (nic_selection_failover < 7)) {
  2302. if(nic_selection == 1) {
  2303. printf("%s\n",NIC_Selection_Mode_String_12g[nic_selection-1]);
  2304. } else if(nic_selection) {
  2305. printf("Shared LOM : %s\n",
  2306. NIC_Selection_Mode_String_12g[nic_selection-1]);
  2307. if(nic_selection_failover == 0) {
  2308. printf("Failover LOM : None\n");
  2309. } else if(nic_selection_failover >= 2 && nic_selection_failover <= 6) {
  2310. printf("Failover LOM : %s\n",
  2311. NIC_Selection_Mode_String_12g[nic_selection_failover + 3]);
  2312. }
  2313. }
  2314. } else {
  2315. lprintf(LOG_ERR, "Error Outof bond Value received (%d) (%d)",
  2316. nic_selection,nic_selection_failover);
  2317. return -1;
  2318. }
  2319. } else {
  2320. printf("%s\n",NIC_Selection_Mode_String[nic_selection]);
  2321. }
  2322. return 0;
  2323. }
  2324. static int
  2325. ipmi_lan_get_active_nic(struct ipmi_intf * intf)
  2326. {
  2327. struct ipmi_rs * rsp;
  2328. struct ipmi_rq req;
  2329. uint8_t active_nic=0;
  2330. uint8_t current_lom =0;
  2331. uint8_t input_length=0;
  2332. uint8_t msg_data[30];
  2333. input_length = 0;
  2334. msg_data[input_length++] = 0; /* Get Status */
  2335. msg_data[input_length++] = 0; /* Reserved */
  2336. msg_data[input_length++] = 0; /* Reserved */
  2337. req.msg.netfn = DELL_OEM_NETFN;
  2338. req.msg.lun = 0;
  2339. req.msg.cmd = GET_ACTIVE_NIC_CMD;
  2340. req.msg.data = msg_data;
  2341. req.msg.data_len = input_length;
  2342. rsp = intf->sendrecv(intf, &req);
  2343. if (rsp == NULL) {
  2344. lprintf(LOG_ERR, "Error in getting Active LOM Status");
  2345. return -1;
  2346. } else if (rsp->ccode > 0) {
  2347. lprintf(LOG_ERR, "Error in getting Active LOM Status (%s)",
  2348. val2str(rsp->ccode, completion_code_vals));
  2349. return -1;
  2350. }
  2351. current_lom = rsp->data[0];
  2352. input_length = 0;
  2353. msg_data[input_length++] = 1; /* Get Link status */
  2354. msg_data[input_length++] = 0; /* Reserved */
  2355. msg_data[input_length++] = 0; /* Reserved */
  2356. req.msg.netfn = DELL_OEM_NETFN;
  2357. req.msg.lun = 0;
  2358. req.msg.cmd = GET_ACTIVE_NIC_CMD;
  2359. req.msg.data = msg_data;
  2360. req.msg.data_len = input_length;
  2361. rsp = intf->sendrecv(intf, &req);
  2362. if (rsp == NULL) {
  2363. lprintf(LOG_ERR, "Error in getting Active LOM Status");
  2364. return -1;
  2365. } else if (rsp->ccode > 0) {
  2366. lprintf(LOG_ERR, "Error in getting Active LOM Status (%s)",
  2367. val2str(rsp->ccode, completion_code_vals));
  2368. return -1;
  2369. }
  2370. active_nic = rsp->data[1];
  2371. if (current_lom < 6 && active_nic) {
  2372. printf("\n%s\n", AciveLOM_String[current_lom]);
  2373. } else {
  2374. printf("\n%s\n", AciveLOM_String[0]);
  2375. }
  2376. return 0;
  2377. }
  2378. static void
  2379. ipmi_lan_usage(void)
  2380. {
  2381. /* TODO:
  2382. * - rewrite
  2383. * - review
  2384. * - make it fit into 80 chars per line
  2385. * - this ``shared with Failover None).'' seems like a typo
  2386. */
  2387. lprintf(LOG_NOTICE,
  2388. "");
  2389. lprintf(LOG_NOTICE,
  2390. " lan set <Mode>");
  2391. lprintf(LOG_NOTICE,
  2392. " sets the NIC Selection Mode :");
  2393. lprintf(LOG_NOTICE,
  2394. " on iDRAC12g OR iDRAC13g :");
  2395. lprintf(LOG_NOTICE,
  2396. " dedicated, shared with lom1, shared with lom2,shared with lom3,shared");
  2397. lprintf(LOG_NOTICE,
  2398. " with lom4,shared with failover lom1,shared with failover lom2,shared");
  2399. lprintf(LOG_NOTICE,
  2400. " with failover lom3,shared with failover lom4,shared with Failover all");
  2401. lprintf(LOG_NOTICE,
  2402. " loms, shared with Failover None).");
  2403. lprintf(LOG_NOTICE,
  2404. " on other systems :");
  2405. lprintf(LOG_NOTICE,
  2406. " dedicated, shared, shared with failover lom2,");
  2407. lprintf(LOG_NOTICE,
  2408. " shared with Failover all loms.");
  2409. lprintf(LOG_NOTICE,
  2410. "");
  2411. lprintf(LOG_NOTICE,
  2412. " lan get ");
  2413. lprintf(LOG_NOTICE,
  2414. " on iDRAC12g or iDRAC13g :");
  2415. lprintf(LOG_NOTICE,
  2416. " returns the current NIC Selection Mode (dedicated, shared with lom1, shared");
  2417. lprintf(LOG_NOTICE,
  2418. " with lom2, shared with lom3, shared with lom4,shared with failover lom1,");
  2419. lprintf(LOG_NOTICE,
  2420. " shared with failover lom2,shared with failover lom3,shared with failover");
  2421. lprintf(LOG_NOTICE,
  2422. " lom4,shared with Failover all loms,shared with Failover None).");
  2423. lprintf(LOG_NOTICE,
  2424. " on other systems :");
  2425. lprintf(LOG_NOTICE,
  2426. " dedicated, shared, shared with failover,");
  2427. lprintf(LOG_NOTICE,
  2428. " lom2, shared with Failover all loms.");
  2429. lprintf(LOG_NOTICE,
  2430. "");
  2431. lprintf(LOG_NOTICE,
  2432. " lan get active");
  2433. lprintf(LOG_NOTICE,
  2434. " returns the current active NIC (dedicated, LOM1, LOM2, LOM3, LOM4).");
  2435. lprintf(LOG_NOTICE,
  2436. "");
  2437. }
  2438. /*
  2439. * Function Name: ipmi_delloem_powermonitor_main
  2440. *
  2441. * Description: This function processes the delloem powermonitor command
  2442. * Input: intf - ipmi interface
  2443. * argc - no of arguments
  2444. * argv - argument string array
  2445. * Output:
  2446. *
  2447. * Return: return code 0 - success
  2448. * -1 - failure
  2449. */
  2450. static int
  2451. ipmi_delloem_powermonitor_main(struct ipmi_intf * intf, int argc, char ** argv)
  2452. {
  2453. int rc = 0;
  2454. current_arg++;
  2455. if (argc > 1 && strcmp(argv[current_arg], "help") == 0) {
  2456. ipmi_powermonitor_usage();
  2457. return 0;
  2458. }
  2459. ipmi_idracvalidator_command(intf);
  2460. if (argc == 1) {
  2461. rc = ipmi_powermgmt(intf);
  2462. } else if (strncmp(argv[current_arg], "status\0", 7) == 0) {
  2463. rc = ipmi_powermgmt(intf);
  2464. } else if (strncmp(argv[current_arg], "clear\0", 6) == 0) {
  2465. current_arg++;
  2466. if (argv[current_arg] == NULL) {
  2467. ipmi_powermonitor_usage();
  2468. return -1;
  2469. } else if (strncmp(argv[current_arg], "peakpower\0", 10) == 0) {
  2470. rc = ipmi_powermgmt_clear(intf, 1);
  2471. } else if (strncmp(argv[current_arg], "cumulativepower\0", 16) == 0) {
  2472. rc = ipmi_powermgmt_clear(intf, 0);
  2473. } else {
  2474. ipmi_powermonitor_usage();
  2475. return -1;
  2476. }
  2477. } else if (strncmp(argv[current_arg], "powerconsumption\0", 17) == 0) {
  2478. current_arg++;
  2479. if (argv[current_arg] == NULL) {
  2480. rc = ipmi_print_get_power_consmpt_data(intf,watt);
  2481. } else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
  2482. rc = ipmi_print_get_power_consmpt_data(intf, watt);
  2483. } else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
  2484. rc = ipmi_print_get_power_consmpt_data(intf, btuphr);
  2485. } else {
  2486. ipmi_powermonitor_usage();
  2487. return -1;
  2488. }
  2489. } else if (strncmp(argv[current_arg], "powerconsumptionhistory\0", 23) == 0) {
  2490. current_arg++;
  2491. if (argv[current_arg] == NULL) {
  2492. rc = ipmi_print_power_consmpt_history(intf,watt);
  2493. } else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
  2494. rc = ipmi_print_power_consmpt_history(intf, watt);
  2495. } else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
  2496. rc = ipmi_print_power_consmpt_history(intf, btuphr);
  2497. } else {
  2498. ipmi_powermonitor_usage();
  2499. return -1;
  2500. }
  2501. } else if (strncmp(argv[current_arg], "getpowerbudget\0", 15) == 0) {
  2502. current_arg++;
  2503. if (argv[current_arg] == NULL) {
  2504. rc=ipmi_print_power_cap(intf,watt);
  2505. } else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
  2506. rc = ipmi_print_power_cap(intf, watt);
  2507. } else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
  2508. rc = ipmi_print_power_cap(intf, btuphr);
  2509. } else {
  2510. ipmi_powermonitor_usage();
  2511. return -1;
  2512. }
  2513. } else if (strncmp(argv[current_arg], "setpowerbudget\0", 15) == 0) {
  2514. int val;
  2515. current_arg++;
  2516. if (argv[current_arg] == NULL) {
  2517. ipmi_powermonitor_usage();
  2518. return -1;
  2519. }
  2520. if (strchr(argv[current_arg], '.')) {
  2521. lprintf(LOG_ERR,
  2522. "Cap value in Watts, Btu/hr or percent should be whole number");
  2523. return -1;
  2524. }
  2525. if (str2int(argv[current_arg], &val) != 0) {
  2526. lprintf(LOG_ERR, "Given capacity value '%s' is invalid.",
  2527. argv[current_arg]);
  2528. return (-1);
  2529. }
  2530. current_arg++;
  2531. if (argv[current_arg] == NULL) {
  2532. ipmi_powermonitor_usage();
  2533. } else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
  2534. rc = ipmi_set_power_cap(intf,watt,val);
  2535. } else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
  2536. rc = ipmi_set_power_cap(intf, btuphr,val);
  2537. } else if (strncmp(argv[current_arg], "percent\0", 8) == 0) {
  2538. rc = ipmi_set_power_cap(intf,percent,val);
  2539. } else {
  2540. ipmi_powermonitor_usage();
  2541. return -1;
  2542. }
  2543. } else if (strncmp(argv[current_arg], "enablepowercap\0", 15) == 0) {
  2544. ipmi_set_power_capstatus_command(intf,1);
  2545. } else if (strncmp(argv[current_arg], "disablepowercap\0", 16) == 0) {
  2546. ipmi_set_power_capstatus_command(intf,0);
  2547. } else {
  2548. ipmi_powermonitor_usage();
  2549. return -1;
  2550. }
  2551. return rc;
  2552. }
  2553. /*
  2554. * Function Name: ipmi_time_to_str
  2555. *
  2556. * Description: This function converts ipmi time format into gmtime format
  2557. * Input: rawTime - ipmi time format
  2558. * Output: strTime - gmtime format
  2559. *
  2560. * Return:
  2561. */
  2562. static void
  2563. ipmi_time_to_str(time_t rawTime, char * strTime)
  2564. {
  2565. struct tm *tm;
  2566. char *temp;
  2567. tm = gmtime(&rawTime);
  2568. temp = asctime(tm);
  2569. strcpy(strTime,temp);
  2570. }
  2571. /*
  2572. * Function Name: ipmi_get_sensor_reading
  2573. *
  2574. * Description: This function retrieves a raw sensor reading
  2575. * Input: sensorOwner - sensor owner id
  2576. * sensorNumber - sensor id
  2577. * intf - ipmi interface
  2578. * Output: sensorReadingData - ipmi response structure
  2579. * Return: 1 on error
  2580. * 0 if successful
  2581. */
  2582. static int
  2583. ipmi_get_sensor_reading(struct ipmi_intf *intf, unsigned char sensorNumber,
  2584. SensorReadingType* pSensorReadingData)
  2585. {
  2586. struct ipmi_rq req;
  2587. struct ipmi_rs * rsp;
  2588. int rc = 0;
  2589. memset(&req, 0, sizeof(req));
  2590. req.msg.netfn = IPMI_NETFN_SE;
  2591. req.msg.lun = 0;
  2592. req.msg.cmd = GET_SENSOR_READING;
  2593. req.msg.data = &sensorNumber;
  2594. req.msg.data_len = 1;
  2595. if (pSensorReadingData == NULL) {
  2596. return -1;
  2597. }
  2598. memset(pSensorReadingData, 0, sizeof(SensorReadingType));
  2599. rsp = intf->sendrecv(intf, &req);
  2600. if (rsp == NULL) {
  2601. return 1;
  2602. } else if (rsp->ccode > 0) {
  2603. return 1;
  2604. }
  2605. memcpy(pSensorReadingData, rsp->data, sizeof(SensorReadingType));
  2606. /* if there is an error transmitting ipmi command, return error */
  2607. if (rsp->ccode != 0) {
  2608. rc = 1;
  2609. }
  2610. /* if sensor messages are disabled, return error*/
  2611. if ((!(rsp->data[1]& 0xC0)) || ((rsp->data[1] & 0x20))) {
  2612. rc =1;
  2613. }
  2614. return rc;
  2615. }
  2616. /*
  2617. * Function Name: ipmi_get_power_capstatus_command
  2618. *
  2619. * Description: This function gets the power cap status
  2620. * Input: intf - ipmi interface
  2621. * Global: PowercapSetable_flag - power cap status
  2622. * Output:
  2623. *
  2624. * Return:
  2625. */
  2626. static int
  2627. ipmi_get_power_capstatus_command(struct ipmi_intf * intf)
  2628. {
  2629. struct ipmi_rs * rsp = NULL;
  2630. struct ipmi_rq req = {0};
  2631. uint8_t data[2];
  2632. req.msg.netfn = DELL_OEM_NETFN;
  2633. req.msg.lun = 0;
  2634. req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS;
  2635. req.msg.data_len = 2;
  2636. req.msg.data = data;
  2637. data[0] = 01;
  2638. data[1] = 0xFF;
  2639. rsp = intf->sendrecv(intf, &req);
  2640. if (rsp == NULL) {
  2641. lprintf(LOG_ERR, "Error getting powercap status");
  2642. return -1;
  2643. } else if (( iDRAC_FLAG_12_13 ) && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
  2644. lprintf(LOG_ERR,
  2645. "FM001 : A required license is missing or expired");
  2646. return -1; /* Return Error as unlicensed */
  2647. } else if (rsp->ccode > 0) {
  2648. lprintf(LOG_ERR, "Error getting powercap statusr: %s",
  2649. val2str(rsp->ccode, completion_code_vals));
  2650. return -1;
  2651. }
  2652. if (rsp->data[0] & 0x02) {
  2653. PowercapSetable_flag=1;
  2654. }
  2655. if (rsp->data[0] & 0x01) {
  2656. PowercapstatusFlag=1;
  2657. }
  2658. return 0;
  2659. }
  2660. /*
  2661. * Function Name: ipmi_set_power_capstatus_command
  2662. *
  2663. * Description: This function sets the power cap status
  2664. * Input: intf - ipmi interface
  2665. * val - power cap status
  2666. * Output:
  2667. *
  2668. * Return:
  2669. */
  2670. static int
  2671. ipmi_set_power_capstatus_command(struct ipmi_intf * intf, uint8_t val)
  2672. {
  2673. struct ipmi_rs * rsp = NULL;
  2674. struct ipmi_rq req = {0};
  2675. uint8_t data[2];
  2676. if (ipmi_get_power_capstatus_command(intf) < 0) {
  2677. return -1;
  2678. }
  2679. if (PowercapSetable_flag != 1) {
  2680. lprintf(LOG_ERR, "Can not set powercap on this system");
  2681. return -1;
  2682. }
  2683. req.msg.netfn = DELL_OEM_NETFN;
  2684. req.msg.lun = 0;
  2685. req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS;
  2686. req.msg.data_len = 2;
  2687. req.msg.data = data;
  2688. data[0] = 00;
  2689. data[1] = val;
  2690. rsp = intf->sendrecv(intf, &req);
  2691. if (rsp == NULL) {
  2692. lprintf(LOG_ERR, "Error setting powercap status");
  2693. return -1;
  2694. } else if ((iDRAC_FLAG_12_13) && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
  2695. lprintf(LOG_ERR,
  2696. "FM001 : A required license is missing or expired");
  2697. return -1; /* return unlicensed Error code */
  2698. } else if (rsp->ccode > 0) {
  2699. lprintf(LOG_ERR, "Error setting powercap statusr: %s",
  2700. val2str(rsp->ccode, completion_code_vals));
  2701. return -1;
  2702. }
  2703. return 0;
  2704. }
  2705. /*
  2706. * Function Name: ipmi_powermgmt
  2707. *
  2708. * Description: This function print the powermonitor details
  2709. * Input: intf - ipmi interface
  2710. * Output:
  2711. *
  2712. * Return:
  2713. */
  2714. static int
  2715. ipmi_powermgmt(struct ipmi_intf * intf)
  2716. {
  2717. struct ipmi_rs * rsp;
  2718. struct ipmi_rq req;
  2719. uint8_t msg_data[2];
  2720. uint32_t cumStartTimeConv;
  2721. uint32_t cumReadingConv;
  2722. uint32_t maxPeakStartTimeConv;
  2723. uint32_t ampPeakTimeConv;
  2724. uint16_t ampReadingConv;
  2725. uint32_t wattPeakTimeConv;
  2726. uint32_t wattReadingConv;
  2727. uint32_t bmctimeconv;
  2728. uint32_t * bmctimeconvval;
  2729. IPMI_POWER_MONITOR * pwrMonitorInfo;
  2730. char cumStartTime[26];
  2731. char maxPeakStartTime[26];
  2732. char ampPeakTime[26];
  2733. char wattPeakTime[26];
  2734. char bmctime[26];
  2735. int ampReading;
  2736. int ampReadingRemainder;
  2737. int remainder;
  2738. int wattReading;
  2739. memset(&req, 0, sizeof(req));
  2740. req.msg.netfn = IPMI_NETFN_STORAGE;
  2741. req.msg.lun = 0;
  2742. req.msg.cmd = IPMI_CMD_GET_SEL_TIME;
  2743. rsp = intf->sendrecv(intf, &req);
  2744. if (rsp == NULL) {
  2745. lprintf(LOG_ERR, "Error getting BMC time info.");
  2746. return -1;
  2747. }
  2748. if (rsp->ccode != 0) {
  2749. lprintf(LOG_ERR,
  2750. "Error getting power management information, return code %x",
  2751. rsp->ccode);
  2752. return -1;
  2753. }
  2754. bmctimeconvval=(uint32_t*)rsp->data;
  2755. # if WORDS_BIGENDIAN
  2756. bmctimeconv=BSWAP_32(*bmctimeconvval);
  2757. # else
  2758. bmctimeconv=*bmctimeconvval;
  2759. # endif
  2760. /* get powermanagement info*/
  2761. req.msg.netfn = DELL_OEM_NETFN;
  2762. req.msg.lun = 0x0;
  2763. req.msg.cmd = GET_PWRMGMT_INFO_CMD;
  2764. req.msg.data = msg_data;
  2765. req.msg.data_len = 2;
  2766. memset(msg_data, 0, 2);
  2767. msg_data[0] = 0x07;
  2768. msg_data[1] = 0x01;
  2769. rsp = intf->sendrecv(intf, &req);
  2770. if (rsp == NULL) {
  2771. lprintf(LOG_ERR, "Error getting power management information.");
  2772. return -1;
  2773. }
  2774. if ((iDRAC_FLAG_12_13) && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
  2775. lprintf(LOG_ERR,
  2776. "FM001 : A required license is missing or expired");
  2777. return -1;
  2778. } else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) {
  2779. lprintf(LOG_ERR, "Error getting power management information: "
  2780. "Command not supported on this system.");
  2781. return -1;
  2782. }else if (rsp->ccode != 0) {
  2783. lprintf(LOG_ERR,
  2784. "Error getting power management information, return code %x",
  2785. rsp->ccode);
  2786. return -1;
  2787. }
  2788. pwrMonitorInfo = (IPMI_POWER_MONITOR*)rsp->data;
  2789. # if WORDS_BIGENDIAN
  2790. cumStartTimeConv = BSWAP_32(pwrMonitorInfo->cumStartTime);
  2791. cumReadingConv = BSWAP_32(pwrMonitorInfo->cumReading);
  2792. maxPeakStartTimeConv = BSWAP_32(pwrMonitorInfo->maxPeakStartTime);
  2793. ampPeakTimeConv = BSWAP_32(pwrMonitorInfo->ampPeakTime);
  2794. ampReadingConv = BSWAP_16(pwrMonitorInfo->ampReading);
  2795. wattPeakTimeConv = BSWAP_32(pwrMonitorInfo->wattPeakTime);
  2796. wattReadingConv = BSWAP_16(pwrMonitorInfo->wattReading);
  2797. # else
  2798. cumStartTimeConv = pwrMonitorInfo->cumStartTime;
  2799. cumReadingConv = pwrMonitorInfo->cumReading;
  2800. maxPeakStartTimeConv = pwrMonitorInfo->maxPeakStartTime;
  2801. ampPeakTimeConv = pwrMonitorInfo->ampPeakTime;
  2802. ampReadingConv = pwrMonitorInfo->ampReading;
  2803. wattPeakTimeConv = pwrMonitorInfo->wattPeakTime;
  2804. wattReadingConv = pwrMonitorInfo->wattReading;
  2805. # endif
  2806. ipmi_time_to_str(cumStartTimeConv, cumStartTime);
  2807. ipmi_time_to_str(maxPeakStartTimeConv, maxPeakStartTime);
  2808. ipmi_time_to_str(ampPeakTimeConv, ampPeakTime);
  2809. ipmi_time_to_str(wattPeakTimeConv, wattPeakTime);
  2810. ipmi_time_to_str(bmctimeconv, bmctime);
  2811. remainder = (cumReadingConv % 1000);
  2812. cumReadingConv = cumReadingConv / 1000;
  2813. remainder = (remainder + 50) / 100;
  2814. ampReading = ampReadingConv;
  2815. ampReadingRemainder = ampReading%10;
  2816. ampReading = ampReading/10;
  2817. wattReading = wattReadingConv;
  2818. printf("Power Tracking Statistics\n");
  2819. printf("Statistic : Cumulative Energy Consumption\n");
  2820. printf("Start Time : %s", cumStartTime);
  2821. printf("Finish Time : %s", bmctime);
  2822. printf("Reading : %d.%d kWh\n\n", cumReadingConv, remainder);
  2823. printf("Statistic : System Peak Power\n");
  2824. printf("Start Time : %s", maxPeakStartTime);
  2825. printf("Peak Time : %s", wattPeakTime);
  2826. printf("Peak Reading : %d W\n\n", wattReading);
  2827. printf("Statistic : System Peak Amperage\n");
  2828. printf("Start Time : %s", maxPeakStartTime);
  2829. printf("Peak Time : %s", ampPeakTime);
  2830. printf("Peak Reading : %d.%d A\n", ampReading, ampReadingRemainder);
  2831. return 0;
  2832. }
  2833. /*
  2834. * Function Name: ipmi_powermgmt_clear
  2835. *
  2836. * Description: This function clears peakpower / cumulativepower value
  2837. * Input: intf - ipmi interface
  2838. * clearValue - peakpower / cumulativepower
  2839. * Output:
  2840. *
  2841. * Return:
  2842. */
  2843. static int
  2844. ipmi_powermgmt_clear(struct ipmi_intf * intf, uint8_t clearValue)
  2845. {
  2846. struct ipmi_rs * rsp;
  2847. struct ipmi_rq req;
  2848. uint8_t clearType = 1;
  2849. uint8_t msg_data[3];
  2850. if (clearValue) {
  2851. clearType = 2;
  2852. }
  2853. /* clear powermanagement info*/
  2854. req.msg.netfn = DELL_OEM_NETFN;
  2855. req.msg.lun = 0;
  2856. req.msg.cmd = CLEAR_PWRMGMT_INFO_CMD;
  2857. req.msg.data = msg_data;
  2858. req.msg.data_len = 3;
  2859. memset(msg_data, 0, 3);
  2860. msg_data[0] = 0x07;
  2861. msg_data[1] = 0x01;
  2862. msg_data[2] = clearType;
  2863. rsp = intf->sendrecv(intf, &req);
  2864. if (rsp == NULL) {
  2865. lprintf(LOG_ERR, "Error clearing power values.");
  2866. return -1;
  2867. } else if ((iDRAC_FLAG_12_13)
  2868. && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
  2869. lprintf(LOG_ERR,
  2870. "FM001 : A required license is missing or expired");
  2871. return -1;
  2872. } else if (rsp->ccode == 0xc1) {
  2873. lprintf(LOG_ERR,
  2874. "Error clearing power values, command not supported on this system.");
  2875. return -1;
  2876. } else if (rsp->ccode != 0) {
  2877. lprintf(LOG_ERR, "Error clearing power values: %s",
  2878. val2str(rsp->ccode, completion_code_vals));
  2879. return -1;
  2880. }
  2881. return 0;
  2882. }
  2883. /*
  2884. * Function Name: watt_to_btuphr_conversion
  2885. *
  2886. * Description: This function converts the power value in watt to btuphr
  2887. * Input: powerinwatt - power in watt
  2888. *
  2889. * Output: power in btuphr
  2890. *
  2891. * Return:
  2892. */
  2893. static uint64_t
  2894. watt_to_btuphr_conversion(uint32_t powerinwatt)
  2895. {
  2896. uint64_t powerinbtuphr;
  2897. powerinbtuphr=(3.413 * powerinwatt);
  2898. return(powerinbtuphr);
  2899. }
  2900. /*
  2901. * Function Name: btuphr_to_watt_conversion
  2902. *
  2903. * Description: This function converts the power value in btuphr to watt
  2904. * Input: powerinbtuphr - power in btuphr
  2905. *
  2906. * Output: power in watt
  2907. *
  2908. * Return:
  2909. */
  2910. static uint32_t
  2911. btuphr_to_watt_conversion(uint64_t powerinbtuphr)
  2912. {
  2913. uint32_t powerinwatt;
  2914. /*returning the floor value*/
  2915. powerinwatt= (powerinbtuphr / 3.413);
  2916. return (powerinwatt);
  2917. }
  2918. /*
  2919. * Function Name: ipmi_get_power_headroom_command
  2920. *
  2921. * Description: This function prints the Power consumption information
  2922. * Input: intf - ipmi interface
  2923. * unit - watt / btuphr
  2924. * Output:
  2925. *
  2926. * Return:
  2927. */
  2928. static int
  2929. ipmi_get_power_headroom_command(struct ipmi_intf * intf,uint8_t unit)
  2930. {
  2931. struct ipmi_rs * rsp = NULL;
  2932. struct ipmi_rq req = {0};
  2933. uint64_t peakpowerheadroombtuphr;
  2934. uint64_t instantpowerhearoom;
  2935. req.msg.netfn = DELL_OEM_NETFN;
  2936. req.msg.lun = 0;
  2937. req.msg.cmd = GET_PWR_HEADROOM_CMD;
  2938. req.msg.data_len = 0;
  2939. rsp = intf->sendrecv(intf, &req);
  2940. if (rsp == NULL) {
  2941. lprintf(LOG_ERR, "Error getting power headroom status");
  2942. return -1;
  2943. } else if ((iDRAC_FLAG_12_13)
  2944. && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
  2945. lprintf(LOG_ERR,
  2946. "FM001 : A required license is missing or expired");
  2947. return -1;
  2948. } else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
  2949. lprintf(LOG_ERR, "Error getting power headroom status: "
  2950. "Command not supported on this system ");
  2951. return -1;
  2952. } else if (rsp->ccode > 0) {
  2953. lprintf(LOG_ERR, "Error getting power headroom status: %s",
  2954. val2str(rsp->ccode, completion_code_vals));
  2955. return -1;
  2956. }
  2957. if (verbose > 1) {
  2958. /* need to look into */
  2959. printf("power headroom Data : %x %x %x %x ", rsp->data[0],
  2960. rsp->data[1], rsp->data[2], rsp->data[3]);
  2961. }
  2962. powerheadroom= *(( POWER_HEADROOM *)rsp->data);
  2963. # if WORDS_BIGENDIAN
  2964. powerheadroom.instheadroom = BSWAP_16(powerheadroom.instheadroom);
  2965. powerheadroom.peakheadroom = BSWAP_16(powerheadroom.peakheadroom);
  2966. # endif
  2967. printf("Headroom\n");
  2968. printf("Statistic Reading\n");
  2969. if (unit == btuphr) {
  2970. peakpowerheadroombtuphr = watt_to_btuphr_conversion(powerheadroom.peakheadroom);
  2971. instantpowerhearoom = watt_to_btuphr_conversion(powerheadroom.instheadroom);
  2972. printf("System Instantaneous Headroom : %" PRId64 " BTU/hr\n",
  2973. instantpowerhearoom);
  2974. printf("System Peak Headroom : %" PRId64 " BTU/hr\n",
  2975. peakpowerheadroombtuphr);
  2976. } else {
  2977. printf("System Instantaneous Headroom : %d W\n",
  2978. powerheadroom.instheadroom);
  2979. printf("System Peak Headroom : %d W\n",
  2980. powerheadroom.peakheadroom);
  2981. }
  2982. return 0;
  2983. }
  2984. /*
  2985. * Function Name: ipmi_get_power_consumption_data
  2986. *
  2987. * Description: This function updates the instant Power consumption information
  2988. * Input: intf - ipmi interface
  2989. * Output: power consumption current reading
  2990. * Assumption value will be in Watt.
  2991. *
  2992. * Return:
  2993. */
  2994. static int
  2995. ipmi_get_power_consumption_data(struct ipmi_intf * intf,uint8_t unit)
  2996. {
  2997. SensorReadingType sensorReadingData;
  2998. struct ipmi_rs * rsp=NULL;
  2999. struct sdr_record_list *sdr;
  3000. int readingbtuphr = 0;
  3001. int warning_threshbtuphr = 0;
  3002. int failure_threshbtuphr = 0;
  3003. int status = 0;
  3004. int sensor_number = 0;
  3005. sdr = ipmi_sdr_find_sdr_byid(intf, "System Level");
  3006. if (sdr == NULL) {
  3007. lprintf(LOG_ERR,
  3008. "Error : Can not access the System Level sensor data");
  3009. return -1;
  3010. }
  3011. sensor_number = sdr->record.common->keys.sensor_num;
  3012. ipmi_get_sensor_reading(intf,sensor_number,&sensorReadingData);
  3013. rsp = ipmi_sdr_get_sensor_thresholds(intf,
  3014. sdr->record.common->keys.sensor_num,
  3015. sdr->record.common->keys.owner_id,
  3016. sdr->record.common->keys.lun,
  3017. sdr->record.common->keys.channel);
  3018. if (rsp == NULL || rsp->ccode != 0) {
  3019. lprintf(LOG_ERR,
  3020. "Error : Can not access the System Level sensor data");
  3021. return -1;
  3022. }
  3023. readingbtuphr = sdr_convert_sensor_reading(sdr->record.full,
  3024. sensorReadingData.sensorReading);
  3025. warning_threshbtuphr = sdr_convert_sensor_reading(sdr->record.full,
  3026. rsp->data[4]);
  3027. failure_threshbtuphr = sdr_convert_sensor_reading(sdr->record.full,
  3028. rsp->data[5]);
  3029. printf("System Board System Level\n");
  3030. if (unit == btuphr) {
  3031. readingbtuphr = watt_to_btuphr_conversion(readingbtuphr);
  3032. warning_threshbtuphr = watt_to_btuphr_conversion(warning_threshbtuphr);
  3033. failure_threshbtuphr = watt_to_btuphr_conversion( failure_threshbtuphr);
  3034. printf("Reading : %d BTU/hr\n", readingbtuphr);
  3035. printf("Warning threshold : %d BTU/hr\n", warning_threshbtuphr);
  3036. printf("Failure threshold : %d BTU/hr\n", failure_threshbtuphr);
  3037. } else {
  3038. printf("Reading : %d W \n",readingbtuphr);
  3039. printf("Warning threshold : %d W \n",(warning_threshbtuphr));
  3040. printf("Failure threshold : %d W \n",(failure_threshbtuphr));
  3041. }
  3042. return status;
  3043. }
  3044. /*
  3045. * Function Name: ipmi_get_instan_power_consmpt_data
  3046. *
  3047. * Description: This function updates the instant Power consumption information
  3048. * Input: intf - ipmi interface
  3049. * Output: instpowerconsumptiondata - instant Power consumption information
  3050. *
  3051. * Return:
  3052. */
  3053. static int
  3054. ipmi_get_instan_power_consmpt_data(struct ipmi_intf * intf,
  3055. IPMI_INST_POWER_CONSUMPTION_DATA * instpowerconsumptiondata)
  3056. {
  3057. struct ipmi_rs * rsp;
  3058. struct ipmi_rq req={0};
  3059. uint8_t msg_data[2];
  3060. /*get instantaneous power consumption command*/
  3061. req.msg.netfn = DELL_OEM_NETFN;
  3062. req.msg.lun = 0;
  3063. req.msg.cmd = GET_PWR_CONSUMPTION_CMD;
  3064. req.msg.data = msg_data;
  3065. req.msg.data_len = 2;
  3066. memset(msg_data, 0, 2);
  3067. msg_data[0] = 0x0A;
  3068. msg_data[1] = 0x00;
  3069. rsp = intf->sendrecv(intf, &req);
  3070. if (rsp == NULL) {
  3071. lprintf(LOG_ERR, "Error getting instantaneous power consumption data .");
  3072. return -1;
  3073. } else if ((iDRAC_FLAG_12_13)
  3074. && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
  3075. lprintf(LOG_ERR,
  3076. "FM001 : A required license is missing or expired");
  3077. return -1;
  3078. } else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
  3079. lprintf(LOG_ERR, "Error getting instantaneous power consumption data: "
  3080. "Command not supported on this system.");
  3081. return -1;
  3082. } else if (rsp->ccode != 0) {
  3083. lprintf(LOG_ERR, "Error getting instantaneous power consumption data: %s",
  3084. val2str(rsp->ccode, completion_code_vals));
  3085. return -1;
  3086. }
  3087. *instpowerconsumptiondata = *((IPMI_INST_POWER_CONSUMPTION_DATA *)(rsp->data));
  3088. #if WORDS_BIGENDIAN
  3089. instpowerconsumptiondata->instanpowerconsumption = BSWAP_16(instpowerconsumptiondata->instanpowerconsumption);
  3090. instpowerconsumptiondata->instanApms = BSWAP_16(instpowerconsumptiondata->instanApms);
  3091. instpowerconsumptiondata->resv1 = BSWAP_16(instpowerconsumptiondata->resv1);
  3092. #endif
  3093. return 0;
  3094. }
  3095. /*
  3096. * Function Name: ipmi_print_get_instan_power_Amps_data
  3097. *
  3098. * Description: This function prints the instant Power consumption information
  3099. * Input: instpowerconsumptiondata - instant Power consumption information
  3100. * Output:
  3101. *
  3102. * Return:
  3103. */
  3104. static void
  3105. ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata)
  3106. {
  3107. uint16_t intampsval=0;
  3108. uint16_t decimalampsval=0;
  3109. if (instpowerconsumptiondata.instanApms > 0) {
  3110. decimalampsval = (instpowerconsumptiondata.instanApms % 10);
  3111. intampsval = instpowerconsumptiondata.instanApms / 10;
  3112. }
  3113. printf("\nAmperage value: %d.%d A \n", intampsval, decimalampsval);
  3114. }
  3115. /*
  3116. * Function Name: ipmi_print_get_power_consmpt_data
  3117. *
  3118. * Description: This function prints the Power consumption information
  3119. * Input: intf - ipmi interface
  3120. * unit - watt / btuphr
  3121. * Output:
  3122. *
  3123. * Return:
  3124. */
  3125. static int
  3126. ipmi_print_get_power_consmpt_data(struct ipmi_intf * intf, uint8_t unit)
  3127. {
  3128. int rc = 0;
  3129. IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata = {0,0,0,0};
  3130. printf("\nPower consumption information\n");
  3131. rc = ipmi_get_power_consumption_data(intf, unit);
  3132. if (rc == (-1)) {
  3133. return rc;
  3134. }
  3135. rc = ipmi_get_instan_power_consmpt_data(intf, &instpowerconsumptiondata);
  3136. if (rc == (-1)) {
  3137. return rc;
  3138. }
  3139. ipmi_print_get_instan_power_Amps_data(instpowerconsumptiondata);
  3140. rc = ipmi_get_power_headroom_command(intf, unit);
  3141. if (rc == (-1)) {
  3142. return rc;
  3143. }
  3144. return rc;
  3145. }
  3146. /*
  3147. * Function Name: ipmi_get_avgpower_consmpt_history
  3148. *
  3149. * Description: This function updates the average power consumption information
  3150. * Input: intf - ipmi interface
  3151. * Output: pavgpower- average power consumption information
  3152. *
  3153. * Return:
  3154. */
  3155. static int
  3156. ipmi_get_avgpower_consmpt_history(struct ipmi_intf * intf,
  3157. IPMI_AVGPOWER_CONSUMP_HISTORY * pavgpower)
  3158. {
  3159. int rc;
  3160. uint8_t *rdata;
  3161. rc = ipmi_mc_getsysinfo(intf, 0xeb, 0, 0, sizeof(*pavgpower), pavgpower);
  3162. if (rc < 0) {
  3163. lprintf(LOG_ERR,
  3164. "Error getting average power consumption history data.");
  3165. return -1;
  3166. } else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
  3167. lprintf(LOG_ERR,
  3168. "FM001 : A required license is missing or expired");
  3169. return -1;
  3170. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  3171. lprintf(LOG_ERR, "Error getting average power consumption history data: "
  3172. "Command not supported on this system.");
  3173. return -1;
  3174. } else if (rc != 0) {
  3175. lprintf(LOG_ERR,
  3176. "Error getting average power consumption history data: %s",
  3177. val2str(rc, completion_code_vals));
  3178. return -1;
  3179. }
  3180. if (verbose > 1) {
  3181. rdata = (void *)pavgpower;
  3182. printf("Average power consumption history data"
  3183. " :%x %x %x %x %x %x %x %x\n\n",
  3184. rdata[0], rdata[1], rdata[2], rdata[3],
  3185. rdata[4], rdata[5], rdata[6], rdata[7]);
  3186. }
  3187. # if WORDS_BIGENDIAN
  3188. pavgpower->lastminutepower = BSWAP_16(pavgpower->lastminutepower);
  3189. pavgpower->lasthourpower = BSWAP_16(pavgpower->lasthourpower);
  3190. pavgpower->lastdaypower = BSWAP_16(pavgpower->lastdaypower);
  3191. pavgpower->lastweakpower = BSWAP_16(pavgpower->lastweakpower);
  3192. # endif
  3193. return 0;
  3194. }
  3195. /*
  3196. * Function Name: ipmi_get_peakpower_consmpt_history
  3197. *
  3198. * Description: This function updates the peak power consumption information
  3199. * Input: intf - ipmi interface
  3200. * Output: pavgpower- peak power consumption information
  3201. *
  3202. * Return:
  3203. */
  3204. static int
  3205. ipmi_get_peakpower_consmpt_history(struct ipmi_intf * intf,
  3206. IPMI_POWER_CONSUMP_HISTORY * pstPeakpower)
  3207. {
  3208. uint8_t *rdata;
  3209. int rc;
  3210. rc = ipmi_mc_getsysinfo(intf, 0xec, 0, 0, sizeof(*pstPeakpower),
  3211. pstPeakpower);
  3212. if (rc < 0) {
  3213. lprintf(LOG_ERR, "Error getting peak power consumption history data.");
  3214. return -1;
  3215. } else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
  3216. lprintf(LOG_ERR,
  3217. "FM001 : A required license is missing or expired");
  3218. return -1;
  3219. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  3220. lprintf(LOG_ERR, "Error getting peak power consumption history data: "
  3221. "Command not supported on this system.");
  3222. return -1;
  3223. } else if (rc != 0) {
  3224. lprintf(LOG_ERR, "Error getting peak power consumption history data: %s",
  3225. val2str(rc, completion_code_vals));
  3226. return -1;
  3227. }
  3228. if (verbose > 1) {
  3229. rdata = (void *)pstPeakpower;
  3230. printf("Peak power consmhistory Data : "
  3231. "%x %x %x %x %x %x %x %x %x %x\n "
  3232. "%x %x %x %x %x %x %x %x %x %x %x %x %x %x\n\n",
  3233. rdata[0], rdata[1], rdata[2], rdata[3],
  3234. rdata[4], rdata[5], rdata[6], rdata[7],
  3235. rdata[8], rdata[9], rdata[10], rdata[11],
  3236. rdata[12], rdata[13], rdata[14], rdata[15],
  3237. rdata[16], rdata[17], rdata[18], rdata[19],
  3238. rdata[20], rdata[21], rdata[22], rdata[23]);
  3239. }
  3240. # if WORDS_BIGENDIAN
  3241. pstPeakpower->lastminutepower = BSWAP_16(pstPeakpower->lastminutepower);
  3242. pstPeakpower->lasthourpower = BSWAP_16(pstPeakpower->lasthourpower);
  3243. pstPeakpower->lastdaypower = BSWAP_16(pstPeakpower->lastdaypower);
  3244. pstPeakpower->lastweakpower = BSWAP_16(pstPeakpower->lastweakpower);
  3245. pstPeakpower->lastminutepowertime = BSWAP_32(pstPeakpower->lastminutepowertime);
  3246. pstPeakpower->lasthourpowertime = BSWAP_32(pstPeakpower->lasthourpowertime);
  3247. pstPeakpower->lastdaypowertime = BSWAP_32(pstPeakpower->lastdaypowertime);
  3248. pstPeakpower->lastweekpowertime = BSWAP_32(pstPeakpower->lastweekpowertime);
  3249. #endif
  3250. return 0;
  3251. }
  3252. /*
  3253. * Function Name: ipmi_get_minpower_consmpt_history
  3254. *
  3255. * Description: This function updates the peak power consumption information
  3256. * Input: intf - ipmi interface
  3257. * Output: pavgpower- peak power consumption information
  3258. *
  3259. * Return:
  3260. */
  3261. static int
  3262. ipmi_get_minpower_consmpt_history(struct ipmi_intf * intf,
  3263. IPMI_POWER_CONSUMP_HISTORY * pstMinpower)
  3264. {
  3265. uint8_t *rdata;
  3266. int rc;
  3267. rc = ipmi_mc_getsysinfo(intf, 0xed, 0, 0, sizeof(*pstMinpower),
  3268. pstMinpower);
  3269. if (rc < 0) {
  3270. lprintf(LOG_ERR, "Error getting peak power consumption history data .");
  3271. return -1;
  3272. } else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
  3273. lprintf(LOG_ERR,
  3274. "FM001 : A required license is missing or expired");
  3275. return -1;
  3276. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  3277. lprintf(LOG_ERR, "Error getting peak power consumption history data: "
  3278. "Command not supported on this system.");
  3279. return -1;
  3280. } else if (rc != 0) {
  3281. lprintf(LOG_ERR, "Error getting peak power consumption history data: %s",
  3282. val2str(rc, completion_code_vals));
  3283. return -1;
  3284. }
  3285. if (verbose > 1) {
  3286. rdata = (void *)pstMinpower;
  3287. printf("Peak power consmhistory Data : "
  3288. "%x %x %x %x %x %x %x %x %x %x\n "
  3289. "%x %x %x %x %x %x %x %x %x %x %x %x %x\n\n",
  3290. rdata[0], rdata[1], rdata[2], rdata[3],
  3291. rdata[4], rdata[5], rdata[6], rdata[7],
  3292. rdata[8], rdata[9], rdata[10], rdata[11],
  3293. rdata[12], rdata[13], rdata[14], rdata[15],
  3294. rdata[16], rdata[17], rdata[18], rdata[19],
  3295. rdata[20], rdata[21], rdata[22], rdata[23]);
  3296. }
  3297. # if WORDS_BIGENDIAN
  3298. pstMinpower->lastminutepower = BSWAP_16(pstMinpower->lastminutepower);
  3299. pstMinpower->lasthourpower = BSWAP_16(pstMinpower->lasthourpower);
  3300. pstMinpower->lastdaypower = BSWAP_16(pstMinpower->lastdaypower);
  3301. pstMinpower->lastweakpower = BSWAP_16(pstMinpower->lastweakpower);
  3302. pstMinpower->lastminutepowertime = BSWAP_32(pstMinpower->lastminutepowertime);
  3303. pstMinpower->lasthourpowertime = BSWAP_32(pstMinpower->lasthourpowertime);
  3304. pstMinpower->lastdaypowertime = BSWAP_32(pstMinpower->lastdaypowertime);
  3305. pstMinpower->lastweekpowertime = BSWAP_32(pstMinpower->lastweekpowertime);
  3306. # endif
  3307. return 0;
  3308. }
  3309. /*
  3310. * Function Name: ipmi_print_power_consmpt_history
  3311. *
  3312. * Description: This function print the average and peak power consumption information
  3313. * Input: intf - ipmi interface
  3314. * unit - watt / btuphr
  3315. * Output:
  3316. *
  3317. * Return:
  3318. */
  3319. static int
  3320. ipmi_print_power_consmpt_history(struct ipmi_intf * intf, int unit)
  3321. {
  3322. char timestr[30];
  3323. uint32_t lastminutepeakpower;
  3324. uint32_t lasthourpeakpower;
  3325. uint32_t lastdaypeakpower;
  3326. uint32_t lastweekpeakpower;
  3327. uint64_t tempbtuphrconv;
  3328. int rc = 0;
  3329. IPMI_AVGPOWER_CONSUMP_HISTORY avgpower;
  3330. IPMI_POWER_CONSUMP_HISTORY stMinpower;
  3331. IPMI_POWER_CONSUMP_HISTORY stPeakpower;
  3332. rc = ipmi_get_avgpower_consmpt_history(intf, &avgpower);
  3333. if (rc == (-1)) {
  3334. return rc;
  3335. }
  3336. rc = ipmi_get_peakpower_consmpt_history(intf, &stPeakpower);
  3337. if (rc == (-1)) {
  3338. return rc;
  3339. }
  3340. rc = ipmi_get_minpower_consmpt_history(intf, &stMinpower);
  3341. if (rc == (-1)) {
  3342. return rc;
  3343. }
  3344. if (rc != 0) {
  3345. return rc;
  3346. }
  3347. printf("Power Consumption History\n\n");
  3348. /* The fields are alligned manually changing the spaces will alter
  3349. * the alignment*/
  3350. printf("Statistic Last Minute Last Hour "
  3351. "Last Day Last Week\n\n");
  3352. if (unit == btuphr) {
  3353. printf("Average Power Consumption ");
  3354. tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastminutepower);
  3355. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3356. tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lasthourpower);
  3357. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3358. tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastdaypower);
  3359. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3360. tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastweakpower);
  3361. printf("%4" PRId64 " BTU/hr\n", tempbtuphrconv);
  3362. printf("Max Power Consumption ");
  3363. tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastminutepower);
  3364. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3365. tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lasthourpower);
  3366. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3367. tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastdaypower);
  3368. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3369. tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastweakpower);
  3370. printf("%4" PRId64 " BTU/hr\n", tempbtuphrconv);
  3371. printf("Min Power Consumption ");
  3372. tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastminutepower);
  3373. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3374. tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lasthourpower);
  3375. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3376. tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastdaypower);
  3377. printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
  3378. tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastweakpower);
  3379. printf("%4" PRId64 " BTU/hr\n\n", tempbtuphrconv);
  3380. } else {
  3381. printf("Average Power Consumption ");
  3382. tempbtuphrconv = (avgpower.lastminutepower);
  3383. printf("%4" PRId64 " W ", tempbtuphrconv);
  3384. tempbtuphrconv = (avgpower.lasthourpower);
  3385. printf("%4" PRId64 " W ", tempbtuphrconv);
  3386. tempbtuphrconv = (avgpower.lastdaypower);
  3387. printf("%4" PRId64 " W ", tempbtuphrconv);
  3388. tempbtuphrconv=(avgpower.lastweakpower);
  3389. printf("%4" PRId64 " W \n", tempbtuphrconv);
  3390. printf("Max Power Consumption ");
  3391. tempbtuphrconv = (stPeakpower.lastminutepower);
  3392. printf("%4" PRId64 " W ", tempbtuphrconv);
  3393. tempbtuphrconv = (stPeakpower.lasthourpower);
  3394. printf("%4" PRId64 " W ", tempbtuphrconv);
  3395. tempbtuphrconv = (stPeakpower.lastdaypower);
  3396. printf("%4" PRId64 " W ", tempbtuphrconv);
  3397. tempbtuphrconv = (stPeakpower.lastweakpower);
  3398. printf("%4" PRId64 " W \n", tempbtuphrconv);
  3399. printf("Min Power Consumption ");
  3400. tempbtuphrconv = (stMinpower.lastminutepower);
  3401. printf("%4" PRId64 " W ", tempbtuphrconv);
  3402. tempbtuphrconv = (stMinpower.lasthourpower);
  3403. printf("%4" PRId64 " W ", tempbtuphrconv);
  3404. tempbtuphrconv = (stMinpower.lastdaypower);
  3405. printf("%4" PRId64 " W ", tempbtuphrconv);
  3406. tempbtuphrconv = (stMinpower.lastweakpower);
  3407. printf("%4" PRId64 " W \n\n", tempbtuphrconv);
  3408. }
  3409. lastminutepeakpower = stPeakpower.lastminutepowertime;
  3410. lasthourpeakpower = stPeakpower.lasthourpowertime;
  3411. lastdaypeakpower = stPeakpower.lastdaypowertime;
  3412. lastweekpeakpower = stPeakpower.lastweekpowertime;
  3413. printf("Max Power Time\n");
  3414. ipmi_time_to_str(lastminutepeakpower, timestr);
  3415. printf("Last Minute : %s",timestr);
  3416. ipmi_time_to_str(lasthourpeakpower, timestr);
  3417. printf("Last Hour : %s",timestr);
  3418. ipmi_time_to_str(lastdaypeakpower, timestr);
  3419. printf("Last Day : %s",timestr);
  3420. ipmi_time_to_str(lastweekpeakpower, timestr);
  3421. printf("Last Week : %s",timestr);
  3422. lastminutepeakpower=stMinpower.lastminutepowertime;
  3423. lasthourpeakpower=stMinpower.lasthourpowertime;
  3424. lastdaypeakpower=stMinpower.lastdaypowertime;
  3425. lastweekpeakpower=stMinpower.lastweekpowertime;
  3426. printf("Min Power Time\n");
  3427. ipmi_time_to_str(lastminutepeakpower, timestr);
  3428. printf("Last Minute : %s", timestr);
  3429. ipmi_time_to_str(lasthourpeakpower, timestr);
  3430. printf("Last Hour : %s", timestr);
  3431. ipmi_time_to_str(lastdaypeakpower, timestr);
  3432. printf("Last Day : %s", timestr);
  3433. ipmi_time_to_str(lastweekpeakpower, timestr);
  3434. printf("Last Week : %s", timestr);
  3435. return rc;
  3436. }
  3437. /*
  3438. * Function Name: ipmi_get_power_cap
  3439. *
  3440. * Description: This function updates the power cap information
  3441. * Input: intf - ipmi interface
  3442. * Output: ipmipowercap - power cap information
  3443. *
  3444. * Return:
  3445. */
  3446. static int
  3447. ipmi_get_power_cap(struct ipmi_intf * intf, IPMI_POWER_CAP * ipmipowercap)
  3448. {
  3449. uint8_t *rdata;
  3450. int rc;
  3451. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_POWER_CAP, 0, 0,
  3452. sizeof(*ipmipowercap), ipmipowercap);
  3453. if (rc < 0) {
  3454. lprintf(LOG_ERR, "Error getting power cap.");
  3455. return -1;
  3456. } else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
  3457. lprintf(LOG_ERR,
  3458. "FM001 : A required license is missing or expired");
  3459. return -1;
  3460. } else if ((rc == 0xc1) || (rc == 0xcb)) {
  3461. lprintf(LOG_ERR, "Error getting power cap: "
  3462. "Command not supported on this system.");
  3463. return -1;
  3464. } else if (rc != 0) {
  3465. lprintf(LOG_ERR, "Error getting power cap: %s",
  3466. val2str(rc, completion_code_vals));
  3467. return -1;
  3468. }
  3469. if (verbose > 1) {
  3470. rdata = (void*)ipmipowercap;
  3471. printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ",
  3472. rdata[1], rdata[2], rdata[3],
  3473. rdata[4], rdata[5], rdata[6], rdata[7],
  3474. rdata[8], rdata[9], rdata[10],rdata[11]);
  3475. }
  3476. # if WORDS_BIGENDIAN
  3477. ipmipowercap->PowerCap = BSWAP_16(ipmipowercap->PowerCap);
  3478. ipmipowercap->MaximumPowerConsmp = BSWAP_16(ipmipowercap->MaximumPowerConsmp);
  3479. ipmipowercap->MinimumPowerConsmp = BSWAP_16(ipmipowercap->MinimumPowerConsmp);
  3480. ipmipowercap->totalnumpowersupp = BSWAP_16(ipmipowercap->totalnumpowersupp);
  3481. ipmipowercap->AvailablePower = BSWAP_16(ipmipowercap->AvailablePower);
  3482. ipmipowercap->SystemThrottling = BSWAP_16(ipmipowercap->SystemThrottling);
  3483. ipmipowercap->Resv = BSWAP_16(ipmipowercap->Resv);
  3484. # endif
  3485. return 0;
  3486. }
  3487. /*
  3488. * Function Name: ipmi_print_power_cap
  3489. *
  3490. * Description: This function print the power cap information
  3491. * Input: intf - ipmi interface
  3492. * unit - watt / btuphr
  3493. * Output:
  3494. * Return:
  3495. */
  3496. static int
  3497. ipmi_print_power_cap(struct ipmi_intf * intf,uint8_t unit)
  3498. {
  3499. uint64_t tempbtuphrconv;
  3500. int rc;
  3501. IPMI_POWER_CAP ipmipowercap;
  3502. memset(&ipmipowercap, 0, sizeof(ipmipowercap));
  3503. rc = ipmi_get_power_cap(intf, &ipmipowercap);
  3504. if (rc == 0) {
  3505. if (unit == btuphr) {
  3506. tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp);
  3507. printf("Maximum power: %" PRId64 " BTU/hr\n", tempbtuphrconv);
  3508. tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp);
  3509. printf("Minimum power: %" PRId64 " BTU/hr\n", tempbtuphrconv);
  3510. tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.PowerCap);
  3511. printf("Power cap : %" PRId64 " BTU/hr\n", tempbtuphrconv);
  3512. } else {
  3513. printf("Maximum power: %d Watt\n", ipmipowercap.MaximumPowerConsmp);
  3514. printf("Minimum power: %d Watt\n", ipmipowercap.MinimumPowerConsmp);
  3515. printf("Power cap : %d Watt\n", ipmipowercap.PowerCap);
  3516. }
  3517. }
  3518. return rc;
  3519. }
  3520. /*
  3521. * Function Name: ipmi_set_power_cap
  3522. *
  3523. * Description: This function updates the power cap information
  3524. * Input: intf - ipmi interface
  3525. * unit - watt / btuphr
  3526. * val - new power cap value
  3527. * Output:
  3528. * Return:
  3529. */
  3530. static int
  3531. ipmi_set_power_cap(struct ipmi_intf * intf, int unit, int val)
  3532. {
  3533. int rc;
  3534. uint8_t data[13], *rdata;
  3535. uint16_t powercapval;
  3536. uint64_t maxpowerbtuphr;
  3537. uint64_t minpowerbtuphr;
  3538. IPMI_POWER_CAP ipmipowercap;
  3539. if (ipmi_get_power_capstatus_command(intf) < 0) {
  3540. return -1; /* Adding the failed condition check */
  3541. }
  3542. if (PowercapSetable_flag != 1) {
  3543. lprintf(LOG_ERR, "Can not set powercap on this system");
  3544. return -1;
  3545. } else if (PowercapstatusFlag != 1) {
  3546. lprintf(LOG_ERR, "Power cap set feature is not enabled");
  3547. return -1;
  3548. }
  3549. rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_POWER_CAP, 0, 0,
  3550. sizeof(ipmipowercap), &ipmipowercap);
  3551. if (rc < 0) {
  3552. lprintf(LOG_ERR, "Error getting power cap.");
  3553. return -1;
  3554. } else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
  3555. lprintf(LOG_ERR,
  3556. "FM001 : A required license is missing or expired");
  3557. return -1;
  3558. } else if (rc == 0xc1) {
  3559. lprintf(LOG_ERR, "Error getting power cap, command not supported on "
  3560. "this system.");
  3561. return -1;
  3562. } else if (rc != 0) {
  3563. lprintf(LOG_ERR, "Error getting power cap: %s",
  3564. val2str(rc, completion_code_vals));
  3565. return -1;
  3566. }
  3567. if (verbose > 1) {
  3568. rdata = (void *)&ipmipowercap;
  3569. printf("power cap Data :%x %x %x %x %x %x %x %x %x %x %x ",
  3570. rdata[1], rdata[2], rdata[3],
  3571. rdata[4], rdata[5], rdata[6], rdata[7],
  3572. rdata[8], rdata[9], rdata[10],rdata[11]);
  3573. }
  3574. # if WORDS_BIGENDIAN
  3575. ipmipowercap.PowerCap = BSWAP_16(ipmipowercap.PowerCap);
  3576. ipmipowercap.MaximumPowerConsmp = BSWAP_16(ipmipowercap.MaximumPowerConsmp);
  3577. ipmipowercap.MinimumPowerConsmp = BSWAP_16(ipmipowercap.MinimumPowerConsmp);
  3578. ipmipowercap.AvailablePower = BSWAP_16(ipmipowercap.AvailablePower);
  3579. ipmipowercap.totalnumpowersupp = BSWAP_16(ipmipowercap.totalnumpowersupp);
  3580. # endif
  3581. memset(data, 0, 13);
  3582. data[0] = IPMI_DELL_POWER_CAP;
  3583. powercapval = val;
  3584. data[1] = (powercapval & 0XFF);
  3585. data[2] = ((powercapval & 0XFF00) >> 8);
  3586. data[3] = unit;
  3587. data[4] = ((ipmipowercap.MaximumPowerConsmp & 0xFF));
  3588. data[5] = ((ipmipowercap.MaximumPowerConsmp & 0xFF00) >> 8);
  3589. data[6] = ((ipmipowercap.MinimumPowerConsmp & 0xFF));
  3590. data[7] = ((ipmipowercap.MinimumPowerConsmp & 0xFF00) >> 8);
  3591. data[8] = (ipmipowercap.totalnumpowersupp);
  3592. data[9] = ((ipmipowercap.AvailablePower & 0xFF));
  3593. data[10] = ((ipmipowercap.AvailablePower & 0xFF00) >> 8);
  3594. data[11] = (ipmipowercap.SystemThrottling);
  3595. data[12] = 0x00;
  3596. if (unit == btuphr) {
  3597. val = btuphr_to_watt_conversion(val);
  3598. } else if (unit == percent) {
  3599. if ((val < 0) || (val > 100)) {
  3600. lprintf(LOG_ERR, "Cap value is out of boundary conditon it "
  3601. "should be between 0 - 100");
  3602. return -1;
  3603. }
  3604. val = ((val*(ipmipowercap.MaximumPowerConsmp
  3605. - ipmipowercap.MinimumPowerConsmp)) / 100)
  3606. + ipmipowercap.MinimumPowerConsmp;
  3607. lprintf(LOG_ERR, "Cap value in percentage is %d ", val);
  3608. data[1] = (val & 0XFF);
  3609. data[2] = ((val & 0XFF00) >> 8);
  3610. data[3] = watt;
  3611. }
  3612. if (((val < ipmipowercap.MinimumPowerConsmp)
  3613. || (val > ipmipowercap.MaximumPowerConsmp)) && (unit == watt)) {
  3614. lprintf(LOG_ERR,
  3615. "Cap value is out of boundary conditon it should be between %d - %d",
  3616. ipmipowercap.MinimumPowerConsmp, ipmipowercap.MaximumPowerConsmp);
  3617. return -1;
  3618. } else if (((val < ipmipowercap.MinimumPowerConsmp)
  3619. || (val > ipmipowercap.MaximumPowerConsmp)) && (unit == btuphr)) {
  3620. minpowerbtuphr = watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp);
  3621. maxpowerbtuphr = watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp);
  3622. lprintf(LOG_ERR,
  3623. "Cap value is out of boundary conditon it should be between %d",
  3624. minpowerbtuphr);
  3625. lprintf(LOG_ERR, " -%d", maxpowerbtuphr);
  3626. return -1;
  3627. }
  3628. rc = ipmi_mc_setsysinfo(intf, 13, data);
  3629. if (rc < 0) {
  3630. lprintf(LOG_ERR, "Error setting power cap");
  3631. return -1;
  3632. } else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
  3633. lprintf(LOG_ERR,
  3634. "FM001 : A required license is missing or expired");
  3635. return -1;
  3636. } else if (rc > 0) {
  3637. lprintf(LOG_ERR, "Error setting power cap: %s",
  3638. val2str(rc, completion_code_vals));
  3639. return -1;
  3640. }
  3641. if (verbose > 1) {
  3642. printf("CC for setpowercap :%d ", rc);
  3643. }
  3644. return 0;
  3645. }
  3646. /*
  3647. * Function Name: ipmi_powermonitor_usage
  3648. *
  3649. * Description: This function prints help message for powermonitor command
  3650. * Input:
  3651. * Output:
  3652. *
  3653. * Return:
  3654. */
  3655. static void
  3656. ipmi_powermonitor_usage(void)
  3657. {
  3658. lprintf(LOG_NOTICE,
  3659. "");
  3660. lprintf(LOG_NOTICE,
  3661. " powermonitor");
  3662. lprintf(LOG_NOTICE,
  3663. " Shows power tracking statistics ");
  3664. lprintf(LOG_NOTICE,
  3665. "");
  3666. lprintf(LOG_NOTICE,
  3667. " powermonitor clear cumulativepower");
  3668. lprintf(LOG_NOTICE,
  3669. " Reset cumulative power reading");
  3670. lprintf(LOG_NOTICE,
  3671. "");
  3672. lprintf(LOG_NOTICE,
  3673. " powermonitor clear peakpower");
  3674. lprintf(LOG_NOTICE,
  3675. " Reset peak power reading");
  3676. lprintf(LOG_NOTICE,
  3677. "");
  3678. lprintf(LOG_NOTICE,
  3679. " powermonitor powerconsumption");
  3680. lprintf(LOG_NOTICE,
  3681. " Displays power consumption in <watt|btuphr>");
  3682. lprintf(LOG_NOTICE,
  3683. "");
  3684. lprintf(LOG_NOTICE,
  3685. " powermonitor powerconsumptionhistory <watt|btuphr>");
  3686. lprintf(LOG_NOTICE,
  3687. " Displays power consumption history ");
  3688. lprintf(LOG_NOTICE,
  3689. "");
  3690. lprintf(LOG_NOTICE,
  3691. " powermonitor getpowerbudget");
  3692. lprintf(LOG_NOTICE,
  3693. " Displays power cap in <watt|btuphr>");
  3694. lprintf(LOG_NOTICE,
  3695. "");
  3696. lprintf(LOG_NOTICE,
  3697. " powermonitor setpowerbudget <val><watt|btuphr|percent>");
  3698. lprintf(LOG_NOTICE,
  3699. " Allows user to set the power cap in <watt|BTU/hr|percentage>");
  3700. lprintf(LOG_NOTICE,
  3701. "");
  3702. lprintf(LOG_NOTICE,
  3703. " powermonitor enablepowercap ");
  3704. lprintf(LOG_NOTICE,
  3705. " To enable set power cap");
  3706. lprintf(LOG_NOTICE,
  3707. "");
  3708. lprintf(LOG_NOTICE,
  3709. " powermonitor disablepowercap ");
  3710. lprintf(LOG_NOTICE,
  3711. " To disable set power cap");
  3712. lprintf(LOG_NOTICE,
  3713. "");
  3714. }
  3715. /*
  3716. * Function Name: ipmi_delloem_vFlash_main
  3717. *
  3718. * Description: This function processes the delloem vFlash command
  3719. * Input: intf - ipmi interface
  3720. * argc - no of arguments
  3721. * argv - argument string array
  3722. * Output:
  3723. *
  3724. * Return: return code 0 - success
  3725. * -1 - failure
  3726. */
  3727. static int
  3728. ipmi_delloem_vFlash_main(struct ipmi_intf * intf, int argc, char ** argv)
  3729. {
  3730. int rc = 0;
  3731. current_arg++;
  3732. rc = ipmi_delloem_vFlash_process(intf, current_arg, argv);
  3733. return rc;
  3734. }
  3735. /*
  3736. * Function Name: get_vFlash_compcode_str
  3737. *
  3738. * Description: This function maps the vFlash completion code
  3739. * to a string
  3740. * Input : vFlash completion code and static array of codes vs strings
  3741. * Output: -
  3742. * Return: returns the mapped string
  3743. */
  3744. const char *
  3745. get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs)
  3746. {
  3747. static char un_str[32];
  3748. int i;
  3749. for (i = 0; vs[i].str != NULL; i++) {
  3750. if (vs[i].val == vflashcompcode)
  3751. return vs[i].str;
  3752. }
  3753. memset(un_str, 0, 32);
  3754. snprintf(un_str, 32, "Unknown (0x%02X)", vflashcompcode);
  3755. return un_str;
  3756. }
  3757. /*
  3758. * Function Name: ipmi_get_sd_card_info
  3759. *
  3760. * Description: This function prints the vFlash Extended SD card info
  3761. * Input : ipmi interface
  3762. * Output: prints the sd card extended info
  3763. * Return: 0 - success -1 - failure
  3764. */
  3765. static int
  3766. ipmi_get_sd_card_info(struct ipmi_intf * intf) {
  3767. struct ipmi_rs * rsp;
  3768. struct ipmi_rq req;
  3769. uint8_t msg_data[2];
  3770. uint8_t input_length=0;
  3771. uint8_t cardstatus=0x00;
  3772. IPMI_DELL_SDCARD_INFO * sdcardinfoblock;
  3773. input_length = 2;
  3774. msg_data[0] = msg_data[1] = 0x00;
  3775. req.msg.netfn = DELL_OEM_NETFN;
  3776. req.msg.lun = 0;
  3777. req.msg.cmd = IPMI_GET_EXT_SD_CARD_INFO;
  3778. req.msg.data = msg_data;
  3779. req.msg.data_len = input_length;
  3780. rsp = intf->sendrecv(intf, &req);
  3781. if (rsp == NULL) {
  3782. lprintf(LOG_ERR, "Error in getting SD Card Extended Information");
  3783. return -1;
  3784. } else if (rsp->ccode > 0) {
  3785. lprintf(LOG_ERR, "Error in getting SD Card Extended Information (%s)",
  3786. val2str(rsp->ccode, completion_code_vals));
  3787. return -1;
  3788. }
  3789. sdcardinfoblock = (IPMI_DELL_SDCARD_INFO *) (void *) rsp->data;
  3790. if ((iDRAC_FLAG_12_13)
  3791. && (sdcardinfoblock->vflashcompcode == VFL_NOT_LICENSED)) {
  3792. lprintf(LOG_ERR,
  3793. "FM001 : A required license is missing or expired");
  3794. return -1;
  3795. } else if (sdcardinfoblock->vflashcompcode != 0x00) {
  3796. lprintf(LOG_ERR, "Error in getting SD Card Extended Information (%s)",
  3797. get_vFlash_compcode_str(sdcardinfoblock->vflashcompcode,
  3798. vFlash_completion_code_vals));
  3799. return -1;
  3800. }
  3801. if (!(sdcardinfoblock->sdcardstatus & 0x04)) {
  3802. lprintf(LOG_ERR,
  3803. "vFlash SD card is unavailable, please insert the card of");
  3804. lprintf(LOG_ERR,
  3805. "size 256MB or greater");
  3806. return (-1);
  3807. }
  3808. printf("vFlash SD Card Properties\n");
  3809. printf("SD Card size : %8dMB\n", sdcardinfoblock->sdcardsize);
  3810. printf("Available size : %8dMB\n", sdcardinfoblock->sdcardavailsize);
  3811. printf("Initialized : %10s\n",
  3812. (sdcardinfoblock->sdcardstatus & 0x80) ? "Yes" : "No");
  3813. printf("Licensed : %10s\n",
  3814. (sdcardinfoblock->sdcardstatus & 0x40) ? "Yes" : "No");
  3815. printf("Attached : %10s\n",
  3816. (sdcardinfoblock->sdcardstatus & 0x20) ? "Yes" : "No");
  3817. printf("Enabled : %10s\n",
  3818. (sdcardinfoblock->sdcardstatus & 0x10) ? "Yes" : "No");
  3819. printf("Write Protected : %10s\n",
  3820. (sdcardinfoblock->sdcardstatus & 0x08) ? "Yes" : "No");
  3821. cardstatus = sdcardinfoblock->sdcardstatus & 0x03;
  3822. printf("Health : %10s\n",
  3823. ((0x00 == cardstatus) ? "OK" : (
  3824. (cardstatus == 0x03) ? "Undefined" : (
  3825. (cardstatus == 0x02) ? "Critical" : "Warning"))));
  3826. printf("Bootable partition : %10d\n", sdcardinfoblock->bootpartion);
  3827. return 0;
  3828. }
  3829. /*
  3830. * Function Name: ipmi_delloem_vFlash_process
  3831. *
  3832. * Description: This function processes the args for vFlash subcmd
  3833. * Input : intf - ipmi interface, arg index, argv array
  3834. * Output: prints help or error with help
  3835. * Return: 0 - Success -1 - failure
  3836. */
  3837. static int
  3838. ipmi_delloem_vFlash_process(struct ipmi_intf * intf, int current_arg, char ** argv)
  3839. {
  3840. int rc;
  3841. if (strncmp(intf->name,"wmi\0",4) && strncmp(intf->name, "open\0",5)) {
  3842. lprintf(LOG_ERR,
  3843. "vFlash support is enabled only for wmi and open interface.");
  3844. lprintf(LOG_ERR, "Its not enabled for lan and lanplus interface.");
  3845. return -1;
  3846. }
  3847. if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) {
  3848. ipmi_vFlash_usage();
  3849. return 0;
  3850. }
  3851. ipmi_idracvalidator_command(intf);
  3852. if (!strncmp(argv[current_arg], "info\0", 5)) {
  3853. current_arg++;
  3854. if (argv[current_arg] == NULL) {
  3855. ipmi_vFlash_usage();
  3856. return -1;
  3857. } else if (strncmp(argv[current_arg], "Card\0", 5) == 0) {
  3858. current_arg++;
  3859. if (argv[current_arg] != NULL) {
  3860. ipmi_vFlash_usage();
  3861. return -1;
  3862. }
  3863. rc = ipmi_get_sd_card_info(intf);
  3864. return rc;
  3865. } else {
  3866. /* TBD: many sub commands are present */
  3867. ipmi_vFlash_usage();
  3868. return -1;
  3869. }
  3870. } else {
  3871. /* TBD other vFlash subcommands */
  3872. ipmi_vFlash_usage();
  3873. return -1;
  3874. }
  3875. }
  3876. /*
  3877. * Function Name: ipmi_vFlash_usage
  3878. *
  3879. * Description: This function displays the usage for using vFlash
  3880. * Input : void
  3881. * Output: prints help
  3882. * Return: void
  3883. */
  3884. static void
  3885. ipmi_vFlash_usage(void)
  3886. {
  3887. lprintf(LOG_NOTICE,
  3888. "");
  3889. lprintf(LOG_NOTICE,
  3890. " vFlash info Card");
  3891. lprintf(LOG_NOTICE,
  3892. " Shows Extended SD Card information");
  3893. lprintf(LOG_NOTICE,
  3894. "");
  3895. }
  3896. /*
  3897. * Function Name: ipmi_setled_usage
  3898. *
  3899. * Description: This function prints help message for setled command
  3900. * Input:
  3901. * Output:
  3902. *
  3903. * Return:
  3904. */
  3905. static void
  3906. ipmi_setled_usage(void)
  3907. {
  3908. lprintf(LOG_NOTICE,
  3909. "");
  3910. lprintf(LOG_NOTICE,
  3911. " setled <b:d.f> <state..>");
  3912. lprintf(LOG_NOTICE,
  3913. " Set backplane LED state");
  3914. lprintf(LOG_NOTICE,
  3915. " b:d.f = PCI Bus:Device.Function of drive (lspci format)");
  3916. lprintf(LOG_NOTICE,
  3917. " state = present|online|hotspare|identify|rebuilding|");
  3918. lprintf(LOG_NOTICE,
  3919. " fault|predict|critical|failed");
  3920. lprintf(LOG_NOTICE,
  3921. "");
  3922. }
  3923. static int
  3924. IsSetLEDSupported(void)
  3925. {
  3926. return SetLEDSupported;
  3927. }
  3928. static void
  3929. CheckSetLEDSupport(struct ipmi_intf * intf)
  3930. {
  3931. struct ipmi_rs * rsp = NULL;
  3932. struct ipmi_rq req = {0};
  3933. uint8_t data[10];
  3934. SetLEDSupported = 0;
  3935. req.msg.netfn = DELL_OEM_NETFN;
  3936. req.msg.lun = 0;
  3937. req.msg.cmd = 0xD5; /* Storage */
  3938. req.msg.data_len = 10;
  3939. req.msg.data = data;
  3940. memset(data, 0, sizeof(data));
  3941. data[0] = 0x01; /* get */
  3942. data[1] = 0x00; /* subcmd:get firmware version */
  3943. data[2] = 0x08; /* length lsb */
  3944. data[3] = 0x00; /* length msb */
  3945. data[4] = 0x00; /* offset lsb */
  3946. data[5] = 0x00; /* offset msb */
  3947. data[6] = 0x00; /* bay id */
  3948. data[7] = 0x00;
  3949. data[8] = 0x00;
  3950. data[9] = 0x00;
  3951. rsp = intf->sendrecv(intf, &req);
  3952. if (rsp == NULL || rsp->ccode != 0) {
  3953. return;
  3954. }
  3955. SetLEDSupported = 1;
  3956. }
  3957. /*
  3958. * Function Name: ipmi_getdrivemap
  3959. *
  3960. * Description: This function returns mapping of BDF to Bay:Slot
  3961. * Input: intf - ipmi interface
  3962. * bdf - PCI Address of drive
  3963. * *bay - Returns bay ID
  3964. * *slot - Returns slot ID
  3965. * Output:
  3966. *
  3967. * Return:
  3968. */
  3969. static int
  3970. ipmi_getdrivemap(struct ipmi_intf * intf, int b, int d, int f, int *bay,
  3971. int *slot)
  3972. {
  3973. struct ipmi_rs * rsp = NULL;
  3974. struct ipmi_rq req = {0};
  3975. uint8_t data[8];
  3976. /* Get mapping of BDF to bay:slot */
  3977. req.msg.netfn = DELL_OEM_NETFN;
  3978. req.msg.lun = 0;
  3979. req.msg.cmd = 0xD5;
  3980. req.msg.data_len = 8;
  3981. req.msg.data = data;
  3982. memset(data, 0, sizeof(data));
  3983. data[0] = 0x01; /* get */
  3984. data[1] = 0x07; /* storage map */
  3985. data[2] = 0x06; /* length lsb */
  3986. data[3] = 0x00; /* length msb */
  3987. data[4] = 0x00; /* offset lsb */
  3988. data[5] = 0x00; /* offset msb */
  3989. data[6] = b; /* bus */
  3990. data[7] = (d << 3) + f; /* devfn */
  3991. rsp = intf->sendrecv(intf, &req);
  3992. if (rsp == NULL) {
  3993. lprintf(LOG_ERR, "Error issuing getdrivemap command.");
  3994. return -1;
  3995. } else if (rsp->ccode != 0) {
  3996. lprintf(LOG_ERR, "Error issuing getdrivemap command: %s",
  3997. val2str(rsp->ccode, completion_code_vals));
  3998. return -1;
  3999. }
  4000. *bay = rsp->data[7];
  4001. *slot = rsp->data[8];
  4002. if (*bay == 0xFF || *slot == 0xFF) {
  4003. lprintf(LOG_ERR, "Error could not get drive bay:slot mapping");
  4004. return -1;
  4005. }
  4006. return 0;
  4007. }
  4008. /*
  4009. * Function Name: ipmi_setled_state
  4010. *
  4011. * Description: This function updates the LED on the backplane
  4012. * Input: intf - ipmi interface
  4013. * bdf - PCI Address of drive
  4014. * state - SES Flags state of drive
  4015. * Output:
  4016. *
  4017. * Return:
  4018. */
  4019. static int
  4020. ipmi_setled_state(struct ipmi_intf * intf, int bayId, int slotId, int state)
  4021. {
  4022. struct ipmi_rs * rsp = NULL;
  4023. struct ipmi_rq req = {0};
  4024. uint8_t data[20];
  4025. /* Issue Drive Status Update to bay:slot */
  4026. req.msg.netfn = DELL_OEM_NETFN;
  4027. req.msg.lun = 0;
  4028. req.msg.cmd = 0xD5;
  4029. req.msg.data_len = 20;
  4030. req.msg.data = data;
  4031. memset(data, 0, sizeof(data));
  4032. data[0] = 0x00; /* set */
  4033. data[1] = 0x04; /* set drive status */
  4034. data[2] = 0x0e; /* length lsb */
  4035. data[3] = 0x00; /* length msb */
  4036. data[4] = 0x00; /* offset lsb */
  4037. data[5] = 0x00; /* offset msb */
  4038. data[6] = 0x0e; /* length lsb */
  4039. data[7] = 0x00; /* length msb */
  4040. data[8] = bayId; /* bayid */
  4041. data[9] = slotId; /* slotid */
  4042. data[10] = state & 0xff; /* state LSB */
  4043. data[11] = state >> 8; /* state MSB; */
  4044. rsp = intf->sendrecv(intf, &req);
  4045. if (rsp == NULL) {
  4046. lprintf(LOG_ERR, "Error issuing setled command.");
  4047. return -1;
  4048. } else if (rsp->ccode != 0) {
  4049. lprintf(LOG_ERR, "Error issuing setled command: %s",
  4050. val2str(rsp->ccode, completion_code_vals));
  4051. return -1;
  4052. }
  4053. return 0;
  4054. }
  4055. /*
  4056. * Function Name: ipmi_getsesmask
  4057. *
  4058. * Description: This function calculates bits in SES drive update
  4059. * Return: Mask set with bits for SES backplane update
  4060. */
  4061. static int
  4062. ipmi_getsesmask(int argc, char **argv)
  4063. {
  4064. int mask = 0;
  4065. while (current_arg < argc) {
  4066. if (!strcmp(argv[current_arg], "present"))
  4067. mask |= (1L << 0);
  4068. if (!strcmp(argv[current_arg], "online"))
  4069. mask |= (1L << 1);
  4070. if (!strcmp(argv[current_arg], "hotspare"))
  4071. mask |= (1L << 2);
  4072. if (!strcmp(argv[current_arg], "identify"))
  4073. mask |= (1L << 3);
  4074. if (!strcmp(argv[current_arg], "rebuilding"))
  4075. mask |= (1L << 4);
  4076. if (!strcmp(argv[current_arg], "fault"))
  4077. mask |= (1L << 5);
  4078. if (!strcmp(argv[current_arg], "predict"))
  4079. mask |= (1L << 6);
  4080. if (!strcmp(argv[current_arg], "critical"))
  4081. mask |= (1L << 9);
  4082. if (!strcmp(argv[current_arg], "failed"))
  4083. mask |= (1L << 10);
  4084. current_arg++;
  4085. }
  4086. return mask;
  4087. }
  4088. /*
  4089. * Function Name: ipmi_delloem_setled_main
  4090. *
  4091. * Description: This function processes the delloem setled command
  4092. * Input: intf - ipmi interface
  4093. * argc - no of arguments
  4094. * argv - argument string array
  4095. * Output:
  4096. *
  4097. * Return: return code 0 - success
  4098. * -1 - failure
  4099. */
  4100. static int
  4101. ipmi_delloem_setled_main(struct ipmi_intf * intf, int argc, char ** argv)
  4102. {
  4103. int b,d,f, mask;
  4104. int bayId, slotId;
  4105. bayId = 0xFF;
  4106. slotId = 0xFF;
  4107. current_arg++;
  4108. if (argc < current_arg) {
  4109. usage();
  4110. return -1;
  4111. }
  4112. /* ipmitool delloem setled info*/
  4113. if (argc == 1 || strcmp(argv[current_arg], "help") == 0) {
  4114. ipmi_setled_usage();
  4115. return 0;
  4116. }
  4117. CheckSetLEDSupport(intf);
  4118. if (!IsSetLEDSupported()) {
  4119. lprintf(LOG_ERR, "'setled' is not supported on this system.");
  4120. return -1;
  4121. } else if (sscanf(argv[current_arg], "%*x:%x:%x.%x", &b,&d,&f) == 3) {
  4122. /* We have bus/dev/function of drive */
  4123. current_arg++;
  4124. ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId);
  4125. } else if (sscanf(argv[current_arg], "%x:%x.%x", &b,&d,&f) == 3) {
  4126. /* We have bus/dev/function of drive */
  4127. current_arg++;
  4128. } else {
  4129. ipmi_setled_usage();
  4130. return -1;
  4131. }
  4132. /* Get mask of SES flags */
  4133. mask = ipmi_getsesmask(argc, argv);
  4134. /* Get drive mapping */
  4135. if (ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId)) {
  4136. return -1;
  4137. }
  4138. /* Set drive LEDs */
  4139. return ipmi_setled_state (intf, bayId, slotId, mask);
  4140. }