diff options
Diffstat (limited to 'drivers/net/wireless/libertas/mesh.c')
| -rw-r--r-- | drivers/net/wireless/libertas/mesh.c | 222 | 
1 files changed, 172 insertions, 50 deletions
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index e385af1f458..194762ab014 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -5,6 +5,7 @@  #include <linux/if_arp.h>  #include <linux/kthread.h>  #include <linux/kfifo.h> +#include <net/cfg80211.h>  #include "mesh.h"  #include "decl.h" @@ -314,7 +315,7 @@ static int lbs_mesh_dev_open(struct net_device *dev)  	spin_lock_irq(&priv->driver_lock); -	if (priv->monitormode) { +	if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {  		ret = -EBUSY;  		goto out;  	} @@ -369,9 +370,6 @@ int lbs_add_mesh(struct lbs_private *priv)  	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); -#ifdef	WIRELESS_EXT -	mesh_dev->wireless_handlers = &mesh_handler_def; -#endif  	mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;  	/* Register virtual mesh interface */  	ret = register_netdev(mesh_dev); @@ -457,65 +455,189 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,   * Mesh command handling   */ -int lbs_cmd_bt_access(struct cmd_ds_command *cmd, -			       u16 cmd_action, void *pdata_buf) +/** + *  @brief Add or delete Mesh Blinding Table entries + * + *  @param priv    	A pointer to struct lbs_private structure + *  @param add  	TRUE to add the entry, FALSE to delete it + *  @param addr1        Destination address to blind or unblind + * + *  @return 	   	0 on success, error on failure + */ +int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)  { -	struct cmd_ds_bt_access *bt_access = &cmd->params.bt; -	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); +	struct cmd_ds_bt_access cmd; +	int ret = 0; -	cmd->command = cpu_to_le16(CMD_BT_ACCESS); -	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + -		sizeof(struct cmd_header)); -	cmd->result = 0; -	bt_access->action = cpu_to_le16(cmd_action); +	lbs_deb_enter(LBS_DEB_CMD); -	switch (cmd_action) { -	case CMD_ACT_BT_ACCESS_ADD: -		memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN); +	BUG_ON(addr1 == NULL); + +	memset(&cmd, 0, sizeof(cmd)); +	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); +	memcpy(cmd.addr1, addr1, ETH_ALEN); +	if (add) { +		cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD);  		lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", -			bt_access->addr1, 6); -		break; -	case CMD_ACT_BT_ACCESS_DEL: -		memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN); +			addr1, ETH_ALEN); +	} else { +		cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL);  		lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", -			bt_access->addr1, 6); -		break; -	case CMD_ACT_BT_ACCESS_LIST: -		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); -		break; -	case CMD_ACT_BT_ACCESS_RESET: -		break; -	case CMD_ACT_BT_ACCESS_SET_INVERT: -		bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); -		break; -	case CMD_ACT_BT_ACCESS_GET_INVERT: -		break; -	default: -		break; +			addr1, ETH_ALEN);  	} -	lbs_deb_leave(LBS_DEB_CMD); -	return 0; + +	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); + +	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); +	return ret;  } -int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, -			       u16 cmd_action, void *pdata_buf) +/** + *  @brief Reset/clear the mesh blinding table + * + *  @param priv    	A pointer to struct lbs_private structure + * + *  @return 	   	0 on success, error on failure + */ +int lbs_mesh_bt_reset(struct lbs_private *priv)  { -	struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; -	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); +	struct cmd_ds_bt_access cmd; +	int ret = 0; -	cmd->command = cpu_to_le16(CMD_FWT_ACCESS); -	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + -		sizeof(struct cmd_header)); -	cmd->result = 0; +	lbs_deb_enter(LBS_DEB_CMD); -	if (pdata_buf) -		memcpy(fwt_access, pdata_buf, sizeof(*fwt_access)); -	else -		memset(fwt_access, 0, sizeof(*fwt_access)); +	memset(&cmd, 0, sizeof(cmd)); +	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); +	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET); -	fwt_access->action = cpu_to_le16(cmd_action); +	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); -	lbs_deb_leave(LBS_DEB_CMD); +	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); +	return ret; +} + +/** + *  @brief Gets the inverted status of the mesh blinding table + * + *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the + *  table, but an inverted table allows *only* traffic from nodes listed in + *  the table. + * + *  @param priv    	A pointer to struct lbs_private structure + *  @param invert  	On success, TRUE if the blinding table is inverted, + *                        FALSE if it is not inverted + * + *  @return 	   	0 on success, error on failure + */ +int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) +{ +	struct cmd_ds_bt_access cmd; +	int ret = 0; + +	lbs_deb_enter(LBS_DEB_CMD); + +	BUG_ON(inverted == NULL); + +	memset(&cmd, 0, sizeof(cmd)); +	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); +	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT); + +	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); +	if (ret == 0) +		*inverted = !!cmd.id; + +	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); +	return ret; +} + +/** + *  @brief Sets the inverted status of the mesh blinding table + * + *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the + *  table, but an inverted table allows *only* traffic from nodes listed in + *  the table. + * + *  @param priv    	A pointer to struct lbs_private structure + *  @param invert  	TRUE to invert the blinding table (only traffic from + *                         listed nodes allowed), FALSE to return it + *                         to normal state (listed nodes ignored) + * + *  @return 	   	0 on success, error on failure + */ +int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) +{ +	struct cmd_ds_bt_access cmd; +	int ret = 0; + +	lbs_deb_enter(LBS_DEB_CMD); + +	memset(&cmd, 0, sizeof(cmd)); +	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); +	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); +	cmd.id = !!inverted; + +	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); + +	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); +	return ret; +} + +/** + *  @brief List an entry in the mesh blinding table + * + *  @param priv    	A pointer to struct lbs_private structure + *  @param id		The ID of the entry to list + *  @param addr1	MAC address associated with the table entry + * + *  @return 	   	0 on success, error on failure + */ +int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) +{ +	struct cmd_ds_bt_access cmd; +	int ret = 0; + +	lbs_deb_enter(LBS_DEB_CMD); + +	BUG_ON(addr1 == NULL); + +	memset(&cmd, 0, sizeof(cmd)); +	cmd.hdr.size = cpu_to_le16(sizeof(cmd)); +	cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); +	cmd.id = cpu_to_le32(id); + +	ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); +	if (ret == 0) +		memcpy(addr1, cmd.addr1, sizeof(cmd.addr1)); + +	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); +	return ret; +} + +/** + *  @brief Access the mesh forwarding table + * + *  @param priv    	A pointer to struct lbs_private structure + *  @param cmd_action	The forwarding table action to perform + *  @param cmd		The pre-filled FWT_ACCESS command + * + *  @return 	   	0 on success and 'cmd' will be filled with the + *                        firmware's response + */ +int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, +			struct cmd_ds_fwt_access *cmd) +{ +	int ret; + +	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); + +	cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS); +	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)); +	cmd->hdr.result = 0; +	cmd->action = cpu_to_le16(cmd_action); + +	ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd); + +	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);  	return 0;  }  |