Extend MESH_CONFIG command to access non-volatile configuration.
PATCH 1/2 Extend MESH_CONFIG command to access non-volatile configuration.
This patch is based on a patch from Shailendra Govardhan and Brian Cavagnolo. It extends the MESH_CONFIG command to configure non-volatile parameters on libertas devices that support them (e.g. OLPC Active Antenna).
This patch only implements the driver/firmware interface.
See http://dev.laptop.org/ticket/6823 for minimal testing results and known issues.
--- drivers/net/wireless/libertas/assoc.c | 6 ++- drivers/net/wireless/libertas/cmd.c | 69 +++++++++++++++++++++++++++------ drivers/net/wireless/libertas/cmd.h | 2 + drivers/net/wireless/libertas/defs.h | 10 +++++ drivers/net/wireless/libertas/host.h | 17 ++++++++ drivers/net/wireless/libertas/main.c | 13 ++++-- drivers/net/wireless/libertas/types.h | 30 ++++++++++++++ drivers/net/wireless/libertas/wext.c | 5 +- 8 files changed, 131 insertions(+), 21 deletions(-)
drivers/net/wireless/libertas/assoc.c +4 -2
@@ -603,7 +603,8 @@ static int assoc_helper_channel(struct lbs_private *priv,/* Change mesh channel first; 21.p21 firmware won't let you change channel otherwise (even though it'll return an error to this */ -lbs_mesh_config (priv,0 , assoc_req->channel); +lbs_mesh_config (priv,CMD_ACT_MESH_CONFIG_STOP , + assoc_req->channel); } lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
@@ -642,7 +643,8 @@ static int assoc_helper_channel(struct lbs_private *priv, restore_mesh:if (priv->mesh_dev) -lbs_mesh_config (priv,1 , priv->curbssparams.channel); +lbs_mesh_config (priv,CMD_ACT_MESH_CONFIG_START , + priv->curbssparams.channel); done:lbs_deb_leave_args (LBS_DEB_ASSOC ,"ret %d" , ret);
drivers/net/wireless/libertas/cmd.c +57 -12
87 lines not on this page · raw message
drivers/net/wireless/libertas/cmd.h +2 -0
@@ -40,6 +40,8 @@ int lbs_set_data_rate(struct lbs_private *priv, u8 rate);int lbs_get_channel (struct lbs_private *priv);int lbs_set_channel (struct lbs_private *priv,u8 channel); +int lbs_mesh_config_send (struct lbs_private *priv, +struct cmd_ds_mesh_config *cmd,u16 action,u16 type);int lbs_mesh_config (struct lbs_private *priv,uint16_t enable,uint16_t chan);int lbs_host_sleep_cfg (struct lbs_private *priv,uint32_t criteria);
drivers/net/wireless/libertas/defs.h +10 -0
@@ -170,6 +170,16 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in#define MARVELL_MESH_IE_LENGTH 9 +/* Values used to populate the struct mrvl_mesh_ie. The only time you need this +* is when enabling the mesh using CMD_MESH_CONFIG. +*/ +#define MARVELL_MESH_IE_TYPE 4 +#define MARVELL_MESH_IE_SUBTYPE 0 +#define MARVELL_MESH_IE_VERSION 0 +#define MARVELL_MESH_PROTO_ID_HWMP 0 +#define MARVELL_MESH_METRIC_ID 0 +#define MARVELL_MESH_CAPABILITY 0 +/** INT status Bit Definition*/ #define MRVDRV_TX_DNLD_RDY 0x0001#define MRVDRV_RX_UPLD_RDY 0x0002
drivers/net/wireless/libertas/host.h +17 -0
@@ -256,6 +256,23 @@ enum cmd_mesh_access_opts { CMD_ACT_MESH_GET_AUTOSTART_ENABLED, }; +/* Define actions and types for CMD_MESH_CONFIG */ +enum cmd_mesh_config_actions { +CMD_ACT_MESH_CONFIG_STOP =0 , +CMD_ACT_MESH_CONFIG_START , +CMD_ACT_MESH_CONFIG_SET , +CMD_ACT_MESH_CONFIG_GET , +}; + +enum cmd_mesh_config_types { +CMD_TYPE_MESH_SET_BOOTFLAG =1 , +CMD_TYPE_MESH_SET_BOOTTIME , +CMD_TYPE_MESH_SET_DEF_CHANNEL , +CMD_TYPE_MESH_SET_MESH_IE , +CMD_TYPE_MESH_GET_DEFAULTS , +CMD_TYPE_MESH_GET_MESH_IE ,/* GET_DEFAULTS is superset of GET_MESHIE */ +}; +/** Card Event definition */ #define MACREG_INT_CODE_TX_PPA_FREE 0#define MACREG_INT_CODE_TX_DMA_DONE 1
drivers/net/wireless/libertas/main.c +8 -5
@@ -343,14 +343,15 @@ static ssize_t lbs_mesh_set(struct device *dev, {struct lbs_private *priv =to_net_dev (dev)->priv;int enable; -int ret; +int ret, action =CMD_ACT_MESH_CONFIG_STOP ;sscanf (buf,"%x" , &enable); enable = !!enable;if (enable == !!priv->mesh_dev)return count; - - ret =lbs_mesh_config (priv, enable, priv->curbssparams.channel); +if (enable) + action =CMD_ACT_MESH_CONFIG_START ; + ret =lbs_mesh_config (priv, action, priv->curbssparams.channel);if (ret)return ret;
@@ -1235,9 +1236,11 @@ int lbs_start_card(struct lbs_private *priv)useful */ priv->mesh_tlv =0x100 +291 ; -if (lbs_mesh_config (priv,1 , priv->curbssparams.channel)) { +if (lbs_mesh_config (priv,CMD_ACT_MESH_CONFIG_START , + priv->curbssparams.channel)) { priv->mesh_tlv =0x100 +37 ; -if (lbs_mesh_config (priv,1 , priv->curbssparams.channel)) +if (lbs_mesh_config (priv,CMD_ACT_MESH_CONFIG_START , + priv->curbssparams.channel)) priv->mesh_tlv =0 ; }if (priv->mesh_tlv) {
drivers/net/wireless/libertas/types.h +30 -0
@@ -6,6 +6,8 @@#include <linux/if_ether.h> #include <asm/byteorder.h> +#include <linux/wireless.h> +#include <net/ieee80211.h> struct ieeetypes_cfparamset {u8 elementid;
@@ -252,4 +254,32 @@ struct mrvlietypes_ledbhv {struct led_bhv ledbhv[1 ]; } __attribute__ ((packed)); +/* Meant to be packed as the value member of a struct ieee80211_info_element. +* Note that the len member of the ieee80211_info_element varies depending on +* the mesh_id_len */ +struct mrvl_meshie_val { +uint8_t oui[P80211_OUI_LEN ]; +uint8_t type; +uint8_t subtype; +uint8_t version; +uint8_t active_protocol_id; +uint8_t active_metric_id; +uint8_t mesh_capability; +uint8_t mesh_id_len; +uint8_t mesh_id[IW_ESSID_MAX_SIZE ]; +} __attribute__ ((packed)); + +struct mrvl_meshie { +struct ieee80211_info_element hdr; +struct mrvl_meshie_val val; +} __attribute__ ((packed)); + +struct mrvl_mesh_defaults { +__le32 bootflag; +uint8_t boottime; +uint8_t reserved; +__le16 channel; +struct mrvl_meshie meshie; +} __attribute__ ((packed)); +#endif
drivers/net/wireless/libertas/wext.c +3 -2
@@ -1002,7 +1002,7 @@ static int lbs_mesh_set_freq(struct net_device *dev,else if (priv->mode ==IW_MODE_ADHOC )lbs_stop_adhoc_network (priv); } -lbs_mesh_config (priv,1 , fwrq->m); +lbs_mesh_config (priv,CMD_ACT_MESH_CONFIG_START , fwrq->m);lbs_update_channel (priv); ret =0 ;
@@ -2011,7 +2011,8 @@ static int lbs_mesh_set_essid(struct net_device *dev, priv->mesh_ssid_len = dwrq->length; } -lbs_mesh_config (priv,1 , priv->curbssparams.channel); +lbs_mesh_config (priv,CMD_ACT_MESH_CONFIG_START , + priv->curbssparams.channel); out:lbs_deb_leave_args (LBS_DEB_WEXT ,"ret %d" , ret);return ret;
Signature · 1 line
1.5.2.4
Quoted 8 lines · Javier Cardona
This patch is based on a patch from Shailendra Govardhan and Brian Cavagnolo. It extends the
MESH_CONFIGcommand to configure non-volatile parameters on libertas devices that support them (e.g. OLPC Active Antenna).This patch only implements the driver/firmware interface.
See http://dev.laptop.org/ticket/6823 for minimal testing results and known issues.
Thanks. That looks much better, modulo a few cosmetic things which I'll fix up, and this (which I'll also fix):
+ cmd.length = sizeof(struct mrvl_meshie_val);
Sparse would have told you about that, if you built with 'C=2 CF=-D__CHECK_ENDIAN__':
drivers/net/wireless/libertas/cmd.c:1052:14: warning: incorrect type in assignment (different base types)drivers/net/wireless/libertas/cmd.c:1052:14: expected restricted unsigned short [addressable] [assigned] [usertype] lengthdrivers/net/wireless/libertas/cmd.c:1052:14: got unsigned int
I'd recommend always testing on a big-endian box, too. Sparse is good, but no substitute for the real thing.
Signature · 1 line
dwmw2