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 /* 225a7763bfSjmcp * Copyright 2008 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 #pragma ident "%Z%%M% %I% %E% SMI" 305a7763bfSjmcp 315a7763bfSjmcp /* 325a7763bfSjmcp * fwflash.h 335a7763bfSjmcp */ 345a7763bfSjmcp 355a7763bfSjmcp #ifdef __cplusplus 365a7763bfSjmcp extern "C" { 375a7763bfSjmcp #endif 385a7763bfSjmcp 395a7763bfSjmcp #include <sys/queue.h> 405a7763bfSjmcp #include <libdevinfo.h> 415a7763bfSjmcp 425a7763bfSjmcp 435a7763bfSjmcp #define MSG_INFO 0 445a7763bfSjmcp #define MSG_WARN 1 455a7763bfSjmcp #define MSG_ERROR 2 465a7763bfSjmcp int fwflash_debug; 475a7763bfSjmcp 485a7763bfSjmcp #define FWFLASH_SUCCESS 0 495a7763bfSjmcp #define FWFLASH_FAILURE 1 505a7763bfSjmcp 515a7763bfSjmcp #define FWFLASH_FLASH_IMAGES 2 525a7763bfSjmcp 535a7763bfSjmcp 545a7763bfSjmcp #define FWPLUGINDIR "/usr/lib/fwflash/identify" 555a7763bfSjmcp #define FWVERIFYPLUGINDIR "/usr/lib/fwflash/verify" 565a7763bfSjmcp 575a7763bfSjmcp /* 585a7763bfSjmcp * we search for a variable (fwplugin_version, type uint32_t) 595a7763bfSjmcp * which should equal FWPLUGIN_VERSION_1 605a7763bfSjmcp */ 615a7763bfSjmcp 625a7763bfSjmcp #define FWPLUGIN_VERSION_1 1 635a7763bfSjmcp 645a7763bfSjmcp struct devicelist; 655a7763bfSjmcp 665a7763bfSjmcp struct fw_plugin { 675a7763bfSjmcp 685a7763bfSjmcp /* 695a7763bfSjmcp * An opaque handle for dlopen()/dlclose() to use. 705a7763bfSjmcp */ 715a7763bfSjmcp void *handle; 725a7763bfSjmcp 735a7763bfSjmcp /* 745a7763bfSjmcp * fully-qualified filename in /usr/lib/fwflash/identify 755a7763bfSjmcp * made up of [drivername].so 765a7763bfSjmcp * 775a7763bfSjmcp * eg /usr/lib/fwflash/identify/ses.so 785a7763bfSjmcp * is the identification plugin for devices attached to 795a7763bfSjmcp * the host using the ses(7D) driver. 805a7763bfSjmcp */ 815a7763bfSjmcp char *filename; 825a7763bfSjmcp 835a7763bfSjmcp /* 845a7763bfSjmcp * The driver name that this plugin will search for in 855a7763bfSjmcp * the device tree snapshot using di_drv_first_node(3DEVINFO) 865a7763bfSjmcp * and di_drv_next_node(3DEVINFO). 875a7763bfSjmcp */ 885a7763bfSjmcp char *drvname; /* "ses" or "tavor" or .... */ 895a7763bfSjmcp 905a7763bfSjmcp /* 915a7763bfSjmcp * Function entry point to support the command-line "-r" 925a7763bfSjmcp * option - read image from device to persistent storage. 935a7763bfSjmcp * 945a7763bfSjmcp * Not all plugins and devices will support this operation. 955a7763bfSjmcp */ 965a7763bfSjmcp int (*fw_readfw)(struct devicelist *device, char *filename); 975a7763bfSjmcp 985a7763bfSjmcp 995a7763bfSjmcp /* 1005a7763bfSjmcp * Function entry point to support the command-line "-f" 1015a7763bfSjmcp * option - writes from persistent storage to device 1025a7763bfSjmcp * 1035a7763bfSjmcp * All identification plugins must support this operation. 1045a7763bfSjmcp */ 1055a7763bfSjmcp int (*fw_writefw)(struct devicelist *device, char *filename); 1065a7763bfSjmcp 1075a7763bfSjmcp 1085a7763bfSjmcp /* 1095a7763bfSjmcp * Function entry point used to build the list of valid, flashable 1105a7763bfSjmcp * devices attached to the system using the loadable module drvname. 1115a7763bfSjmcp * (Not all devices attached using drvname will be valid for this 1125a7763bfSjmcp * plugin to report. 1135a7763bfSjmcp * 1145a7763bfSjmcp * start allows us to display flashable devices attached with 1155a7763bfSjmcp * different drivers and provide the user with a visual clue 1165a7763bfSjmcp * that these devices are different to others that are detected. 1175a7763bfSjmcp * 1185a7763bfSjmcp * All identification plugins must support this operation. 1195a7763bfSjmcp */ 1205a7763bfSjmcp int (*fw_identify)(int start); 1215a7763bfSjmcp 1225a7763bfSjmcp /* 1235a7763bfSjmcp * Function entry point to support the command-line "-l" 1245a7763bfSjmcp * option - list/report flashable devices attached to the system. 1255a7763bfSjmcp * 1265a7763bfSjmcp * All identification plugins must support this operation. 1275a7763bfSjmcp */ 1285a7763bfSjmcp int (*fw_devinfo)(struct devicelist *thisdev); 1295a7763bfSjmcp }; 1305a7763bfSjmcp 1315a7763bfSjmcp 1325a7763bfSjmcp struct pluginlist { 1335a7763bfSjmcp /* 1345a7763bfSjmcp * fully qualified filename in /usr/lib/fwflash/identify 1355a7763bfSjmcp * made up of fwflash-[drivername].so 1365a7763bfSjmcp * 1375a7763bfSjmcp * eg /usr/lib/fwflash/identify/ses.so 1385a7763bfSjmcp * is the identification plugin for devices attached to 1395a7763bfSjmcp * the host using the ses(7D) driver. 1405a7763bfSjmcp */ 1415a7763bfSjmcp char *filename; 1425a7763bfSjmcp 1435a7763bfSjmcp /* 1445a7763bfSjmcp * The driver name that this plugin will search for in 1455a7763bfSjmcp * the device tree snapshot using di_drv_first_node(3DEVINFO) 1465a7763bfSjmcp * and di_drv_next_node(3DEVINFO). 1475a7763bfSjmcp */ 1485a7763bfSjmcp char *drvname; 1495a7763bfSjmcp 1505a7763bfSjmcp /* 1515a7763bfSjmcp * pointer to the actual plugin, so we can access its 1525a7763bfSjmcp * function entry points 1535a7763bfSjmcp */ 1545a7763bfSjmcp struct fw_plugin *plugin; 1555a7763bfSjmcp 1565a7763bfSjmcp /* pointer to the next element in the list */ 1575a7763bfSjmcp TAILQ_ENTRY(pluginlist) nextplugin; 1585a7763bfSjmcp }; 1595a7763bfSjmcp 1605a7763bfSjmcp 1615a7763bfSjmcp struct vpr { 1625a7763bfSjmcp /* vendor ID, eg "HITACHI " */ 1635a7763bfSjmcp char *vid; 1645a7763bfSjmcp 1655a7763bfSjmcp /* product ID, eg "DK32EJ36NSUN36G " */ 1665a7763bfSjmcp char *pid; 1675a7763bfSjmcp 1685a7763bfSjmcp /* revision, eg "PQ08" */ 1695a7763bfSjmcp char *revid; 1705a7763bfSjmcp 1715a7763bfSjmcp /* 1725a7763bfSjmcp * Additional, encapsulated identifying information. 1735a7763bfSjmcp * This pointer allows us to add details such as the 1745a7763bfSjmcp * IB hba sector size, which command set should be 1755a7763bfSjmcp * used or a part number. 1765a7763bfSjmcp */ 1775a7763bfSjmcp void *encap_ident; 1785a7763bfSjmcp }; 1795a7763bfSjmcp 1805a7763bfSjmcp 1815a7763bfSjmcp 1825a7763bfSjmcp 1835a7763bfSjmcp struct fwfile { 1845a7763bfSjmcp /* 1855a7763bfSjmcp * The fully qualified filename. No default location for 1865a7763bfSjmcp * for 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 1985a7763bfSjmcp 1995a7763bfSjmcp struct devicelist { 2005a7763bfSjmcp /* 2015a7763bfSjmcp * fully qualified pathname, with /devices/.... prefix 2025a7763bfSjmcp */ 2035a7763bfSjmcp char *access_devname; 2045a7763bfSjmcp 2055a7763bfSjmcp /* 2065a7763bfSjmcp * Which drivername did we find this device attached with 2075a7763bfSjmcp * in our device tree walk? Eg, ses or tavor or sgen... 2085a7763bfSjmcp */ 2095a7763bfSjmcp char *drvname; 2105a7763bfSjmcp 2115a7763bfSjmcp /* 2125a7763bfSjmcp * What class of device is this? For tavor-attached devices, 2135a7763bfSjmcp * we set this to "IB". For other devices, unless there is 2145a7763bfSjmcp * a common name to use, just make this the same as the 2155a7763bfSjmcp * drvname field. 2165a7763bfSjmcp */ 2175a7763bfSjmcp char *classname; 2185a7763bfSjmcp 2195a7763bfSjmcp /* pointer to the VPR structure */ 2205a7763bfSjmcp struct vpr *ident; 2215a7763bfSjmcp 2225a7763bfSjmcp /* 2235a7763bfSjmcp * In the original fwflash(1M), it was possible to select a 2245a7763bfSjmcp * device for flashing by using an index number called a 2255a7763bfSjmcp * dev_num. We retain that concept for pluggable fwflash, with 2265a7763bfSjmcp * the following change - whenever our identification plugin has 2275a7763bfSjmcp * finished and found at least one acceptable device, we bump the 2285a7763bfSjmcp * index number by 100. This provides the user with another key 2295a7763bfSjmcp * to distinguish the desired device from a potentially very large 2305a7763bfSjmcp * list of similar-looking devices. 2315a7763bfSjmcp */ 2325a7763bfSjmcp unsigned int index; 2335a7763bfSjmcp 2345a7763bfSjmcp /* 2355a7763bfSjmcp * Contains SAS or FC Port-WWNs, or IB GUIDS. Both SAS and FC only 2365a7763bfSjmcp * need one entry in this array since they really only have one 2375a7763bfSjmcp * address which we should track. IB devices can have 4 GUIDs 2385a7763bfSjmcp * (System Image, Node Image, Port 1 and Port 2). 2395a7763bfSjmcp */ 2405a7763bfSjmcp char *addresses[4]; 2415a7763bfSjmcp 2425a7763bfSjmcp /* 2435a7763bfSjmcp * Pointer to the plugin needed to flash this device, and 2445a7763bfSjmcp * to use for printing appropriate device-specific information 2455a7763bfSjmcp * as required by the "-l" option to fwflash(1M). 2465a7763bfSjmcp */ 2475a7763bfSjmcp struct fw_plugin *plugin; 2485a7763bfSjmcp 2495a7763bfSjmcp /* Next entry in the list */ 2505a7763bfSjmcp TAILQ_ENTRY(devicelist) nextdev; 2515a7763bfSjmcp }; 2525a7763bfSjmcp 2535a7763bfSjmcp 2545a7763bfSjmcp /* 2555a7763bfSjmcp * this type of plugin is for the firmware image vendor-specific 2565a7763bfSjmcp * verification functions, which we load from FWVERIFYPLUGINDIR 2575a7763bfSjmcp */ 2585a7763bfSjmcp 2595a7763bfSjmcp struct vrfyplugin { 2605a7763bfSjmcp 2615a7763bfSjmcp /* 2625a7763bfSjmcp * fully-qualified filename in /usr/lib/fwflash/verify, 2635a7763bfSjmcp * made up of [drivername]-[vendorname].so 2645a7763bfSjmcp * 2655a7763bfSjmcp * eg /usr/lib/fwflash/verify/ses-SUN.so 2665a7763bfSjmcp * is the verification plugin for ses-attached devices which 2675a7763bfSjmcp * have a vendorname of "SUN". 2685a7763bfSjmcp */ 2695a7763bfSjmcp char *filename; 2705a7763bfSjmcp 2715a7763bfSjmcp /* 2725a7763bfSjmcp * The vendor name, such as "SUN" or "MELLANOX" 2735a7763bfSjmcp */ 2745a7763bfSjmcp char *vendor; 2755a7763bfSjmcp 2765a7763bfSjmcp /* 2775a7763bfSjmcp * An opaque handle for dlopen()/dlclose() to use. 2785a7763bfSjmcp */ 2795a7763bfSjmcp void *handle; 2805a7763bfSjmcp 2815a7763bfSjmcp /* 2825a7763bfSjmcp * Firmware image size in bytes, as reported by 2835a7763bfSjmcp * stat(). 2845a7763bfSjmcp */ 2855a7763bfSjmcp unsigned int imgsize; 2865a7763bfSjmcp 2875a7763bfSjmcp /* 2885a7763bfSjmcp * Flashable devices frequently have different buffers 2895a7763bfSjmcp * to use for different image types. We track the buffer 2905a7763bfSjmcp * required for this particular image with this variable. 2915a7763bfSjmcp * 2925a7763bfSjmcp * Once the verifier has figured out what sort of image 2935a7763bfSjmcp * it's been passed, it will know what value to use for 2945a7763bfSjmcp * this variable. 2955a7763bfSjmcp */ 2965a7763bfSjmcp unsigned int flashbuf; 2975a7763bfSjmcp 2985a7763bfSjmcp /* 2995a7763bfSjmcp * Points to the entire firmware image in memory. 3005a7763bfSjmcp * We do this so we can avoid multiple open()/close() 3015a7763bfSjmcp * operations, and to make it easier for checksum 3025a7763bfSjmcp * calculations. 3035a7763bfSjmcp */ 3045a7763bfSjmcp int *fwimage; 3055a7763bfSjmcp 3065a7763bfSjmcp /* 3075a7763bfSjmcp * We also store the name of the firmware file that 3085a7763bfSjmcp * we point to with *fwimage. This is needed in cases 3095a7763bfSjmcp * where we need to key off the name of the file to 3105a7763bfSjmcp * determine whether a different buffer in the target 3115a7763bfSjmcp * device should be targeted. 3125a7763bfSjmcp * 3135a7763bfSjmcp * For example, our "standard" firmware image (file.fw) 3145a7763bfSjmcp * might require use of buffer id 0, but a boot image 3155a7763bfSjmcp * (boot.fw) might require use of buffer id 17. In each 3165a7763bfSjmcp * case, it is the verifier plugin that determines the 3175a7763bfSjmcp * specific bufferid that is needed by that firmware image. 3185a7763bfSjmcp */ 3195a7763bfSjmcp char *imgfile; 3205a7763bfSjmcp 3215a7763bfSjmcp /* 3225a7763bfSjmcp * The verification function entry point. The code 3235a7763bfSjmcp * in fwflash.c calls this function to verify that 3245a7763bfSjmcp * the nominated firmware image file is valid for 3255a7763bfSjmcp * the selected devicenode. 3265a7763bfSjmcp * 3275a7763bfSjmcp * Note that if the verification fails, the image 3285a7763bfSjmcp * does _not_ get force-flashed to the device. 3295a7763bfSjmcp */ 3305a7763bfSjmcp int (*vendorvrfy)(struct devicelist *devicenode); 3315a7763bfSjmcp }; 3325a7763bfSjmcp 3335a7763bfSjmcp 3345a7763bfSjmcp 3355a7763bfSjmcp /* Flags for argument parsing */ 3365a7763bfSjmcp #define FWFLASH_HELP_FLAG 0x01 3375a7763bfSjmcp #define FWFLASH_VER_FLAG 0x02 3385a7763bfSjmcp #define FWFLASH_YES_FLAG 0x04 3395a7763bfSjmcp #define FWFLASH_LIST_FLAG 0x08 3405a7763bfSjmcp #define FWFLASH_CLASS_FLAG 0x10 3415a7763bfSjmcp #define FWFLASH_DEVICE_FLAG 0x20 3425a7763bfSjmcp #define FWFLASH_FW_FLAG 0x40 3435a7763bfSjmcp #define FWFLASH_READ_FLAG 0x80 3445a7763bfSjmcp 3455a7763bfSjmcp /* global variables for fwflash */ 3465a7763bfSjmcp 3475a7763bfSjmcp TAILQ_HEAD(PLUGINLIST, pluginlist); 3485a7763bfSjmcp TAILQ_HEAD(DEVICELIST, devicelist); 3495a7763bfSjmcp struct PLUGINLIST *fw_pluginlist; 3505a7763bfSjmcp struct DEVICELIST *fw_devices; 3515a7763bfSjmcp 3525a7763bfSjmcp 3535a7763bfSjmcp struct vrfyplugin *verifier; 3545a7763bfSjmcp di_node_t rootnode; 3555a7763bfSjmcp struct fw_plugin *self; 3565a7763bfSjmcp 3575a7763bfSjmcp 358*c4800545Sjmcp int manufacturing_mode = 0; 359*c4800545Sjmcp 3605a7763bfSjmcp /* 3615a7763bfSjmcp * utility defines and macros, since the firmware image we get 3625a7763bfSjmcp * from LSI is ARM-format and that means byte- and short-swapping 3635a7763bfSjmcp * on sparc 3645a7763bfSjmcp */ 3655a7763bfSjmcp 3665a7763bfSjmcp #define HIGHBITS16 0xff00 3675a7763bfSjmcp #define HIGHBITS32 0xffff0000 3685a7763bfSjmcp #define HIGHBITS64 0xffffffff00000000ULL 3695a7763bfSjmcp #define LOWBITS16 0x00ff 3705a7763bfSjmcp #define LOWBITS32 0x0000ffff 3715a7763bfSjmcp #define LOWBITS64 0x00000000ffffffffULL 3725a7763bfSjmcp 3735a7763bfSjmcp 3745a7763bfSjmcp #if defined(_LITTLE_ENDIAN) 3755a7763bfSjmcp #define ARMSWAPBITS(bs) (bs) 3765a7763bfSjmcp #define MLXSWAPBITS16(bs) \ 3775a7763bfSjmcp (BE_16(((bs) & LOWBITS16)) | BE_16(((bs) & HIGHBITS16))) 3785a7763bfSjmcp #define MLXSWAPBITS32(bs) \ 3795a7763bfSjmcp (BE_32(((bs) & LOWBITS32)) | BE_32(((bs) & HIGHBITS32))) 3805a7763bfSjmcp #define MLXSWAPBITS64(bs) \ 3815a7763bfSjmcp (BE_64(((bs) & LOWBITS64)) | BE_64(((bs) & HIGHBITS64))) 3825a7763bfSjmcp #else 3835a7763bfSjmcp #define ARMSWAPBITS(bs) (LE_32(((bs) & LOWBITS32)) | LE_32(((bs) & HIGHBITS32))) 3845a7763bfSjmcp #define MLXSWAPBITS16(bs) (bs) 3855a7763bfSjmcp #define MLXSWAPBITS32(bs) (bs) 3865a7763bfSjmcp #define MLXSWAPBITS64(bs) (bs) 3875a7763bfSjmcp 3885a7763bfSjmcp #endif 3895a7763bfSjmcp 3905a7763bfSjmcp 3915a7763bfSjmcp /* common functions for fwflash */ 3925a7763bfSjmcp 3935a7763bfSjmcp void logmsg(int severity, char *msg, ...); 3945a7763bfSjmcp 3955a7763bfSjmcp 3965a7763bfSjmcp #ifdef __cplusplus 3975a7763bfSjmcp } 3985a7763bfSjmcp #endif 3995a7763bfSjmcp 4005a7763bfSjmcp #endif /* _FWFLASH_H */ 401