All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 1/4] ieee80211: rename CCFS1/CCFS2 to CCFS0/CCFS1
@ 2017-02-14 11:28 Johannes Berg
  2017-02-14 11:28 ` [RFC 2/4] ieee80211: define HT operation CCFS2 field Johannes Berg
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Johannes Berg @ 2017-02-14 11:28 UTC (permalink / raw)
  To: linux-wireless; +Cc: j, greearb, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This matches the spec, and otherwise things are really
confusing with the next patch adding CCFS2.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/marvell/mwifiex/tdls.c |  2 +-
 include/linux/ieee80211.h                   |  4 ++--
 net/mac80211/spectmgmt.c                    |  4 ++--
 net/mac80211/util.c                         | 22 +++++++++++-----------
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c
index df9704de0715..5fc8319ed302 100644
--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
+++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
@@ -349,7 +349,7 @@ static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
 		chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;
 		break;
 	}
-	vht_oper->center_freq_seg1_idx =
+	vht_oper->center_freq_seg0_idx =
 			mwifiex_get_center_freq_index(priv, BAND_AAC,
 						      bss_desc->channel,
 						      chan_bw);
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 0dd9498c694f..4a15e77d9d66 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1525,14 +1525,14 @@ enum ieee80211_vht_chanwidth {
  * This structure is the "VHT operation element" as
  * described in 802.11ac D3.0 8.4.2.161
  * @chan_width: Operating channel width
+ * @center_freq_seg0_idx: center freq segment 0 index
  * @center_freq_seg1_idx: center freq segment 1 index
- * @center_freq_seg2_idx: center freq segment 2 index
  * @basic_mcs_set: VHT Basic MCS rate set
  */
 struct ieee80211_vht_operation {
 	u8 chan_width;
+	u8 center_freq_seg0_idx;
 	u8 center_freq_seg1_idx;
-	u8 center_freq_seg2_idx;
 	__le16 basic_mcs_set;
 } __packed;
 
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 97f4c9d6b54c..0782e486fe89 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -132,9 +132,9 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
 		struct ieee80211_vht_operation vht_oper = {
 			.chan_width =
 				wide_bw_chansw_ie->new_channel_width,
-			.center_freq_seg1_idx =
+			.center_freq_seg0_idx =
 				wide_bw_chansw_ie->new_center_freq_seg0,
-			.center_freq_seg2_idx =
+			.center_freq_seg1_idx =
 				wide_bw_chansw_ie->new_center_freq_seg1,
 			/* .basic_mcs_set doesn't matter */
 		};
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ac59fbd280df..7a37ce78bb38 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2413,13 +2413,13 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
 	*pos++ = WLAN_EID_VHT_OPERATION;
 	*pos++ = sizeof(struct ieee80211_vht_operation);
 	vht_oper = (struct ieee80211_vht_operation *)pos;
-	vht_oper->center_freq_seg1_idx = ieee80211_frequency_to_channel(
+	vht_oper->center_freq_seg0_idx = ieee80211_frequency_to_channel(
 							chandef->center_freq1);
 	if (chandef->center_freq2)
-		vht_oper->center_freq_seg2_idx =
+		vht_oper->center_freq_seg1_idx =
 			ieee80211_frequency_to_channel(chandef->center_freq2);
 	else
-		vht_oper->center_freq_seg2_idx = 0x00;
+		vht_oper->center_freq_seg1_idx = 0x00;
 
 	switch (chandef->width) {
 	case NL80211_CHAN_WIDTH_160:
@@ -2428,11 +2428,11 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
 		 * workaround.
 		 */
 		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
-		vht_oper->center_freq_seg2_idx = vht_oper->center_freq_seg1_idx;
+		vht_oper->center_freq_seg1_idx = vht_oper->center_freq_seg0_idx;
 		if (chandef->chan->center_freq < chandef->center_freq1)
-			vht_oper->center_freq_seg1_idx -= 8;
+			vht_oper->center_freq_seg0_idx -= 8;
 		else
-			vht_oper->center_freq_seg1_idx += 8;
+			vht_oper->center_freq_seg0_idx += 8;
 		break;
 	case NL80211_CHAN_WIDTH_80P80:
 		/*
@@ -2491,9 +2491,9 @@ bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper,
 	if (!oper)
 		return false;
 
-	cf1 = ieee80211_channel_to_frequency(oper->center_freq_seg1_idx,
+	cf1 = ieee80211_channel_to_frequency(oper->center_freq_seg0_idx,
 					     chandef->chan->band);
-	cf2 = ieee80211_channel_to_frequency(oper->center_freq_seg2_idx,
+	cf2 = ieee80211_channel_to_frequency(oper->center_freq_seg1_idx,
 					     chandef->chan->band);
 
 	switch (oper->chan_width) {
@@ -2503,11 +2503,11 @@ bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper,
 		new.width = NL80211_CHAN_WIDTH_80;
 		new.center_freq1 = cf1;
 		/* If needed, adjust based on the newer interop workaround. */
-		if (oper->center_freq_seg2_idx) {
+		if (oper->center_freq_seg1_idx) {
 			unsigned int diff;
 
-			diff = abs(oper->center_freq_seg2_idx -
-				   oper->center_freq_seg1_idx);
+			diff = abs(oper->center_freq_seg1_idx -
+				   oper->center_freq_seg0_idx);
 			if (diff == 8) {
 				new.width = NL80211_CHAN_WIDTH_160;
 				new.center_freq1 = cf2;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC 2/4] ieee80211: define HT operation CCFS2 field
  2017-02-14 11:28 [RFC 1/4] ieee80211: rename CCFS1/CCFS2 to CCFS0/CCFS1 Johannes Berg
@ 2017-02-14 11:28 ` Johannes Berg
  2017-02-14 11:28 ` [RFC 3/4] ieee80211: add new VHT capability fields/parsing Johannes Berg
  2017-02-14 11:28 ` [RFC 4/4] mac80211: add ability to parse CCFS2 Johannes Berg
  2 siblings, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2017-02-14 11:28 UTC (permalink / raw)
  To: linux-wireless; +Cc: j, greearb, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

