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