diff options
author | Dan Williams <dcbw@redhat.com> | 2007-12-11 16:54:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:06:50 -0500 |
commit | 2dd4b26264d48f10e802cc9f2d75542be5a3c7fa (patch) | |
tree | 2d79fa1cde5146df36c2add9c357e404512def94 | |
parent | 8e3c91bb70372da692a5fefae9f698c94bb1e641 (diff) |
libertas: convert RF_CHANNEL to a direct command
Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 71 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmd.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmdresp.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/hostcmd.h | 10 |
5 files changed, 75 insertions, 57 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 63bd692c7239..bd9cfe118c44 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "decl.h" | 9 | #include "decl.h" |
10 | #include "hostcmd.h" | 10 | #include "hostcmd.h" |
11 | #include "host.h" | 11 | #include "host.h" |
12 | #include "cmd.h" | ||
12 | 13 | ||
13 | 14 | ||
14 | static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 15 | static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
@@ -165,11 +166,14 @@ done: | |||
165 | static int update_channel(struct lbs_private *priv) | 166 | static int update_channel(struct lbs_private *priv) |
166 | { | 167 | { |
167 | int ret; | 168 | int ret; |
169 | |||
168 | /* the channel in f/w could be out of sync, get the current channel */ | 170 | /* the channel in f/w could be out of sync, get the current channel */ |
169 | lbs_deb_enter(LBS_DEB_ASSOC); | 171 | lbs_deb_enter(LBS_DEB_ASSOC); |
170 | ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL, | 172 | |
171 | CMD_OPT_802_11_RF_CHANNEL_GET, | 173 | ret = lbs_get_channel(priv); |
172 | CMD_OPTION_WAITFORRSP, 0, NULL); | 174 | if (ret > 0) |
175 | priv->curbssparams.channel = (u8) ret; | ||
176 | |||
173 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 177 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
174 | return ret; | 178 | return ret; |
175 | } | 179 | } |
@@ -203,17 +207,16 @@ static int assoc_helper_channel(struct lbs_private *priv, | |||
203 | lbs_deb_assoc("ASSOC: channel: %d -> %d\n", | 207 | lbs_deb_assoc("ASSOC: channel: %d -> %d\n", |
204 | priv->curbssparams.channel, assoc_req->channel); | 208 | priv->curbssparams.channel, assoc_req->channel); |
205 | 209 | ||
206 | ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL, | 210 | ret = lbs_set_channel(priv, assoc_req->channel); |
207 | CMD_OPT_802_11_RF_CHANNEL_SET, | 211 | if (ret < 0) |
208 | CMD_OPTION_WAITFORRSP, 0, &assoc_req->channel); | ||
209 | if (ret < 0) { | ||
210 | lbs_deb_assoc("ASSOC: channel: error setting channel."); | 212 | lbs_deb_assoc("ASSOC: channel: error setting channel."); |
211 | } | ||
212 | 213 | ||
214 | /* FIXME: shouldn't need to grab the channel _again_ after setting | ||
215 | * it since the firmware is supposed to return the new channel, but | ||
216 | * whatever... */ | ||
213 | ret = update_channel(priv); | 217 | ret = update_channel(priv); |
214 | if (ret < 0) { | 218 | if (ret < 0) |
215 | lbs_deb_assoc("ASSOC: channel: error getting channel."); | 219 | lbs_deb_assoc("ASSOC: channel: error getting channel."); |
216 | } | ||
217 | 220 | ||
218 | if (assoc_req->channel != priv->curbssparams.channel) { | 221 | if (assoc_req->channel != priv->curbssparams.channel) { |
219 | lbs_deb_assoc("ASSOC: channel: failed to update channel to %d", | 222 | lbs_deb_assoc("ASSOC: channel: failed to update channel to %d", |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index eff78792fc6f..32f9f880a15a 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -810,25 +810,65 @@ static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv, | |||
810 | return 0; | 810 | return 0; |
811 | } | 811 | } |
812 | 812 | ||
813 | static int lbs_cmd_802_11_rf_channel(struct lbs_private *priv, | 813 | /** |
814 | struct cmd_ds_command *cmd, | 814 | * @brief Get the radio channel |
815 | int option, void *pdata_buf) | 815 | * |
816 | * @param priv A pointer to struct lbs_private structure | ||
817 | * | ||
818 | * @return The channel on success, error on failure | ||
819 | */ | ||
820 | int lbs_get_channel(struct lbs_private *priv) | ||
816 | { | 821 | { |
817 | struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel; | 822 | struct cmd_ds_802_11_rf_channel cmd; |
823 | int ret = 0; | ||
818 | 824 | ||
819 | lbs_deb_enter(LBS_DEB_CMD); | 825 | lbs_deb_enter(LBS_DEB_CMD); |
820 | cmd->command = cpu_to_le16(CMD_802_11_RF_CHANNEL); | ||
821 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) + | ||
822 | S_DS_GEN); | ||
823 | 826 | ||
824 | if (option == CMD_OPT_802_11_RF_CHANNEL_SET) { | 827 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
825 | rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf)); | 828 | cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET); |
826 | } | ||
827 | 829 | ||
828 | rfchan->action = cpu_to_le16(option); | 830 | ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, cmd); |
831 | if (ret) | ||
832 | goto out; | ||
829 | 833 | ||
830 | lbs_deb_leave(LBS_DEB_CMD); | 834 | lbs_deb_cmd("current radio channel is %d\n", cmd.channel); |
831 | return 0; | 835 | ret = (int) cmd.channel; |
836 | |||
837 | out: | ||
838 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
839 | return ret; | ||
840 | } | ||
841 | |||
842 | /** | ||
843 | * @brief Set the radio channel | ||
844 | * | ||
845 | * @param priv A pointer to struct lbs_private structure | ||
846 | * @param channel The desired channel, or 0 to clear a locked channel | ||
847 | * | ||
848 | * @return 0 on success, error on failure | ||
849 | */ | ||
850 | int lbs_set_channel(struct lbs_private *priv, u8 channel) | ||
851 | { | ||
852 | struct cmd_ds_802_11_rf_channel cmd; | ||
853 | u8 old_channel = priv->curbssparams.channel; | ||
854 | int ret = 0; | ||
855 | |||
856 | lbs_deb_enter(LBS_DEB_CMD); | ||
857 | |||
858 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | ||
859 | cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); | ||
860 | cmd.channel = cpu_to_le16(channel); | ||
861 | |||
862 | ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, cmd); | ||
863 | if (ret) | ||
864 | goto out; | ||
865 | |||
866 | priv->curbssparams.channel = cmd.channel; | ||
867 | lbs_deb_cmd("channel switch from %d to %d\n", old_channel, cmd.channel); | ||
868 | |||
869 | out: | ||
870 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
871 | return ret; | ||
832 | } | 872 | } |
833 | 873 | ||
834 | static int lbs_cmd_802_11_rssi(struct lbs_private *priv, | 874 | 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 | ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); | 1430 | ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); |
1391 | break; | 1431 | break; |
1392 | 1432 | ||
1393 | case CMD_802_11_RF_CHANNEL: | ||
1394 | ret = lbs_cmd_802_11_rf_channel(priv, cmdptr, | ||
1395 | cmd_action, pdata_buf); | ||
1396 | break; | ||
1397 | |||
1398 | case CMD_802_11_RF_TX_POWER: | 1433 | case CMD_802_11_RF_TX_POWER: |
1399 | ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr, | 1434 | ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr, |
1400 | cmd_action, pdata_buf); | 1435 | cmd_action, pdata_buf); |
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index 4bd6f56281f6..5b02d73c8a0e 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h | |||
@@ -30,4 +30,7 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, | |||
30 | int lbs_get_data_rate(struct lbs_private *priv); | 30 | int lbs_get_data_rate(struct lbs_private *priv); |
31 | int lbs_set_data_rate(struct lbs_private *priv, u8 rate); | 31 | int lbs_set_data_rate(struct lbs_private *priv, u8 rate); |
32 | 32 | ||
33 | int lbs_get_channel(struct lbs_private *priv); | ||
34 | int lbs_set_channel(struct lbs_private *priv, u8 channel); | ||
35 | |||
33 | #endif /* _LBS_CMD_H */ | 36 | #endif /* _LBS_CMD_H */ |
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 797c943457eb..bf9941ecc239 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -325,28 +325,6 @@ static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv, | |||
325 | return 0; | 325 | return 0; |
326 | } | 326 | } |
327 | 327 | ||
328 | static int lbs_ret_802_11_rf_channel(struct lbs_private *priv, | ||
329 | struct cmd_ds_command *resp) | ||
330 | { | ||
331 | struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel; | ||
332 | u16 action = le16_to_cpu(rfchannel->action); | ||
333 | u16 newchannel = le16_to_cpu(rfchannel->currentchannel); | ||
334 | |||
335 | lbs_deb_enter(LBS_DEB_CMD); | ||
336 | |||
337 | if (action == CMD_OPT_802_11_RF_CHANNEL_GET | ||
338 | && priv->curbssparams.channel != newchannel) { | ||
339 | lbs_deb_cmd("channel switch from %d to %d\n", | ||
340 | priv->curbssparams.channel, newchannel); | ||
341 | |||
342 | /* Update the channel again */ | ||
343 | priv->curbssparams.channel = newchannel; | ||
344 | } | ||
345 | |||
346 | lbs_deb_enter(LBS_DEB_CMD); | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int lbs_ret_802_11_rssi(struct lbs_private *priv, | 328 | static int lbs_ret_802_11_rssi(struct lbs_private *priv, |
351 | struct cmd_ds_command *resp) | 329 | struct cmd_ds_command *resp) |
352 | { | 330 | { |
@@ -548,9 +526,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, | |||
548 | case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET): | 526 | case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET): |
549 | ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp); | 527 | ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp); |
550 | break; | 528 | break; |
551 | case CMD_RET(CMD_802_11_RF_CHANNEL): | ||
552 | ret = lbs_ret_802_11_rf_channel(priv, resp); | ||
553 | break; | ||
554 | 529 | ||
555 | case CMD_RET(CMD_802_11_RSSI): | 530 | case CMD_RET(CMD_802_11_RSSI): |
556 | ret = lbs_ret_802_11_rssi(priv, resp); | 531 | ret = lbs_ret_802_11_rssi(priv, resp); |
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index d51010c47b5b..7acb65116678 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h | |||
@@ -386,11 +386,13 @@ struct cmd_ds_802_11_inactivity_timeout { | |||
386 | }; | 386 | }; |
387 | 387 | ||
388 | struct cmd_ds_802_11_rf_channel { | 388 | struct cmd_ds_802_11_rf_channel { |
389 | struct cmd_header hdr; | ||
390 | |||
389 | __le16 action; | 391 | __le16 action; |
390 | __le16 currentchannel; | 392 | __le16 channel; |
391 | __le16 rftype; | 393 | __le16 rftype; /* unused */ |
392 | __le16 reserved; | 394 | __le16 reserved; /* unused */ |
393 | u8 channellist[32]; | 395 | u8 channellist[32]; /* unused */ |
394 | }; | 396 | }; |
395 | 397 | ||
396 | struct cmd_ds_802_11_rssi { | 398 | struct cmd_ds_802_11_rssi { |