From: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Subject: [PATCH 4/6] net/e1000: provide access to iNVM even if a flash is present
Date: Wed, 22 Nov 2017 11:22:29 +0100 [thread overview]
Message-ID: <20171122102231.16872-5-u.kleine-koenig@pengutronix.de> (raw)
In-Reply-To: <20171122102231.16872-1-u.kleine-koenig@pengutronix.de>
An i210 (aka e1000_igb) supports two different non-volatile storages for
configuration. There is a built-in one-time programmable storage called
iNVM and an optional external SPI-Flash. If a flash is populated and
contains a valid configuration image the iNVM is not used (if I
understood the documentation correctly). Still the iNVM can be useful if
the flash is not configured. Also the iNVM contains manufacturing
identification information.
So it makes sense to provide the invm device even if a flash is present.
This patch also cleans up some confusion that suggests that invm is a
way to access the (simulated) eeprom structures and drops some unused
enum values.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
If you look at the diff ignoring whitespace changes (git diff -b) the patch
looks much prettier.
drivers/net/e1000/e1000.h | 6 +-
drivers/net/e1000/eeprom.c | 133 ++++++++++++++++++++++++---------------------
2 files changed, 72 insertions(+), 67 deletions(-)
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index f2da08b4d5c1..ac68e28276c1 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -65,13 +65,9 @@ typedef enum {
} e1000_media_type;
typedef enum {
- e1000_eeprom_uninitialized = 0,
e1000_eeprom_spi,
e1000_eeprom_microwire,
- e1000_eeprom_flash,
- e1000_eeprom_ich8,
- e1000_eeprom_none, /* No NVM support */
- e1000_eeprom_invm,
+ e1000_eeprom_flash, /* access via EERD */
e1000_num_eeprom_types
} e1000_eeprom_type;
diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c
index 9948a8c95275..e5d1c5921f5e 100644
--- a/drivers/net/e1000/eeprom.c
+++ b/drivers/net/e1000/eeprom.c
@@ -493,13 +493,11 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
"limiting access to first 4KB\n");
}
- eeprom->type = e1000_eeprom_flash;
eeprom->acquire = e1000_acquire_eeprom_flash;
eeprom->release = e1000_release_eeprom_flash;
- } else {
- eeprom->type = e1000_eeprom_invm;
}
+ eeprom->type = e1000_eeprom_flash;
eeprom->read = e1000_read_eeprom_eerd;
break;
@@ -507,8 +505,7 @@ int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
break;
}
- if (eeprom->type == e1000_eeprom_spi ||
- eeprom->type == e1000_eeprom_invm) {
+ if (eeprom->type == e1000_eeprom_spi) {
/* eeprom_size will be an enum [0..8] that maps
* to eeprom sizes 128B to
* 32KB (incremented by powers of 2).
@@ -1385,75 +1382,87 @@ fail:
return ret;
}
-int e1000_register_eeprom(struct e1000_hw *hw)
+int e1000_register_invm(struct e1000_hw *hw)
{
- int ret = E1000_SUCCESS;
+ int ret;
u16 word;
struct param_d *p;
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
+ ret = e1000_read_eeprom(hw, 0x0a, 1, &word);
+ if (ret < 0)
+ return ret;
- switch (eeprom->type) {
- case e1000_eeprom_invm:
- ret = e1000_read_eeprom(hw, 0x0A, 1, &word);
- if (ret < 0)
- return ret;
+ if (word & (1 << 15))
+ dev_warn(hw->dev, "iNVM lockout mechanism is active\n");
- if (word & (1 << 15))
- dev_warn(hw->dev, "iNVM lockout mechanism is active\n");
+ hw->invm.cdev.dev = hw->dev;
+ hw->invm.cdev.ops = &e1000_invm_ops;
+ hw->invm.cdev.priv = hw;
+ hw->invm.cdev.name = xasprintf("e1000-invm%d", hw->dev->id);
+ hw->invm.cdev.size = 32 * E1000_INVM_DATA_MAX_N;
- hw->invm.cdev.dev = hw->dev;
- hw->invm.cdev.ops = &e1000_invm_ops;
- hw->invm.cdev.priv = hw;
- hw->invm.cdev.name = xasprintf("e1000-invm%d", hw->dev->id);
- hw->invm.cdev.size = 32 * E1000_INVM_DATA_MAX_N;
+ ret = devfs_create(&hw->invm.cdev);
+ if (ret < 0)
+ return ret;
- ret = devfs_create(&hw->invm.cdev);
- if (ret < 0)
- break;
+ strcpy(hw->invm.dev.name, "invm");
+ hw->invm.dev.parent = hw->dev;
+ ret = register_device(&hw->invm.dev);
+ if (ret < 0) {
+ devfs_remove(&hw->invm.cdev);
+ return ret;
+ }
- strcpy(hw->invm.dev.name, "invm");
- hw->invm.dev.parent = hw->dev;
- ret = register_device(&hw->invm.dev);
- if (ret < 0) {
- devfs_remove(&hw->invm.cdev);
- break;
- }
+ p = dev_add_param_int(&hw->invm.dev, "lock", e1000_invm_set_lock,
+ NULL, &hw->invm.line, "%u", hw);
+ if (IS_ERR(p)) {
+ unregister_device(&hw->invm.dev);
+ devfs_remove(&hw->invm.cdev);
+ ret = PTR_ERR(p);
+ }
- p = dev_add_param_int(&hw->invm.dev, "lock", e1000_invm_set_lock,
- NULL, &hw->invm.line, "%u", hw);
- if (IS_ERR(p)) {
- unregister_device(&hw->invm.dev);
- devfs_remove(&hw->invm.cdev);
- break;
+ return ret;
+}
+
+/*
+ * This function has a wrong name for historic reasons, it doesn't add an
+ * eeprom, but the flash (if available) that is used to simulate the eeprom.
+ * Also a device that represents the invm is registered here (if available).
+ */
+int e1000_register_eeprom(struct e1000_hw *hw)
+{
+ int ret = E1000_SUCCESS;
+
+ struct e1000_eeprom_info *eeprom = &hw->eeprom;
+
+ if (hw->mac_type == e1000_igb) {
+ uint32_t eecd = e1000_read_reg(hw, E1000_EECD);
+
+ if (eecd & E1000_EECD_I210_FLASH_DETECTED) {
+ hw->mtd.parent = hw->dev;
+ hw->mtd.read = e1000_mtd_read;
+ hw->mtd.write = e1000_mtd_write;
+ hw->mtd.erase = e1000_mtd_erase;
+ hw->mtd.size = eeprom->word_size * 2;
+ hw->mtd.writesize = 1;
+ hw->mtd.subpage_sft = 0;
+
+ hw->mtd.eraseregions = xzalloc(sizeof(struct mtd_erase_region_info));
+ hw->mtd.erasesize = SZ_4K;
+ hw->mtd.eraseregions[0].erasesize = SZ_4K;
+ hw->mtd.eraseregions[0].numblocks = hw->mtd.size / SZ_4K;
+ hw->mtd.numeraseregions = 1;
+
+ hw->mtd.flags = MTD_CAP_NORFLASH;
+ hw->mtd.type = MTD_NORFLASH;
+
+ ret = add_mtd_device(&hw->mtd, "e1000-nor",
+ DEVICE_ID_DYNAMIC);
+ if (ret)
+ return ret;
}
- break;
- case e1000_eeprom_flash:
- if (hw->mac_type != e1000_igb)
- break;
- hw->mtd.parent = hw->dev;
- hw->mtd.read = e1000_mtd_read;
- hw->mtd.write = e1000_mtd_write;
- hw->mtd.erase = e1000_mtd_erase;
- hw->mtd.size = eeprom->word_size * 2;
- hw->mtd.writesize = 1;
- hw->mtd.subpage_sft = 0;
-
- hw->mtd.eraseregions = xzalloc(sizeof(struct mtd_erase_region_info));
- hw->mtd.erasesize = SZ_4K;
- hw->mtd.eraseregions[0].erasesize = SZ_4K;
- hw->mtd.eraseregions[0].numblocks = hw->mtd.size / SZ_4K;
- hw->mtd.numeraseregions = 1;
-
- hw->mtd.flags = MTD_CAP_NORFLASH;
- hw->mtd.type = MTD_NORFLASH;
-
- ret = add_mtd_device(&hw->mtd, "e1000-nor",
- DEVICE_ID_DYNAMIC);
- break;
- default:
- break;
+ ret = e1000_register_invm(hw);
}
return ret;
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2017-11-22 10:23 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-22 10:22 [PATCH 0/6] net/e1000: more cleanups and ways to access i210 storage Uwe Kleine-König
2017-11-22 10:22 ` [PATCH 1/6] net/e1000: fix coding style at a few locations Uwe Kleine-König
2017-11-22 10:22 ` [PATCH 2/6] net/e1000: don't use the eeprom word size as timeout to get a semaphore Uwe Kleine-König
2017-11-22 10:22 ` [PATCH 3/6] net/e1000: reorder functions Uwe Kleine-König
2017-11-22 10:22 ` Uwe Kleine-König [this message]
2017-11-22 10:22 ` [PATCH 5/6] net/e1000: fix size of invm device Uwe Kleine-König
2017-11-22 10:22 ` [PATCH 6/6] net/e1000: provide device for accessing emulated eeprom Uwe Kleine-König
2017-11-23 11:12 ` [PATCH 7/6] net/e1000: don't fail to bind on uninitialized flash Uwe Kleine-König
2017-11-23 11:12 ` [PATCH 8/6] net/e1000: log flash/invm status at probe time Uwe Kleine-König
2017-11-23 11:12 ` [PATCH 9/6] net/e1000: don't access the (simulated) eeprom when it is invalid Uwe Kleine-König
2017-11-23 11:12 ` [PATCH 10/6] net/e1000: indicate in error messages where the failure occured Uwe Kleine-König
2017-11-23 11:12 ` [PATCH 11/6] net/e1000: expand timeout for flash erasure Uwe Kleine-König
2017-11-24 9:06 ` [PATCH 0/6] net/e1000: more cleanups and ways to access i210 storage Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171122102231.16872-5-u.kleine-koenig@pengutronix.de \
--to=u.kleine-koenig@pengutronix.de \
--cc=andrew.smirnov@gmail.com \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox