[dpdk-dev,03/13] cxgbe: update flash part information

Message ID 15963875f2ff7057a9aba34c76442f1dbcdacedb.1495856462.git.rahul.lakkireddy@chelsio.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Rahul Lakkireddy May 27, 2017, 3:46 a.m. UTC
  Update flash part identification and decoding to accommodate new
flash parts.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
---
 drivers/net/cxgbe/base/t4_hw.c | 106 +++++++++++++++++++++++++++++++----------
 1 file changed, 81 insertions(+), 25 deletions(-)
  

Patch

diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index da28aa0..4ab12ac 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -3863,8 +3863,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 {
@@ -3880,47 +3884,96 @@  int t4_get_flash_params(struct adapter *adapter)
 	 * 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;
+
+	/**
+	 * 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;
+	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
+	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;
+		default:
+			dev_err(adapter, "Micron Flash Part has bad size, ID = %#x, Density code = %#x\n",
+				flashid, density);
+			return -EINVAL;
+		}
+
+		adapter->params.sf_size = size;
+		adapter->params.sf_nsec = size / SF_SEC_SIZE;
+		break;
+	}
+	default:
+		dev_err(adapter, "Unsupported Flash Part, ID = %#x\n", flashid);
 		return -EINVAL;
-	adapter->params.sf_size = 1 << info;
+	}
 
+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;
 }
@@ -4023,8 +4076,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;