ipmi_picmg.c 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382
  1. /*
  2. Copyright (c) Kontron. All right reserved
  3. * Redistribution and use in source and binary forms, with or without
  4. * modification, are permitted provided that the following conditions
  5. * are met:
  6. *
  7. * Redistribution of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. *
  10. * Redistribution in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * Neither the name of Kontron, or the names of
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * This software is provided "AS IS," without a warranty of any kind.
  19. * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
  20. * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
  21. * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
  22. * DELL COMPUTERS ("DELL") AND ITS LICENSORS SHALL NOT BE LIABLE
  23. * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  24. * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
  25. * DELL OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
  26. * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
  27. * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
  28. * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
  29. * EVEN IF DELL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  30. */
  31. #include <ipmitool/ipmi_intf.h>
  32. #include <ipmitool/ipmi_picmg.h>
  33. #include <ipmitool/ipmi_fru.h> /* for access to link descriptor defines */
  34. #include <ipmitool/ipmi_strings.h>
  35. #include <ipmitool/log.h>
  36. #define PICMG_EXTENSION_ATCA_MAJOR_VERSION 2
  37. #define PICMG_EXTENSION_AMC0_MAJOR_VERSION 4
  38. #define PICMG_EXTENSION_UTCA_MAJOR_VERSION 5
  39. #define PICMG_EKEY_MODE_QUERY 0
  40. #define PICMG_EKEY_MODE_PRINT_ALL 1
  41. #define PICMG_EKEY_MODE_PRINT_ENABLED 2
  42. #define PICMG_EKEY_MODE_PRINT_DISABLED 3
  43. #define PICMG_EKEY_MAX_CHANNEL 16
  44. #define PICMG_EKEY_MAX_FABRIC_CHANNEL 15
  45. #define PICMG_EKEY_MAX_INTERFACE 3
  46. #define PICMG_EKEY_AMC_MAX_CHANNEL 16
  47. #define PICMG_EKEY_AMC_MAX_DEVICE 15 /* 4 bits */
  48. typedef enum picmg_bused_resource_mode {
  49. PICMG_BUSED_RESOURCE_SUMMARY,
  50. } t_picmg_bused_resource_mode ;
  51. typedef enum picmg_card_type {
  52. PICMG_CARD_TYPE_CPCI,
  53. PICMG_CARD_TYPE_ATCA,
  54. PICMG_CARD_TYPE_AMC,
  55. PICMG_CARD_TYPE_RESERVED
  56. } t_picmg_card_type ;
  57. /* This is the version of the PICMG Extenstion */
  58. static t_picmg_card_type PicmgCardType = PICMG_CARD_TYPE_RESERVED;
  59. void
  60. ipmi_picmg_help (void)
  61. {
  62. lprintf(LOG_NOTICE, "PICMG commands:");
  63. lprintf(LOG_NOTICE, " properties - get PICMG properties");
  64. lprintf(LOG_NOTICE, " frucontrol - FRU control");
  65. lprintf(LOG_NOTICE, " addrinfo - get address information");
  66. lprintf(LOG_NOTICE, " activate - activate a FRU");
  67. lprintf(LOG_NOTICE, " deactivate - deactivate a FRU");
  68. lprintf(LOG_NOTICE, " policy get - get the FRU activation policy");
  69. lprintf(LOG_NOTICE, " policy set - set the FRU activation policy");
  70. lprintf(LOG_NOTICE, " portstate get - get port state");
  71. lprintf(LOG_NOTICE,
  72. " portstate getdenied - get all denied[disabled] port description");
  73. lprintf(LOG_NOTICE,
  74. " portstate getgranted - get all granted[enabled] port description");
  75. lprintf(LOG_NOTICE,
  76. " portstate getall - get all port state description");
  77. lprintf(LOG_NOTICE, " portstate set - set port state");
  78. lprintf(LOG_NOTICE, " amcportstate get - get port state");
  79. lprintf(LOG_NOTICE, " amcportstate set - set port state");
  80. lprintf(LOG_NOTICE, " led prop - get led properties");
  81. lprintf(LOG_NOTICE, " led cap - get led color capabilities");
  82. lprintf(LOG_NOTICE, " led get - get led state");
  83. lprintf(LOG_NOTICE, " led set - set led state");
  84. lprintf(LOG_NOTICE, " power get - get power level info");
  85. lprintf(LOG_NOTICE, " power set - set power level");
  86. lprintf(LOG_NOTICE, " clk get - get clk state");
  87. lprintf(LOG_NOTICE,
  88. " clk getdenied - get all(up to 16) denied[disabled] clock descriptions");
  89. lprintf(LOG_NOTICE,
  90. " clk getgranted - get all(up to 16) granted[enabled] clock descriptions");
  91. lprintf(LOG_NOTICE,
  92. " clk getall - get all(up to 16) clock descriptions");
  93. lprintf(LOG_NOTICE, " clk set - set clk state");
  94. lprintf(LOG_NOTICE,
  95. " busres summary - display brief bused resource status info");
  96. }
  97. struct sAmcAddrMap {
  98. unsigned char ipmbLAddr;
  99. char* amcBayId;
  100. unsigned char siteNum;
  101. } amcAddrMap[] = {
  102. {0xFF, "reserved", 0},
  103. {0x72, "A1" , 1},
  104. {0x74, "A2" , 2},
  105. {0x76, "A3" , 3},
  106. {0x78, "A4" , 4},
  107. {0x7A, "B1" , 5},
  108. {0x7C, "B2" , 6},
  109. {0x7E, "B3" , 7},
  110. {0x80, "B4" , 8},
  111. {0x82, "reserved", 0},
  112. {0x84, "reserved", 0},
  113. {0x86, "reserved", 0},
  114. {0x88, "reserved", 0},
  115. };
  116. /* is_amc_channel - wrapper to convert user input into integer
  117. * AMC Channel range seems to be <0..255>, bits [7:0]
  118. *
  119. * @argv_ptr: source string to convert from; usually argv
  120. * @amc_chan_ptr: pointer where to store result
  121. * returns: zero on success, other values mean error
  122. */
  123. int
  124. is_amc_channel(const char *argv_ptr, uint8_t *amc_chan_ptr)
  125. {
  126. if (!argv_ptr || !amc_chan_ptr) {
  127. lprintf(LOG_ERR, "is_amc_channel(): invalid argument(s).");
  128. return (-1);
  129. }
  130. if (str2uchar(argv_ptr, amc_chan_ptr) == 0) {
  131. return 0;
  132. }
  133. lprintf(LOG_ERR, "Given AMC Channel '%s' is invalid.", argv_ptr);
  134. return (-1);
  135. }
  136. /* is_amc_dev - wrapper to convert user input into integer.
  137. * AMC Dev ID limits are uknown.
  138. *
  139. * @argv_ptr: source string to convert from; usually argv
  140. * @amc_dev_ptr: pointer where to store result
  141. * returns: zero on success, other values mean error
  142. */
  143. int
  144. is_amc_dev(const char *argv_ptr, int32_t *amc_dev_ptr)
  145. {
  146. if (!argv_ptr || !amc_dev_ptr) {
  147. lprintf(LOG_ERR, "is_amc_dev(): invalid argument(s).");
  148. return (-1);
  149. }
  150. if (str2int(argv_ptr, amc_dev_ptr) == 0 && *amc_dev_ptr >= 0) {
  151. return 0;
  152. }
  153. lprintf(LOG_ERR, "Given PICMG Device '%s' is invalid.",
  154. argv_ptr);
  155. return (-1);
  156. }
  157. /* is_amc_intf - wrapper to convert user input into integer.
  158. * AMC Interface (ID) limits are uknown.
  159. *
  160. * @argv_ptr: source string to convert from; usually argv
  161. * @amc_intf_ptr: pointer where to store result
  162. * returns: zero on success, other values mean error
  163. */
  164. int
  165. is_amc_intf(const char *argv_ptr, int32_t *amc_intf_ptr)
  166. {
  167. if (!argv_ptr || !amc_intf_ptr) {
  168. lprintf(LOG_ERR, "is_amc_intf(): invalid argument(s).");
  169. return (-1);
  170. }
  171. if (str2int(argv_ptr, amc_intf_ptr) == 0 && *amc_intf_ptr >= 0) {
  172. return 0;
  173. }
  174. lprintf(LOG_ERR, "Given PICMG Interface '%s' is invalid.",
  175. argv_ptr);
  176. return (-1);
  177. }
  178. /* is_amc_port - wrapper to convert user input into integer.
  179. * AMC Port limits are uknown.
  180. *
  181. * @argv_ptr: source string to convert from; usually argv
  182. * @amc_port_ptr: pointer where to store result
  183. * returns: zero on success, other values mean error
  184. */
  185. int
  186. is_amc_port(const char *argv_ptr, int32_t *amc_port_ptr)
  187. {
  188. if (!argv_ptr || !amc_port_ptr) {
  189. lprintf(LOG_ERR, "is_amc_port(): invalid argument(s).");
  190. return (-1);
  191. }
  192. if (str2int(argv_ptr, amc_port_ptr) == 0 && *amc_port_ptr >= 0) {
  193. return 0;
  194. }
  195. lprintf(LOG_ERR, "Given PICMG Port '%s' is invalid.", argv_ptr);
  196. return (-1);
  197. }
  198. /* is_clk_acc - wrapper to convert user input into integer.
  199. * Clock Accuracy limits are uknown[1byte by spec].
  200. *
  201. * @argv_ptr: source string to convert from; usually argv
  202. * @clk_acc_ptr: pointer where to store result
  203. * returns: zero on success, other values mean error
  204. */
  205. int
  206. is_clk_acc(const char *argv_ptr, uint8_t *clk_acc_ptr)
  207. {
  208. if (!argv_ptr || !clk_acc_ptr) {
  209. lprintf(LOG_ERR, "is_clk_acc(): invalid argument(s).");
  210. return (-1);
  211. }
  212. if (str2uchar(argv_ptr, clk_acc_ptr) == 0) {
  213. return 0;
  214. }
  215. lprintf(LOG_ERR, "Given Clock Accuracy '%s' is invalid.",
  216. argv_ptr);
  217. return (-1);
  218. }
  219. /* is_clk_family - wrapper to convert user input into integer.
  220. * Clock Family limits are uknown[1byte by spec].
  221. *
  222. * @argv_ptr: source string to convert from; usually argv
  223. * @clk_family_ptr: pointer where to store result
  224. * returns: zero on success, other values mean error
  225. */
  226. int
  227. is_clk_family(const char *argv_ptr, uint8_t *clk_family_ptr)
  228. {
  229. if (!argv_ptr || !clk_family_ptr) {
  230. lprintf(LOG_ERR, "is_clk_family(): invalid argument(s).");
  231. return (-1);
  232. }
  233. if (str2uchar(argv_ptr, clk_family_ptr) == 0) {
  234. return 0;
  235. }
  236. lprintf(LOG_ERR, "Given Clock Family '%s' is invalid.",
  237. argv_ptr);
  238. return (-1);
  239. }
  240. /* is_clk_freq - wrapper to convert user input into integer.
  241. * Clock Frequency limits are uknown, but specification says
  242. * 3Bytes + 1B checksum
  243. *
  244. * @argv_ptr: source string to convert from; usually argv
  245. * @clk_freq_ptr: pointer where to store result
  246. * returns: zero on success, other values mean error
  247. */
  248. int
  249. is_clk_freq(const char *argv_ptr, uint32_t *clk_freq_ptr)
  250. {
  251. if (!argv_ptr || !clk_freq_ptr) {
  252. lprintf(LOG_ERR, "is_clk_freq(): invalid argument(s).");
  253. return (-1);
  254. }
  255. if (str2uint(argv_ptr, clk_freq_ptr) == 0) {
  256. return 0;
  257. }
  258. lprintf(LOG_ERR, "Given Clock Frequency '%s' is invalid.",
  259. argv_ptr);
  260. return (-1);
  261. }
  262. /* is_clk_id - wrapper to convert user input into integer.
  263. * Clock ID limits are uknown, however it's 1B by specification and I've
  264. * found two ranges: <1..5> or <0..15>
  265. *
  266. * @argv_ptr: source string to convert from; usually argv
  267. * @clk_id_ptr: pointer where to store result
  268. * returns: zero on success, other values mean error
  269. */
  270. int
  271. is_clk_id(const char *argv_ptr, uint8_t *clk_id_ptr)
  272. {
  273. if (!argv_ptr || !clk_id_ptr) {
  274. lprintf(LOG_ERR, "is_clk_id(): invalid argument(s).");
  275. return (-1);
  276. }
  277. if (str2uchar(argv_ptr, clk_id_ptr) == 0) {
  278. return 0;
  279. }
  280. lprintf(LOG_ERR, "Given Clock ID '%s' is invalid.", argv_ptr);
  281. return (-1);
  282. }
  283. /* is_clk_index - wrapper to convert user input into integer.
  284. * Clock Index limits are uknown[1B by spec]
  285. *
  286. * @argv_ptr: source string to convert from; usually argv
  287. * @clk_index_ptr: pointer where to store result
  288. * returns: zero on success, other values mean error
  289. */
  290. int
  291. is_clk_index(const char *argv_ptr, uint8_t *clk_index_ptr)
  292. {
  293. if (!argv_ptr || !clk_index_ptr) {
  294. lprintf(LOG_ERR, "is_clk_index(): invalid argument(s).");
  295. return (-1);
  296. }
  297. if (str2uchar(argv_ptr, clk_index_ptr) == 0) {
  298. return 0;
  299. }
  300. lprintf(LOG_ERR, "Given Clock Index '%s' is invalid.", argv_ptr);
  301. return (-1);
  302. }
  303. /* is_clk_resid - wrapper to convert user input into integer.
  304. * Clock Resource Index(?) limits are uknown, but maximum seems to be 15.
  305. *
  306. * @argv_ptr: source string to convert from; usually argv
  307. * @clk_resid_ptr: pointer where to store result
  308. * returns: zero on success, other values mean error
  309. */
  310. int
  311. is_clk_resid(const char *argv_ptr, int8_t *clk_resid_ptr)
  312. {
  313. if (!argv_ptr || !clk_resid_ptr) {
  314. lprintf(LOG_ERR, "is_clk_resid(): invalid argument(s).");
  315. return (-1);
  316. }
  317. if (str2char(argv_ptr, clk_resid_ptr) == 0
  318. && *clk_resid_ptr > (-1)) {
  319. return 0;
  320. }
  321. lprintf(LOG_ERR, "Given Resource ID '%s' is invalid.",
  322. clk_resid_ptr);
  323. return (-1);
  324. }
  325. /* is_clk_setting - wrapper to convert user input into integer.
  326. * Clock Setting is a 1B bitfield:
  327. * x [7:4] - reserved
  328. * x [3] - state - 0/1
  329. * x [2] - direction - 0/1
  330. * x [1:0] - PLL ctrl - 00/01/10/11[Reserved]
  331. *
  332. * @argv_ptr: source string to convert from; usually argv
  333. * @clk_setting_ptr: pointer where to store result
  334. * returns: zero on success, other values mean error
  335. */
  336. int
  337. is_clk_setting(const char *argv_ptr, uint8_t *clk_setting_ptr)
  338. {
  339. if (!argv_ptr || !clk_setting_ptr) {
  340. lprintf(LOG_ERR, "is_clk_setting(): invalid argument(s).");
  341. return (-1);
  342. }
  343. if (str2uchar(argv_ptr, clk_setting_ptr) == 0) {
  344. return 0;
  345. }
  346. /* FIXME - validate bits 4-7 are 0 ? */
  347. lprintf(LOG_ERR, "Given Clock Setting '%s' is invalid.", argv_ptr);
  348. return (-1);
  349. }
  350. /* is_enable - wrapper to convert user input into integer.
  351. * Valid input range for Enable is <0..1>.
  352. *
  353. * @argv_ptr: source string to convert from; usually argv
  354. * @enable_ptr: pointer where to store result
  355. * returns: zero on success, other values mean error
  356. */
  357. int
  358. is_enable(const char *argv_ptr, uint8_t *enable_ptr)
  359. {
  360. if (!argv_ptr || !enable_ptr) {
  361. lprintf(LOG_ERR, "is_enable(): invalid argument(s).");
  362. return (-1);
  363. }
  364. if (str2uchar(argv_ptr, enable_ptr) == 0
  365. && (*enable_ptr == 0 || *enable_ptr == 1)) {
  366. return 0;
  367. }
  368. lprintf(LOG_ERR, "Given Enable '%s' is invalid.", argv_ptr);
  369. return (-1);
  370. }
  371. /* is_enable - wrapper to convert user input into integer.
  372. * LED colors:
  373. * - valid <1..6>, <0xE..0xF>
  374. * - reserved [0, 7]
  375. * - undefined <8..D>
  376. *
  377. * @argv_ptr: source string to convert from; usually argv
  378. * @enable_ptr: pointer where to store result
  379. * returns: zero on success, other values mean error
  380. */
  381. int
  382. is_led_color(const char *argv_ptr, uint8_t *led_color_ptr)
  383. {
  384. if (!argv_ptr || !led_color_ptr) {
  385. lprintf(LOG_ERR, "is_led_color(): invalid argument(s).");
  386. return (-1);
  387. }
  388. if (str2uchar(argv_ptr, led_color_ptr) != 0) {
  389. lprintf(LOG_ERR, "Given LED Color '%s' is invalid.",
  390. argv_ptr);
  391. lprintf(LOG_ERR,
  392. "LED Color must be from ranges: <1..6>, <0xE..0xF>");
  393. return (-1);
  394. }
  395. if ((*led_color_ptr >= 1 && *led_color_ptr <= 6)
  396. || (*led_color_ptr >= 0xE && *led_color_ptr <= 0xF)) {
  397. return 0;
  398. }
  399. lprintf(LOG_ERR, "Given LED Color '%s' is out of range.", argv_ptr);
  400. lprintf(LOG_ERR, "LED Color must be from ranges: <1..6>, <0xE..0xF>");
  401. return (-1);
  402. }
  403. /* is_led_function - wrapper to convert user input into integer.
  404. * LED functions, however, might differ by OEM:
  405. * - 0x00 - off override
  406. * - <0x01..0xFA> - blinking override
  407. * - 0xFB - lamp test state
  408. * - 0xFC - state restored to local ctrl state
  409. * - <0xFD..0xFE> - reserved
  410. * - 0xFF - on override
  411. *
  412. * @argv_ptr: source string to convert from; usually argv
  413. * @led_fn_ptr: pointer where to store result
  414. * returns: zero on success, other values mean error
  415. */
  416. int
  417. is_led_function(const char *argv_ptr, uint8_t *led_fn_ptr)
  418. {
  419. if (!argv_ptr || !led_fn_ptr) {
  420. lprintf(LOG_ERR, "is_led_function(): invalid argument(s).");
  421. return (-1);
  422. }
  423. if (str2uchar(argv_ptr, led_fn_ptr) == 0
  424. && (*led_fn_ptr < 0xFD || *led_fn_ptr > 0xFE)) {
  425. return 0;
  426. }
  427. lprintf(LOG_ERR, "Given LED Function '%s' is invalid.", argv_ptr);
  428. return (-1);
  429. }
  430. /* is_led_id - wrapper to convert user input into integer.
  431. * LED ID range seems to be <0..255>
  432. *
  433. * @argv_ptr: source string to convert from; usually argv
  434. * @led_id_ptr: pointer where to store result
  435. * returns: zero on success, other values mean error
  436. */
  437. int
  438. is_led_id(const char *argv_ptr, uint8_t *led_id_ptr)
  439. {
  440. if (!argv_ptr || !led_id_ptr) {
  441. lprintf(LOG_ERR, "is_led_id(): invalid argument(s).");
  442. return (-1);
  443. }
  444. if (str2uchar(argv_ptr, led_id_ptr) == 0) {
  445. return 0;
  446. }
  447. lprintf(LOG_ERR, "Given LED ID '%s' is invalid.", argv_ptr);
  448. return (-1);
  449. }
  450. /* is_link_group - wrapper to convert user input into integer.
  451. * Link Grouping ID limis are unknown, bits [31:24] by spec.
  452. *
  453. * @argv_ptr: source string to convert from; usually argv
  454. * @link_grp_ptr: pointer where to store result
  455. * returns: zero on success, other values mean error
  456. */
  457. int
  458. is_link_group(const char *argv_ptr, uint8_t *link_grp_ptr)
  459. {
  460. if (!argv_ptr || !link_grp_ptr) {
  461. lprintf(LOG_ERR, "is_link_group(): invalid argument(s).");
  462. return (-1);
  463. }
  464. if (str2uchar(argv_ptr, link_grp_ptr) == 0) {
  465. return 0;
  466. }
  467. lprintf(LOG_ERR, "Given Link Group '%s' is invalid.", argv_ptr);
  468. return (-1);
  469. }
  470. /* is_link_type - wrapper to convert user input into integer.
  471. * Link Type limits are unknown, bits [19:12]
  472. *
  473. * @argv_ptr: source string to convert from; usually argv
  474. * @link_type_ptr: pointer where to store result
  475. * returns: zero on success, other values mean error
  476. */
  477. int
  478. is_link_type(const char *argv_ptr, uint8_t *link_type_ptr)
  479. {
  480. if (!argv_ptr || !link_type_ptr) {
  481. lprintf(LOG_ERR, "is_link_type(): invalid argument(s).");
  482. return (-1);
  483. }
  484. if (str2uchar(argv_ptr, link_type_ptr) == 0) {
  485. return 0;
  486. }
  487. lprintf(LOG_ERR, "Given Link Type '%s' is invalid.", argv_ptr);
  488. return (-1);
  489. }
  490. /* is_link_type_ext - wrapper to convert user input into integer.
  491. * Link Type Extension limits are unknown, bits [23:20] => <0..15> ?
  492. *
  493. * @argv_ptr: source string to convert from; usually argv
  494. * @link_type_ext_ptr: pointer where to store result
  495. * returns: zero on success, other values mean error
  496. */
  497. int
  498. is_link_type_ext(const char *argv_ptr, uint8_t *link_type_ext_ptr)
  499. {
  500. if (!argv_ptr || !link_type_ext_ptr) {
  501. lprintf(LOG_ERR, "is_link_type_ext(): invalid argument(s).");
  502. return (-1);
  503. }
  504. if (str2uchar(argv_ptr, link_type_ext_ptr) != 0
  505. || *link_type_ext_ptr > 15) {
  506. lprintf(LOG_ERR,
  507. "Given Link Type Extension '%s' is invalid.",
  508. argv_ptr);
  509. return (-1);
  510. }
  511. return 0;
  512. }
  513. int
  514. ipmi_picmg_getaddr(struct ipmi_intf * intf, int argc, char ** argv)
  515. {
  516. struct ipmi_rs * rsp;
  517. struct ipmi_rq req;
  518. unsigned char msg_data[5];
  519. memset(&req, 0, sizeof(req));
  520. req.msg.netfn = IPMI_NETFN_PICMG;
  521. req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
  522. req.msg.data = msg_data;
  523. req.msg.data_len = 2;
  524. msg_data[0] = 0; /* picmg identifier */
  525. msg_data[1] = 0; /* default fru id */
  526. if(argc > 0) {
  527. if (is_fru_id(argv[0], &msg_data[1]) != 0) {
  528. return (-1);
  529. }
  530. }
  531. rsp = intf->sendrecv(intf, &req);
  532. if (!rsp) {
  533. lprintf(LOG_ERR, "Error. No valid response received.");
  534. return (-1);
  535. } else if (rsp->ccode) {
  536. lprintf(LOG_ERR, "Error getting address information CC: 0x%02x",
  537. rsp->ccode);
  538. return (-1);
  539. }
  540. printf("Hardware Address : 0x%02x\n", rsp->data[1]);
  541. printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]);
  542. printf("FRU ID : 0x%02x\n", rsp->data[4]);
  543. printf("Site ID : 0x%02x\n", rsp->data[5]);
  544. printf("Site Type : ");
  545. switch (rsp->data[6]) {
  546. case PICMG_ATCA_BOARD:
  547. printf("ATCA board\n");
  548. break;
  549. case PICMG_POWER_ENTRY:
  550. printf("Power Entry Module\n");
  551. break;
  552. case PICMG_SHELF_FRU:
  553. printf("Shelf FRU\n");
  554. break;
  555. case PICMG_DEDICATED_SHMC:
  556. printf("Dedicated Shelf Manager\n");
  557. break;
  558. case PICMG_FAN_TRAY:
  559. printf("Fan Tray\n");
  560. break;
  561. case PICMG_FAN_FILTER_TRAY:
  562. printf("Fan Filter Tray\n");
  563. break;
  564. case PICMG_ALARM:
  565. printf("Alarm module\n");
  566. break;
  567. case PICMG_AMC:
  568. printf("AMC");
  569. printf(" -> IPMB-L Address: 0x%02x\n", amcAddrMap[rsp->data[5]].ipmbLAddr);
  570. break;
  571. case PICMG_PMC:
  572. printf("PMC\n");
  573. break;
  574. case PICMG_RTM:
  575. printf("RTM\n");
  576. break;
  577. default:
  578. if (rsp->data[6] >= 0xc0 && rsp->data[6] <= 0xcf) {
  579. printf("OEM\n");
  580. } else {
  581. printf("unknown\n");
  582. }
  583. }
  584. return 0;
  585. }
  586. int
  587. ipmi_picmg_properties(struct ipmi_intf * intf, int show )
  588. {
  589. unsigned char PicmgExtMajorVersion;
  590. struct ipmi_rs * rsp;
  591. struct ipmi_rq req;
  592. unsigned char msg_data;
  593. memset(&req, 0, sizeof(req));
  594. req.msg.netfn = IPMI_NETFN_PICMG;
  595. req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
  596. req.msg.data = &msg_data;
  597. req.msg.data_len = 1;
  598. msg_data = 0;
  599. rsp = intf->sendrecv(intf, &req);
  600. if (!rsp || rsp->ccode) {
  601. lprintf(LOG_ERR, "Error getting address information.");
  602. return -1;
  603. }
  604. if( show )
  605. {
  606. printf("PICMG identifier : 0x%02x\n", rsp->data[0]);
  607. printf("PICMG Ext. Version : %i.%i\n", rsp->data[1]&0x0f,
  608. (rsp->data[1]&0xf0) >> 4);
  609. printf("Max FRU Device ID : 0x%02x\n", rsp->data[2]);
  610. printf("FRU Device ID : 0x%02x\n", rsp->data[3]);
  611. }
  612. /* We cache the major extension version ...
  613. to know how to format some commands */
  614. PicmgExtMajorVersion = rsp->data[1]&0x0f;
  615. if( PicmgExtMajorVersion == PICMG_CPCI_MAJOR_VERSION ) {
  616. PicmgCardType = PICMG_CARD_TYPE_CPCI;
  617. }
  618. else if( PicmgExtMajorVersion == PICMG_ATCA_MAJOR_VERSION) {
  619. PicmgCardType = PICMG_CARD_TYPE_ATCA;
  620. }
  621. else if( PicmgExtMajorVersion == PICMG_AMC_MAJOR_VERSION) {
  622. PicmgCardType = PICMG_CARD_TYPE_AMC;
  623. }
  624. return 0;
  625. }
  626. #define PICMG_FRU_DEACTIVATE (unsigned char) 0x00
  627. #define PICMG_FRU_ACTIVATE (unsigned char) 0x01
  628. int
  629. ipmi_picmg_fru_activation(struct ipmi_intf * intf, int argc, char ** argv, unsigned char state)
  630. {
  631. struct ipmi_rs * rsp;
  632. struct ipmi_rq req;
  633. struct picmg_set_fru_activation_cmd cmd;
  634. memset(&req, 0, sizeof(req));
  635. req.msg.netfn = IPMI_NETFN_PICMG;
  636. req.msg.cmd = PICMG_FRU_ACTIVATION_CMD;
  637. req.msg.data = (unsigned char*) &cmd;
  638. req.msg.data_len = 3;
  639. cmd.picmg_id = 0; /* PICMG identifier */
  640. if (is_fru_id(argv[0], &(cmd.fru_id)) != 0) {
  641. return (-1);
  642. }
  643. cmd.fru_state = state;
  644. rsp = intf->sendrecv(intf, &req);
  645. if (!rsp || rsp->ccode) {
  646. lprintf(LOG_ERR, "Error activation/deactivation of FRU.");
  647. return -1;
  648. }
  649. if (rsp->data[0] != 0x00) {
  650. lprintf(LOG_ERR, "Error activation/deactivation of FRU.");
  651. }
  652. return 0;
  653. }
  654. int
  655. ipmi_picmg_fru_activation_policy_get(struct ipmi_intf * intf, int argc, char ** argv)
  656. {
  657. struct ipmi_rs * rsp;
  658. struct ipmi_rq req;
  659. unsigned char msg_data[4];
  660. memset(&req, 0, sizeof(req));
  661. req.msg.netfn = IPMI_NETFN_PICMG;
  662. req.msg.cmd = PICMG_GET_FRU_POLICY_CMD;
  663. req.msg.data = msg_data;
  664. req.msg.data_len = 2;
  665. msg_data[0] = 0; /* PICMG identifier */
  666. if (is_fru_id(argv[0], &msg_data[1]) != 0) {
  667. return (-1);
  668. }
  669. rsp = intf->sendrecv(intf, &req);
  670. if (!rsp) {
  671. lprintf(LOG_ERR, "No valid response received.");
  672. return -1;
  673. }
  674. if (rsp->ccode) {
  675. lprintf(LOG_ERR, "FRU activation policy get failed with CC code 0x%02x",
  676. rsp->ccode);
  677. return -1;
  678. }
  679. printf(" %s\n", ((rsp->data[1] & 0x01) == 0x01) ?
  680. "activation locked" : "activation not locked");
  681. printf(" %s\n", ((rsp->data[1] & 0x02) == 0x02) ?
  682. "deactivation locked" : "deactivation not locked");
  683. return 0;
  684. }
  685. int
  686. ipmi_picmg_fru_activation_policy_set(struct ipmi_intf * intf, int argc, char ** argv)
  687. {
  688. struct ipmi_rs * rsp;
  689. struct ipmi_rq req;
  690. unsigned char msg_data[4];
  691. memset(&req, 0, sizeof(req));
  692. req.msg.netfn = IPMI_NETFN_PICMG;
  693. req.msg.cmd = PICMG_SET_FRU_POLICY_CMD;
  694. req.msg.data = msg_data;
  695. req.msg.data_len = 4;
  696. msg_data[0] = 0; /* PICMG identifier */
  697. if (is_fru_id(argv[0], &msg_data[1]) != 0) {
  698. return (-1);
  699. }
  700. if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 3) {
  701. /* FRU Lock Mask */
  702. lprintf(LOG_ERR, "Given FRU Lock Mask '%s' is invalid.",
  703. argv[1]);
  704. return (-1);
  705. }
  706. if (str2uchar(argv[2], &msg_data[3]) != 0 || msg_data[3] > 3) {
  707. /* FRU Act Policy */
  708. lprintf(LOG_ERR,
  709. "Given FRU Activation Policy '%s' is invalid.",
  710. argv[2]);
  711. return (-1);
  712. }
  713. rsp = intf->sendrecv(intf, &req);
  714. if (!rsp) {
  715. lprintf(LOG_ERR, "No valid response received.");
  716. return -1;
  717. }
  718. if (rsp->ccode) {
  719. lprintf(LOG_ERR, "FRU activation policy set failed with CC code 0x%02x",
  720. rsp->ccode);
  721. return -1;
  722. }
  723. return 0;
  724. }
  725. #define PICMG_MAX_LINK_PER_CHANNEL 4
  726. int
  727. ipmi_picmg_portstate_get(struct ipmi_intf * intf, int32_t interface,
  728. uint8_t channel, int mode)
  729. {
  730. struct ipmi_rs * rsp = NULL;
  731. struct ipmi_rq req;
  732. unsigned char msg_data[4];
  733. struct fru_picmgext_link_desc* d; /* descriptor pointer for rec. data */
  734. memset(&req, 0, sizeof(req));
  735. req.msg.netfn = IPMI_NETFN_PICMG;
  736. req.msg.cmd = PICMG_GET_PORT_STATE_CMD;
  737. req.msg.data = msg_data;
  738. req.msg.data_len = 2;
  739. msg_data[0] = 0x00; /* PICMG identifier */
  740. msg_data[1] = (interface & 0x3)<<6; /* interface */
  741. msg_data[1] |= (channel & 0x3F); /* channel number */
  742. rsp = intf->sendrecv(intf, &req);
  743. if (!rsp) {
  744. lprintf(LOG_ERR, "No valid response received.");
  745. return -1;
  746. }
  747. if (rsp->ccode) {
  748. if( mode == PICMG_EKEY_MODE_QUERY ){
  749. lprintf(LOG_ERR, "FRU portstate get failed with CC code 0x%02x",
  750. rsp->ccode);
  751. }
  752. return -1;
  753. }
  754. if (rsp->data_len >= 6) {
  755. int index;
  756. /* add support for more than one link per channel */
  757. for(index=0;index<PICMG_MAX_LINK_PER_CHANNEL;index++){
  758. if( rsp->data_len > (1+ (index*5))){
  759. d = (struct fru_picmgext_link_desc *) &(rsp->data[1 + (index*5)]);
  760. if
  761. (
  762. mode == PICMG_EKEY_MODE_PRINT_ALL
  763. ||
  764. mode == PICMG_EKEY_MODE_QUERY
  765. ||
  766. (
  767. mode == PICMG_EKEY_MODE_PRINT_ENABLED
  768. &&
  769. rsp->data[5 + (index*5) ] == 0x01
  770. )
  771. ||
  772. (
  773. mode == PICMG_EKEY_MODE_PRINT_DISABLED
  774. &&
  775. rsp->data[5 + (index*5) ] == 0x00
  776. )
  777. )
  778. {
  779. printf(" Link Grouping ID: 0x%02x\n", d->grouping);
  780. printf(" Link Type Extension: 0x%02x\n", d->ext);
  781. printf(" Link Type: 0x%02x ", d->type);
  782. if (d->type == 0 || d->type == 0xff)
  783. {
  784. printf("Reserved %d\n",d->type);
  785. }
  786. else if (d->type >= 0x06 && d->type <= 0xef)
  787. {
  788. printf("Reserved\n");
  789. }
  790. else if (d->type >= 0xf0 && d->type <= 0xfe)
  791. {
  792. printf("OEM GUID Definition\n");
  793. }
  794. else
  795. {
  796. switch (d->type)
  797. {
  798. case FRU_PICMGEXT_LINK_TYPE_BASE:
  799. printf("PICMG 3.0 Base Interface 10/100/1000\n");
  800. break;
  801. case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET:
  802. printf("PICMG 3.1 Ethernet Fabric Interface\n");
  803. break;
  804. case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND:
  805. printf("PICMG 3.2 Infiniband Fabric Interface\n");
  806. break;
  807. case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR:
  808. printf("PICMG 3.3 Star Fabric Interface\n");
  809. break;
  810. case FRU_PICMGEXT_LINK_TYPE_PCIE:
  811. printf("PCI Express Fabric Interface\n");
  812. break;
  813. default:
  814. printf("Invalid\n");
  815. break;
  816. }
  817. }
  818. printf(" Link Designator: \n");
  819. printf(" Port Flag: 0x%02x\n", d->desig_port);
  820. printf(" Interface: 0x%02x - ", d->desig_if);
  821. switch (d->desig_if)
  822. {
  823. case FRU_PICMGEXT_DESIGN_IF_BASE:
  824. printf("Base Interface\n");
  825. break;
  826. case FRU_PICMGEXT_DESIGN_IF_FABRIC:
  827. printf("Fabric Interface\n");
  828. break;
  829. case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL:
  830. printf("Update Channel\n");
  831. break;
  832. case FRU_PICMGEXT_DESIGN_IF_RESERVED:
  833. printf("Reserved\n");
  834. break;
  835. default:
  836. printf("Invalid");
  837. break;
  838. }
  839. printf(" Channel Number: 0x%02x\n", d->desig_channel);
  840. printf(" STATE: %s\n",
  841. ( rsp->data[5 +(index*5)] == 0x01) ?"enabled":"disabled");
  842. printf("\n");
  843. }
  844. }
  845. }
  846. }
  847. else
  848. {
  849. lprintf(LOG_ERR, "Unexpected answer, can't print result.");
  850. }
  851. return 0;
  852. }
  853. int
  854. ipmi_picmg_portstate_set(struct ipmi_intf * intf, int32_t interface,
  855. uint8_t channel, int32_t port, uint8_t type,
  856. uint8_t typeext, uint8_t group, uint8_t enable)
  857. {
  858. struct ipmi_rs * rsp;
  859. struct ipmi_rq req;
  860. unsigned char msg_data[6];
  861. memset(&req, 0, sizeof(req));
  862. req.msg.netfn = IPMI_NETFN_PICMG;
  863. req.msg.cmd = PICMG_SET_PORT_STATE_CMD;
  864. req.msg.data = msg_data;
  865. req.msg.data_len = 6;
  866. msg_data[0] = 0x00; /* PICMG identifier */
  867. msg_data[1] = (channel & 0x3f) | ((interface & 3) << 6);
  868. msg_data[2] = (port & 0xf) | ((type & 0xf) << 4);
  869. msg_data[3] = ((type >> 4) & 0xf) | ((typeext & 0xf) << 4);
  870. msg_data[4] = group & 0xff;
  871. msg_data[5] = (enable & 0x01); /* enable/disable */
  872. rsp = intf->sendrecv(intf, &req);
  873. if (!rsp) {
  874. lprintf(LOG_ERR, "No valid response received.");
  875. return -1;
  876. }
  877. if (rsp->ccode) {
  878. lprintf(LOG_ERR, "Picmg portstate set failed with CC code 0x%02x",
  879. rsp->ccode);
  880. return -1;
  881. }
  882. return 0;
  883. }
  884. /* AMC.0 commands */
  885. #define PICMG_AMC_MAX_LINK_PER_CHANNEL 4
  886. int
  887. ipmi_picmg_amc_portstate_get(struct ipmi_intf * intf, int32_t device,
  888. uint8_t channel, int mode)
  889. {
  890. struct ipmi_rs * rsp;
  891. struct ipmi_rq req;
  892. unsigned char msg_data[4];
  893. struct fru_picmgext_amc_link_info* d; /* descriptor pointer for rec. data */
  894. memset(&req, 0, sizeof(req));
  895. req.msg.netfn = IPMI_NETFN_PICMG;
  896. req.msg.cmd = PICMG_AMC_GET_PORT_STATE_CMD;
  897. req.msg.data = msg_data;
  898. /* FIXME : add check for AMC or carrier device */
  899. if(device == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){
  900. req.msg.data_len = 2; /* for amc only channel */
  901. }else{
  902. req.msg.data_len = 3; /* for carrier channel and device */
  903. }
  904. msg_data[0] = 0x00; /* PICMG identifier */
  905. msg_data[1] = channel ;
  906. msg_data[2] = device ;
  907. rsp = intf->sendrecv(intf, &req);
  908. if (!rsp) {
  909. lprintf(LOG_ERR, "No valid response received.");
  910. return -1;
  911. }
  912. if (rsp->ccode) {
  913. if( mode == PICMG_EKEY_MODE_QUERY ){
  914. lprintf(LOG_ERR, "Amc portstate get failed with CC code 0x%02x",
  915. rsp->ccode);
  916. }
  917. return -1;
  918. }
  919. if (rsp->data_len >= 5) {
  920. int index;
  921. /* add support for more than one link per channel */
  922. for(index=0;index<PICMG_AMC_MAX_LINK_PER_CHANNEL;index++){
  923. if( rsp->data_len > (1+ (index*4))){
  924. unsigned char type;
  925. unsigned char ext;
  926. unsigned char grouping;
  927. unsigned char port;
  928. unsigned char enabled;
  929. d = (struct fru_picmgext_amc_link_info *)&(rsp->data[1 + (index*4)]);
  930. /* Removed endianness check here, probably not required
  931. as we dont use bitfields */
  932. port = d->linkInfo[0] & 0x0F;
  933. type = ((d->linkInfo[0] & 0xF0) >> 4 )|(d->linkInfo[1] & 0x0F );
  934. ext = ((d->linkInfo[1] & 0xF0) >> 4 );
  935. grouping = d->linkInfo[2];
  936. enabled = rsp->data[4 + (index*4) ];
  937. if
  938. (
  939. mode == PICMG_EKEY_MODE_PRINT_ALL
  940. ||
  941. mode == PICMG_EKEY_MODE_QUERY
  942. ||
  943. (
  944. mode == PICMG_EKEY_MODE_PRINT_ENABLED
  945. &&
  946. enabled == 0x01
  947. )
  948. ||
  949. (
  950. mode == PICMG_EKEY_MODE_PRINT_DISABLED
  951. &&
  952. enabled == 0x00
  953. )
  954. )
  955. {
  956. if(device == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){
  957. printf(" Link device : AMC\n");
  958. }else{
  959. printf(" Link device : 0x%02x\n", device );
  960. }
  961. printf(" Link Grouping ID: 0x%02x\n", grouping);
  962. if (type == 0 || type == 1 ||type == 0xff)
  963. {
  964. printf(" Link Type Extension: 0x%02x\n", ext);
  965. printf(" Link Type: Reserved\n");
  966. }
  967. else if (type >= 0xf0 && type <= 0xfe)
  968. {
  969. printf(" Link Type Extension: 0x%02x\n", ext);
  970. printf(" Link Type: OEM GUID Definition\n");
  971. }
  972. else
  973. {
  974. if (type <= FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE )
  975. {
  976. printf(" Link Type Extension: %s\n",
  977. amc_link_type_ext_str[type][ext]);
  978. printf(" Link Type: %s\n",
  979. amc_link_type_str[type]);
  980. }
  981. else{
  982. printf(" Link Type Extension: 0x%02x\n", ext);
  983. printf(" Link Type: undefined\n");
  984. }
  985. }
  986. printf(" Link Designator: \n");
  987. printf(" Channel Number: 0x%02x\n", channel);
  988. printf(" Port Flag: 0x%02x\n", port );
  989. printf(" STATE: %s\n",
  990. ( enabled == 0x01 )?"enabled":"disabled");
  991. printf("\n");
  992. }
  993. }
  994. }
  995. }
  996. else
  997. {
  998. lprintf(LOG_NOTICE,"ipmi_picmg_amc_portstate_get"\
  999. "Unexpected answer, can't print result");
  1000. }
  1001. return 0;
  1002. }
  1003. int
  1004. ipmi_picmg_amc_portstate_set(struct ipmi_intf * intf, uint8_t channel,
  1005. int32_t port, uint8_t type, uint8_t typeext,
  1006. uint8_t group, uint8_t enable, int32_t device)
  1007. {
  1008. struct ipmi_rs * rsp;
  1009. struct ipmi_rq req;
  1010. unsigned char msg_data[7];
  1011. memset(&req, 0, sizeof(req));
  1012. req.msg.netfn = IPMI_NETFN_PICMG;
  1013. req.msg.cmd = PICMG_AMC_SET_PORT_STATE_CMD;
  1014. req.msg.data = msg_data;
  1015. msg_data[0] = 0x00; /* PICMG identifier*/
  1016. msg_data[1] = channel; /* channel id */
  1017. msg_data[2] = port & 0xF; /* port flags */
  1018. msg_data[2] |= (type & 0x0F)<<4; /* type */
  1019. msg_data[3] = (type & 0xF0)>>4; /* type */
  1020. msg_data[3] |= (typeext & 0x0F)<<4; /* extension */
  1021. msg_data[4] = (group & 0xFF); /* group */
  1022. msg_data[5] = (enable & 0x01); /* state */
  1023. req.msg.data_len = 6;
  1024. /* device id - only for carrier needed */
  1025. if (device >= 0) {
  1026. msg_data[6] = device;
  1027. req.msg.data_len = 7;
  1028. }
  1029. rsp = intf->sendrecv(intf, &req);
  1030. if (!rsp) {
  1031. lprintf(LOG_ERR, "No valid response received.");
  1032. return -1;
  1033. }
  1034. if (rsp->ccode) {
  1035. lprintf(LOG_ERR, "Amc portstate set failed with CC code 0x%02x",
  1036. rsp->ccode);
  1037. return -1;
  1038. }
  1039. return 0;
  1040. }
  1041. int
  1042. ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv)
  1043. {
  1044. struct ipmi_rs * rsp;
  1045. struct ipmi_rq req;
  1046. unsigned char msg_data[6];
  1047. memset(&req, 0, sizeof(req));
  1048. req.msg.netfn = IPMI_NETFN_PICMG;
  1049. req.msg.cmd = PICMG_GET_FRU_LED_PROPERTIES_CMD;
  1050. req.msg.data = msg_data;
  1051. req.msg.data_len = 2;
  1052. msg_data[0] = 0x00; /* PICMG identifier */
  1053. if (is_fru_id(argv[0], &msg_data[1]) != 0) {
  1054. return (-1);
  1055. }
  1056. rsp = intf->sendrecv(intf, &req);
  1057. if (!rsp) {
  1058. lprintf(LOG_ERR, "No valid response received.");
  1059. return -1;
  1060. }
  1061. if (rsp->ccode) {
  1062. lprintf(LOG_ERR, "LED get properties failed with CC code 0x%02x",
  1063. rsp->ccode);
  1064. return -1;
  1065. }
  1066. printf("General Status LED Properties: 0x%2x\n", rsp->data[1] );
  1067. printf("App. Specific LED Count: 0x%2x\n", rsp->data[2] );
  1068. return 0;
  1069. }
  1070. int
  1071. ipmi_picmg_get_led_capabilities(struct ipmi_intf * intf, int argc, char ** argv)
  1072. {
  1073. int i;
  1074. struct ipmi_rs * rsp;
  1075. struct ipmi_rq req;
  1076. unsigned char msg_data[6];
  1077. memset(&req, 0, sizeof(req));
  1078. req.msg.netfn = IPMI_NETFN_PICMG;
  1079. req.msg.cmd = PICMG_GET_LED_COLOR_CAPABILITIES_CMD;
  1080. req.msg.data = msg_data;
  1081. req.msg.data_len = 3;
  1082. msg_data[0] = 0x00; /* PICMG identifier */
  1083. if (is_fru_id(argv[0], &msg_data[1]) != 0
  1084. || is_led_id(argv[1], &msg_data[2]) != 0) {
  1085. return (-1);
  1086. }
  1087. rsp = intf->sendrecv(intf, &req);
  1088. if (!rsp) {
  1089. lprintf(LOG_ERR, "No valid response received.");
  1090. return -1;
  1091. }
  1092. if (rsp->ccode) {
  1093. lprintf(LOG_ERR, "LED get capabilities failed with CC code 0x%02x",
  1094. rsp->ccode);
  1095. return -1;
  1096. }
  1097. printf("LED Color Capabilities: ");
  1098. for ( i=0 ; i<8 ; i++ ) {
  1099. if ( rsp->data[1] & (0x01 << i) ) {
  1100. printf("%s, ", led_color_str[ i ]);
  1101. }
  1102. }
  1103. printf("\n");
  1104. printf("Default LED Color in\n");
  1105. printf(" LOCAL control: %s\n", led_color_str[ rsp->data[2] ] );
  1106. printf(" OVERRIDE state: %s\n", led_color_str[ rsp->data[3] ] );
  1107. return 0;
  1108. }
  1109. int
  1110. ipmi_picmg_get_led_state(struct ipmi_intf * intf, int argc, char ** argv)
  1111. {
  1112. struct ipmi_rs * rsp;
  1113. struct ipmi_rq req;
  1114. unsigned char msg_data[6];
  1115. memset(&req, 0, sizeof(req));
  1116. req.msg.netfn = IPMI_NETFN_PICMG;
  1117. req.msg.cmd = PICMG_GET_FRU_LED_STATE_CMD;
  1118. req.msg.data = msg_data;
  1119. req.msg.data_len = 3;
  1120. msg_data[0] = 0x00; /* PICMG identifier */
  1121. if (is_fru_id(argv[0], &msg_data[1]) != 0
  1122. || is_led_id(argv[1], &msg_data[2]) != 0) {
  1123. return (-1);
  1124. }
  1125. rsp = intf->sendrecv(intf, &req);
  1126. if (!rsp) {
  1127. lprintf(LOG_ERR, "No valid response received.");
  1128. return -1;
  1129. }
  1130. if (rsp->ccode) {
  1131. lprintf(LOG_ERR, "LED get state failed with CC code 0x%02x", rsp->ccode);
  1132. return -1;
  1133. }
  1134. printf("LED states: %x ", rsp->data[1] );
  1135. if (!(rsp->data[1] & 0x1)) {
  1136. printf("[NO LOCAL CONTROL]\n");
  1137. return 0;
  1138. }
  1139. printf("[LOCAL CONTROL");
  1140. if (rsp->data[1] & 0x2) {
  1141. printf("|OVERRIDE");
  1142. }
  1143. if (rsp->data[1] & 0x4) {
  1144. printf("|LAMPTEST");
  1145. }
  1146. printf("]\n");
  1147. printf(" Local Control function: %x ", rsp->data[2] );
  1148. if (rsp->data[2] == 0x0) {
  1149. printf("[OFF]\n");
  1150. } else if (rsp->data[2] == 0xff) {
  1151. printf("[ON]\n");
  1152. } else {
  1153. printf("[BLINKING]\n");
  1154. }
  1155. printf(" Local Control On-Duration: %x\n", rsp->data[3] );
  1156. printf(" Local Control Color: %x [%s]\n", rsp->data[4], led_color_str[ rsp->data[4] ]);
  1157. /* override state or lamp test */
  1158. if (rsp->data[1] & 0x02) {
  1159. printf(" Override function: %x ", rsp->data[5] );
  1160. if (rsp->data[2] == 0x0) {
  1161. printf("[OFF]\n");
  1162. } else if (rsp->data[2] == 0xff) {
  1163. printf("[ON]\n");
  1164. } else {
  1165. printf("[BLINKING]\n");
  1166. }
  1167. printf(" Override On-Duration: %x\n", rsp->data[6] );
  1168. printf(" Override Color: %x [%s]\n", rsp->data[7], led_color_str[ rsp->data[7] ]);
  1169. }
  1170. if (rsp->data[1] & 0x04) {
  1171. printf(" Lamp test duration: %x\n", rsp->data[8] );
  1172. }
  1173. return 0;
  1174. }
  1175. int
  1176. ipmi_picmg_set_led_state(struct ipmi_intf * intf, int argc, char ** argv)
  1177. {
  1178. struct ipmi_rs * rsp;
  1179. struct ipmi_rq req;
  1180. unsigned char msg_data[6];
  1181. memset(&req, 0, sizeof(req));
  1182. req.msg.netfn = IPMI_NETFN_PICMG;
  1183. req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD;
  1184. req.msg.data = msg_data;
  1185. req.msg.data_len = 6;
  1186. msg_data[0] = 0x00; /* PICMG identifier */
  1187. if (is_fru_id(argv[0], &msg_data[1]) != 0
  1188. || is_led_id(argv[1], &msg_data[2]) != 0
  1189. || is_led_function(argv[2], &msg_data[3]) != 0
  1190. || is_led_color(argv[4], &msg_data[5]) != 0) {
  1191. return (-1);
  1192. }
  1193. /* Validating the LED duration is not as simple as the other arguments, as
  1194. * the range of valid durations depends on the LED function. From the spec:
  1195. *
  1196. * ``On-duration: LED on-time in tens of milliseconds if (1 <= Byte 4 <= FAh)
  1197. * Lamp Test time in hundreds of milliseconds if (Byte 4 = FBh). Lamp Test
  1198. * time value must be less than 128. Other values when Byte 4 = FBh are
  1199. * reserved. Otherwise, this field is ignored and shall be set to 0h.''
  1200. *
  1201. * If we're doing a lamp test, then the allowed values are 0 -> 127.
  1202. * Otherwise, the allowed values are 0 -> 255. However, if the function is
  1203. * not a lamp test (0xFB) and outside the range 0x01 -> 0xFA then the value
  1204. * should be set to 0.
  1205. *
  1206. * Start by checking we have a parameter.
  1207. */
  1208. if (!argv[3]) {
  1209. lprintf(LOG_ERR, "LED Duration: invalid argument(s).");
  1210. return (-1);
  1211. }
  1212. /* Next check we have a number. */
  1213. if (str2uchar(argv[3], &msg_data[4]) != 0) {
  1214. lprintf(LOG_ERR, "Given LED Duration '%s' is invalid", argv[3]);
  1215. return (-1);
  1216. }
  1217. /* If we have a lamp test, ensure it's not too long a duration. */
  1218. if (msg_data[3] == 0xFB && msg_data[4] > 127) {
  1219. lprintf(LOG_ERR, "Given LED Duration '%s' is invalid", argv[3]);
  1220. return (-1);
  1221. }
  1222. /* If we're outside the range that allows durations, set the duration to 0.
  1223. * Warn the user that we're doing this.
  1224. */
  1225. if (msg_data[4] != 0 && (msg_data[3] == 0 || msg_data[3] > 0xFB)) {
  1226. lprintf(LOG_WARN, "Setting LED Duration '%s' to '0'", argv[3]);
  1227. msg_data[4] = 0;
  1228. }
  1229. rsp = intf->sendrecv(intf, &req);
  1230. if (!rsp) {
  1231. lprintf(LOG_ERR, "No valid response received.");
  1232. return -1;
  1233. }
  1234. if (rsp->ccode) {
  1235. lprintf(LOG_ERR, "LED set state failed with CC code 0x%02x", rsp->ccode);
  1236. return -1;
  1237. }
  1238. return 0;
  1239. }
  1240. int
  1241. ipmi_picmg_get_power_level(struct ipmi_intf * intf, int argc, char ** argv)
  1242. {
  1243. int i;
  1244. struct ipmi_rs * rsp;
  1245. struct ipmi_rq req;
  1246. unsigned char msg_data[6];
  1247. memset(&req, 0, sizeof(req));
  1248. req.msg.netfn = IPMI_NETFN_PICMG;
  1249. req.msg.cmd = PICMG_GET_POWER_LEVEL_CMD;
  1250. req.msg.data = msg_data;
  1251. req.msg.data_len = 3;
  1252. msg_data[0] = 0x00; /* PICMG identifier */
  1253. if (is_fru_id(argv[0], &msg_data[1]) != 0) {
  1254. return (-1);
  1255. }
  1256. /* PICMG Power Type - <0..3> */
  1257. if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 3) {
  1258. lprintf(LOG_ERR, "Given Power Type '%s' is invalid",
  1259. argv[1]);
  1260. return (-1);
  1261. }
  1262. rsp = intf->sendrecv(intf, &req);
  1263. if (!rsp) {
  1264. lprintf(LOG_ERR, "No valid response received.");
  1265. return -1;
  1266. }
  1267. if (rsp->ccode) {
  1268. lprintf(LOG_ERR, "Power level get failed with CC code 0x%02x", rsp->ccode);
  1269. return -1;
  1270. }
  1271. printf("Dynamic Power Configuration: %s\n", (rsp->data[1]&0x80)==0x80?"enabled":"disabled" );
  1272. printf("Actual Power Level: %i\n", (rsp->data[1] & 0xf));
  1273. printf("Delay to stable Power: %i\n", rsp->data[2]);
  1274. printf("Power Multiplier: %i\n", rsp->data[3]);
  1275. for ( i = 1; i+3 < rsp->data_len ; i++ ) {
  1276. printf(" Power Draw %i: %i\n", i, (rsp->data[i+3]) * rsp->data[3] / 10);
  1277. }
  1278. return 0;
  1279. }
  1280. int
  1281. ipmi_picmg_set_power_level(struct ipmi_intf * intf, int argc, char ** argv)
  1282. {
  1283. struct ipmi_rs * rsp;
  1284. struct ipmi_rq req;
  1285. unsigned char msg_data[6];
  1286. memset(&req, 0, sizeof(req));
  1287. req.msg.netfn = IPMI_NETFN_PICMG;
  1288. req.msg.cmd = PICMG_SET_POWER_LEVEL_CMD;
  1289. req.msg.data = msg_data;
  1290. req.msg.data_len = 4;
  1291. msg_data[0] = 0x00; /* PICMG identifier */
  1292. if (is_fru_id(argv[0], &msg_data[1]) != 0) {
  1293. return (-1);
  1294. }
  1295. /* PICMG Power Level - <0x00..0x14>, [0xFF] */
  1296. if (str2uchar(argv[1], &msg_data[2]) != 0
  1297. || (msg_data[2] > 0x14 && msg_data[2] != 0xFF)) {
  1298. lprintf(LOG_ERR,
  1299. "Given PICMG Power Level '%s' is invalid.",
  1300. argv[1]);
  1301. return (-1);
  1302. }
  1303. /* PICMG Present-to-desired - <0..1> */
  1304. if (str2uchar(argv[2], &msg_data[3]) != 0 || msg_data[3] > 1) {
  1305. lprintf(LOG_ERR,
  1306. "Given PICMG Present-to-desired '%s' is invalid.",
  1307. argv[2]);
  1308. return (-1);
  1309. }
  1310. rsp = intf->sendrecv(intf, &req);
  1311. if (!rsp) {
  1312. lprintf(LOG_ERR, "No valid response received.");
  1313. return -1;
  1314. }
  1315. if (rsp->ccode) {
  1316. lprintf(LOG_ERR, "Power level set failed with CC code 0x%02x", rsp->ccode);
  1317. return -1;
  1318. }
  1319. return 0;
  1320. }
  1321. int
  1322. ipmi_picmg_bused_resource(struct ipmi_intf * intf, t_picmg_bused_resource_mode mode)
  1323. {
  1324. struct ipmi_rs * rsp;
  1325. struct ipmi_rq req;
  1326. unsigned char msg_data[6];
  1327. memset(&req, 0, sizeof(req));
  1328. int status = 0;
  1329. switch ( mode ) {
  1330. case PICMG_BUSED_RESOURCE_SUMMARY:
  1331. {
  1332. t_picmg_busres_resource_id resource;
  1333. t_picmg_busres_board_cmd_types cmd =PICMG_BUSRES_BOARD_CMD_QUERY;
  1334. req.msg.netfn = IPMI_NETFN_PICMG;
  1335. req.msg.cmd = PICMG_BUSED_RESOURCE_CMD;
  1336. req.msg.data = msg_data;
  1337. req.msg.data_len = 3;
  1338. /* IF BOARD
  1339. query for all resources
  1340. */
  1341. for( resource=PICMG_BUSRES_METAL_TEST_BUS_1;resource<=PICMG_BUSRES_SYNC_CLOCK_GROUP_3;resource+=(t_picmg_busres_resource_id)1 ) {
  1342. msg_data[0] = 0x00; /* PICMG identifier */
  1343. msg_data[1] = (unsigned char) cmd;
  1344. msg_data[2] = (unsigned char) resource;
  1345. rsp = intf->sendrecv(intf, &req);
  1346. if (!rsp) {
  1347. printf("bused resource control: no response\n");
  1348. return -1;
  1349. }
  1350. if (rsp->ccode) {
  1351. printf("bused resource control: returned CC code 0x%02x\n", rsp->ccode);
  1352. return -1;
  1353. } else {
  1354. printf("Resource 0x%02x '%-26s' : 0x%02x [%s] \n" ,
  1355. resource, val2str(resource,picmg_busres_id_vals),
  1356. rsp->data[1], oemval2str(cmd,rsp->data[1],
  1357. picmg_busres_board_status_vals));
  1358. }
  1359. }
  1360. }
  1361. break;
  1362. default :
  1363. break;
  1364. }
  1365. return status;
  1366. }
  1367. int
  1368. ipmi_picmg_fru_control(struct ipmi_intf * intf, int argc, char ** argv)
  1369. {
  1370. struct ipmi_rs * rsp;
  1371. struct ipmi_rq req;
  1372. unsigned char msg_data[6];
  1373. memset(&req, 0, sizeof(req));
  1374. req.msg.netfn = IPMI_NETFN_PICMG;
  1375. req.msg.cmd = PICMG_FRU_CONTROL_CMD;
  1376. req.msg.data = msg_data;
  1377. req.msg.data_len = 3;
  1378. msg_data[0] = 0x00; /* PICMG identifier */
  1379. if (is_fru_id(argv[0], &msg_data[1]) != 0) {
  1380. return (-1);
  1381. }
  1382. /* FRU Control Option, valid range: <0..4> */
  1383. if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 4) {
  1384. lprintf(LOG_ERR,
  1385. "Given FRU Control Option '%s' is invalid.",
  1386. argv[1]);
  1387. return (-1);
  1388. }
  1389. printf("FRU Device Id: %d FRU Control Option: %s\n", msg_data[1], \
  1390. val2str( msg_data[2], picmg_frucontrol_vals));
  1391. rsp = intf->sendrecv(intf, &req);
  1392. if (!rsp) {
  1393. lprintf(LOG_ERR, "No valid response received.");
  1394. return -1;
  1395. }
  1396. if (rsp->ccode) {
  1397. lprintf(LOG_ERR, "frucontrol failed with CC code 0x%02x", rsp->ccode);
  1398. return -1;
  1399. } else {
  1400. printf("frucontrol: ok\n");
  1401. }
  1402. return 0;
  1403. }
  1404. int
  1405. ipmi_picmg_clk_get(struct ipmi_intf * intf, uint8_t clk_id, int8_t clk_res,
  1406. int mode)
  1407. {
  1408. struct ipmi_rs * rsp;
  1409. struct ipmi_rq req;
  1410. unsigned char enabled;
  1411. unsigned char direction;
  1412. unsigned char msg_data[6];
  1413. memset(&req, 0, sizeof(req));
  1414. req.msg.netfn = IPMI_NETFN_PICMG;
  1415. req.msg.cmd = PICMG_AMC_GET_CLK_STATE_CMD;
  1416. req.msg.data = msg_data;
  1417. msg_data[0] = 0x00; /* PICMG identifier */
  1418. msg_data[1] = clk_id;
  1419. if(clk_res == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){
  1420. req.msg.data_len = 2; /* for amc only channel */
  1421. }else{
  1422. req.msg.data_len = 3; /* for carrier channel and device */
  1423. msg_data[2] = clk_res;
  1424. }
  1425. rsp = intf->sendrecv(intf, &req);
  1426. if (!rsp) {
  1427. lprintf(LOG_ERR, "No valid response received.");
  1428. return -1;
  1429. }
  1430. if (rsp->ccode && (mode == PICMG_EKEY_MODE_QUERY) ) {
  1431. lprintf(LOG_ERR, "Clk get failed with CC code 0x%02x", rsp->ccode);
  1432. return -1;
  1433. }
  1434. if (rsp->ccode == 0 ) {
  1435. enabled = (rsp->data[1]&0x8)!=0;
  1436. direction = (rsp->data[1]&0x4)!=0;
  1437. if
  1438. (
  1439. mode == PICMG_EKEY_MODE_QUERY
  1440. ||
  1441. mode == PICMG_EKEY_MODE_PRINT_ALL
  1442. ||
  1443. (
  1444. mode == PICMG_EKEY_MODE_PRINT_DISABLED
  1445. &&
  1446. enabled == 0
  1447. )
  1448. ||
  1449. (
  1450. mode == PICMG_EKEY_MODE_PRINT_ENABLED
  1451. &&
  1452. enabled == 1
  1453. )
  1454. ) {
  1455. if( PicmgCardType != PICMG_CARD_TYPE_AMC ) {
  1456. printf("CLK resource id : %3d [ %s ]\n", clk_res ,
  1457. oemval2str( ((clk_res>>6)&0x03), (clk_res&0x0F),
  1458. picmg_clk_resource_vals));
  1459. } else {
  1460. printf("CLK resource id : N/A [ AMC Module ]\n");
  1461. clk_res = 0x40; /* Set */
  1462. }
  1463. printf("CLK id : %3d [ %s ]\n", clk_id,
  1464. oemval2str( ((clk_res>>6)&0x03), clk_id ,
  1465. picmg_clk_id_vals));
  1466. printf("CLK setting : 0x%02x\n", rsp->data[1]);
  1467. printf(" - state: %s\n", (enabled)?"enabled":"disabled");
  1468. printf(" - direction: %s\n", (direction)?"Source":"Receiver");
  1469. printf(" - PLL ctrl: 0x%x\n", rsp->data[1]&0x3);
  1470. if(enabled){
  1471. unsigned long freq = 0;
  1472. freq = ( rsp->data[5] << 0
  1473. | rsp->data[6] << 8
  1474. | rsp->data[7] << 16
  1475. | rsp->data[8] << 24 );
  1476. printf(" - Index: %3d\n", rsp->data[2]);
  1477. printf(" - Family: %3d [ %s ] \n", rsp->data[3],
  1478. val2str( rsp->data[3], picmg_clk_family_vals));
  1479. printf(" - AccLVL: %3d [ %s ] \n", rsp->data[4],
  1480. oemval2str( rsp->data[3], rsp->data[4],
  1481. picmg_clk_accuracy_vals));
  1482. printf(" - Freq: %ld\n", freq);
  1483. }
  1484. }
  1485. }
  1486. return 0;
  1487. }
  1488. int
  1489. ipmi_picmg_clk_set(struct ipmi_intf * intf, int argc, char ** argv)
  1490. {
  1491. struct ipmi_rs * rsp;
  1492. struct ipmi_rq req;
  1493. unsigned char msg_data[11] = {0};
  1494. uint32_t freq = 0;
  1495. memset(&req, 0, sizeof(req));
  1496. req.msg.netfn = IPMI_NETFN_PICMG;
  1497. req.msg.cmd = PICMG_AMC_SET_CLK_STATE_CMD;
  1498. req.msg.data = msg_data;
  1499. msg_data[0] = 0x00; /* PICMG identifier */
  1500. if (is_clk_id(argv[0], &msg_data[1]) != 0
  1501. || is_clk_index(argv[1], &msg_data[2]) != 0
  1502. || is_clk_setting(argv[2], &msg_data[3]) != 0
  1503. || is_clk_family(argv[3], &msg_data[4]) != 0
  1504. || is_clk_acc(argv[4], &msg_data[5]) != 0
  1505. || is_clk_freq(argv[5], &freq) != 0) {
  1506. return (-1);
  1507. }
  1508. msg_data[6] = (freq >> 0)& 0xFF; /* freq */
  1509. msg_data[7] = (freq >> 8)& 0xFF; /* freq */
  1510. msg_data[8] = (freq >>16)& 0xFF; /* freq */
  1511. msg_data[9] = (freq >>24)& 0xFF; /* freq */
  1512. req.msg.data_len = 10;
  1513. if( PicmgCardType == PICMG_CARD_TYPE_ATCA )
  1514. {
  1515. if( argc > 7)
  1516. {
  1517. req.msg.data_len = 11;
  1518. if (is_clk_resid(argv[6], &msg_data[10]) != 0) {
  1519. return (-1);
  1520. }
  1521. }
  1522. else
  1523. {
  1524. lprintf(LOG_ERR, "Missing resource id for atca board.");
  1525. return -1;
  1526. }
  1527. }
  1528. rsp = intf->sendrecv(intf, &req);
  1529. if (!rsp) {
  1530. lprintf(LOG_ERR, "No valid response received.");
  1531. return -1;
  1532. }
  1533. if (rsp->ccode) {
  1534. lprintf(LOG_ERR, "Clk set failed with CC code 0x%02x", rsp->ccode);
  1535. return -1;
  1536. }
  1537. return 0;
  1538. }
  1539. int
  1540. ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv)
  1541. {
  1542. int rc = 0;
  1543. int showProperties = 0;
  1544. if (argc == 0 || (!strncmp(argv[0], "help", 4))) {
  1545. ipmi_picmg_help();
  1546. return 0;
  1547. }
  1548. /* Get PICMG properties is called to obtain version information */
  1549. if (argc !=0 && !strncmp(argv[0], "properties", 10)) {
  1550. showProperties =1;
  1551. }
  1552. rc = ipmi_picmg_properties(intf,showProperties);
  1553. /* address info command */
  1554. if (!strncmp(argv[0], "addrinfo", 8)) {
  1555. rc = ipmi_picmg_getaddr(intf, argc-1, &argv[1]);
  1556. }
  1557. else if (!strncmp(argv[0], "busres", 6)) {
  1558. if (argc > 1) {
  1559. if (!strncmp(argv[1], "summary", 7)) {
  1560. ipmi_picmg_bused_resource(intf, PICMG_BUSED_RESOURCE_SUMMARY );
  1561. }
  1562. } else {
  1563. lprintf(LOG_NOTICE, "usage: busres summary");
  1564. }
  1565. }
  1566. /* fru control command */
  1567. else if (!strncmp(argv[0], "frucontrol", 10)) {
  1568. if (argc > 2) {
  1569. rc = ipmi_picmg_fru_control(intf, argc-1, &(argv[1]));
  1570. }
  1571. else {
  1572. lprintf(LOG_NOTICE, "usage: frucontrol <FRU-ID> <OPTION>");
  1573. lprintf(LOG_NOTICE, " OPTION:");
  1574. lprintf(LOG_NOTICE, " 0 - Cold Reset");
  1575. lprintf(LOG_NOTICE, " 1 - Warm Reset");
  1576. lprintf(LOG_NOTICE, " 2 - Graceful Reboot");
  1577. lprintf(LOG_NOTICE, " 3 - Issue Diagnostic Interrupt");
  1578. lprintf(LOG_NOTICE, " 4 - Quiesce [AMC only]");
  1579. lprintf(LOG_NOTICE, " 5-255 - Reserved");
  1580. return -1;
  1581. }
  1582. }
  1583. /* fru activation command */
  1584. else if (!strncmp(argv[0], "activate", 8)) {
  1585. if (argc > 1) {
  1586. rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_ACTIVATE);
  1587. }
  1588. else {
  1589. lprintf(LOG_ERR, "Specify the FRU to activate.");
  1590. return -1;
  1591. }
  1592. }
  1593. /* fru deactivation command */
  1594. else if (!strncmp(argv[0], "deactivate", 10)) {
  1595. if (argc > 1) {
  1596. rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_DEACTIVATE);
  1597. }else {
  1598. lprintf(LOG_ERR, "Specify the FRU to deactivate.");
  1599. return -1;
  1600. }
  1601. }
  1602. /* activation policy command */
  1603. else if (!strncmp(argv[0], "policy", 6)) {
  1604. if (argc > 1) {
  1605. if (!strncmp(argv[1], "get", 3)) {
  1606. if (argc > 2) {
  1607. rc = ipmi_picmg_fru_activation_policy_get(intf, argc-1, &(argv[2]));
  1608. } else {
  1609. lprintf(LOG_NOTICE, "usage: get <fruid>");
  1610. }
  1611. } else if (!strncmp(argv[1], "set", 3)) {
  1612. if (argc > 4) {
  1613. rc = ipmi_picmg_fru_activation_policy_set(intf, argc-1, &(argv[2]));
  1614. } else {
  1615. lprintf(LOG_NOTICE, "usage: set <fruid> <lockmask> <lock>");
  1616. lprintf(LOG_NOTICE,
  1617. " lockmask: [1] affect the deactivation locked bit");
  1618. lprintf(LOG_NOTICE,
  1619. " [0] affect the activation locked bit");
  1620. lprintf(LOG_NOTICE,
  1621. " lock: [1] set/clear deactivation locked");
  1622. lprintf(LOG_NOTICE, " [0] set/clear locked");
  1623. }
  1624. }
  1625. else {
  1626. lprintf(LOG_ERR, "Specify FRU.");
  1627. return -1;
  1628. }
  1629. } else {
  1630. lprintf(LOG_ERR, "Wrong parameters.");
  1631. return -1;
  1632. }
  1633. }
  1634. /* portstate command */
  1635. else if (!strncmp(argv[0], "portstate", 9)) {
  1636. lprintf(LOG_DEBUG,"PICMG: portstate API");
  1637. if (argc > 1) {
  1638. if (!strncmp(argv[1], "get", 3)) {
  1639. int32_t iface;
  1640. uint8_t channel = 0;
  1641. lprintf(LOG_DEBUG,"PICMG: get");
  1642. if(!strncmp(argv[1], "getall", 6)) {
  1643. for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++) {
  1644. for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++) {
  1645. if(!(( iface == FRU_PICMGEXT_DESIGN_IF_FABRIC ) &&
  1646. ( channel > PICMG_EKEY_MAX_FABRIC_CHANNEL ) ))
  1647. {
  1648. rc = ipmi_picmg_portstate_get(intf,iface,channel,
  1649. PICMG_EKEY_MODE_PRINT_ALL);
  1650. }
  1651. }
  1652. }
  1653. }
  1654. else if(!strncmp(argv[1], "getgranted", 10)) {
  1655. for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++) {
  1656. for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++) {
  1657. rc = ipmi_picmg_portstate_get(intf,iface,channel,
  1658. PICMG_EKEY_MODE_PRINT_ENABLED);
  1659. }
  1660. }
  1661. }
  1662. else if(!strncmp(argv[1], "getdenied", 9)){
  1663. for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++) {
  1664. for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++) {
  1665. rc = ipmi_picmg_portstate_get(intf,iface,channel,
  1666. PICMG_EKEY_MODE_PRINT_DISABLED);
  1667. }
  1668. }
  1669. }
  1670. else if (argc > 3){
  1671. if (is_amc_intf(argv[2], &iface) != 0
  1672. || is_amc_channel(argv[3], &channel) != 0) {
  1673. return (-1);
  1674. }
  1675. lprintf(LOG_DEBUG,"PICMG: requesting interface %d",iface);
  1676. lprintf(LOG_DEBUG,"PICMG: requesting channel %d",channel);
  1677. rc = ipmi_picmg_portstate_get(intf,iface,channel,
  1678. PICMG_EKEY_MODE_QUERY );
  1679. }
  1680. else {
  1681. lprintf(LOG_NOTICE, "<intf> <chn>|getall|getgranted|getdenied");
  1682. }
  1683. }
  1684. else if (!strncmp(argv[1], "set", 3)) {
  1685. if (argc == 9) {
  1686. int32_t interface = 0;
  1687. int32_t port = 0;
  1688. uint8_t channel = 0;
  1689. uint8_t enable = 0;
  1690. uint8_t group = 0;
  1691. uint8_t type = 0;
  1692. uint8_t typeext = 0;
  1693. if (is_amc_intf(argv[2], &interface) != 0
  1694. || is_amc_channel(argv[3], &channel) != 0
  1695. || is_amc_port(argv[4], &port) != 0
  1696. || is_link_type(argv[5], &type) != 0
  1697. || is_link_type_ext(argv[6], &typeext) != 0
  1698. || is_link_group(argv[7], &group) != 0
  1699. || is_enable(argv[8], &enable) != 0) {
  1700. return (-1);
  1701. }
  1702. lprintf(LOG_DEBUG,"PICMG: interface %d",interface);
  1703. lprintf(LOG_DEBUG,"PICMG: channel %d",channel);
  1704. lprintf(LOG_DEBUG,"PICMG: port %d",port);
  1705. lprintf(LOG_DEBUG,"PICMG: type %d",type);
  1706. lprintf(LOG_DEBUG,"PICMG: typeext %d",typeext);
  1707. lprintf(LOG_DEBUG,"PICMG: group %d",group);
  1708. lprintf(LOG_DEBUG,"PICMG: enable %d",enable);
  1709. rc = ipmi_picmg_portstate_set(intf, interface,
  1710. channel, port, type, typeext ,group ,enable);
  1711. }
  1712. else {
  1713. lprintf(LOG_NOTICE,
  1714. "<intf> <chn> <port> <type> <ext> <group> <1|0>");
  1715. return -1;
  1716. }
  1717. }
  1718. }
  1719. else {
  1720. lprintf(LOG_NOTICE, "<set>|<getall>|<getgranted>|<getdenied>");
  1721. return -1;
  1722. }
  1723. }
  1724. /* amc portstate command */
  1725. else if (!strncmp(argv[0], "amcportstate", 12)) {
  1726. lprintf(LOG_DEBUG,"PICMG: amcportstate API");
  1727. if (argc > 1) {
  1728. if (!strncmp(argv[1], "get", 3)){
  1729. int32_t device;
  1730. uint8_t channel;
  1731. lprintf(LOG_DEBUG,"PICMG: get");
  1732. if(!strncmp(argv[1], "getall", 6)){
  1733. int maxDevice = PICMG_EKEY_AMC_MAX_DEVICE;
  1734. if( PicmgCardType != PICMG_CARD_TYPE_ATCA ){
  1735. maxDevice = 0;
  1736. }
  1737. for(device=0;device<=maxDevice;device++){
  1738. for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){
  1739. rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
  1740. PICMG_EKEY_MODE_PRINT_ALL);
  1741. }
  1742. }
  1743. }
  1744. else if(!strncmp(argv[1], "getgranted", 10)){
  1745. int maxDevice = PICMG_EKEY_AMC_MAX_DEVICE;
  1746. if( PicmgCardType != PICMG_CARD_TYPE_ATCA ){
  1747. maxDevice = 0;
  1748. }
  1749. for(device=0;device<=maxDevice;device++){
  1750. for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){
  1751. rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
  1752. PICMG_EKEY_MODE_PRINT_ENABLED);
  1753. }
  1754. }
  1755. }
  1756. else if(!strncmp(argv[1], "getdenied", 9)){
  1757. int maxDevice = PICMG_EKEY_AMC_MAX_DEVICE;
  1758. if( PicmgCardType != PICMG_CARD_TYPE_ATCA ){
  1759. maxDevice = 0;
  1760. }
  1761. for(device=0;device<=maxDevice;device++){
  1762. for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){
  1763. rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
  1764. PICMG_EKEY_MODE_PRINT_DISABLED);
  1765. }
  1766. }
  1767. }
  1768. else if (argc > 2){
  1769. if (is_amc_channel(argv[2], &channel) != 0) {
  1770. return (-1);
  1771. }
  1772. if (argc > 3){
  1773. if (is_amc_dev(argv[3], &device) != 0) {
  1774. return (-1);
  1775. }
  1776. }else{
  1777. device = -1;
  1778. }
  1779. lprintf(LOG_DEBUG,"PICMG: requesting device %d",device);
  1780. lprintf(LOG_DEBUG,"PICMG: requesting channel %d",channel);
  1781. rc = ipmi_picmg_amc_portstate_get(intf,device,channel,
  1782. PICMG_EKEY_MODE_QUERY );
  1783. }
  1784. else {
  1785. lprintf(LOG_NOTICE, "<chn> <device>|getall|getgranted|getdenied");
  1786. }
  1787. }
  1788. else if (!strncmp(argv[1], "set", 3)) {
  1789. if (argc > 7) {
  1790. int32_t device = -1;
  1791. int32_t port = 0;
  1792. uint8_t channel = 0;
  1793. uint8_t enable = 0;
  1794. uint8_t group = 0;
  1795. uint8_t type = 0;
  1796. uint8_t typeext = 0;
  1797. if (is_amc_channel(argv[2], &channel) != 0
  1798. || is_amc_port(argv[3], &port) != 0
  1799. || is_link_type(argv[4], &type) !=0
  1800. || is_link_type_ext(argv[5], &typeext) != 0
  1801. || is_link_group(argv[6], &group) != 0
  1802. || is_enable(argv[7], &enable) != 0) {
  1803. return (-1);
  1804. }
  1805. if(argc > 8){
  1806. if (is_amc_dev(argv[8], &device) != 0) {
  1807. return (-1);
  1808. }
  1809. }
  1810. lprintf(LOG_DEBUG,"PICMG: channel %d",channel);
  1811. lprintf(LOG_DEBUG,"PICMG: portflags %d",port);
  1812. lprintf(LOG_DEBUG,"PICMG: type %d",type);
  1813. lprintf(LOG_DEBUG,"PICMG: typeext %d",typeext);
  1814. lprintf(LOG_DEBUG,"PICMG: group %d",group);
  1815. lprintf(LOG_DEBUG,"PICMG: enable %d",enable);
  1816. lprintf(LOG_DEBUG,"PICMG: device %d",device);
  1817. rc = ipmi_picmg_amc_portstate_set(intf, channel, port, type,
  1818. typeext, group, enable, device);
  1819. }
  1820. else {
  1821. lprintf(LOG_NOTICE,
  1822. "<chn> <portflags> <type> <ext> <group> <1|0> [<device>]");
  1823. return -1;
  1824. }
  1825. }
  1826. }
  1827. else {
  1828. lprintf(LOG_NOTICE, "<set>|<get>|<getall>|<getgranted>|<getdenied>");
  1829. return -1;
  1830. }
  1831. }
  1832. /* ATCA led commands */
  1833. else if (!strncmp(argv[0], "led", 3)) {
  1834. if (argc > 1) {
  1835. if (!strncmp(argv[1], "prop", 4)) {
  1836. if (argc > 2) {
  1837. rc = ipmi_picmg_get_led_properties(intf, argc-1, &(argv[2]));
  1838. }
  1839. else {
  1840. lprintf(LOG_NOTICE, "led prop <FRU-ID>");
  1841. }
  1842. }
  1843. else if (!strncmp(argv[1], "cap", 3)) {
  1844. if (argc > 3) {
  1845. rc = ipmi_picmg_get_led_capabilities(intf, argc-1, &(argv[2]));
  1846. }
  1847. else {
  1848. lprintf(LOG_NOTICE, "led cap <FRU-ID> <LED-ID>");
  1849. }
  1850. }
  1851. else if (!strncmp(argv[1], "get", 3)) {
  1852. if (argc > 3) {
  1853. rc = ipmi_picmg_get_led_state(intf, argc-1, &(argv[2]));
  1854. }
  1855. else {
  1856. lprintf(LOG_NOTICE, "led get <FRU-ID> <LED-ID>");
  1857. }
  1858. }
  1859. else if (!strncmp(argv[1], "set", 3)) {
  1860. if (argc > 6) {
  1861. rc = ipmi_picmg_set_led_state(intf, argc-1, &(argv[2]));
  1862. }
  1863. else {
  1864. lprintf(LOG_NOTICE,
  1865. "led set <FRU-ID> <LED-ID> <function> <duration> <color>");
  1866. lprintf(LOG_NOTICE, " <FRU-ID>");
  1867. lprintf(LOG_NOTICE, " <LED-ID> 0: Blue LED");
  1868. lprintf(LOG_NOTICE, " 1: LED 1");
  1869. lprintf(LOG_NOTICE, " 2: LED 2");
  1870. lprintf(LOG_NOTICE, " 3: LED 3");
  1871. lprintf(LOG_NOTICE, " 0x04-0xFE: OEM defined");
  1872. lprintf(LOG_NOTICE,
  1873. " 0xFF: All LEDs under management control");
  1874. lprintf(LOG_NOTICE, " <function> 0: LED OFF override");
  1875. lprintf(LOG_NOTICE,
  1876. " 1 - 250: LED blinking override (off duration)");
  1877. lprintf(LOG_NOTICE, " 251: LED Lamp Test");
  1878. lprintf(LOG_NOTICE,
  1879. " 252: LED restore to local control");
  1880. lprintf(LOG_NOTICE, " 255: LED ON override");
  1881. lprintf(LOG_NOTICE, " <duration> 0 - 127: LED Lamp Test duration");
  1882. lprintf(LOG_NOTICE, " 0 - 255: LED Lamp ON duration");
  1883. lprintf(LOG_NOTICE, " <color> 0: reserved");
  1884. lprintf(LOG_NOTICE, " 1: BLUE");
  1885. lprintf(LOG_NOTICE, " 2: RED");
  1886. lprintf(LOG_NOTICE, " 3: GREEN");
  1887. lprintf(LOG_NOTICE, " 4: AMBER");
  1888. lprintf(LOG_NOTICE, " 5: ORANGE");
  1889. lprintf(LOG_NOTICE, " 6: WHITE");
  1890. lprintf(LOG_NOTICE, " 7: reserved");
  1891. lprintf(LOG_NOTICE, " 0xE: do not change");
  1892. lprintf(LOG_NOTICE, " 0xF: use default color");
  1893. }
  1894. }
  1895. else {
  1896. lprintf(LOG_NOTICE, "prop | cap | get | set");
  1897. }
  1898. }
  1899. }
  1900. /* power commands */
  1901. else if (!strncmp(argv[0], "power", 5)) {
  1902. if (argc > 1) {
  1903. if (!strncmp(argv[1], "get", 3)) {
  1904. if (argc > 3) {
  1905. rc = ipmi_picmg_get_power_level(intf, argc-1, &(argv[2]));
  1906. }
  1907. else {
  1908. lprintf(LOG_NOTICE, "power get <FRU-ID> <type>");
  1909. lprintf(LOG_NOTICE, " <type> 0 : steady state power draw levels");
  1910. lprintf(LOG_NOTICE,
  1911. " 1 : desired steady state draw levels");
  1912. lprintf(LOG_NOTICE, " 2 : early power draw levels");
  1913. lprintf(LOG_NOTICE, " 3 : desired early levels");
  1914. return -1;
  1915. }
  1916. }
  1917. else if (!strncmp(argv[1], "set", 3)) {
  1918. if (argc > 4) {
  1919. rc = ipmi_picmg_set_power_level(intf, argc-1, &(argv[2]));
  1920. }
  1921. else {
  1922. lprintf(LOG_NOTICE, "power set <FRU-ID> <level> <present-desired>");
  1923. lprintf(LOG_NOTICE, " <level> 0 : Power Off");
  1924. lprintf(LOG_NOTICE, " 0x1-0x14 : Power level");
  1925. lprintf(LOG_NOTICE, " 0xFF : do not change");
  1926. lprintf(LOG_NOTICE,
  1927. "\n <present-desired> 0: do not change present levels");
  1928. lprintf(LOG_NOTICE,
  1929. " 1: copy desired to present level");
  1930. return -1;
  1931. }
  1932. }
  1933. else {
  1934. lprintf(LOG_NOTICE, "<set>|<get>");
  1935. return -1;
  1936. }
  1937. }
  1938. else {
  1939. lprintf(LOG_NOTICE, "<set>|<get>");
  1940. return -1;
  1941. }
  1942. }/* clk commands*/
  1943. else if (!strncmp(argv[0], "clk", 3)) {
  1944. if (argc > 1) {
  1945. if (!strncmp(argv[1], "get", 3)) {
  1946. int8_t clk_res = -1;
  1947. uint8_t clk_id;
  1948. uint8_t max_res = 15;
  1949. if( PicmgCardType == PICMG_CARD_TYPE_AMC ) {
  1950. max_res = 0;
  1951. }
  1952. if(!strncmp(argv[1], "getall", 6)) {
  1953. if( verbose ) { printf("Getting all clock state\n") ;}
  1954. for(clk_res=0;clk_res<=max_res;clk_res++) {
  1955. for(clk_id=0;clk_id<=15;clk_id++) {
  1956. rc = ipmi_picmg_clk_get(intf,clk_id,clk_res,
  1957. PICMG_EKEY_MODE_PRINT_ALL);
  1958. }
  1959. }
  1960. }
  1961. else if(!strncmp(argv[1], "getdenied", 6)) {
  1962. if( verbose ) { printf("Getting disabled clocks\n") ;}
  1963. for(clk_res=0;clk_res<=max_res;clk_res++) {
  1964. for(clk_id=0;clk_id<=15;clk_id++) {
  1965. rc = ipmi_picmg_clk_get(intf,clk_id,clk_res,
  1966. PICMG_EKEY_MODE_PRINT_DISABLED);
  1967. }
  1968. }
  1969. }
  1970. else if(!strncmp(argv[1], "getgranted", 6)) {
  1971. if( verbose ) { printf("Getting enabled clocks\n") ;}
  1972. for(clk_res=0;clk_res<=max_res;clk_res++) {
  1973. for(clk_id=0;clk_id<=15;clk_id++) {
  1974. rc = ipmi_picmg_clk_get(intf,clk_id,clk_res,
  1975. PICMG_EKEY_MODE_PRINT_ENABLED);
  1976. }
  1977. }
  1978. }
  1979. else if (argc > 2) {
  1980. if (is_clk_id(argv[2], &clk_id) != 0) {
  1981. return (-1);
  1982. }
  1983. if (argc > 3) {
  1984. if (is_clk_resid(argv[3], &clk_res) != 0) {
  1985. return (-1);
  1986. }
  1987. }
  1988. rc = ipmi_picmg_clk_get(intf, clk_id, clk_res,
  1989. PICMG_EKEY_MODE_QUERY );
  1990. }
  1991. else {
  1992. lprintf(LOG_NOTICE, "clk get");
  1993. lprintf(LOG_NOTICE,
  1994. "<CLK-ID> [<DEV-ID>] |getall|getgranted|getdenied");
  1995. return -1;
  1996. }
  1997. }
  1998. else if (!strncmp(argv[1], "set", 3)) {
  1999. if (argc > 7) {
  2000. rc = ipmi_picmg_clk_set(intf, argc-1, &(argv[2]));
  2001. }
  2002. else {
  2003. lprintf(LOG_NOTICE,
  2004. "clk set <CLK-ID> <index> <setting> <family> <acc-lvl> <freq> [<DEV-ID>]");
  2005. return -1;
  2006. }
  2007. }
  2008. else {
  2009. lprintf(LOG_NOTICE, "<set>|<get>|<getall>|<getgranted>|<getdenied>");
  2010. return -1;
  2011. }
  2012. }
  2013. else {
  2014. lprintf(LOG_NOTICE, "<set>|<get>|<getall>|<getgranted>|<getdenied>");
  2015. return -1;
  2016. }
  2017. }
  2018. else if(showProperties == 0 ){
  2019. ipmi_picmg_help();
  2020. return -1;
  2021. }
  2022. return rc;
  2023. }
  2024. uint8_t
  2025. ipmi_picmg_ipmb_address(struct ipmi_intf *intf) {
  2026. struct ipmi_rq req;
  2027. struct ipmi_rs *rsp;
  2028. uint8_t msg_data;
  2029. if (!intf->picmg_avail) {
  2030. return 0;
  2031. }
  2032. memset(&req, 0, sizeof(req));
  2033. req.msg.netfn = IPMI_NETFN_PICMG;
  2034. req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD;
  2035. msg_data = 0x00;
  2036. req.msg.data = &msg_data;
  2037. req.msg.data_len = 1;
  2038. msg_data = 0;
  2039. rsp = intf->sendrecv(intf, &req);
  2040. if (rsp && !rsp->ccode) {
  2041. return rsp->data[2];
  2042. }
  2043. if (rsp) {
  2044. lprintf(LOG_DEBUG, "Get Address Info failed: %#x %s",
  2045. rsp->ccode, val2str(rsp->ccode, completion_code_vals));
  2046. } else {
  2047. lprintf(LOG_DEBUG, "Get Address Info failed: No Response");
  2048. }
  2049. return 0;
  2050. }
  2051. uint8_t
  2052. picmg_discover(struct ipmi_intf *intf) {
  2053. /* Check if PICMG extension is available to use the function
  2054. * GetDeviceLocator to retreive i2c address PICMG hack to set
  2055. * right IPMB address, If extension is not supported, should
  2056. * not give any problems
  2057. * PICMG Extension Version 2.0 (PICMG 3.0 Revision 1.0 ATCA) to
  2058. * PICMG Extension Version 2.3 (PICMG 3.0 Revision 3.0 ATCA)
  2059. * PICMG Extension Version 4.1 (PICMG 3.0 Revision 3.0 AMC)
  2060. * PICMG Extension Version 5.0 (MTCA.0 R1.0)
  2061. */
  2062. /* First, check if PICMG extension is available and supported */
  2063. struct ipmi_rq req;
  2064. struct ipmi_rs *rsp;
  2065. uint8_t msg_data;
  2066. uint8_t picmg_avail = 0;
  2067. memset(&req, 0, sizeof(req));
  2068. req.msg.netfn = IPMI_NETFN_PICMG;
  2069. req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
  2070. msg_data = 0x00;
  2071. req.msg.data = &msg_data;
  2072. req.msg.data_len = 1;
  2073. msg_data = 0;
  2074. lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
  2075. intf->my_addr, intf->transit_addr, intf->target_addr);
  2076. rsp = intf->sendrecv(intf, &req);
  2077. if (rsp == NULL) {
  2078. lprintf(LOG_INFO,"No response from Get PICMG Properties");
  2079. } else if (rsp->ccode != 0) {
  2080. lprintf(LOG_INFO,"Error response %#x from Get PICMG Properities",
  2081. rsp->ccode);
  2082. } else if (rsp->data_len < 4) {
  2083. lprintf(LOG_INFO,"Invalid Get PICMG Properties response length %d",
  2084. rsp->data_len);
  2085. } else if (rsp->data[0] != 0) {
  2086. lprintf(LOG_INFO,"Invalid Get PICMG Properties group extension %#x",
  2087. rsp->data[0]);
  2088. } else if ((rsp->data[1] & 0x0F) != PICMG_EXTENSION_ATCA_MAJOR_VERSION
  2089. && (rsp->data[1] & 0x0F) != PICMG_EXTENSION_AMC0_MAJOR_VERSION
  2090. && (rsp->data[1] & 0x0F) != PICMG_EXTENSION_UTCA_MAJOR_VERSION) {
  2091. lprintf(LOG_INFO,"Unknown PICMG Extension Version %d.%d",
  2092. (rsp->data[1] & 0x0F), (rsp->data[1] >> 4));
  2093. } else {
  2094. picmg_avail = 1;
  2095. lprintf(LOG_INFO, "Discovered PICMG Extension Version %d.%d",
  2096. (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
  2097. }
  2098. return picmg_avail;
  2099. }