mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
mac80211: determine chandef from HE 6 GHz operation
Support connecting to HE 6 GHz APs and mesh networks on 6 GHz, where the HT/VHT information is missing but instead the HE 6 GHz band capability is present, and the 6 GHz Operation information field is used to encode the channel configuration instead of the HT/VHT operation elements. Also add some other bits needed to connect to 6 GHz networks. Link: https://lore.kernel.org/r/1589399105-25472-10-git-send-email-rmanohar@codeaurora.org Co-developed-by: Rajkumar Manoharan <rmanohar@codeaurora.org> Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org> Link: https://lore.kernel.org/r/20200528213443.25687d2695bc.I3f9747c1147480f65445f13eda5c4a5ed4e86757@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
2a333a0db2
commit
57fa5e85d5
4 changed files with 160 additions and 19 deletions
|
@ -3244,6 +3244,112 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
|
||||
const struct ieee80211_he_operation *he_oper,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_supported_band *sband;
|
||||
enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
|
||||
const struct ieee80211_sta_he_cap *he_cap;
|
||||
struct cfg80211_chan_def he_chandef = *chandef;
|
||||
const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
|
||||
bool support_80_80, support_160;
|
||||
u8 he_phy_cap;
|
||||
u32 freq;
|
||||
|
||||
if (chandef->chan->band != NL80211_BAND_6GHZ)
|
||||
return true;
|
||||
|
||||
sband = local->hw.wiphy->bands[NL80211_BAND_6GHZ];
|
||||
|
||||
he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
|
||||
if (!he_cap) {
|
||||
sdata_info(sdata, "Missing iftype sband data/HE cap");
|
||||
return false;
|
||||
}
|
||||
|
||||
he_phy_cap = he_cap->he_cap_elem.phy_cap_info[0];
|
||||
support_160 =
|
||||
he_phy_cap &
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
|
||||
support_80_80 =
|
||||
he_phy_cap &
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
|
||||
|
||||
if (!he_oper) {
|
||||
sdata_info(sdata,
|
||||
"HE is not advertised on (on %d MHz), expect issues\n",
|
||||
chandef->chan->center_freq);
|
||||
return false;
|
||||
}
|
||||
|
||||
he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
|
||||
|
||||
if (!he_6ghz_oper) {
|
||||
sdata_info(sdata,
|
||||
"HE 6GHz operation missing (on %d MHz), expect issues\n",
|
||||
chandef->chan->center_freq);
|
||||
return false;
|
||||
}
|
||||
|
||||
freq = ieee80211_channel_to_frequency(he_6ghz_oper->primary,
|
||||
NL80211_BAND_6GHZ);
|
||||
he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
|
||||
|
||||
switch (u8_get_bits(he_6ghz_oper->control,
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH)) {
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_20;
|
||||
break;
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_40;
|
||||
break;
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_80;
|
||||
break;
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_80;
|
||||
if (!he_6ghz_oper->ccfs1)
|
||||
break;
|
||||
if (abs(he_6ghz_oper->ccfs1 - he_6ghz_oper->ccfs0) == 8) {
|
||||
if (support_160)
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_160;
|
||||
} else {
|
||||
if (support_80_80)
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_80P80;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (he_chandef.width == NL80211_CHAN_WIDTH_160) {
|
||||
he_chandef.center_freq1 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
|
||||
NL80211_BAND_6GHZ);
|
||||
} else {
|
||||
he_chandef.center_freq1 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs0,
|
||||
NL80211_BAND_6GHZ);
|
||||
he_chandef.center_freq2 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
|
||||
NL80211_BAND_6GHZ);
|
||||
}
|
||||
|
||||
if (!cfg80211_chandef_valid(&he_chandef)) {
|
||||
sdata_info(sdata,
|
||||
"HE 6GHz operation resulted in invalid chandef: %d MHz/%d/%d MHz/%d MHz\n",
|
||||
he_chandef.chan ? he_chandef.chan->center_freq : 0,
|
||||
he_chandef.width,
|
||||
he_chandef.center_freq1,
|
||||
he_chandef.center_freq2);
|
||||
return false;
|
||||
}
|
||||
|
||||
*chandef = he_chandef;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
|
||||
const struct ieee80211_supported_band *sband,
|
||||
const u8 *srates, int srates_len, u32 *rates)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue