aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c67
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
290static 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
298static 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
289static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) 315static 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
359bad_res:
303 cfg80211_put_dev(rdev); 360 cfg80211_put_dev(rdev);
304 return result; 361 return result;
305} 362}