Commit 0848e297 authored by Wey-Yi Guy's avatar Wey-Yi Guy Committed by John W. Linville
Browse files

iwlwifi: support NVM access (EEPROM/OTP)



Two type of NVM available for devices 1000, 6000 and after, adding
support to read OTP lower blocks if OTP is used instead of EEPROM.

Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8a566afe
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -2298,8 +2298,10 @@ static ssize_t show_version(struct device *d,

	if (priv->eeprom) {
		eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
		pos += sprintf(buf + pos, "EEPROM version: 0x%x\n",
				 eeprom_ver);
		pos += sprintf(buf + pos, "NVM Type: %s, version: 0x%x\n",
			       (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
			       ? "OTP" : "EEPROM", eeprom_ver);

	} else {
		pos += sprintf(buf + pos, "EEPROM not initialzed\n");
	}
+5 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@
/* EEPROM reads */
#define CSR_EEPROM_REG          (CSR_BASE+0x02c)
#define CSR_EEPROM_GP           (CSR_BASE+0x030)
#define CSR_OTP_GP_REG   	(CSR_BASE+0x034)
#define CSR_GIO_REG		(CSR_BASE+0x03C)
#define CSR_GP_UCODE		(CSR_BASE+0x044)
#define CSR_UCODE_DRV_GP1       (CSR_BASE+0x054)
@@ -226,6 +227,10 @@
#define CSR_EEPROM_GP_VALID_MSK		(0x00000007)
#define CSR_EEPROM_GP_BAD_SIGNATURE	(0x00000000)
#define CSR_EEPROM_GP_IF_OWNER_MSK	(0x00000180)
#define CSR_OTP_GP_REG_DEVICE_SELECT	(0x00010000) /* 0 - EEPROM, 1 - OTP */
#define CSR_OTP_GP_REG_OTP_ACCESS_MODE	(0x00020000) /* 0 - absolute, 1 - relative */
#define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK          (0x00100000) /* bit 20 */
#define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK        (0x00200000) /* bit 21 */

/* CSR GIO */
#define CSR_GIO_REG_VAL_L0S_ENABLED	(0x00000002)
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ struct iwl_debugfs {
	struct dentry *dir_rf;
	struct dir_data_files {
		struct dentry *file_sram;
		struct dentry *file_eeprom;
		struct dentry *file_nvm;
		struct dentry *file_stations;
		struct dentry *file_rx_statistics;
		struct dentry *file_tx_statistics;
+12 −6
Original line number Diff line number Diff line
@@ -292,7 +292,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
	return ret;
}

static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
static ssize_t iwl_dbgfs_nvm_read(struct file *file,
				       char __user *user_buf,
				       size_t count,
				       loff_t *ppos)
@@ -306,7 +306,7 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
	buf_size = 4 * eeprom_len + 256;

	if (eeprom_len % 16) {
		IWL_ERR(priv, "EEPROM size is not multiple of 16.\n");
		IWL_ERR(priv, "NVM size is not multiple of 16.\n");
		return -ENODATA;
	}

@@ -318,6 +318,13 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
	}

	ptr = priv->eeprom;
	if (!ptr) {
		IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
		return -ENOMEM;
	}
	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n",
			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
			? "OTP" : "EEPROM");
	for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
		pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
		hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
@@ -419,7 +426,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
				channels[i].flags &
				IEEE80211_CHAN_PASSIVE_SCAN ?
				"passive only" : "active/passive");

	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
	kfree(buf);
	return ret;
@@ -564,7 +570,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,

DEBUGFS_READ_WRITE_FILE_OPS(sram);
DEBUGFS_WRITE_FILE_OPS(log_event);
DEBUGFS_READ_FILE_OPS(eeprom);
DEBUGFS_READ_FILE_OPS(nvm);
DEBUGFS_READ_FILE_OPS(stations);
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
@@ -598,7 +604,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)

	DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
	DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
	DEBUGFS_ADD_FILE(eeprom, data);
	DEBUGFS_ADD_FILE(nvm, data);
	DEBUGFS_ADD_FILE(sram, data);
	DEBUGFS_ADD_FILE(log_event, data);
	DEBUGFS_ADD_FILE(stations, data);
@@ -629,7 +635,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
	if (!priv->dbgfs)
		return;

	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);
	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics);
	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics);
	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
+6 −0
Original line number Diff line number Diff line
@@ -814,6 +814,11 @@ enum {
	MEASUREMENT_ACTIVE = (1 << 1),
};

enum iwl_nvm_type {
	NVM_DEVICE_TYPE_EEPROM = 0,
	NVM_DEVICE_TYPE_OTP,
};

/* interrupt statistics */
struct isr_statistics {
	u32 hw;
@@ -1024,6 +1029,7 @@ struct iwl_priv {

	/* eeprom */
	u8 *eeprom;
	int    nvm_device_type;
	struct iwl_eeprom_calib_info *calib_info;

	enum nl80211_iftype iw_mode;
Loading