aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2008-08-07 13:07:01 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-29 16:23:55 -0400
commit9f1ba9062e032fb7b395cd27fc564754fe4e9867 (patch)
tree6610106cd769aa3cc144b7a4f1547e07eeba5c88 /net
parent7f93ea3e246db512c0c17b79847f57dd3a2891e1 (diff)
mac80211/cfg80211: Add BSS configuration options for AP mode
This change adds a new cfg80211 command, NL80211_CMD_SET_BSS, to allow AP mode BSS parameters to be changed from user space (e.g., hostapd). The drivers using mac80211 are expected to be modified with separate changes to use the new BSS info parameter for short slot time in the bss_info_changed() handler. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c37
-rw-r--r--net/wireless/nl80211.c52
2 files changed, 89 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6d2ad2bf3ab5..2b19532f4c8a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1010,6 +1010,42 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1010} 1010}
1011#endif 1011#endif
1012 1012
1013static int ieee80211_change_bss(struct wiphy *wiphy,
1014 struct net_device *dev,
1015 struct bss_parameters *params)
1016{
1017 struct ieee80211_local *local = wiphy_priv(wiphy);
1018 struct ieee80211_sub_if_data *sdata;
1019 u32 changed = 0;
1020
1021 if (dev == local->mdev)
1022 return -EOPNOTSUPP;
1023
1024 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1025
1026 if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
1027 return -EINVAL;
1028
1029 if (params->use_cts_prot >= 0) {
1030 sdata->bss_conf.use_cts_prot = params->use_cts_prot;
1031 changed |= BSS_CHANGED_ERP_CTS_PROT;
1032 }
1033 if (params->use_short_preamble >= 0) {
1034 sdata->bss_conf.use_short_preamble =
1035 params->use_short_preamble;
1036 changed |= BSS_CHANGED_ERP_PREAMBLE;
1037 }
1038 if (params->use_short_slot_time >= 0) {
1039 sdata->bss_conf.use_short_slot =
1040 params->use_short_slot_time;
1041 changed |= BSS_CHANGED_ERP_SLOT;
1042 }
1043
1044 ieee80211_bss_info_change_notify(sdata, changed);
1045
1046 return 0;
1047}
1048
1013struct cfg80211_ops mac80211_config_ops = { 1049struct cfg80211_ops mac80211_config_ops = {
1014 .add_virtual_intf = ieee80211_add_iface, 1050 .add_virtual_intf = ieee80211_add_iface,
1015 .del_virtual_intf = ieee80211_del_iface, 1051 .del_virtual_intf = ieee80211_del_iface,
@@ -1033,4 +1069,5 @@ struct cfg80211_ops mac80211_config_ops = {
1033 .get_mpath = ieee80211_get_mpath, 1069 .get_mpath = ieee80211_get_mpath,
1034 .dump_mpath = ieee80211_dump_mpath, 1070 .dump_mpath = ieee80211_dump_mpath,
1035#endif 1071#endif
1072 .change_bss = ieee80211_change_bss,
1036}; 1073};
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 59eb2cf42e5f..47542ee01c57 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -87,6 +87,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
87 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, 87 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
88 .len = IEEE80211_MAX_MESH_ID_LEN }, 88 .len = IEEE80211_MAX_MESH_ID_LEN },
89 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, 89 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
90
91 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
92 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
93 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90}; 94};
91 95
92/* message building helper */ 96/* message building helper */
@@ -1525,6 +1529,48 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1525 return err; 1529 return err;
1526} 1530}
1527 1531
1532static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1533{
1534 struct cfg80211_registered_device *drv;
1535 int err;
1536 struct net_device *dev;
1537 struct bss_parameters params;
1538
1539 memset(&params, 0, sizeof(params));
1540 /* default to not changing parameters */
1541 params.use_cts_prot = -1;
1542 params.use_short_preamble = -1;
1543 params.use_short_slot_time = -1;
1544
1545 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
1546 params.use_cts_prot =
1547 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
1548 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
1549 params.use_short_preamble =
1550 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
1551 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1552 params.use_short_slot_time =
1553 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1554
1555 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1556 if (err)
1557 return err;
1558
1559 if (!drv->ops->change_bss) {
1560 err = -EOPNOTSUPP;
1561 goto out;
1562 }
1563
1564 rtnl_lock();
1565 err = drv->ops->change_bss(&drv->wiphy, dev, &params);
1566 rtnl_unlock();
1567
1568 out:
1569 cfg80211_put_dev(drv);
1570 dev_put(dev);
1571 return err;
1572}
1573
1528static struct genl_ops nl80211_ops[] = { 1574static struct genl_ops nl80211_ops[] = {
1529 { 1575 {
1530 .cmd = NL80211_CMD_GET_WIPHY, 1576 .cmd = NL80211_CMD_GET_WIPHY,
@@ -1656,6 +1702,12 @@ static struct genl_ops nl80211_ops[] = {
1656 .policy = nl80211_policy, 1702 .policy = nl80211_policy,
1657 .flags = GENL_ADMIN_PERM, 1703 .flags = GENL_ADMIN_PERM,
1658 }, 1704 },
1705 {
1706 .cmd = NL80211_CMD_SET_BSS,
1707 .doit = nl80211_set_bss,
1708 .policy = nl80211_policy,
1709 .flags = GENL_ADMIN_PERM,
1710 },
1659}; 1711};
1660 1712
1661/* multicast groups */ 1713/* multicast groups */