[PATCH] Configurable beacon interval

Dan Williams dcbw at redhat.com
Thu Oct 25 13:29:50 EDT 2007


On Wed, 2007-10-24 at 15:42 -0700, Javier Cardona wrote: 
> From: Brajesh Dave <brajeshd at marvell.com>
> 
> See https://dev.laptop.org/ticket/2750#comment:12
> 
> Requires firmware version 5.110.19.p0 or newer, available here:
> http://dev.laptop.org/pub/firmware/libertas/

What I'd like to do with patches from now on (now that Libertas is fully
merged upstream) is to split out the OLPC specific parts (like the
ioctls) and channel those directly into olpc-2.6 through Andres, but
push the generic bits straight to linux-wireless and John Linville.  I'd
like to get rid of libertas-2.6 alltogether, and if people have
individual enhancements that they want to carry outside of wireless-2.6
then they should get personal git repos to carry those.

So for this patch, the following file hunks should not be sent upstream:

drivers/net/wireless/libertas/README
drivers/net/wireless/libertas/ioctl.c
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/libertas/wext.h

The rest look like great candidates for linux-wireless@ and
wireless-2.6.  For about 3 weeks or so we've been pushing all libertas
patches to linux-wireless, and I'll send a mail to libertas-dev about
it.

Comments below...

