Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26a7ca9a authored by Johannes Berg's avatar Johannes Berg
Browse files

iwlwifi: refactor EEPROM reading/parsing



The EEPROM reading/parsing code is all mixed in
the driver today, and the EEPROM is parsed only
when we access data from it. This is problematic
because the NVM needs to be parsed and that is
independent of reading it. Also, the NVM format
for new devices will be different and probably
require a new parser.

Therefore refactor the reading and parsing and
create two independent components. Reading the
EEPROM requires direct hardware accesses and
therefore access to the transport, but parsing
is independent and can be done on an NVM blob.

Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 08838cde
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ iwlwifi-objs += iwl-io.o
iwlwifi-objs		+= iwl-drv.o
iwlwifi-objs		+= iwl-debug.o
iwlwifi-objs		+= iwl-notif-wait.o
iwlwifi-objs		+= iwl-eeprom-read.o iwl-eeprom-parse.o
iwlwifi-objs		+= pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
iwlwifi-objs		+= pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o

+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ obj-$(CONFIG_IWLDVM) += iwldvm.o
iwldvm-objs		+= main.o rs.o mac80211.o ucode.o tx.o
iwldvm-objs		+= lib.o calib.o tt.o sta.o rx.o

iwldvm-objs		+= eeprom.o power.o
iwldvm-objs		+= power.o
iwldvm-objs		+= scan.o led.o
iwldvm-objs		+= rxon.o devices.o

+1 −4
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ extern struct iwl_lib_ops iwl6030_lib;
#define STATUS_CT_KILL		1
#define STATUS_ALIVE		2
#define STATUS_READY		3
#define STATUS_GEO_CONFIGURED	4
#define STATUS_EXIT_PENDING	5
#define STATUS_STATISTICS	6
#define STATUS_SCANNING		7
@@ -443,10 +442,8 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,

static inline int iwl_is_ready(struct iwl_priv *priv)
{
	/* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
	 * set but EXIT_PENDING is not */
	/* The adapter is 'ready' if READY EXIT_PENDING is not set */
	return test_bit(STATUS_READY, &priv->status) &&
	       test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
	       !test_bit(STATUS_EXIT_PENDING, &priv->status);
}

+9 −8
Original line number Diff line number Diff line
@@ -833,14 +833,14 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
	 * To be safe, simply mask out any chains that we know
	 * are not on the device.
	 */
	active_chains &= priv->hw_params.valid_rx_ant;
	active_chains &= priv->eeprom_data->valid_rx_ant;

	num_tx_chains = 0;
	for (i = 0; i < NUM_RX_CHAINS; i++) {
		/* loops on all the bits of
		 * priv->hw_setting.valid_tx_ant */
		u8 ant_msk = (1 << i);
		if (!(priv->hw_params.valid_tx_ant & ant_msk))
		if (!(priv->eeprom_data->valid_tx_ant & ant_msk))
			continue;

		num_tx_chains++;
@@ -854,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
			 * connect the first valid tx chain
			 */
			first_chain =
				find_first_chain(priv->hw_params.valid_tx_ant);
				find_first_chain(priv->eeprom_data->valid_tx_ant);
			data->disconn_array[first_chain] = 0;
			active_chains |= BIT(first_chain);
			IWL_DEBUG_CALIB(priv,
@@ -864,13 +864,13 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
		}
	}

	if (active_chains != priv->hw_params.valid_rx_ant &&
	if (active_chains != priv->eeprom_data->valid_rx_ant &&
	    active_chains != priv->chain_noise_data.active_chains)
		IWL_DEBUG_CALIB(priv,
				"Detected that not all antennas are connected! "
				"Connected: %#x, valid: %#x.\n",
				active_chains,
				priv->hw_params.valid_rx_ant);
				priv->eeprom_data->valid_rx_ant);

	/* Save for use within RXON, TX, SCAN commands, etc. */
	data->active_chains = active_chains;
@@ -1055,7 +1055,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
	    priv->cfg->bt_params->advanced_bt_coexist) {
		/* Disable disconnected antenna algorithm for advanced
		   bt coex, assuming valid antennas are connected */
		data->active_chains = priv->hw_params.valid_rx_ant;
		data->active_chains = priv->eeprom_data->valid_rx_ant;
		for (i = 0; i < NUM_RX_CHAINS; i++)
			if (!(data->active_chains & (1<<i)))
				data->disconn_array[i] = 1;
@@ -1084,8 +1084,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
	IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n",
			min_average_noise, min_average_noise_antenna_i);

	iwlagn_gain_computation(priv, average_noise,
				find_first_chain(priv->hw_params.valid_rx_ant));
	iwlagn_gain_computation(
		priv, average_noise,
		find_first_chain(priv->eeprom_data->valid_rx_ant));

	/* Some power changes may have been made during the calibration.
	 * Update and commit the RXON
+8 −15
Original line number Diff line number Diff line
@@ -303,13 +303,13 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
	const u8 *ptr;
	char *buf;
	u16 eeprom_ver;
	size_t eeprom_len = priv->cfg->base_params->eeprom_size;
	size_t eeprom_len = priv->eeprom_blob_size;
	buf_size = 4 * eeprom_len + 256;

	if (eeprom_len % 16)
		return -ENODATA;

	ptr = priv->eeprom;
	ptr = priv->eeprom_blob;
	if (!ptr)
		return -ENOMEM;

@@ -318,11 +318,9 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
	if (!buf)
		return -ENOMEM;

	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
			"version: 0x%x\n",
			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
			 ? "OTP" : "EEPROM", eeprom_ver);
	eeprom_ver = priv->eeprom_data->eeprom_version;
	pos += scnprintf(buf + pos, buf_size - pos,
			 "NVM version: 0x%x\n", eeprom_ver);
	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,
@@ -347,9 +345,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
	char *buf;
	ssize_t ret;

	if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
		return -EAGAIN;

	buf = kzalloc(bufsz, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
@@ -422,8 +417,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
		test_bit(STATUS_ALIVE, &priv->status));
	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
		test_bit(STATUS_READY, &priv->status));
	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
		test_bit(STATUS_GEO_CONFIGURED, &priv->status));
	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
		test_bit(STATUS_EXIT_PENDING, &priv->status));
	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
@@ -1337,17 +1330,17 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
	if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
		pos += scnprintf(buf + pos, bufsz - pos,
			"tx power: (1/2 dB step)\n");
		if ((priv->hw_params.valid_tx_ant & ANT_A) &&
		if ((priv->eeprom_data->valid_tx_ant & ANT_A) &&
		    tx->tx_power.ant_a)
			pos += scnprintf(buf + pos, bufsz - pos,
					fmt_hex, "antenna A:",
					tx->tx_power.ant_a);
		if ((priv->hw_params.valid_tx_ant & ANT_B) &&
		if ((priv->eeprom_data->valid_tx_ant & ANT_B) &&
		    tx->tx_power.ant_b)
			pos += scnprintf(buf + pos, bufsz - pos,
					fmt_hex, "antenna B:",
					tx->tx_power.ant_b);
		if ((priv->hw_params.valid_tx_ant & ANT_C) &&
		if ((priv->eeprom_data->valid_tx_ant & ANT_C) &&
		    tx->tx_power.ant_c)
			pos += scnprintf(buf + pos, bufsz - pos,
					fmt_hex, "antenna C:",
Loading