drivers/net/wireless/intel/iwlwifi/mld/regulatory.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/intel/iwlwifi/mld/regulatory.c
Extension
.c
Size
15859 bytes
Lines
550
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

if (!iwl_bios_get_wgds_table(&mld->fwrt)) {
			/* If basic SAR is not available, we check for WGDS,
			 * which should *not* be available either. If it is
			 * available, issue an error, because we can't use SAR
			 * Geo without basic SAR.
			 */
			IWL_ERR(mld, "BIOS contains WGDS but no WRDS\n");
		}

	} else {
		ret = iwl_bios_get_ewrd_table(&mld->fwrt);
		/* If EWRD is not available, we can still use
		 * WRDS, so don't fail.
		 */
		if (ret < 0)
			IWL_DEBUG_RADIO(mld,
					"EWRD SAR BIOS table invalid or unavailable. (%d)\n",
					ret);

		ret = iwl_bios_get_wgds_table(&mld->fwrt);
		if (ret < 0)
			IWL_DEBUG_RADIO(mld,
					"Geo SAR BIOS table invalid or unavailable. (%d)\n",
					ret);
		/* we don't fail if the table is not available */
	}

	iwl_uefi_get_uats_table(mld->trans, &mld->fwrt);
	iwl_uefi_get_uneb_table(mld->trans, &mld->fwrt);

	iwl_bios_get_phy_filters(&mld->fwrt);
}

static int iwl_mld_geo_sar_init(struct iwl_mld *mld)
{
	u32 cmd_id = WIDE_ID(PHY_OPS_GROUP, PER_CHAIN_LIMIT_OFFSET_CMD);
	/* Only set to South Korea if the table revision is 1 */
	u8 sk = mld->fwrt.geo_rev == 1 ? 1 : 0;
	union iwl_geo_tx_power_profiles_cmd cmd = {
		.v5.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES),
	};
	u32 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id, 0);
	int n_subbands;
	int cmd_size;
	int ret;

	switch (cmd_ver) {
	case 5:
		n_subbands = ARRAY_SIZE(cmd.v5.table[0]);
		cmd.v5.table_revision = cpu_to_le32(sk);
		cmd_size = sizeof(cmd.v5);
		break;
	case 6:
		n_subbands = ARRAY_SIZE(cmd.v6.table[0]);
		cmd.v6.bios_hdr.table_revision = mld->fwrt.geo_rev;
		cmd.v6.bios_hdr.table_source = mld->fwrt.geo_bios_source;
		cmd_size = sizeof(cmd.v6);
		break;
	default:
		WARN(false, "unsupported version: %d", cmd_ver);
		return -EINVAL;
	}

	BUILD_BUG_ON(offsetof(typeof(cmd), v6.table) !=
		     offsetof(typeof(cmd), v5.table));
	ret = iwl_sar_geo_fill_table(&mld->fwrt, &cmd.v6.table[0][0],
				     n_subbands, BIOS_GEO_MAX_PROFILE_NUM);

	/* It is a valid scenario to not support SAR, or miss wgds table,
	 * but in that case there is no need to send the command.
	 */
	if (ret)
		return 0;

	return iwl_mld_send_cmd_pdu(mld, cmd_id, &cmd, cmd_size);
}

int iwl_mld_config_sar_profile(struct iwl_mld *mld, int prof_a, int prof_b)
{
	struct iwl_dev_tx_power_cmd cmd = {
		.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
	};
	u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, REDUCE_TX_POWER_CMD, 10);
	int num_subbands;
	int cmd_size;
	int ret;

	switch (cmd_ver) {
	case 10:
		cmd.v10.flags = cpu_to_le32(mld->fwrt.reduced_power_flags);

Annotation

Implementation Notes