diff --git a/SOURCES/cxoem-jb-cx6.patch b/SOURCES/cxoem-jb-cx6.patch
deleted file mode 100644
index 12c6e6b..0000000
--- a/SOURCES/cxoem-jb-cx6.patch
+++ /dev/null
@@ -1,4759 +0,0 @@
-commit 194d20c909c93874583db20fbf1e0739a8f8c7e0
-Author: Ales Ledvinka <aledvink@redhat.com>
-Date:   Thu Jul 25 12:29:08 2013 +0200
-
-    Jeff's bugzilla cx6 patch
-
-diff --git a/include/ipmitool/Makefile.am b/include/ipmitool/Makefile.am
-index fb6f6bf..83bc76f 100644
---- a/include/ipmitool/Makefile.am
-+++ b/include/ipmitool/Makefile.am
-@@ -38,5 +38,5 @@ noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_cc.h ipmi_intf.h \
- 	ipmi_oem.h ipmi_sdradd.h ipmi_isol.h ipmi_sunoem.h ipmi_picmg.h \
- 	ipmi_fwum.h ipmi_main.h ipmi_tsol.h ipmi_firewall.h \
- 	ipmi_kontronoem.h ipmi_ekanalyzer.h ipmi_gendev.h ipmi_ime.h \
--	ipmi_delloem.h ipmi_dcmi.h
-+	ipmi_delloem.h ipmi_dcmi.h ipmi_cxoem.h
- 
-diff --git a/include/ipmitool/ipmi.h b/include/ipmitool/ipmi.h
-index e74c252..759417c 100644
---- a/include/ipmitool/ipmi.h
-+++ b/include/ipmitool/ipmi.h
-@@ -245,6 +245,7 @@ struct ipmi_rs {
- #define IPMI_NETFN_OEM		0x2E
- #define IPMI_NETFN_ISOL			0x34
- #define IPMI_NETFN_TSOL			0x30
-+#define IPMI_NETFN_CX_OEM		0x3e
- 
- #define IPMI_BMC_SLAVE_ADDR		0x20
- #define IPMI_REMOTE_SWID		0x81
-diff --git a/include/ipmitool/ipmi_constants.h b/include/ipmitool/ipmi_constants.h
-index 2aad2cf..d316c61 100644
---- a/include/ipmitool/ipmi_constants.h
-+++ b/include/ipmitool/ipmi_constants.h
-@@ -114,6 +114,8 @@
- #define IPMI_CHASSIS_BOOTPARAM_INIT_INFO	6
- #define IPMI_CHASSIS_BOOTPARAM_INIT_MBOX	7
- 
-+#define IPMI_CHASSIS_BOOTPARAM_OEM_BOOT_POLICY	96 // Calxeda OEM boot param
-+
- /* From table 13-17 of the IPMI v2 specification */
- #define IPMI_AUTH_RAKP_NONE         0x00
- #define IPMI_AUTH_RAKP_HMAC_SHA1    0x01
-diff --git a/include/ipmitool/ipmi_cxoem.h b/include/ipmitool/ipmi_cxoem.h
-new file mode 100644
-index 0000000..9a01f85
---- /dev/null
-+++ b/include/ipmitool/ipmi_cxoem.h
-@@ -0,0 +1,209 @@
-+/*
-+ * Copyright (c) 2011 Calxeda, Inc.  All Rights Reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * Redistribution of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * Redistribution in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * Neither the name of Calxeda, Inc. or the names of
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * This software is provided "AS IS," without a warranty of any kind.
-+ */
-+
-+#ifndef IPMI_CXOEM_H
-+#define IPMI_CXOEM_H
-+
-+#if HAVE_CONFIG_H
-+#include <config.h>
-+#endif
-+#include <ipmitool/ipmi.h>
-+#include <ipmitool/ipmi_sdr.h>
-+
-+#define CX_VERSION				"-cx6"
-+#define IPMI_NETFN_OEM_SS		0x3e
-+
-+/*
-+ * CX IPMI OEM command ids
-+ */
-+#define MSG_ELEMENT_TERMINATOR  0xff
-+#define MSG_PARAM_VAL_START_SCALAR  	0xf0
-+#define MSG_PARAM_VAL_START_STRING  	0xf1
-+#define MSG_PARAM_VAL_START_IPV4_ADDR  	0xf2
-+#define MSG_PARAM_VAL_START_MAC_ADDR  	0xf3
-+#define MSG_PARAM_VAL_START_BITMAP  	0xf4
-+
-+#define IPMI_CMD_OEM_GET_DEVICE_INFO                0x01
-+#define IPMI_CMD_OEM_FEATURES_ENABLE                0xD0
-+#define IPMI_CMD_OEM_FW_DOWNLOAD                    0xE0
-+#define IPMI_CMD_OEM_FW_GET_STATUS                  0xE1
-+#define IPMI_CMD_OEM_FW_SET_STATUS                  0xE2
-+#define IPMI_CMD_OEM_FW_RAW                         0xE3
-+#define IPMI_CMD_OEM_FABRIC_GET                     0xE4
-+#define IPMI_CMD_OEM_FABRIC_SET                     0xE5
-+#define IPMI_CMD_OEM_FABRIC_CONFIG_GET				0xE6
-+#define IPMI_CMD_OEM_FABRIC_CONFIG_SET				0xE7
-+#define IPMI_CMD_OEM_FABRIC_UPDATE_CONFIG           0xE8
-+#define IPMI_CMD_OEM_FW_RESET                       0xE9
-+#define IPMI_CMD_OEM_DATA_ACCESS                    0xEA
-+#define IPMI_CMD_OEM_FABRIC_ADD						0xEB
-+#define IPMI_CMD_OEM_FABRIC_RM						0xEC
-+#define IPMI_CMD_OEM_TEST                           0xED
-+#define IPMI_CMD_OEM_FABRIC_INFO					0xEE
-+#define IPMI_CMD_OEM_FABRIC_SET_WATCH				0xEF
-+#define IPMI_CMD_OEM_FABRIC_CLEAR_WATCH				0xF0
-+#define IPMI_CMD_OEM_FABRIC_FACTORY_DEFAULT         0xF1
-+#define IPMI_CMD_OEM_FABRIC_CREATE					0xF2
-+#define IPMI_CMD_OEM_FABRIC_DELETE					0xF3
-+#define IPMI_CMD_OEM_FABRIC_TRACE					0xF4
-+
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR        		0x01
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_NETMASK       		0x02
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_DEFGW         		0x03
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_IPSRC         		0x04
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDR       		0x05
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_IPINFO        		0x06
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_MTU           		0x07
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_MODE   		0x08
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDRS      		0x09
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_NODEID      			0x0A
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED    			0x0B
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK    			0x0C
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINKMAP    			0x0D
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_DEPTH_CHART  			0x0E
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_ROUTING_TABLE			0x0F
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_STATS			0x10
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_STATS				0x11
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_STATS			0x12
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_CHANNEL_STATS		0x13
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_GLOBAL_WATCH			0x14
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_WATCH				0x15
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_CHANNEL_WATCH		0x16
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_WATCH			0x17
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_WATCH			0x18
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_SERVER			0x19
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_PORT				0x1A
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_RESILIENCE		0x1B
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_NODENUM_OFFSET		0x1C
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED_POLICY		0x1D
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS			0x1E
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_CONFIGURATIONID		0x1F
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITIONID			0x20
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_NODES		0x21
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_RANGE		0x22
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_PROFILEID				0x23
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_BASE			0x24
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_NUM			0x25
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_CUSTOMER_MACADDR		0x26
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS_FACTOR		0x27
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_INFO			0x28
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_START					0x29
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_STOP					0x2a
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_STATUS				0x2b
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_DUMP					0x2c
-+#define IPMI_CMD_OEM_FABRIC_PARAMETER_LACP_STATUS			0x2d
-+
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_NODE          0x40
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE     0x41
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP          0x42
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT          0x43
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME      0x44
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK			0x45
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_OVERRIDE    	0x46
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC 	   		0x47
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_HOST 	   		0x48
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_FREQUENCY  	0x49
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_ACTUAL  		0x50
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_AVERAGING_FREQUENCY  	0x51
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION 0x52
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION 	0x53
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_PROFILE 		0x54
-+#define IPMI_CMD_OEM_FABRIC_SPECIFIER_SIZE	 		0x55
-+
-+/*
-+ * CX-defined constants
-+ */
-+#define CXOEM_FW_DOWNLOAD       1
-+#define CXOEM_FW_STOP           2
-+#define CXOEM_FW_UPLOAD         3
-+#define CXOEM_FW_REGISTER_READ  4
-+#define CXOEM_FW_REGISTER_WRITE 5
-+
-+
-+static const int CXOEM_SUCCESS = 0;
-+static const int CXOEM_ERROR = -1;
-+
-+
-+/*
-+ * OEM FW rq/rs structs
-+ */
-+
-+typedef struct img_info_s {
-+	unsigned char id;
-+	unsigned char type;
-+	uint32_t img_addr;
-+	uint32_t img_size;
-+	uint32_t in_use;
-+} __attribute__ ((packed)) img_info_t;
-+
-+typedef struct simg_header_s {
-+	unsigned char magic[4];
-+	uint16_t hdrfmt;
-+	uint16_t priority;
-+	uint32_t imgoff;
-+	uint32_t imglen;
-+	uint32_t daddr;
-+	uint32_t flags;
-+	uint32_t crc32;
-+	unsigned char version[32];
-+} __attribute__ ((packed)) simg_header_t;
-+
-+struct cx_fw_info_rs {
-+	unsigned char ver;	/* param version */
-+	unsigned char count;	/* number of bytes */
-+	img_info_t img_info;
-+} __attribute__ ((packed));
-+
-+
-+/*
-+ * OEM info rs structs
-+ */
-+
-+typedef union cx_info_basic_u {
-+	/* Revision 1 */
-+	struct {
-+		uint32_t iana;
-+		uint8_t parameter_revision;
-+		uint8_t ecme_major_version;
-+		uint8_t ecme_minor_version;
-+		uint8_t ecme_revision;
-+		uint32_t ecme_build_number;
-+		uint32_t ecme_timestamp;
-+		char firmware_version[32];
-+	} __attribute__ ((packed)) rev1;
-+
-+	/* Revision 2 -- replaced ECME version with a string */
-+	struct {
-+		uint32_t iana;
-+		uint8_t parameter_revision;
-+		char ecme_version[32];
-+		uint32_t ecme_timestamp;
-+		char firmware_version[32];
-+	} __attribute__ ((packed)) rev2;
-+} cx_info_basic_t;
-+
-+
-+/*
-+ * Prototypes
-+ */
-+int ipmi_cxoem_main(struct ipmi_intf *, int, char **);
-+
-+#endif /*IPMI_CXOEM_H */
-diff --git a/include/ipmitool/ipmi_lanp.h b/include/ipmitool/ipmi_lanp.h
-index 1aaae5e..0e457f7 100644
---- a/include/ipmitool/ipmi_lanp.h
-+++ b/include/ipmitool/ipmi_lanp.h
-@@ -79,10 +79,17 @@ enum {
- 	IPMI_LANP_OEM_ALERT_STRING=96,
- 	IPMI_LANP_ALERT_RETRY=97,
- 	IPMI_LANP_UTC_OFFSET=98,
--	IPMI_LANP_DHCP_SERVER_IP=192,
--	IPMI_LANP_DHCP_SERVER_MAC=193,
--	IPMI_LANP_DHCP_ENABLE=194,
--	IPMI_LANP_CHAN_ACCESS_MODE=201,
-+	IPMI_LANP_TFTP_SERVER_IP=193,
-+	IPMI_LANP_TFTP_UDP_PORT=194,
-+	IPMI_LANP_NTP_SERVER_IP=195,
-+	IPMI_LANP_NTP_UDP_PORT=196,
-+	IPMI_LANP_OEM_OUID=197,
-+	IPMI_LANP_OEM_MAC0=198,
-+	IPMI_LANP_OEM_MAC1=199,
-+	IPMI_LANP_OEM_MAC2=200,
-+	IPMI_LANP_SC_OUID=201,
-+	IPMI_LANP_SC_MODE=202,
-+	IPMI_LANP_SC_FID=203
- };
- 
- static struct lan_param {
-@@ -120,10 +127,17 @@ static struct lan_param {
- 	{ IPMI_LANP_OEM_ALERT_STRING,	28,	"OEM Alert String"	}, /* 25 */
- 	{ IPMI_LANP_ALERT_RETRY,	1,	"Alert Retry Algorithm" },
- 	{ IPMI_LANP_UTC_OFFSET,		3,	"UTC Offset"		},
--	{ IPMI_LANP_DHCP_SERVER_IP,	4,	"DHCP Server IP"	},
--	{ IPMI_LANP_DHCP_SERVER_MAC,	6,	"DHDP Server MAC"	}, 
--	{ IPMI_LANP_DHCP_ENABLE,	1,	"DHCP Enable"		}, /* 30 */
--	{ IPMI_LANP_CHAN_ACCESS_MODE,	2,	"Channel Access Mode"	},
-+	{ IPMI_LANP_TFTP_SERVER_IP,	4,	"TFTP Server IP"	}, /* 28 */
-+	{ IPMI_LANP_TFTP_UDP_PORT,	2,	"TFTP UDP port"	}, 
-+	{ IPMI_LANP_NTP_SERVER_IP,	4,	"NTP Server IP"	},
-+	{ IPMI_LANP_NTP_UDP_PORT,	2,	"NTP UDP port"	}, 
-+	{ IPMI_LANP_OEM_OUID, 3, "OEM OUID" },
-+	{ IPMI_LANP_OEM_MAC0, 6, "OEM MAC0" },
-+	{ IPMI_LANP_OEM_MAC1, 6, "OEM MAC1" },
-+	{ IPMI_LANP_OEM_MAC2, 6, "OEM MAC2" },
-+	{ IPMI_LANP_SC_OUID, 3, "Supercluster OUID" },
-+	{ IPMI_LANP_SC_MODE, 1, "Supercluster mode" },
-+	{ IPMI_LANP_SC_FID, 1, "Supercluster FID" },
- 	{ -1 }
- };
- 
-diff --git a/lib/Makefile.am b/lib/Makefile.am
-index 3422521..f304502 100644
---- a/lib/Makefile.am
-+++ b/lib/Makefile.am
-@@ -39,7 +39,7 @@ libipmitool_la_SOURCES	= helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
- 				  ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c    \
- 				  ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c        \
- 				  ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c    \
--				  ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c \
-+				  ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c ipmi_cxoem.c \
- 				  ../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
- 
- libipmitool_la_LDFLAGS		= -export-dynamic
-diff --git a/lib/ipmi_chassis.c b/lib/ipmi_chassis.c
-index 2d47974..445b34d 100644
---- a/lib/ipmi_chassis.c
-+++ b/lib/ipmi_chassis.c
-@@ -746,6 +746,12 @@ ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
- 			printf(" Block Data : %s\n", buf2str(rsp->data+3, rsp->data_len - 2));
- 		}
- 		break;
-+		case 96:
-+		{
-+			printf(" Selector   : %d\n", rsp->data[1] );
-+			printf(" Boot Policy : %d\n", rsp->data[2] );
-+		}
-+		break;
- 		default:
- 			printf(" Undefined byte\n");
- 			break;
-@@ -860,6 +866,86 @@ ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, uint8_t *iflags)
- }
- 
- static int
-+ipmi_chassis_set_boot_policy(struct ipmi_intf * intf, char * arg)
-+{
-+   uint8_t flags[5];
-+   int rc = 0;
-+   int use_progress = 1;
-+
-+   if (use_progress) {
-+      /* set set-in-progress flag */
-+      memset(flags, 0, 5);
-+      flags[0] = 0x01;
-+      rc = ipmi_chassis_set_bootparam(intf,
-+         IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS, flags, 1);
-+      if (rc < 0)
-+         use_progress = 0;
-+   }
-+
-+   memset(flags, 0, 5);
-+   flags[0] = 0x01;
-+   flags[1] = 0x01;
-+   rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_INFO_ACK,
-+               flags, 2);
-+
-+   if (rc < 0) {
-+      if (use_progress) {
-+         /* set-in-progress = set-complete */
-+         memset(flags, 0, 5);
-+         ipmi_chassis_set_bootparam(intf,
-+               IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
-+               flags, 1);
-+      }
-+      return -1;
-+   }
-+
-+   memset(flags, 0, 5);
-+
-+   if (strncmp(arg, "0", 1) == 0)
-+      flags[0] = 0;
-+   else if (strncmp(arg, "1", 1) == 0)
-+      flags[0] = 1;
-+   else if (strncmp(arg, "2", 1) == 0)
-+      flags[0] = 2;
-+   else {
-+      lprintf(LOG_ERR, "Invalid argument: %s", arg);
-+      if (use_progress) {
-+         /* set-in-progress = set-complete */
-+         memset(flags, 0, 5);
-+         ipmi_chassis_set_bootparam(intf,
-+               IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
-+               flags, 1);
-+      }
-+      return -1;
-+   }
-+
-+   rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_OEM_BOOT_POLICY,
-+               flags, 1);
-+   if (rc == 0) {
-+      if (use_progress) {
-+         /* set-in-progress = commit-write */
-+         memset(flags, 0, 5);
-+         flags[0] = 0x02;
-+         ipmi_chassis_set_bootparam(intf,
-+               IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
-+               flags, 1);
-+      }
-+
-+      printf("Set Boot Policy to %s\n", arg);
-+   }
-+
-+   if (use_progress) {
-+      /* set-in-progress = set-complete */
-+      memset(flags, 0, 5);
-+      ipmi_chassis_set_bootparam(intf,
-+            IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
-+            flags, 1);
-+   }
-+
-+   return rc;
-+}
-+
-+static int
- ipmi_chassis_power_policy(struct ipmi_intf * intf, uint8_t policy)
- {
- 	struct ipmi_rs * rsp;
-@@ -1043,6 +1129,10 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
- 			lprintf(LOG_NOTICE, "  force_diag  : Force boot from Diagnostic Partition");
- 			lprintf(LOG_NOTICE, "  force_cdrom : Force boot from CD/DVD");
- 			lprintf(LOG_NOTICE, "  force_bios  : Force boot into BIOS Setup");
-+			lprintf(LOG_NOTICE, "bootparam set policy <value>");
-+			lprintf(LOG_NOTICE, "          0   : Boot ASAP");
-+			lprintf(LOG_NOTICE, "          1   : Boot when Fabric is ready");
-+			lprintf(LOG_NOTICE, "          2   : Boot after a fixed delay");
- 		}
- 		else {
- 			if (strncmp(argv[1], "get", 3) == 0) {
-@@ -1054,6 +1144,8 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
- 				} else {
- 					if (strncmp(argv[2], "bootflag", 8) == 0)
- 						rc = ipmi_chassis_set_bootdev(intf, argv[3], NULL);
-+					else if (strncmp(argv[2], "policy", 6) == 0)
-+						rc = ipmi_chassis_set_boot_policy(intf, argv[3]);
- 					else
- 						lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
- 				}
-diff --git a/lib/ipmi_cxoem.c b/lib/ipmi_cxoem.c
-new file mode 100644
-index 0000000..fbc008e
---- /dev/null
-+++ b/lib/ipmi_cxoem.c
-@@ -0,0 +1,3928 @@
-+/*
-+ * Copyright (c) 2011 Calxeda, Inc.  All Rights Reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * Redistribution of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * Redistribution in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ *
-+ * Neither the name of Calxeda, Inc. or the names of
-+ * contributors may be used to endorse or promote products derived
-+ * from this software without specific prior written permission.
-+ *
-+ * This software is provided "AS IS," without a warranty of any kind.
-+ */
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <signal.h>
-+#include <ctype.h>
-+#include <time.h>
-+
-+#include <ipmitool/ipmi.h>
-+#include <ipmitool/ipmi_intf.h>
-+#include <ipmitool/helper.h>
-+#include <ipmitool/log.h>
-+#include <ipmitool/ipmi_sel.h>
-+#include <ipmitool/ipmi_sdr.h>
-+#include <ipmitool/ipmi_strings.h>
-+#include <ipmitool/ipmi_channel.h>
-+#include <ipmitool/ipmi_cxoem.h>
-+#include <ipmitool/ipmi_raw.h>
-+
-+/* cxoem data targets -- i.e. the kinds of data we can read and write
-+ */
-+#define CX_DATA_TARGET_MEM 1
-+#define CX_DATA_TARGET_CDB 2
-+#define CX_DATA_TARGET_UNKNOWN 0
-+/* Maximum amount of data that can be read from or written to the configuration
-+   data base
-+*/
-+#define MAX_RETURNABLE_CDB_LEN 64
-+/* Kinds of access to cxoem data supported
-+ */
-+#define CX_DATA_ACCESS_READ 1
-+#define CX_DATA_ACCESS_WRITE 2
-+#define CX_DATA_ACCESS_UNKNOWN 0
-+/* Supported cxoem data formatting hints
-+ */
-+#define CX_DATA_FMT_DEFAULT 0
-+#define CX_DATA_FMT_INT 1
-+#define CX_DATA_FMT_UINT 2
-+#define CX_DATA_FMT_XINT 3
-+#define CX_DATA_FMT_ASCII 4
-+#define CX_DATA_FMT_XSTR 5
-+#define CX_DATA_INT_TYPE 1
-+#define CX_DATA_BYTE_TYPE 2
-+/* cxoem internal return codes
-+ */
-+#define CX_DATA_BAD_VALUE -1
-+#define CX_DATA_BAD_LENGTH -2
-+#define CX_DATA_OK 0
-+
-+const struct valstr cx_ptypes[] = {
-+	{0x00, "DEL"},
-+	{0x01, "DEL1"},
-+	{0x02, "S2_ELF"},
-+	{0x03, "SOC_ELF"},
-+	{0x04, "A9_UEFI"},
-+	{0x05, "A9_UBOOT"},
-+	{0x06, "A9_EXEC"},
-+	{0x07, "A9_ELF"},
-+	{0x08, "SOCDATA"},
-+	{0x09, "DTB"},
-+	{0x0a, "CDB"},
-+	{0x0b, "UBOOTENV"},
-+	{0x0c, "SEL"},
-+	{0x0d, "BOOT_LOG"},
-+	{0x0e, "UEFI_ENV"},
-+	{0x0f, "DIAG_ELF"},
-+};
-+
-+const struct valstr cx_tftp_status[] = {
-+	{0x00, "Invalid"},
-+	{0x01, "In progress"},
-+	{0x02, "Failed"},
-+	{0x03, "Complete"},
-+	{0x04, "Canceled"},
-+};
-+
-+const char *tps_table[] = {
-+	"(Init)",
-+	"(Cold)",
-+	"(Warm)",
-+	"(Hot)",
-+	"(Critical)",
-+	"(Shutdown)",
-+};
-+
-+static void ipmi_cxoem_usage(void)
-+{
-+	lprintf(LOG_NOTICE,
-+		"Usage: ipmitool cxoem <command> [option...]\n"
-+		"\n"
-+		"Commands: \n" "\n" "  fw fabric mac log data info feature\n");
-+}
-+
-+static void cx_fw_usage(void)
-+{
-+	lprintf(LOG_NOTICE,
-+		"\n"
-+		"Usage: ipmitool cxoem fw <command> [option...]\n"
-+		"\n"
-+		"Firmware Commands: \n"
-+		"\n"
-+		"  download       <filename> <partition> <type> tftp <ip[:port]>\n"
-+		"  upload         <partition> <filename> <type> tftp <ip[:port]>\n"
-+		"  register read  <partition> <filename> <type>\n"
-+		"  register write <partition> <filename> <type>\n"
-+		"  activate       <partition>\n"
-+		"  invalidate     <partition>\n"
-+		"  makenext       <partition>\n"
-+		"  flags          <partition> <flags> \n"
-+		"  status         <job id>      - returns status of the transfer by <job id>\n"
-+		"  check          <partition>   - force a crc check\n"
-+		"  cancel         <job id>\n"
-+		"  info\n"
-+		"  get            <filename> <offset> <size> tftp <ip[:port]>\n"
-+		"  put            <filename> <offset> <size> tftp <ip[:port]>\n"
-+		"  reset          Reset to factory default\n"
-+		"  version        <version_str> - set the firmware version\n"
-+		"\n");
-+}
-+
-+static void cx_fabric_usage(void)
-+{
-+	lprintf(LOG_NOTICE,
-+		"\n"
-+		"Usage: ipmitool cxoem fabric <command> [option...]\n"
-+		"\n"
-+		"Fabric Commands: \n"
-+		"\n"
-+		"  set|get  <parameter> <value> [node <node_id>]\n"
-+		"     where parameter = node_id, ipaddr, netmask, defgw, ipsrc, macaddr, ntp_server, ntp_port, link_resilience\n"
-+		"  factory_default node <node_id>\n"
-+		"  update_config node <node_id>\n"
-+		"\n"
-+		"Ex: ipmitool cxoem fabric get ipaddr node 1\n"
-+		"\n"
-+		"\n"
-+		"Fabric Config commands affect all nodes in the fabric\n"
-+		"Usage: ipmitool cxoem fabric config <command> [option...]\n"
-+		"\n"
-+		"Fabric Config Commands: \n"
-+		"\n"
-+		"  set|get ipinfo tftp <tftp_server_addr> port <tftp_server_port> file <filename>\n"
-+		"  set|get ipsrc\n"
-+		"  set|get ntp_server <ntp_server_ipaddr>\n"
-+		"  set|get ntp_port <ntp_port>\n"
-+		"  set|get nodenum_offset <offset>\n"
-+		"  set|get macaddrs tftp <tftp_server_addr> port <tftp_server_port> file <filename>\n"
-+		"  set|get mtu <standard|jumbo>\n"
-+		"  set|get uplink <uplink_id> node <node_id> interface <interface_id>\n"
-+		"    where mode is:\n"
-+		"      0 - all interfaces go to Uplink0\n"
-+		"      1 - managment interfaces go to Uplink0, server interfaces go to Uplink1\n"
-+		"      2 - managment and eth0 interfaces go to Uplink0, eth1 interfaces go to Uplink1\n"
-+		"  set|get link_resilience <setting>\n"
-+		"    where setting is:\n"
-+		"      0 - Resilient: All redundant links are left enabled\n"
-+		"      1 - Link Minimal: All redundant links are disabled\n"
-+		"  factory_default\n"
-+		"  update_config\n"
-+		"\n"
-+		"Ex: ipmitool cxoem fabric config get ipinfo tftp 10.1.1.1 port 69 file ipinfo.out\n"
-+		"\n");
-+}
-+
-+static void cx_feature_usage(void)
-+{
-+	lprintf(LOG_NOTICE,
-+		"\n"
-+		"Usage: ipmitool cxoem feature <status|enable|disable> <feature> \n"
-+		"\n"
-+		"Feature to Enable/Disable/Query are:\n"
-+		"  selaging : SEL Aging or Circular SEL buffer\n"
-+		"  hwwd     : Hardware Watchdog\n"
-+		"  tps      : Thermal Protection System (Status Only)\n"
-+		"  mansen   : Override for manual sensors monitoring\n"
-+		"\n"
-+		"Ex: ipmitool cxoem feature status selaging\n"
-+		"Ex: ipmitool cxoem feature enable hwwd\n" "\n");
-+}
-+
-+int cx_fw_download(struct ipmi_intf *intf, char *filename, int partition,
-+		   int type, int ip1, int ip2, int ip3, int ip4, int port)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_DOWNLOAD;
-+	msg_data[0] = type;
-+	msg_data[1] = partition;
-+	msg_data[2] = CXOEM_FW_DOWNLOAD;
-+	msg_data[3] = 0;
-+	msg_data[4] = 0;
-+	msg_data[5] = 6;	// ipv4 addresses by default (for now)
-+	msg_data[6] = ip1;
-+	msg_data[7] = ip2;
-+	msg_data[8] = ip3;
-+	msg_data[9] = ip4;
-+	msg_data[10] = (port & 0xff);
-+	msg_data[11] = (port >> 8) & 0xff;
-+	msg_data[12] = strlen(filename) + 1;
-+	memcpy(&msg_data[13], filename, msg_data[12]);
-+	req.msg.data = msg_data;
-+	req.msg.data_len = msg_data[12] + 13;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error starting fw download");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode == 0) {
-+		uint16_t handle;
-+		handle = (unsigned int)rsp->data[0];
-+		handle |= (unsigned int)(rsp->data[1] << 8);
-+		printf("TFTP Handle ID:  %d\n", handle);
-+	} else if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Start FW download failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return rc;
-+}
-+
-+int cx_fw_upload(struct ipmi_intf *intf, char *filename, int partition,
-+		 int type, int ip1, int ip2, int ip3, int ip4, int port)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_DOWNLOAD;
-+	msg_data[0] = type;
-+	msg_data[1] = partition;
-+	msg_data[2] = CXOEM_FW_UPLOAD;
-+	msg_data[3] = 0;
-+	msg_data[4] = 0;
-+	msg_data[5] = 6;	// ipv4 addresses by default (for now)
-+	msg_data[6] = ip1;
-+	msg_data[7] = ip2;
-+	msg_data[8] = ip3;
-+	msg_data[9] = ip4;
-+	msg_data[10] = (port & 0xff);
-+	msg_data[11] = (port >> 8) & 0xff;
-+	msg_data[12] = fmin(strlen(filename) + 1, 51);
-+	memcpy(&msg_data[13], filename, msg_data[12] - 1);
-+	req.msg.data = msg_data;
-+	req.msg.data_len = msg_data[12] + 13;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error starting fw upload");
-+		return -1;
-+	}
-+	if (rsp->ccode == 0) {
-+		uint16_t handle;
-+		handle = (unsigned int)rsp->data[0];
-+		handle |= (unsigned int)(rsp->data[1] << 8);
-+		printf("TFTP Handle ID:  %d\n", handle);
-+	} else if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Start FW upload failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return rc;
-+}
-+
-+int cx_fw_register_read(struct ipmi_intf *intf, char *filename, int partition,
-+			int type)
-+{
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_DOWNLOAD;
-+	msg_data[0] = type;
-+	msg_data[1] = partition;
-+	msg_data[2] = CXOEM_FW_REGISTER_READ;
-+	msg_data[12] = fmin(strlen(filename) + 1, 51);
-+	memcpy(&msg_data[13], filename, msg_data[12] - 1);
-+	req.msg.data = msg_data;
-+	req.msg.data_len = msg_data[12] + 13;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error     : No response");
-+		return -1;
-+	}
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Error     : %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+	if (rsp->data_len != 0) {
-+		lprintf(LOG_ERR, "Error     : Invalid response size");
-+		return -1;
-+	}
-+
-+	return CXOEM_SUCCESS;
-+}
-+
-+int cx_fw_register_write(struct ipmi_intf *intf, char *filename, int partition,
-+			 int type)
-+{
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_DOWNLOAD;
-+	msg_data[0] = type;
-+	msg_data[1] = partition;
-+	msg_data[2] = CXOEM_FW_REGISTER_WRITE;
-+	msg_data[12] = fmin(strlen(filename) + 1, 51);
-+	memcpy(&msg_data[13], filename, msg_data[12] - 1);
-+	req.msg.data = msg_data;
-+	req.msg.data_len = msg_data[12] + 13;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error     : No response");
-+		return -1;
-+	}
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Error     : %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+	if (rsp->data_len != 0) {
-+		lprintf(LOG_ERR, "Error     : Invalid response size");
-+		return -1;
-+	}
-+
-+	return CXOEM_SUCCESS;
-+}
-+
-+int cx_fw_raw(struct ipmi_intf *intf, char *filename, unsigned int address,
-+	      unsigned int size, int dir,
-+	      int ip1, int ip2, int ip3, int ip4, int port)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_RAW;
-+	msg_data[0] = dir;
-+	msg_data[1] = address & 0xff;
-+	msg_data[2] = (address >> 8) & 0xff;
-+	msg_data[3] = (address >> 16) & 0xff;
-+	msg_data[4] = (address >> 24) & 0xff;
-+	msg_data[5] = size & 0xff;
-+	msg_data[6] = (size >> 8) & 0xff;
-+	msg_data[7] = (size >> 16) & 0xff;
-+	msg_data[8] = (size >> 24) & 0xff;
-+	msg_data[9] = ip1;
-+	msg_data[10] = ip2;
-+	msg_data[11] = ip3;
-+	msg_data[12] = ip4;
-+	msg_data[13] = (port & 0xff);
-+	msg_data[14] = (port >> 8) & 0xff;
-+	msg_data[15] = strlen(filename) + 1;
-+	memcpy(&msg_data[16], filename, msg_data[15]);
-+	req.msg.data = msg_data;
-+	req.msg.data_len = msg_data[15] + 16;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error starting raw transfer");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode == 0) {
-+		uint16_t handle;
-+		handle = (unsigned int)rsp->data[0];
-+		handle |= (unsigned int)(rsp->data[1] << 8);
-+
-+		printf("TFTP Handle ID:  %d\n", handle);
-+	} else if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Start raw transfer failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return rc;
-+}
-+
-+int cx_fw_status(struct ipmi_intf *intf, uint16_t handle)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[16];
-+	int status = -1;
-+
-+	memset(&req, 0, sizeof(req));
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_GET_STATUS;
-+	msg_data[0] = 0;
-+	msg_data[1] = 1;	// param 1 = download status
-+
-+	msg_data[2] = handle & 0x00ff;
-+	msg_data[3] = (handle >> 8) & 0x00ff;
-+	req.msg.data = msg_data;
-+	req.msg.data_len = 4;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error checking fw status");
-+		return -1;
-+	}
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Check FW status failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	status = rsp->data[1];
-+
-+	printf("Status : %s\n", val2str(status, cx_tftp_status));
-+
-+	return rc;
-+}
-+
-+int cx_fw_check(struct ipmi_intf *intf, int partition)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_GET_STATUS;
-+	msg_data[0] = 0;
-+	msg_data[1] = 4;	// param 4 = check image
-+	msg_data[2] = partition;
-+	req.msg.data = msg_data;
-+	req.msg.data_len = 3;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error during firmware check\n");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode == 0) {
-+		unsigned int crc32;
-+		crc32 = (unsigned int)rsp->data[5];
-+		crc32 |= (unsigned int)(rsp->data[4] << 8);
-+		crc32 |= (unsigned int)(rsp->data[3] << 16);
-+		crc32 |= (unsigned int)(rsp->data[2] << 24);
-+		if (rsp->data[1] == 0) {
-+			printf("CRC32 :  %08x\n", crc32);
-+		} else {
-+			printf("Error : %02x\n", rsp->data[0]);
-+			return -1;
-+		}
-+	} else if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Firmware check failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return rc;
-+}
-+
-+int cx_fw_info(struct ipmi_intf *intf, int partition)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+	int i;
-+	struct cx_fw_info_rs *s;
-+	int count;
-+	img_info_t ii[20];
-+	simg_header_t header;
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_GET_STATUS;
-+	msg_data[0] = 0;
-+	msg_data[1] = 2;	// param 2 = info
-+	msg_data[2] = partition;
-+	req.msg.data = msg_data;
-+	req.msg.data_len = 2;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error starting fw download");
-+		return -1;
-+	}
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Start FW download failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	if (rsp->data_len < sizeof(struct cx_fw_info_rs))
-+		return -1;
-+
-+	s = (struct cx_fw_info_rs *)&rsp->data[0];
-+	count = s->count / sizeof(img_info_t);
-+	memcpy(ii, &s->img_info, count * sizeof(img_info_t));
-+
-+	printf("\n");
-+	for (i = 0; i < count; i++) {
-+		if (cx_fw_get_simg_header(intf, i, &header)) {
-+			return -1;
-+		}
-+
-+		printf("%-18s : %02d\n", "Partition", ii[i].id);
-+		printf("%-18s : %02x (%s)\n", "Type", ii[i].type,
-+		       val2str(ii[i].type, cx_ptypes));
-+		printf("%-18s : %08x\n", "Offset", ii[i].img_addr);
-+		printf("%-18s : %08x\n", "Size", ii[i].img_size);
-+		printf("%-18s : %08x\n", "Priority", header.priority);
-+		printf("%-18s : %08x\n", "Daddr", header.daddr);
-+		printf("%-18s : %08x\n", "Flags", header.flags);
-+		if (header.hdrfmt >= 2)
-+			printf("%-18s : %s\n", "Version", header.version);
-+		else
-+			printf("%-18s : Unknown\n", "Version");
-+		if (ii[i].in_use <= 1)
-+			printf("%-18s : %u\n\n", "In Use", ii[i].in_use);
-+		else
-+			printf("%-18s : Unknown\n\n", "In Use");
-+	}
-+
-+	return rc;
-+}
-+
-+
-+int
-+cx_fw_get_simg_header(struct ipmi_intf *intf, int partition,
-+		      simg_header_t * header)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 64);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_GET_STATUS;
-+	msg_data[0] = 0;
-+	msg_data[1] = 3;	// param 3 = get SIMG header
-+	msg_data[2] = partition;
-+	req.msg.data = msg_data;
-+	req.msg.data_len = 3;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error reading SIMG info\n");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode == 0) {
-+		memcpy(header, &rsp->data[1], sizeof(*header));
-+	} else if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "SIMG read failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return rc;
-+}
-+
-+
-+int cx_fw_flags(struct ipmi_intf *intf, int partition, uint32_t flags)
-+{
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[16];
-+	int i;
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, sizeof(msg_data));
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_SET_STATUS;
-+	msg_data[0] = 0;	// resvd
-+	msg_data[1] = 1;	// param = 1 = "set flags"
-+	msg_data[2] = partition;
-+	msg_data[3] = (uint8_t) ((flags >> 24) & 0xff);
-+	msg_data[4] = (uint8_t) ((flags >> 16) & 0xff);
-+	msg_data[5] = (uint8_t) ((flags >> 8) & 0xff);
-+	msg_data[6] = (uint8_t) (flags & 0xff);
-+	req.msg.data = msg_data;
-+	req.msg.data_len = 7;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error starting fw download");
-+		return -1;
-+	}
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "FW set flags failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+int cx_fw_get_flags(struct ipmi_intf *intf, int partition, unsigned int *flags)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	simg_header_t header;
-+
-+	if (cx_fw_get_simg_header(intf, partition, &header)) {
-+		return -1;
-+	}
-+
-+	*flags = header.flags;
-+
-+	return rc;
-+}
-+
-+
-+int cx_fw_makenext(struct ipmi_intf *intf, int partition)
-+{
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[4];
-+	int i;
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, sizeof(msg_data));
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_SET_STATUS;
-+	msg_data[0] = 0;	// resvd
-+	msg_data[1] = 3;	// param = 3 = "make next"
-+	msg_data[2] = partition;
-+	req.msg.data = msg_data;
-+	req.msg.data_len = 3;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error setting firmware image to 'next'");
-+		return -1;
-+	}
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "FW set next failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+int cx_fw_activate(struct ipmi_intf *intf, int partition)
-+{
-+	unsigned int flags;
-+
-+	if (cx_fw_get_flags(intf, partition, &flags)) {
-+		return -1;
-+	}
-+	//printf("activate: read flags <%08x>\n", flags);
-+	flags &= (~0x02);	// bit 1 = SIMG_FLAG_ACTIVE
-+	printf("activate: write flags <%08x>\n", flags);
-+
-+	cx_fw_flags(intf, partition, flags);
-+
-+	return 0;
-+}
-+
-+
-+int cx_fw_invalidate(struct ipmi_intf *intf, int partition)
-+{
-+	unsigned int flags;
-+
-+	if (cx_fw_get_flags(intf, partition, &flags)) {
-+		return -1;
-+	}
-+	//printf("invalidate: read flags <%08x>\n", flags);
-+	flags &= (~0x04);	// bit 2 = SIMG_FLAG_INVALID
-+	printf("invalidate: write flags <%08x>\n", flags);
-+
-+	cx_fw_flags(intf, partition, flags);
-+
-+	return 0;
-+}
-+
-+
-+int cx_fw_reset(struct ipmi_intf *intf)
-+{
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+
-+	memset(&req, 0, sizeof(req));
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_RESET;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR,
-+			"Error resetting firmware to factory default\n");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "Firmware reset failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+int cx_fw_version(struct ipmi_intf *intf, char *version)
-+{
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[64];
-+	int i;
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, sizeof(msg_data));
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_FW_SET_STATUS;
-+	msg_data[0] = 0;	// resvd
-+	msg_data[1] = 4;	// param = 4 = "set version"
-+	strncpy(&msg_data[2], version, 32);
-+	req.msg.data = msg_data;
-+	req.msg.data_len = 34;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error starting fw download");
-+		return -1;
-+	}
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "FW set version failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+int cx_fw_main(struct ipmi_intf *intf, int argc, char **argv)
-+{
-+	char filename[65];
-+	int rv = 0;
-+	int partition, type;
-+	int ip1 = 0, ip2 = 0, ip3 = 0, ip4 = 0;
-+	int port = 0;
-+
-+	errno = 0;
-+
-+	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
-+		cx_fw_usage();
-+		return 0;
-+	}
-+
-+	if (strncmp(argv[0], "download", 8) == 0) {
-+		if ((argc > 3) && (argc < 7) && (strlen(argv[1]) > 0)) {
-+			/* There is a file name in the parameters */
-+			if (strlen(argv[1]) < 32) {
-+				strcpy((char *)filename, argv[1]);
-+				printf("File Name         : %s\n", filename);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"File name must be smaller than 32 bytes\n");
-+			}
-+
-+			partition = strtol(argv[2], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (isdigit(argv[3][0])) {
-+				type = strtol(argv[3], (char **)NULL, 10);
-+			} else {
-+				type = str2val(argv[3], cx_ptypes);
-+				if (type < 1 || type > 14)
-+					errno = -1;
-+			}
-+			if (!errno) {
-+				printf("Type              : %d\n", type);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<type> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (argc > 5 && strncmp(argv[4], "tftp", 4) == 0) {
-+				if (strchr(argv[5], ':')) {
-+					if (sscanf(argv[5], "%d.%d.%d.%d:%d",
-+						   &ip1, &ip2, &ip3, &ip4,
-+						   &port) != 5) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d:%d\n", ip1,
-+					       ip2, ip3, ip4, port);
-+				} else {
-+					if (sscanf(argv[5], "%d.%d.%d.%d",
-+						   &ip1, &ip2, &ip3,
-+						   &ip4) != 4) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d\n", ip1, ip2,
-+					       ip3, ip4);
-+				}
-+			} else {
-+				cx_fw_usage();
-+				return -1;
-+			}
-+			cx_fw_download(intf, filename, partition, type,
-+				       ip1, ip2, ip3, ip4, port);
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+	} else if (strncmp(argv[0], "upload", 8) == 0) {
-+		if ((argc > 3) && (argc < 7) && (strlen(argv[1]) > 0)) {
-+			/* There is a file name in the parameters */
-+			if (strlen(argv[2]) < 32) {
-+				strcpy((char *)filename, argv[2]);
-+				printf("File Name         : %s\n", filename);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"File name must be smaller than 32 bytes\n");
-+			}
-+
-+			partition = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (isdigit(argv[3][0])) {
-+				type = strtol(argv[3], (char **)NULL, 10);
-+			} else {
-+				type = str2val(argv[3], cx_ptypes);
-+				if (type < 1 || type > 14)
-+					errno = -1;
-+			}
-+			if (!errno) {
-+				printf("Type              : %d\n", type);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<type> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (argc > 5 && strncmp(argv[4], "tftp", 4) == 0) {
-+				if (strchr(argv[5], ':')) {
-+					if (sscanf(argv[5], "%d.%d.%d.%d:%d",
-+						   &ip1, &ip2, &ip3, &ip4,
-+						   &port) != 5) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d:%d\n", ip1,
-+					       ip2, ip3, ip4, port);
-+				} else {
-+					if (sscanf(argv[5], "%d.%d.%d.%d",
-+						   &ip1, &ip2, &ip3,
-+						   &ip4) != 4) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d\n", ip1, ip2,
-+					       ip3, ip4);
-+				}
-+			} else {
-+				cx_fw_usage();
-+				return -1;
-+			}
-+			cx_fw_upload(intf, filename, partition, type,
-+				     ip1, ip2, ip3, ip4, port);
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+	} else if (strncmp(argv[0], "register", 8) == 0) {
-+		if (argc == 5) {
-+			partition = strtol(argv[2], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (strlen(argv[3]) < 32) {
-+				strcpy((char *)filename, argv[3]);
-+				printf("File Name : %s\n", filename);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"File name must be smaller than 32 bytes\n");
-+			}
-+
-+			if (isdigit(argv[4][0])) {
-+				type = strtol(argv[4], (char **)NULL, 10);
-+			} else {
-+				type = str2val(argv[4], cx_ptypes);
-+				if (type < 1 || type > 14)
-+					errno = -1;
-+			}
-+			if (!errno) {
-+				printf("Type      : %d\n", type);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<type> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (strncmp(argv[1], "read", 4) == 0) {
-+				cx_fw_register_read(intf, filename, partition,
-+						    type);
-+			} else if(strncmp(argv[1], "write", 5) == 0) {
-+				cx_fw_register_write(intf, filename, partition,
-+						     type);
-+			} else {
-+				cx_fw_usage();
-+				return -1;
-+			}
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+	} else if (strncmp(argv[0], "put", 3) == 0) {
-+		unsigned int addr = 0;
-+		unsigned int size = 0;
-+		int dir = 0;	// 0 = download, 1 = upload
-+		if ((argc > 3) && (argc < 7) && (strlen(argv[1]) > 0)) {
-+			/* There is a file name in the parameters */
-+			if (strlen(argv[1]) < 32) {
-+				strcpy((char *)filename, argv[1]);
-+				printf("File Name         : %s\n", filename);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"File name must be smaller than 32 bytes\n");
-+			}
-+
-+			addr = strtoul(argv[2], (char **)NULL, 0);
-+			if (!errno) {
-+				printf("Address   : %08x\n", addr);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<address> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			size = strtoul(argv[3], (char **)NULL, 0);
-+			if (!errno) {
-+				printf("Size      : %08x\n", size);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<size> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (argc > 5 && strncmp(argv[4], "tftp", 4) == 0) {
-+				if (strchr(argv[5], ':')) {
-+					if (sscanf(argv[5], "%d.%d.%d.%d:%d",
-+						   &ip1, &ip2, &ip3, &ip4,
-+						   &port) != 5) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d:%d\n", ip1,
-+					       ip2, ip3, ip4, port);
-+				} else {
-+					if (sscanf(argv[5], "%d.%d.%d.%d",
-+						   &ip1, &ip2, &ip3,
-+						   &ip4) != 4) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d\n", ip1, ip2,
-+					       ip3, ip4);
-+				}
-+			} else {
-+				cx_fw_usage();
-+				return -1;
-+			}
-+			cx_fw_raw(intf, filename, addr, size, dir,
-+				  ip1, ip2, ip3, ip4, port);
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+	} else if (strncmp(argv[0], "get", 3) == 0) {
-+		unsigned int addr = 0;
-+		unsigned int size = 0;
-+		int dir = 1;	// 0 = download, 1 = upload
-+		if ((argc > 3) && (argc < 7) && (strlen(argv[1]) > 0)) {
-+			/* There is a file name in the parameters */
-+			if (strlen(argv[1]) < 32) {
-+				strcpy((char *)filename, argv[1]);
-+				printf("File Name         : %s\n", filename);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"File name must be smaller than 32 bytes\n");
-+			}
-+
-+			addr = strtoul(argv[2], (char **)NULL, 0);
-+			if (!errno) {
-+				printf("Address   : %08x\n", addr);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<address> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			size = strtoul(argv[3], (char **)NULL, 0);
-+			if (!errno) {
-+				printf("Size      : %08x\n", size);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<size> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+
-+			if (argc > 5 && strncmp(argv[4], "tftp", 4) == 0) {
-+				if (strchr(argv[5], ':')) {
-+					if (sscanf(argv[5], "%d.%d.%d.%d:%d",
-+						   &ip1, &ip2, &ip3, &ip4,
-+						   &port) != 5) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d:%d\n", ip1,
-+					       ip2, ip3, ip4, port);
-+				} else {
-+					if (sscanf(argv[5], "%d.%d.%d.%d",
-+						   &ip1, &ip2, &ip3,
-+						   &ip4) != 4) {
-+						lprintf(LOG_ERR,
-+							"Invalid IP address: %s",
-+							argv[5]);
-+						return -1;
-+					}
-+					printf("IP = %d.%d.%d.%d\n", ip1, ip2,
-+					       ip3, ip4);
-+				}
-+			} else {
-+				cx_fw_usage();
-+				return -1;
-+			}
-+			cx_fw_raw(intf, filename, addr, size, dir,
-+				  ip1, ip2, ip3, ip4, port);
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+	} else if (strncmp(argv[0], "status", 6) == 0) {
-+		uint16_t handle = 0;
-+
-+		if (argc == 2) {
-+			handle = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Handle : %d\n", handle);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<handle> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+		}
-+		cx_fw_status(intf, handle);
-+		rv = 0;
-+	} else if (strncmp(argv[0], "info", 4) == 0) {
-+		int partition = -1;
-+
-+		if (argc > 3) {
-+			partition = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+		}
-+		cx_fw_info(intf, partition);
-+	} else if (strncmp(argv[0], "makenext", 8) == 0) {
-+		if (argc == 2) {
-+			partition = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				fprintf(stderr,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+		cx_fw_makenext(intf, partition);
-+	} else if (strncmp(argv[0], "activate", 8) == 0) {
-+		int partition = -1;
-+
-+		if (argc == 2) {
-+			partition = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+		cx_fw_activate(intf, partition);
-+	} else if (strncmp(argv[0], "invalidate", 10) == 0) {
-+		int partition = -1;
-+
-+		if (argc == 2) {
-+			partition = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+		cx_fw_invalidate(intf, partition);
-+	} else if (strncmp(argv[0], "flags", 5) == 0) {
-+		int partition = -1;
-+		uint32_t flags = 0xffffffff;
-+
-+		if (argc == 3) {
-+			partition = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+			flags = strtoul(argv[2], (char **)NULL, 16);
-+			if (!errno) {
-+				printf("Flags             : %08x\n", flags);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<flags> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+		cx_fw_flags(intf, partition, flags);
-+	} else if (strncmp(argv[0], "check", 5) == 0) {
-+		int partition = -1;
-+
-+		if (argc == 2) {
-+			partition = strtol(argv[1], (char **)NULL, 10);
-+			if (!errno) {
-+				printf("Partition         : %d\n", partition);
-+			} else {
-+				lprintf(LOG_ERR,
-+					"<partition> doesn't look like a valid value\n");
-+				return -1;
-+			}
-+		} else {
-+			cx_fw_usage();
-+			return -1;
-+		}
-+		cx_fw_check(intf, partition);
-+		rv = 0;
-+	} else if (strncmp(argv[0], "reset", 5) == 0) {
-+		cx_fw_reset(intf);
-+		rv = 0;
-+	} else if (strncmp(argv[0], "version", 7) == 0) {
-+		cx_fw_version(intf, argv[1]);
-+		rv = 0;
-+	} else {
-+		cx_fw_usage();
-+		return -1;
-+	}
-+
-+
-+	return rv;
-+}
-+
-+typedef enum {
-+	Cx_Fabric_Arg_Invalid,
-+	Cx_Fabric_Arg_Command,
-+	Cx_Fabric_Arg_Parameter,
-+	Cx_Fabric_Arg_Specifier,
-+	Cx_Fabric_Arg_Value_Scalar,
-+	Cx_Fabric_Arg_Value_String,
-+	Cx_Fabric_Arg_Value_IPV4_Address,
-+	Cx_Fabric_Arg_Value_MAC_Address,
-+	Cx_Fabric_Arg_Value_Bitmap,
-+} cx_fabric_arg_type_t;
-+
-+typedef struct {
-+	char *keyword;
-+	cx_fabric_arg_type_t arg_type;
-+	void *data;
-+} cx_fabric_arg_t;
-+
-+#define MAX_PERMITTED_PARAMS 20
-+#define MAX_PERMITTED_SPECIFIERS 20
-+#define MAX_REQUIRED_SPECIFIERS 20
-+
-+#define IPMI_CMD_OEM_PARAMETER_UNDEF 0
-+#define IPMI_CMD_OEM_SPECIFIER_UNDEF 0
-+
-+typedef struct {
-+	char *keyword;
-+	uint8_t ipmi_cmd;
-+	uint8_t parameter_required;
-+	uint8_t parameter_value_expected;
-+	uint8_t permitted_params[MAX_PERMITTED_PARAMS];
-+	uint8_t permitted_specifiers[MAX_PERMITTED_SPECIFIERS];
-+	uint8_t required_specifiers[MAX_REQUIRED_SPECIFIERS];
-+} cx_fabric_cmd_t;
-+
-+cx_fabric_cmd_t update_cmd = {
-+	"update_config",
-+	IPMI_CMD_OEM_FABRIC_UPDATE_CONFIG,
-+	0, 0,
-+	{0, 0, 0, 0, 0},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_NODE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION, 0, 0, 0},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t factory_default_node_cmd = {
-+	"factory_default",
-+	IPMI_CMD_OEM_FABRIC_FACTORY_DEFAULT,
-+	0, 0,
-+	{0, 0, 0, 0, 0},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION, 0, 0, 0},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t get_cmd = {
-+	"get",
-+	IPMI_CMD_OEM_FABRIC_GET,
-+	1, 0,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NETMASK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_DEFGW,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPSRC,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NODEID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_RESILIENCE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_SERVER,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_PORT,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_CONFIGURATIONID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PROFILEID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_NODES,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_RANGE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_BASE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_NUM,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED_POLICY,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_CUSTOMER_MACADDR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS_FACTOR},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_NODE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_OVERRIDE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_ACTUAL,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PROFILE},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t set_cmd = {
-+	"set",
-+	IPMI_CMD_OEM_FABRIC_SET,
-+	1, 1,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NETMASK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_DEFGW,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPSRC,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_RESILIENCE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_SERVER,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_PORT,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_CUSTOMER_MACADDR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_CONFIGURATIONID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITIONID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PROFILEID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_BASE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_NUM,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED_POLICY,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS_FACTOR},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_NODE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_OVERRIDE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PROFILE},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t add_cmd = {
-+	"add",
-+	IPMI_CMD_OEM_FABRIC_ADD,
-+	1, 1,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_CONFIGURATIONID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_NODES,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_RANGE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITIONID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PROFILEID},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_NODE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION, 0, 0},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t rm_cmd = {
-+	"rm",
-+	IPMI_CMD_OEM_FABRIC_RM,
-+	1, 1,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_CONFIGURATIONID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_RANGE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITIONID,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_PROFILEID},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_NODE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION, 0},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t info_cmd = {
-+	"info",
-+	IPMI_CMD_OEM_FABRIC_INFO,
-+	1, 0,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_LINKMAP,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_DEPTH_CHART,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_ROUTING_TABLE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_STATS,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_STATS,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_CHANNEL_STATS,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_STATS,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS},
-+	{ IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t set_watch_cmd = {
-+	"set_watch",
-+	IPMI_CMD_OEM_FABRIC_SET_WATCH,
-+	1, 0,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_GLOBAL_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_CHANNEL_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_WATCH, 0},
-+	{ IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_HOST,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_FREQUENCY,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_AVERAGING_FREQUENCY},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_HOST, 0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t clear_watch_cmd = {
-+	"clear_watch",
-+	IPMI_CMD_OEM_FABRIC_CLEAR_WATCH,
-+	1, 0,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_GLOBAL_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_CHANNEL_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_WATCH,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_WATCH, 0},
-+	{ IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_HOST,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT, 0},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_HOST, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t trace_cmd = {
-+	"trace",
-+	IPMI_CMD_OEM_FABRIC_TRACE,
-+	1, 0,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_START,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_STOP,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_STATUS,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_DUMP, 0},
-+	{ IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_SIZE, 0},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+#define MAC_ADDRESS_SIZE    6
-+typedef uint8_t mac_address_t[MAC_ADDRESS_SIZE];
-+
-+#define IPV4_ADDRESS_SIZE   4
-+typedef uint8_t ipv4_address_t[IPV4_ADDRESS_SIZE];
-+
-+#define MAX_VAL_STRING 20
-+#define MAX_VAL_BITMAP 25
-+typedef union {
-+	uint8_t scalar[4];
-+	mac_address_t mac_addr;
-+	ipv4_address_t ipv4_addr;
-+	char string[MAX_VAL_STRING];
-+	uint8_t bitmap[MAX_VAL_BITMAP];
-+} cx_fabric_value_u;
-+
-+typedef struct {
-+	cx_fabric_arg_type_t val_type;
-+	cx_fabric_value_u val;
-+	uint8_t val_len;
-+} cx_fabric_value_t;
-+
-+typedef struct {
-+	char *keyword;
-+	uint8_t param;
-+	uint8_t required_specifiers[MAX_REQUIRED_SPECIFIERS];
-+	cx_fabric_arg_type_t val_type;
-+	int val_len;
-+	void (*printer) (void *data, int len);
-+} cx_fabric_param_t;
-+
-+typedef struct {
-+	char *keyword;
-+	uint8_t spec;
-+	cx_fabric_arg_type_t val_type;
-+	int val_len;
-+	void (*printer) (void *data, int len);
-+} cx_fabric_spec_t;
-+
-+void cx_fabric_string_printer(void *data, int len)
-+{
-+	int i;
-+	cx_fabric_value_t *val = (cx_fabric_value_t *) data;
-+	int value = 0;
-+
-+	printf("%s\n", val->val.string);
-+	return;
-+}
-+
-+void cx_fabric_bitmap_printer(void *data, int len)
-+{
-+	int i, in_range = 0, range_start = 0;
-+	int first = 1;
-+	cx_fabric_value_t *val = (cx_fabric_value_t *) data;
-+
-+	for (i = 0; i < MAX_VAL_BITMAP * 8; i++) {
-+		if (val->val.bitmap[i/8] & (1 << (i%8))) {
-+			if (in_range) {
-+				continue;
-+			} else {
-+				if (first) {
-+					printf("%d", i);
-+					first = 0;
-+				} else {
-+					printf(",%d", i);
-+				}
-+				range_start = i;
-+				in_range = 1;
-+			}
-+		} else if (in_range) {
-+			if (range_start != (i-1)) {
-+				printf("-%d", i-1);
-+			}
-+			in_range = 0;
-+		}
-+	}
-+
-+	if (in_range) {
-+		if (range_start != (i-1)) {
-+			printf("-%d", i-1);
-+		}
-+	} else if (first) {
-+		printf("No nodes in partition");
-+	}
-+
-+	printf("\n");
-+	return;
-+}
-+
-+void cx_fabric_scalar_printer(void *data, int len)
-+{
-+	int i;
-+	cx_fabric_value_t *val = (cx_fabric_value_t *) data;
-+	int value = 0;
-+
-+	for (i = 0; i < len; i++) {
-+		value |= (val->val.scalar[i] << (8 * i));
-+	}
-+	printf("%d\n", value);
-+	return;
-+}
-+
-+void cx_fabric_hex_printer(void *data, int len)
-+{
-+	int i;
-+	cx_fabric_value_t *val = (cx_fabric_value_t *) data;
-+	int value = 0;
-+
-+	for (i = 0; i < len; i++) {
-+		value |= (val->val.scalar[i] << (8 * i));
-+	}
-+	printf("0x%0x\n", (unsigned int)value);
-+	return;
-+}
-+
-+void cx_fabric_ipv4_printer(void *data, int len)
-+{
-+	cx_fabric_value_t *val = (cx_fabric_value_t *) data;
-+	printf("%d.%d.%d.%d\n", val->val.ipv4_addr[0],
-+	       val->val.ipv4_addr[1], val->val.ipv4_addr[2],
-+	       val->val.ipv4_addr[3]);
-+	return;
-+}
-+
-+void cx_fabric_mac_printer(void *data, int len)
-+{
-+	cx_fabric_value_t *val = (cx_fabric_value_t *) data;
-+	printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
-+	       val->val.mac_addr[0], val->val.mac_addr[1], val->val.mac_addr[2],
-+	       val->val.mac_addr[3], val->val.mac_addr[4],
-+	       val->val.mac_addr[5]);
-+	return;
-+}
-+
-+cx_fabric_param_t ipaddr_param = {
-+	"ipaddr",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_param_t ntp_server_param = {
-+	"ntp_server",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_SERVER,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_param_t ntp_port_param = {
-+	"ntp_port",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_PORT,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t ipsrc_param = {
-+	"ipsrc",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_IPSRC,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t netmask_param = {
-+	"netmask",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_NETMASK,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_param_t defgw_param = {
-+	"defgw",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_DEFGW,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_param_t nodeid_param = {
-+	"nodeid",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_NODEID,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t linkspeed_param = {
-+	"linkspeed",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED,
-+	{0, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_Scalar, 4,
-+	cx_fabric_string_printer
-+};
-+
-+cx_fabric_param_t link_resilience_param = {
-+	"link_resilience",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_RESILIENCE,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t linkspeed_policy_param = {
-+	"ls_policy",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED_POLICY,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t link_users_factor_param = {
-+	"lu_factor",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS_FACTOR,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t uplink_param = {
-+	"uplink",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t cust_macaddr_param = {
-+	"customer_macaddr",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_CUSTOMER_MACADDR,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_MAC_Address, 6,
-+	cx_fabric_mac_printer
-+};
-+
-+cx_fabric_param_t macaddr_param = {
-+	"macaddr",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDR,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE, 0, 0, 0, 0}
-+	,
-+	Cx_Fabric_Arg_Value_MAC_Address, 6,
-+	cx_fabric_mac_printer
-+};
-+
-+cx_fabric_param_t linkmap_param = {
-+	"linkmap",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINKMAP,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t depth_chart_param = {
-+	"depth_chart",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_DEPTH_CHART,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t routing_table_param = {
-+	"routing_table",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_ROUTING_TABLE,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t link_users_param = {
-+	"link_users",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t global_watch_param = {
-+	"global_watch",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_GLOBAL_WATCH,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t link_stats_param = {
-+	"link_stats",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_STATS,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t link_watch_param = {
-+	"link_watch_stats",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_WATCH,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t mac_stats_param = {
-+	"mac_stats",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_STATS,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t mac_watch_param = {
-+	"mac_watch",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_WATCH,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t mac_channel_stats_param = {
-+	"mac_channel_stats",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_CHANNEL_STATS,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t mac_channel_watch_param = {
-+	"mac_channel_watch",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_MAC_CHANNEL_WATCH,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t uplink_stats_param = {
-+	"uplink_stats",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_STATS,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t uplink_watch_param = {
-+	"uplink_watch",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_WATCH,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t configurationid_param = {
-+	"configid",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_CONFIGURATIONID,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t partitionid_param = {
-+	"partid",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITIONID,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t profileid_param = {
-+	"profileid",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_PROFILEID,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t partition_nodes_param = {
-+	"part_nodes",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_NODES,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t partition_range_param = {
-+	"part_range",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_PARTITION_RANGE,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Bitmap, MAX_VAL_BITMAP,
-+	cx_fabric_bitmap_printer
-+};
-+
-+cx_fabric_param_t ipaddr_base_param = {
-+	"ipaddr_base",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_BASE,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_param_t ipaddr_num_param = {
-+	"ipaddr_num",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_NUM,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t start_param = {
-+	"start",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_START,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t stop_param = {
-+	"stop",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_STOP,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t status_param = {
-+	"status",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_STATUS,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t dump_param = {
-+	"dump",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_DUMP,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP, 
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t node_spec = {
-+	"node",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_NODE,
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t interface_spec = {
-+	"interface",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t link_spec = {
-+	"link",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_LINK,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t override_spec = {
-+	"override",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_OVERRIDE,
-+	Cx_Fabric_Arg_Invalid, 0,
-+	NULL
-+};
-+
-+cx_fabric_spec_t actual_spec = {
-+	"actual",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_ACTUAL,
-+	Cx_Fabric_Arg_Invalid, 0,
-+	NULL
-+};
-+
-+cx_fabric_spec_t mac_spec = {
-+	"mac",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_MAC,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t tftp_spec = {
-+	"tftp",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP,
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_spec_t host_spec = {
-+	"host",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_HOST,
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_spec_t port_spec = {
-+	"port",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT,
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t frequency_spec = {
-+	"frequency",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_FREQUENCY,
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t averaging_frequency_spec = {
-+	"averaging_frequency",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_AVERAGING_FREQUENCY,
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t file_spec = {
-+	"file",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME,
-+	Cx_Fabric_Arg_Value_String, 20,
-+	cx_fabric_string_printer
-+};
-+
-+cx_fabric_spec_t configuration_spec = {
-+	"config",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_CONFIGURATION,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t partition_spec = {
-+	"part",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_PARTITION,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t profile_spec = {
-+	"profile",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_PROFILE,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t size_spec = {
-+	"size",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_SIZE,
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_arg_t cx_fabric_main_arg[] = {
-+	{"set_watch", Cx_Fabric_Arg_Command, (void *)&set_watch_cmd},
-+	{"clear_watch", Cx_Fabric_Arg_Command, (void *)&clear_watch_cmd},
-+	{"get", Cx_Fabric_Arg_Command, (void *)&get_cmd},
-+	{"set", Cx_Fabric_Arg_Command, (void *)&set_cmd},
-+	{"add", Cx_Fabric_Arg_Command, (void *)&add_cmd},
-+	{"rm", Cx_Fabric_Arg_Command, (void *)&rm_cmd},
-+	{"info", Cx_Fabric_Arg_Command, (void *)&info_cmd},
-+	{"update_config", Cx_Fabric_Arg_Command, (void *)&update_cmd},
-+	{"factory_default", Cx_Fabric_Arg_Command, (void *)&factory_default_node_cmd},
-+	{"trace", Cx_Fabric_Arg_Command, (void *)&trace_cmd},
-+	{"ipaddr_base", Cx_Fabric_Arg_Parameter, (void *)&ipaddr_base_param},
-+	{"ipaddr_num", Cx_Fabric_Arg_Parameter, (void *)&ipaddr_num_param},
-+	{"ipaddr", Cx_Fabric_Arg_Parameter, (void *)&ipaddr_param},
-+	{"ipsrc", Cx_Fabric_Arg_Parameter, (void *)&ipsrc_param},
-+	{"netmask", Cx_Fabric_Arg_Parameter, (void *)&netmask_param},
-+	{"ntp_server", Cx_Fabric_Arg_Parameter, (void *)&ntp_server_param},
-+	{"ntp_port", Cx_Fabric_Arg_Parameter, (void *)&ntp_port_param},
-+	{"defgw", Cx_Fabric_Arg_Parameter, (void *)&defgw_param},
-+	{"customer_macaddr", Cx_Fabric_Arg_Parameter, (void *)&cust_macaddr_param},
-+	{"macaddr", Cx_Fabric_Arg_Parameter, (void *)&macaddr_param},
-+	{"nodeid", Cx_Fabric_Arg_Parameter, (void *)&nodeid_param},
-+	{"linkspeed", Cx_Fabric_Arg_Parameter, (void *)&linkspeed_param},
-+	{"link_resilience", Cx_Fabric_Arg_Parameter, (void *)&link_resilience_param},
-+	{"ls_policy", Cx_Fabric_Arg_Parameter, (void *)&linkspeed_policy_param},
-+	{"lu_factor", Cx_Fabric_Arg_Parameter,
-+	 (void *)&link_users_factor_param},
-+	{"linkmap", Cx_Fabric_Arg_Parameter, (void *)&linkmap_param},
-+	{"depth_chart", Cx_Fabric_Arg_Parameter, (void *)&depth_chart_param},
-+	{"routing_table", Cx_Fabric_Arg_Parameter, (void *)&routing_table_param},
-+	{"link_users", Cx_Fabric_Arg_Parameter, (void *)&link_users_param},
-+	{"global_watch", Cx_Fabric_Arg_Parameter, (void *)&global_watch_param},
-+	{"link_stats", Cx_Fabric_Arg_Parameter, (void *)&link_stats_param},
-+	{"link_watch", Cx_Fabric_Arg_Parameter, (void *)&link_watch_param},
-+	{"mac_channel_stats", Cx_Fabric_Arg_Parameter,
-+			(void *)&mac_channel_stats_param},
-+	{"mac_channel_watch", Cx_Fabric_Arg_Parameter,
-+			(void *)&mac_channel_watch_param},
-+	{"mac_stats", Cx_Fabric_Arg_Parameter, (void *)&mac_stats_param},
-+	{"mac_watch", Cx_Fabric_Arg_Parameter, (void *)&mac_watch_param},
-+	{"uplink_stats", Cx_Fabric_Arg_Parameter, (void *)&uplink_stats_param},
-+	{"uplink_watch", Cx_Fabric_Arg_Parameter, (void *)&uplink_watch_param},
-+	{"uplink", Cx_Fabric_Arg_Parameter, (void *)&uplink_param},
-+	{"configid", Cx_Fabric_Arg_Parameter, (void *)&configurationid_param},
-+	{"partid", Cx_Fabric_Arg_Parameter, (void *)&partitionid_param},
-+	{"profileid", Cx_Fabric_Arg_Parameter, (void *)&profileid_param},
-+	{"part_nodes", Cx_Fabric_Arg_Parameter, (void *)&partition_nodes_param},
-+	{"part_range", Cx_Fabric_Arg_Parameter, (void *)&partition_range_param},
-+	{"start", Cx_Fabric_Arg_Parameter, (void *)&start_param},
-+	{"stop", Cx_Fabric_Arg_Parameter, (void *)&stop_param},
-+	{"status", Cx_Fabric_Arg_Parameter, (void *)&status_param},
-+	{"dump", Cx_Fabric_Arg_Parameter, (void *)&dump_param},
-+	{"node", Cx_Fabric_Arg_Specifier, (void *)&node_spec},
-+	{"interface", Cx_Fabric_Arg_Specifier, (void *)&interface_spec},
-+	{"link", Cx_Fabric_Arg_Specifier, (void *)&link_spec},
-+	{"override", Cx_Fabric_Arg_Specifier, (void *)&override_spec},
-+	{"actual", Cx_Fabric_Arg_Specifier, (void *)&actual_spec},
-+	{"mac", Cx_Fabric_Arg_Specifier, (void *)&mac_spec},
-+	{"tftp", Cx_Fabric_Arg_Specifier, (void *)&tftp_spec},
-+	{"host", Cx_Fabric_Arg_Specifier, (void *)&host_spec},
-+	{"port", Cx_Fabric_Arg_Specifier, (void *)&port_spec},
-+	{"size", Cx_Fabric_Arg_Specifier, (void *)&size_spec},
-+	{"frequency", Cx_Fabric_Arg_Specifier, (void *)&frequency_spec},
-+	{"averaging_frequency", Cx_Fabric_Arg_Specifier, (void *)&averaging_frequency_spec},
-+	{"file", Cx_Fabric_Arg_Specifier, (void *)&file_spec},
-+	{"config", Cx_Fabric_Arg_Specifier, (void *)&configuration_spec},
-+	{"part", Cx_Fabric_Arg_Specifier, (void *)&partition_spec},
-+	{"profile", Cx_Fabric_Arg_Specifier, (void *)&profile_spec},
-+	{NULL, Cx_Fabric_Arg_Invalid, (void *)NULL},
-+};
-+
-+cx_fabric_cmd_t config_get_cmd = {
-+	"get",
-+	IPMI_CMD_OEM_FABRIC_CONFIG_GET,
-+	1, 0,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_IPINFO,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPSRC,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MTU,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_MODE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDRS,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_SERVER,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_PORT,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_RESILIENCE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NODENUM_OFFSET,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_BASE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_NUM,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NETMASK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_DEFGW,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED_POLICY,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS_FACTOR,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_INFO,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LACP_STATUS,
-+	},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_OVERRIDE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_ACTUAL,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	},
-+	{
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	}
-+};
-+
-+cx_fabric_cmd_t config_set_cmd = {
-+	"set",
-+	IPMI_CMD_OEM_FABRIC_CONFIG_SET,
-+	1, 1,
-+	{IPMI_CMD_OEM_FABRIC_PARAMETER_IPINFO,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPSRC,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MTU,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_MODE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDRS,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_SERVER,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_PORT,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_RESILIENCE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NODENUM_OFFSET,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_BASE,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_IPADDR_NUM,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_NETMASK,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_DEFGW,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED_POLICY,
-+	 IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_USERS_FACTOR,
-+	},
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_OVERRIDE,
-+	 IPMI_CMD_OEM_FABRIC_SPECIFIER_INTERFACE,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	},
-+	{IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	 IPMI_CMD_OEM_SPECIFIER_UNDEF,
-+	}
-+};
-+
-+cx_fabric_cmd_t update_config_cmd = {
-+	"update_config",
-+	IPMI_CMD_OEM_FABRIC_UPDATE_CONFIG,
-+	0, 0,
-+	{0, 0, 0, 0, 0},
-+	{0, 0, 0, 0, 0},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_cmd_t factory_default_cmd = {
-+	"factory_default",
-+	IPMI_CMD_OEM_FABRIC_FACTORY_DEFAULT,
-+	0, 0,
-+	{0, 0, 0, 0, 0},
-+	{0, 0, 0, 0, 0},
-+	{0, 0, 0, 0, 0}
-+};
-+
-+cx_fabric_param_t ipinfo_config_param = {
-+	"ipinfo",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_IPINFO,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Invalid, 0,
-+	NULL
-+};
-+
-+cx_fabric_param_t uplink_info_config_param = {
-+	"uplink_info",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_INFO,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Invalid, 0,
-+	NULL
-+};
-+
-+cx_fabric_param_t lacp_status_config_param = {
-+	"lacp_status",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LACP_STATUS,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 4,
-+	cx_fabric_hex_printer
-+};
-+
-+cx_fabric_param_t ntp_server_config_param = {
-+	"ntp_server",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_SERVER,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_param_t ntp_port_config_param = {
-+	"ntp_port",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_NTP_PORT,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t nodenum_offset_config_param = {
-+	"nodenum_offset",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_NODENUM_OFFSET,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t ipsrc_config_param = {
-+	"ipsrc",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_IPSRC,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t mtu_config_param = {
-+	"mtu",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_MTU,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t uplink_mode_config_param = {
-+	"uplink_mode",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_UPLINK_MODE,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t macaddrs_config_param = {
-+	"macaddrs",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_MACADDRS,
-+	{IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME, 0, 0, 0},
-+	Cx_Fabric_Arg_Invalid, 0,
-+	NULL
-+};
-+
-+cx_fabric_param_t linkspeed_config_param = {
-+	"linkspeed",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 4,
-+	cx_fabric_string_printer
-+};
-+
-+cx_fabric_param_t link_resilience_config_param = {
-+	"link_resilience",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINK_RESILIENCE,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_param_t linkspeed_policy_config_param = {
-+	"ls_policy",
-+	IPMI_CMD_OEM_FABRIC_PARAMETER_LINKSPEED_POLICY,
-+	{0, 0, 0, 0, 0},
-+	Cx_Fabric_Arg_Value_Scalar, 1,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t tftp_config_spec = {
-+	"tftp",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_TFTP,
-+	Cx_Fabric_Arg_Value_IPV4_Address, 4,
-+	cx_fabric_ipv4_printer
-+};
-+
-+cx_fabric_spec_t port_config_spec = {
-+	"port",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_PORT,
-+	Cx_Fabric_Arg_Value_Scalar, 2,
-+	cx_fabric_scalar_printer
-+};
-+
-+cx_fabric_spec_t file_config_spec = {
-+	"file",
-+	IPMI_CMD_OEM_FABRIC_SPECIFIER_FILENAME,
-+	Cx_Fabric_Arg_Value_String, 20,
-+	cx_fabric_string_printer
-+};
-+
-+cx_fabric_arg_t cx_fabric_config_arg[] = {
-+	{"get", Cx_Fabric_Arg_Command, (void *)&config_get_cmd},
-+	{"set", Cx_Fabric_Arg_Command, (void *)&config_set_cmd},
-+	{"update_config", Cx_Fabric_Arg_Command, (void *)&update_config_cmd},
-+	{"factory_default", Cx_Fabric_Arg_Command, (void *)&factory_default_cmd},
-+	{"ipinfo", Cx_Fabric_Arg_Parameter, (void *)&ipinfo_config_param},
-+	{"uplink_info", Cx_Fabric_Arg_Parameter, (void *)&uplink_info_config_param},
-+	{"lacp_status", Cx_Fabric_Arg_Parameter, (void *)&lacp_status_config_param},
-+	{"ntp_server", Cx_Fabric_Arg_Parameter, (void *)&ntp_server_config_param},
-+	{"ntp_port", Cx_Fabric_Arg_Parameter, (void *)&ntp_port_config_param},
-+	{"nodenum_offset", Cx_Fabric_Arg_Parameter, (void *)&nodenum_offset_config_param},
-+	{"ipsrc", Cx_Fabric_Arg_Parameter, (void *)&ipsrc_config_param},
-+	{"mtu", Cx_Fabric_Arg_Parameter, (void *)&mtu_config_param},
-+	{"uplink_mode", Cx_Fabric_Arg_Parameter,
-+	 (void *)&uplink_mode_config_param},
-+	{"uplink", Cx_Fabric_Arg_Parameter, (void *)&uplink_param},
-+	{"macaddrs", Cx_Fabric_Arg_Parameter, (void *)&macaddrs_config_param},
-+	{"linkspeed", Cx_Fabric_Arg_Parameter, (void *)&linkspeed_config_param},
-+	{"link_resilience", Cx_Fabric_Arg_Parameter,
-+	 (void *)&link_resilience_config_param},
-+	{"ls_policy", Cx_Fabric_Arg_Parameter,
-+	 (void *)&linkspeed_policy_config_param},
-+	{"lu_factor", Cx_Fabric_Arg_Parameter,
-+	 (void *)&link_users_factor_param},
-+	{"ipaddr_base", Cx_Fabric_Arg_Parameter, (void *)&ipaddr_base_param},
-+	{"ipaddr_num", Cx_Fabric_Arg_Parameter, (void *)&ipaddr_num_param},
-+	{"netmask", Cx_Fabric_Arg_Parameter, (void *)&netmask_param},
-+	{"defgw", Cx_Fabric_Arg_Parameter, (void *)&defgw_param},
-+	{"tftp", Cx_Fabric_Arg_Specifier, (void *)&tftp_config_spec},
-+	{"port", Cx_Fabric_Arg_Specifier, (void *)&port_config_spec},
-+	{"file", Cx_Fabric_Arg_Specifier, (void *)&file_config_spec},
-+	{"override", Cx_Fabric_Arg_Specifier, (void *)&override_spec},
-+	{"interface", Cx_Fabric_Arg_Specifier, (void *)&interface_spec},
-+	{NULL, Cx_Fabric_Arg_Invalid, (void *)NULL},
-+};
-+
-+cx_fabric_arg_type_t
-+cx_fabric_find_arg_type(cx_fabric_arg_t * arg_type_list, char *arg)
-+{
-+	int i, ip0, ip1, ip2, ip3;
-+	int mac0, mac1, mac2, mac3, mac4, mac5;
-+	int ls0, ls1;
-+	int val;
-+	int ret;
-+
-+	errno = 0;
-+
-+	// First see if it is a standard type (Command, Parameter, Specifier)
-+	i = 0;
-+	while (arg_type_list[i].keyword != NULL) {
-+		if ((strlen(arg) == strlen(arg_type_list[i].keyword)) &&
-+		    !strncasecmp(arg, arg_type_list[i].keyword,
-+				 strlen(arg_type_list[i].keyword))) {
-+			return arg_type_list[i].arg_type;
-+		}
-+		i++;
-+	}
-+
-+	// If not, is it an expected value type (Scalar, String,
-+	//              IPV4 address, MAC address
-+
-+	// Is it a MAC Address?
-+	if ((sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x",
-+		    &mac0, &mac1, &mac2, &mac3, &mac4, &mac5)) == 6) {
-+		return Cx_Fabric_Arg_Value_MAC_Address;
-+	}
-+	// Is it an IPV4 Address?
-+	if ((sscanf(arg, "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3)) == 4) {
-+		return Cx_Fabric_Arg_Value_IPV4_Address;
-+	}
-+
-+	if ((sscanf(arg, "%d.%d", &ls0, &ls1)) == 2) {
-+		return Cx_Fabric_Arg_Value_Scalar;
-+	}
-+
-+	// Is it a string?
-+	if (isalpha(arg[0])) {
-+		// Probably...
-+		return Cx_Fabric_Arg_Value_String;
-+	}
-+
-+	// Is it a node range?
-+	if (strchr(arg, '-') || strchr(arg, ',')) {
-+		return Cx_Fabric_Arg_Value_Bitmap;
-+	}
-+
-+	// Is it scalar?
-+	val = strtol(arg, NULL, 10);
-+	if (errno == 0) {
-+		return Cx_Fabric_Arg_Value_Scalar;
-+	}
-+
-+	return Cx_Fabric_Arg_Invalid;
-+}
-+
-+cx_fabric_cmd_t *cx_fabric_get_cmd(cx_fabric_arg_t * arg_type_list, char *arg)
-+{
-+	int i;
-+
-+	errno = 0;
-+
-+	i = 0;
-+	while (arg_type_list[i].keyword != NULL) {
-+		if (!strncasecmp(arg, arg_type_list[i].keyword,
-+				 strlen(arg_type_list[i].keyword))) {
-+			return ((cx_fabric_cmd_t *) arg_type_list[i].data);
-+		}
-+		i++;
-+	}
-+	return NULL;
-+}
-+
-+cx_fabric_param_t *cx_fabric_get_param(cx_fabric_arg_t * arg_type_list,
-+				       char *arg)
-+{
-+	int i;
-+
-+	errno = 0;
-+
-+	i = 0;
-+	while (arg_type_list[i].keyword != NULL) {
-+		if (!strncasecmp(arg, arg_type_list[i].keyword,
-+				 strlen(arg_type_list[i].keyword))) {
-+			return ((cx_fabric_param_t *) arg_type_list[i].data);
-+		}
-+		i++;
-+	}
-+	return NULL;
-+}
-+
-+cx_fabric_spec_t *cx_fabric_get_spec(cx_fabric_arg_t * arg_type_list, char *arg)
-+{
-+	int i;
-+
-+	errno = 0;
-+
-+	i = 0;
-+	while (arg_type_list[i].keyword != NULL) {
-+		if (!strncasecmp(arg, arg_type_list[i].keyword,
-+				 strlen(arg_type_list[i].keyword))) {
-+			return ((cx_fabric_spec_t *) arg_type_list[i].data);
-+		}
-+		i++;
-+	}
-+	return NULL;
-+}
-+
-+int ranges_to_bitmap(char *arg, uint8_t *bitmap)
-+{
-+	int start, end, i = 0;
-+	char *ptr = arg;
-+	while(*ptr) {
-+		//printf("ptr = %s\n", ptr);
-+		start = strtol(ptr, &ptr, 10);
-+		if (*ptr == '-') {
-+			ptr++;
-+			end = strtol(ptr, &ptr, 10);
-+			for (i = start; i <= end; i++) {
-+				bitmap[i/8] |= (1 << (i%8));
-+			}
-+		} else {
-+			bitmap[start/8] |= (1 << (start%8));
-+		}
-+
-+		if (*ptr == ',') {
-+			ptr++;
-+		}
-+	}
-+}
-+
-+int
-+cx_fabric_get_value(cx_fabric_arg_type_t val_type, char *arg,
-+		    cx_fabric_value_t * value)
-+{
-+	int val;
-+	int i;
-+
-+	value->val_type = val_type;
-+	switch (val_type) {
-+	case Cx_Fabric_Arg_Value_Scalar:
-+		val = strtol(arg, NULL, 10);
-+		value->val.scalar[0] = val & 0xff;
-+		value->val.scalar[1] = ((val >> 8) & 0xff);
-+		value->val.scalar[2] = ((val >> 16) & 0xff);
-+		value->val.scalar[3] = ((val >> 24) & 0xff);
-+		value->val_len = 4;
-+		break;
-+	case Cx_Fabric_Arg_Value_String:
-+		strncpy(value->val.string, arg, MAX_VAL_STRING);
-+		value->val_len = strlen(value->val.string);
-+		break;
-+	case Cx_Fabric_Arg_Value_IPV4_Address:
-+		sscanf(arg, "%d.%d.%d.%d",
-+		       (int *)&value->val.ipv4_addr[0],
-+		       (int *)&value->val.ipv4_addr[1],
-+		       (int *)&value->val.ipv4_addr[2],
-+		       (int *)&value->val.ipv4_addr[3]);
-+		value->val_len = 4;
-+		break;
-+	case Cx_Fabric_Arg_Value_MAC_Address:
-+		sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x",
-+		       (int *)&value->val.mac_addr[0],
-+		       (int *)&value->val.mac_addr[1],
-+		       (int *)&value->val.mac_addr[2],
-+		       (int *)&value->val.mac_addr[3],
-+		       (int *)&value->val.mac_addr[4],
-+		       (int *)&value->val.mac_addr[5]);
-+		value->val_len = 6;
-+		fprintf(stdout, "ADDR = %02x:%02x:%02x:%02x:%02x:%02x\n",
-+			value->val.mac_addr[0], value->val.mac_addr[1],
-+			value->val.mac_addr[2], value->val.mac_addr[3],
-+			value->val.mac_addr[4], value->val.mac_addr[5]);
-+
-+		break;
-+	case Cx_Fabric_Arg_Value_Bitmap:
-+		memset(value->val.bitmap, 0, MAX_VAL_BITMAP);
-+		ranges_to_bitmap(arg, value->val.bitmap);
-+		value->val_len = MAX_VAL_BITMAP;
-+		break;
-+	default:
-+		return -1;
-+		break;
-+	};
-+	return 0;
-+}
-+
-+#define MAX_SPECS 8
-+int
-+cx_fabric_cmd_parser(struct ipmi_intf *intf,
-+		     cx_fabric_arg_t * args, int argc, char **argv)
-+{
-+	int ret, i, j, cur_arg = 0;
-+	cx_fabric_arg_type_t arg_type;
-+	struct ipmi_rq req;
-+	struct ipmi_rs *rsp;
-+	uint8_t msg_data[128];
-+	cx_fabric_cmd_t *cmd = NULL;
-+	cx_fabric_param_t *param = NULL;
-+	cx_fabric_value_t param_value;
-+	cx_fabric_spec_t *spec[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-+	cx_fabric_value_t spec_value[MAX_SPECS];
-+	uint8_t spec_count = 0, req_specs = 0, req_specs_found = 0;
-+	int data_pos = 0;
-+
-+
-+	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
-+		cx_fabric_usage();
-+		return 0;
-+	}
-+
-+	param_value.val_type = Cx_Fabric_Arg_Invalid;
-+	memset(&spec_value[0], 0, MAX_SPECS * sizeof(cx_fabric_value_t));
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, 128);
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+
-+	// Each argument is either a command, a parameter, a value, or a specifier
-+	// Commands are config, get, set, update
-+	// Parameters are ipaddr, ipsrc, netmask, defgw, macaddr,
-+	//    linkspeed, uplink
-+	// Specifiers are node, interface
-+	// Values can be a decimal number, ipv4 address, mac address, or
-+	//    the strings "static" or "dynamic"
-+
-+	while (cur_arg < argc) {
-+	        //printf("argv[%d] = .%s.\n", cur_arg, argv[cur_arg]);
-+		arg_type = cx_fabric_find_arg_type(args, argv[cur_arg]);
-+
-+		if (arg_type == Cx_Fabric_Arg_Command) {
-+			cmd = cx_fabric_get_cmd(args, argv[cur_arg]);
-+			if (cmd == NULL) {
-+				lprintf(LOG_NOTICE,
-+					"No defined activity for cmd %s\n",
-+					argv[cur_arg]);
-+				cur_arg++;
-+				continue;
-+			}
-+			req.msg.cmd = cmd->ipmi_cmd;
-+		} else if (arg_type == Cx_Fabric_Arg_Parameter) {
-+			param = cx_fabric_get_param(args, argv[cur_arg]);
-+
-+			if ((cmd && cmd->parameter_value_expected) &&
-+			    (param->val_type != Cx_Fabric_Arg_Invalid)) {
-+
-+				if ((cur_arg + 1) >= argc) {
-+					lprintf(LOG_ERR,
-+						"No value specified for parameter %s\n",
-+						param->keyword);
-+					return -1;
-+
-+				}
-+				// Now we need to look at its value
-+				cur_arg++;
-+
-+				arg_type = cx_fabric_find_arg_type(args,
-+								   argv
-+								   [cur_arg]);
-+				if ((arg_type == Cx_Fabric_Arg_Value_Scalar) && (param->val_type == Cx_Fabric_Arg_Value_Bitmap)) {
-+					arg_type = Cx_Fabric_Arg_Value_Bitmap;
-+				}
-+				if (arg_type != param->val_type) {
-+					lprintf(LOG_ERR,
-+						"Invalid value type for parameter %s\n",
-+						param->keyword);
-+					return -1;
-+				}
-+
-+				ret =
-+				    cx_fabric_get_value(arg_type, argv[cur_arg],
-+							&param_value);
-+			} else if (!cmd) {
-+				lprintf(LOG_ERR,
-+					"No valid command specified\n");
-+				goto cx_fabric_main_error_out;
-+			}
-+		} else if (arg_type == Cx_Fabric_Arg_Specifier) {
-+			spec[spec_count] =
-+			    cx_fabric_get_spec(args, argv[cur_arg]);
-+
-+			if (spec[spec_count]->val_type != Cx_Fabric_Arg_Invalid) {
-+
-+				cur_arg++;
-+
-+				if ((cur_arg) >= argc) {
-+					lprintf(LOG_ERR,
-+						"No  value specified for specifier %s\n",
-+						spec[spec_count]->keyword);
-+					return -1;
-+
-+				}
-+				// Now we need to look at its value
-+				arg_type = cx_fabric_find_arg_type(args,
-+								   argv
-+								   [cur_arg]);
-+				if (arg_type != spec[spec_count]->val_type) {
-+					lprintf(LOG_ERR,
-+						"Invalid value type for specifier %s\n",
-+						spec[spec_count]->keyword);
-+					return -1;
-+				}
-+
-+				ret =
-+				    cx_fabric_get_value(arg_type, argv[cur_arg],
-+							&spec_value
-+							[spec_count]);
-+			} else {
-+				spec_value[spec_count].val_type =
-+				    Cx_Fabric_Arg_Invalid;
-+				spec_value[spec_count].val.scalar[0] = 0;
-+				spec_value[spec_count].val_len = 1;
-+
-+			}
-+			spec_count++;
-+		} else {
-+			lprintf(LOG_ERR, "Unexpected argument\n");
-+			goto cx_fabric_main_error_out;
-+		}
-+
-+		cur_arg++;
-+	}
-+
-+	if (cmd == NULL) {
-+		goto cx_fabric_main_error_out;
-+	}
-+	// Now, sanity check everything before forming the message
-+	// Does this command require a parameter, if so do we have one?
-+	if (cmd->parameter_required) {
-+		if (param == NULL) {
-+			lprintf(LOG_ERR,
-+				"Required parameter for cmd %s missing\n",
-+				cmd->keyword);
-+			goto cx_fabric_main_error_out;
-+
-+		}
-+	}
-+	// Does this command accept the parameter being passed?
-+	if (param) {
-+		for (i = 0; i < MAX_PERMITTED_PARAMS; i++) {
-+			if (param->param == cmd->permitted_params[i]) {
-+				break;
-+			}
-+		}
-+		if (i == MAX_PERMITTED_PARAMS) {
-+			lprintf(LOG_ERR,
-+				"Parameter %s not permitted for cmd %s\n",
-+				param->keyword, cmd->keyword);
-+			goto cx_fabric_main_error_out;
-+		}
-+	}
-+	// Does this command accept the specifiers that are given
-+	for (j = 0; j < MAX_SPECS; j++) {
-+		if (spec[j]) {
-+			for (i = 0; i < MAX_PERMITTED_SPECIFIERS; i++) {
-+				if (spec[j]->spec ==
-+				    cmd->permitted_specifiers[i]) {
-+					break;
-+				}
-+			}
-+			if (i == MAX_PERMITTED_SPECIFIERS) {
-+				lprintf(LOG_ERR,
-+					"Specifier %s not permitted for cmd %s\n",
-+					spec[j]->keyword, cmd->keyword);
-+				goto cx_fabric_main_error_out;
-+			}
-+		}
-+	}
-+	// Are all required specifiers for the command present?
-+	for (j = 0; j < MAX_REQUIRED_SPECIFIERS; j++) {
-+		if (cmd->required_specifiers[j] != 0) {
-+			req_specs++;
-+			for (i = 0; i < MAX_SPECS; i++) {
-+				if (spec[i]) {
-+					if (spec[i]->spec ==
-+					    cmd->required_specifiers[j]) {
-+						req_specs_found++;
-+					}
-+				}
-+			}
-+		}
-+	}
-+	if (req_specs != req_specs_found) {
-+		lprintf(LOG_ERR, "Required specifiers for command %s missing\n",
-+			cmd->keyword);
-+		goto cx_fabric_main_error_out;
-+	}
-+	// Are all the required specifiers for the parameter present
-+	if (param) {
-+		for (j = 0; j < MAX_REQUIRED_SPECIFIERS; j++) {
-+			if (param->required_specifiers[j] != 0) {
-+				req_specs++;
-+				for (i = 0; i < MAX_SPECS; i++) {
-+					if (spec[i]) {
-+						if (spec[i]->spec ==
-+						    param->
-+						    required_specifiers[j]) {
-+							req_specs_found++;
-+						}
-+					}
-+				}
-+			}
-+		}
-+	}
-+	if (req_specs != req_specs_found) {
-+		lprintf(LOG_ERR,
-+			"Required specifiers for parameter %s missing\n",
-+			param->keyword);
-+		goto cx_fabric_main_error_out;
-+	}
-+	// Start filling in msg_data
-+	if (param) {
-+		msg_data[data_pos++] = param->param;
-+
-+		if (param_value.val_type != Cx_Fabric_Arg_Invalid) {
-+			switch (param_value.val_type) {
-+			case Cx_Fabric_Arg_Value_Scalar:
-+				msg_data[data_pos++] =
-+				    MSG_PARAM_VAL_START_SCALAR;
-+				for (i = 0; i < param_value.val_len; i++) {
-+					msg_data[data_pos++] =
-+					    param_value.val.scalar[i];
-+				}
-+				msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+				break;
-+			case Cx_Fabric_Arg_Value_String:
-+				msg_data[data_pos++] =
-+				    MSG_PARAM_VAL_START_STRING;
-+				for (i = 0; i < param_value.val_len; i++) {
-+					msg_data[data_pos++] =
-+					    param_value.val.string[i];
-+				}
-+				msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+				break;
-+			case Cx_Fabric_Arg_Value_IPV4_Address:
-+				msg_data[data_pos++] =
-+				    MSG_PARAM_VAL_START_IPV4_ADDR;
-+				for (i = 0; i < param_value.val_len; i++) {
-+					msg_data[data_pos++] =
-+					    param_value.val.ipv4_addr[i];
-+				}
-+				msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+				break;
-+			case Cx_Fabric_Arg_Value_MAC_Address:
-+				msg_data[data_pos++] =
-+				    MSG_PARAM_VAL_START_MAC_ADDR;
-+				for (i = 0; i < param_value.val_len; i++) {
-+					msg_data[data_pos++] =
-+					    param_value.val.mac_addr[i];
-+				}
-+				msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+				break;
-+			case Cx_Fabric_Arg_Value_Bitmap:
-+				msg_data[data_pos++] =
-+				    MSG_PARAM_VAL_START_BITMAP;
-+				for (i = 0; i < param_value.val_len; i++) {
-+					msg_data[data_pos++] =
-+					    param_value.val.bitmap[i];
-+				}
-+				msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+				break;
-+			}
-+		}
-+	}
-+	for (j = 0; j < spec_count; j++) {
-+		msg_data[data_pos++] = spec[j]->spec;
-+		switch (spec[j]->val_type) {
-+		case Cx_Fabric_Arg_Value_Scalar:
-+			for (i = 0; i < spec_value[j].val_len; i++) {
-+				msg_data[data_pos++] =
-+				    spec_value[j].val.scalar[i];
-+			}
-+			msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+			break;
-+		case Cx_Fabric_Arg_Value_String:
-+			for (i = 0; i < spec_value[j].val_len; i++) {
-+				msg_data[data_pos++] =
-+				    spec_value[j].val.string[i];
-+			}
-+			msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+			break;
-+		case Cx_Fabric_Arg_Value_IPV4_Address:
-+			for (i = 0; i < spec_value[j].val_len; i++) {
-+				msg_data[data_pos++] =
-+				    spec_value[j].val.ipv4_addr[i];
-+			}
-+			msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+			break;
-+		case Cx_Fabric_Arg_Value_MAC_Address:
-+			for (i = 0; i < spec_value[j].val_len; i++) {
-+				msg_data[data_pos++] =
-+				    spec_value[j].val.mac_addr[i];
-+			}
-+			msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+			break;
-+		case Cx_Fabric_Arg_Value_Bitmap:
-+			msg_data[data_pos++] =
-+			    MSG_PARAM_VAL_START_BITMAP;
-+			for (i = 0; i < param_value.val_len; i++) {
-+				msg_data[data_pos++] =
-+				    param_value.val.bitmap[i];
-+			}
-+			msg_data[data_pos++] = MSG_ELEMENT_TERMINATOR;
-+			break;
-+		}
-+	}
-+
-+	req.msg.data = msg_data;
-+	req.msg.data_len = data_pos;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+//	lprintf(LOG_ERR, "req: netfn: 0x%x, lun: 0x%x, \n"
-+//	        "cmd: 0x%x, target_cmd: 0x%x, data_len: 0x%x\n"
-+//	        "data: \n"
-+//	        "%02x %02x %02x %02x %02x %02x %02x %02x \n"
-+//	        "%02x %02x %02x %02x %02x %02x %02x %02x \n",
-+//	        req.msg.netfn, req.msg.lun, req.msg.cmd,
-+//	        req.msg.target_cmd, req.msg.data_len,
-+//	        req.msg.data[0], req.msg.data[1], req.msg.data[2], req.msg.data[3],
-+//	        req.msg.data[4], req.msg.data[5], req.msg.data[6], req.msg.data[7],
-+//	        req.msg.data[8], req.msg.data[9], req.msg.data[10], req.msg.data[11],
-+//	        req.msg.data[12], req.msg.data[13], req.msg.data[14], req.msg.data[15]);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error during fabric command\n");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode == 0) {
-+		if ((cmd->ipmi_cmd == IPMI_CMD_OEM_FABRIC_GET) ||
-+		    ((cmd->ipmi_cmd == IPMI_CMD_OEM_FABRIC_CONFIG_GET) &&
-+		     (param->val_len))) {
-+			memcpy(param_value.val.scalar, rsp->data,
-+			       param->val_len);
-+			param->printer(&param_value, param->val_len);
-+		}
-+	} else {
-+		lprintf(LOG_ERR, "Command failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	return 0;
-+
-+cx_fabric_main_error_out:
-+//      cx_fabric_usage();
-+	return -1;
-+}
-+
-+int cx_fabric_main(struct ipmi_intf *intf, int argc, char **argv)
-+{
-+	if ((argc > 1) && (!strcmp("config", argv[0]))) {
-+		cx_fabric_cmd_parser(intf, cx_fabric_config_arg, argc - 1,
-+				     &argv[1]);
-+	} else {
-+		cx_fabric_cmd_parser(intf, cx_fabric_main_arg, argc, &argv[0]);
-+	}
-+}
-+
-+static void cx_data_usage(void)
-+{
-+	lprintf(LOG_NOTICE,
-+		"\n"
-+		"Usage: ipmitool cxoem data <type> <command> [option...]\n"
-+		"\n"
-+		"Data Commands: \n"
-+		"\n"
-+		"  mem  <read/write> <width>  <address> [fmt] [data] \n"
-+		"  cdb  <read/write> <length> <cid> [fmt] [data] \n"
-+		"where fmt is an optional formatting hint, one of,\n"
-+		"    'int' -- decimal integer\n"
-+		"    'uint' -- unsigned decimal integer\n"
-+		"    'xint' -- a hexadecimal integer\n"
-+		"    'ascii' -- an ascii string\n"
-+		"    'xstr' -- a byte string expressed in hex (i.e. 01ef23)\n"
-+		"\n");
-+}
-+
-+static void cx_info_usage(void)
-+{
-+	lprintf(LOG_NOTICE,
-+		"\n"
-+		"Usage: ipmitool cxoem info <Type>\n"
-+		"\n"
-+		"Type Commands: \n"
-+		"\n"
-+		"  basic \n" "  partnum \n" "  chassis \n" "  card \n" "  node \n" "\n");
-+}
-+
-+/* Interpret the string pointed to by valrep according to the length contraint
-+   and the claimed format.  Put the result byte-by-byte into the out array.
-+   Use the fmt parameter to decide whether to make integer values
-+   little-endian (ints are encoded little-endian).
-+*/
-+static int
-+asc_to_bin(const char *valrep, int length, int fmt, unsigned char *out)
-+{
-+	int i;
-+	const char *p;
-+	unsigned int intval = 0;
-+	memset(out, 0, length);
-+	// the string types (ascii and xstr) are easy: they just get stuffed
-+	// into the output, byte-for-byte
-+	if (fmt == CX_DATA_FMT_ASCII) {
-+		for (i = 0; i < length && valrep[i]; i++)
-+			out[i] = (unsigned int)valrep[i];
-+	} else if (fmt == CX_DATA_FMT_XSTR) {
-+		int vallen = strlen(valrep);
-+		if (vallen & 1) {	// input can't have an odd number of chars
-+			lprintf(LOG_ERR,
-+				"<value> must have an even number of hex digits\n");
-+			return CX_DATA_BAD_VALUE;
-+		}
-+		if (vallen < (2 * length)) {
-+			lprintf(LOG_ERR, "<value> must have enough characters "
-+				"to encode <length> bytes.\n");
-+			return CX_DATA_BAD_VALUE;
-+		}
-+		p = valrep;
-+		if (strncmp(valrep, "0x", 2) == 0 ||
-+		    strncmp(valrep, "0X", 2) == 0)
-+			p += 2;
-+		for (i = 0; i < length && *p; i++) {
-+			char byterep[3];
-+			int j = 2 * i;
-+			byterep[0] = *p++;
-+			byterep[1] = *p++;
-+			byterep[2] = 0;
-+			out[i] = strtoul(byterep, NULL, 16);
-+			if (errno) {
-+				lprintf(LOG_ERR,
-+					"<value> is not a valid hex string\n");
-+				return CX_DATA_BAD_VALUE;
-+			}
-+		}
-+	}
-+	// For the integer types we have to get the value, then
-+	// pack the out buffer little-endian.  Fortunately, this is the
-+	// same for memory locations and cdb values, so all we have to
-+	// worry about is length, which is guaranteed to be 1 or 4.
-+	else {
-+		if (length < 1 || length > 4) {
-+			lprintf(LOG_ERR, "<width> must be either 1 or 4\n");
-+			return CX_DATA_BAD_LENGTH;
-+		}
-+		if (fmt == CX_DATA_FMT_INT) {
-+			intval = (unsigned int)strtol(valrep, NULL, 10);
-+		} else if (fmt == CX_DATA_FMT_UINT) {
-+			intval = strtoul(valrep, NULL, 10);
-+		} else if (fmt == CX_DATA_FMT_XINT) {
-+			intval = strtoul(valrep, NULL, 16);
-+		}
-+		if (errno) {
-+			lprintf(LOG_ERR,
-+				"<value> is not a valid integer value.\n");
-+			return CX_DATA_BAD_VALUE;
-+		}
-+		out[0] = intval & 0xff;
-+		if (length == 4) {
-+			out[1] = (intval >> 8) & 0xff;
-+			out[2] = (intval >> 16) & 0xff;
-+			out[3] = (intval >> 24) & 0xff;
-+		}
-+	}
-+	return CX_DATA_OK;
-+}
-+
-+/*
-+  Print a value or a series of values according to the specified format.
-+  This function can present one or more ints or bytes.  Ints are space-
-+  separated.  Bytes are not separated.
-+*/
-+static int print_value(int length, int format, const unsigned char *value)
-+{
-+	int rc = CX_DATA_OK;
-+	int datatype = CX_DATA_INT_TYPE;
-+	char *prntfmt = "0x%08x";
-+	printf("Value    :");
-+	if (length > 0) {
-+		switch (format) {
-+		case CX_DATA_FMT_INT:
-+			datatype = CX_DATA_INT_TYPE;
-+			prntfmt = " %d";
-+			break;
-+		case CX_DATA_FMT_UINT:
-+			datatype = CX_DATA_INT_TYPE;
-+			prntfmt = " %u";
-+			break;
-+		case CX_DATA_FMT_XINT:
-+			datatype = CX_DATA_INT_TYPE;
-+			prntfmt = " 0x%08x";
-+			break;
-+		case CX_DATA_FMT_ASCII:
-+			datatype = CX_DATA_BYTE_TYPE;
-+			prntfmt = "%c";
-+			break;
-+		case CX_DATA_FMT_XSTR:
-+			datatype = CX_DATA_BYTE_TYPE;
-+			prntfmt = "%02x";
-+			break;
-+		}		// switch
-+		if (datatype == CX_DATA_INT_TYPE) {	// integer
-+			int i;
-+			if (length == 1) {
-+				printf(prntfmt, value[0]);
-+			} else {
-+				for (i = 0; (4 * i) + 3 < length; i++) {
-+					int n = i * 4;
-+					unsigned int iv;
-+					iv = ((unsigned int)value[n + 3] << 24)
-+					    +
-+					    ((unsigned int)value[n + 2] << 16) +
-+					    ((unsigned int)value[n + 1] << 8) +
-+					    (unsigned int)value[n];
-+					printf(prntfmt, iv);
-+				}
-+			}
-+		} else {	// string data
-+			int i;
-+			printf(" ");
-+			for (i = 0; i < length; i++) {
-+				printf(prntfmt, value[i]);
-+			}
-+		}
-+		printf("\n");
-+	} else {
-+		rc = CX_DATA_BAD_LENGTH;
-+	}
-+	return rc;
-+}
-+
-+/*  Execute commands to access the configuration data base
-+        Initialize the ipmi message
-+	Send the message
-+        On a read:
-+          print the value returned.
-+*/
-+int
-+cx_data_cdb(struct ipmi_intf *intf, int access, int length,
-+	    unsigned int cid, unsigned int fmt, unsigned char *value)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[8 + MAX_RETURNABLE_CDB_LEN];
-+	char out[5];
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, sizeof(msg_data));
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_DATA_ACCESS;
-+	msg_data[0] = 2;	// 2 = cdb access
-+	msg_data[1] = access;	// direction, i.e. read/write
-+	msg_data[2] = length & 0xff;
-+	msg_data[3] = (length >> 8) & 0xff;
-+	msg_data[4] = cid & 0xff;
-+	msg_data[5] = (cid >> 8) & 0xff;
-+	msg_data[6] = (cid >> 16) & 0xff;
-+	msg_data[7] = (cid >> 24) & 0xff;
-+	if (access == CX_DATA_ACCESS_WRITE) {
-+		memcpy((void *)(msg_data + 8), (void *)value, length);
-+		req.msg.data_len = length + 8;
-+	} else {
-+		req.msg.data_len = 8;
-+	}
-+	req.msg.data = msg_data;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error during cdb data command\n");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "cxoem data cdb command failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	if ((rsp->ccode == 0) && (access == CX_DATA_ACCESS_READ)) {
-+		unsigned int value;
-+		unsigned int dlength = 0;
-+		unsigned int actual_length = 0;
-+		int n = 2;
-+		int datatype = 1;
-+		const char *prntfmt = " %d";
-+
-+		actual_length = rsp->data[0] & 0xff;
-+		actual_length |= (rsp->data[1] << 8) & 0xff;
-+		dlength = rsp->data[2] & 0xff;
-+		dlength |= (rsp->data[3] << 8) & 0xff;
-+		if (dlength > MAX_RETURNABLE_CDB_LEN) {
-+			printf("CDB read length too lengthy\n");
-+			return -1;
-+		}
-+		printf("Data size: %d\n", dlength);
-+		printf("CID size :  %d\n", actual_length);
-+		print_value(dlength, fmt, &rsp->data[4]);
-+	}
-+	return rc;
-+}
-+
-+
-+
-+
-+/*  Execute commands to access cxoem memory mapped registers
-+       Initialize the msg
-+       Send the msg
-+       On a read:
-+          print the value returned.
-+ */
-+int
-+cx_data_mem(struct ipmi_intf *intf, int access, int width,
-+	    unsigned int address, int fmt, const char *value)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[16];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, sizeof(msg_data));
-+	req.msg.netfn = IPMI_NETFN_OEM_SS;
-+	req.msg.cmd = IPMI_CMD_OEM_DATA_ACCESS;
-+	msg_data[0] = 1;	// 1 = memory access
-+	msg_data[1] = (access == CX_DATA_ACCESS_READ) ? 1 : 2;
-+	msg_data[2] = width;
-+	msg_data[3] = address & 0xff;
-+	msg_data[4] = (address >> 8) & 0xff;
-+	msg_data[5] = (address >> 16) & 0xff;
-+	msg_data[6] = (address >> 24) & 0xff;
-+	if (access == CX_DATA_ACCESS_WRITE) {
-+		msg_data[7] = value[0];
-+		if (width > 1) {
-+			msg_data[8] = value[1];
-+			msg_data[9] = value[2];
-+			msg_data[10] = value[3];
-+		}
-+		req.msg.data_len = 11;
-+	} else {
-+		req.msg.data_len = 7;
-+	}
-+	req.msg.data = msg_data;
-+
-+	rsp = intf->sendrecv(intf, &req);
-+	if (rsp == NULL) {
-+		lprintf(LOG_ERR, "Error during cxoem data mem command\n");
-+		return -1;
-+	}
-+
-+	if (rsp->ccode > 0) {
-+		lprintf(LOG_ERR, "cxoem data mem command failed: %s",
-+			val2str(rsp->ccode, completion_code_vals));
-+		return -1;
-+	}
-+
-+	if ((rsp->ccode == 0) && (access == CX_DATA_ACCESS_READ)) {
-+		print_value(width, fmt, rsp->data);
-+	}
-+
-+	return rc;
-+}
-+
-+static int str_to_fmt(const char *fmtstr)
-+{
-+	struct _sftbl {
-+		const char *fmtstr;
-+		unsigned int fmt;
-+	};
-+	struct _sftbl sftbl[] = {
-+		{"int", CX_DATA_FMT_INT},
-+		{"uint", CX_DATA_FMT_UINT},
-+		{"xint", CX_DATA_FMT_XINT},
-+		{"ascii", CX_DATA_FMT_ASCII},
-+		{"xstr", CX_DATA_FMT_XSTR},
-+		{0, 0}
-+	};
-+	int i;
-+	for (i = 0; sftbl[i].fmtstr; i++)
-+		if (!strcmp(fmtstr, sftbl[i].fmtstr))
-+			return sftbl[i].fmt;
-+	lprintf(LOG_ERR,
-+		"<fmt> isn't a valid format\n"
-+		"It sould be one of 'int', 'uint',"
-+		"'xint', 'ascii or 'xstr', or omitted.\n");
-+	return CX_DATA_FMT_DEFAULT;
-+}
-+
-+/* For the cxoem data read/write mem n command,
-+      edit the data length (n) -- we handle only byte and word access for mem
-+      extract the address
-+      for reads:
-+         extract the optional formatting hint
-+      for writes:
-+         extract the optional formatting hint
-+         extract the value to be written
-+      access the memory
-+ */
-+static int
-+cx_data_mem_main(struct ipmi_intf *intf, int argc, char **argv,
-+		 int access, int length)
-+{
-+	int ret = 0;
-+	unsigned int addr;
-+	int fmt = CX_DATA_FMT_DEFAULT;
-+	const char *valptr = argv[4];
-+
-+	if (length < 1 || length > 64) {
-+		lprintf(LOG_ERR, "<length> out of range. must be 1-64\n");
-+		return -1;
-+	}
-+	addr = strtoul(argv[3], (char **)NULL, 16);
-+	unsigned char value[4];
-+	if (!errno) {
-+		printf("Addr     : %08x\n", addr);
-+	} else {
-+		lprintf(LOG_ERR, "<addr> doesn't look like a valid value\n");
-+		return -1;
-+	}
-+
-+	if (access == CX_DATA_ACCESS_READ && argc > 4) {
-+		fmt = str_to_fmt(argv[4]);
-+		if (fmt == CX_DATA_FMT_DEFAULT) {
-+			return -1;
-+		}
-+	}
-+	if (access == CX_DATA_ACCESS_WRITE) {
-+		if (argc > 5) {
-+			fmt = str_to_fmt(argv[4]);
-+			valptr = argv[5];
-+		} else if (argc > 4) {
-+			fmt = CX_DATA_FMT_XINT;
-+			valptr = argv[4];
-+		} else {
-+			lprintf(LOG_ERR, "<value> wasn't specified\n");
-+			return -1;
-+		}
-+		if (fmt != CX_DATA_FMT_INT)
-+			fmt = CX_DATA_FMT_XINT;
-+		if (asc_to_bin(valptr, length, fmt, value) == CX_DATA_OK) {
-+			print_value(length, fmt, value);
-+		} else {
-+			return -1;
-+		}
-+	}
-+	return cx_data_mem(intf, access, length, addr, fmt, value);
-+
-+}
-+
-+/* For the cxoem data read/write mem n command,
-+      Extract the CID (configuration id)
-+      On a read:
-+         extract the optional format hint.
-+      On a write:
-+         extract the optional format hint.
-+         extract the data to be written
-+      Access the cdb
-+ */
-+static int
-+cx_data_cdb_main(struct ipmi_intf *intf, int argc,
-+		 char **argv, int access, int length)
-+{
-+	int width = 4;		// default to 4-bytes
-+	unsigned int addr;
-+	int fmt = CX_DATA_FMT_DEFAULT;
-+	unsigned char value[MAX_RETURNABLE_CDB_LEN];
-+	unsigned int cid = 0;
-+	char *valptr = argv[4];
-+
-+	cid = strtoul(argv[3], (char **)NULL, 16);
-+	if (!errno) {
-+		printf("Cid      : %08x\n", cid);
-+	} else {
-+		lprintf(LOG_ERR, "<cid> doesn't look like a valid value\n");
-+		return -1;
-+	}
-+
-+	if (access == CX_DATA_ACCESS_READ && argc > 4) {
-+		fmt = str_to_fmt(argv[4]);
-+		if (fmt == CX_DATA_FMT_DEFAULT) {
-+			return -1;
-+		}
-+	}
-+	if (access == CX_DATA_ACCESS_WRITE) {
-+		// at this point, we have either a value or a format and
-+		// value left to parse from the cmdline.
-+		if (argc > 5) {
-+			fmt = str_to_fmt(argv[4]);
-+			valptr = argv[5];
-+		} else if (argc > 4) {
-+			fmt = CX_DATA_FMT_XSTR;
-+			valptr = argv[4];
-+		} else {
-+			lprintf(LOG_ERR, "<value> wasn't specified\n");
-+			return -1;
-+		}
-+		if (asc_to_bin(valptr, length, fmt, value) != CX_DATA_OK) {
-+			return -1;
-+		} else {
-+			print_value(length, fmt, value);
-+		}
-+	}
-+	if (fmt == CX_DATA_FMT_DEFAULT)
-+		fmt = CX_DATA_FMT_XSTR;
-+	return cx_data_cdb(intf, access, length, cid, fmt, value);
-+}
-+
-+static int get_access(int argc, char **argv)
-+{
-+	int access = CX_DATA_ACCESS_UNKNOWN;
-+	if (argc > 1) {
-+		if (strncmp(argv[1], "read", 4) == 0)
-+			access = CX_DATA_ACCESS_READ;
-+		else if (strncmp(argv[1], "write", 4) == 0)
-+			access = CX_DATA_ACCESS_WRITE;
-+	}
-+	return access;
-+}
-+
-+/*  For the cxoem data command, extract the common fields:
-+       target (cdb or memory)
-+       access (read or write)
-+       length of data
-+    then call the appropriate handler for the target.
-+*/
-+static int cx_data_main(struct ipmi_intf *intf, int argc, char **argv)
-+{
-+	int rv = 0;
-+	int target = CX_DATA_TARGET_UNKNOWN;
-+	int length = 0;
-+	int maxwidth = 64;
-+	int access;
-+	errno = 0;
-+
-+	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
-+		cx_data_usage();
-+		return 0;
-+	}
-+	if (strncmp(argv[0], "mem", 3) == 0) {
-+		target = CX_DATA_TARGET_MEM;
-+	} else if (strncmp(argv[0], "cdb", 3) == 0) {
-+		target = CX_DATA_TARGET_CDB;
-+		maxwidth = MAX_RETURNABLE_CDB_LEN;
-+	} else {
-+		cx_data_usage();
-+		rv = -1;
-+	}
-+	access = get_access(argc, argv);
-+	if ((access == CX_DATA_ACCESS_READ && argc < 4) ||
-+	    (access == CX_DATA_ACCESS_WRITE && argc < 5) ||
-+	    access == CX_DATA_ACCESS_UNKNOWN) {
-+		cx_data_usage();
-+		return -1;
-+	}
-+
-+	length = strtol(argv[2], (char **)NULL, 10);
-+	if (!errno) {
-+		if (length < 1 || length > maxwidth) {
-+			lprintf(LOG_ERR, "<length> out of range\n");
-+			return -1;
-+		} else {
-+			printf("Length   : %d\n", length);
-+		}
-+	} else {
-+		lprintf(LOG_ERR, "<length> doesn't look like a valid value\n");
-+		return -1;
-+	}
-+
-+
-+	switch (target) {
-+	case CX_DATA_TARGET_MEM:
-+		rv = cx_data_mem_main(intf, argc, argv, access, length);
-+		break;
-+	case CX_DATA_TARGET_CDB:
-+		rv = cx_data_cdb_main(intf, argc, argv, access, length);
-+		break;
-+	default:
-+		cx_data_usage();
-+		rv = -1;
-+	}
-+
-+	return rv;
-+}
-+
-+#define MAX_MSG_DATA_SIZE 	256
-+/**
-+ * Generic Execute IPMI command
-+ *
-+ * @param intf       IPMI Interface
-+ *
-+ * @param net_fn     Net Function
-+ * @param command    Command to be send
-+ * @param input_buf  Input Buffer that contains the data
-+ * @param input_bufsize
-+ *                   Input Buffer Size.  Must be less than or equal to 256
-+ * @param output_buf IPMI Response will be stored here.
-+ * @param output_bufsize
-+ *                   Buffer size of the output_buffer, and on return it
-+ *                   contains the actual number of bytes of data
-+ * @param completion_code
-+ *                   Command completion code
-+ *
-+ * @return 0  = successful
-+ *         -1 = failure
-+ */
-+int
-+cx_send_ipmi_cmd(struct ipmi_intf *intf,
-+		 uint8_t net_fn, uint8_t command,
-+		 uint8_t * input_buf, int input_bufsize,
-+		 uint8_t * output_buf, int *output_bufsize,
-+		 uint8_t * completion_code)
-+{
-+	int rc = CXOEM_SUCCESS;
-+	struct ipmi_rs *rsp;
-+	struct ipmi_rq req;
-+	uint8_t msg_data[MAX_MSG_DATA_SIZE];
-+
-+	memset(&req, 0, sizeof(req));
-+	memset(msg_data, 0, sizeof(msg_data));
-+	if (input_bufsize > MAX_MSG_DATA_SIZE) {
-+		lprintf(LOG_ERR,
-+			"[cx_send_ipmi_cmd] message length exceeded.\n");
-+		return -1;
-+	}
-+	req.msg.netfn = net_fn;
-+	req.msg.cmd = command;
-+	if (input_bufsize) {
-+		if (input_buf) {
-+			memcpy(msg_data, input_buf, input_bufsize);
-+		} else {
-+			lprintf(LOG_ERR,
-+				"[cx_send_ipmi_cmd] Input buffer is null.\n");
-+			rc = CXOEM_ERROR;
-+		}
-+	}
-+
-+	if (CXOEM_SUCCESS == rc) {
-+		req.msg.data = msg_data;
-+		req.msg.data_len = input_bufsize;
-+
-+		rsp = intf->sendrecv(intf, &req);
-+		if (rsp == NULL) {
-+			lprintf(LOG_ERR,
-+				"[cx_send_ipmi_cmd] sendrecv failed.\n");
-+			rc = CXOEM_ERROR;
-+		} else {
-+			*completion_code = rsp->ccode;
-+			if (rsp->data_len > *output_bufsize) {
-+				lprintf(LOG_ERR,
-+					"[cx_send_ipmi_cmd] output buffer size is too small: (%d, %d).\n",
-+					*output_bufsize, rsp->data_len);
-+				rc = CXOEM_ERROR;
-+			} else {
-+				*output_bufsize = rsp->data_len;
-+				if (rsp->data_len) {
-+					if (output_buf) {
-+						memcpy(output_buf, rsp->data,
-+						       rsp->data_len);
-+					} else {
-+						lprintf(LOG_ERR,
-+							"[cx_send_ipmi_cmd] output buffer is null.\n");
-+						rc = CXOEM_ERROR;
-+					}
-+				}
-+			}
-+
-+		}
-+	}
-+
-+	return rc;
-+}
-+
-+/**
-+ * Ping the "BMC" to see if this is Calxeda SoC
-+ *
-+ * @param intf     IPMI interface
-+ * @param to_print TRUE to print the result
-+ *                 FALSE not to print the result
-+ *
-+ * @return TRUE if this is Calxeda SoC
-+ *         FALSE otherwise.
-+ */
-+tboolean cx_is_CalxedaSoc(struct ipmi_intf * intf, tboolean to_print)
-+{
-+	tboolean is_Calxeda_soc = 0;	/* Assuming it's not Calxeda */
-+	int rv = 0;
-+	uint8_t rs_data[MAX_MSG_DATA_SIZE] = {0};
-+	int rs_data_size = MAX_MSG_DATA_SIZE;
-+	uint8_t completion_code = 0;
-+	cx_info_basic_t *basic_rs = (void *)rs_data;
-+
-+	rs_data[0] = 0x01;	/* Basic Info */
-+	rv = cx_send_ipmi_cmd(intf, IPMI_NETFN_OEM_SS,
-+			      IPMI_CMD_OEM_GET_DEVICE_INFO, rs_data, 1, rs_data,
-+			      &rs_data_size, &completion_code);
-+	if (rv == 0) {
-+		if (completion_code) {
-+			printf("command failed with 0x%X completion code\n",
-+			       completion_code & 0xFF);
-+		} else {
-+			time_t lt;
-+			if (0x96CD == basic_rs->rev1.iana) {
-+				is_Calxeda_soc = 1;
-+				if (to_print) {
-+					printf("Calxeda SoC (0x%6.6X)\n",
-+					       basic_rs->rev1.iana);
-+					if (basic_rs->rev1.parameter_revision == 1)
-+					{
-+						/* Revision 1 */
-+						printf("  Firmware Version: %s\n",
-+						       basic_rs->rev1.firmware_version);
-+						printf("  SoC Version: v%d.%d.%d\n",
-+						       basic_rs->rev1.ecme_major_version,
-+						       basic_rs->rev1.ecme_minor_version,
-+						       basic_rs->rev1.ecme_revision);
-+						printf("  Build Number: %X %s\n",
-+						       basic_rs->rev1.ecme_build_number,
-+						       ((basic_rs->rev1.
-+							 ecme_build_number & 0x0F) ==
-+							0x0D) ? "(Dirty)" : "");
-+						lt = basic_rs->rev1.ecme_timestamp;
-+						printf("  Timestamp (%d): %s\n",
-+						       basic_rs->rev1.ecme_timestamp,
-+						       asctime(localtime(&lt)));
-+					}
-+					else if (basic_rs->rev1.parameter_revision == 2)
-+					{
-+						/* Revision 2 */
-+						printf("  Firmware Version: %s\n",
-+						       basic_rs->rev2.firmware_version);
-+						printf("  SoC Version: %s\n",
-+						       basic_rs->rev2.ecme_version);
-+						lt = basic_rs->rev2.ecme_timestamp;
-+						printf("  Timestamp (%d): %s\n",
-+						       basic_rs->rev2.ecme_timestamp,
-+						       asctime(localtime(&lt)));
-+					}
-+					else
-+					{
-+						/* Don't know how to read it */
-+						printf("  Unknown parameter revision\n");
-+					}
-+				}
-+			} else {
-+				printf("This is not Calxeda SoC\n");
-+			}
-+		}
-+	}
-+	return is_Calxeda_soc;
-+}
-+
-+/*  For the cxoem info command, extract the common fields:
-+    then call the appropriate handler for the target.
-+*/
-+static int cx_info_main(struct ipmi_intf *intf, int argc, char **argv)
-+{
-+
-+	int rv = -1;		// Assuming error
-+	uint8_t rs_data[MAX_MSG_DATA_SIZE];
-+	int rs_data_size = MAX_MSG_DATA_SIZE;
-+	uint8_t completion_code;
-+	int i;
-+
-+	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
-+		cx_info_usage();
-+		return 0;
-+	}
-+	if (strncmp(argv[0], "basic", 5) == 0) {
-+		if (cx_is_CalxedaSoc(intf, TRUE)) {
-+			rv = 0;
-+		}
-+	} else if (strncmp(argv[0], "partnum", 7) == 0) {
-+		if (cx_is_CalxedaSoc(intf, FALSE)) {
-+		}
-+	} else if (strncmp(argv[0], "chassis", 7) == 0) {
-+		if (cx_is_CalxedaSoc(intf, FALSE)) {
-+		}
-+	} else if (strncmp(argv[0], "card", 4) == 0) {
-+		struct oem_device_info_card_s {
-+			uint16_t	card_id;
-+			uint16_t	card_rev;
-+		} __attribute__ ((packed));
-+		typedef struct oem_device_info_card_s oem_device_info_card_t;
-+		char board_type[32];
-+
-+		oem_device_info_card_t *card_rs;
-+		card_rs = (void *) rs_data;
-+
-+		if (cx_is_CalxedaSoc(intf, FALSE)) {
-+			rs_data[0] = 0x06;	/* Card Info */
-+			rv = cx_send_ipmi_cmd(intf, IPMI_NETFN_OEM_SS,
-+					      IPMI_CMD_OEM_GET_DEVICE_INFO,
-+					      rs_data, 1, rs_data,
-+					      &rs_data_size, &completion_code);
-+			if (rv == 0) {
-+				if (completion_code) {
-+					printf
-+					    ("command failed with 0x%X completion code\n",
-+					     completion_code & 0xFF);
-+					rv = -1;
-+				} else {
-+					switch (card_rs->card_id) {
-+					/* Case 0 isn't really energycard, but
-+					   old versions will return that, so
-+					   we'll just go with it. */
-+					case 0:
-+					case 1:
-+						strcpy(board_type, "EnergyCard");
-+						break;
-+					case 7:
-+						strcpy(board_type, "Slingshot");
-+						break;
-+					default:
-+						sprintf(board_type, "Unknown (%X)", card_rs->card_id);
-+						break;
-+					}
-+					printf("  Board Type: %s\n", board_type);
-+					printf("  Board Revision: %d\n", card_rs->card_rev);
-+				}
-+			}
-+
-+		}
-+	} else if (strncmp(argv[0], "node", 4) == 0) {
-+		struct oem_device_info_node_s {
-+			uint8_t oui[3];
-+			uint16_t fabric_node_id;
-+			uint8_t slot_number;
-+			uint8_t local_node_id;
-+		} __attribute__ ((packed));
-+		typedef struct oem_device_info_node_s oem_device_info_node_t;
-+
-+		oem_device_info_node_t *node_rs;
-+		node_rs = (void *)rs_data;
-+
-+		if (cx_is_CalxedaSoc(intf, FALSE)) {
-+			rs_data[0] = 0x04;	/* Node Info */
-+			rv = cx_send_ipmi_cmd(intf, IPMI_NETFN_OEM_SS,
-+					      IPMI_CMD_OEM_GET_DEVICE_INFO,
-+					      rs_data, 1, rs_data,
-+					      &rs_data_size, &completion_code);
-+			if (rv == 0) {
-+				if (completion_code) {
-+					printf("command failed with 0x%X completion code\n",
-+                           completion_code & 0xFF);
-+					rv = -1;
-+				} else {
-+					printf("OUI = 0x%X%X%X\n",
-+					       node_rs->oui[2], node_rs->oui[1],
-+					       node_rs->oui[0]);
-+					printf("Fabric Node ID = %d\n",
-+					       node_rs->fabric_node_id);
-+					printf("Slot Number = %d\n",
-+					       node_rs->slot_number);
-+					printf("Local Node ID = %d\n",
-+					       node_rs->local_node_id);
-+				}
-+			}
-+		}
-+	} else if (strncmp(argv[0], "wafer", 4) == 0) {
-+		struct oem_device_info_wafer_s {
-+			uint8_t wafer_info[16];
-+		} __attribute__ ((packed));
-+		typedef struct oem_device_info_wafer_s oem_device_info_wafer_t;
-+
-+		oem_device_info_wafer_t *wafer_rs;
-+		wafer_rs = (void *)rs_data;
-+
-+		if (cx_is_CalxedaSoc(intf, FALSE)) {
-+			rs_data[0] = 0x05;	/* Wafer Info */
-+			rv = cx_send_ipmi_cmd(intf, IPMI_NETFN_OEM_SS,
-+					      IPMI_CMD_OEM_GET_DEVICE_INFO,
-+					      rs_data, 1, rs_data,
-+					      &rs_data_size, &completion_code);
-+			if (rv == 0) {
-+				if (completion_code) {
-+					printf
-+					    ("command failed with 0x%X completion code\n",
-+					     completion_code & 0xFF);
-+					rv = -1;
-+				} else {
-+					char wafer_string[16];
-+					printf("Wafer Info\n");
-+					printf("   Raw : ");
-+					for (i = 0;
-+					     i < sizeof(wafer_rs->wafer_info);
-+					     i++) {
-+						printf("%2.2X ",
-+						       wafer_rs->
-+						       wafer_info[i] & 0xFF);
-+					}
-+					printf("\n");
-+					printf("   X-Coord	 : %d\n",
-+					       wafer_rs->wafer_info[0] & 0xFF);
-+					printf("   Y-Coord	 : %d\n",
-+					       wafer_rs->wafer_info[1] & 0xFF);
-+					printf("   Number 	 : %d\n",
-+					       wafer_rs->wafer_info[2] & 0xFF);
-+					memset(wafer_string, 0, 16);
-+					/*
-+					   for (i = 0; i < 8; i++) {
-+					   wafer_string[i] = wafer_rs->wafer_info[10-i];
-+					   }
-+					 */
-+					memcpy(wafer_string,
-+					       &(wafer_rs->wafer_info[3]), 8);
-+					printf("   Lot Number: %s\n",
-+					       wafer_string);
-+				}
-+			}
-+		}
-+	} else {
-+		cx_info_usage();
-+	}
-+	return rv;
-+}
-+
-+static const char *tps_to_string(unsigned char state)
-+{
-+	int num_elements;
-+
-+	num_elements = sizeof(tps_table)/sizeof(*tps_table);
-+	if (state < num_elements) {
-+		return tps_table[state];
-+	}
-+	return "";
-+}
-+
-+static int cx_feature_main(struct ipmi_intf *intf, int argc, char **argv)
-+{
-+	uint8_t rs_data[MAX_MSG_DATA_SIZE];
-+	int rs_data_size = MAX_MSG_DATA_SIZE;
-+	int rq_data_size = 0;
-+	uint8_t *rq_data;
-+	uint8_t completion_code;
-+	int get_op = 0;
-+	const struct valstr oem_features[] = {
-+		{0x01, "selaging"},
-+		{0x02, "hwwd"},
-+		{0x03, "tps"},
-+		{0x04, "mansen"},
-+		{0x00, "Invalid"},	// make sure this is the last entry
-+	};
-+	int rv = 0;
-+	int i;
-+	int feature_index = 0;
-+
-+	if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
-+		cx_feature_usage();
-+		return 0;
-+	}
-+
-+	rq_data = rs_data;
-+	if (strncmp(argv[0], "status", 6) == 0) {
-+		rq_data_size = 2;
-+		rq_data[0] = 2;	// Get Operation
-+		get_op = 1;
-+	} else if (strncmp(argv[0], "enable", 6) == 0) {
-+		rq_data[2] = 1;	// Enable
-+		rq_data_size = 3;
-+		rq_data[0] = 1;	// Set Operation
-+	} else if (strncmp(argv[0], "disable", 7) == 0) {
-+		rq_data[2] = 0;	// Disable
-+		rq_data_size = 3;
-+		rq_data[0] = 1;	// Set Operation
-+	} else {
-+		rv = -1;
-+	}
-+
-+	if (0 == rv) {
-+		i = 0;
-+		rv = -1;	// Assuming the feature specified cannot be found
-+		while (oem_features[i].val) {
-+			if (strncmp
-+			    (argv[1], oem_features[i].str,
-+			     strlen(oem_features[i].str)) == 0) {
-+				rq_data[1] = oem_features[i].val;
-+				rv = 0;
-+				feature_index = i;
-+				break;
-+			}
-+			i++;
-+		}
-+	}
-+
-+
-+	if (0 == rv) {
-+
-+		rv = cx_send_ipmi_cmd(intf, IPMI_NETFN_OEM_SS,
-+				      IPMI_CMD_OEM_FEATURES_ENABLE, rq_data,
-+				      rq_data_size, rs_data, &rs_data_size,
-+				      &completion_code);
-+		if (0 == rv) {
-+			if (get_op) {
-+				if (2 == feature_index) {
-+					printf("   %s state is %d %s\n", oem_features[feature_index].str,
-+						   rs_data[0], tps_to_string(rs_data[0]));
-+				} else {
-+					printf("   %s is %s\n",
-+						   oem_features[feature_index].str,
-+						   rs_data[0] ? "enabled" : "disabled");
-+				}
-+			}
-+		}
-+	}
-+
-+	if (rv) {
-+		cx_feature_usage();
-+	}
-+
-+	return rv;
-+}
-+
-+int ipmi_cxoem_main(struct ipmi_intf *intf, int argc, char **argv)
-+{
-+	int rc = 0;
-+
-+	if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
-+		ipmi_cxoem_usage();
-+		return 0;
-+	} else if (!strncmp(argv[0], "fw", 2)) {
-+		rc = cx_fw_main(intf, argc - 1, &argv[1]);
-+	} else if (!strncmp(argv[0], "fabric", 6)) {
-+		rc = cx_fabric_main(intf, argc - 1, &argv[1]);
-+	} else if (!strncmp(argv[0], "data", 4)) {
-+		rc = cx_data_main(intf, argc - 1, &argv[1]);
-+	} else if (!strncmp(argv[0], "info", 4)) {
-+		rc = cx_info_main(intf, argc - 1, &argv[1]);
-+	} else if (!strncmp(argv[0], "feature", 7)) {
-+		rc = cx_feature_main(intf, argc - 1, &argv[1]);
-+	}
-+
-+	return rc;
-+}
-diff --git a/lib/ipmi_lanp.c b/lib/ipmi_lanp.c
-index 060cbf7..98ddbb8 100644
---- a/lib/ipmi_lanp.c
-+++ b/lib/ipmi_lanp.c
-@@ -130,6 +130,7 @@ get_lan_param_select(struct ipmi_intf * intf, uint8_t chan, int param, int selec
- 			break;
- 		}
- 	}
-+	/* XXX: LEDVA iterate cxoem options too (rejected patch) */
- 
- 	if (p == NULL) {
- 		lprintf(LOG_INFO, "Get LAN Parameter failed: Unknown parameter.");
-@@ -747,6 +748,99 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
- 		printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
- 		       p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
- 
-+	p = get_lan_param(intf, chan, IPMI_LANP_TFTP_SERVER_IP);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL)
-+		printf("%-24s: %d.%d.%d.%d\n", p->desc,
-+		       p->data[0], p->data[1], p->data[2], p->data[3]);
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_NTP_SERVER_IP);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL)
-+		printf("%-24s: %d.%d.%d.%d\n", p->desc,
-+		       p->data[0], p->data[1], p->data[2], p->data[3]);
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_TFTP_UDP_PORT);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL) {
-+		int *port;
-+		port = (int *)&p->data[0];
-+		printf("%-24s: %d\n", p->desc, *port);
-+	}
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_NTP_UDP_PORT);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL) {
-+		int *port;
-+		port = (int *)&p->data[0];
-+		printf("%-24s: %d\n", p->desc, *port);
-+	}
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_OEM_MAC0);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL)
-+		printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
-+		       p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_OEM_MAC1);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL)
-+		printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
-+		       p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_OEM_MAC2);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL)
-+		printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
-+		       p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_OEM_OUID);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL)
-+		printf("%-24s: %02x:%02x:%02x\n", p->desc,
-+		       p->data[0], p->data[1], p->data[2]);
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_SC_OUID);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL)
-+		printf("%-24s: %02x:%02x:%02x\n", p->desc,
-+		       p->data[0], p->data[1], p->data[2]);
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_SC_MODE);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL) {
-+		printf("%-24s: ", p->desc);
-+		p->data[0] &= 0xf;
-+		switch (p->data[0]) {
-+		case 0:
-+			printf("Zero\n");
-+			break;
-+		case 1:
-+			printf("One\n");
-+			break;
-+		default:
-+			printf("Other\n");
-+			break;
-+		}
-+	}
-+
-+	p = get_lan_param(intf, chan, IPMI_LANP_SC_FID);
-+	if (p == NULL)
-+		return -1;
-+	if (p->data != NULL) {
-+		printf("%-24s: %02X\n", p->desc, p->data[0]);
-+	}
-+
- 	p = get_lan_param(intf, chan, IPMI_LANP_VLAN_ID);
- 	if (p != NULL && p->data != NULL) {
- 		int id = ((p->data[1] & 0x0f) << 8) + p->data[0];
-@@ -1175,6 +1269,21 @@ get_cmdline_macaddr(char * arg, uint8_t * buf)
- 
- 
- static int
-+get_cmdline_ouiaddr(char * arg, uint8_t * buf)
-+{
-+	uint32_t m1, m2, m3;
-+	if (sscanf(arg, "%02x:%02x:%02x",
-+		   &m1, &m2, &m3) != 3) {
-+		lprintf(LOG_ERR, "Invalid OUI address: %s", arg);
-+		return -1;
-+	}
-+	buf[0] = (uint8_t)m1;
-+	buf[1] = (uint8_t)m2;
-+	buf[2] = (uint8_t)m3;
-+	return 0;
-+}
-+
-+static int
- get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
- {
- 	int i, ret = 0;
-@@ -1251,6 +1360,19 @@ get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
- 	return ret;
- }
- 
-+static int
-+get_cmdline_int(char * arg, uint8_t * buf)
-+{
-+	uint32_t port;
-+	if (sscanf(arg, "%d", &port) != 1) {
-+		lprintf(LOG_ERR, "Invalid port address: %s", arg);
-+		return -1;
-+	}
-+	buf[1] = (port & 0xff00) >> 8;
-+	buf[0] = (port & 0xff);
-+	return 0;
-+}
-+
- 
- static int
- get_cmdline_ipaddr(char * arg, uint8_t * buf)
-@@ -1278,6 +1400,10 @@ static void ipmi_lan_set_usage(void)
- 	lprintf(LOG_NOTICE, "  defgw macaddr <x:x:x:x:x:x>    Set default gateway MAC address");
- 	lprintf(LOG_NOTICE, "  bakgw ipaddr <x.x.x.x>         Set backup gateway IP address");
- 	lprintf(LOG_NOTICE, "  bakgw macaddr <x:x:x:x:x:x>    Set backup gateway MAC address");
-+	lprintf(LOG_NOTICE, "  tftp  ipaddr <x.x.x.x>         Set tftp server    IP address");
-+	lprintf(LOG_NOTICE, "  ntp   ipaddr <x.x.x.x>         Set ntp server     IP address");
-+	lprintf(LOG_NOTICE, "  tftp port    <num>             Set tftp server UDP port num ");
-+	lprintf(LOG_NOTICE, "  ntp  port    <num>             Set ntp  server UDP port num ");
- 	lprintf(LOG_NOTICE, "  password <password>            Set session password for this channel");
- 	lprintf(LOG_NOTICE, "  snmp <community string>        Set SNMP public community string");
- 	lprintf(LOG_NOTICE, "  user                           Enable default user for this channel");
-@@ -1743,6 +1869,158 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
- 			rc = set_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS, data, 9);
- 		}
- 	}
-+	else if (strncmp(argv[1], "tftp", 4) == 0) {
-+		if (argc < 4 || (strncmp(argv[2], "help", 4) == 0)) {
-+			lprintf(LOG_NOTICE, "LAN set tftp Commands: ipaddr, port");
-+		}
-+		else if ((strncmp(argv[2], "ipaddr", 5) == 0) &&
-+			 (get_cmdline_ipaddr(argv[3], data) == 0)) {
-+			printf("Setting tftp ip %s to %d.%d.%d.%d\n",
-+			       ipmi_lan_params[28].desc,
-+			       data[0], data[1], data[2], data[3]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_TFTP_SERVER_IP, data, 4);
-+		}
-+		else if ((strncmp(argv[2], "port", 4) == 0) &&
-+			 (get_cmdline_int(argv[3], data) == 0)) {
-+			printf("Setting tftp port %s to %02x%02x\n",
-+			       ipmi_lan_params[29].desc,
-+			       data[1], data[0]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_TFTP_UDP_PORT, data, 2);
-+		}
-+		else {
-+			ipmi_lan_set_usage();
-+			return -1;
-+		}
-+	}		
-+	else if (strncmp(argv[1], "ntp", 3) == 0) {
-+		if (argc < 4 || (strncmp(argv[2], "help", 4) == 0)) {
-+			lprintf(LOG_NOTICE, "LAN set ntp Commands: ipaddr, port");
-+		}
-+		else if ((strncmp(argv[2], "ipaddr", 5) == 0) &&
-+			 (get_cmdline_ipaddr(argv[3], data) == 0)) {
-+			printf("Setting ntp ip %s to %d.%d.%d.%d\n",
-+			       ipmi_lan_params[30].desc,
-+			       data[0], data[1], data[2], data[3]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_NTP_SERVER_IP, data, 4);
-+		}
-+		else if ((strncmp(argv[2], "port", 4) == 0) &&
-+			 (get_cmdline_int(argv[3], data) == 0)) {
-+			printf("Setting ntp port %s to %02x%02x\n",
-+			       ipmi_lan_params[31].desc,
-+			       data[1], data[0]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_NTP_UDP_PORT, data, 2);
-+		}
-+		else {
-+			ipmi_lan_set_usage();
-+			return -1;
-+		}
-+	}		
-+	else if (strncmp(argv[1], "oem_mac0", 8) == 0) {
-+		if(argc != 3)
-+		{
-+			ipmi_lan_set_usage();
-+			return -1;
-+		}
-+		rc = get_cmdline_macaddr(argv[2], data);
-+		if (rc == 0) {
-+			printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
-+		       		ipmi_lan_params[IPMI_LANP_OEM_MAC0].desc,
-+		       		data[0], data[1], data[2], data[3], data[4], data[5]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_OEM_MAC0, data, 6);
-+		}
-+	}
-+	else if (strncmp(argv[1], "oem_mac1", 8) == 0) {
-+		if(argc != 3)
-+		{
-+			ipmi_lan_set_usage();
-+			return -1;
-+		}
-+		rc = get_cmdline_macaddr(argv[2], data);
-+		if (rc == 0) {
-+			printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
-+		       		ipmi_lan_params[IPMI_LANP_OEM_MAC1].desc,
-+		       		data[0], data[1], data[2], data[3], data[4], data[5]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_OEM_MAC1, data, 6);
-+		}
-+	}
-+	else if (strncmp(argv[1], "oem_mac2", 8) == 0) {
-+		if(argc != 3)
-+		{
-+			ipmi_lan_set_usage();
-+			return -1;
-+		}
-+		rc = get_cmdline_macaddr(argv[2], data);
-+		if (rc == 0) {
-+			printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
-+		       		ipmi_lan_params[IPMI_LANP_OEM_MAC2].desc,
-+		       		data[0], data[1], data[2], data[3], data[4], data[5]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_OEM_MAC2, data, 6);
-+		}
-+	}
-+	else if (strncmp(argv[1], "oem_ouid", 8) == 0) {
-+		if(argc != 3)
-+		{
-+			ipmi_lan_set_usage();
-+			return -1;
-+		}
-+		rc = get_cmdline_ouiaddr(argv[2], data);
-+		if (rc == 0) {
-+			printf("Setting LAN %s to %02x:%02x:%02x\n",
-+		       		ipmi_lan_params[IPMI_LANP_OEM_OUID].desc,
-+		       		data[0], data[1], data[2]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_OEM_OUID, data, 3);
-+		}
-+	}
-+	else if (strncmp(argv[1], "sc_ouid", 7) == 0) {
-+		if(argc != 3)
-+		{
-+			ipmi_lan_set_usage();
-+			return -1;
-+		}
-+		rc = get_cmdline_ouiaddr(argv[2], data);
-+		if (rc == 0) {
-+			printf("Setting LAN %s to %02x:%02x:%02x\n",
-+		       		ipmi_lan_params[IPMI_LANP_SC_OUID].desc,
-+		       		data[0], data[1], data[2]);
-+			rc = set_lan_param(intf, chan, IPMI_LANP_SC_OUID, data, 3);
-+		}
-+	}
-+	else if (strncmp(argv[1], "sc_mode", 7) == 0) {
-+		if (argc < 3 || (strncmp(argv[2], "help", 4) == 0)) {
-+			lprintf(LOG_NOTICE,
-+				"lan set <channel> sc_mode <mode>\n"
-+				"  off = zero\n"
-+				"  on  = one\n");
-+			return 0;
-+		}
-+		else if (strncmp(argv[2], "off", 3) == 0)
-+			data[0] = 0;
-+		else if (strncmp(argv[2], "on", 2) == 0)
-+			data[0] = 1;
-+		else {
-+			lprintf(LOG_NOTICE,
-+				"lan set <channel> sc_mode <mode>\n"
-+				"  off = zero\n"
-+				"  on  = one\n");
-+			return -1;
-+		}
-+			printf("Setting LAN %s to %02x\n",
-+		       		ipmi_lan_params[IPMI_LANP_SC_OUID].desc,
-+		       		data[0]);
-+		rc = set_lan_param(intf, chan, IPMI_LANP_SC_MODE, data, 1);
-+	}
-+	else if (strncasecmp(argv[1], "sc_fid", 6) == 0) {
-+		if (argc < 3 || (strncmp(argv[2], "help", 4) == 0)) {
-+			lprintf(LOG_NOTICE,
-+				"lan set <channel> sc_fid <fid>\n");
-+			return 0;
-+		}
-+		data[0] = (uint8_t)strtol(argv[2], NULL, 0);
-+		printf("Setting LAN %s to %02x\n",
-+		       	ipmi_lan_params[IPMI_LANP_SC_OUID].desc,
-+		       	data[0]);
-+		rc = set_lan_param(intf, chan, IPMI_LANP_SC_FID, data, 1);
-+	}
- 	else {
- 		ipmi_lan_set_usage();
- 		return (-1);
-@@ -1872,6 +2150,13 @@ ipmi_lan_alert_set_usage(void)
- 	lprintf(LOG_NOTICE, "    type <pet|oem1|oem2>           Set destination type as PET or OEM");
- 	lprintf(LOG_NOTICE, "    time <seconds>                 Set ack timeout or unack retry interval");
- 	lprintf(LOG_NOTICE, "    retry <number>                 Set number of alert retries");
-+	lprintf(LOG_NOTICE, "    oem_mac0 <x:x:x:x:x:x>         Set OEM MAC address");
-+	lprintf(LOG_NOTICE, "    oem_mac1 <x:x:x:x:x:x>         Set OEM MAC address");
-+	lprintf(LOG_NOTICE, "    oem_mac2 <x:x:x:x:x:x>         Set OEM MAC address");
-+	lprintf(LOG_NOTICE, "    oem_ouid <x:x:x>               Set OEM OUID address");
-+	lprintf(LOG_NOTICE, "    sc_ouid <x:x:x>                Set Supercluster OUID address");
-+	lprintf(LOG_NOTICE, "    sc_mode <on|off>               Set Supercluster mode");
-+	lprintf(LOG_NOTICE, "    sc_fid  <fid>                  Set Supercluster FID");
- 	lprintf(LOG_NOTICE, "");
- }
- 
-diff --git a/lib/ipmi_strings.c b/lib/ipmi_strings.c
-index 277b82f..57e3609 100644
---- a/lib/ipmi_strings.c
-+++ b/lib/ipmi_strings.c
-@@ -157,6 +157,7 @@ const struct valstr ipmi_netfn_vals[] = {
- 	{ IPMI_NETFN_FIRMWARE,	"Firmware" },
- 	{ IPMI_NETFN_STORAGE,	"Storage" },
- 	{ IPMI_NETFN_TRANSPORT,	"Transport" },
-+	{ IPMI_NETFN_CX_OEM,	"cx_oem" },
- 	{ 0xff,			NULL },
- };
- 
-diff --git a/src/ipmitool.c b/src/ipmitool.c
-index 6230e5c..51a7b67 100644
---- a/src/ipmitool.c
-+++ b/src/ipmitool.c
-@@ -65,6 +65,7 @@
- #include <ipmitool/ipmi_ekanalyzer.h>
- #include <ipmitool/ipmi_ime.h>
- #include <ipmitool/ipmi_dcmi.h>
-+#include <ipmitool/ipmi_cxoem.h>
- 
- #ifdef HAVE_CONFIG_H
- # include <config.h>
-@@ -105,6 +106,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = {
- 	{ ipmi_session_main, "session", "Print session information" },
-     { ipmi_dcmi_main,    "dcmi",    "Data Center Management Interface"},
- 	{ ipmi_sunoem_main,  "sunoem",  "OEM Commands for Sun servers" },
-+	{ ipmi_cxoem_main,   "cxoem",   "OEM Commands for Calxeda servers" },
- 	{ ipmi_kontronoem_main, "kontronoem", "OEM Commands for Kontron devices"},
- 	{ ipmi_picmg_main,   "picmg",   "Run a PICMG/ATCA extended cmd"},
- 	{ ipmi_fwum_main,    "fwum",	"Update IPMC using Kontron OEM Firmware Update Manager" },
-diff --git a/src/plugins/lan/lan.c b/src/plugins/lan/lan.c
-index e088479..f35ee6c 100644
---- a/src/plugins/lan/lan.c
-+++ b/src/plugins/lan/lan.c
-@@ -253,6 +253,8 @@ ipmi_lan_recv_packet(struct ipmi_intf * intf)
- 	if (ret < 0 || FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set))
- 		return NULL;
- 
-+	memset(&rsp, 0, sizeof(rsp));
-+
- 	/* the first read may return ECONNREFUSED because the rmcp ping
- 	 * packet--sent to UDP port 623--will be processed by both the
- 	 * BMC and the OS.
diff --git a/SOURCES/ipmitool-1.8.13-bootparam.patch b/SOURCES/ipmitool-1.8.13-bootparam.patch
new file mode 100644
index 0000000..f9120d7
--- /dev/null
+++ b/SOURCES/ipmitool-1.8.13-bootparam.patch
@@ -0,0 +1,349 @@
+From ca5cc560f60ebe601b5219699f56f99938895b4b Mon Sep 17 00:00:00 2001
+From: Jim Mankovich <jmank@hp.com>
+Date: Tue, 11 Mar 2014 10:26:43 -0600
+Subject: [PATCH] Add options to chassis bootparam set bootflag
+
+
+Signed-off-by: Jim Mankovich <jmank@hp.com>
+---
+ doc/ipmitool.1     |   39 ++++++++-
+ lib/ipmi_chassis.c |  233 ++++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 255 insertions(+), 17 deletions(-)
+
+diff --git a/doc/ipmitool.1 b/doc/ipmitool.1
+index a73d564..b35eff8 100644
+--- a/doc/ipmitool.1
++++ b/doc/ipmitool.1
+@@ -2309,14 +2309,16 @@ Get boot parameter. Currently supported values for <\fBparam #\fR> are:
+ .br 
+ 
+ .TP 
+-\fIset\fP <\fBoption\fR> [\fBvalue ...\fR]
++\fIset\fP <\fBdevice\fR> [<\fIoptions\fP=\fBhelp,...\fR>]
+ .br 
+ 
+-Set boot parameter.
++Set boot device parameter used for next boot.  Various options may be used
++to change when the the next boot device is cleared.
++Run \fI"options=help"\fP for a list of available bootparam set device options.
+ 
+ .RS
+ .TP 
+-Currently supported values for \fB<option>\fR are:
++Currently supported bootparam \fBdevice\fR settings are:
+ .TP 
+ \fIforce_pxe\fP
+ .br 
+@@ -2349,6 +2351,37 @@ Force boot from CD/DVD
+ Force boot into BIOS setup
+ 
+ .RE
++.RS
++.TP 
++Currently supported bootparam \fBoptions\fR settings are associated with BMC Boot Valid Bit Clearing and are as follows:   Any option can be prefixed with "no-" to invert the sense of the operation.
++.TP 
++\fIPEF\fP
++.br 
++
++Clear valid bit on reset/power cycle caused by PEF
++.TP 
++\fItimeout\fP
++.br 
++
++Automatically clear boot flag valid bit if Chassis Control command is
++not received within 60 seconds.
++.TP 
++\fIwatchdog\fP
++.br 
++
++Clear valid bit on reset/power cycle caused by watchdog timeout
++.TP 
++\fIreset\fP
++.br 
++
++Clear valid bit on push button reset / soft-reset
++.TP 
++\fIpower\fP
++.br 
++
++Clear valid bit on power up via power push button or wake event
++
++.RE
+ .RE
+ .RE
+ .RE
+diff --git a/lib/ipmi_chassis.c b/lib/ipmi_chassis.c
+index 2d47974..d4e88ee 100644
+--- a/lib/ipmi_chassis.c
++++ b/lib/ipmi_chassis.c
+@@ -755,6 +755,193 @@ ipmi_chassis_get_bootparam(struct ipmi_intf * intf, char * arg)
+ }
+ 
+ static int
++get_bootparam_options(char *optstring,
++		unsigned char *set_flag, unsigned char *clr_flag)
++{
++	char *token;
++	char *saveptr = NULL;
++	int optionError = 0;
++	*set_flag = 0;
++	*clr_flag = 0;
++	static struct {
++		char *name;
++		unsigned char value;
++		char *desc;
++	} options[] = {
++	{"PEF",          0x10,
++	    "Clear valid bit on reset/power cycle cause by PEF"},
++	{"timeout",      0x08,
++	    "Automatically clear boot flag valid bit on timeout"},
++	{"watchdog",     0x04,
++	    "Clear valid bit on reset/power cycle cause by watchdog"},
++	{"reset",        0x02,
++	    "Clear valid bit on push button reset/soft reset"},
++	{"power", 0x01,
++	    "Clear valid bit on power up via power push button or wake event"},
++
++	{NULL}	/* End marker */
++	}, *op;
++
++	if (strncmp(optstring, "options=", 8) != 0) {
++		lprintf(LOG_ERR, "No options= keyword found \"%s\"", optstring);
++		return -1;
++	}
++	token = strtok_r(optstring + 8, ",", &saveptr);
++	while (token != NULL) {
++		int setbit = 0;
++		if (strcmp(token, "help") == 0) {
++			optionError = 1;
++			break;
++		}
++		if (strncmp(token, "no-", 3) == 0) {
++			setbit = 1;
++			token += 3;
++		}
++		for (op = options; op->name != NULL; ++op) {
++			if (strncmp(token, op->name, strlen(op->name)) == 0) {
++				if (setbit) {
++				    *set_flag |= op->value;
++				} else {
++				    *clr_flag |= op->value;
++				}
++				break;
++			}
++		}
++		if (op->name == NULL) {
++			/* Option not found */
++			optionError = 1;
++			if (setbit) {
++				token -=3;
++			}
++			lprintf(LOG_ERR, "Invalid option: %s", token);
++		}
++		token = strtok_r(NULL, ",", &saveptr);
++	}
++	if (optionError) {
++		lprintf(LOG_NOTICE, " Legal options are:");
++		lprintf(LOG_NOTICE, "  %-8s: print this message", "help");
++		for (op = options; op->name != NULL; ++op) {
++			lprintf(LOG_NOTICE, "  %-8s: %s", op->name, op->desc);
++		}
++		lprintf(LOG_NOTICE, " Any Option may be prepended with no-"
++				    " to invert sense of operation\n");
++		return (-1);
++	}
++	return (0);
++}
++
++static int
++ipmi_chassis_get_bootvalid(struct ipmi_intf * intf)
++{
++	struct ipmi_rs * rsp;
++	struct ipmi_rq req;
++	uint8_t msg_data[3];
++	uint8_t param_id = IPMI_CHASSIS_BOOTPARAM_FLAG_VALID;
++	memset(msg_data, 0, 3);
++
++	msg_data[0] = param_id & 0x7f;
++	msg_data[1] = 0;
++	msg_data[2] = 0;
++
++	memset(&req, 0, sizeof(req));
++	req.msg.netfn = IPMI_NETFN_CHASSIS;
++	req.msg.cmd = 0x9;
++	req.msg.data = msg_data;
++	req.msg.data_len = 3;
++
++	rsp = intf->sendrecv(intf, &req);
++	if (rsp == NULL) {
++		lprintf(LOG_ERR,
++			"Error Getting Chassis Boot Parameter %d", param_id);
++		return -1;
++	}
++	if (rsp->ccode > 0) {
++		lprintf(LOG_ERR, "Get Chassis Boot Parameter %d failed: %s",
++			param_id, val2str(rsp->ccode, completion_code_vals));
++		return -1;
++	}
++
++	if (verbose > 2)
++		printbuf(rsp->data, rsp->data_len, "Boot Option");
++
++	return(rsp->data[2]);
++}
++
++static int
++ipmi_chassis_set_bootvalid(struct ipmi_intf *intf, uint8_t set_flag, uint8_t clr_flag)
++{
++	int bootvalid;
++	uint8_t flags[5];
++	int rc = 0;
++	int use_progress = 1;
++	uint8_t param_id = IPMI_CHASSIS_BOOTPARAM_FLAG_VALID;
++
++	if (use_progress) {
++		/* set set-in-progress flag */
++		memset(flags, 0, 5);
++		flags[0] = 0x01;
++		rc = ipmi_chassis_set_bootparam(intf,
++				IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS, flags, 1);
++		if (rc < 0)
++			use_progress = 0;
++	}
++
++	memset(flags, 0, 5);
++	flags[0] = 0x01;
++	flags[1] = 0x01;
++	rc = ipmi_chassis_set_bootparam(intf, IPMI_CHASSIS_BOOTPARAM_INFO_ACK,
++			flags, 2);
++
++	if (rc < 0) {
++		if (use_progress) {
++			/* set-in-progress = set-complete */
++			memset(flags, 0, 5);
++			ipmi_chassis_set_bootparam(intf,
++					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
++					flags, 1);
++		}
++		return -1;
++	}
++
++	bootvalid = ipmi_chassis_get_bootvalid(intf);
++
++	if (bootvalid < 0) {
++		if (use_progress) {
++			/* set-in-progress = set-complete */
++			memset(flags, 0, 5);
++			ipmi_chassis_set_bootparam(intf,
++					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
++					flags, 1);
++		}
++		return -1;
++	}
++	flags[0] = (bootvalid & ~clr_flag) | set_flag;
++
++	rc = ipmi_chassis_set_bootparam(intf, param_id, flags, 1);
++
++	if (rc == 0) {
++		if (use_progress) {
++			/* set-in-progress = commit-write */
++			memset(flags, 0, 5);
++			flags[0] = 0x02;
++			ipmi_chassis_set_bootparam(intf,
++					IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
++					flags, 1);
++		}
++	}
++
++	if (use_progress) {
++		/* set-in-progress = set-complete */
++		memset(flags, 0, 5);
++		ipmi_chassis_set_bootparam(intf,
++				IPMI_CHASSIS_BOOTPARAM_SET_IN_PROGRESS,
++				flags, 1);
++	}
++
++	return rc;
++}
++
++static int
+ ipmi_chassis_set_bootdev(struct ipmi_intf * intf, char * arg, uint8_t *iflags)
+ {
+ 	uint8_t flags[5];
+@@ -946,6 +1133,23 @@ ipmi_power_main(struct ipmi_intf * intf, int argc, char ** argv)
+ 	return rc;
+ }
+ 
++void
++ipmi_chassis_set_bootflag_help()
++{
++	unsigned char set_flag;
++	unsigned char clr_flag;
++	lprintf(LOG_NOTICE, "bootparam set bootflag <device> [options=...]");
++	lprintf(LOG_NOTICE, " Legal devices are:");
++	lprintf(LOG_NOTICE, "  none        : No override");
++	lprintf(LOG_NOTICE, "  force_pxe   : Force PXE boot");
++	lprintf(LOG_NOTICE, "  force_disk  : Force boot from default Hard-drive");
++	lprintf(LOG_NOTICE, "  force_safe  : Force boot from default Hard-drive, request Safe Mode");
++	lprintf(LOG_NOTICE, "  force_diag  : Force boot from Diagnostic Partition");
++	lprintf(LOG_NOTICE, "  force_cdrom : Force boot from CD/DVD");
++	lprintf(LOG_NOTICE, "  force_bios  : Force boot into BIOS Setup");
++	get_bootparam_options("options=help", &set_flag, &clr_flag);
++}
++
+ int
+ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
+ {
+@@ -1036,26 +1240,27 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
+ 	else if (strncmp(argv[0], "bootparam", 9) == 0) {
+ 		if ((argc < 3) || (strncmp(argv[1], "help", 4) == 0)) {
+ 			lprintf(LOG_NOTICE, "bootparam get <param #>");
+-			lprintf(LOG_NOTICE, "bootparam set bootflag <flag>");
+-			lprintf(LOG_NOTICE, "  force_pxe   : Force PXE boot");
+-			lprintf(LOG_NOTICE, "  force_disk  : Force boot from default Hard-drive");
+-			lprintf(LOG_NOTICE, "  force_safe  : Force boot from default Hard-drive, request Safe Mode");
+-			lprintf(LOG_NOTICE, "  force_diag  : Force boot from Diagnostic Partition");
+-			lprintf(LOG_NOTICE, "  force_cdrom : Force boot from CD/DVD");
+-			lprintf(LOG_NOTICE, "  force_bios  : Force boot into BIOS Setup");
++		    ipmi_chassis_set_bootflag_help();
+ 		}
+ 		else {
+ 			if (strncmp(argv[1], "get", 3) == 0) {
+ 				rc = ipmi_chassis_get_bootparam(intf, argv[2]);
+ 			}
+ 			else if (strncmp(argv[1], "set", 3) == 0) {
+-				if (argc < 4) {
+-					lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
++			    unsigned char set_flag=0;
++			    unsigned char clr_flag=0;
++				if (strncmp(argv[2], "help", 4) == 0  ||
++						argc < 4 || (argc >= 4 &&
++							 strncmp(argv[2], "bootflag", 8) != 0)) {
++					ipmi_chassis_set_bootflag_help();
+ 				} else {
+-					if (strncmp(argv[2], "bootflag", 8) == 0)
+-						rc = ipmi_chassis_set_bootdev(intf, argv[3], NULL);
+-					else
+-						lprintf(LOG_NOTICE, "bootparam set <option> [value ...]");
++					if (argc == 5) {
++						get_bootparam_options(argv[4], &set_flag, &clr_flag);
++					}
++					rc = ipmi_chassis_set_bootdev(intf, argv[3], NULL);
++					if (argc == 5 && (set_flag != 0 || clr_flag != 0)) {
++						rc = ipmi_chassis_set_bootvalid(intf, set_flag, clr_flag);
++					}
+ 				}
+ 			}
+ 			else
+@@ -1166,7 +1371,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
+ 				token = strtok_r(NULL, ",", &saveptr);
+ 			}
+ 			if (optionError) {
+-				lprintf(LOG_NOTICE, "Legal options are:");
++				lprintf(LOG_NOTICE, "Legal options settings are:");
+ 				lprintf(LOG_NOTICE, "\thelp:\tprint this message");
+ 				for (op = options; op->name != NULL; ++op) {
+ 					lprintf(LOG_NOTICE, "\t%s:\t%s", op->name, op->desc);
+-- 
+1.7.9.5
+
diff --git a/SPECS/ipmitool.spec b/SPECS/ipmitool.spec
index 8481065..035c0d8 100644
--- a/SPECS/ipmitool.spec
+++ b/SPECS/ipmitool.spec
@@ -1,7 +1,7 @@
 Name:         ipmitool
 Summary:      Utility for IPMI control
 Version:      1.8.13
-Release:      7%{?dist}
+Release:      8%{?dist}
 License:      BSD
 Group:        System Environment/Base
 URL:          http://ipmitool.sourceforge.net/
@@ -29,7 +29,7 @@ Patch1: ipmitool-1.8.10-ipmievd-init.patch
 Patch2: ipmitool-1.8.10-ipmievd-condrestart.patch
 Patch3: ipmitool-1.8.11-remove-umask0.patch
 # various threads. still pending.
-Patch4: cxoem-jb-cx6.patch
+#Patch4: cxoem-jb-cx6.patch
 # pending
 #Patch5: ipmitool-1.8.12-fips.patch
 # pending
@@ -42,6 +42,7 @@ Patch8: ipmitool-1.8.13-bmc-snmp.patch
 Patch9: ipmitool-1.8.13-set-kg-key1.patch
 # todo
 #Patch10: ipmitool-1.8.11-set-kg-key2.patch
+Patch11: ipmitool-1.8.13-bootparam.patch
 
 %description
 This package contains a utility for interfacing with devices that support
@@ -93,13 +94,14 @@ for the host OS to use.
 %patch1 -p1 -b .ipmievd-init
 %patch2 -p0 -b .condrestart
 %patch3 -p1 -b .umask
-%patch4 -p1 -b .cxoem
+#patch4 -p1 -b .cxoem
 #patch5 -p0 -b .fips
 #patch6 -p0 -b .fipsman
 %patch7 -p1 -b .dualbridgedoc
 %patch8 -p1 -b .bmcsnmp
 %patch9 -p1 -b .kg1
-#% p atch10 -p1 -b .kegkey2
+#patch10 -p1 -b .kegkey2
+%patch11 -p1 -b .bootparam
 
 for f in AUTHORS ChangeLog; do
     iconv -f iso-8859-1 -t utf8 < ${f} > ${f}.utf8
@@ -191,6 +193,9 @@ install -Dm 755 contrib/bmc-snmp-proxy         %{buildroot}%{_libexecdir}/bmc-sn
 %{_libexecdir}/bmc-snmp-proxy
 
 %changelog
+* Mon Mar 09 2015 Ales Ledvinka <aledvink@redhat.com> - 1.8.13-8
+- Chassis boot parameter settings support.
+
 * Wed Mar 05 2014 Ales Ledvinka <aledvink@redhat.com> - 1.8.13-7
 - Allow setting channel Kg key.