[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