The Channel Center Frequency Segment 2 field is used in
802.11-2016 for encoding the actual channel position of
the 80+80/160 MHz channel, if the max NSS is restricted.
This is used for backwards compatibility.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/linux/ieee80211.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 4a15e77d9d66..4a7200c6c9ea 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1411,6 +1411,8 @@ struct ieee80211_ht_operation {
 #define		IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED	3
 #define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT		0x0004
 #define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT		0x0010
+#define IEEE80211_HT_OP_MODE_CCFS2_SHIFT		5
+#define IEEE80211_HT_OP_MODE_CCFS2_MASK			0x1fe0
 
 /* for stbc_param */
 #define IEEE80211_HT_STBC_PARAM_DUAL_BEACON		0x0040
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC 3/4] ieee80211: add new VHT capability fields/parsing
  2017-02-14 11:28 [RFC 1/4] ieee80211: rename CCFS1/CCFS2 to CCFS0/CCFS1 Johannes Berg
  2017-02-14 11:28 ` [RFC 2/4] ieee80211: define HT operation CCFS2 field Johannes Berg
@ 2017-02-14 11:28 ` Johannes Berg
  2017-02-14 13:06   ` Johannes Berg
  2017-02-14 11:28 ` [RFC 4/4] mac80211: add ability to parse CCFS2 Johannes Berg
  2 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2017-02-14 11:28 UTC (permalink / raw)
  To: linux-wireless; +Cc: j, greearb, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

IEEE 802.11-2016 extended the VHT capability fields to allow
indicating the number of spatial streams depending on the
actually used bandwidth, add support for decoding this.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/linux/ieee80211.h | 81 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 4a7200c6c9ea..eecae214c47a 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1457,13 +1457,16 @@ struct ieee80211_ht_operation {
  *	STA can receive. Rate expressed in units of 1 Mbps.
  *	If this field is 0 this value should not be used to
  *	consider the highest RX data rate supported.
- *	The top 3 bits of this field are reserved.
+ *	The top 3 bits of this field indicate the Maximum NSTS,total
+ *	(a beamformee capability.)
  * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
  * @tx_highest: Indicates highest long GI VHT PPDU data rate
  *	STA can transmit. Rate expressed in units of 1 Mbps.
  *	If this field is 0 this value should not be used to
  *	consider the highest TX data rate supported.
- *	The top 3 bits of this field are reserved.
+ *	The top 2 bits of this field are reserved, the
+ *	3rd bit from the top indiciates VHT Extended NSS BW
+ *	Capability.
  */
 struct ieee80211_vht_mcs_info {
 	__le16 rx_mcs_map;
@@ -1472,6 +1475,11 @@ struct ieee80211_vht_mcs_info {
 	__le16 tx_highest;
 } __packed;
 
+#define IEEE80211_VHT_MAX_NSTS_TOTAL_SHIFT	13
+#define IEEE80211_VHT_MAX_NSTS_TOTAL_MASK	(7 << IEEE80211_VHT_MAX_NSTS_TOTAL_SHIFT)
+
+#define IEEE80211_VHT_EXT_NSS_BW_CAPABLE	(1 << 13)
+
 /**
  * enum ieee80211_vht_mcs_support - VHT MCS support definitions
  * @IEEE80211_VHT_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the
@@ -1547,6 +1555,7 @@ struct ieee80211_vht_operation {
 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ		0x00000004
 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ	0x00000008
 #define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK			0x0000000C
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT			2
 #define IEEE80211_VHT_CAP_RXLDPC				0x00000010
 #define IEEE80211_VHT_CAP_SHORT_GI_80				0x00000020
 #define IEEE80211_VHT_CAP_SHORT_GI_160				0x00000040
@@ -1575,6 +1584,74 @@ struct ieee80211_vht_operation {
 #define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB	0x0c000000
 #define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN			0x10000000
 #define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN			0x20000000
+#define IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT			30
+#define IEEE80211_VHT_CAP_EXT_NSS_BW_MASK			0xc0000000
+
+static inline int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
+					    enum ieee80211_vht_chanwidth bw)
+{
+	unsigned long w;
+	int max_vht_nss;
+	int ext_nss_bw;
+	int supp_width;
+
+	if (cap->supp_mcs.rx_mcs_map == 0xffff)
+		return 0;
+
+	w = cap->supp_mcs.rx_mcs_map ^ 0xffff;
+	max_vht_nss = DIV_ROUND_UP(fls(w) + 1, 2);
+
+	if (!(cap->supp_mcs.tx_mcs_map & IEEE80211_VHT_EXT_NSS_BW_CAPABLE))
+		return max_vht_nss;
+
+	ext_nss_bw = (le32_to_cpu(cap->vht_cap_info) &
+					IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)
+			>> IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT;
+	supp_width = (le32_to_cpu(cap->vht_cap_info) &
+					IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)
+			>> IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT;
+
+	/*
+	 * Cover all the special cases according to IEEE 802.11-2016 Table 9-250.
+	 * All other cases are either factor of 1 or not valid/supported.
+	 */
+	switch (bw) {
+	case IEEE80211_VHT_CHANWIDTH_USE_HT:
+	case IEEE80211_VHT_CHANWIDTH_80MHZ:
+		if ((supp_width == 1 || supp_width == 2) &&
+		    ext_nss_bw == 3)
+			return 2 * max_vht_nss;
+		break;
+	case IEEE80211_VHT_CHANWIDTH_160MHZ:
+		if (supp_width == 0 &&
+		    (ext_nss_bw == 1 || ext_nss_bw == 2))
+			return DIV_ROUND_UP(max_vht_nss, 2);
+		if (supp_width == 0 &&
+		    ext_nss_bw == 3)
+			return DIV_ROUND_UP(3 * max_vht_nss, 4);
+		if (supp_width == 1 &&
+		    ext_nss_bw == 3)
+			return 2 * max_vht_nss;
+		break;
+	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
+		if (supp_width == 0 &&
+		    ext_nss_bw == 2)
+			return DIV_ROUND_UP(max_vht_nss, 2);
+		if (supp_width == 0 &&
+		    ext_nss_bw == 3)
+			return DIV_ROUND_UP(3 * max_vht_nss, 4);
+		if (supp_width == 1 &&
+		    ext_nss_bw == 1)
+			return DIV_ROUND_UP(max_vht_nss, 2);
+		if (supp_width == 1 &&
+		    ext_nss_bw == 2)
+			return DIV_ROUND_UP(3 * max_vht_nss, 4);
+		break;
+	}
+
+	/* not covered or invalid combination received */
+	return max_vht_nss;
+}
 
 /* Authentication algorithms */
 #define WLAN_AUTH_OPEN 0
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC 4/4] mac80211: add ability to parse CCFS2
  2017-02-14 11:28 [RFC 1/4] ieee80211: rename CCFS1/CCFS2 to CCFS0/CCFS1 Johannes Berg
  2017-02-14 11:28 ` [RFC 2/4] ieee80211: define HT operation CCFS2 field Johannes Berg
  2017-02-14 11:28 ` [RFC 3/4] ieee80211: add new VHT capability fields/parsing Johannes Berg
