[PATCH] libertas: Support for mesh_start/mesh_stop iwpriv commands.

Ashish Shukla javier at cozybit.com
Wed Nov 28 15:55:26 EST 2007


Disable mesh autostart:  mesh will be controlled by the host via iwpriv
mesh_start and mesh_stop commands.
Bump driver version number (for Marvell QA use).

Signed-off-by: Javier Cardona <javier at cozybit.com>
---
 drivers/net/wireless/libertas/assoc.c   |   16 ++++++
 drivers/net/wireless/libertas/cmd.c     |   32 ++++++++++++
 drivers/net/wireless/libertas/cmdresp.c |   38 +++++++++++---
 drivers/net/wireless/libertas/dev.h     |    2 +
 drivers/net/wireless/libertas/host.h    |    3 +
 drivers/net/wireless/libertas/hostcmd.h |   10 ++++
 drivers/net/wireless/libertas/if_usb.c  |   26 ----------
 drivers/net/wireless/libertas/ioctl.c   |   83 +++++++++++++++++++++++++++++-
 drivers/net/wireless/libertas/join.c    |   38 +++++++++++---
 drivers/net/wireless/libertas/main.c    |   68 ++------------------------
 drivers/net/wireless/libertas/wext.c    |    3 +
 drivers/net/wireless/libertas/wext.h    |    3 +
 12 files changed, 213 insertions(+), 109 deletions(-)

diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index ffeec2f..01913e9 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -13,6 +13,8 @@
 
 static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+extern int libertas_mesh_config(wlan_private * priv, int action, int channel,
+	char *str);
 
 static void print_assoc_req(const char * extra, struct assoc_request * assoc_req)
 {
@@ -211,9 +213,16 @@ static int assoc_helper_channel(wlan_private *priv,
 {
 	wlan_adapter *adapter = priv->adapter;
 	int ret = 0;
+	int restart_mesh = 0;
 
 	lbs_deb_enter(LBS_DEB_ASSOC);
 
+	if (adapter->mesh_connect_status == LIBERTAS_CONNECTED) {
+		libertas_mesh_config(priv, 0, adapter->curbssparams.channel,
+				     NULL);
+		restart_mesh = 1;
+	}
+
 	ret = update_channel(priv);
 	if (ret < 0) {
 		lbs_deb_assoc("ASSOC: channel: error getting channel.");
@@ -225,11 +234,13 @@ static int assoc_helper_channel(wlan_private *priv,
 	lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
 	       adapter->curbssparams.channel, assoc_req->channel);
 
+
 	ret = libertas_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL,
 				CMD_OPT_802_11_RF_CHANNEL_SET,
 				CMD_OPTION_WAITFORRSP, 0, &assoc_req->channel);
 	if (ret < 0) {
 		lbs_deb_assoc("ASSOC: channel: error setting channel.");
+		lbs_pr_alert("Warning: error setting channel.");
 	}
 
 	ret = update_channel(priv);
@@ -256,6 +267,11 @@ static int assoc_helper_channel(wlan_private *priv,
 	set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
 
 done:
+	if (restart_mesh == 1) {
+		libertas_mesh_config(priv, 1, adapter->curbssparams.channel,
+			adapter->meshid);
+	}
+
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
 	return ret;
 }
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 50747fa..5c9260c 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -901,6 +901,34 @@ static int wlan_cmd_mesh_access(wlan_private * priv,
 	return 0;
 }
 
+static int wlan_cmd_mesh_config(wlan_private * priv,
+				struct cmd_ds_command *cmd,
+				u16 cmd_action, void *pdata_buf)
+{
+	struct cmd_ds_mesh_config *pmconf = &cmd->params.mesh_config;
+	struct cmd_ds_mesh_config *pmesh_config;
+	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+	pmesh_config = pdata_buf;
+	pmconf->action = cpu_to_le16(pmesh_config->action);
+	pmconf->channel = cpu_to_le16(pmesh_config->channel);
+	pmconf->type = cpu_to_le16(pmesh_config->type);
+	pmconf->length = cpu_to_le16(pmesh_config->length);
+
+	/* Set fixed field variables in scan command */
+	memcpy(&pmconf->data[0], &pmesh_config->data[0], pmconf->length);
+	cmd->command = cpu_to_le16(CMD_MESH_CONFIG);
+
+	/* size is equal to the sizeof(fixed portions) + the TLV len + header */
+	cmd->size = cpu_to_le16(sizeof(pmconf->action) + sizeof(pmconf->channel)
+				+ sizeof(pmconf->type) + sizeof(pmconf->length)
+				+ pmconf->length + S_DS_GEN);
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+
+}
+
+
 static int wlan_cmd_set_boot2_ver(wlan_private * priv,
 				struct cmd_ds_command *cmd,
 				u16 cmd_action, void *pdata_buf)
@@ -1467,6 +1495,10 @@ struct cmd_ctrl_node *libertas_prepare_command(wlan_private * priv,
 		ret = wlan_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf);
 		break;
 
+	case CMD_MESH_CONFIG:
+		ret = wlan_cmd_mesh_config(priv, cmdptr, cmd_action, pdata_buf);
+		break;
+
 	case CMD_SET_BOOT2_VER:
 		ret = wlan_cmd_set_boot2_ver(priv, cmdptr, cmd_action, pdata_buf);
 		break;
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index dd1e188..ae6b0f1 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -426,8 +426,15 @@ static int wlan_ret_802_11_rf_channel(wlan_private * priv,
 	u16 action = le16_to_cpu(rfchannel->action);
 	u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
 
+	u16 result = le16_to_cpu(resp->result);
+
 	lbs_deb_enter(LBS_DEB_CMD);
 
+	if (result) {
+		lbs_pr_alert("Warning: channel change failed!\n");
+		return 0;
+	}
+
 	if (action == CMD_OPT_802_11_RF_CHANNEL_GET
 	    && adapter->curbssparams.channel != newchannel) {
 		lbs_deb_cmd("channel switch from %d to %d\n",
@@ -553,7 +560,7 @@ static inline int handle_cmd_response(u16 respcmd,
 				      struct cmd_ds_command *resp,
 				      wlan_private *priv)
 {
-	int ret = 0;
+	int ret = 0, l = 0;
 	unsigned long flags;
 	wlan_adapter *adapter = priv->adapter;
 
@@ -717,6 +724,28 @@ 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_MESH_CONFIG):
+		if (resp->params.mesh_config.action == 1) {
+			priv->adapter->mesh_connect_status = LIBERTAS_CONNECTED;
+			netif_carrier_on(priv->mesh_dev);
+			netif_wake_queue(priv->mesh_dev);
+			lbs_pr_alert("mesh_start: mesh started on channel %d\n",
+					resp->params.mesh_config.channel);
+			adapter->curbssparams.channel =
+				le16_to_cpu(resp->params.mesh_config.channel);
+			for (l = 0; l < resp->params.mesh_config.length; ++l)
+				adapter->meshid[l] =
+					resp->params.mesh_config.data[l];
+			adapter->meshid[resp->params.mesh_config.length] = '\0';
+			adapter->meshid_length = strlen(adapter->meshid);
+		} else if (resp->params.mesh_config.action == 0) {
+			priv->adapter->mesh_connect_status =
+							LIBERTAS_DISCONNECTED;
+			netif_stop_queue(priv->mesh_dev);
+			netif_carrier_off(priv->mesh_dev);
+		}
+		break;
+
 	case CMD_RET(CMD_802_11_BEACON_CTRL):
 		ret = wlan_ret_802_11_bcn_ctrl(priv, resp);
 		break;
@@ -987,12 +1016,7 @@ int libertas_process_event(wlan_private * priv)
 		lbs_pr_alert("EVENT: Wireless firmware ready\n");
 		break;
 	case MACREG_INT_CODE_MESH_AUTO_STARTED:
-		/* Ignore spurious autostart events if autostart is disabled */
-		if (!priv->mesh_autostart_enabled) {
-			lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
-			break;
-		}
-		lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
+		lbs_pr_info("EVENT: Mesh Started\n");
 		adapter->mesh_connect_status = LIBERTAS_CONNECTED;
 		if (priv->mesh_open == 1) {
 			netif_wake_queue(priv->mesh_dev);
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 404ca50..7d9633c 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -374,6 +374,8 @@ struct _wlan_adapter {
 	u8 fw_ready;
 
 	u8 last_scanned_channel;
+	u16 meshid_length;
+	u8  meshid[IW_ESSID_MAX_SIZE + 1];
 };
 
 #endif				/* _WLAN_DEV_H_ */
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 2150ea0..c976198 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_MESH_CONFIG               0x00a3
+
 #define CMD_SET_BOOT2_VER                 0x00a5
 
 #define CMD_802_11_BEACON_CTRL        0x00b0
@@ -266,6 +268,7 @@ enum cmd_mesh_access_opts {
 	CMD_ACT_MESH_GET_ROUTE_EXP,
 	CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
 	CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
+	CMD_ACT_MESH_START,
 };
 
 /** Card Event definition */
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index 7865746..3fadb44 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -616,6 +616,15 @@ struct cmd_ds_mesh_access {
 	__le32 data[32];	/* last position reserved */
 } __attribute__ ((packed));
 
+struct cmd_ds_mesh_config {
+	u16 action;
+	u16 channel;
+	u16 type;
+	u16 length;
+	u8 data[128];	/* last position reserved */
+} __attribute__ ((packed));
+
+
 /* Number of stats counters returned by the firmware */
 #define MESH_STATS_NUM 8
 
@@ -678,6 +687,7 @@ struct cmd_ds_command {
 		struct cmd_ds_bt_access bt;
 		struct cmd_ds_fwt_access fwt;
 		struct cmd_ds_mesh_access mesh;
+		struct cmd_ds_mesh_config mesh_config;
 		struct cmd_ds_set_boot2_ver boot2_ver;
 		struct cmd_ds_get_tsf gettsf;
 		struct cmd_ds_802_11_subscribe_event subscribe_event;
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 740065b..09c8537 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -1055,19 +1055,6 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 	/* Unlink TX URB */
 	usb_kill_urb(cardp->tx_urb);
 
-	if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
-		/* Mesh autostart must be activated while sleeping
-		 * On resume it will go back to the current state
-		 */
-		struct cmd_ds_mesh_access mesh_access;
-		memset(&mesh_access, 0, sizeof(mesh_access));
-		mesh_access.data[0] = cpu_to_le32(1);
-		libertas_download_command(priv,
-				CMD_MESH_ACCESS,
-				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-				(void *)&mesh_access);
-	}
-
 	ret = libertas_download_command(priv,
 		CMD_802_11_HOST_SLEEP_CFG,
 		CMD_ACT_SET, (void *)&config);
@@ -1110,19 +1097,6 @@ static int if_usb_resume(struct usb_interface *intf)
 
 	if_usb_submit_rx_urb(cardp->priv);
 
-	if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
-		/* Mesh autostart was activated while sleeping
-		 * Disable it if appropriate
-		 */
-		struct cmd_ds_mesh_access mesh_access;
-		memset(&mesh_access, 0, sizeof(mesh_access));
-		mesh_access.data[0] = cpu_to_le32(0);
-		libertas_download_command(priv,
-				CMD_MESH_ACCESS,
-				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-				(void *)&mesh_access);
-	}
-
 	netif_device_attach(cardp->eth_dev);
 	netif_device_attach(priv->mesh_dev);
 
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
index 3ededab..dcc296b 100644
--- a/drivers/net/wireless/libertas/ioctl.c
+++ b/drivers/net/wireless/libertas/ioctl.c
@@ -27,6 +27,9 @@
 
 #define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)
 
+int libertas_mesh_config(wlan_private * priv, int action, int channel,
+			 char *str);
+
 static int libertas_set_region(wlan_private * priv, u16 region_code)
 {
 	int i;
@@ -816,7 +819,6 @@ static int libertas_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
 	return 0;
 }
 
-
 /**
  *  @brief              Manages all mesh related ioctls
  *  @param priv         A pointer to wlan_private structure
@@ -832,14 +834,39 @@ static int libertas_mesh_ioctl(wlan_private * priv, struct iwreq * wrq,
 {
 	struct cmd_ds_mesh_access mesh_access;
 	int parameter;
-	char str[128];
+	char str[128], chan[3];
 	char *ptr = str;
-	int ret, i;
+	int ret, i, channel, count = 0;
 
 	lbs_deb_enter(LBS_DEB_IOCTL);
 
 	memset(&mesh_access, 0, sizeof(mesh_access));
 
+	if (subcmd == CMD_ACT_MESH_START) {
+		if (priv->adapter->mesh_connect_status == LIBERTAS_CONNECTED) {
+			lbs_pr_alert("mesh_start: Mesh is already running!\n");
+			return 0;
+		}
+		if (wrq->u.data.length <= 1) {
+			channel = priv->adapter->curbssparams.channel;
+			ret =  libertas_mesh_config(priv, 1, channel,
+						    "olpc_mesh");
+
+		} else {
+			if (copy_from_user(str, wrq->u.data.pointer,
+						wrq->u.data.length))
+				return -EFAULT;
+			while (*ptr++ != ' ') {
+				if (*ptr == '\0') break;
+				chan[count] = str[count];
+				count++;
+			}
+			chan[count] = '\0';
+			channel = simple_strtol(chan, (char **)NULL, 10);
+			ret =  libertas_mesh_config (priv, 1, channel, ptr);
+		}
+		return ret;
+	}
 	if (cmd == LIBERTAS_SETONEINT_GETNONE) {
 		parameter = SUBCMD_DATA(wrq);
 
@@ -1101,6 +1128,7 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 	wlan_private *priv = dev->priv;
 	wlan_adapter *adapter = priv->adapter;
 	struct iwreq *wrq = (struct iwreq *)req;
+	char str[32];
 
 	lbs_deb_enter(LBS_DEB_IOCTL);
 
@@ -1114,6 +1142,25 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 		case LIBERTAS_SUBCMD_FWT_RESET:
 			libertas_fwt_reset_ioctl(priv);
 			break;
+		case LIBERTAS_SUBCMD_MESH_STOP:
+			if (priv->adapter->mesh_connect_status ==
+				LIBERTAS_DISCONNECTED) {
+				lbs_pr_alert("mesh_stop: Mesh already off!\n");
+			} else
+				libertas_mesh_config(priv, 0,
+					adapter->curbssparams.channel, NULL);
+			break;
+		case LIBERTAS_SUBCMD_GET_MESH_STATUS:
+			if (priv->adapter->mesh_connect_status ==
+				LIBERTAS_CONNECTED) {
+				strcpy(str, adapter->meshid);
+				lbs_pr_alert("mesh_status: mesh ON channel = %d"
+					     " Mesh ID = %s \n",
+					     adapter->curbssparams.channel,
+					     str);
+			} else
+				lbs_pr_alert("mesh_status: mesh OFF\n");
+			break;
 		}
 		break;
 
@@ -1147,6 +1194,7 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 		}
 		break;
 
+
 	case LIBERTAS_SET128CHAR_GET128CHAR:
 		switch ((int)wrq->u.data.flags) {
 		case LIBERTAS_SUBCMD_BT_ADD:
@@ -1184,6 +1232,10 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 			ret = libertas_mesh_ioctl(priv, wrq, cmd,
 					CMD_ACT_MESH_GET_LINK_COSTS);
 			break;
+		case LIBERTAS_SUBCMD_MESH_START:
+			ret = libertas_mesh_ioctl(priv, wrq, cmd,
+					CMD_ACT_MESH_START);
+			break;
 		}
 		break;
 
@@ -1246,4 +1298,29 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 	return ret;
 }
 
+int libertas_mesh_config(wlan_private * priv, int action, int channel,
+			 char *str)
+{
+	struct cmd_ds_mesh_config mesh_config;
+	int ret;
+	memset(&mesh_config, 0, sizeof(mesh_config));
+	mesh_config.action = cpu_to_le16(action);
+	mesh_config.channel = cpu_to_le16(channel);
+	mesh_config.type = cpu_to_le16(0x100 + 37) ;
+
+	if (str != NULL) {
+		mesh_config.length = cpu_to_le16(strlen(str));
+		memcpy(&mesh_config.data[0], str, strlen(str));
+	} else
+		mesh_config.length = 0;
+
+	ret = libertas_prepare_and_send_command(priv, CMD_MESH_CONFIG, 0,
+				    CMD_OPTION_WAITFORRSP, 0,
+				    (void *)&mesh_config);
+
+	return ret;
+}
+
+
+
 
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index 5447407..6949eda 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -426,9 +426,6 @@ int libertas_cmd_80211_associate(wlan_private * priv,
 	rates->header.len = cpu_to_le16(tmplen);
 	lbs_deb_join("ASSOC_CMD: num rates = %u\n", tmplen);
 
-	/* Copy the infra. association rates into Current BSS state structure */
-	memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
-	memcpy(&adapter->curbssparams.rates, &rates->rates, tmplen);
 
 	/* Set MSB on basic rates as the firmware requires, but _after_
 	 * copying to current bss rates.
@@ -447,8 +444,6 @@ int libertas_cmd_80211_associate(wlan_private * priv,
 		pos += sizeof(rsn->header) + tmplen;
 	}
 
-	/* update curbssparams */
-	adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
 
 	if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
 		ret = -1;
@@ -635,7 +630,6 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
 	/* probedelay */
 	join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
 
-	adapter->curbssparams.channel = bss->channel;
 
 	/* Copy Data rates from the rates recorded in scan response */
 	memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates));
@@ -647,9 +641,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
 		goto done;
 	}
 
-	/* Copy the ad-hoc creating rates into Current BSS state structure */
-	memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
-	memcpy(&adapter->curbssparams.rates, join_cmd->bss.rates, ratesize);
+
 
 	/* Set MSB on basic rates as the firmware requires, but _after_
 	 * copying to current bss rates.
@@ -719,6 +711,7 @@ int libertas_ret_80211_associate(wlan_private * priv,
 
 		lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n",
 			     le16_to_cpu(passocrsp->statuscode));
+		lbs_pr_alert("Warning: INFRA Join Failed\n");
 
 		ret = -1;
 		goto done;
@@ -738,6 +731,14 @@ int libertas_ret_80211_associate(wlan_private * priv,
 	adapter->curbssparams.ssid_len = bss->ssid_len;
 	memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
 
+	/* update curbssparams */
+	adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
+
+	/* Copy the infra. association rates into Current BSS state structure */
+	memset(&adapter->curbssparams.rates, 0,
+		sizeof(adapter->curbssparams.rates));
+	memcpy(&adapter->curbssparams.rates, &bss->rates, sizeof(bss->rates));
+
 	lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n",
 	       adapter->currentpacketfilter);
 
@@ -820,6 +821,16 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
 	lbs_deb_join("ADHOC_RESP: associated to '%s'\n",
 	             escape_essid(bss->ssid, bss->ssid_len));
 
+	if (padhocresult->pad[0] == 8) {
+		if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
+			lbs_pr_alert("Warning: ADHOC Started on channel "
+				     "%d\n", adapter->curbssparams.channel);
+		} else {
+			lbs_pr_alert("Warning: ADHOC Join Failed\n");
+			goto done;
+		}
+	}
+
 	/* Send a Media Connected event, according to the Spec */
 	adapter->connect_status = LIBERTAS_CONNECTED;
 
@@ -835,6 +846,15 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
 	memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
 	adapter->curbssparams.ssid_len = bss->ssid_len;
 
+	if (bss->channel != 0)
+		adapter->curbssparams.channel = bss->channel;
+
+	/* Copy the ad-hoc creating rates into Current BSS state structure */
+	memset(&adapter->curbssparams.rates, 0,
+	       sizeof(adapter->curbssparams.rates));
+	memcpy(&adapter->curbssparams.rates, bss->rates,
+	       sizeof(adapter->curbssparams.rates));
+
 	netif_carrier_on(priv->dev);
 	netif_wake_queue(priv->dev);
 
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 2b104d2..dd4ae32 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -26,11 +26,11 @@
 #include "join.h"
 
 #define DRIVER_RELEASE_VERSION "322.p1"
-const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
+const char libertas_driver_version[] = "MRVL-USB8388-" DRIVER_RELEASE_VERSION
 #ifdef  DEBUG
-    "-dbg"
+    ""
 #endif
-    "";
+    "-1";
 
 
 /* Module parameters */
@@ -315,48 +315,8 @@ static DEVICE_ATTR(libertas_rtap, 0644, libertas_rtap_get,
  */
 static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set);
 
-static ssize_t libertas_autostart_enabled_get(struct device * dev,
-		struct device_attribute *attr, char * buf)
-{
-	struct cmd_ds_mesh_access mesh_access;
-
-	memset(&mesh_access, 0, sizeof(mesh_access));
-	libertas_prepare_and_send_command(to_net_dev(dev)->priv,
-			CMD_MESH_ACCESS,
-			CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
-			CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-
-	return sprintf(buf, "%d\n", le32_to_cpu(mesh_access.data[0]));
-}
-
-static ssize_t libertas_autostart_enabled_set(struct device * dev,
-		struct device_attribute *attr, const char * buf, size_t count)
-{
-	struct cmd_ds_mesh_access mesh_access;
-	uint32_t datum;
-	wlan_private * priv = (to_net_dev(dev))->priv;
-	int ret;
-
-	memset(&mesh_access, 0, sizeof(mesh_access));
-	sscanf(buf, "%d", &datum);
-	mesh_access.data[0] = cpu_to_le32(datum);
-
-	ret = libertas_prepare_and_send_command(priv,
-			CMD_MESH_ACCESS,
-			CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-			CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-	if (ret == 0)
-		priv->mesh_autostart_enabled = datum ? 1 : 0;
-
-	return strlen(buf);
-}
-
-static DEVICE_ATTR(autostart_enabled, 0644,
-		libertas_autostart_enabled_get, libertas_autostart_enabled_set);
-
 static struct attribute *libertas_mesh_sysfs_entries[] = {
 	&dev_attr_anycast_mask.attr,
-	&dev_attr_autostart_enabled.attr,
 	NULL,
 };
 
@@ -438,12 +398,7 @@ static int libertas_mesh_open(struct net_device *dev)
 	if (pre_open_check(dev) == -1)
 		return -1;
 	priv->mesh_open = 1 ;
-	netif_wake_queue(priv->mesh_dev);
 
-        priv->adapter->mesh_connect_status = LIBERTAS_CONNECTED;
-
-	netif_carrier_on(priv->mesh_dev);
-	netif_wake_queue(priv->mesh_dev);
 	if (priv->infra_open == 0)
 		return libertas_dev_open(priv->dev) ;
 	return 0;
@@ -948,7 +903,6 @@ static int wlan_setup_station_hw(wlan_private * priv)
 {
 	int ret = -1;
 	wlan_adapter *adapter = priv->adapter;
-	struct cmd_ds_mesh_access mesh_access;
 
 	lbs_deb_enter(LBS_DEB_FW);
 
@@ -985,21 +939,6 @@ static int wlan_setup_station_hw(wlan_private * priv)
 		goto done;
 	}
 
-	/* Disable mesh autostart */
-	if (priv->mesh_dev) {
-		memset(&mesh_access, 0, sizeof(mesh_access));
-		mesh_access.data[0] = cpu_to_le32(0);
-		ret = libertas_prepare_and_send_command(priv,
-				CMD_MESH_ACCESS,
-				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-		if (ret) {
-			ret = -1;
-			goto done;
-		}
-		priv->mesh_autostart_enabled = 0;
-	}
-
        /* Set the boot2 version in firmware */
        ret = libertas_prepare_and_send_command(priv, CMD_SET_BOOT2_VER,
                                    0, CMD_OPTION_WAITFORRSP, 0, NULL);
@@ -1115,6 +1054,7 @@ static void wlan_init_adapter(wlan_private * priv)
 
 	adapter->connect_status = LIBERTAS_DISCONNECTED;
 	adapter->mesh_connect_status = LIBERTAS_DISCONNECTED;
+	adapter->meshid_length = 0;
 	memset(adapter->current_addr, 0xff, ETH_ALEN);
 
 	/* 802.11 specific */
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 11f9389..77ebeaf 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -831,6 +831,8 @@ static const struct iw_priv_args wlan_private_args[] = {
 	{ LIBERTAS_SETNONE_GETNONE, 0, 0, "" },
 	    { LIBERTAS_SUBCMD_FWT_RESET, 0, 0, "fwt_reset"},
 	    { LIBERTAS_SUBCMD_BT_RESET, 0, 0, "bt_reset"},
+	    { LIBERTAS_SUBCMD_MESH_STOP, 0, 0, "mesh_stop"},
+	    { LIBERTAS_SUBCMD_GET_MESH_STATUS, 0, 0, "mesh_status"},
 	{ LIBERTAS_SETNONE_GETONEINT, 0, INT_PARAM, ""},
 	    { LIBERTAS_SUBCMD_GET_REGION, 0, INT_PARAM, "getregioncode"},
 	    { LIBERTAS_SUBCMD_FWT_CLEANUP, 0, INT_PARAM, "fwt_cleanup"},
@@ -859,6 +861,7 @@ static const struct iw_priv_args wlan_private_args[] = {
 	    { LIBERTAS_SUBCMD_FWT_LIST_ROUTE, CHAR128_PARAM, CHAR128_PARAM, "fwt_list_route"},
 	    { LIBERTAS_SUBCMD_MESH_SET_LINK_COSTS, CHAR128_PARAM, CHAR128_PARAM, "set_link_costs"},
 	    { LIBERTAS_SUBCMD_MESH_GET_LINK_COSTS, CHAR128_PARAM, CHAR128_PARAM, "get_link_costs"},
+	    { LIBERTAS_SUBCMD_MESH_START, CHAR128_PARAM, CHAR128_PARAM, "mesh_start"},
 	{ 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"},
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
index e93853b..4a2c28e 100644
--- a/drivers/net/wireless/libertas/wext.h
+++ b/drivers/net/wireless/libertas/wext.h
@@ -14,6 +14,9 @@
 #define LIBERTAS_SETNONE_GETNONE	        (SIOCIWFIRSTPRIV + 8)
 #define LIBERTAS_SUBCMD_BT_RESET		13
 #define LIBERTAS_SUBCMD_FWT_RESET		14
+#define LIBERTAS_SUBCMD_MESH_START		15
+#define LIBERTAS_SUBCMD_MESH_STOP		16
+#define LIBERTAS_SUBCMD_GET_MESH_STATUS		17
 
 #define LIBERTAS_SETNONE_GETONEINT		(SIOCIWFIRSTPRIV + 15)
 #define LIBERTAS_SUBCMD_GET_REGION		1
-- 
1.5.2.5






More information about the Devel mailing list