diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1ea5e3fd3931..e3e1494e769a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -58,6 +58,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { | |||
58 | [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, | 58 | [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, |
59 | [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, | 59 | [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, |
60 | .len = BUS_ID_SIZE-1 }, | 60 | .len = BUS_ID_SIZE-1 }, |
61 | [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, | ||
61 | 62 | ||
62 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, | 63 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, |
63 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, | 64 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, |
@@ -286,20 +287,76 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
286 | return -ENOBUFS; | 287 | return -ENOBUFS; |
287 | } | 288 | } |
288 | 289 | ||
290 | static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { | ||
291 | [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 }, | ||
292 | [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 }, | ||
293 | [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 }, | ||
294 | [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 }, | ||
295 | [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 }, | ||
296 | }; | ||
297 | |||
298 | static int parse_txq_params(struct nlattr *tb[], | ||
299 | struct ieee80211_txq_params *txq_params) | ||
300 | { | ||
301 | if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] || | ||
302 | !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] || | ||
303 | !tb[NL80211_TXQ_ATTR_AIFS]) | ||
304 | return -EINVAL; | ||
305 | |||
306 | txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]); | ||
307 | txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]); | ||
308 | txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]); | ||
309 | txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]); | ||
310 | txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
289 | static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | 315 | static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) |
290 | { | 316 | { |
291 | struct cfg80211_registered_device *rdev; | 317 | struct cfg80211_registered_device *rdev; |
292 | int result; | 318 | int result = 0, rem_txq_params = 0; |
293 | 319 | struct nlattr *nl_txq_params; | |
294 | if (!info->attrs[NL80211_ATTR_WIPHY_NAME]) | ||
295 | return -EINVAL; | ||
296 | 320 | ||
297 | rdev = cfg80211_get_dev_from_info(info); | 321 | rdev = cfg80211_get_dev_from_info(info); |
298 | if (IS_ERR(rdev)) | 322 | if (IS_ERR(rdev)) |
299 | return PTR_ERR(rdev); | 323 | return PTR_ERR(rdev); |
300 | 324 | ||
301 | result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); | 325 | if (info->attrs[NL80211_ATTR_WIPHY_NAME]) { |
326 | result = cfg80211_dev_rename( | ||
327 | rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); | ||
328 | if (result) | ||
329 | goto bad_res; | ||
330 | } | ||
331 | |||
332 | if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { | ||
333 | struct ieee80211_txq_params txq_params; | ||
334 | struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1]; | ||
335 | |||
336 | if (!rdev->ops->set_txq_params) { | ||
337 | result = -EOPNOTSUPP; | ||
338 | goto bad_res; | ||
339 | } | ||
340 | |||
341 | nla_for_each_nested(nl_txq_params, | ||
342 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], | ||
343 | rem_txq_params) { | ||
344 | nla_parse(tb, NL80211_TXQ_ATTR_MAX, | ||
345 | nla_data(nl_txq_params), | ||
346 | nla_len(nl_txq_params), | ||
347 | txq_params_policy); | ||
348 | result = parse_txq_params(tb, &txq_params); | ||
349 | if (result) | ||
350 | goto bad_res; | ||
351 | |||
352 | result = rdev->ops->set_txq_params(&rdev->wiphy, | ||
353 | &txq_params); | ||
354 | if (result) | ||
355 | goto bad_res; | ||
356 | } | ||
357 | } | ||
302 | 358 | ||
359 | bad_res: | ||
303 | cfg80211_put_dev(rdev); | 360 | cfg80211_put_dev(rdev); |
304 | return result; | 361 | return result; |
305 | } | 362 | } |