@ 2017-02-14 11:28 ` Johannes Berg
  2 siblings, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2017-02-14 11:28 UTC (permalink / raw)
  To: linux-wireless; +Cc: j, greearb, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

With newer VHT implementations, it's necessary to look at the
HT operation's CCFS2 field to identify the actual bandwidth
used.

NOTE: this cannot be applied until we make rate scaling aware
      of the NSS restrictions in the previous patches, and we
      may need to make this parsing conditional on that?

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/ibss.c        |  1 +
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/mesh.c        |  3 ++-
 net/mac80211/mlme.c        |  2 +-
 net/mac80211/spectmgmt.c   |  4 +++-
 net/mac80211/util.c        | 43 ++++++++++++++++++++++++++++---------------
 6 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 98999d3d5262..20abe88a82bb 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1066,6 +1066,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
 			struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap;
 
 			ieee80211_chandef_vht_oper(elems->vht_operation,
+						   elems->ht_operation,
 						   &chandef);
 			memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie));
 			ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 159a1a733725..3ee63fb38a8d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2072,6 +2072,7 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo);
 bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
 			       struct cfg80211_chan_def *chandef);
 bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper,
+				const struct ieee80211_ht_operation *htop,
 				struct cfg80211_chan_def *chandef);
 u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);
 
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c28b0af9c1f2..585b59104ab6 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -92,7 +92,8 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
 	cfg80211_chandef_create(&sta_chan_def, sdata->vif.bss_conf.chandef.chan,
 				NL80211_CHAN_NO_HT);
 	ieee80211_chandef_ht_oper(ie->ht_operation, &sta_chan_def);
-	ieee80211_chandef_vht_oper(ie->vht_operation, &sta_chan_def);
+	ieee80211_chandef_vht_oper(ie->vht_operation, ie->ht_operation,
+				   &sta_chan_def);
 
 	if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
 					 &sta_chan_def))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6e90301154d5..fedd4f798d55 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -213,7 +213,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
 	}
 
 	vht_chandef = *chandef;
-	if (!ieee80211_chandef_vht_oper(vht_oper, &vht_chandef)) {
+	if (!ieee80211_chandef_vht_oper(vht_oper, ht_oper, &vht_chandef)) {
 		if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
 			sdata_info(sdata,
 				   "AP VHT information is invalid, disable VHT\n");
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 0782e486fe89..b0cc99d5f4e9 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -138,6 +138,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
 				wide_bw_chansw_ie->new_center_freq_seg1,
 			/* .basic_mcs_set doesn't matter */
 		};
+		struct ieee80211_ht_operation ht_oper = {};
 
 		/* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT,
 		 * to the previously parsed chandef
@@ -145,7 +146,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
 		new_vht_chandef = csa_ie->chandef;
 
 		/* ignore if parsing fails */
-		if (!ieee80211_chandef_vht_oper(&vht_oper, &new_vht_chandef))
+		if (!ieee80211_chandef_vht_oper(&vht_oper, &ht_oper,
+						&new_vht_chandef))
 			new_vht_chandef.chan = NULL;
 
 		if (sta_flags & IEEE80211_STA_DISABLE_80P80MHZ &&
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7a37ce78bb38..10bdca76f469 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2483,48 +2483,61 @@ bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
 }
 
 bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper,
+				const struct ieee80211_ht_operation *htop,
 				struct cfg80211_chan_def *chandef)
 {
 	struct cfg80211_chan_def new = *chandef;
-	int cf1, cf2;
+	int cf0, cf1;
+	int ccfs0, ccfs1, ccfs2;
+	int ccf0, ccf1;
 
-	if (!oper)
+	if (!oper || !htop)
 		return false;
 
-	cf1 = ieee80211_channel_to_frequency(oper->center_freq_seg0_idx,
-					     chandef->chan->band);
-	cf2 = ieee80211_channel_to_frequency(oper->center_freq_seg1_idx,
-					     chandef->chan->band);
+	ccfs0 = oper->center_freq_seg0_idx;
+	ccfs1 = oper->center_freq_seg1_idx;
+	ccfs2 = (le16_to_cpu(htop->operation_mode) &
+				IEEE80211_HT_OP_MODE_CCFS2_MASK)
+			>> IEEE80211_HT_OP_MODE_CCFS2_SHIFT;
+
+	/* when parsing (and we know how to) CCFS1 and CCFS2 are equivalent */
+	ccf0 = ccfs0;
+	ccf1 = ccfs1 ?: ccfs2;
+
+	cf0 = ieee80211_channel_to_frequency(ccf0, chandef->chan->band);
+	cf1 = ieee80211_channel_to_frequency(ccf1, chandef->chan->band);
 
 	switch (oper->chan_width) {
 	case IEEE80211_VHT_CHANWIDTH_USE_HT:
+		/* just use HT information directly */
 		break;
 	case IEEE80211_VHT_CHANWIDTH_80MHZ:
 		new.width = NL80211_CHAN_WIDTH_80;
-		new.center_freq1 = cf1;
+		new.center_freq1 = cf0;
 		/* If needed, adjust based on the newer interop workaround. */
-		if (oper->center_freq_seg1_idx) {
+		if (ccf1) {
 			unsigned int diff;
 
-			diff = abs(oper->center_freq_seg1_idx -
-				   oper->center_freq_seg0_idx);
+			diff = abs(ccf1 - ccf0);
 			if (diff == 8) {
 				new.width = NL80211_CHAN_WIDTH_160;
-				new.center_freq1 = cf2;
+				new.center_freq1 = cf1;
 			} else if (diff > 8) {
 				new.width = NL80211_CHAN_WIDTH_80P80;
-				new.center_freq2 = cf2;
+				new.center_freq2 = cf1;
 			}
 		}
 		break;
 	case IEEE80211_VHT_CHANWIDTH_160MHZ:
+		/* deprecated encoding */
 		new.width = NL80211_CHAN_WIDTH_160;
-		new.center_freq1 = cf1;
+		new.center_freq1 = cf0;
 		break;
 	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
+		/* deprecated encoding */
 		new.width = NL80211_CHAN_WIDTH_80P80;
-		new.center_freq1 = cf1;
-		new.center_freq2 = cf2;
+		new.center_freq1 = cf0;
+		new.center_freq2 = cf1;
 		break;
 	default:
 		return false;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [RFC 3/4] ieee80211: add new VHT capability fields/parsing
  2017-02-14 11:28 ` [RFC 3/4] ieee80211: add new VHT capability fields/parsing Johannes Berg
