xref: /titanic_51/usr/src/cmd/fwflash/common/fwflash.h (revision a799b1e741b6f59012a469e6b57c40cb8061127b)
15a7763bfSjmcp /*
25a7763bfSjmcp  * CDDL HEADER START
35a7763bfSjmcp  *
45a7763bfSjmcp  * The contents of this file are subject to the terms of the
55a7763bfSjmcp  * Common Development and Distribution License (the "License").
65a7763bfSjmcp  * You may not use this file except in compliance with the License.
75a7763bfSjmcp  *
85a7763bfSjmcp  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95a7763bfSjmcp  * or http://www.opensolaris.org/os/licensing.
105a7763bfSjmcp  * See the License for the specific language governing permissions
115a7763bfSjmcp  * and limitations under the License.
125a7763bfSjmcp  *
135a7763bfSjmcp  * When distributing Covered Code, include this CDDL HEADER in each
145a7763bfSjmcp  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155a7763bfSjmcp  * If applicable, add the following below this CDDL HEADER, with the
165a7763bfSjmcp  * fields enclosed by brackets "[]" replaced with your own identifying
175a7763bfSjmcp  * information: Portions Copyright [yyyy] [name of copyright owner]
185a7763bfSjmcp  *
195a7763bfSjmcp  * CDDL HEADER END
205a7763bfSjmcp  */
215a7763bfSjmcp /*
2287d06e46Speihong huang  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
235a7763bfSjmcp  * Use is subject to license terms.
245a7763bfSjmcp  */
255a7763bfSjmcp 
265a7763bfSjmcp #ifndef	_FWFLASH_H
275a7763bfSjmcp #define	_FWFLASH_H
285a7763bfSjmcp 
295a7763bfSjmcp /*
305a7763bfSjmcp  * fwflash.h
315a7763bfSjmcp  */
325a7763bfSjmcp 
335a7763bfSjmcp #ifdef __cplusplus
345a7763bfSjmcp extern "C" {
355a7763bfSjmcp #endif
365a7763bfSjmcp 
375a7763bfSjmcp #include <sys/queue.h>
385a7763bfSjmcp #include <libdevinfo.h>
395a7763bfSjmcp 
405a7763bfSjmcp 
415a7763bfSjmcp #define	MSG_INFO	0
425a7763bfSjmcp #define	MSG_WARN	1
435a7763bfSjmcp #define	MSG_ERROR	2
445a7763bfSjmcp 
455a7763bfSjmcp #define	FWFLASH_SUCCESS		0
465a7763bfSjmcp #define	FWFLASH_FAILURE		1
475a7763bfSjmcp 
485a7763bfSjmcp #define	FWFLASH_FLASH_IMAGES	2
495a7763bfSjmcp 
505a7763bfSjmcp #define	FWPLUGINDIR		"/usr/lib/fwflash/identify"
515a7763bfSjmcp #define	FWVERIFYPLUGINDIR	"/usr/lib/fwflash/verify"
525a7763bfSjmcp 
535a7763bfSjmcp /*
545a7763bfSjmcp  * we search for a variable (fwplugin_version, type uint32_t)
555a7763bfSjmcp  * which should equal FWPLUGIN_VERSION_1
565a7763bfSjmcp  */
575a7763bfSjmcp 
585a7763bfSjmcp #define	FWPLUGIN_VERSION_1	1
59d65b419eSXinChen #define	FWPLUGIN_VERSION_2	2
605a7763bfSjmcp 
615a7763bfSjmcp struct devicelist;
625a7763bfSjmcp 
635a7763bfSjmcp struct fw_plugin {
645a7763bfSjmcp 	/*
655a7763bfSjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
665a7763bfSjmcp 	 */
675a7763bfSjmcp 	void *handle;
685a7763bfSjmcp 
695a7763bfSjmcp 	/*
705a7763bfSjmcp 	 * fully-qualified filename in /usr/lib/fwflash/identify
715a7763bfSjmcp 	 * made up of [drivername].so
725a7763bfSjmcp 	 *
735a7763bfSjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
745a7763bfSjmcp 	 * is the identification plugin for devices attached to
755a7763bfSjmcp 	 * the host using the ses(7D) driver.
765a7763bfSjmcp 	 */
775a7763bfSjmcp 	char *filename;
785a7763bfSjmcp 
795a7763bfSjmcp 	/*
805a7763bfSjmcp 	 * The driver name that this plugin will search for in
815a7763bfSjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
825a7763bfSjmcp 	 * and di_drv_next_node(3DEVINFO).
835a7763bfSjmcp 	 */
845a7763bfSjmcp 	char *drvname; /* "ses" or "tavor" or .... */
855a7763bfSjmcp 
865a7763bfSjmcp 	/*
875a7763bfSjmcp 	 * Function entry point to support the command-line "-r"
885a7763bfSjmcp 	 * option - read image from device to persistent storage.
895a7763bfSjmcp 	 *
905a7763bfSjmcp 	 * Not all plugins and devices will support this operation.
915a7763bfSjmcp 	 */
925a7763bfSjmcp 	int (*fw_readfw)(struct devicelist *device, char *filename);
935a7763bfSjmcp 
945a7763bfSjmcp 	/*
955a7763bfSjmcp 	 * Function entry point to support the command-line "-f"
965a7763bfSjmcp 	 * option - writes from persistent storage to device
975a7763bfSjmcp 	 *
985a7763bfSjmcp 	 * All identification plugins must support this operation.
995a7763bfSjmcp 	 */
1005a7763bfSjmcp 	int (*fw_writefw)(struct devicelist *device, char *filename);
1015a7763bfSjmcp 
1025a7763bfSjmcp 	/*
1035a7763bfSjmcp 	 * Function entry point used to build the list of valid, flashable
1045a7763bfSjmcp 	 * devices attached to the system using the loadable module drvname.
1055a7763bfSjmcp 	 * (Not all devices attached using drvname will be valid for this
1065a7763bfSjmcp 	 * plugin to report.
1075a7763bfSjmcp 	 *
1085a7763bfSjmcp 	 * start allows us to display flashable devices attached with
1095a7763bfSjmcp 	 * different drivers and provide the user with a visual clue
1105a7763bfSjmcp 	 * that these devices are different to others that are detected.
1115a7763bfSjmcp 	 *
1125a7763bfSjmcp 	 * All identification plugins must support this operation.
1135a7763bfSjmcp 	 */
1145a7763bfSjmcp 	int (*fw_identify)(int start);
1155a7763bfSjmcp 
1165a7763bfSjmcp 	/*
1175a7763bfSjmcp 	 * Function entry point to support the command-line "-l"
1185a7763bfSjmcp 	 * option - list/report flashable devices attached to the system.
1195a7763bfSjmcp 	 *
1205a7763bfSjmcp 	 * All identification plugins must support this operation.
1215a7763bfSjmcp 	 */
1225a7763bfSjmcp 	int (*fw_devinfo)(struct devicelist *thisdev);
123d65b419eSXinChen 
124d65b419eSXinChen 	/*
125d65b419eSXinChen 	 * Function entry point to allow the plugin to clean up its
126d65b419eSXinChen 	 * data structure use IF plugin_version == FWPLUGIN_VERSION_2.
127d65b419eSXinChen 	 *
128d65b419eSXinChen 	 * If this function is not defined in the plugin, that is not
129d65b419eSXinChen 	 * an error condition unless the plugin_version variable is
130d65b419eSXinChen 	 * defined.
131d65b419eSXinChen 	 */
132d65b419eSXinChen 	void (*fw_cleanup)(struct devicelist *thisdev);
1335a7763bfSjmcp };
1345a7763bfSjmcp 
1355a7763bfSjmcp 
1365a7763bfSjmcp struct pluginlist {
1375a7763bfSjmcp 	/*
1385a7763bfSjmcp 	 * fully qualified filename in /usr/lib/fwflash/identify
1395a7763bfSjmcp 	 * made up of fwflash-[drivername].so
1405a7763bfSjmcp 	 *
1415a7763bfSjmcp 	 * eg  /usr/lib/fwflash/identify/ses.so
1425a7763bfSjmcp 	 * is the identification plugin for devices attached to
1435a7763bfSjmcp 	 * the host using the ses(7D) driver.
1445a7763bfSjmcp 	 */
1455a7763bfSjmcp 	char *filename;
1465a7763bfSjmcp 
1475a7763bfSjmcp 	/*
1485a7763bfSjmcp 	 * The driver name that this plugin will search for in
1495a7763bfSjmcp 	 * the device tree snapshot using di_drv_first_node(3DEVINFO)
1505a7763bfSjmcp 	 * and di_drv_next_node(3DEVINFO).
1515a7763bfSjmcp 	 */
1525a7763bfSjmcp 	char *drvname;
1535a7763bfSjmcp 
1545a7763bfSjmcp 	/*
1555a7763bfSjmcp 	 * pointer to the actual plugin, so we can access its
1565a7763bfSjmcp 	 * function entry points
1575a7763bfSjmcp 	 */
1585a7763bfSjmcp 	struct fw_plugin *plugin;
1595a7763bfSjmcp 
1605a7763bfSjmcp 	/* pointer to the next element in the list */
1615a7763bfSjmcp 	TAILQ_ENTRY(pluginlist) nextplugin;
1625a7763bfSjmcp };
1635a7763bfSjmcp 
1645a7763bfSjmcp struct vpr {
1655a7763bfSjmcp 	/* vendor ID, eg "HITACHI " */
1665a7763bfSjmcp 	char *vid;
1675a7763bfSjmcp 
1685a7763bfSjmcp 	/* product ID, eg "DK32EJ36NSUN36G " */
1695a7763bfSjmcp 	char *pid;
1705a7763bfSjmcp 
1715a7763bfSjmcp 	/* revision, eg "PQ08" */
1725a7763bfSjmcp 	char *revid;
1735a7763bfSjmcp 
1745a7763bfSjmcp 	/*
1755a7763bfSjmcp 	 * Additional, encapsulated identifying information.
1765a7763bfSjmcp 	 * This pointer allows us to add details such as the
1775a7763bfSjmcp 	 * IB hba sector size, which command set should be
1785a7763bfSjmcp 	 * used or a part number.
1795a7763bfSjmcp 	 */
1805a7763bfSjmcp 	void *encap_ident;
1815a7763bfSjmcp };
1825a7763bfSjmcp 
1835a7763bfSjmcp struct fwfile {
1845a7763bfSjmcp 	/*
1855a7763bfSjmcp 	 * The fully qualified filename. No default location for
186d65b419eSXinChen 	 * the firmware image file is mandated.
1875a7763bfSjmcp 	 */
1885a7763bfSjmcp 	char *filename;
1895a7763bfSjmcp 
1905a7763bfSjmcp 	/* Pointer to the identification plugin required */
1915a7763bfSjmcp 	struct fw_plugin *plugin;
1925a7763bfSjmcp 
1935a7763bfSjmcp 	/* pointer to the identification summary structure */
1945a7763bfSjmcp 	struct vpr *ident;
1955a7763bfSjmcp };
1965a7763bfSjmcp 
1975a7763bfSjmcp struct devicelist {
1985a7763bfSjmcp 	/*
1995a7763bfSjmcp 	 * fully qualified pathname, with /devices/.... prefix
2005a7763bfSjmcp 	 */
2015a7763bfSjmcp 	char *access_devname;
2025a7763bfSjmcp 
2035a7763bfSjmcp 	/*
2045a7763bfSjmcp 	 * Which drivername did we find this device attached with
2055a7763bfSjmcp 	 * in our device tree walk? Eg, ses or tavor or sgen...
2065a7763bfSjmcp 	 */
2075a7763bfSjmcp 	char *drvname;
2085a7763bfSjmcp 
2095a7763bfSjmcp 	/*
2105a7763bfSjmcp 	 * What class of device is this? For tavor-attached devices,
2115a7763bfSjmcp 	 * we set this to "IB". For other devices, unless there is
2125a7763bfSjmcp 	 * a common name to use, just make this the same as the
2135a7763bfSjmcp 	 * drvname field.
2145a7763bfSjmcp 	 */
2155a7763bfSjmcp 	char *classname;
2165a7763bfSjmcp 
2175a7763bfSjmcp 	/* pointer to the VPR structure */
2185a7763bfSjmcp 	struct vpr *ident;
2195a7763bfSjmcp 
2205a7763bfSjmcp 	/*
2215a7763bfSjmcp 	 * In the original fwflash(1M), it was possible to select a
2225a7763bfSjmcp 	 * device for flashing by using an index number called a
2235a7763bfSjmcp 	 * dev_num. We retain that concept for pluggable fwflash, with
2245a7763bfSjmcp 	 * the following change - whenever our identification plugin has
2255a7763bfSjmcp 	 * finished and found at least one acceptable device, we bump the
2265a7763bfSjmcp 	 * index number by 100. This provides the user with another key
2275a7763bfSjmcp 	 * to distinguish the desired device from a potentially very large
2285a7763bfSjmcp 	 * list of similar-looking devices.
2295a7763bfSjmcp 	 */
2305a7763bfSjmcp 	unsigned int index;
2315a7763bfSjmcp 
2325a7763bfSjmcp 	/*
2335a7763bfSjmcp 	 * Contains SAS or FC Port-WWNs, or IB GUIDS. Both SAS and FC only
2345a7763bfSjmcp 	 * need one entry in this array since they really only have one
2355a7763bfSjmcp 	 * address which we should track. IB devices can have 4 GUIDs
2365a7763bfSjmcp 	 * (System Image, Node Image, Port 1 and Port 2).
2375a7763bfSjmcp 	 */
2385a7763bfSjmcp 	char *addresses[4];
2395a7763bfSjmcp 
2405a7763bfSjmcp 	/*
2415a7763bfSjmcp 	 * Pointer to the plugin needed to flash this device, and
2425a7763bfSjmcp 	 * to use for printing appropriate device-specific information
2435a7763bfSjmcp 	 * as required by the "-l" option to fwflash(1M).
2445a7763bfSjmcp 	 */
2455a7763bfSjmcp 	struct fw_plugin *plugin;
2465a7763bfSjmcp 
2475a7763bfSjmcp 	/* Next entry in the list */
2485a7763bfSjmcp 	TAILQ_ENTRY(devicelist) nextdev;
2495a7763bfSjmcp };
2505a7763bfSjmcp 
2515a7763bfSjmcp 
2525a7763bfSjmcp /*
2535a7763bfSjmcp  * this type of plugin is for the firmware image vendor-specific
2545a7763bfSjmcp  * verification functions, which we load from FWVERIFYPLUGINDIR
2555a7763bfSjmcp  */
2565a7763bfSjmcp 
2575a7763bfSjmcp struct vrfyplugin {
2585a7763bfSjmcp 	/*
2595a7763bfSjmcp 	 * fully-qualified filename in /usr/lib/fwflash/verify,
2605a7763bfSjmcp 	 * made up of [drivername]-[vendorname].so
2615a7763bfSjmcp 	 *
2625a7763bfSjmcp 	 * eg  /usr/lib/fwflash/verify/ses-SUN.so
2635a7763bfSjmcp 	 * is the verification plugin for ses-attached devices which
2645a7763bfSjmcp 	 * have a vendorname of "SUN".
2655a7763bfSjmcp 	 */
2665a7763bfSjmcp 	char *filename;
2675a7763bfSjmcp 
2685a7763bfSjmcp 	/*
2695a7763bfSjmcp 	 * The vendor name, such as "SUN" or "MELLANOX"
2705a7763bfSjmcp 	 */
2715a7763bfSjmcp 	char *vendor;
2725a7763bfSjmcp 
2735a7763bfSjmcp 	/*
2745a7763bfSjmcp 	 * An opaque handle for dlopen()/dlclose() to use.
2755a7763bfSjmcp 	 */
2765a7763bfSjmcp 	void *handle;
2775a7763bfSjmcp 
2785a7763bfSjmcp 	/*
2795a7763bfSjmcp 	 * Firmware image size in bytes, as reported by
2805a7763bfSjmcp 	 * stat().
2815a7763bfSjmcp 	 */
2825a7763bfSjmcp 	unsigned int imgsize;
2835a7763bfSjmcp 
2845a7763bfSjmcp 	/*
2855a7763bfSjmcp 	 * Flashable devices frequently have different buffers
2865a7763bfSjmcp 	 * to use for different image types. We track the buffer
2875a7763bfSjmcp 	 * required for this particular image with this variable.
2885a7763bfSjmcp 	 *
2895a7763bfSjmcp 	 * Once the verifier has figured out what sort of image
2905a7763bfSjmcp 	 * it's been passed, it will know what value to use for
2915a7763bfSjmcp 	 * this variable.
2925a7763bfSjmcp 	 */
2935a7763bfSjmcp 	unsigned int flashbuf;
2945a7763bfSjmcp 
2955a7763bfSjmcp 	/*
2965a7763bfSjmcp 	 * Points to the entire firmware image in memory.
2975a7763bfSjmcp 	 * We do this so we can avoid multiple open()/close()
2985a7763bfSjmcp 	 * operations, and to make it easier for checksum
2995a7763bfSjmcp 	 * calculations.
3005a7763bfSjmcp 	 */
3015a7763bfSjmcp 	int *fwimage;
3025a7763bfSjmcp 
3035a7763bfSjmcp 	/*
3045a7763bfSjmcp 	 * We also store the name of the firmware file that
3055a7763bfSjmcp 	 * we point to with *fwimage. This is needed in cases
3065a7763bfSjmcp 	 * where we need to key off the name of the file to
3075a7763bfSjmcp 	 * determine whether a different buffer in the target
3085a7763bfSjmcp 	 * device should be targeted.
3095a7763bfSjmcp 	 *
3105a7763bfSjmcp 	 * For example, our "standard" firmware image (file.fw)
3115a7763bfSjmcp 	 * might require use of buffer id 0, but a boot image
3125a7763bfSjmcp 	 * (boot.fw) might require use of buffer id 17. In each
3135a7763bfSjmcp 	 * case, it is the verifier plugin that determines the
3145a7763bfSjmcp 	 * specific bufferid that is needed by that firmware image.
3155a7763bfSjmcp 	 */
3165a7763bfSjmcp 	char *imgfile;
3175a7763bfSjmcp 
3185a7763bfSjmcp 	/*
3195a7763bfSjmcp 	 * The verification function entry point. The code
3205a7763bfSjmcp 	 * in fwflash.c calls this function to verify that
3215a7763bfSjmcp 	 * the nominated firmware image file is valid for
3225a7763bfSjmcp 	 * the selected devicenode.
3235a7763bfSjmcp 	 *
3245a7763bfSjmcp 	 * Note that if the verification fails, the image
3255a7763bfSjmcp 	 * does _not_ get force-flashed to the device.
3265a7763bfSjmcp 	 */
3275a7763bfSjmcp 	int (*vendorvrfy)(struct devicelist *devicenode);
3285a7763bfSjmcp };
3295a7763bfSjmcp 
3305a7763bfSjmcp /* Flags for argument parsing */
3315a7763bfSjmcp #define	FWFLASH_HELP_FLAG	0x01
3325a7763bfSjmcp #define	FWFLASH_VER_FLAG	0x02
3335a7763bfSjmcp #define	FWFLASH_YES_FLAG	0x04
3345a7763bfSjmcp #define	FWFLASH_LIST_FLAG	0x08
3355a7763bfSjmcp #define	FWFLASH_CLASS_FLAG	0x10
3365a7763bfSjmcp #define	FWFLASH_DEVICE_FLAG	0x20
3375a7763bfSjmcp #define	FWFLASH_FW_FLAG		0x40
3385a7763bfSjmcp #define	FWFLASH_READ_FLAG	0x80
3395a7763bfSjmcp 
3405a7763bfSjmcp /* global variables for fwflash */
3415a7763bfSjmcp TAILQ_HEAD(PLUGINLIST, pluginlist);
3425a7763bfSjmcp TAILQ_HEAD(DEVICELIST, devicelist);
3435a7763bfSjmcp 
344*a799b1e7Speihong huang /* exposed global args */
345*a799b1e7Speihong huang extern di_node_t rootnode;
346*a799b1e7Speihong huang extern struct PLUGINLIST *fw_pluginlist;
347*a799b1e7Speihong huang extern struct DEVICELIST *fw_devices;
348*a799b1e7Speihong huang extern struct vrfyplugin *verifier;
349*a799b1e7Speihong huang extern struct fw_plugin *self;
350*a799b1e7Speihong huang extern int fwflash_debug;
3515a7763bfSjmcp 
3525a7763bfSjmcp /*
3535a7763bfSjmcp  * utility defines and macros, since the firmware image we get
3545a7763bfSjmcp  * from LSI is ARM-format and that means byte- and short-swapping
3555a7763bfSjmcp  * on sparc
3565a7763bfSjmcp  */
3575a7763bfSjmcp 
3585a7763bfSjmcp #define	HIGHBITS16		0xff00
3595a7763bfSjmcp #define	HIGHBITS32		0xffff0000
3605a7763bfSjmcp #define	HIGHBITS64		0xffffffff00000000ULL
3615a7763bfSjmcp #define	LOWBITS16		0x00ff
3625a7763bfSjmcp #define	LOWBITS32		0x0000ffff
3635a7763bfSjmcp #define	LOWBITS64		0x00000000ffffffffULL
3645a7763bfSjmcp 
3655a7763bfSjmcp #if defined(_LITTLE_ENDIAN)
3665a7763bfSjmcp #define	ARMSWAPBITS(bs)		(bs)
367b3f3b44fSJames C. McPherson #define	MLXSWAPBITS16(bs)	ntohs(bs)
368b3f3b44fSJames C. McPherson #define	MLXSWAPBITS32(bs)	ntohl(bs)
3695a7763bfSjmcp #define	MLXSWAPBITS64(bs)	\
3705a7763bfSjmcp 	(BE_64(((bs) & LOWBITS64)) | BE_64(((bs) & HIGHBITS64)))
3715a7763bfSjmcp #else
3725a7763bfSjmcp #define	ARMSWAPBITS(bs)	(LE_32(((bs) & LOWBITS32)) | LE_32(((bs) & HIGHBITS32)))
3735a7763bfSjmcp #define	MLXSWAPBITS16(bs)	(bs)
3745a7763bfSjmcp #define	MLXSWAPBITS32(bs)	(bs)
3755a7763bfSjmcp #define	MLXSWAPBITS64(bs)	(bs)
3765a7763bfSjmcp #endif
3775a7763bfSjmcp 
3785a7763bfSjmcp /* common functions for fwflash */
379f1c23465SJames C. McPherson void logmsg(int severity, const char *msg, ...);
3805a7763bfSjmcp 
3815a7763bfSjmcp #ifdef __cplusplus
3825a7763bfSjmcp }
3835a7763bfSjmcp #endif
3845a7763bfSjmcp 
3855a7763bfSjmcp #endif /* _FWFLASH_H */
386