This command triggers a new callback: set_mcast_rate(). It enables
the user to change the rate used to send multicast frames for vif
configured as IBSS or MESH_POINT
Signed-off-by: Antonio Quartulli <[email protected]>
---
v2:
- added check for !set_mcast_rate in nl80211_set_mcast_rate()
- moved all the changes for cfg80211 in 1/2. 2/2 now contains mac80211
changes only
v3:
- rebased on last mac80211-next
- fixed destination param in memcpy in ieee80211_mcast_rate()
include/net/cfg80211.h | 6 ++++++
include/uapi/linux/nl80211.h | 5 +++++
net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index aa0e4a1..63c9ba2 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1544,6 +1544,9 @@ struct cfg80211_gtk_rekey_data {
* to a merge.
* @leave_ibss: Leave the IBSS.
*
+ * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or
+ * MESH mode)
+ *
* @set_wiphy_params: Notify that wiphy parameters have changed;
* @changed bitfield (see &enum wiphy_params_flags) describes which values
* have changed. The actual parameter values are available in
@@ -1745,6 +1748,9 @@ struct cfg80211_ops {
struct cfg80211_ibss_params *params);
int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
+ int (*set_mcast_rate)(struct wiphy *wiphy, struct net_device *dev,
+ int rate[IEEE80211_NUM_BANDS]);
+
int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);
int (*set_tx_power)(struct wiphy *wiphy,
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 617d0fb..654ff1e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -578,6 +578,9 @@
* station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON
* is used for this.
*
+ * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
+ * for IBSS or MESH vif.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -726,6 +729,8 @@ enum nl80211_commands {
NL80211_CMD_CONN_FAILED,
+ NL80211_CMD_SET_MCAST_RATE,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8c08578..4c774a9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5444,6 +5444,36 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
return cfg80211_leave_ibss(rdev, dev, false);
}
+static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ int mcast_rate[IEEE80211_NUM_BANDS];
+ u32 nla_rate;
+ int err;
+
+ if (!rdev->ops->set_mcast_rate)
+ return -EOPNOTSUPP;
+
+ memset(mcast_rate, 0, sizeof(mcast_rate));
+
+ if (!info->attrs[NL80211_ATTR_MCAST_RATE])
+ return -EINVAL;
+
+ nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
+ if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
+ return -EINVAL;
+
+ wdev_lock(dev->ieee80211_ptr);
+
+ err = rdev->ops->set_mcast_rate(&rdev->wiphy, dev, mcast_rate);
+
+ wdev_unlock(dev->ieee80211_ptr);
+
+ return err;
+}
+
+
#ifdef CONFIG_NL80211_TESTMODE
static struct genl_multicast_group nl80211_testmode_mcgrp = {
.name = "testmode",
@@ -7625,6 +7655,14 @@ static struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_SET_MCAST_RATE,
+ .doit = nl80211_set_mcast_rate,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
--
1.7.12.4
This new callback can be used to tune the rate to be used to send
multicast frames. The callback can be used with vif configured as
ADHOC or MESH_POINT only.
In the current state the multicast rate can be specified on IBSS/MESH
joining only. This makes it impossible to select a custom multicast
rate when then join command is sent by an external program (e.g.
wpa_supplicant)
Signed-off-by: Antonio Quartulli <[email protected]>
---
net/mac80211/cfg.c | 7 +++++++
net/mac80211/ieee80211_i.h | 3 +++
net/mac80211/util.c | 12 ++++++++++++
3 files changed, 22 insertions(+)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 34fd3eb..9518e96 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1954,6 +1954,12 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev));
}
+static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev,
+ int rate[IEEE80211_NUM_BANDS])
+{
+ return ieee80211_mcast_rate(IEEE80211_DEV_TO_SUB_IF(dev), rate);
+}
+
static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
@@ -3151,6 +3157,7 @@ struct cfg80211_ops mac80211_config_ops = {
.disassoc = ieee80211_disassoc,
.join_ibss = ieee80211_join_ibss,
.leave_ibss = ieee80211_leave_ibss,
+ .set_mcast_rate = ieee80211_set_mcast_rate,
.set_wiphy_params = ieee80211_set_wiphy_params,
.set_tx_power = ieee80211_set_tx_power,
.get_tx_power = ieee80211_get_tx_power,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3026519..375f230 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1609,6 +1609,9 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
struct ieee80211_chanctx *chanctx);
+int ieee80211_mcast_rate(struct ieee80211_sub_if_data *sdata,
+ int rate[IEEE80211_NUM_BANDS]);
+
#ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline
#else
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index dd0e6f2..ac935c3 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1966,3 +1966,15 @@ u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs)
return 2;
return 1;
}
+
+int ieee80211_mcast_rate(struct ieee80211_sub_if_data *sdata,
+ int rate[IEEE80211_NUM_BANDS])
+{
+ if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
+
+ memcpy(sdata->vif.bss_conf.mcast_rate, rate, sizeof(rate));
+
+ return 0;
+}
--
1.7.12.4
On Fri, 2012-10-26 at 17:57 +0200, Antonio Quartulli wrote:
> The callback can be used with vif configured as
> ADHOC or MESH_POINT only.
You said the same in the cfg80211 patch, so
> +int ieee80211_mcast_rate(struct ieee80211_sub_if_data *sdata,
> + int rate[IEEE80211_NUM_BANDS])
> +{
> + if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
> + sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
> + return -EOPNOTSUPP;
should that check be in cfg80211?
OTOH, it seems it might be valid in AP mode as well?
johannes
On Mon, Oct 29, 2012 at 10:15:10AM +0100, Johannes Berg wrote:
> On Fri, 2012-10-26 at 17:57 +0200, Antonio Quartulli wrote:
> > The callback can be used with vif configured as
> > ADHOC or MESH_POINT only.
>
> You said the same in the cfg80211 patch, so
>
> > +int ieee80211_mcast_rate(struct ieee80211_sub_if_data *sdata,
> > + int rate[IEEE80211_NUM_BANDS])
> > +{
> > + if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
> > + sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
> > + return -EOPNOTSUPP;
>
> should that check be in cfg80211?
Ok, will change that.
>
> OTOH, it seems it might be valid in AP mode as well?
as we discussed on IRC, the AP has no real mcast_rate parameter since it seems
to be chosen from the basic rates every time. How ever this would be an
interesting feature. Maybe we can add this later after this API change.
Cheers,
--
Antonio Quartulli
..each of us alone is worth nothing..
Ernesto "Che" Guevara
On Fri, 2012-10-26 at 17:57 +0200, Antonio Quartulli wrote:
> + * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
> + * for IBSS or MESH vif.
You should probably advertise the new command, see nl80211_send_wiphy()
johannes
On Mon, Oct 29, 2012 at 10:13:36AM +0100, Johannes Berg wrote:
> On Fri, 2012-10-26 at 17:57 +0200, Antonio Quartulli wrote:
>
> > + * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
> > + * for IBSS or MESH vif.
>
> You should probably advertise the new command, see nl80211_send_wiphy()
Right. Thanks!
--
Antonio Quartulli
..each of us alone is worth nothing..
Ernesto "Che" Guevara