@ 2017-02-14 13:06   ` Johannes Berg
  0 siblings, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2017-02-14 13:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: j, greearb


> +static inline int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap
> *cap,
> +					    enum
> ieee80211_vht_chanwidth bw)
> +{
> +	unsigned long w;
> +	int max_vht_nss;
> +	int ext_nss_bw;
> +	int supp_width;
> +
> +	if (cap->supp_mcs.rx_mcs_map == 0xffff)
> +		return 0;

Apart from the various endian issues, this function is completely wrong
because the max_vht_nss is per MCS (at least 0-7, 8 and 9 separately),
which this can't take into account.

Also, the only code that would use this right now, in mac80211,
probably won't use the same types as the parameters were to this
function.

I want to preserve the strange table somewhere in a single place, but
not sure yet how to do that best.

johannes

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-02-14 13:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-14 11:28 [RFC 1/4] ieee80211: rename CCFS1/CCFS2 to CCFS0/CCFS1 Johannes Berg
2017-02-14 11:28 ` [RFC 2/4] ieee80211: define HT operation CCFS2 field Johannes Berg
2017-02-14 11:28 ` [RFC 3/4] ieee80211: add new VHT capability fields/parsing Johannes Berg
2017-02-14 13:06   ` Johannes Berg
2017-02-14 11:28 ` [RFC 4/4] mac80211: add ability to parse CCFS2 Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.