Example #1
0
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
				struct iwl_nvm_data *data,
				const __le16 * const nvm_ch_flags,
				bool lar_supported)
{
	int ch_idx;
	int n_channels = 0;
	struct ieee80211_channel *channel;
	u16 ch_flags;
	bool is_5ghz;
	int num_of_ch, num_2ghz_channels;
	const u8 *nvm_chan;

	if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
		num_of_ch = IWL_NUM_CHANNELS;
		nvm_chan = &iwl_nvm_channels[0];
		num_2ghz_channels = NUM_2GHZ_CHANNELS;
	} else {
		num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
		nvm_chan = &iwl_nvm_channels_family_8000[0];
		num_2ghz_channels = NUM_2GHZ_CHANNELS_FAMILY_8000;
	}

	for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
		ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);

		if (ch_idx >= num_2ghz_channels &&
		    !data->sku_cap_band_52GHz_enable)
			continue;

		if (ch_flags & NVM_CHANNEL_160MHZ)
			data->vht160_supported = true;

		if (!lar_supported && !(ch_flags & NVM_CHANNEL_VALID)) {
			/*
			 * Channels might become valid later if lar is
			 * supported, hence we still want to add them to
			 * the list of supported channels to cfg80211.
			 */
			IWL_DEBUG_EEPROM(dev,
					 "Ch. %d Flags %x [%sGHz] - No traffic\n",
					 nvm_chan[ch_idx],
					 ch_flags,
					 (ch_idx >= num_2ghz_channels) ?
					 "5.2" : "2.4");
			continue;
		}

		channel = &data->channels[n_channels];
		n_channels++;

		channel->hw_value = nvm_chan[ch_idx];
		channel->band = (ch_idx < num_2ghz_channels) ?
				NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
		channel->center_freq =
			ieee80211_channel_to_frequency(
				channel->hw_value, channel->band);

		/* Initialize regulatory-based run-time data */

		/*
		 * Default value - highest tx power value.  max_power
		 * is not used in mvm, and is used for backwards compatibility
		 */
		channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
		is_5ghz = channel->band == NL80211_BAND_5GHZ;

		/* don't put limitations in case we're using LAR */
		if (!lar_supported)
			channel->flags = iwl_get_channel_flags(nvm_chan[ch_idx],
							       ch_idx, is_5ghz,
							       ch_flags, cfg);
		else
			channel->flags = 0;

		IWL_DEBUG_EEPROM(dev,
				 "Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
				 channel->hw_value,
				 is_5ghz ? "5.2" : "2.4",
				 ch_flags,
				 CHECK_AND_PRINT_I(VALID),
				 CHECK_AND_PRINT_I(IBSS),
				 CHECK_AND_PRINT_I(ACTIVE),
				 CHECK_AND_PRINT_I(RADAR),
				 CHECK_AND_PRINT_I(INDOOR_ONLY),
				 CHECK_AND_PRINT_I(GO_CONCURRENT),
				 CHECK_AND_PRINT_I(WIDE),
				 CHECK_AND_PRINT_I(40MHZ),
				 CHECK_AND_PRINT_I(80MHZ),
				 CHECK_AND_PRINT_I(160MHZ),
				 channel->max_power,
				 ((ch_flags & NVM_CHANNEL_IBSS) &&
				  !(ch_flags & NVM_CHANNEL_RADAR))
					? "" : "not ");
	}

	return n_channels;
}
Example #2
0
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
				struct iwl_nvm_data *data,
				const void * const nvm_ch_flags,
				u32 sbands_flags, bool v4)
{
	int ch_idx;
	int n_channels = 0;
	struct ieee80211_channel *channel;
	u32 ch_flags;
	int num_of_ch, num_2ghz_channels = NUM_2GHZ_CHANNELS;
	const u16 *nvm_chan;

	if (cfg->uhb_supported) {
		num_of_ch = IWL_NVM_NUM_CHANNELS_UHB;
		nvm_chan = iwl_uhb_nvm_channels;
	} else if (cfg->nvm_type == IWL_NVM_EXT) {
		num_of_ch = IWL_NVM_NUM_CHANNELS_EXT;
		nvm_chan = iwl_ext_nvm_channels;
	} else {
		num_of_ch = IWL_NVM_NUM_CHANNELS;
		nvm_chan = iwl_nvm_channels;
	}

	for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
		bool is_5ghz = (ch_idx >= num_2ghz_channels);

		if (v4)
			ch_flags =
				__le32_to_cpup((__le32 *)nvm_ch_flags + ch_idx);
		else
			ch_flags =
				__le16_to_cpup((__le16 *)nvm_ch_flags + ch_idx);

		if (is_5ghz && !data->sku_cap_band_52ghz_enable)
			continue;

		/* workaround to disable wide channels in 5GHz */
		if ((sbands_flags & IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ) &&
		    is_5ghz) {
			ch_flags &= ~(NVM_CHANNEL_40MHZ |
				     NVM_CHANNEL_80MHZ |
				     NVM_CHANNEL_160MHZ);
		}

		if (ch_flags & NVM_CHANNEL_160MHZ)
			data->vht160_supported = true;

		if (!(sbands_flags & IWL_NVM_SBANDS_FLAGS_LAR) &&
		    !(ch_flags & NVM_CHANNEL_VALID)) {
			/*
			 * Channels might become valid later if lar is
			 * supported, hence we still want to add them to
			 * the list of supported channels to cfg80211.
			 */
			iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
						    nvm_chan[ch_idx], ch_flags);
			continue;
		}

		channel = &data->channels[n_channels];
		n_channels++;

		channel->hw_value = nvm_chan[ch_idx];
		channel->band = is_5ghz ?
				NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
		channel->center_freq =
			ieee80211_channel_to_frequency(
				channel->hw_value, channel->band);

		/* Initialize regulatory-based run-time data */

		/*
		 * Default value - highest tx power value.  max_power
		 * is not used in mvm, and is used for backwards compatibility
		 */
		channel->max_power = IWL_DEFAULT_MAX_TX_POWER;

		/* don't put limitations in case we're using LAR */
		if (!(sbands_flags & IWL_NVM_SBANDS_FLAGS_LAR))
			channel->flags = iwl_get_channel_flags(nvm_chan[ch_idx],
							       ch_idx, is_5ghz,
							       ch_flags, cfg);
		else
			channel->flags = 0;

		iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
					    channel->hw_value, ch_flags);
		IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n",
				 channel->hw_value, channel->max_power);
	}

	return n_channels;
}