From: ftillier Date: Mon, 27 Mar 2006 19:35:01 +0000 (+0000) Subject: [MT23108] Fix error reading CA guid from firmware image X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=b905079adf34fa232e49eab1b328706825bdfd03;p=~shefty%2Frdma-win.git [MT23108] Fix error reading CA guid from firmware image on Lion Cub rev. C HCAs (and any Mellanox HCA with flash sector size != 64K) git-svn-id: svn://openib.tc.cornell.edu/gen1@255 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/hw/mt23108/kernel/hca_driver.c b/trunk/hw/mt23108/kernel/hca_driver.c index 519251cc..1bb64efd 100644 --- a/trunk/hw/mt23108/kernel/hca_driver.c +++ b/trunk/hw/mt23108/kernel/hca_driver.c @@ -914,6 +914,7 @@ hca_start( NTSTATUS status; hca_dev_ext_t *p_ext; net64_t ca_guid = 0; + HCA_ENTER( HCA_DBG_PNP ); /* Handled on the way up. */ @@ -1260,7 +1261,10 @@ fw_get_pci_bus_interface( NULL, &event, &ioStatus ); - if (p_irp == NULL) { + if (p_irp == NULL) + { + HCA_TRACE( HCA_DBG_ERROR, + ("IoBuildSynchronousFsdRequest failed.\n") ); status = STATUS_INSUFFICIENT_RESOURCES; goto End; } @@ -1473,9 +1477,9 @@ fw_flash_get_ca_guid( NTSTATUS status = STATUS_SUCCESS; BUS_INTERFACE_STANDARD BusInterface; - uint32_t NODE_GUIDH, NODE_GUIDL; + uint32_t NODE_GUIDH, NODE_GUIDL; uint32_t prim_ptr = 0; - uint32_t signature; + uint32_t signature, offset, sect_size; primary_sector_t ps; cl_memset( &ps, 0, sizeof(primary_sector_t)); @@ -1487,39 +1491,67 @@ fw_flash_get_ca_guid( status = fw_flash_init (&BusInterface); if (status != STATUS_SUCCESS ) - return status; - status = fw_flash_read_data(&BusInterface, &signature, 0x24, 4); + goto err1; + + status = fw_flash_read_data(&BusInterface, &signature, FW_SIG_OFFSET, 4); if (status != STATUS_SUCCESS ) - return status; - //signature = cl_ntoh32(signature); + goto err2; - if (signature == FW_SIGNATURE) - { - //Fail Safe image - - // Assume flash has been verified, and both images have the same guids, therefore, - // we only need to read the primary image's guids - status = fw_flash_readbuf(&BusInterface, FW_SECT_SIZE, &ps, sizeof(ps)); - if ( status == STATUS_SUCCESS ) + if (signature == FW_SIGNATURE) + { + //Fail Safe image + + /* Find the sector size offset. */ + status = fw_flash_read_data( + &BusInterface, &offset, FW_SECT_PTR_OFFSET, 4 ); + if( status != STATUS_SUCCESS ) + goto err2; + + offset &= 0x0000FFFF; + + status = fw_flash_read_data( + &BusInterface, §_size, FW_SECT_OFFSET + offset, 4 ); + if( status != STATUS_SUCCESS ) + goto err2; + + sect_size = 1 << (sect_size & 0x0000FFFF); + + /* Try to read the GUIDs from the primary image. */ + status = fw_flash_readbuf(&BusInterface, sect_size, &ps, sizeof(ps)); + if ( status == STATUS_SUCCESS && ps.signature != FW_SIGNATURE ) { + /* Hmm, that didn't work. Try the secondary image. */ + status = fw_flash_readbuf( + &BusInterface, sect_size * 2, &ps, sizeof(ps) ); + } + if( status == STATUS_SUCCESS ) + { + signature = ps.signature; status = fw_flash_read_data(&BusInterface, &prim_ptr, ps.fi_addr+0x24, 4); if (status == STATUS_SUCCESS ) prim_ptr = prim_ptr + ps.fi_addr; } - } - else - { - // Short image - prim_ptr = signature; - } + else + { + signature = 0; + } + } + else + { + // Short image + HCA_TRACE( HCA_DBG_ERROR, + ("Invalid signature %08x, assuming short image.\n", signature) ); + prim_ptr = signature; + signature = FW_SIGNATURE; + } - if ( signature == FW_SIGNATURE || prim_ptr < MAX_FLASH_SIZE ) - { + if ( signature == FW_SIGNATURE && prim_ptr < MAX_FLASH_SIZE ) + { /* now we can read ca guid * since we read it in host mode fw_flash_read4() * swaps it back in BE - how it was stored in FW */ - if (( status = fw_flash_read4(&BusInterface, prim_ptr, &NODE_GUIDL)) == STATUS_SUCCESS ) + if (( status = fw_flash_read4(&BusInterface, prim_ptr, &NODE_GUIDL)) == STATUS_SUCCESS ) if (( status = fw_flash_read4(&BusInterface, prim_ptr+4, &NODE_GUIDH)) == STATUS_SUCCESS ) { *ca_guid = NODE_GUIDH; @@ -1527,13 +1559,15 @@ fw_flash_get_ca_guid( } } else - { - //invalid GUID pointer - return STATUS_NO_SUCH_DEVICE; - } + { + //invalid GUID pointer + status = STATUS_NO_SUCH_DEVICE; + } +err2: fw_flash_deinit(&BusInterface); +err1: BusInterface.InterfaceDereference((PVOID)BusInterface.Context); - return status; + return status; } static NTSTATUS @@ -1548,14 +1582,20 @@ fw_flash_read4( static uint32_t curr_bank = 0xffffffff; if (addr & 0x3) + { + HCA_TRACE( HCA_DBG_ERROR, ("Invalid address %08x\n", addr) ); return STATUS_INVALID_PARAMETER; + } bank = addr & BANK_MASK; if (bank != curr_bank) { curr_bank = bank; if ((status = fw_set_bank(p_BusInterface, bank)) != STATUS_SUCCESS ) + { + HCA_TRACE( HCA_DBG_ERROR, ("fw_set_bank returned %08x\n", status) ); return STATUS_INVALID_PARAMETER; + } } status = fw_flash_read_data(p_BusInterface, &lcl_data, addr, 4); *p_data = cl_ntoh32(lcl_data); @@ -1576,11 +1616,13 @@ fw_flash_readbuf( if (offset & 0x3) { //Address should be 4-bytes aligned + HCA_TRACE( HCA_DBG_ERROR, ("Invalid address %08x\n", offset) ); return STATUS_INVALID_PARAMETER; } if (len & 0x3) { //Length should be 4-bytes aligned + HCA_TRACE( HCA_DBG_ERROR, ("Invalid length %d\n", len) ); return STATUS_INVALID_PARAMETER; } p_lcl_data = (uint32_t *)p_data; diff --git a/trunk/hw/mt23108/kernel/hca_driver.h b/trunk/hw/mt23108/kernel/hca_driver.h index fe119796..7b08a5f6 100644 --- a/trunk/hw/mt23108/kernel/hca_driver.h +++ b/trunk/hw/mt23108/kernel/hca_driver.h @@ -138,6 +138,11 @@ Firmware Update definitions #define FW_CLOSE_IF 0x7e #define FW_SIGNATURE (0x5a445a44) -#define FW_SECT_SIZE (0x10000) +#define FW_SIG_OFFSET (0x24) + +#define FW_SECT_PTR_OFFSET (0x14) +/* The real offset is 0x32, but we're reading DWORDS at a time, so we align */ +#define FW_SECT_OFFSET (0x30) + #endif /* !defined( _HCA_DRIVER_H_ ) */