Commit b6011960 authored by Thomas Pedersen's avatar Thomas Pedersen Committed by Johannes Berg
Browse files

mac80211: handle channel frequency offset



cfg80211_chan_def and ieee80211_channel recently gained a
frequency offset component. Handle this where it makes
sense (potentially required by S1G channels).

For IBSS, TDLS, CSA, and ROC we return -EOPNOTSUPP if a
channel with frequency offset is passed, since they may or
may not work. Once someone tests and verifies these
commands work on thos types of channels, we can remove
that error.

join_ocb and join_mesh look harmless because they use a
simple ieee80211_vif_use_channel(), which is using an
already verified channel, so we let those through.

Signed-off-by: default avatarThomas Pedersen <thomas@adapt-ip.com>
Link: https://lore.kernel.org/r/20200402011810.22947-4-thomas@adapt-ip.com


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 934f4c7d
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3287,6 +3287,12 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
		goto out;
	}

	if (params->chandef.chan->freq_offset) {
		/* this may work, but is untested */
		err = -EOPNOTSUPP;
		goto out;
	}

	chanctx = container_of(conf, struct ieee80211_chanctx, conf);

	ch_switch.timestamp = 0;
+1 −0
Original line number Diff line number Diff line
@@ -533,6 +533,7 @@ static void ieee80211_del_chanctx(struct ieee80211_local *local,
		struct cfg80211_chan_def *chandef = &local->_oper_chandef;
		chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
		chandef->center_freq1 = chandef->chan->center_freq;
		chandef->freq1_offset = chandef->chan->freq_offset;
		chandef->center_freq2 = 0;

		/* NOTE: Disabling radar is only valid here for
+5 −0
Original line number Diff line number Diff line
@@ -1758,6 +1758,11 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
	int i;
	int ret;

	if (params->chandef.chan->freq_offset) {
		/* this may work, but is untested */
		return -EOPNOTSUPP;
	}

	ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
					    &params->chandef,
					    sdata->wdev.iftype);
+5 −3
Original line number Diff line number Diff line
@@ -107,13 +107,15 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
		chandef.chan = local->tmp_channel;
		chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
		chandef.center_freq1 = chandef.chan->center_freq;
		chandef.freq1_offset = chandef.chan->freq_offset;
	} else
		chandef = local->_oper_chandef;

	WARN(!cfg80211_chandef_valid(&chandef),
	     "control:%d MHz width:%d center: %d/%d MHz",
	     chandef.chan->center_freq, chandef.width,
	     chandef.center_freq1, chandef.center_freq2);
	     "control:%d.%03d MHz width:%d center: %d.%03d/%d MHz",
	     chandef.chan->center_freq, chandef.chan->freq_offset,
	     chandef.width, chandef.center_freq1, chandef.freq1_offset,
	     chandef.center_freq2);

	if (!cfg80211_chandef_identical(&chandef, &local->_oper_chandef))
		local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
+12 −4
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
	chandef->chan = channel;
	chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
	chandef->center_freq1 = channel->center_freq;
	chandef->freq1_offset = channel->freq_offset;

	if (!ht_oper || !sta_ht_cap.ht_supported) {
		ret = IEEE80211_STA_DISABLE_HT |
@@ -396,9 +397,12 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
		return 0;

	sdata_info(sdata,
		   "AP %pM changed bandwidth, new config is %d MHz, width %d (%d/%d MHz)\n",
		   ifmgd->bssid, chandef.chan->center_freq, chandef.width,
		   chandef.center_freq1, chandef.center_freq2);
		   "AP %pM changed bandwidth, new config is %d.%03d MHz, "
		   "width %d (%d.%03d/%d MHz)\n",
		   ifmgd->bssid, chandef.chan->center_freq,
		   chandef.chan->freq_offset, chandef.width,
		   chandef.center_freq1, chandef.freq1_offset,
		   chandef.center_freq2);

	if (flags != (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
				      IEEE80211_STA_DISABLE_VHT |
@@ -1364,10 +1368,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
	if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
				     IEEE80211_CHAN_DISABLED)) {
		sdata_info(sdata,
			   "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
			   "AP %pM switches to unsupported channel "
			   "(%d.%03d MHz, width:%d, CF1/2: %d.%03d/%d MHz), "
			   "disconnecting\n",
			   ifmgd->associated->bssid,
			   csa_ie.chandef.chan->center_freq,
			   csa_ie.chandef.chan->freq_offset,
			   csa_ie.chandef.width, csa_ie.chandef.center_freq1,
			   csa_ie.chandef.freq1_offset,
			   csa_ie.chandef.center_freq2);
		ieee80211_queue_work(&local->hw,
				     &ifmgd->csa_connection_drop_work);
Loading