[MT23108] Fix error reading CA guid from firmware image
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 27 Mar 2006 19:35:01 +0000 (19:35 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 27 Mar 2006 19:35:01 +0000 (19:35 +0000)
on Lion Cub rev. C HCAs (and any Mellanox HCA with flash sector size != 64K)

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@255 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

hw/mt23108/kernel/hca_driver.c
hw/mt23108/kernel/hca_driver.h

index 519251c..1bb64ef 100644 (file)
@@ -914,6 +914,7 @@ hca_start(
        NTSTATUS                        status;\r
        hca_dev_ext_t           *p_ext;\r
        net64_t                         ca_guid = 0;\r
+\r
        HCA_ENTER( HCA_DBG_PNP );\r
 \r
        /* Handled on the way up. */\r
@@ -1260,7 +1261,10 @@ fw_get_pci_bus_interface(
                                                                                NULL,\r
                                                                                &event,\r
                                                                                &ioStatus );\r
-       if (p_irp == NULL) {\r
+       if (p_irp == NULL)\r
+       {\r
+               HCA_TRACE( HCA_DBG_ERROR,\r
+                       ("IoBuildSynchronousFsdRequest failed.\n") );\r
                status = STATUS_INSUFFICIENT_RESOURCES;\r
                goto End;\r
        }\r
@@ -1473,9 +1477,9 @@ fw_flash_get_ca_guid(
        NTSTATUS                status = STATUS_SUCCESS;\r
        BUS_INTERFACE_STANDARD          BusInterface;\r
 \r
-    uint32_t NODE_GUIDH, NODE_GUIDL;\r
+       uint32_t NODE_GUIDH, NODE_GUIDL;\r
        uint32_t prim_ptr = 0;\r
-    uint32_t signature;\r
+       uint32_t signature, offset, sect_size;\r
 \r
        primary_sector_t        ps;\r
        cl_memset( &ps, 0, sizeof(primary_sector_t));\r
@@ -1487,39 +1491,67 @@ fw_flash_get_ca_guid(
        \r
        status = fw_flash_init (&BusInterface);\r
        if (status != STATUS_SUCCESS )\r
-               return status;\r
-    status = fw_flash_read_data(&BusInterface, &signature, 0x24, 4); \r
+               goto err1;\r
+\r
+       status = fw_flash_read_data(&BusInterface, &signature, FW_SIG_OFFSET, 4);\r
        if (status != STATUS_SUCCESS )\r
-               return status;\r
-    //signature = cl_ntoh32(signature);\r
+               goto err2;\r
 \r
-    if (signature == FW_SIGNATURE)\r
-    {\r
-       //Fail Safe image\r
-        \r
-        // Assume flash has been verified, and both images have the same guids, therefore,\r
-        // we only need to read the primary image's guids\r
-        status = fw_flash_readbuf(&BusInterface, FW_SECT_SIZE, &ps, sizeof(ps));\r
-               if ( status == STATUS_SUCCESS )\r
+       if (signature == FW_SIGNATURE)\r
+       {\r
+               //Fail Safe image\r
+\r
+               /* Find the sector size offset. */\r
+               status = fw_flash_read_data(\r
+                       &BusInterface, &offset, FW_SECT_PTR_OFFSET, 4 );\r
+               if( status != STATUS_SUCCESS )\r
+                       goto err2;\r
+\r
+               offset &= 0x0000FFFF;\r
+\r
+               status = fw_flash_read_data(\r
+                       &BusInterface, &sect_size, FW_SECT_OFFSET + offset, 4 );\r
+               if( status != STATUS_SUCCESS )\r
+                       goto err2;\r
+\r
+               sect_size = 1 << (sect_size & 0x0000FFFF);\r
+\r
+               /* Try to read the GUIDs from the primary image. */\r
+               status = fw_flash_readbuf(&BusInterface, sect_size, &ps, sizeof(ps));\r
+               if ( status == STATUS_SUCCESS && ps.signature != FW_SIGNATURE )\r
                {\r
+                       /* Hmm, that didn't work.  Try the secondary image. */\r
+                       status = fw_flash_readbuf(\r
+                               &BusInterface, sect_size * 2, &ps, sizeof(ps) );\r
+               }\r
+               if( status == STATUS_SUCCESS )\r
+               {\r
+                       signature = ps.signature;\r
                        status = fw_flash_read_data(&BusInterface, &prim_ptr, ps.fi_addr+0x24, 4);\r
                        if (status == STATUS_SUCCESS )\r
                                prim_ptr = prim_ptr + ps.fi_addr;\r
                }\r
-    }\r
-    else\r
-    {\r
-        // Short image\r
-        prim_ptr = signature;       \r
-    }\r
+               else\r
+               {\r
+                       signature = 0;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               // Short image\r
+               HCA_TRACE( HCA_DBG_ERROR,\r
+                       ("Invalid signature %08x, assuming short image.\n", signature) );\r
+               prim_ptr = signature;       \r
+               signature = FW_SIGNATURE;\r
+       }\r
 \r
-    if ( signature == FW_SIGNATURE || prim_ptr < MAX_FLASH_SIZE )\r
-    {\r
+       if ( signature == FW_SIGNATURE && prim_ptr < MAX_FLASH_SIZE )\r
+       {\r
                /* now we can read ca guid\r
                 * since we read it in host mode fw_flash_read4() \r
                 * swaps it back in BE - how it was stored in FW\r
                 */\r
-        if (( status = fw_flash_read4(&BusInterface, prim_ptr, &NODE_GUIDL)) == STATUS_SUCCESS )\r
+               if (( status = fw_flash_read4(&BusInterface, prim_ptr, &NODE_GUIDL)) == STATUS_SUCCESS )\r
                        if (( status = fw_flash_read4(&BusInterface, prim_ptr+4, &NODE_GUIDH)) == STATUS_SUCCESS )\r
                        {\r
                                *ca_guid = NODE_GUIDH;\r
@@ -1527,13 +1559,15 @@ fw_flash_get_ca_guid(
                        }\r
        }\r
        else \r
-    {\r
-        //invalid GUID pointer\r
-        return STATUS_NO_SUCH_DEVICE;\r
-    }\r
+       {\r
+               //invalid GUID pointer\r
+               status = STATUS_NO_SUCH_DEVICE;\r
+       }\r
+err2:\r
        fw_flash_deinit(&BusInterface);\r
+err1:\r
        BusInterface.InterfaceDereference((PVOID)BusInterface.Context);\r
-    return status;\r
+       return status;\r
 }\r
 \r
 static NTSTATUS\r
@@ -1548,14 +1582,20 @@ fw_flash_read4(
        static uint32_t curr_bank =     0xffffffff;\r
 \r
        if (addr & 0x3)\r
+       {\r
+               HCA_TRACE( HCA_DBG_ERROR, ("Invalid address %08x\n", addr) );\r
                return STATUS_INVALID_PARAMETER;\r
+       }\r
 \r
        bank = addr & BANK_MASK;\r
        if (bank !=  curr_bank)\r
        {\r
                curr_bank = bank;\r
                if ((status = fw_set_bank(p_BusInterface, bank)) != STATUS_SUCCESS )\r
+               {\r
+                       HCA_TRACE( HCA_DBG_ERROR, ("fw_set_bank returned %08x\n", status) );\r
                        return STATUS_INVALID_PARAMETER;\r
+               }\r
        }\r
        status = fw_flash_read_data(p_BusInterface, &lcl_data, addr, 4);\r
        *p_data = cl_ntoh32(lcl_data);\r
@@ -1576,11 +1616,13 @@ fw_flash_readbuf(
     if (offset & 0x3)\r
     {\r
         //Address should be 4-bytes aligned\r
+               HCA_TRACE( HCA_DBG_ERROR, ("Invalid address %08x\n", offset) );\r
         return STATUS_INVALID_PARAMETER;\r
     }\r
     if (len & 0x3)\r
     {\r
         //Length should be 4-bytes aligned\r
+               HCA_TRACE( HCA_DBG_ERROR, ("Invalid length %d\n", len) );\r
         return STATUS_INVALID_PARAMETER;\r
     }\r
     p_lcl_data = (uint32_t *)p_data;\r
index fe11979..7b08a5f 100644 (file)
@@ -138,6 +138,11 @@ Firmware Update definitions
 #define FW_CLOSE_IF            0x7e\r
 \r
 #define FW_SIGNATURE           (0x5a445a44)\r
-#define FW_SECT_SIZE           (0x10000)\r
+#define FW_SIG_OFFSET          (0x24)\r
+\r
+#define FW_SECT_PTR_OFFSET     (0x14)\r
+/* The real offset is 0x32, but we're reading DWORDS at a time, so we align */\r
+#define FW_SECT_OFFSET         (0x30)\r
+\r
 \r
 #endif /* !defined( _HCA_DRIVER_H_ ) */\r