aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-01-24 13:38:39 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:32 -0500
commitee688b000d35f413f33561ec9c7d3355be561e2f (patch)
treee0814191f873ba6f397ffb419b5e37ed4c0c531c
parent8318d78a44d49ac1edf2bdec7299de3617c4232e (diff)
nl80211: export hardware bitrate/channel capabilities
This makes nl80211 export the hardware bitrate/channel capabilities as registered in a wiphy. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/linux/nl80211.h64
-rw-r--r--net/wireless/nl80211.c74
2 files changed, 138 insertions, 0 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 9fecf902419c..63695060db9f 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -161,6 +161,9 @@ enum nl80211_commands {
161 * given for %NL80211_CMD_GET_STATION, nested attribute containing 161 * given for %NL80211_CMD_GET_STATION, nested attribute containing
162 * info as possible, see &enum nl80211_sta_stats. 162 * info as possible, see &enum nl80211_sta_stats.
163 * 163 *
164 * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands,
165 * consisting of a nested array.
166 *
164 * @NL80211_ATTR_MAX: highest attribute number currently defined 167 * @NL80211_ATTR_MAX: highest attribute number currently defined
165 * @__NL80211_ATTR_AFTER_LAST: internal use 168 * @__NL80211_ATTR_AFTER_LAST: internal use
166 */ 169 */
@@ -195,6 +198,8 @@ enum nl80211_attrs {
195 NL80211_ATTR_STA_VLAN, 198 NL80211_ATTR_STA_VLAN,
196 NL80211_ATTR_STA_STATS, 199 NL80211_ATTR_STA_STATS,
197 200
201 NL80211_ATTR_WIPHY_BANDS,
202
198 /* add attributes here, update the policy in nl80211.c */ 203 /* add attributes here, update the policy in nl80211.c */
199 204
200 __NL80211_ATTR_AFTER_LAST, 205 __NL80211_ATTR_AFTER_LAST,
@@ -280,4 +285,63 @@ enum nl80211_sta_stats {
280 NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1 285 NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1
281}; 286};
282 287
288/**
289 * enum nl80211_band_attr - band attributes
290 * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved
291 * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band,
292 * an array of nested frequency attributes
293 * @NL80211_BAND_ATTR_RATES: supported bitrates in this band,
294 * an array of nested bitrate attributes
295 */
296enum nl80211_band_attr {
297 __NL80211_BAND_ATTR_INVALID,
298 NL80211_BAND_ATTR_FREQS,
299 NL80211_BAND_ATTR_RATES,
300
301 /* keep last */
302 __NL80211_BAND_ATTR_AFTER_LAST,
303 NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
304};
305
306/**
307 * enum nl80211_frequency_attr - frequency attributes
308 * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
309 * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
310 * regulatory domain.
311 * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is
312 * permitted on this channel in current regulatory domain.
313 * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted
314 * on this channel in current regulatory domain.
315 * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
316 * on this channel in current regulatory domain.
317 */
318enum nl80211_frequency_attr {
319 __NL80211_FREQUENCY_ATTR_INVALID,
320 NL80211_FREQUENCY_ATTR_FREQ,
321 NL80211_FREQUENCY_ATTR_DISABLED,
322 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN,
323 NL80211_FREQUENCY_ATTR_NO_IBSS,
324 NL80211_FREQUENCY_ATTR_RADAR,
325
326 /* keep last */
327 __NL80211_FREQUENCY_ATTR_AFTER_LAST,
328 NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
329};
330
331/**
332 * enum nl80211_bitrate_attr - bitrate attributes
333 * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps
334 * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported
335 * in 2.4 GHz band.
336 */
337enum nl80211_bitrate_attr {
338 __NL80211_BITRATE_ATTR_INVALID,
339 NL80211_BITRATE_ATTR_RATE,
340 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE,
341
342 /* keep last */
343 __NL80211_BITRATE_ATTR_AFTER_LAST,
344 NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1
345};
346
283#endif /* __LINUX_NL80211_H */ 347#endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e3a214f63f91..b123f58d3909 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -98,6 +98,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
98 struct cfg80211_registered_device *dev) 98 struct cfg80211_registered_device *dev)
99{ 99{
100 void *hdr; 100 void *hdr;
101 struct nlattr *nl_bands, *nl_band;
102 struct nlattr *nl_freqs, *nl_freq;
103 struct nlattr *nl_rates, *nl_rate;
104 enum ieee80211_band band;
105 struct ieee80211_channel *chan;
106 struct ieee80211_rate *rate;
107 int i;
101 108
102 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); 109 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
103 if (!hdr) 110 if (!hdr)
@@ -105,6 +112,73 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
105 112
106 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); 113 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
107 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 114 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
115
116 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
117 if (!nl_bands)
118 goto nla_put_failure;
119
120 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
121 if (!dev->wiphy.bands[band])
122 continue;
123
124 nl_band = nla_nest_start(msg, band);
125 if (!nl_band)
126 goto nla_put_failure;
127
128 /* add frequencies */
129 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
130 if (!nl_freqs)
131 goto nla_put_failure;
132
133 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
134 nl_freq = nla_nest_start(msg, i);
135 if (!nl_freq)
136 goto nla_put_failure;
137
138 chan = &dev->wiphy.bands[band]->channels[i];
139 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
140 chan->center_freq);
141
142 if (chan->flags & IEEE80211_CHAN_DISABLED)
143 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
144 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
145 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
146 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
147 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
148 if (chan->flags & IEEE80211_CHAN_RADAR)
149 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
150
151 nla_nest_end(msg, nl_freq);
152 }
153
154 nla_nest_end(msg, nl_freqs);
155
156 /* add bitrates */
157 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
158 if (!nl_rates)
159 goto nla_put_failure;
160
161 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
162 nl_rate = nla_nest_start(msg, i);
163 if (!nl_rate)
164 goto nla_put_failure;
165
166 rate = &dev->wiphy.bands[band]->bitrates[i];
167 NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
168 rate->bitrate);
169 if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
170 NLA_PUT_FLAG(msg,
171 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
172
173 nla_nest_end(msg, nl_rate);
174 }
175
176 nla_nest_end(msg, nl_rates);
177
178 nla_nest_end(msg, nl_band);
179 }
180 nla_nest_end(msg, nl_bands);
181
108 return genlmsg_end(msg, hdr); 182 return genlmsg_end(msg, hdr);
109 183
110 nla_put_failure: 184 nla_put_failure: