Commit 2dd4b262 authored by Dan Williams's avatar Dan Williams Committed by David S. Miller

libertas: convert RF_CHANNEL to a direct command

Signed-off-by: default avatarDan Williams <dcbw@redhat.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8e3c91bb
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "decl.h" #include "decl.h"
#include "hostcmd.h" #include "hostcmd.h"
#include "host.h" #include "host.h"
#include "cmd.h"
static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
...@@ -165,11 +166,14 @@ static int assoc_helper_mode(struct lbs_private *priv, ...@@ -165,11 +166,14 @@ static int assoc_helper_mode(struct lbs_private *priv,
static int update_channel(struct lbs_private *priv) static int update_channel(struct lbs_private *priv)
{ {
int ret; int ret;
/* the channel in f/w could be out of sync, get the current channel */ /* the channel in f/w could be out of sync, get the current channel */
lbs_deb_enter(LBS_DEB_ASSOC); lbs_deb_enter(LBS_DEB_ASSOC);
ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL,
CMD_OPT_802_11_RF_CHANNEL_GET, ret = lbs_get_channel(priv);
CMD_OPTION_WAITFORRSP, 0, NULL); if (ret > 0)
priv->curbssparams.channel = (u8) ret;
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret; return ret;
} }
...@@ -203,17 +207,16 @@ static int assoc_helper_channel(struct lbs_private *priv, ...@@ -203,17 +207,16 @@ static int assoc_helper_channel(struct lbs_private *priv,
lbs_deb_assoc("ASSOC: channel: %d -> %d\n", lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
priv->curbssparams.channel, assoc_req->channel); priv->curbssparams.channel, assoc_req->channel);
ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL, ret = lbs_set_channel(priv, assoc_req->channel);
CMD_OPT_802_11_RF_CHANNEL_SET, if (ret < 0)
CMD_OPTION_WAITFORRSP, 0, &assoc_req->channel);
if (ret < 0) {
lbs_deb_assoc("ASSOC: channel: error setting channel."); lbs_deb_assoc("ASSOC: channel: error setting channel.");
}
/* FIXME: shouldn't need to grab the channel _again_ after setting
* it since the firmware is supposed to return the new channel, but
* whatever... */
ret = update_channel(priv); ret = update_channel(priv);
if (ret < 0) { if (ret < 0)
lbs_deb_assoc("ASSOC: channel: error getting channel."); lbs_deb_assoc("ASSOC: channel: error getting channel.");
}
if (assoc_req->channel != priv->curbssparams.channel) { if (assoc_req->channel != priv->curbssparams.channel) {
lbs_deb_assoc("ASSOC: channel: failed to update channel to %d", lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
......
...@@ -810,25 +810,65 @@ static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv, ...@@ -810,25 +810,65 @@ static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv,
return 0; return 0;
} }
static int lbs_cmd_802_11_rf_channel(struct lbs_private *priv, /**
struct cmd_ds_command *cmd, * @brief Get the radio channel
int option, void *pdata_buf) *
* @param priv A pointer to struct lbs_private structure
*
* @return The channel on success, error on failure
*/
int lbs_get_channel(struct lbs_private *priv)
{ {
struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel; struct cmd_ds_802_11_rf_channel cmd;
int ret = 0;
lbs_deb_enter(LBS_DEB_CMD); lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(CMD_802_11_RF_CHANNEL);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) +
S_DS_GEN);
if (option == CMD_OPT_802_11_RF_CHANNEL_SET) { cmd.hdr.size = cpu_to_le16(sizeof(cmd));
rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf)); cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
}
rfchan->action = cpu_to_le16(option); ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, cmd);
if (ret)
goto out;
lbs_deb_leave(LBS_DEB_CMD); lbs_deb_cmd("current radio channel is %d\n", cmd.channel);
return 0; ret = (int) cmd.channel;
out:
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
/**
* @brief Set the radio channel
*
* @param priv A pointer to struct lbs_private structure
* @param channel The desired channel, or 0 to clear a locked channel
*
* @return 0 on success, error on failure
*/
int lbs_set_channel(struct lbs_private *priv, u8 channel)
{
struct cmd_ds_802_11_rf_channel cmd;
u8 old_channel = priv->curbssparams.channel;
int ret = 0;
lbs_deb_enter(LBS_DEB_CMD);
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
cmd.channel = cpu_to_le16(channel);
ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, cmd);
if (ret)
goto out;
priv->curbssparams.channel = cmd.channel;
lbs_deb_cmd("channel switch from %d to %d\n", old_channel, cmd.channel);
out:
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
} }
static int lbs_cmd_802_11_rssi(struct lbs_private *priv, static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
...@@ -1390,11 +1430,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, ...@@ -1390,11 +1430,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf);
break; break;
case CMD_802_11_RF_CHANNEL:
ret = lbs_cmd_802_11_rf_channel(priv, cmdptr,
cmd_action, pdata_buf);
break;
case CMD_802_11_RF_TX_POWER: case CMD_802_11_RF_TX_POWER:
ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr, ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr,
cmd_action, pdata_buf); cmd_action, pdata_buf);
......
...@@ -30,4 +30,7 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, ...@@ -30,4 +30,7 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
int lbs_get_data_rate(struct lbs_private *priv); int lbs_get_data_rate(struct lbs_private *priv);
int lbs_set_data_rate(struct lbs_private *priv, u8 rate); 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);
#endif /* _LBS_CMD_H */ #endif /* _LBS_CMD_H */
...@@ -325,28 +325,6 @@ static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv, ...@@ -325,28 +325,6 @@ static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv,
return 0; return 0;
} }
static int lbs_ret_802_11_rf_channel(struct lbs_private *priv,
struct cmd_ds_command *resp)
{
struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
u16 action = le16_to_cpu(rfchannel->action);
u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
lbs_deb_enter(LBS_DEB_CMD);
if (action == CMD_OPT_802_11_RF_CHANNEL_GET
&& priv->curbssparams.channel != newchannel) {
lbs_deb_cmd("channel switch from %d to %d\n",
priv->curbssparams.channel, newchannel);
/* Update the channel again */
priv->curbssparams.channel = newchannel;
}
lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
static int lbs_ret_802_11_rssi(struct lbs_private *priv, static int lbs_ret_802_11_rssi(struct lbs_private *priv,
struct cmd_ds_command *resp) struct cmd_ds_command *resp)
{ {
...@@ -548,9 +526,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, ...@@ -548,9 +526,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET): case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET):
ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp); ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
break; break;
case CMD_RET(CMD_802_11_RF_CHANNEL):
ret = lbs_ret_802_11_rf_channel(priv, resp);
break;
case CMD_RET(CMD_802_11_RSSI): case CMD_RET(CMD_802_11_RSSI):
ret = lbs_ret_802_11_rssi(priv, resp); ret = lbs_ret_802_11_rssi(priv, resp);
......
...@@ -386,11 +386,13 @@ struct cmd_ds_802_11_inactivity_timeout { ...@@ -386,11 +386,13 @@ struct cmd_ds_802_11_inactivity_timeout {
}; };
struct cmd_ds_802_11_rf_channel { struct cmd_ds_802_11_rf_channel {
struct cmd_header hdr;
__le16 action; __le16 action;
__le16 currentchannel; __le16 channel;
__le16 rftype; __le16 rftype; /* unused */
__le16 reserved; __le16 reserved; /* unused */
u8 channellist[32]; u8 channellist[32]; /* unused */
}; };
struct cmd_ds_802_11_rssi { struct cmd_ds_802_11_rssi {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment