[PATCH] libertas: new mesh control knobs
luisca at cozybit.com
luisca at cozybit.com
Mon May 7 21:30:51 EDT 2007
Support for new mesh control knobs on firmware 5.220.11.p4:
mesh_{set,get}_bcastr rate
Sets/gets tx rate for mesh broadcast and multicast data frames.
{set,get}_rreq_delay cs
Sets/gets delay for RREQ forwarding, in 1/100 s.
{set,get}_route_exp s
Sets/gets route expiration time, in s.
{set_get)_link_costs cost54 cost36 cost11 cost1
Sets/gets link cost for each available rate.
Rates with cost 0 will be disabled.
---
drivers/net/wireless/libertas/README | 65 +++++++++++++++
drivers/net/wireless/libertas/host.h | 8 ++
drivers/net/wireless/libertas/ioctl.c | 138 ++++++++++++++++++++++-----------
drivers/net/wireless/libertas/wext.c | 40 ++++++++++
drivers/net/wireless/libertas/wext.h | 10 +++
5 files changed, 216 insertions(+), 45 deletions(-)
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index 7de8c8f..64f7b6c 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -146,6 +146,14 @@ MESH Commands:
iwpriv ethX mesh_get_ttl
iwpriv ethX mesh_set_ttl ttl
+ iwpriv ethX mesh_get_bcastr rate
+ iwpriv ethX mesh_set_bcastr rate
+ iwpriv ethX get_rreq_delay
+ iwpriv ethX set_rreq_delay delay
+ iwpriv ethX get_route_exp
+ iwpriv ethX set_route_exp time
+ iwpriv ethX get_link_costs
+ iwpriv ethX set_link_costs "cost54 cost36 cost11 cost1"
DESCRIPTION
Those commands are used to send additional commands to the Marvell WLAN
@@ -819,6 +827,63 @@ mesh_set_ttl ttl
iwpriv ethX mesh_set_ttl <ttl>
+mesh_get_bcastr
+
+ Shows the rate index used for mesh broadcast and multicast packets. The
+ mapping to actual rates is the same as for rateadapt command.
+
+ iwpriv ethX mesh_get_bcastr rate
+
+mesh_set_bcastr rate
+
+ Sets the rate index for mesh broadcast and muticast packets. The mapping
+ to actual rates is the same as for rateadapt command.
+
+ iwpriv ethX mesh_set_bcastr rate
+
+get_rreq_delay
+
+ Shows the delay to forward a RREQ frame. This delay allows the node to
+ forward just the best route in case the same RREQ arrives to the node
+ through different routes. The argument is shown in 1/100 seconds.
+
+ iwpriv ethX get_rreq_delay
+
+set_rreq_delay delay
+
+ Sets the RREQ forward delay. The delay is interpreted as 1/100 seconds.
+
+ iwpriv ethX set_rreq_delay delay
+
+get_route_exp
+
+ Shows the mesh route expiration time, in seconds.
+
+ iwpriv ethX get_route_exp
+
+set_route_exp time
+
+ Gets the mesh route, expiration time, in seconds.
+
+ iwpriv ethX set_route_exp time
+
+get_link_costs
+
+ Gets the mesh hop base cost for each used rate. The output gives us the
+ base cost for hops at 54Mbps, 36Mbps, 11Mbps and 1Mbps, in that order.
+ The base cost gets divided by a battery state factor to get the actual
+ cost. A cost of 0 means that rate is deactivated.
+
+ iwpriv ethX get_link_costs
+
+set_link_costs "cost54 cost36 cost11 cost1"
+
+ Sets the mesh hop base cost for the used speeds. The input parameter
+ will specify the cost for hops at 54Mbps, 36Mbps, 11Mbps and 1Mbps, in
+ that order. A cost of 0 will disable a specific rate.
+
+ iwpriv ethX set_link_costs "cost54 cost36 cost11 cost1"
+
=========================
ETHTOOL
=========================
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 0b54232..ec54c92 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -312,6 +312,14 @@ enum cmd_mesh_access_opts {
cmd_act_mesh_get_stats,
cmd_act_mesh_get_mpp,
cmd_act_mesh_set_mpp,
+ cmd_act_mesh_set_link_costs,
+ cmd_act_mesh_get_link_costs,
+ cmd_act_mesh_set_bcast_rate,
+ cmd_act_mesh_get_bcast_rate,
+ cmd_act_mesh_set_rreq_delay,
+ cmd_act_mesh_get_rreq_delay,
+ cmd_act_mesh_set_route_exp,
+ cmd_act_mesh_get_route_exp,
};
/** Card Event definition */
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
index d64ef7a..cb9cf69 100644
--- a/drivers/net/wireless/libertas/ioctl.c
+++ b/drivers/net/wireless/libertas/ioctl.c
@@ -1766,63 +1766,72 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
}
/**
- * @brief Gets mesh ttl from firmware
- * @param priv A pointer to wlan_private structure
- * @param req A pointer to ifreq structure
- * @return 0 --success, otherwise fail
+ * @brief Manages all mesh related ioctls
+ * @param priv A pointer to wlan_private structure
+ * @param req A pointer to ifreq structure
+ * @param cmd The command type
+ * @param host_subcmd The device code for the subcommand
+ * 0: sets a value in the firmware
+ * 1: retrieves an int from the firmware
+ * @return 0 --success, otherwise fail
*/
-static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
+static int wlan_mesh_ioctl(wlan_private * priv, struct ifreq *req,
+ int cmd, int subcmd)
{
+ struct iwreq *wrq = (struct iwreq *)req ;
struct cmd_ds_mesh_access mesh_access;
- int ret;
-
+ int parameter ;
+ char str[128];
+ char *ptr = str ;
+ int ret, i;
+
lbs_deb_enter(LBS_DEB_IOCTL);
memset(&mesh_access, 0, sizeof(mesh_access));
- ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
- cmd_act_mesh_get_ttl,
+ if ( cmd == WLAN_SETONEINT_GETNONE ) {
+ parameter = SUBCMD_DATA(wrq);
+ if ( parameter < 0 )
+ return -EINVAL ;
+ mesh_access.data[0] = parameter ;
+ }
+
+ else if ( subcmd == cmd_act_mesh_set_link_costs ) {
+ if (copy_from_user( str, wrq->u.data.pointer, sizeof(str)))
+ return -EFAULT ;
+
+ for (i = 0 ; i < COSTS_LIST_SIZE ; i++) {
+ mesh_access.data[i] = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)) ;
+ if (!(ptr = next_param(ptr)) && i!= (COSTS_LIST_SIZE - 1))
+ return -EINVAL ;
+ }
+ }
+
+ ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, subcmd,
cmd_option_waitforrsp, 0,
(void *)&mesh_access);
+
+ if (ret != 0)
+ return -EFAULT ;
- if (ret == 0)
+ if ( cmd == WLAN_SETNONE_GETONEINT ) {
req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0]));
- else
- return -EFAULT;
+ }
- lbs_deb_leave(LBS_DEB_IOCTL);
- return 0;
-}
+ else if ( subcmd == cmd_act_mesh_get_link_costs ) {
+ for (i = 0 ; i < COSTS_LIST_SIZE ; i++)
+ ptr += sprintf (ptr, " %u", le32_to_cpu(mesh_access.data[i])) ;
+ wrq->u.data.length = strlen(str);
-/**
- * @brief Gets mesh ttl from firmware
- * @param priv A pointer to wlan_private structure
- * @param ttl New ttl value
- * @return 0 --success, otherwise fail
- */
-static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
-{
- struct cmd_ds_mesh_access mesh_access;
- int ret;
-
- lbs_deb_enter(LBS_DEB_IOCTL);
+ if (copy_to_user(wrq->u.data.pointer, (char *)str,
+ wrq->u.data.length)) {
+ lbs_deb_ioctl("MESH_IOCTL: Copy to user failed!\n");
+ ret = -EFAULT;
+ }
+ }
- if( (ttl > 0xff) || (ttl < 0) )
- return -EINVAL;
-
- memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = ttl;
-
- ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
- cmd_act_mesh_set_ttl,
- cmd_option_waitforrsp, 0,
- (void *)&mesh_access);
-
- if (ret != 0)
- ret = -EFAULT;
-
lbs_deb_leave(LBS_DEB_IOCTL);
- return ret;
+ return ret ;
}
/**
@@ -2028,8 +2037,23 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
break;
case WLAN_SUBCMD_MESH_SET_TTL:
- idata = SUBCMD_DATA(wrq);
- ret = wlan_mesh_set_ttl_ioctl(priv, idata);
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_set_ttl);
+ break;
+
+ case WLAN_SUBCMD_MESH_SET_BCAST_RATE:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_set_bcast_rate);
+ break;
+
+ case WLAN_SUBCMD_MESH_SET_RREQ_DELAY:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_set_rreq_delay) ;
+ break;
+
+ case WLAN_SUBCMD_MESH_SET_ROUTE_EXP:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_set_route_exp) ;
break;
case WLAN_SUBCMD_BT_SET_INVERT:
@@ -2102,6 +2126,14 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
case WLAN_SUBCMD_FWT_LIST_ROUTE:
ret = wlan_fwt_list_route_ioctl(priv, req);
break;
+ case WLAN_SUBCMD_MESH_SET_LINK_COSTS:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_set_link_costs) ;
+ break ;
+ case WLAN_SUBCMD_MESH_GET_LINK_COSTS:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_get_link_costs) ;
+ break;
}
break;
@@ -2150,7 +2182,23 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
break;
case WLAN_SUBCMD_MESH_GET_TTL:
- ret = wlan_mesh_get_ttl_ioctl(priv, req);
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_get_ttl) ;
+ break;
+
+ case WLAN_SUBCMD_MESH_GET_BCAST_RATE:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_get_bcast_rate) ;
+ break;
+
+ case WLAN_SUBCMD_MESH_GET_RREQ_DELAY:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_get_rreq_delay) ;
+ break;
+
+ case WLAN_SUBCMD_MESH_GET_ROUTE_EXP:
+ ret = wlan_mesh_ioctl(priv, req, cmd,
+ cmd_act_mesh_get_route_exp) ;
break;
case WLAN_SUBCMD_BT_GET_INVERT:
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index d48b211..b1b855b 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1062,6 +1062,21 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_NONE,
"mesh_set_ttl"},
{
+ WLAN_SUBCMD_MESH_SET_BCAST_RATE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_NONE,
+ "mesh_set_bcastr"},
+ {
+ WLAN_SUBCMD_MESH_SET_RREQ_DELAY,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_NONE,
+ "set_rreq_delay"},
+ {
+ WLAN_SUBCMD_MESH_SET_ROUTE_EXP,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_NONE,
+ "set_route_exp"},
+ {
WLAN_SETNONE_GETONEINT,
IW_PRIV_TYPE_NONE,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -1122,6 +1137,21 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"mesh_get_ttl"},
{
+ WLAN_SUBCMD_MESH_GET_BCAST_RATE,
+ IW_PRIV_TYPE_NONE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "mesh_get_bcastr"},
+ {
+ WLAN_SUBCMD_MESH_GET_RREQ_DELAY,
+ IW_PRIV_TYPE_NONE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_rreq_delay"},
+ {
+ WLAN_SUBCMD_MESH_GET_ROUTE_EXP,
+ IW_PRIV_TYPE_NONE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_route_exp"},
+ {
WLAN_SETNONE_GETTWELVE_CHAR,
IW_PRIV_TYPE_NONE,
IW_PRIV_TYPE_CHAR | 12,
@@ -1142,6 +1172,16 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_CHAR | 12,
"gettsf"},
{
+ WLAN_SUBCMD_MESH_SET_LINK_COSTS,
+ IW_PRIV_TYPE_CHAR | 128,
+ IW_PRIV_TYPE_CHAR | 128,
+ "set_link_costs"},
+ {
+ WLAN_SUBCMD_MESH_GET_LINK_COSTS,
+ IW_PRIV_TYPE_CHAR | 128,
+ IW_PRIV_TYPE_CHAR | 128,
+ "get_link_costs"},
+ {
WLAN_SETNONE_GETNONE,
IW_PRIV_TYPE_NONE,
IW_PRIV_TYPE_NONE,
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
index fdac44a..0f361ec 100644
--- a/drivers/net/wireless/libertas/wext.h
+++ b/drivers/net/wireless/libertas/wext.h
@@ -4,6 +4,8 @@
#ifndef _WLAN_WEXT_H_
#define _WLAN_WEXT_H_
+#define COSTS_LIST_SIZE 4
+
#define SUBCMD_OFFSET 4
#define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET))
@@ -52,6 +54,9 @@
#define WLAN_SUBCMD_FWT_TIME 16
#define WLAN_SUBCMD_MESH_GET_TTL 17
#define WLAN_SUBCMD_BT_GET_INVERT 18
+#define WLAN_SUBCMD_MESH_GET_BCAST_RATE 19
+#define WLAN_SUBCMD_MESH_GET_RREQ_DELAY 20
+#define WLAN_SUBCMD_MESH_GET_ROUTE_EXP 21
#define WLANREGCFRDWR (WLANIOCTL + 18)
@@ -88,6 +93,9 @@
#define WLAN_SET_DEBUGMODE 17
#define WLAN_SUBCMD_MESH_SET_TTL 18
#define WLAN_SUBCMD_BT_SET_INVERT 19
+#define WLAN_SUBCMD_MESH_SET_BCAST_RATE 20
+#define WLAN_SUBCMD_MESH_SET_RREQ_DELAY 21
+#define WLAN_SUBCMD_MESH_SET_ROUTE_EXP 22
#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25)
#define WLANSCAN_MODE 6
@@ -103,6 +111,8 @@
#define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24
#define WLAN_SUBCMD_FWT_LIST 25
#define WLAN_SUBCMD_FWT_LIST_ROUTE 26
+#define WLAN_SUBCMD_MESH_SET_LINK_COSTS 27
+#define WLAN_SUBCMD_MESH_GET_LINK_COSTS 28
#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29)
#define WLAN_TPCCFG 1
--
1.4.4.2
More information about the libertas-dev
mailing list