New upstream version 16.11.8
[deb_dpdk.git] / drivers / net / cxgbe / base / t4_hw.c
index 565a695..6b9f7e8 100644 (file)
@@ -3315,8 +3315,12 @@ static int t4_wait_dev_ready(struct adapter *adapter)
 
        msleep(500);
        whoami = t4_read_reg(adapter, A_PL_WHOAMI);
-       return (whoami != 0xffffffff && whoami != X_CIM_PF_NOACCESS
-                       ? 0 : -EIO);
+       if (whoami != 0xffffffff && whoami != X_CIM_PF_NOACCESS)
+               return 0;
+
+       dev_err(adapter, "Device didn't become ready for access, whoami = %#x\n",
+               whoami);
+       return -EIO;
 }
 
 struct flash_desc {
@@ -3327,52 +3331,172 @@ struct flash_desc {
 int t4_get_flash_params(struct adapter *adapter)
 {
        /*
-        * Table for non-Numonix supported flash parts.  Numonix parts are left
-        * to the preexisting well-tested code.  All flash parts have 64KB
-        * sectors.
+        * Table for non-standard supported Flash parts.  Note, all Flash
+        * parts must have 64KB sectors.
         */
        static struct flash_desc supported_flash[] = {
-               { 0x150201, 4 << 20 },       /* Spansion 4MB S25FL032P */
+               { 0x00150201, 4 << 20 },       /* Spansion 4MB S25FL032P */
        };
 
        int ret;
-       unsigned int i;
-       u32 info = 0;
-
+       u32 flashid = 0;
+       unsigned int part, manufacturer;
+       unsigned int density, size = 0;
+
+       /**
+        * Issue a Read ID Command to the Flash part.  We decode supported
+        * Flash parts and their sizes from this.  There's a newer Query
+        * Command which can retrieve detailed geometry information but
+        * many Flash parts don't support it.
+        */
        ret = sf1_write(adapter, 1, 1, 0, SF_RD_ID);
        if (!ret)
-               ret = sf1_read(adapter, 3, 0, 1, &info);
+               ret = sf1_read(adapter, 3, 0, 1, &flashid);
        t4_write_reg(adapter, A_SF_OP, 0);               /* unlock SF */
        if (ret < 0)
                return ret;
 
-       for (i = 0; i < ARRAY_SIZE(supported_flash); ++i)
-               if (supported_flash[i].vendor_and_model_id == info) {
-                       adapter->params.sf_size = supported_flash[i].size_mb;
+       /**
+        * Check to see if it's one of our non-standard supported Flash parts.
+        */
+       for (part = 0; part < ARRAY_SIZE(supported_flash); part++) {
+               if (supported_flash[part].vendor_and_model_id == flashid) {
+                       adapter->params.sf_size =
+                               supported_flash[part].size_mb;
                        adapter->params.sf_nsec =
                                adapter->params.sf_size / SF_SEC_SIZE;
-                       return 0;
+                       goto found;
                }
+       }
 
-       if ((info & 0xff) != 0x20)             /* not a Numonix flash */
-               return -EINVAL;
-       info >>= 16;                           /* log2 of size */
-       if (info >= 0x14 && info < 0x18)
-               adapter->params.sf_nsec = 1 << (info - 16);
-       else if (info == 0x18)
-               adapter->params.sf_nsec = 64;
-       else
-               return -EINVAL;
-       adapter->params.sf_size = 1 << info;
+       /**
+        * Decode Flash part size.  The code below looks repetative with
+        * common encodings, but that's not guaranteed in the JEDEC
+        * specification for the Read JADEC ID command.  The only thing that
+        * we're guaranteed by the JADEC specification is where the
+        * Manufacturer ID is in the returned result.  After that each
+        * Manufacturer ~could~ encode things completely differently.
+        * Note, all Flash parts must have 64KB sectors.
+        */
+       manufacturer = flashid & 0xff;
+       switch (manufacturer) {
+       case 0x20: { /* Micron/Numonix */
+               /**
+                * This Density -> Size decoding table is taken from Micron
+                * Data Sheets.
+                */
+               density = (flashid >> 16) & 0xff;
+               switch (density) {
+               case 0x14:
+                       size = 1 << 20; /* 1MB */
+                       break;
+               case 0x15:
+                       size = 1 << 21; /* 2MB */
+                       break;
+               case 0x16:
+                       size = 1 << 22; /* 4MB */
+                       break;
+               case 0x17:
+                       size = 1 << 23; /* 8MB */
+                       break;
+               case 0x18:
+                       size = 1 << 24; /* 16MB */
+                       break;
+               case 0x19:
+                       size = 1 << 25; /* 32MB */
+                       break;
+               case 0x20:
+                       size = 1 << 26; /* 64MB */
+                       break;
+               case 0x21:
+                       size = 1 << 27; /* 128MB */
+                       break;
+               case 0x22:
+                       size = 1 << 28; /* 256MB */
+                       break;
+               }
+               break;
+       }
+
+       case 0x9d: { /* ISSI -- Integrated Silicon Solution, Inc. */
+               /**
+                * This Density -> Size decoding table is taken from ISSI
+                * Data Sheets.
+                */
+               density = (flashid >> 16) & 0xff;
+               switch (density) {
+               case 0x16:
+                       size = 1 << 25; /* 32MB */
+                       break;
+               case 0x17:
+                       size = 1 << 26; /* 64MB */
+                       break;
+               }
+               break;
+       }
+
+       case 0xc2: { /* Macronix */
+               /**
+                * This Density -> Size decoding table is taken from Macronix
+                * Data Sheets.
+                */
+               density = (flashid >> 16) & 0xff;
+               switch (density) {
+               case 0x17:
+                       size = 1 << 23; /* 8MB */
+                       break;
+               case 0x18:
+                       size = 1 << 24; /* 16MB */
+                       break;
+               }
+               break;
+       }
+
+       case 0xef: { /* Winbond */
+               /**
+                * This Density -> Size decoding table is taken from Winbond
+                * Data Sheets.
+                */
+               density = (flashid >> 16) & 0xff;
+               switch (density) {
+               case 0x17:
+                       size = 1 << 23; /* 8MB */
+                       break;
+               case 0x18:
+                       size = 1 << 24; /* 16MB */
+                       break;
+               }
+               break;
+       }
+       }
+
+       /* If we didn't recognize the FLASH part, that's no real issue: the
+        * Hardware/Software contract says that Hardware will _*ALWAYS*_
+        * use a FLASH part which is at least 4MB in size and has 64KB
+        * sectors.  The unrecognized FLASH part is likely to be much larger
+        * than 4MB, but that's all we really need.
+        */
+       if (size == 0) {
+               dev_warn(adapter,
+                        "Unknown Flash Part, ID = %#x, assuming 4MB\n",
+                        flashid);
+               size = 1 << 22;
+       }
+
+       /**
+        * Store decoded Flash size and fall through into vetting code.
+        */
+       adapter->params.sf_size = size;
+       adapter->params.sf_nsec = size / SF_SEC_SIZE;
 
+found:
        /*
         * We should reject adapters with FLASHes which are too small. So, emit
         * a warning.
         */
-       if (adapter->params.sf_size < FLASH_MIN_SIZE) {
-               dev_warn(adapter, "WARNING!!! FLASH size %#x < %#x!!!\n",
-                        adapter->params.sf_size, FLASH_MIN_SIZE);
-       }
+       if (adapter->params.sf_size < FLASH_MIN_SIZE)
+               dev_warn(adapter, "WARNING: Flash Part ID %#x, size %#x < %#x\n",
+                        flashid, adapter->params.sf_size, FLASH_MIN_SIZE);
 
        return 0;
 }
@@ -3439,8 +3563,11 @@ int t4_prep_adapter(struct adapter *adapter)
                t4_os_find_pci_capability(adapter, PCI_CAP_ID_VPD);
 
        ret = t4_get_flash_params(adapter);
-       if (ret < 0)
+       if (ret < 0) {
+               dev_err(adapter, "Unable to retrieve Flash Parameters, ret = %d\n",
+                       -ret);
                return ret;
+       }
 
        adapter->params.cim_la_size = CIMLA_SIZE;