drivers/net/wireless/intel/iwlwifi/dvm/calib.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/iwlwifi/dvm/calib.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/dvm/calib.c
Extension
.c
Size
34307 bytes
Lines
1057
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct iwl_calib_result {
	struct list_head list;
	size_t cmd_len;
	struct iwl_calib_cmd cmd;
};

struct statistics_general_data {
	u32 beacon_silence_rssi_a;
	u32 beacon_silence_rssi_b;
	u32 beacon_silence_rssi_c;
	u32 beacon_energy_a;
	u32 beacon_energy_b;
	u32 beacon_energy_c;
};

int iwl_send_calib_results(struct iwl_priv *priv)
{
	struct iwl_host_cmd hcmd = {
		.id = REPLY_PHY_CALIBRATION_CMD,
	};
	struct iwl_calib_result *res;

	list_for_each_entry(res, &priv->calib_results, list) {
		int ret;

		hcmd.len[0] = res->cmd_len;
		hcmd.data[0] = &res->cmd;
		hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
		ret = iwl_dvm_send_cmd(priv, &hcmd);
		if (ret) {
			IWL_ERR(priv, "Error %d on calib cmd %d\n",
				ret, res->cmd.hdr.op_code);
			return ret;
		}
	}

	return 0;
}

int iwl_calib_set(struct iwl_priv *priv,
		  const struct iwl_calib_cmd *cmd, size_t len)
{
	struct iwl_calib_result *res, *tmp;

	if (check_sub_overflow(len, sizeof(*cmd), &len))
		return -ENOMEM;

	res = kmalloc_flex(*res, cmd.data, len, GFP_ATOMIC);
	if (!res)
		return -ENOMEM;
	res->cmd = *cmd;
	memcpy(res->cmd.data, cmd->data, len);
	res->cmd_len = struct_size(cmd, data, len);

	list_for_each_entry(tmp, &priv->calib_results, list) {
		if (tmp->cmd.hdr.op_code == res->cmd.hdr.op_code) {
			list_replace(&tmp->list, &res->list);
			kfree(tmp);
			return 0;
		}
	}

	/* wasn't in list already */
	list_add_tail(&res->list, &priv->calib_results);

	return 0;
}

void iwl_calib_free_results(struct iwl_priv *priv)
{
	struct iwl_calib_result *res, *tmp;

	list_for_each_entry_safe(res, tmp, &priv->calib_results, list) {
		list_del(&res->list);
		kfree(res);
	}
}

/*****************************************************************************
 * RUNTIME calibrations framework
 *****************************************************************************/

/* "false alarms" are signals that our DSP tries to lock onto,
 *   but then determines that they are either noise, or transmissions
 *   from a distant wireless network (also "noise", really) that get
 *   "stepped on" by stronger transmissions within our own network.
 * This algorithm attempts to set a sensitivity level that is high
 *   enough to receive all of our own network traffic, but not so
 *   high that our DSP gets too busy trying to lock onto non-network
 *   activity/noise. */

Annotation

Implementation Notes