Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edaea5ce authored by Javier Cardona's avatar Javier Cardona Committed by John W. Linville
Browse files

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

Signed-off-by: default avatarJavier Cardona <javier@cozybit.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 75bf45a7
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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);
+57 −11
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
  */

#include <net/iw_handler.h>
#include <net/ieee80211.h>
#include <linux/kfifo.h>
#include "host.h"
#include "hostcmd.h"
@@ -998,24 +999,69 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
	return ret;
}

int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
int lbs_mesh_config_send(struct lbs_private *priv,
			 struct cmd_ds_mesh_config *cmd,
			 uint16_t action, uint16_t type)
{
	int ret;

	lbs_deb_enter(LBS_DEB_CMD);

	cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG);
	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
	cmd->hdr.result = 0;

	cmd->type = cpu_to_le16(type);
	cmd->action = cpu_to_le16(action);

	ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);

	lbs_deb_leave(LBS_DEB_CMD);
	return ret;
}

/* This function is the CMD_MESH_CONFIG legacy function.  It only handles the
 * START and STOP actions.  The extended actions supported by CMD_MESH_CONFIG
 * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
 * lbs_mesh_config_send.
 */
int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
{
	struct cmd_ds_mesh_config cmd;
	struct mrvl_meshie *ie;

	memset(&cmd, 0, sizeof(cmd));
	cmd.action = cpu_to_le16(enable);
	cmd.channel = cpu_to_le16(chan);
	cmd.type = cpu_to_le16(priv->mesh_tlv);
	cmd.hdr.size = cpu_to_le16(sizeof(cmd));

	if (enable) {
		cmd.length = cpu_to_le16(priv->mesh_ssid_len);
		memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
	ie = (struct mrvl_meshie *)cmd.data;

	switch (action) {
	case CMD_ACT_MESH_CONFIG_START:
		ie->hdr.id = MFIE_TYPE_GENERIC;
		ie->val.oui[0] = 0x00;
		ie->val.oui[1] = 0x50;
		ie->val.oui[2] = 0x43;
		ie->val.type = MARVELL_MESH_IE_TYPE;
		ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
		ie->val.version = MARVELL_MESH_IE_VERSION;
		ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
		ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
		ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
		ie->val.mesh_id_len = priv->mesh_ssid_len;
		memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
		ie->hdr.len = sizeof(struct mrvl_meshie_val) -
			IW_ESSID_MAX_SIZE + priv->mesh_ssid_len;
		cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
		break;
	case CMD_ACT_MESH_CONFIG_STOP:
		break;
	default:
		return -1;
	}
	lbs_deb_cmd("mesh config enable %d TLV %x channel %d SSID %s\n",
		    enable, priv->mesh_tlv, chan,
	lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
		    action, priv->mesh_tlv, chan,
		    escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
	return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);

	return lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
}

static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
+3 −0
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@ 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,
			 uint16_t action, uint16_t 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);
+10 −0
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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
Loading