> Signed-off-by: Ashish Shukla <ashishs at marvell.com>
> Signed-off-by: Javier Cardona <javier at cozybit.com>
> ---
>  drivers/net/wireless/libertas/README    |   20 +++++++++++
>  drivers/net/wireless/libertas/cmd.c     |   25 ++++++++++++++
>  drivers/net/wireless/libertas/cmdresp.c |   22 ++++++++++++
>  drivers/net/wireless/libertas/dev.h     |    2 +
>  drivers/net/wireless/libertas/host.h    |    2 +
>  drivers/net/wireless/libertas/hostcmd.h |    7 ++++
>  drivers/net/wireless/libertas/ioctl.c   |   54 +++++++++++++++++++++++++++++++
>  drivers/net/wireless/libertas/join.c    |    4 ++-
>  drivers/net/wireless/libertas/wext.c    |    1 +
>  drivers/net/wireless/libertas/wext.h    |    1 +
>  10 files changed, 137 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
> index 34fc1ff..73f1893 100644
> --- a/drivers/net/wireless/libertas/README
> +++ b/drivers/net/wireless/libertas/README
> @@ -143,6 +143,26 @@ ledgpio
>  	Note: LED0 is invalid
>  	Note: Maximum Number of LEDs are 16.
>  
> +bcn_control
> +	This command is used to enable disable beacons. This can also be used
> +	to set beacon interval.
> +
> +	Usage:
> +		iwpriv ethX bcn_control [enable] [beacon_interval]
> +
> +		enable: 0 to disable beacon. 1 to enable beacon.
> +		beacon_interval: 20 - 1000ms.
> +
> +	Examples:
> +		1. iwpriv ethX bcn_control
> +		   Returns (x, y), where x if 1, indicates beacon is enabled, y 
> +		   beacon period.
> +		2. iwpriv ethX bcn_control 0
> +		   Turns off beacon transmission.
> +		3. iwpriv ethX bcn_control 1 500
> +		   Enable beacon with beacon interval 500ms.
> +		
> +
>  fwt_add
>  	This command is used to insert an entry into the FWT table. The list of
>  	parameters must follow the following structure:
> diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
> index 98295e1..a2dcb74 100644
> --- a/drivers/net/wireless/libertas/cmd.c
> +++ b/drivers/net/wireless/libertas/cmd.c
> @@ -901,6 +901,28 @@ static int wlan_cmd_mesh_access(wlan_private * priv,
>  	return 0;
>  }
>  
> +static int wlan_cmd_bcn_ctrl(wlan_private * priv,
> +					      struct cmd_ds_command *cmd,
> +					      u16 cmd_action)
> +{
> +	struct cmd_ds_802_11_beacon_control
> +		*bcn_ctrl = &cmd->params.bcn_ctrl;
> +	wlan_adapter *adapter = priv->adapter;
> +
> +	lbs_deb_enter(LBS_DEB_CMD);
> +	cmd->size =
> +	    cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
> +			     + S_DS_GEN);
> +	cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
> +
> +	bcn_ctrl->action = cpu_to_le16(cmd_action);
> +	bcn_ctrl->beacon_enable = cpu_to_le16(adapter->beacon_enable);
> +	bcn_ctrl->beacon_period = cpu_to_le16(adapter->beacon_period);
> +
> +	lbs_deb_leave(LBS_DEB_CMD);
> +	return 0;
> +}
> +
>  void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail)
>  {
>  	unsigned long flags;
> @@ -1395,6 +1417,9 @@ int libertas_prepare_and_send_command(wlan_private * priv,
>  					   S_DS_GEN);
>  		ret = 0;
>  		break;
> +	case CMD_802_11_BEACON_CTRL:
> +		ret = wlan_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
> +		break;
>  	default:
>  		lbs_deb_host("PREP_CMD: unknown command 0x%04x\n", cmd_no);
>  		ret = -1;
> diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
> index da72dfc..6f4039b 100644
> --- a/drivers/net/wireless/libertas/cmdresp.c
> +++ b/drivers/net/wireless/libertas/cmdresp.c
> @@ -531,6 +531,24 @@ static int libertas_ret_802_11_enable_rsn(wlan_private * priv,
>  	return 0;
>  }
>  
> +static int wlan_ret_802_11_bcn_ctrl(wlan_private * priv,
> +					      struct cmd_ds_command *resp)
> +{
> +	struct cmd_ds_802_11_beacon_control *bcn_ctrl =
> +	    &resp->params.bcn_ctrl;
> +	wlan_adapter *adapter = priv->adapter;
> +
> +	lbs_deb_enter(LBS_DEB_CMD);
> +
> +	if (bcn_ctrl->action == CMD_ACT_GET) {
> +		adapter->beacon_enable =(u8) le16_to_cpu( bcn_ctrl->beacon_enable);
> +		adapter->beacon_period = le16_to_cpu( bcn_ctrl->beacon_period);
> +	}
> +
> +	lbs_deb_enter(LBS_DEB_CMD);
> +	return 0;
> +}
> +
>  static inline int handle_cmd_response(u16 respcmd,
>  				      struct cmd_ds_command *resp,
>  				      wlan_private *priv)
> @@ -699,6 +717,10 @@ static inline int handle_cmd_response(u16 respcmd,
>  			memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh,
>  			       sizeof(resp->params.mesh));
>  		break;
> +	case CMD_RET(CMD_802_11_BEACON_CTRL):
> +		ret = wlan_ret_802_11_bcn_ctrl(priv, resp);
> +		break;
> +		
>  	default:
>  		lbs_deb_host("CMD_RESP: unknown cmd response 0x%04x\n",
>  			    resp->command);
> diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
> index 5302074..926ef29 100644
> --- a/drivers/net/wireless/libertas/dev.h
> +++ b/drivers/net/wireless/libertas/dev.h
> @@ -266,6 +266,8 @@ struct _wlan_adapter {
>  	struct list_head network_free_list;
>  	struct bss_descriptor *networks;
>  
> +	u16 beacon_period;
> +	u8 beacon_enable;
>  	u8 adhoccreate;
>  
>  	/** capability Info used in Association, start, join */
> diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
> index 37360ba..fdd7b06 100644
> --- a/drivers/net/wireless/libertas/host.h
> +++ b/drivers/net/wireless/libertas/host.h
> @@ -117,6 +117,8 @@
>  
>  #define CMD_MESH_ACCESS               0x009b
>  
> +#define CMD_802_11_BEACON_CTRL        0x00b0
> +
>  /* For the IEEE Power Save */
>  #define CMD_SUBCMD_ENTER_PS               0x0030
>  #define CMD_SUBCMD_EXIT_PS                0x0031
> diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
> index 3bee36d..9c1b560 100644
> --- a/drivers/net/wireless/libertas/hostcmd.h
> +++ b/drivers/net/wireless/libertas/hostcmd.h
> @@ -332,6 +332,12 @@ struct cmd_ds_802_11_radio_control {
>  	__le16 control;
>  };
>  
> +struct cmd_ds_802_11_beacon_control {
> +	__le16 action;
> +	__le16 beacon_enable;
> +	__le16 beacon_period;
> +};
> +
>  struct cmd_ds_802_11_sleep_params {
>  	/* ACT_GET/ACT_SET */
>  	__le16 action;
> @@ -670,6 +676,7 @@ struct cmd_ds_command {
>  		struct cmd_ds_get_tsf gettsf;
>  		struct cmd_ds_802_11_subscribe_event subscribe_event;
>  		struct cmd_ds_host_sleep sleep_config;
> +		struct cmd_ds_802_11_beacon_control bcn_ctrl;
>  	} params;
>  } __attribute__ ((packed));
>  
> diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
> index f87133a..8648e68 100644
> --- a/drivers/net/wireless/libertas/ioctl.c
> +++ b/drivers/net/wireless/libertas/ioctl.c
> @@ -891,6 +891,57 @@ static int libertas_mesh_ioctl(wlan_private * priv, struct iwreq * wrq,
>  	return ret;
>  }
>  
> +/**
> + *  @brief Control Beacon transmissions
> + *  @param priv                 A pointer to wlan_private structure
> + *  @param wrq			A pointer to iwreq structure
> + *  @return 	   		0 --success, otherwise fail
> + */
> +static int libertas_bcn_ioctl(wlan_private * priv, struct iwreq *wrq)
> +{
> +	int ret;
> +	wlan_adapter *adapter = priv->adapter;
> +	int data[2];
> +
> +	memset(data, 0, sizeof(data));
> +	if (!wrq->u.data.length) {
> +		lbs_deb_ioctl("Get Beacon control\n");
> +		ret = libertas_prepare_and_send_command(priv,
> +					    CMD_802_11_BEACON_CTRL,
> +					    CMD_ACT_GET,
> +					    CMD_OPTION_WAITFORRSP, 0, NULL);
> +		data[0] = adapter->beacon_enable;
> +		data[1] = adapter->beacon_period;
> +		if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
> +			lbs_deb_ioctl("Copy to user failed\n");
> +			return -EFAULT;
> +		}
> +#define GET_TWO_INT	2
> +		wrq->u.data.length = GET_TWO_INT;
> +	} else {
> +		lbs_deb_ioctl("Set beacon control\n");
> +		if (wrq->u.data.length > 2)
> +			return -EINVAL;
> +		if (copy_from_user (data, wrq->u.data.pointer,
> +		     sizeof(int) * wrq->u.data.length)) {
> +			lbs_deb_ioctl("Copy from user failed\n");
> +			return -EFAULT;
> +		}
> +		adapter->beacon_enable = data[0];
> +		if (wrq->u.data.length > 1) {
> +		if ((data[1] > MRVDRV_MAX_BEACON_INTERVAL)
> +		    || (data[1] < MRVDRV_MIN_BEACON_INTERVAL))
> +			return -ENOTSUPP;
> +		adapter->beacon_period= data[1];
> +		}
> +		ret = libertas_prepare_and_send_command(priv,
> +					    CMD_802_11_BEACON_CTRL,
> +					    CMD_ACT_SET,
> +					    CMD_OPTION_WAITFORRSP, 0, NULL);
> +	}
> +	return ret;
> +}
> +
>  static int libertas_led_gpio_ioctl(wlan_private * priv, struct ifreq *req)
>  {
>  	struct iwreq *wrq = (struct iwreq *)req;
> @@ -1091,6 +1142,9 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
>  		case LIBERTAS_LED_GPIO_CTRL:
>  			ret = libertas_led_gpio_ioctl(priv, req);
>  			break;
> +		case LIBERTAS_BCN_CTRL:
> +			ret = libertas_bcn_ioctl(priv,wrq);
> +			break;
>  		}
>  		break;
>  
> diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
> index 4408579..5447407 100644
> --- a/drivers/net/wireless/libertas/join.c
> +++ b/drivers/net/wireless/libertas/join.c
> @@ -512,7 +512,9 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
>  	/* set the BSS type */
>  	adhs->bsstype = CMD_BSS_TYPE_IBSS;
>  	adapter->mode = IW_MODE_ADHOC;
> -	adhs->beaconperiod = cpu_to_le16(MRVDRV_BEACON_INTERVAL);
> +	if (adapter->beacon_period == 0)
> +		adapter->beacon_period = MRVDRV_BEACON_INTERVAL;
> +	adhs->beaconperiod = cpu_to_le16(adapter->beacon_period);

Are you sure this is the behavior you want?  Would seem better to do
something like:

if (adapter->beacon_period == 0)
    adhs->beaconperiod = cpu_to_le16(MRVDRV_BEACON_INTERVAL);
else
    adhs->beaconperiod = cpu_to_le16(adapter->beacon_period);

otherwise when you set the beacon interval then get it again, it'll be
the default interval, not what you just set.

Dan

> 	/* set Physical param set */
>  #define DS_PARA_IE_ID   3
> diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
> index 948f124..1c8128d 100644
> --- a/drivers/net/wireless/libertas/wext.c
> +++ b/drivers/net/wireless/libertas/wext.c
> @@ -861,6 +861,7 @@ static const struct iw_priv_args wlan_private_args[] = {
>  	    { LIBERTAS_SUBCMD_MESH_GET_LINK_COSTS, CHAR128_PARAM, CHAR128_PARAM, "get_link_costs"},
>  	{ LIBERTAS_SET_GET_SIXTEEN_INT, INT16_PARAM, INT16_PARAM, ""},
>  	    { LIBERTAS_LED_GPIO_CTRL, INT16_PARAM, INT16_PARAM, "ledgpio"},
> +	    { LIBERTAS_BCN_CTRL, INT16_PARAM, INT16_PARAM, "bcn_control"},
>  };
>  
>  static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
> diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
> index 7b76987..eb155aa 100644
> --- a/drivers/net/wireless/libertas/wext.h
> +++ b/drivers/net/wireless/libertas/wext.h
> @@ -48,6 +48,7 @@
>  
>  #define LIBERTAS_SET_GET_SIXTEEN_INT		(SIOCIWFIRSTPRIV + 29)
>  #define LIBERTAS_LED_GPIO_CTRL			5
> +#define LIBERTAS_BCN_CTRL               6
>  
>  /** wlan_ioctl_regrdwr */
>  struct wlan_ioctl_regrdwr {




More information about the Devel mailing list