aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h43
-rw-r--r--include/net/cfg80211.h23
-rw-r--r--net/mac80211/cfg.c25
-rw-r--r--net/wireless/nl80211.c67
4 files changed, 151 insertions, 7 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 5009809588c0..79827345351d 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -25,8 +25,9 @@
25 * 25 *
26 * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request 26 * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request
27 * to get a list of all present wiphys. 27 * to get a list of all present wiphys.
28 * @NL80211_CMD_SET_WIPHY: set wiphy name, needs %NL80211_ATTR_WIPHY and 28 * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
29 * %NL80211_ATTR_WIPHY_NAME. 29 * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME
30 * and/or %NL80211_ATTR_WIPHY_TXQ_PARAMS.
30 * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request 31 * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
31 * or rename notification. Has attributes %NL80211_ATTR_WIPHY and 32 * or rename notification. Has attributes %NL80211_ATTR_WIPHY and
32 * %NL80211_ATTR_WIPHY_NAME. 33 * %NL80211_ATTR_WIPHY_NAME.
@@ -178,6 +179,7 @@ enum nl80211_commands {
178 * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf. 179 * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf.
179 * /sys/class/ieee80211/<phyname>/index 180 * /sys/class/ieee80211/<phyname>/index
180 * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) 181 * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
182 * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
181 * 183 *
182 * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on 184 * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
183 * @NL80211_ATTR_IFNAME: network interface name 185 * @NL80211_ATTR_IFNAME: network interface name
@@ -312,6 +314,8 @@ enum nl80211_attrs {
312 314
313 NL80211_ATTR_BSS_BASIC_RATES, 315 NL80211_ATTR_BSS_BASIC_RATES,
314 316
317 NL80211_ATTR_WIPHY_TXQ_PARAMS,
318
315 /* add attributes here, update the policy in nl80211.c */ 319 /* add attributes here, update the policy in nl80211.c */
316 320
317 __NL80211_ATTR_AFTER_LAST, 321 __NL80211_ATTR_AFTER_LAST,
@@ -324,6 +328,7 @@ enum nl80211_attrs {
324 */ 328 */
325#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY 329#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
326#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES 330#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
331#define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
327 332
328#define NL80211_MAX_SUPP_RATES 32 333#define NL80211_MAX_SUPP_RATES 32
329#define NL80211_MAX_SUPP_REG_RULES 32 334#define NL80211_MAX_SUPP_REG_RULES 32
@@ -698,4 +703,38 @@ enum nl80211_meshconf_params {
698 NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1 703 NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
699}; 704};
700 705
706/**
707 * enum nl80211_txq_attr - TX queue parameter attributes
708 * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
709 * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
710 * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning
711 * disabled
712 * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form
713 * 2^n-1 in the range 1..32767]
714 * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form
715 * 2^n-1 in the range 1..32767]
716 * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255]
717 * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal
718 * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number
719 */
720enum nl80211_txq_attr {
721 __NL80211_TXQ_ATTR_INVALID,
722 NL80211_TXQ_ATTR_QUEUE,
723 NL80211_TXQ_ATTR_TXOP,
724 NL80211_TXQ_ATTR_CWMIN,
725 NL80211_TXQ_ATTR_CWMAX,
726 NL80211_TXQ_ATTR_AIFS,
727
728 /* keep last */
729 __NL80211_TXQ_ATTR_AFTER_LAST,
730 NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1
731};
732
733enum nl80211_txq_q {
734 NL80211_TXQ_Q_VO,
735 NL80211_TXQ_Q_VI,
736 NL80211_TXQ_Q_BE,
737 NL80211_TXQ_Q_BK
738};
739
701#endif /* __LINUX_NL80211_H */ 740#endif /* __LINUX_NL80211_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7caf3c76a12f..448023193e55 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -371,6 +371,24 @@ struct mesh_config {
371 u16 dot11MeshHWMPnetDiameterTraversalTime; 371 u16 dot11MeshHWMPnetDiameterTraversalTime;
372}; 372};
373 373
374/**
375 * struct ieee80211_txq_params - TX queue parameters
376 * @queue: TX queue identifier (NL80211_TXQ_Q_*)
377 * @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled
378 * @cwmin: Minimum contention window [a value of the form 2^n-1 in the range
379 * 1..32767]
380 * @cwmax: Maximum contention window [a value of the form 2^n-1 in the range
381 * 1..32767]
382 * @aifs: Arbitration interframe space [0..255]
383 */
384struct ieee80211_txq_params {
385 enum nl80211_txq_q queue;
386 u16 txop;
387 u16 cwmin;
388 u16 cwmax;
389 u8 aifs;
390};
391
374/* from net/wireless.h */ 392/* from net/wireless.h */
375struct wiphy; 393struct wiphy;
376 394
@@ -430,6 +448,8 @@ struct wiphy;
430 * @set_mesh_cfg: set mesh parameters (by now, just mesh id) 448 * @set_mesh_cfg: set mesh parameters (by now, just mesh id)
431 * 449 *
432 * @change_bss: Modify parameters for a given BSS. 450 * @change_bss: Modify parameters for a given BSS.
451 *
452 * @set_txq_params: Set TX queue parameters
433 */ 453 */
434struct cfg80211_ops { 454struct cfg80211_ops {
435 int (*add_virtual_intf)(struct wiphy *wiphy, char *name, 455 int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
@@ -490,6 +510,9 @@ struct cfg80211_ops {
490 const struct mesh_config *nconf, u32 mask); 510 const struct mesh_config *nconf, u32 mask);
491 int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, 511 int (*change_bss)(struct wiphy *wiphy, struct net_device *dev,
492 struct bss_parameters *params); 512 struct bss_parameters *params);
513
514 int (*set_txq_params)(struct wiphy *wiphy,
515 struct ieee80211_txq_params *params);
493}; 516};
494 517
495#endif /* __NET_CFG80211_H */ 518#endif /* __NET_CFG80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 442a4d7b1808..fe672faa819d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1069,6 +1069,30 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1069 return 0; 1069 return 0;
1070} 1070}
1071 1071
1072static int ieee80211_set_txq_params(struct wiphy *wiphy,
1073 struct ieee80211_txq_params *params)
1074{
1075 struct ieee80211_local *local = wiphy_priv(wiphy);
1076 struct ieee80211_tx_queue_params p;
1077
1078 if (!local->ops->conf_tx)
1079 return -EOPNOTSUPP;
1080
1081 memset(&p, 0, sizeof(p));
1082 p.aifs = params->aifs;
1083 p.cw_max = params->cwmax;
1084 p.cw_min = params->cwmin;
1085 p.txop = params->txop;
1086 if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) {
1087 printk(KERN_DEBUG "%s: failed to set TX queue "
1088 "parameters for queue %d\n", local->mdev->name,
1089 params->queue);
1090 return -EINVAL;
1091 }
1092
1093 return 0;
1094}
1095
1072struct cfg80211_ops mac80211_config_ops = { 1096struct cfg80211_ops mac80211_config_ops = {
1073 .add_virtual_intf = ieee80211_add_iface, 1097 .add_virtual_intf = ieee80211_add_iface,
1074 .del_virtual_intf = ieee80211_del_iface, 1098 .del_virtual_intf = ieee80211_del_iface,
@@ -1095,4 +1119,5 @@ struct cfg80211_ops mac80211_config_ops = {
1095 .get_mesh_params = ieee80211_get_mesh_params, 1119 .get_mesh_params = ieee80211_get_mesh_params,
1096#endif 1120#endif
1097 .change_bss = ieee80211_change_bss, 1121 .change_bss = ieee80211_change_bss,
1122 .set_txq_params = ieee80211_set_txq_params,
1098}; 1123};
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}