Skip to contentSkip to conversation

cfg80211: Add channel type for IBSS

PATCH In review Alexander Simon 3 participants 18 messages Apr 12, 2011 – Apr 29, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/4 cfg80211: Add channel type for IBSS

Needed for IBSS IEEE802.11N operation

* Add ht channel type for cfg80211 IBSS configuration

---
 cfg80211.h |    1 +
 1 file changed, 1 insertion(+)
include/net/cfg80211.h +1 -0
diff -Nrup a/include/net/cfg80211.h b/include/net/cfg80211.h
@@ -964,6 +964,7 @@ struct cfg80211_ibss_params {
 	u8 *ssid;
 	u8 *bssid;
 	struct ieee80211_channel *channel;
+	enum nl80211_channel_type channel_type;
 	u8 *ie;
 	u8 ssid_len, ie_len;
 	u16 beacon_interval;
#1 lore raw

Re: [PATCH 2/4] nl80211: Add NL80211_ATTR_WIPHY_CHANNEL_TYPE for IBSS

Needed for IBSS IEEE802.11N operation

* Add a new attribute NL80211_ATTR_WIPHY_CHANNEL_TYPE to specify a HT channel type for IBSS

---
 nl80211.c |   20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)
net/wireless/nl80211.c +18 -2
diff -Nrup a/net/wireless/nl80211.c b/net/wireless/nl80211.c
@@ -3927,8 +3927,24 @@ static int nl80211_join_ibss(struct sk_b
 		ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	ibss.channel = ieee80211_get_channel(wiphy,
-		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+	if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+		enum nl80211_channel_type channel_type;
+
+		channel_type = nla_get_u32(
+			info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+		if (channel_type != NL80211_CHAN_NO_HT &&
+				channel_type != NL80211_CHAN_HT20 &&
+				channel_type != NL80211_CHAN_HT40PLUS &&
+				channel_type != NL80211_CHAN_HT40MINUS)
+			return -EINVAL;
+		ibss.channel_type = channel_type;
+	} else {
+		ibss.channel_type = NL80211_CHAN_NO_HT;
+	}
+
+	ibss.channel = rdev_freq_to_chan(rdev,
+		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
+		ibss.channel_type);
 	if (!ibss.channel ||
 	    ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
 	    ibss.channel->flags & IEEE80211_CHAN_DISABLED)
maintainer
#2 lore raw

Re: [PATCH 2/4] nl80211: Add NL80211_ATTR_WIPHY_CHANNEL_TYPE for IBSS

Quoted 8 lines · Alexander Simon

Needed for IBSS IEEE802.11N operation

* Add a new attribute NL80211_ATTR_WIPHY_CHANNEL_TYPE to specify a HT channel type for IBSS

net/wireless/nl80211.c +1 -2
-	ibss.channel = ieee80211_get_channel(wiphy,
-		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+	if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {

net/wireless/nl80211.c static int nl80211_join_ibss(struct sk_b · line 3940

Quoted 10 lines
net/wireless/nl80211.c +10 -0
+		enum nl80211_channel_type channel_type;
+
+		channel_type = nla_get_u32(
+			info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+		if (channel_type != NL80211_CHAN_NO_HT &&
+				channel_type != NL80211_CHAN_HT20 &&
+				channel_type != NL80211_CHAN_HT40PLUS &&
+				channel_type != NL80211_CHAN_HT40MINUS)
+			return -EINVAL;
+		ibss.channel_type = channel_type;

Please use Linux coding style.

net/wireless/nl80211.c static int nl80211_join_ibss(struct sk_b · line 3947

Quoted 3 lines
net/wireless/nl80211.c +3 -0
+	ibss.channel = rdev_freq_to_chan(rdev,
+		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
+		ibss.channel_type);

I don't think that is sufficient. Need to check that IBSS is allowed on both channels, maybe with a function like can_beacon_sec_chan.

johannes

#3 lore raw

Re: [PATCH 3/4] mac80211: Add function to build HT caps

In reply to Alexander Simon

Some refracturing work.

Add a new function ieee80211_ie_build_ht_cap in util.c. Use this shared code from ieee80211_build_preq_ies (util.c) and ieee80211_add_ht_ie (work.c)

This will be used from ibss.c also.

---
 ieee80211_i.h |    2 ++
 util.c        |   54 +++++++++++++++++++++++++++++++++++++-----------------
 work.c        |   29 +----------------------------
 3 files changed, 40 insertions(+), 45 deletions(-)
net/mac80211/ieee80211_i.h +2 -0
diff -Nrup a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
@@ -1351,6 +1352,8 @@ void ieee80211_recalc_smps(struct ieee80
 size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
 			  const u8 *ids, int n_ids, size_t offset);
 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+                              u16 cap);
 
 /* internal work items */
 void ieee80211_work_init(struct ieee80211_local *local);
net/mac80211/util.c +37 -17

63 lines not on this page · raw message

net/mac80211/work.c +1 -28
diff -Nrup a/net/mac80211/work.c b/net/mac80211/work.c
@@ -110,7 +110,6 @@ static void ieee80211_add_ht_ie(struct s
 	u8 *pos;
 	u32 flags = channel->flags;
 	u16 cap = sband->ht_cap.cap;
-	__le16 tmp;
 
 	if (!sband->ht_cap.ht_supported)
 		return;
@@ -161,34 +160,8 @@ static void ieee80211_add_ht_ie(struct s
 	}
 
 	/* reserve and fill IE */
-
 	pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
-	*pos++ = WLAN_EID_HT_CAPABILITY;
-	*pos++ = sizeof(struct ieee80211_ht_cap);
-	memset(pos, 0, sizeof(struct ieee80211_ht_cap));
-
-	/* capability flags */
-	tmp = cpu_to_le16(cap);
-	memcpy(pos, &tmp, sizeof(u16));
-	pos += sizeof(u16);
-
-	/* AMPDU parameters */
-	*pos++ = sband->ht_cap.ampdu_factor |
-		 (sband->ht_cap.ampdu_density <<
-			IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
-
-	/* MCS set */
-	memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
-	pos += sizeof(sband->ht_cap.mcs);
-
-	/* extended capabilities */
-	pos += sizeof(__le16);
-
-	/* BF capabilities */
-	pos += sizeof(__le32);
-
-	/* antenna selection */
-	pos += sizeof(u8);
+	ieee80211_ie_build_ht_cap(pos, sband, cap);
 }
 
 static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
maintainer
#4 lore raw

Re: [PATCH 3/4] mac80211: Add function to build HT caps

net/mac80211/util.c size_t ieee80211_ie_split_vendor(const u · line 1433

Quoted 2 lines · Alexander Simon
net/mac80211/util.c +2 -0
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+                              u16 cap)

It makes no sense to pass cap as an argument since it's taken from the sband.

johannes

#5 lore raw

Re: [PATCH 3/4] mac80211: Add function to build HT caps

Am Dienstag, den 12.04.2011, 13:16 +0200 schrieb Johannes Berg:

Quoted 10 lines · Alexander Simon

net/mac80211/util.c size_t ieee80211_ie_split_vendor(const u · line 1433

Quoted 3 lines
net/mac80211/util.c +2 -0
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+                              u16 cap)

It makes no sense to pass cap as an argument since it's taken from the sband.

johannes

Not true, in ieee80211_add_ht_ie in work.c cap is modified before.

Alex

#6 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

In reply to Alexander Simon

Okay, here we go. Hopefully this meets your requirements.

* Use HT IEs from other stations for rate algo
* Parameter to set HT channel type for IBSS join
* Build HT IEs when joining an IBSS
* Allow frame aggregation sessions for IBSS

HT operation will only be started for a station after receiving a beacon. So there may be a delay running in legacy when adding a station from a data packet to a third station (prepare_for_handlers).

---
 agg-rx.c      |    2 +
 agg-tx.c      |    5 ++-
 ht.c          |    2 +
 ibss.c        |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 ieee80211_i.h |    3 +
 rx.c          |    5 +--
 6 files changed, 95 insertions(+), 16 deletions(-)
net/mac80211/agg-rx.c +2 -0
diff -Nrup a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
@@ -160,6 +160,8 @@ static void ieee80211_send_addba_resp(st
 		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
 	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
 		memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+		memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
 
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 					  IEEE80211_STYPE_ACTION);
net/mac80211/agg-tx.c +4 -1
diff -Nrup a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
@@ -83,6 +83,8 @@ static void ieee80211_send_addba_request
 		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
 	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
 		memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+		memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
 
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 					  IEEE80211_STYPE_ACTION);
@@ -377,7 +379,8 @@ int ieee80211_start_tx_ba_session(struct
 	 */
 	if (sdata->vif.type != NL80211_IFTYPE_STATION &&
 	    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
-	    sdata->vif.type != NL80211_IFTYPE_AP)
+	    sdata->vif.type != NL80211_IFTYPE_AP &&
+	    sdata->vif.type != NL80211_IFTYPE_ADHOC)
 		return -EINVAL;
 
 	if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
net/mac80211/ht.c +2 -0
diff -Nrup a/net/mac80211/ht.c b/net/mac80211/ht.c
@@ -182,6 +182,8 @@ void ieee80211_send_delba(struct ieee802
 		memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
 	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
 		memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+		memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
 
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 					  IEEE80211_STYPE_ACTION);
net/mac80211/ibss.c +82 -12

181 lines not on this page · raw message

net/mac80211/ieee80211_i.h +2 -1
diff -Nrup a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
@@ -439,6 +439,7 @@ struct ieee80211_if_ibss {
 	u8 ssid_len, ie_len;
 	u8 *ie;
 	struct ieee80211_channel *channel;
+	enum nl80211_channel_type channel_type;
 
 	unsigned long ibss_join_req;
 	/* probe response/beacon for IBSS */
@@ -1107,7 +1108,7 @@ void ieee80211_ibss_notify_scan_complete
 void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
 struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 					u8 *bssid, u8 *addr, u32 supp_rates,
-					gfp_t gfp);
+					struct ieee80211_ht_cap *ht_cap, gfp_t gfp);
 int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 			struct cfg80211_ibss_params *params);
 int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
net/mac80211/rx.c +3 -2
diff -Nrup a/net/mac80211/rx.c b/net/mac80211/rx.c
@@ -2118,7 +2118,8 @@ ieee80211_rx_h_action(struct ieee80211_r
 		 */
 		if (sdata->vif.type != NL80211_IFTYPE_STATION &&
 		    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
-		    sdata->vif.type != NL80211_IFTYPE_AP)
+		    sdata->vif.type != NL80211_IFTYPE_AP &&
+		    sdata->vif.type != NL80211_IFTYPE_ADHOC)
 			break;
 
 		/* verify action_code is present */
@@ -2674,7 +2675,7 @@ static int prepare_for_handlers(struct i
 			else
 				rate_idx = status->rate_idx;
 			rx->sta = ieee80211_ibss_add_sta(sdata, bssid,
-					hdr->addr2, BIT(rate_idx), GFP_ATOMIC);
+					hdr->addr2, BIT(rate_idx), NULL, GFP_ATOMIC);
 		}
 		break;
 	case NL80211_IFTYPE_MESH_POINT:
maintainer
#7 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

net/mac80211/ibss.c int ieee80211_ibss_join(struct ieee80211 · line 967

Quoted 9 lines · Alexander Simon
net/mac80211/ibss.c +3 -5
 	skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
-			    36 /* bitrates */ +
-			    34 /* SSID */ +
-			    3  /* DS params */ +
-			    4  /* IBSS params */ +
-			    params->ie_len);
+				sizeof(struct ieee80211_hdr_3addr) + 
+				12 /* struct ieee80211_mgmt.u.beacon */ +
+				2 + IEEE80211_MAX_SSID_LEN /* max SSID */ +

You have a tendency to mess up the coding style.

Also what if the IBSS is created with HT40+ and then joins, can it join HT40-? Is the channel type "advisory" like the frequency? Can it join HT20 IBSS as well?

johannes

#8 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Quoted 3 lines

Also what if the IBSS is created with HT40+ and then joins, can it join HT40-? Is the channel type "advisory" like the frequency? Can it join HT20 IBSS as well?

HT type can`t be advisory, as there may be stations without n.

Our card is set to HT40+/- if set by iw.
Some other station is added into our internal station list by its HT beacons. E.g. if we have configured HT40- and there is someone with HT40+, minstrel_ht should use HT20 only. But i admit it seems cleaner to AND both caps.

maintainer
#9 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Quoted 4 lines · Alexander Simon
Quoted 3 lines

Also what if the IBSS is created with HT40+ and then joins, can it join HT40-? Is the channel type "advisory" like the frequency? Can it join HT20 IBSS as well?

HT type can`t be advisory, as there may be stations without n.

Yeah, but it's possible to still communicate with them.

Quoted 4 lines

Our card is set to HT40+/- if set by iw.
Some other station is added into our internal station list by its HT beacons. E.g. if we have configured HT40- and there is someone with HT40+, minstrel_ht should use HT20 only. But i admit it seems cleaner to AND both caps.

Well. You need to consider more than just this. I have a feeling you're only considering fixed channel use cases. But if we configure HT40+, and then find a peer on a channel that may only use HT40-, then what?

johannes

#10 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Quoted 3 lines

Well. You need to consider more than just this. I have a feeling you're only considering fixed channel use cases. But if we configure HT40+, and then find a peer on a channel that may only use HT40-, then what?

Good point. But still i think this is the same case. Right now, the card would still be set into HT40+, regardless of the frequency. Then, minstrel_ht would just use HT20, i suppose.

My proposal would be making the HT iw argument non-advisory: Use it when creating a network, discard it when joining one.

I also will do some refactoring in nl80211.c in order to check main and extension channel.

maintainer
#11 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Quoted 10 lines · Alexander Simon
Quoted 3 lines

Well. You need to consider more than just this. I have a feeling you're only considering fixed channel use cases. But if we configure HT40+, and then find a peer on a channel that may only use HT40-, then what?

Good point. But still i think this is the same case. Right now, the card would still be set into HT40+, regardless of the frequency. Then, minstrel_ht would just use HT20, i suppose.

My proposal would be making the HT iw argument non-advisory: Use it when creating a network, discard it when joining one.

Yeah it would be an option to just always join as HT if HT is available, but not create as HT unless asked.

johannes

#12 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Quoted 2 lines

Yeah it would be an option to just always join as HT if HT is available, but not create as HT unless asked.

Ok. I just had a few thoughts about this:
This way an ht ibss has to be created from a (patched) mac80211 HT hardware. There would be no way to "convert" an existing g network into n.
Additionally, if a non-ht implementation joins the network, it will advertise it as non-ht. If a second ht-station joins from one of these beacons, it won't use ht.

This way a single non-ht station could destroy a ht ibss.

I Think the best way to go would be to obey HT information when joining HT but using the HT iw parameter when joining non-ht.

Then we could have the following scenario: Non-HT station A creates non-HT.
HT station B joins and sets HT- (from iw). HT station C joins from A but doesn't see B. It's iw parameter says ht+.
But when B comes closer to C do a "HT merge", comparing TSFs.

Conclusion:
- Create an ibss with the iw parameter
- When joining a ht ibss, use its parameters
- When joining non-ht, add ht from iw parameter
- When encounter a different ht config, do a ht merge.

#13 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Sorry for replying to myself but i'll try to explain this a little bit easier:

- If the channel is not *fixed*, the channel type is only advisory. This means that a merge of two HT40 networks with fixed channels will only take place if the HT40 configuration equals.

- When merging, the looser will obey the winner's HT configuration if there is one. If not, keep the old one.

- If HT has been configured through iw and a non-HT network is to be joined, iw's HT setting is used and announced.

HT configuration within an IBSS may get inhomogeneous as a HT station may join from a non-HT beacon but there are other HT members.

- When receiving a different HT configuration from another member of our BSSID, use this configuration (first beacon wins)

Alex

maintainer
#14 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Quoted 2 lines · Alexander Simon

- If HT has been configured through iw and a non-HT network is to be joined, iw's HT setting is used and announced.

This isn't possible, you might join a network on a channel that doesn't allow HT40+ for example.

johannes

#15 lore raw

Re: [PATCH 4/4] mac80211: Add IEEE802.11n for IBSS

Quoted 5 lines
Quoted 2 lines

- If HT has been configured through iw and a non-HT network is to be joined, iw's HT setting is used and announced.

This isn't possible, you might join a network on a channel that doesn't allow HT40+ for example.

Of course it must be checked.
It has to be checked even when joining HT networks.
E.g. a european user travels to America and opens an HT+ Network on channel 9. The american card should disable HT40+.