[PATCH] libertas: new mesh control knobs

Michail Bletsas mbletsas at laptop.org
Wed May 30 11:48:46 EDT 2007


Dan,

The first 3 calls will be applicable across 802.11s implementations, so I 
don't see any reason for them to change in the future.
The last one is more specific to our implementation however we won't be 
able to tell for sure until we see other implementations.
The irony is that I need the 4th call for debugging in Uruguay right 
now....

M.





Dan Williams <dcbw at redhat.com> 
Sent by: libertas-dev-bounces at lists.infradead.org
05/30/2007 11:41 AM

To
"luisca at cozybit.com" <luisca at cozybit.com>
cc
"libertas-dev at lists.infradead.org" <libertas-dev at lists.infradead.org>
Subject
Re: [PATCH] libertas: new mesh control knobs






On Tue, 2007-05-08 at 01:30 +0000, luisca at cozybit.com wrote:
> 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.

So adding new private ioctls means we _MUST_ be comfortable that they
will not change in the foreseeable future.  Once they hit upstream, they
are kernel API/ABI and must not change.  So, will these be unchanged for
the next few years?

Otherwise we can just stuff this patch into a libertas-dev branch that
we don't push upstream, but requires periodic manual merges from
libertas-2.6.

> ---
>  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.

^^^ should probably be "Sets"

> +              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]));

This breaks with sparse.  We should be doing stuff like this instead.
At least, that's how I _think_ it should be done :)

                 struct iwreq *wrq = (struct iwreq *)req;

                 ...

                 if (ret == 0)
                                 wrq->u.param.value = 
le32_to_cpu(param.id);

Dan

> -              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
> _______________________________________________
> libertas-dev mailing list
> libertas-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libertas-dev


_______________________________________________
libertas-dev mailing list
libertas-dev at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/libertas-dev






More information about the libertas-dev mailing list