From e86dc1ca4676445d9f0dfe35104efe0eb8a2f566 Mon Sep 17 00:00:00 2001 From: Kiran Divekar Date: Mon, 14 Jun 2010 22:01:26 +0530 Subject: Libertas: cfg80211 support Holger Schurig's patch (https://patchwork.kernel.org/patch/64286/) is rebased to latest wireless-testing tree. (Includes patches from me originally posted as "libertas: fix build error due to undefined symbol" and "libertas: unmangle capability value". -- JWL) Signed-off-by: Amitkumar Karwar Signed-off-by: Kiran Divekar Tested-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/mesh.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/libertas/mesh.c') diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index e385af1f458..bc5bc1384c3 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -5,6 +5,7 @@ #include #include #include +#include #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); -- cgit v1.2.3 From 52148655608b31b7e18325ae7711de3a86466136 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 27 Jul 2010 13:01:47 -0700 Subject: libertas: convert Mesh Blinding Table access to a direct command Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 4 - drivers/net/wireless/libertas/cmdresp.c | 7 -- drivers/net/wireless/libertas/host.h | 3 +- drivers/net/wireless/libertas/mesh.c | 182 ++++++++++++++++++++++++++------ drivers/net/wireless/libertas/mesh.h | 8 +- 5 files changed, 158 insertions(+), 46 deletions(-) (limited to 'drivers/net/wireless/libertas/mesh.c') diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index b8df1fd8924..dd25b2a9dbe 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1208,10 +1208,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, #ifdef CONFIG_LIBERTAS_MESH - case CMD_BT_ACCESS: - ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf); - break; - case CMD_FWT_ACCESS: ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); break; diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 810d75882e7..098b6453cb0 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -68,13 +68,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, case CMD_RET(CMD_802_11_BEACON_STOP): break; - case CMD_RET(CMD_BT_ACCESS): - spin_lock_irqsave(&priv->driver_lock, flags); - if (priv->cur_cmd->callback_arg) - memcpy((void *)priv->cur_cmd->callback_arg, - &resp->params.bt.addr1, 2 * ETH_ALEN); - spin_unlock_irqrestore(&priv->driver_lock, flags); - break; case CMD_RET(CMD_FWT_ACCESS): spin_lock_irqsave(&priv->driver_lock, flags); if (priv->cur_cmd->callback_arg) diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 0a4ddc1cdd6..e8171777846 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -903,6 +903,8 @@ struct cmd_ds_get_tsf { } __packed; struct cmd_ds_bt_access { + struct cmd_header hdr; + __le16 action; __le32 id; u8 addr1[ETH_ALEN]; @@ -959,7 +961,6 @@ struct cmd_ds_command { /* command Body */ union { struct cmd_ds_802_11_ps_mode psmode; - struct cmd_ds_bt_access bt; struct cmd_ds_fwt_access fwt; } params; } __packed; diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index bc5bc1384c3..35ee574f588 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -455,44 +455,162 @@ 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); + + BUG_ON(addr1 == NULL); - switch (cmd_action) { - case CMD_ACT_BT_ACCESS_ADD: - memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN); + 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; +} + +/** + * @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_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_RESET); + + ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &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; } int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h index 84ea2481ff2..855497902d9 100644 --- a/drivers/net/wireless/libertas/mesh.h +++ b/drivers/net/wireless/libertas/mesh.h @@ -51,8 +51,12 @@ struct cmd_ds_command; struct cmd_ds_mesh_access; struct cmd_ds_mesh_config; -int lbs_cmd_bt_access(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf); +int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1); +int lbs_mesh_bt_reset(struct lbs_private *priv); +int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted); +int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted); +int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1); + int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf); int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, -- cgit v1.2.3 From a6bb1bcebced1eeed6a96f37cda7cbb7cbd6dae6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 27 Jul 2010 13:03:46 -0700 Subject: libertas: convert CMD_FWT_ACCESS to a direct command Slightly different approach here since there are so many arguments to the firmware command. Just let the caller fill them in before pushing the command to the firmware. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 8 -------- drivers/net/wireless/libertas/cmdresp.c | 9 --------- drivers/net/wireless/libertas/host.h | 3 ++- drivers/net/wireless/libertas/mesh.c | 34 +++++++++++++++++++-------------- drivers/net/wireless/libertas/mesh.h | 6 ++++-- 5 files changed, 26 insertions(+), 34 deletions(-) (limited to 'drivers/net/wireless/libertas/mesh.c') diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index dd25b2a9dbe..2c96cf3400c 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1206,14 +1206,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); break; -#ifdef CONFIG_LIBERTAS_MESH - - case CMD_FWT_ACCESS: - ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); - break; - -#endif - case CMD_802_11_DEEP_SLEEP: cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP); cmdptr->size = cpu_to_le16(sizeof(struct cmd_header)); diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 098b6453cb0..26a30db77d3 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -59,7 +59,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, { struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response; int ret = 0; - unsigned long flags; uint16_t respcmd = le16_to_cpu(resp->command); lbs_deb_enter(LBS_DEB_HOST); @@ -68,14 +67,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, case CMD_RET(CMD_802_11_BEACON_STOP): break; - case CMD_RET(CMD_FWT_ACCESS): - spin_lock_irqsave(&priv->driver_lock, flags); - if (priv->cur_cmd->callback_arg) - memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt, - sizeof(resp->params.fwt)); - spin_unlock_irqrestore(&priv->driver_lock, flags); - break; - default: lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n", le16_to_cpu(resp->command)); diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index e8171777846..03d2ae9bdd7 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -912,6 +912,8 @@ struct cmd_ds_bt_access { } __packed; struct cmd_ds_fwt_access { + struct cmd_header hdr; + __le16 action; __le32 id; u8 valid; @@ -961,7 +963,6 @@ struct cmd_ds_command { /* command Body */ union { struct cmd_ds_802_11_ps_mode psmode; - struct cmd_ds_fwt_access fwt; } params; } __packed; #endif diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 35ee574f588..194762ab014 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -613,25 +613,31 @@ int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) return ret; } -int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf) +/** + * @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) { - struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; - lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); + int ret; - 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_args(LBS_DEB_CMD, "action %d", cmd_action); - if (pdata_buf) - memcpy(fwt_access, pdata_buf, sizeof(*fwt_access)); - else - memset(fwt_access, 0, sizeof(*fwt_access)); + 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); - fwt_access->action = cpu_to_le16(cmd_action); + ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd); - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return 0; } diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h index 855497902d9..afb2e8dead3 100644 --- a/drivers/net/wireless/libertas/mesh.h +++ b/drivers/net/wireless/libertas/mesh.h @@ -8,6 +8,7 @@ #include #include +#include "host.h" #ifdef CONFIG_LIBERTAS_MESH @@ -57,8 +58,9 @@ int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted); int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted); int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1); -int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf); +int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, + struct cmd_ds_fwt_access *cmd); + int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, struct cmd_ds_mesh_access *cmd); int lbs_mesh_config_send(struct lbs_private *priv, -- cgit v1.2.3