This reimplements code allowing for mesh channel selection according
to how NetworkManager expects.
Signed-off-by: Daniel Drake <[email protected]>
---
drivers/net/wireless/libertas/dev.h | 1 +
drivers/net/wireless/libertas/mesh.c | 76 +++++++++++++++++++++++++++++----
2 files changed, 67 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index adb3490..86494b0 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -48,6 +48,7 @@ struct lbs_private {
uint16_t mesh_tlv;
u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
u8 mesh_ssid_len;
+ short mesh_channel;
#endif
/* Debugfs */
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index be72c08..87d1049 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -123,7 +123,7 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
return -1;
}
lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
- action, priv->mesh_tlv, chan,
+ action, priv->mesh_tlv, priv->mesh_channel,
print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
@@ -803,6 +803,62 @@ static void lbs_persist_config_remove(struct net_device *dev)
/***************************************************************************
+ * WEXT handlers
+ */
+
+static int mesh_get_name(struct net_device *dev,
+ struct iw_request_info *info, char *name, char *extra)
+{
+ strcpy(name, "IEEE 802.11b/g");
+ return 0;
+}
+
+static int mesh_get_freq(struct net_device *dev,
+ struct iw_request_info *info, struct iw_freq *freq, char *extra)
+{
+ struct lbs_private *priv = dev->ml_priv;
+ freq->e = 0;
+ freq->m = priv->mesh_channel;
+ return 0;
+}
+
+static int mesh_set_freq(struct net_device *dev,
+ struct iw_request_info *info, struct iw_freq *freq, char *extra)
+{
+ struct lbs_private *priv = dev->ml_priv;
+ short channel = 0;
+
+ if (freq->e == 0)
+ channel = freq->m;
+ else {
+ channel = ieee80211_freq_to_dsss_chan(freq->m);
+ if (channel < 0)
+ channel = 1;
+ }
+
+ priv->mesh_channel = channel;
+
+ if (netif_running(dev))
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->mesh_channel);
+
+ return 0;
+}
+
+static const iw_handler mesh_iw_handler[] =
+{
+ IW_HANDLER(SIOCGIWNAME, (iw_handler) mesh_get_name),
+ IW_HANDLER(SIOCGIWFREQ, (iw_handler) mesh_get_freq),
+ IW_HANDLER(SIOCSIWFREQ, (iw_handler) mesh_set_freq),
+};
+
+static const struct iw_handler_def mesh_iw_handler_def = {
+ .num_standard = ARRAY_SIZE(mesh_iw_handler),
+ .standard = mesh_iw_handler,
+};
+
+
+/***************************************************************************
* Initializing and starting, stopping mesh
*/
@@ -837,11 +893,9 @@ int lbs_init_mesh(struct lbs_private *priv)
useful */
priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel)) {
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) {
priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel))
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
priv->mesh_tlv = 0;
}
} else
@@ -851,13 +905,12 @@ int lbs_init_mesh(struct lbs_private *priv)
* 0x100+37; Do not invoke command with old TLV.
*/
priv->mesh_tlv = TLV_TYPE_MESH_ID;
- if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
- priv->channel))
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
priv->mesh_tlv = 0;
}
/* Stop meshing until interface is brought up */
- lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel);
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
if (priv->mesh_tlv) {
sprintf(priv->mesh_ssid, "mesh");
@@ -904,7 +957,7 @@ static int lbs_mesh_stop(struct net_device *dev)
struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_MESH);
- lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel);
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->mesh_channel);
spin_lock_irq(&priv->driver_lock);
@@ -947,7 +1000,8 @@ static int lbs_mesh_dev_open(struct net_device *dev)
spin_unlock_irq(&priv->driver_lock);
- ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, priv->channel);
+ ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->mesh_channel);
out:
lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
@@ -984,8 +1038,10 @@ static int lbs_add_mesh(struct lbs_private *priv)
}
mesh_dev->ml_priv = priv;
priv->mesh_dev = mesh_dev;
+ priv->mesh_channel = 1;
mesh_dev->netdev_ops = &mesh_netdev_ops;
+ mesh_dev->wireless_handlers = &mesh_iw_handler_def;
mesh_dev->ethtool_ops = &lbs_ethtool_ops;
memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN);
--
1.7.6
On Wed, 2011-07-20 at 21:10 +0300, Kalle Valo wrote:
> Daniel Drake <[email protected]> writes:
>
> > This reimplements code allowing for mesh channel selection according
> > to how NetworkManager expects.
>
> [...]
>
> > +static const iw_handler mesh_iw_handler[] =
> > +{
> > + IW_HANDLER(SIOCGIWNAME, (iw_handler) mesh_get_name),
> > + IW_HANDLER(SIOCGIWFREQ, (iw_handler) mesh_get_freq),
> > + IW_HANDLER(SIOCSIWFREQ, (iw_handler) mesh_set_freq),
> > +};
>
> We are trying to remove wext code, not add it. I'm surprised to see this.
Mesh on OLPC/usb8388 was a pre-802.11s mesh protocol specific to OLPC
implementations. It's unlikely it would map directly to the standard
mesh layer in mac80211/nl80211, plus it's all fullmac handled by the
firmware. So unless we want to look into creating one-off commands for
the OLPC mesh bits for nl80211, we probably just want to keep the wext
bits for this until we remove wext completely in the next few years.
Dan
On 21 July 2011 17:38, Dan Williams <[email protected]> wrote:
> Mesh on OLPC/usb8388 was a pre-802.11s mesh protocol specific to OLPC
> implementations. ?It's unlikely it would map directly to the standard
> mesh layer in mac80211/nl80211, plus it's all fullmac handled by the
> firmware. ?So unless we want to look into creating one-off commands for
> the OLPC mesh bits for nl80211, we probably just want to keep the wext
> bits for this until we remove wext completely in the next few years.
I've got it working creating a 2nd interface off the same wiphy, it
seems to be working and avoids wext. It was simpler than I expected.
I'll submit it later and we'll see if people like it.
Thanks,
Daniel
Daniel Drake <[email protected]> writes:
> This reimplements code allowing for mesh channel selection according
> to how NetworkManager expects.
[...]
> +static const iw_handler mesh_iw_handler[] =
> +{
> + IW_HANDLER(SIOCGIWNAME, (iw_handler) mesh_get_name),
> + IW_HANDLER(SIOCGIWFREQ, (iw_handler) mesh_get_freq),
> + IW_HANDLER(SIOCSIWFREQ, (iw_handler) mesh_set_freq),
> +};
We are trying to remove wext code, not add it. I'm surprised to see this.
--
Kalle Valo