xref: /onnv-gate/usr/src/cmd/fwflash/common/fwflash.h (revision 10507:0cb858d3268b)
16489Sjmcp /*
26489Sjmcp  * CDDL HEADER START
36489Sjmcp  *
46489Sjmcp  * The contents of this file are subject to the terms of the
56489Sjmcp  * Common Development and Distribution License (the "License").
66489Sjmcp  * You may not use this file except in compliance with the License.
76489Sjmcp  *
86489Sjmcp  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96489Sjmcp  * or http://www.opensolaris.org/os/licensing.
106489Sjmcp  * See the License for the specific language governing permissions
116489Sjmcp  * and limitations under the License.
126489Sjmcp  *
136489Sjmcp  * When distributing Covered Code, include this CDDL HEADER in each
146489Sjmcp  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156489Sjmcp  * If applicable, add the following below this CDDL HEADER, with the
166489Sjmcp  * fields enclosed by brackets "[]" replaced with your own identifying
176489Sjmcp  * information: Portions Copyright [yyyy] [name of copyright owner]
186489Sjmcp  *
196489Sjmcp  * CDDL HEADER END
206489Sjmcp  */
216489Sjmcp /*
229560SPei-Hong.Huang@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
236489Sjmcp  * Use is subject to license terms.
246489Sjmcp  */
256489Sjmcp 
266489Sjmcp #ifndef	_FWFLASH_H
276489Sjmcp #define	_FWFLASH_H
286489Sjmcp 
296489Sjmcp /*
306489Sjmcp  * fwflash.h
316489Sjmcp  */
326489Sjmcp 
336489Sjmcp #ifdef __cplusplus
346489Sjmcp extern "C" {
356489Sjmcp #endif
366489Sjmcp 
376489Sjmcp #include <sys/queue.h>
386489Sjmcp #include <libdevinfo.h>
396489Sjmcp 
406489Sjmcp 
416489Sjmcp #define	MSG_INFO	0
426489Sjmcp #define	MSG_WARN	1
436489Sjmcp #define	MSG_ERROR	2
446489Sjmcp 
456489Sjmcp #define	FWFLASH_SUCCESS		0
466489Sjmcp #define	FWFLASH_FAILURE		1
476489Sjmcp 
486489Sjmcp #define	FWFLASH_FLASH_IMAGES	2
496489Sjmcp 
506489Sjmcp #define	FWPLUGINDIR		"/usr/lib/fwflash/identify"
516489Sjmcp #define	FWVERIFYPLUGINDIR	"/usr/lib/fwflash/verify"
526489Sjmcp 
536489Sjmcp /*
546489Sjmcp  * we search for a variable (fwplugin_version, type uint32_t)
556489Sjmcp  * which should equal FWPLUGIN_VERSION_1
566489Sjmcp  */
576489Sjmcp 
586489Sjmcp #define	FWPLUGIN_VERSION_1	1
599683SXin.Chen@Sun.COM #define	FWPLUGIN_VERSION_2	2
606489Sjmcp 
616489Sjmcp struct devicelist;
626489Sjmcp 
636489Sjmcp struct fw_plugin {
646489Sjmcp 	/*
656489Sjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
666489Sjmcp 	 */
676489Sjmcp 	void *handle;
686489Sjmcp 
696489Sjmcp 	/*
706489Sjmcp 	 * fully-qualified filename in /usr/lib/fwflash/identify
716489Sjmcp 	 * made up of [drivername].so
726489Sjmcp 	 *
736489Sjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
746489Sjmcp 	 * is the identification plugin for devices attached to
756489Sjmcp 	 * the host using the ses(7D) driver.
766489Sjmcp 	 */
776489Sjmcp 	char *filename;
786489Sjmcp 
796489Sjmcp 	/*
806489Sjmcp 	 * The driver name that this plugin will search for in
816489Sjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
826489Sjmcp 	 * and di_drv_next_node(3DEVINFO).
836489Sjmcp 	 */
846489Sjmcp 	char *drvname; /* "ses" or "tavor" or .... */
856489Sjmcp 
866489Sjmcp 	/*
876489Sjmcp 	 * Function entry point to support the command-line "-r"
886489Sjmcp 	 * option - read image from device to persistent storage.
896489Sjmcp 	 *
906489Sjmcp 	 * Not all plugins and devices will support this operation.
916489Sjmcp 	 */
926489Sjmcp 	int (*fw_readfw)(struct devicelist *device, char *filename);
936489Sjmcp 
946489Sjmcp 	/*
956489Sjmcp 	 * Function entry point to support the command-line "-f"
966489Sjmcp 	 * option - writes from persistent storage to device
976489Sjmcp 	 *
986489Sjmcp 	 * All identification plugins must support this operation.
996489Sjmcp 	 */
1006489Sjmcp 	int (*fw_writefw)(struct devicelist *device, char *filename);
1016489Sjmcp 
1026489Sjmcp 	/*
1036489Sjmcp 	 * Function entry point used to build the list of valid, flashable
1046489Sjmcp 	 * devices attached to the system using the loadable module drvname.
1056489Sjmcp 	 * (Not all devices attached using drvname will be valid for this
1066489Sjmcp 	 * plugin to report.
1076489Sjmcp 	 *
1086489Sjmcp 	 * start allows us to display flashable devices attached with
1096489Sjmcp 	 * different drivers and provide the user with a visual clue
1106489Sjmcp 	 * that these devices are different to others that are detected.
1116489Sjmcp 	 *
1126489Sjmcp 	 * All identification plugins must support this operation.
1136489Sjmcp 	 */
1146489Sjmcp 	int (*fw_identify)(int start);
1156489Sjmcp 
1166489Sjmcp 	/*
1176489Sjmcp 	 * Function entry point to support the command-line "-l"
1186489Sjmcp 	 * option - list/report flashable devices attached to the system.
1196489Sjmcp 	 *
1206489Sjmcp 	 * All identification plugins must support this operation.
1216489Sjmcp 	 */
1226489Sjmcp 	int (*fw_devinfo)(struct devicelist *thisdev);
1239683SXin.Chen@Sun.COM 
1249683SXin.Chen@Sun.COM 	/*
1259683SXin.Chen@Sun.COM 	 * Function entry point to allow the plugin to clean up its
1269683SXin.Chen@Sun.COM 	 * data structure use IF plugin_version == FWPLUGIN_VERSION_2.
1279683SXin.Chen@Sun.COM 	 *
1289683SXin.Chen@Sun.COM 	 * If this function is not defined in the plugin, that is not
1299683SXin.Chen@Sun.COM 	 * an error condition unless the plugin_version variable is
1309683SXin.Chen@Sun.COM 	 * defined.
1319683SXin.Chen@Sun.COM 	 */
1329683SXin.Chen@Sun.COM 	void (*fw_cleanup)(struct devicelist *thisdev);
1336489Sjmcp };
1346489Sjmcp 
1356489Sjmcp 
1366489Sjmcp struct pluginlist {
1376489Sjmcp 	/*
1386489Sjmcp 	 * fully qualified filename in /usr/lib/fwflash/identify
1396489Sjmcp 	 * made up of fwflash-[drivername].so
1406489Sjmcp 	 *
1416489Sjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
1426489Sjmcp 	 * is the identification plugin for devices attached to
1436489Sjmcp 	 * the host using the ses(7D) driver.
1446489Sjmcp 	 */
1456489Sjmcp 	char *filename;
1466489Sjmcp 
1476489Sjmcp 	/*
1486489Sjmcp 	 * The driver name that this plugin will search for in
1496489Sjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
1506489Sjmcp 	 * and di_drv_next_node(3DEVINFO).
1516489Sjmcp 	 */
1526489Sjmcp 	char *drvname;
1536489Sjmcp 
1546489Sjmcp 	/*
1556489Sjmcp 	 * pointer to the actual plugin, so we can access its
1566489Sjmcp 	 * function entry points
1576489Sjmcp 	 */
1586489Sjmcp 	struct fw_plugin *plugin;
1596489Sjmcp 
1606489Sjmcp 	/* pointer to the next element in the list */
1616489Sjmcp 	TAILQ_ENTRY(pluginlist) nextplugin;
1626489Sjmcp };
1636489Sjmcp 
1646489Sjmcp struct vpr {
1656489Sjmcp 	/* vendor ID, eg "HITACHI " */
1666489Sjmcp 	char *vid;
1676489Sjmcp 
1686489Sjmcp 	/* product ID, eg "DK32EJ36NSUN36G " */
1696489Sjmcp 	char *pid;
1706489Sjmcp 
1716489Sjmcp 	/* revision, eg "PQ08" */
1726489Sjmcp 	char *revid;
1736489Sjmcp 
1746489Sjmcp 	/*
1756489Sjmcp 	 * Additional, encapsulated identifying information.
1766489Sjmcp 	 * This pointer allows us to add details such as the
1776489Sjmcp 	 * IB hba sector size, which command set should be
1786489Sjmcp 	 * used or a part number.
1796489Sjmcp 	 */
1806489Sjmcp 	void *encap_ident;
1816489Sjmcp };
1826489Sjmcp 
1836489Sjmcp struct fwfile {
1846489Sjmcp 	/*
1856489Sjmcp 	 * The fully qualified filename. No default location for
1869683SXin.Chen@Sun.COM 	 * the firmware image file is mandated.
1876489Sjmcp 	 */
1886489Sjmcp 	char *filename;
1896489Sjmcp 
1906489Sjmcp 	/* Pointer to the identification plugin required */
1916489Sjmcp 	struct fw_plugin *plugin;
1926489Sjmcp 
1936489Sjmcp 	/* pointer to the identification summary structure */
1946489Sjmcp 	struct vpr *ident;
1956489Sjmcp };
1966489Sjmcp 
1976489Sjmcp struct devicelist {
1986489Sjmcp 	/*
1996489Sjmcp 	 * fully qualified pathname, with /devices/.... prefix
2006489Sjmcp 	 */
2016489Sjmcp 	char *access_devname;
2026489Sjmcp 
2036489Sjmcp 	/*
2046489Sjmcp 	 * Which drivername did we find this device attached with
2056489Sjmcp 	 * in our device tree walk? Eg, ses or tavor or sgen...
2066489Sjmcp 	 */
2076489Sjmcp 	char *drvname;
2086489Sjmcp 
2096489Sjmcp 	/*
2106489Sjmcp 	 * What class of device is this? For tavor-attached devices,
2116489Sjmcp 	 * we set this to "IB". For other devices, unless there is
2126489Sjmcp 	 * a common name to use, just make this the same as the
2136489Sjmcp 	 * drvname field.
2146489Sjmcp 	 */
2156489Sjmcp 	char *classname;
2166489Sjmcp 
2176489Sjmcp 	/* pointer to the VPR structure */
2186489Sjmcp 	struct vpr *ident;
2196489Sjmcp 
2206489Sjmcp 	/*
2216489Sjmcp 	 * In the original fwflash(1M), it was possible to select a
2226489Sjmcp 	 * device for flashing by using an index number called a
2236489Sjmcp 	 * dev_num. We retain that concept for pluggable fwflash, with
2246489Sjmcp 	 * the following change - whenever our identification plugin has
2256489Sjmcp 	 * finished and found at least one acceptable device, we bump the
2266489Sjmcp 	 * index number by 100. This provides the user with another key
2276489Sjmcp 	 * to distinguish the desired device from a potentially very large
2286489Sjmcp 	 * list of similar-looking devices.
2296489Sjmcp 	 */
2306489Sjmcp 	unsigned int index;
2316489Sjmcp 
2326489Sjmcp 	/*
2336489Sjmcp 	 * Contains SAS or FC Port-WWNs, or IB GUIDS. Both SAS and FC only
2346489Sjmcp 	 * need one entry in this array since they really only have one
2356489Sjmcp 	 * address which we should track. IB devices can have 4 GUIDs
2366489Sjmcp 	 * (System Image, Node Image, Port 1 and Port 2).
2376489Sjmcp 	 */
2386489Sjmcp 	char *addresses[4];
2396489Sjmcp 
2406489Sjmcp 	/*
2416489Sjmcp 	 * Pointer to the plugin needed to flash this device, and
2426489Sjmcp 	 * to use for printing appropriate device-specific information
2436489Sjmcp 	 * as required by the "-l" option to fwflash(1M).
2446489Sjmcp 	 */
2456489Sjmcp 	struct fw_plugin *plugin;
2466489Sjmcp 
2476489Sjmcp 	/* Next entry in the list */
2486489Sjmcp 	TAILQ_ENTRY(devicelist) nextdev;
2496489Sjmcp };
2506489Sjmcp 
2516489Sjmcp 
2526489Sjmcp /*
2536489Sjmcp  * this type of plugin is for the firmware image vendor-specific
2546489Sjmcp  * verification functions, which we load from FWVERIFYPLUGINDIR
2556489Sjmcp  */
2566489Sjmcp 
2576489Sjmcp struct vrfyplugin {
2586489Sjmcp 	/*
2596489Sjmcp 	 * fully-qualified filename in /usr/lib/fwflash/verify,
2606489Sjmcp 	 * made up of [drivername]-[vendorname].so
2616489Sjmcp 	 *
2626489Sjmcp 	 * eg  /usr/lib/fwflash/verify/ses-SUN.so
2636489Sjmcp 	 * is the verification plugin for ses-attached devices which
2646489Sjmcp 	 * have a vendorname of "SUN".
2656489Sjmcp 	 */
2666489Sjmcp 	char *filename;
2676489Sjmcp 
2686489Sjmcp 	/*
2696489Sjmcp 	 * The vendor name, such as "SUN" or "MELLANOX"
2706489Sjmcp 	 */
2716489Sjmcp 	char *vendor;
2726489Sjmcp 
2736489Sjmcp 	/*
2746489Sjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
2756489Sjmcp 	 */
2766489Sjmcp 	void *handle;
2776489Sjmcp 
2786489Sjmcp 	/*
2796489Sjmcp 	 * Firmware image size in bytes, as reported by
2806489Sjmcp 	 * stat().
2816489Sjmcp 	 */
2826489Sjmcp 	unsigned int imgsize;
2836489Sjmcp 
2846489Sjmcp 	/*
2856489Sjmcp 	 * Flashable devices frequently have different buffers
2866489Sjmcp 	 * to use for different image types. We track the buffer
2876489Sjmcp 	 * required for this particular image with this variable.
2886489Sjmcp 	 *
2896489Sjmcp 	 * Once the verifier has figured out what sort of image
2906489Sjmcp 	 * it's been passed, it will know what value to use for
2916489Sjmcp 	 * this variable.
2926489Sjmcp 	 */
2936489Sjmcp 	unsigned int flashbuf;
2946489Sjmcp 
2956489Sjmcp 	/*
2966489Sjmcp 	 * Points to the entire firmware image in memory.
2976489Sjmcp 	 * We do this so we can avoid multiple open()/close()
2986489Sjmcp 	 * operations, and to make it easier for checksum
2996489Sjmcp 	 * calculations.
3006489Sjmcp 	 */
3016489Sjmcp 	int *fwimage;
3026489Sjmcp 
3036489Sjmcp 	/*
3046489Sjmcp 	 * We also store the name of the firmware file that
3056489Sjmcp 	 * we point to with *fwimage. This is needed in cases
3066489Sjmcp 	 * where we need to key off the name of the file to
3076489Sjmcp 	 * determine whether a different buffer in the target
3086489Sjmcp 	 * device should be targeted.
3096489Sjmcp 	 *
3106489Sjmcp 	 * For example, our "standard" firmware image (file.fw)
3116489Sjmcp 	 * might require use of buffer id 0, but a boot image
3126489Sjmcp 	 * (boot.fw) might require use of buffer id 17. In each
3136489Sjmcp 	 * case, it is the verifier plugin that determines the
3146489Sjmcp 	 * specific bufferid that is needed by that firmware image.
3156489Sjmcp 	 */
3166489Sjmcp 	char *imgfile;
3176489Sjmcp 
3186489Sjmcp 	/*
3196489Sjmcp 	 * The verification function entry point. The code
3206489Sjmcp 	 * in fwflash.c calls this function to verify that
3216489Sjmcp 	 * the nominated firmware image file is valid for
3226489Sjmcp 	 * the selected devicenode.
3236489Sjmcp 	 *
3246489Sjmcp 	 * Note that if the verification fails, the image
3256489Sjmcp 	 * does _not_ get force-flashed to the device.
3266489Sjmcp 	 */
3276489Sjmcp 	int (*vendorvrfy)(struct devicelist *devicenode);
3286489Sjmcp };
3296489Sjmcp 
3306489Sjmcp /* Flags for argument parsing */
3316489Sjmcp #define	FWFLASH_HELP_FLAG	0x01
3326489Sjmcp #define	FWFLASH_VER_FLAG	0x02
3336489Sjmcp #define	FWFLASH_YES_FLAG	0x04
3346489Sjmcp #define	FWFLASH_LIST_FLAG	0x08
3356489Sjmcp #define	FWFLASH_CLASS_FLAG	0x10
3366489Sjmcp #define	FWFLASH_DEVICE_FLAG	0x20
3376489Sjmcp #define	FWFLASH_FW_FLAG		0x40
3386489Sjmcp #define	FWFLASH_READ_FLAG	0x80
3396489Sjmcp 
3406489Sjmcp /* global variables for fwflash */
3416489Sjmcp TAILQ_HEAD(PLUGINLIST, pluginlist);
3426489Sjmcp TAILQ_HEAD(DEVICELIST, devicelist);
3436489Sjmcp 
344*10507SPei-Hong.Huang@Sun.COM /* exposed global args */
345*10507SPei-Hong.Huang@Sun.COM extern di_node_t rootnode;
346*10507SPei-Hong.Huang@Sun.COM extern struct PLUGINLIST *fw_pluginlist;
347*10507SPei-Hong.Huang@Sun.COM extern struct DEVICELIST *fw_devices;
348*10507SPei-Hong.Huang@Sun.COM extern struct vrfyplugin *verifier;
349*10507SPei-Hong.Huang@Sun.COM extern struct fw_plugin *self;
350*10507SPei-Hong.Huang@Sun.COM extern int fwflash_debug;
3516489Sjmcp 
3526489Sjmcp /*
3536489Sjmcp  * utility defines and macros, since the firmware image we get
3546489Sjmcp  * from LSI is ARM-format and that means byte- and short-swapping
3556489Sjmcp  * on sparc
3566489Sjmcp  */
3576489Sjmcp 
3586489Sjmcp #define	HIGHBITS16		0xff00
3596489Sjmcp #define	HIGHBITS32		0xffff0000
3606489Sjmcp #define	HIGHBITS64		0xffffffff00000000ULL
3616489Sjmcp #define	LOWBITS16		0x00ff
3626489Sjmcp #define	LOWBITS32		0x0000ffff
3636489Sjmcp #define	LOWBITS64		0x00000000ffffffffULL
3646489Sjmcp 
3656489Sjmcp #if defined(_LITTLE_ENDIAN)
3667840SJames.McPherson@Sun.COM #define	ARMSWAPBITS(bs)		(bs)
3677840SJames.McPherson@Sun.COM #define	MLXSWAPBITS16(bs)	ntohs(bs)
3687840SJames.McPherson@Sun.COM #define	MLXSWAPBITS32(bs)	ntohl(bs)
3696489Sjmcp #define	MLXSWAPBITS64(bs)	\
3706489Sjmcp 	(BE_64(((bs) & LOWBITS64)) | BE_64(((bs) & HIGHBITS64)))
3716489Sjmcp #else
3726489Sjmcp #define	ARMSWAPBITS(bs)	(LE_32(((bs) & LOWBITS32)) | LE_32(((bs) & HIGHBITS32)))
3736489Sjmcp #define	MLXSWAPBITS16(bs)	(bs)
3746489Sjmcp #define	MLXSWAPBITS32(bs)	(bs)
3756489Sjmcp #define	MLXSWAPBITS64(bs)	(bs)
3766489Sjmcp #endif
3776489Sjmcp 
3786489Sjmcp /* common functions for fwflash */
3797317SJames.McPherson@Sun.COM void logmsg(int severity, const char *msg, ...);
3806489Sjmcp 
3816489Sjmcp #ifdef __cplusplus
3826489Sjmcp }
3836489Sjmcp #endif
3846489Sjmcp 
3856489Sjmcp #endif /* _FWFLASH_H */
386