Add missing configuration symbol on CONFIG_INPUT_IXP4XX_BEEPER
[openwrt.git] / package / mac80211 / patches / 330-nl80211_ht40.patch
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).
4
5 Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
6 Acked-by: Johannes Berg <johannes@sipsolutions.net>
7
8
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
13 @@ -26,8 +26,9 @@
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.
25 @@ -180,6 +181,14 @@
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
33 + *             this attribute)
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
37   *
38   * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
39   * @NL80211_ATTR_IFNAME: network interface name
40 @@ -315,6 +324,8 @@
41         NL80211_ATTR_BSS_BASIC_RATES,
42  
43         NL80211_ATTR_WIPHY_TXQ_PARAMS,
44 +       NL80211_ATTR_WIPHY_FREQ,
45 +       NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET,
46  
47         /* add attributes here, update the policy in nl80211.c */
48  
49 @@ -329,6 +340,8 @@
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
55  
56  #define NL80211_MAX_SUPP_RATES                 32
57  #define NL80211_MAX_SUPP_REG_RULES             32
58 @@ -742,4 +755,10 @@
59         NL80211_TXQ_Q_BK
60  };
61  
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+ */
67 +};
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
73 @@ -392,6 +392,9 @@
74  /* from net/wireless.h */
75  struct wiphy;
76  
77 +/* from net/ieee80211.h */
78 +struct ieee80211_channel;
79 +
80  /**
81   * struct cfg80211_ops - backend description for wireless configuration
82   *
83 @@ -450,6 +453,8 @@
84   * @change_bss: Modify parameters for a given BSS.
85   *
86   * @set_txq_params: Set TX queue parameters
87 + *
88 + * @set_channel: Set channel
89   */
90  struct cfg80211_ops {
91         int     (*add_virtual_intf)(struct wiphy *wiphy, char *name,
92 @@ -513,6 +518,10 @@
93  
94         int     (*set_txq_params)(struct wiphy *wiphy,
95                                   struct ieee80211_txq_params *params);
96 +
97 +       int     (*set_channel)(struct wiphy *wiphy,
98 +                              struct ieee80211_channel *chan,
99 +                              enum nl80211_sec_chan_offset);
100  };
101  
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 @@
108         return 0;
109  }
110  
111 +static int ieee80211_set_channel(struct wiphy *wiphy,
112 +                                struct ieee80211_channel *chan,
113 +                                enum nl80211_sec_chan_offset sec_chan_offset)
114 +{
115 +       struct ieee80211_local *local = wiphy_priv(wiphy);
116 +
117 +       local->oper_channel = chan;
118 +       local->oper_sec_chan_offset = sec_chan_offset;
119 +
120 +       return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
121 +}
122 +
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 @@
127  #endif
128         .change_bss = ieee80211_change_bss,
129         .set_txq_params = ieee80211_set_txq_params,
130 +       .set_channel = ieee80211_set_channel,
131  };
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
136 @@ -59,6 +59,8 @@
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 },
142  
143         [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
144         [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
145 @@ -359,6 +361,61 @@
146                 }
147         }
148  
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;
154 +
155 +               if (!rdev->ops->set_channel) {
156 +                       result = -EOPNOTSUPP;
157 +                       goto bad_res;
158 +               }
159 +
160 +               if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) {
161 +                       sec_chan_offset = nla_get_u32(
162 +                               info->attrs[
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) {
168 +                               result = -EINVAL;
169 +                               goto bad_res;
170 +                       }
171 +               }
172 +
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 */
177 +                       result = -EINVAL;
178 +                       goto bad_res;
179 +               }
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;
184 +               else
185 +                       sec_freq = 0;
186 +
187 +               if (sec_freq) {
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 */
192 +                               result = -EINVAL;
193 +                               goto bad_res;
194 +                       }
195 +               }
196 +
197 +               result = rdev->ops->set_channel(&rdev->wiphy, chan,
198 +                                               sec_chan_offset);
199 +               if (result)
200 +                       goto bad_res;
201 +       }
202 +
203 +
204  bad_res:
205         cfg80211_put_dev(rdev);
206         return result;
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
211 @@ -507,6 +507,9 @@
212  
213  struct ieee80211_ht_conf {
214         bool enabled;
215 +       int sec_chan_offset; /* 0 = HT40 disabled; -1 = HT40 enabled, secondary
216 +                             * channel below primary; 1 = HT40 enabled,
217 +                             * secondary channel above primary */
218  };
219  
220  /**
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
225 @@ -641,6 +641,7 @@
226                     chan->flags & IEEE80211_CHAN_NO_IBSS)
227                         return ret;
228                 local->oper_channel = chan;
229 +               local->oper_sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
230  
231                 if (local->sw_scanning || local->hw_scanning)
232                         ret = 0;
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
237 @@ -626,6 +626,7 @@
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;
251         int ret = 0;
252         int power;
253 +       enum nl80211_sec_chan_offset sec_chan_offset;
254  
255         might_sleep();
256  
257 -       if (local->sw_scanning)
258 +       if (local->sw_scanning) {
259                 chan = local->scan_channel;
260 -       else
261 +               sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
262 +       } else {
263                 chan = local->oper_channel;
264 +               sec_chan_offset = local->oper_sec_chan_offset;
265 +       }
266  
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;
275 +                       break;
276 +               case NL80211_SEC_CHAN_DISABLED:
277 +                       local->hw.conf.ht.enabled = true;
278 +                       local->hw.conf.ht.sec_chan_offset = 0;
279 +                       break;
280 +               case NL80211_SEC_CHAN_BELOW:
281 +                       local->hw.conf.ht.enabled = true;
282 +                       local->hw.conf.ht.sec_chan_offset = -1;
283 +                       break;
284 +               case NL80211_SEC_CHAN_ABOVE:
285 +                       local->hw.conf.ht.enabled = true;
286 +                       local->hw.conf.ht.sec_chan_offset = 1;
287 +                       break;
288 +               }
289                 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
290         }
291  
292 -
293         if (!local->hw.conf.power_level)
294                 power = chan->max_power;
295         else
296
297 -- 
298 Jouni Malinen                                            PGP id EFC895FA
299 --
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
303