1 This patch adds new NL80211_CMD_SET_WIPHY attributes
2 NL80211_ATTR_WIPHY_FREQ and NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET to allow
3 userspace to set the operating channel (e.g., hostapd for AP mode).
5 Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
6 Acked-by: Johannes Berg <johannes@sipsolutions.net>
9 Index: wireless-testing/include/linux/nl80211.h
10 ===================================================================
11 --- wireless-testing.orig/include/linux/nl80211.h 2008-11-26 15:15:31.000000000 +0200
12 +++ wireless-testing/include/linux/nl80211.h 2008-11-26 15:16:59.000000000 +0200
14 * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request
15 * to get a list of all present wiphys.
16 * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
17 - * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME
18 - * and/or %NL80211_ATTR_WIPHY_TXQ_PARAMS.
19 + * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
20 + * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, and/or
21 + * %NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET.
22 * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
23 * or rename notification. Has attributes %NL80211_ATTR_WIPHY and
24 * %NL80211_ATTR_WIPHY_NAME.
26 * /sys/class/ieee80211/<phyname>/index
27 * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
28 * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
29 + * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz
30 + * @NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET: included with NL80211_ATTR_WIPHY_FREQ
31 + * if HT20 or HT40 are allowed (i.e., 802.11n disabled if not included):
32 + * NL80211_SEC_CHAN_NO_HT = HT not allowed (i.e., same as not including
34 + * NL80211_SEC_CHAN_DISABLED = HT20 only
35 + * NL80211_SEC_CHAN_BELOW = secondary channel is below the primary channel
36 + * NL80211_SEC_CHAN_ABOVE = secondary channel is above the primary channel
38 * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
39 * @NL80211_ATTR_IFNAME: network interface name
41 NL80211_ATTR_BSS_BASIC_RATES,
43 NL80211_ATTR_WIPHY_TXQ_PARAMS,
44 + NL80211_ATTR_WIPHY_FREQ,
45 + NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET,
47 /* add attributes here, update the policy in nl80211.c */
50 #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
51 #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
52 #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
53 +#define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ
54 +#define NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET
56 #define NL80211_MAX_SUPP_RATES 32
57 #define NL80211_MAX_SUPP_REG_RULES 32
62 +enum nl80211_sec_chan_offset {
63 + NL80211_SEC_CHAN_NO_HT /* No HT */,
64 + NL80211_SEC_CHAN_DISABLED /* HT20 only */,
65 + NL80211_SEC_CHAN_BELOW /* HT40- */,
66 + NL80211_SEC_CHAN_ABOVE /* HT40+ */
68 #endif /* __LINUX_NL80211_H */
69 Index: wireless-testing/include/net/cfg80211.h
70 ===================================================================
71 --- wireless-testing.orig/include/net/cfg80211.h 2008-11-26 15:15:31.000000000 +0200
72 +++ wireless-testing/include/net/cfg80211.h 2008-11-26 15:29:50.000000000 +0200
74 /* from net/wireless.h */
77 +/* from net/ieee80211.h */
78 +struct ieee80211_channel;
81 * struct cfg80211_ops - backend description for wireless configuration
84 * @change_bss: Modify parameters for a given BSS.
86 * @set_txq_params: Set TX queue parameters
88 + * @set_channel: Set channel
91 int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
94 int (*set_txq_params)(struct wiphy *wiphy,
95 struct ieee80211_txq_params *params);
97 + int (*set_channel)(struct wiphy *wiphy,
98 + struct ieee80211_channel *chan,
99 + enum nl80211_sec_chan_offset);
102 #endif /* __NET_CFG80211_H */
103 Index: wireless-testing/net/mac80211/cfg.c
104 ===================================================================
105 --- wireless-testing.orig/net/mac80211/cfg.c 2008-11-26 15:15:31.000000000 +0200
106 +++ wireless-testing/net/mac80211/cfg.c 2008-11-26 15:19:34.000000000 +0200
107 @@ -1095,6 +1095,18 @@
111 +static int ieee80211_set_channel(struct wiphy *wiphy,
112 + struct ieee80211_channel *chan,
113 + enum nl80211_sec_chan_offset sec_chan_offset)
115 + struct ieee80211_local *local = wiphy_priv(wiphy);
117 + local->oper_channel = chan;
118 + local->oper_sec_chan_offset = sec_chan_offset;
120 + return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
123 struct cfg80211_ops mac80211_config_ops = {
124 .add_virtual_intf = ieee80211_add_iface,
125 .del_virtual_intf = ieee80211_del_iface,
126 @@ -1122,4 +1134,5 @@
128 .change_bss = ieee80211_change_bss,
129 .set_txq_params = ieee80211_set_txq_params,
130 + .set_channel = ieee80211_set_channel,
132 Index: wireless-testing/net/wireless/nl80211.c
133 ===================================================================
134 --- wireless-testing.orig/net/wireless/nl80211.c 2008-11-26 15:15:31.000000000 +0200
135 +++ wireless-testing/net/wireless/nl80211.c 2008-11-26 15:31:31.000000000 +0200
137 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
138 .len = BUS_ID_SIZE-1 },
139 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
140 + [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
141 + [NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET] = { .type = NLA_U32 },
143 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
144 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
149 + if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
150 + enum nl80211_sec_chan_offset sec_chan_offset =
151 + NL80211_SEC_CHAN_NO_HT;
152 + struct ieee80211_channel *chan;
153 + u32 freq, sec_freq;
155 + if (!rdev->ops->set_channel) {
156 + result = -EOPNOTSUPP;
160 + if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) {
161 + sec_chan_offset = nla_get_u32(
163 + NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]);
164 + if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT &&
165 + sec_chan_offset != NL80211_SEC_CHAN_DISABLED &&
166 + sec_chan_offset != NL80211_SEC_CHAN_BELOW &&
167 + sec_chan_offset != NL80211_SEC_CHAN_ABOVE) {
173 + freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
174 + chan = ieee80211_get_channel(&rdev->wiphy, freq);
175 + if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
176 + /* Primary channel not allowed */
180 + if (sec_chan_offset == NL80211_SEC_CHAN_BELOW)
181 + sec_freq = freq - 20;
182 + else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE)
183 + sec_freq = freq + 20;
188 + struct ieee80211_channel *schan;
189 + schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
190 + if (!schan || schan->flags & IEEE80211_CHAN_DISABLED) {
191 + /* Secondary channel not allowed */
197 + result = rdev->ops->set_channel(&rdev->wiphy, chan,
205 cfg80211_put_dev(rdev);
207 Index: wireless-testing/include/net/mac80211.h
208 ===================================================================
209 --- wireless-testing.orig/include/net/mac80211.h 2008-11-26 15:15:31.000000000 +0200
210 +++ wireless-testing/include/net/mac80211.h 2008-11-26 15:15:47.000000000 +0200
213 struct ieee80211_ht_conf {
215 + int sec_chan_offset; /* 0 = HT40 disabled; -1 = HT40 enabled, secondary
216 + * channel below primary; 1 = HT40 enabled,
217 + * secondary channel above primary */
221 Index: wireless-testing/net/mac80211/util.c
222 ===================================================================
223 --- wireless-testing.orig/net/mac80211/util.c 2008-11-26 15:15:31.000000000 +0200
224 +++ wireless-testing/net/mac80211/util.c 2008-11-26 15:20:26.000000000 +0200
226 chan->flags & IEEE80211_CHAN_NO_IBSS)
228 local->oper_channel = chan;
229 + local->oper_sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
231 if (local->sw_scanning || local->hw_scanning)
233 Index: wireless-testing/net/mac80211/ieee80211_i.h
234 ===================================================================
235 --- wireless-testing.orig/net/mac80211/ieee80211_i.h 2008-11-26 15:15:31.000000000 +0200
236 +++ wireless-testing/net/mac80211/ieee80211_i.h 2008-11-26 15:20:12.000000000 +0200
238 struct delayed_work scan_work;
239 struct ieee80211_sub_if_data *scan_sdata;
240 struct ieee80211_channel *oper_channel, *scan_channel;
241 + enum nl80211_sec_chan_offset oper_sec_chan_offset;
242 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
243 size_t scan_ssid_len;
244 struct list_head bss_list;
245 Index: wireless-testing/net/mac80211/main.c
246 ===================================================================
247 --- wireless-testing.orig/net/mac80211/main.c 2008-11-26 15:15:31.000000000 +0200
248 +++ wireless-testing/net/mac80211/main.c 2008-11-26 15:29:09.000000000 +0200
249 @@ -195,20 +195,42 @@
250 struct ieee80211_channel *chan;
253 + enum nl80211_sec_chan_offset sec_chan_offset;
257 - if (local->sw_scanning)
258 + if (local->sw_scanning) {
259 chan = local->scan_channel;
261 + sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
263 chan = local->oper_channel;
264 + sec_chan_offset = local->oper_sec_chan_offset;
267 - if (chan != local->hw.conf.channel) {
268 + if (chan != local->hw.conf.channel ||
269 + sec_chan_offset != local->hw.conf.ht.sec_chan_offset) {
270 local->hw.conf.channel = chan;
271 + switch (sec_chan_offset) {
272 + case NL80211_SEC_CHAN_NO_HT:
273 + local->hw.conf.ht.enabled = false;
274 + local->hw.conf.ht.sec_chan_offset = 0;
276 + case NL80211_SEC_CHAN_DISABLED:
277 + local->hw.conf.ht.enabled = true;
278 + local->hw.conf.ht.sec_chan_offset = 0;
280 + case NL80211_SEC_CHAN_BELOW:
281 + local->hw.conf.ht.enabled = true;
282 + local->hw.conf.ht.sec_chan_offset = -1;
284 + case NL80211_SEC_CHAN_ABOVE:
285 + local->hw.conf.ht.enabled = true;
286 + local->hw.conf.ht.sec_chan_offset = 1;
289 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
293 if (!local->hw.conf.power_level)
294 power = chan->max_power;
298 Jouni Malinen PGP id EFC895FA
300 To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
301 the body of a message to majordomo@vger.kernel.org
302 More majordomo info at http://vger.kernel.org/majordomo-info.html