diff options
Diffstat (limited to 'package/mac80211/patches/020-nl80211-beacon-parameters.patch')
-rw-r--r-- | package/mac80211/patches/020-nl80211-beacon-parameters.patch | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/package/mac80211/patches/020-nl80211-beacon-parameters.patch b/package/mac80211/patches/020-nl80211-beacon-parameters.patch new file mode 100644 index 0000000000..51836f332f --- /dev/null +++ b/package/mac80211/patches/020-nl80211-beacon-parameters.patch @@ -0,0 +1,279 @@ +Subject: cfg80211/nl80211: add beacon settings + +This adds the necessary API to cfg80211/nl80211 to allow +changing beaconing settings. + +Signed-off-by: Johannes Berg <johannes@sipsolutions.net> + +--- + include/linux/nl80211.h | 24 ++++++++ + include/net/cfg80211.h | 33 +++++++++++ + net/wireless/nl80211.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 190 insertions(+) + +--- everything.orig/include/net/cfg80211.h 2007-11-08 11:50:57.412840007 +0100 ++++ everything/include/net/cfg80211.h 2007-11-08 16:50:38.421522842 +0100 +@@ -69,6 +69,26 @@ struct key_params { + u32 cipher; + }; + ++/** ++ * struct beacon_parameters - beacon parameters ++ * ++ * Used to configure the beacon for an interface. ++ * ++ * @head: head portion of beacon (before TIM IE) ++ * or %NULL if not changed ++ * @tail: tail portion of beacon (after TIM IE) ++ * or %NULL if not changed ++ * @interval: beacon interval or zero if not changed ++ * @dtim_period: DTIM period or zero if not changed ++ * @head_len: length of @head ++ * @tail_len: length of @tail ++ */ ++struct beacon_parameters { ++ u8 *head, *tail; ++ int interval, dtim_period; ++ int head_len, tail_len; ++}; ++ + /* from net/wireless.h */ + struct wiphy; + +@@ -103,6 +123,13 @@ struct wiphy; + * and @key_index + * + * @set_default_key: set the default key on an interface ++ * ++ * @add_beacon: Add a beacon with given parameters, @head, @interval ++ * and @dtim_period will be valid, @tail is optional. ++ * @set_beacon: Change the beacon parameters for an access point mode ++ * interface. This should reject the call when no beacon has been ++ * configured. ++ * @del_beacon: Remove beacon configuration and stop sending the beacon. + */ + struct cfg80211_ops { + int (*add_virtual_intf)(struct wiphy *wiphy, char *name, +@@ -122,6 +149,12 @@ struct cfg80211_ops { + int (*set_default_key)(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index); ++ ++ int (*add_beacon)(struct wiphy *wiphy, struct net_device *dev, ++ struct beacon_parameters *info); ++ int (*set_beacon)(struct wiphy *wiphy, struct net_device *dev, ++ struct beacon_parameters *info); ++ int (*del_beacon)(struct wiphy *wiphy, struct net_device *dev); + }; + + #endif /* __NET_CFG80211_H */ +--- everything.orig/include/linux/nl80211.h 2007-11-08 11:50:57.362839952 +0100 ++++ everything/include/linux/nl80211.h 2007-11-08 16:56:32.431522732 +0100 +@@ -47,6 +47,15 @@ + * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX + * or %NL80211_ATTR_MAC. + * ++ * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a ++ * %NL80222_CMD_NEW_BEACON message) ++ * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface ++ * using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD, ++ * %NL80211_BEACON_HEAD and %NL80211_BEACON_TAIL attributes. ++ * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface, ++ * parameters are like for %NL80211_CMD_SET_BEACON. ++ * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it ++ * + * @NL80211_CMD_MAX: highest used command number + * @__NL80211_CMD_AFTER_LAST: internal use + */ +@@ -69,6 +78,11 @@ enum nl80211_commands { + NL80211_CMD_NEW_KEY, + NL80211_CMD_DEL_KEY, + ++ NL80211_CMD_GET_BEACON, ++ NL80211_CMD_SET_BEACON, ++ NL80211_CMD_NEW_BEACON, ++ NL80211_CMD_DEL_BEACON, ++ + /* add commands here */ + + /* used to define NL80211_CMD_MAX below */ +@@ -101,6 +115,11 @@ enum nl80211_commands { + * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and + * CCMP keys, each six bytes in little endian + * ++ * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU ++ * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing ++ * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE ++ * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE ++ * + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use + */ +@@ -123,6 +142,11 @@ enum nl80211_attrs { + NL80211_ATTR_KEY_SEQ, + NL80211_ATTR_KEY_DEFAULT, + ++ NL80211_ATTR_BEACON_INTERVAL, ++ NL80211_ATTR_DTIM_PERIOD, ++ NL80211_ATTR_BEACON_HEAD, ++ NL80211_ATTR_BEACON_TAIL, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +--- everything.orig/net/wireless/nl80211.c 2007-11-08 11:50:57.382836589 +0100 ++++ everything/net/wireless/nl80211.c 2007-11-08 16:58:36.711524524 +0100 +@@ -69,6 +69,13 @@ static struct nla_policy nl80211_policy[ + [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, + [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, + [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, ++ ++ [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, ++ [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, ++ [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY, ++ .len = IEEE80211_MAX_DATA_LEN }, ++ [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY, ++ .len = IEEE80211_MAX_DATA_LEN }, + }; + + /* message building helper */ +@@ -600,6 +607,114 @@ static int nl80211_del_key(struct sk_buf + return err; + } + ++static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) ++{ ++ int (*call)(struct wiphy *wiphy, struct net_device *dev, ++ struct beacon_parameters *info); ++ struct cfg80211_registered_device *drv; ++ int err; ++ struct net_device *dev; ++ struct beacon_parameters params; ++ int haveinfo = 0; ++ ++ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); ++ if (err) ++ return err; ++ ++ switch (info->genlhdr->cmd) { ++ case NL80211_CMD_NEW_BEACON: ++ /* these are required for NEW_BEACON */ ++ if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || ++ !info->attrs[NL80211_ATTR_DTIM_PERIOD] || ++ !info->attrs[NL80211_ATTR_BEACON_HEAD]) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ call = drv->ops->add_beacon; ++ break; ++ case NL80211_CMD_SET_BEACON: ++ call = drv->ops->set_beacon; ++ break; ++ default: ++ WARN_ON(1); ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ ++ if (!call) { ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ ++ memset(¶ms, 0, sizeof(params)); ++ ++ if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { ++ params.interval = ++ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); ++ haveinfo = 1; ++ } ++ ++ if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) { ++ params.dtim_period = ++ nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); ++ haveinfo = 1; ++ } ++ ++ if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { ++ params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); ++ params.head_len = ++ nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); ++ haveinfo = 1; ++ } ++ ++ if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { ++ params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); ++ params.tail_len = ++ nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]); ++ haveinfo = 1; ++ } ++ ++ if (!haveinfo) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ rtnl_lock(); ++ err = call(&drv->wiphy, dev, ¶ms); ++ rtnl_unlock(); ++ ++ out: ++ cfg80211_put_dev(drv); ++ dev_put(dev); ++ return err; ++} ++ ++static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct cfg80211_registered_device *drv; ++ int err; ++ struct net_device *dev; ++ ++ err = get_drv_dev_by_info_ifindex(info, &drv, &dev); ++ if (err) ++ return err; ++ ++ if (!drv->ops->del_beacon) { ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ ++ rtnl_lock(); ++ err = drv->ops->del_beacon(&drv->wiphy, dev); ++ rtnl_unlock(); ++ ++ out: ++ cfg80211_put_dev(drv); ++ dev_put(dev); ++ return err; ++} ++ + static struct genl_ops nl80211_ops[] = { + { + .cmd = NL80211_CMD_GET_WIPHY, +@@ -663,6 +778,24 @@ static struct genl_ops nl80211_ops[] = { + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, ++ { ++ .cmd = NL80211_CMD_SET_BEACON, ++ .policy = nl80211_policy, ++ .flags = GENL_ADMIN_PERM, ++ .doit = nl80211_addset_beacon, ++ }, ++ { ++ .cmd = NL80211_CMD_NEW_BEACON, ++ .policy = nl80211_policy, ++ .flags = GENL_ADMIN_PERM, ++ .doit = nl80211_addset_beacon, ++ }, ++ { ++ .cmd = NL80211_CMD_DEL_BEACON, ++ .policy = nl80211_policy, ++ .flags = GENL_ADMIN_PERM, ++ .doit = nl80211_del_beacon, ++ }, + }; + + /* multicast groups */ |