aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r--drivers/net/wireless/libertas/cmd.c538
1 files changed, 211 insertions, 327 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index b3c1acbcc655..6328b9593877 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -4,19 +4,57 @@
4 */ 4 */
5 5
6#include <net/iw_handler.h> 6#include <net/iw_handler.h>
7#include <linux/kfifo.h>
7#include "host.h" 8#include "host.h"
8#include "hostcmd.h" 9#include "hostcmd.h"
9#include "decl.h" 10#include "decl.h"
10#include "defs.h" 11#include "defs.h"
11#include "dev.h" 12#include "dev.h"
12#include "join.h" 13#include "assoc.h"
13#include "wext.h" 14#include "wext.h"
14#include "cmd.h" 15#include "cmd.h"
15 16
16static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); 17static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
17static void lbs_set_cmd_ctrl_node(struct lbs_private *priv, 18
18 struct cmd_ctrl_node *ptempnode, 19
19 void *pdata_buf); 20/**
21 * @brief Simple callback that copies response back into command
22 *
23 * @param priv A pointer to struct lbs_private structure
24 * @param extra A pointer to the original command structure for which
25 * 'resp' is a response
26 * @param resp A pointer to the command response
27 *
28 * @return 0 on success, error on failure
29 */
30int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
31 struct cmd_header *resp)
32{
33 struct cmd_header *buf = (void *)extra;
34 uint16_t copy_len;
35
36 copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
37 memcpy(buf, resp, copy_len);
38 return 0;
39}
40EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
41
42/**
43 * @brief Simple callback that ignores the result. Use this if
44 * you just want to send a command to the hardware, but don't
45 * care for the result.
46 *
47 * @param priv ignored
48 * @param extra ignored
49 * @param resp ignored
50 *
51 * @return 0 for success
52 */
53static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
54 struct cmd_header *resp)
55{
56 return 0;
57}
20 58
21 59
22/** 60/**
@@ -143,8 +181,7 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
143} 181}
144EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); 182EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
145 183
146static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv, 184static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd,
147 struct cmd_ds_command *cmd,
148 u16 cmd_action) 185 u16 cmd_action)
149{ 186{
150 struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode; 187 struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
@@ -259,6 +296,7 @@ int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
259 296
260 lbs_deb_enter(LBS_DEB_CMD); 297 lbs_deb_enter(LBS_DEB_CMD);
261 298
299 memset(&cmd, 0, sizeof(cmd));
262 cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP); 300 cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP);
263 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 301 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
264 302
@@ -322,7 +360,9 @@ int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
322 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 360 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
323 cmd.action = cpu_to_le16(cmd_action); 361 cmd.action = cpu_to_le16(cmd_action);
324 362
325 if (cmd_action == CMD_ACT_SET) { 363 if (cmd_action == CMD_ACT_GET)
364 cmd.enable = 0;
365 else {
326 if (*enable) 366 if (*enable)
327 cmd.enable = cpu_to_le16(CMD_ENABLE_RSN); 367 cmd.enable = cpu_to_le16(CMD_ENABLE_RSN);
328 else 368 else
@@ -338,81 +378,108 @@ int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
338 return ret; 378 return ret;
339} 379}
340 380
341static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, 381static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam,
342 struct enc_key * pkey) 382 struct enc_key *key)
343{ 383{
344 lbs_deb_enter(LBS_DEB_CMD); 384 lbs_deb_enter(LBS_DEB_CMD);
345 385
346 if (pkey->flags & KEY_INFO_WPA_ENABLED) { 386 if (key->flags & KEY_INFO_WPA_ENABLED)
347 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); 387 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
348 } 388 if (key->flags & KEY_INFO_WPA_UNICAST)
349 if (pkey->flags & KEY_INFO_WPA_UNICAST) { 389 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
350 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); 390 if (key->flags & KEY_INFO_WPA_MCAST)
351 } 391 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
352 if (pkey->flags & KEY_INFO_WPA_MCAST) {
353 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
354 }
355 392
356 pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); 393 keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
357 pkeyparamset->keytypeid = cpu_to_le16(pkey->type); 394 keyparam->keytypeid = cpu_to_le16(key->type);
358 pkeyparamset->keylen = cpu_to_le16(pkey->len); 395 keyparam->keylen = cpu_to_le16(key->len);
359 memcpy(pkeyparamset->key, pkey->key, pkey->len); 396 memcpy(keyparam->key, key->key, key->len);
360 pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid) 397
361 + sizeof(pkeyparamset->keyinfo) 398 /* Length field doesn't include the {type,length} header */
362 + sizeof(pkeyparamset->keylen) 399 keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4);
363 + sizeof(pkeyparamset->key));
364 lbs_deb_leave(LBS_DEB_CMD); 400 lbs_deb_leave(LBS_DEB_CMD);
365} 401}
366 402
367static int lbs_cmd_802_11_key_material(struct lbs_private *priv, 403int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
368 struct cmd_ds_command *cmd, 404 struct assoc_request *assoc)
369 u16 cmd_action,
370 u32 cmd_oid, void *pdata_buf)
371{ 405{
372 struct cmd_ds_802_11_key_material *pkeymaterial = 406 struct cmd_ds_802_11_key_material cmd;
373 &cmd->params.keymaterial;
374 struct assoc_request * assoc_req = pdata_buf;
375 int ret = 0; 407 int ret = 0;
376 int index = 0; 408 int index = 0;
377 409
378 lbs_deb_enter(LBS_DEB_CMD); 410 lbs_deb_enter(LBS_DEB_CMD);
379 411
380 cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL); 412 cmd.action = cpu_to_le16(cmd_action);
381 pkeymaterial->action = cpu_to_le16(cmd_action); 413 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
382 414
383 if (cmd_action == CMD_ACT_GET) { 415 if (cmd_action == CMD_ACT_GET) {
384 cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); 416 cmd.hdr.size = cpu_to_le16(S_DS_GEN + 2);
385 ret = 0; 417 } else {
386 goto done; 418 memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet));
387 }
388 419
389 memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet)); 420 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) {
421 set_one_wpa_key(&cmd.keyParamSet[index],
422 &assoc->wpa_unicast_key);
423 index++;
424 }
390 425
391 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 426 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) {
392 set_one_wpa_key(&pkeymaterial->keyParamSet[index], 427 set_one_wpa_key(&cmd.keyParamSet[index],
393 &assoc_req->wpa_unicast_key); 428 &assoc->wpa_mcast_key);
394 index++; 429 index++;
395 } 430 }
396 431
397 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { 432 /* The common header and as many keys as we included */
398 set_one_wpa_key(&pkeymaterial->keyParamSet[index], 433 cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd),
399 &assoc_req->wpa_mcast_key); 434 keyParamSet[index]));
400 index++;
401 } 435 }
436 ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
437 /* Copy the returned key to driver private data */
438 if (!ret && cmd_action == CMD_ACT_GET) {
439 void *buf_ptr = cmd.keyParamSet;
440 void *resp_end = &(&cmd)[1];
441
442 while (buf_ptr < resp_end) {
443 struct MrvlIEtype_keyParamSet *keyparam = buf_ptr;
444 struct enc_key *key;
445 uint16_t param_set_len = le16_to_cpu(keyparam->length);
446 uint16_t key_len = le16_to_cpu(keyparam->keylen);
447 uint16_t key_flags = le16_to_cpu(keyparam->keyinfo);
448 uint16_t key_type = le16_to_cpu(keyparam->keytypeid);
449 void *end;
450
451 end = (void *)keyparam + sizeof(keyparam->type)
452 + sizeof(keyparam->length) + param_set_len;
453
454 /* Make sure we don't access past the end of the IEs */
455 if (end > resp_end)
456 break;
457
458 if (key_flags & KEY_INFO_WPA_UNICAST)
459 key = &priv->wpa_unicast_key;
460 else if (key_flags & KEY_INFO_WPA_MCAST)
461 key = &priv->wpa_mcast_key;
462 else
463 break;
402 464
403 cmd->size = cpu_to_le16( S_DS_GEN 465 /* Copy returned key into driver */
404 + sizeof (pkeymaterial->action) 466 memset(key, 0, sizeof(struct enc_key));
405 + (index * sizeof(struct MrvlIEtype_keyParamSet))); 467 if (key_len > sizeof(key->key))
468 break;
469 key->type = key_type;
470 key->flags = key_flags;
471 key->len = key_len;
472 memcpy(key->key, keyparam->key, key->len);
406 473
407 ret = 0; 474 buf_ptr = end + 1;
475 }
476 }
408 477
409done:
410 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 478 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
411 return ret; 479 return ret;
412} 480}
413 481
414static int lbs_cmd_802_11_reset(struct lbs_private *priv, 482static int lbs_cmd_802_11_reset(struct cmd_ds_command *cmd, int cmd_action)
415 struct cmd_ds_command *cmd, int cmd_action)
416{ 483{
417 struct cmd_ds_802_11_reset *reset = &cmd->params.reset; 484 struct cmd_ds_802_11_reset *reset = &cmd->params.reset;
418 485
@@ -426,30 +493,6 @@ static int lbs_cmd_802_11_reset(struct lbs_private *priv,
426 return 0; 493 return 0;
427} 494}
428 495
429static int lbs_cmd_802_11_get_log(struct lbs_private *priv,
430 struct cmd_ds_command *cmd)
431{
432 lbs_deb_enter(LBS_DEB_CMD);
433 cmd->command = cpu_to_le16(CMD_802_11_GET_LOG);
434 cmd->size =
435 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN);
436
437 lbs_deb_leave(LBS_DEB_CMD);
438 return 0;
439}
440
441static int lbs_cmd_802_11_get_stat(struct lbs_private *priv,
442 struct cmd_ds_command *cmd)
443{
444 lbs_deb_enter(LBS_DEB_CMD);
445 cmd->command = cpu_to_le16(CMD_802_11_GET_STAT);
446 cmd->size =
447 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN);
448
449 lbs_deb_leave(LBS_DEB_CMD);
450 return 0;
451}
452
453static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv, 496static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
454 struct cmd_ds_command *cmd, 497 struct cmd_ds_command *cmd,
455 int cmd_action, 498 int cmd_action,
@@ -570,8 +613,7 @@ static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
570 return 0; 613 return 0;
571} 614}
572 615
573static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv, 616static int lbs_cmd_802_11_rf_tx_power(struct cmd_ds_command *cmd,
574 struct cmd_ds_command *cmd,
575 u16 cmd_action, void *pdata_buf) 617 u16 cmd_action, void *pdata_buf)
576{ 618{
577 619
@@ -614,8 +656,7 @@ static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv,
614 return 0; 656 return 0;
615} 657}
616 658
617static int lbs_cmd_802_11_monitor_mode(struct lbs_private *priv, 659static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd,
618 struct cmd_ds_command *cmd,
619 u16 cmd_action, void *pdata_buf) 660 u16 cmd_action, void *pdata_buf)
620{ 661{
621 struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor; 662 struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor;
@@ -773,6 +814,7 @@ int lbs_get_channel(struct lbs_private *priv)
773 814
774 lbs_deb_enter(LBS_DEB_CMD); 815 lbs_deb_enter(LBS_DEB_CMD);
775 816
817 memset(&cmd, 0, sizeof(cmd));
776 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 818 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
777 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET); 819 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
778 820
@@ -788,6 +830,22 @@ out:
788 return ret; 830 return ret;
789} 831}
790 832
833int lbs_update_channel(struct lbs_private *priv)
834{
835 int ret;
836
837 /* the channel in f/w could be out of sync; get the current channel */
838 lbs_deb_enter(LBS_DEB_ASSOC);
839
840 ret = lbs_get_channel(priv);
841 if (ret > 0) {
842 priv->curbssparams.channel = ret;
843 ret = 0;
844 }
845 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
846 return ret;
847}
848
791/** 849/**
792 * @brief Set the radio channel 850 * @brief Set the radio channel
793 * 851 *
@@ -804,6 +862,7 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel)
804 862
805 lbs_deb_enter(LBS_DEB_CMD); 863 lbs_deb_enter(LBS_DEB_CMD);
806 864
865 memset(&cmd, 0, sizeof(cmd));
807 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 866 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
808 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); 867 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
809 cmd.channel = cpu_to_le16(channel); 868 cmd.channel = cpu_to_le16(channel);
@@ -842,8 +901,7 @@ static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
842 return 0; 901 return 0;
843} 902}
844 903
845static int lbs_cmd_reg_access(struct lbs_private *priv, 904static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr,
846 struct cmd_ds_command *cmdptr,
847 u8 cmd_action, void *pdata_buf) 905 u8 cmd_action, void *pdata_buf)
848{ 906{
849 struct lbs_offset_value *offval; 907 struct lbs_offset_value *offval;
@@ -917,53 +975,7 @@ static int lbs_cmd_reg_access(struct lbs_private *priv,
917 return 0; 975 return 0;
918} 976}
919 977
920static int lbs_cmd_802_11_mac_address(struct lbs_private *priv, 978static int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
921 struct cmd_ds_command *cmd,
922 u16 cmd_action)
923{
924
925 lbs_deb_enter(LBS_DEB_CMD);
926 cmd->command = cpu_to_le16(CMD_802_11_MAC_ADDRESS);
927 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
928 S_DS_GEN);
929 cmd->result = 0;
930
931 cmd->params.macadd.action = cpu_to_le16(cmd_action);
932
933 if (cmd_action == CMD_ACT_SET) {
934 memcpy(cmd->params.macadd.macadd,
935 priv->current_addr, ETH_ALEN);
936 lbs_deb_hex(LBS_DEB_CMD, "SET_CMD: MAC addr", priv->current_addr, 6);
937 }
938
939 lbs_deb_leave(LBS_DEB_CMD);
940 return 0;
941}
942
943static int lbs_cmd_802_11_eeprom_access(struct lbs_private *priv,
944 struct cmd_ds_command *cmd,
945 int cmd_action, void *pdata_buf)
946{
947 struct lbs_ioctl_regrdwr *ea = pdata_buf;
948
949 lbs_deb_enter(LBS_DEB_CMD);
950
951 cmd->command = cpu_to_le16(CMD_802_11_EEPROM_ACCESS);
952 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
953 S_DS_GEN);
954 cmd->result = 0;
955
956 cmd->params.rdeeprom.action = cpu_to_le16(ea->action);
957 cmd->params.rdeeprom.offset = cpu_to_le16(ea->offset);
958 cmd->params.rdeeprom.bytecount = cpu_to_le16(ea->NOB);
959 cmd->params.rdeeprom.value = 0;
960
961 lbs_deb_leave(LBS_DEB_CMD);
962 return 0;
963}
964
965static int lbs_cmd_bt_access(struct lbs_private *priv,
966 struct cmd_ds_command *cmd,
967 u16 cmd_action, void *pdata_buf) 979 u16 cmd_action, void *pdata_buf)
968{ 980{
969 struct cmd_ds_bt_access *bt_access = &cmd->params.bt; 981 struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
@@ -1000,8 +1012,7 @@ static int lbs_cmd_bt_access(struct lbs_private *priv,
1000 return 0; 1012 return 0;
1001} 1013}
1002 1014
1003static int lbs_cmd_fwt_access(struct lbs_private *priv, 1015static int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
1004 struct cmd_ds_command *cmd,
1005 u16 cmd_action, void *pdata_buf) 1016 u16 cmd_action, void *pdata_buf)
1006{ 1017{
1007 struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; 1018 struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
@@ -1153,9 +1164,9 @@ static void lbs_submit_command(struct lbs_private *priv,
1153 command == CMD_802_11_AUTHENTICATE) 1164 command == CMD_802_11_AUTHENTICATE)
1154 timeo = 10 * HZ; 1165 timeo = 10 * HZ;
1155 1166
1156 lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n", 1167 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
1157 command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies); 1168 command, le16_to_cpu(cmd->seqnum), cmdsize);
1158 lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); 1169 lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
1159 1170
1160 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); 1171 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
1161 1172
@@ -1164,9 +1175,7 @@ static void lbs_submit_command(struct lbs_private *priv,
1164 /* Let the timer kick in and retry, and potentially reset 1175 /* Let the timer kick in and retry, and potentially reset
1165 the whole thing if the condition persists */ 1176 the whole thing if the condition persists */
1166 timeo = HZ; 1177 timeo = HZ;
1167 } else 1178 }
1168 lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n",
1169 command, jiffies);
1170 1179
1171 /* Setup the timer after transmit command */ 1180 /* Setup the timer after transmit command */
1172 mod_timer(&priv->command_timer, jiffies + timeo); 1181 mod_timer(&priv->command_timer, jiffies + timeo);
@@ -1174,24 +1183,6 @@ static void lbs_submit_command(struct lbs_private *priv,
1174 lbs_deb_leave(LBS_DEB_HOST); 1183 lbs_deb_leave(LBS_DEB_HOST);
1175} 1184}
1176 1185
1177static int lbs_cmd_mac_control(struct lbs_private *priv,
1178 struct cmd_ds_command *cmd)
1179{
1180 struct cmd_ds_mac_control *mac = &cmd->params.macctrl;
1181
1182 lbs_deb_enter(LBS_DEB_CMD);
1183
1184 cmd->command = cpu_to_le16(CMD_MAC_CONTROL);
1185 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
1186 mac->action = cpu_to_le16(priv->currentpacketfilter);
1187
1188 lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n",
1189 le16_to_cpu(mac->action), le16_to_cpu(cmd->size));
1190
1191 lbs_deb_leave(LBS_DEB_CMD);
1192 return 0;
1193}
1194
1195/** 1186/**
1196 * This function inserts command node to cmdfreeq 1187 * This function inserts command node to cmdfreeq
1197 * after cleans it. Requires priv->driver_lock held. 1188 * after cleans it. Requires priv->driver_lock held.
@@ -1234,7 +1225,7 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1234 cmd->cmdwaitqwoken = 1; 1225 cmd->cmdwaitqwoken = 1;
1235 wake_up_interruptible(&cmd->cmdwait_q); 1226 wake_up_interruptible(&cmd->cmdwait_q);
1236 1227
1237 if (!cmd->callback) 1228 if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
1238 __lbs_cleanup_and_insert_cmd(priv, cmd); 1229 __lbs_cleanup_and_insert_cmd(priv, cmd);
1239 priv->cur_cmd = NULL; 1230 priv->cur_cmd = NULL;
1240} 1231}
@@ -1278,18 +1269,20 @@ int lbs_set_radio_control(struct lbs_private *priv)
1278 return ret; 1269 return ret;
1279} 1270}
1280 1271
1281int lbs_set_mac_packet_filter(struct lbs_private *priv) 1272void lbs_set_mac_control(struct lbs_private *priv)
1282{ 1273{
1283 int ret = 0; 1274 struct cmd_ds_mac_control cmd;
1284 1275
1285 lbs_deb_enter(LBS_DEB_CMD); 1276 lbs_deb_enter(LBS_DEB_CMD);
1286 1277
1287 /* Send MAC control command to station */ 1278 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1288 ret = lbs_prepare_and_send_command(priv, 1279 cmd.action = cpu_to_le16(priv->mac_control);
1289 CMD_MAC_CONTROL, 0, 0, 0, NULL); 1280 cmd.reserved = 0;
1290 1281
1291 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 1282 lbs_cmd_async(priv, CMD_MAC_CONTROL,
1292 return ret; 1283 &cmd.hdr, sizeof(cmd));
1284
1285 lbs_deb_leave(LBS_DEB_CMD);
1293} 1286}
1294 1287
1295/** 1288/**
@@ -1338,7 +1331,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1338 goto done; 1331 goto done;
1339 } 1332 }
1340 1333
1341 lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf); 1334 cmdnode->callback = NULL;
1335 cmdnode->callback_arg = (unsigned long)pdata_buf;
1342 1336
1343 cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf; 1337 cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
1344 1338
@@ -1353,15 +1347,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1353 1347
1354 switch (cmd_no) { 1348 switch (cmd_no) {
1355 case CMD_802_11_PS_MODE: 1349 case CMD_802_11_PS_MODE:
1356 ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action); 1350 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
1357 break;
1358
1359 case CMD_802_11_SCAN:
1360 ret = lbs_cmd_80211_scan(priv, cmdptr, pdata_buf);
1361 break;
1362
1363 case CMD_MAC_CONTROL:
1364 ret = lbs_cmd_mac_control(priv, cmdptr);
1365 break; 1351 break;
1366 1352
1367 case CMD_802_11_ASSOCIATE: 1353 case CMD_802_11_ASSOCIATE:
@@ -1376,25 +1362,15 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1376 case CMD_802_11_AD_HOC_START: 1362 case CMD_802_11_AD_HOC_START:
1377 ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf); 1363 ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
1378 break; 1364 break;
1379 case CMD_CODE_DNLD:
1380 break;
1381 1365
1382 case CMD_802_11_RESET: 1366 case CMD_802_11_RESET:
1383 ret = lbs_cmd_802_11_reset(priv, cmdptr, cmd_action); 1367 ret = lbs_cmd_802_11_reset(cmdptr, cmd_action);
1384 break;
1385
1386 case CMD_802_11_GET_LOG:
1387 ret = lbs_cmd_802_11_get_log(priv, cmdptr);
1388 break; 1368 break;
1389 1369
1390 case CMD_802_11_AUTHENTICATE: 1370 case CMD_802_11_AUTHENTICATE:
1391 ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf); 1371 ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
1392 break; 1372 break;
1393 1373
1394 case CMD_802_11_GET_STAT:
1395 ret = lbs_cmd_802_11_get_stat(priv, cmdptr);
1396 break;
1397
1398 case CMD_802_11_SNMP_MIB: 1374 case CMD_802_11_SNMP_MIB:
1399 ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr, 1375 ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr,
1400 cmd_action, cmd_oid, pdata_buf); 1376 cmd_action, cmd_oid, pdata_buf);
@@ -1403,12 +1379,12 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1403 case CMD_MAC_REG_ACCESS: 1379 case CMD_MAC_REG_ACCESS:
1404 case CMD_BBP_REG_ACCESS: 1380 case CMD_BBP_REG_ACCESS:
1405 case CMD_RF_REG_ACCESS: 1381 case CMD_RF_REG_ACCESS:
1406 ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); 1382 ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf);
1407 break; 1383 break;
1408 1384
1409 case CMD_802_11_RF_TX_POWER: 1385 case CMD_802_11_RF_TX_POWER:
1410 ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr, 1386 ret = lbs_cmd_802_11_rf_tx_power(cmdptr,
1411 cmd_action, pdata_buf); 1387 cmd_action, pdata_buf);
1412 break; 1388 break;
1413 1389
1414 case CMD_802_11_RATE_ADAPT_RATESET: 1390 case CMD_802_11_RATE_ADAPT_RATESET:
@@ -1421,7 +1397,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1421 break; 1397 break;
1422 1398
1423 case CMD_802_11_MONITOR_MODE: 1399 case CMD_802_11_MONITOR_MODE:
1424 ret = lbs_cmd_802_11_monitor_mode(priv, cmdptr, 1400 ret = lbs_cmd_802_11_monitor_mode(cmdptr,
1425 cmd_action, pdata_buf); 1401 cmd_action, pdata_buf);
1426 break; 1402 break;
1427 1403
@@ -1434,26 +1410,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1434 break; 1410 break;
1435 1411
1436 case CMD_802_11_AD_HOC_STOP: 1412 case CMD_802_11_AD_HOC_STOP:
1437 ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr); 1413 ret = lbs_cmd_80211_ad_hoc_stop(cmdptr);
1438 break;
1439
1440 case CMD_802_11_KEY_MATERIAL:
1441 ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action,
1442 cmd_oid, pdata_buf);
1443 break;
1444
1445 case CMD_802_11_PAIRWISE_TSC:
1446 break;
1447 case CMD_802_11_GROUP_TSC:
1448 break;
1449
1450 case CMD_802_11_MAC_ADDRESS:
1451 ret = lbs_cmd_802_11_mac_address(priv, cmdptr, cmd_action);
1452 break;
1453
1454 case CMD_802_11_EEPROM_ACCESS:
1455 ret = lbs_cmd_802_11_eeprom_access(priv, cmdptr,
1456 cmd_action, pdata_buf);
1457 break; 1414 break;
1458 1415
1459 case CMD_802_11_SET_AFC: 1416 case CMD_802_11_SET_AFC:
@@ -1509,22 +1466,12 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1509 break; 1466 break;
1510 } 1467 }
1511 1468
1512 case CMD_802_11_PWR_CFG:
1513 cmdptr->command = cpu_to_le16(CMD_802_11_PWR_CFG);
1514 cmdptr->size =
1515 cpu_to_le16(sizeof(struct cmd_ds_802_11_pwr_cfg) +
1516 S_DS_GEN);
1517 memmove(&cmdptr->params.pwrcfg, pdata_buf,
1518 sizeof(struct cmd_ds_802_11_pwr_cfg));
1519
1520 ret = 0;
1521 break;
1522 case CMD_BT_ACCESS: 1469 case CMD_BT_ACCESS:
1523 ret = lbs_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf); 1470 ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf);
1524 break; 1471 break;
1525 1472
1526 case CMD_FWT_ACCESS: 1473 case CMD_FWT_ACCESS:
1527 ret = lbs_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf); 1474 ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf);
1528 break; 1475 break;
1529 1476
1530 case CMD_GET_TSF: 1477 case CMD_GET_TSF:
@@ -1697,36 +1644,6 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
1697} 1644}
1698 1645
1699/** 1646/**
1700 * @brief This function cleans command node.
1701 *
1702 * @param ptempnode A pointer to cmdCtrlNode structure
1703 * @return n/a
1704 */
1705
1706/**
1707 * @brief This function initializes the command node.
1708 *
1709 * @param priv A pointer to struct lbs_private structure
1710 * @param ptempnode A pointer to cmd_ctrl_node structure
1711 * @param pdata_buf A pointer to informaion buffer
1712 * @return 0 or -1
1713 */
1714static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
1715 struct cmd_ctrl_node *ptempnode,
1716 void *pdata_buf)
1717{
1718 lbs_deb_enter(LBS_DEB_HOST);
1719
1720 if (!ptempnode)
1721 return;
1722
1723 ptempnode->callback = NULL;
1724 ptempnode->callback_arg = (unsigned long)pdata_buf;
1725
1726 lbs_deb_leave(LBS_DEB_HOST);
1727}
1728
1729/**
1730 * @brief This function executes next command in command 1647 * @brief This function executes next command in command
1731 * pending queue. It will put fimware back to PS mode 1648 * pending queue. It will put fimware back to PS mode
1732 * if applicable. 1649 * if applicable.
@@ -1741,9 +1658,9 @@ int lbs_execute_next_command(struct lbs_private *priv)
1741 unsigned long flags; 1658 unsigned long flags;
1742 int ret = 0; 1659 int ret = 0;
1743 1660
1744 // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the 1661 /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
1745 // only caller to us is lbs_thread() and we get even when a 1662 * only caller to us is lbs_thread() and we get even when a
1746 // data packet is received 1663 * data packet is received */
1747 lbs_deb_enter(LBS_DEB_THREAD); 1664 lbs_deb_enter(LBS_DEB_THREAD);
1748 1665
1749 spin_lock_irqsave(&priv->driver_lock, flags); 1666 spin_lock_irqsave(&priv->driver_lock, flags);
@@ -1907,44 +1824,32 @@ void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str)
1907 lbs_deb_leave(LBS_DEB_WEXT); 1824 lbs_deb_leave(LBS_DEB_WEXT);
1908} 1825}
1909 1826
1910static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size) 1827static void lbs_send_confirmsleep(struct lbs_private *priv)
1911{ 1828{
1912 unsigned long flags; 1829 unsigned long flags;
1913 int ret = 0; 1830 int ret;
1914 1831
1915 lbs_deb_enter(LBS_DEB_HOST); 1832 lbs_deb_enter(LBS_DEB_HOST);
1833 lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep,
1834 sizeof(confirm_sleep));
1916 1835
1917 lbs_deb_host("SEND_SLEEPC_CMD: before download, cmd size %d\n", 1836 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
1918 size); 1837 sizeof(confirm_sleep));
1919 1838 if (ret) {
1920 lbs_deb_hex(LBS_DEB_HOST, "sleep confirm command", cmdptr, size); 1839 lbs_pr_alert("confirm_sleep failed\n");
1921 1840 goto out;
1922 ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size); 1841 }
1923 1842
1924 spin_lock_irqsave(&priv->driver_lock, flags); 1843 spin_lock_irqsave(&priv->driver_lock, flags);
1925 if (priv->intcounter || priv->currenttxskb)
1926 lbs_deb_host("SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p\n",
1927 priv->intcounter, priv->currenttxskb);
1928 spin_unlock_irqrestore(&priv->driver_lock, flags);
1929 1844
1930 if (ret) { 1845 /* If nothing to do, go back to sleep (?) */
1931 lbs_pr_alert( 1846 if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx])
1932 "SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep\n"); 1847 priv->psstate = PS_STATE_SLEEP;
1933 } else {
1934 spin_lock_irqsave(&priv->driver_lock, flags);
1935 if (!priv->intcounter) {
1936 priv->psstate = PS_STATE_SLEEP;
1937 } else {
1938 lbs_deb_host("SEND_SLEEPC_CMD: after sent, intcounter %d\n",
1939 priv->intcounter);
1940 }
1941 spin_unlock_irqrestore(&priv->driver_lock, flags);
1942 1848
1943 lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n"); 1849 spin_unlock_irqrestore(&priv->driver_lock, flags);
1944 }
1945 1850
1946 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); 1851out:
1947 return ret; 1852 lbs_deb_leave(LBS_DEB_HOST);
1948} 1853}
1949 1854
1950void lbs_ps_sleep(struct lbs_private *priv, int wait_option) 1855void lbs_ps_sleep(struct lbs_private *priv, int wait_option)
@@ -1992,10 +1897,10 @@ void lbs_ps_wakeup(struct lbs_private *priv, int wait_option)
1992 * @param psmode Power Saving mode 1897 * @param psmode Power Saving mode
1993 * @return n/a 1898 * @return n/a
1994 */ 1899 */
1995void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode) 1900void lbs_ps_confirm_sleep(struct lbs_private *priv)
1996{ 1901{
1997 unsigned long flags =0; 1902 unsigned long flags =0;
1998 u8 allowed = 1; 1903 int allowed = 1;
1999 1904
2000 lbs_deb_enter(LBS_DEB_HOST); 1905 lbs_deb_enter(LBS_DEB_HOST);
2001 1906
@@ -2005,20 +1910,22 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
2005 } 1910 }
2006 1911
2007 spin_lock_irqsave(&priv->driver_lock, flags); 1912 spin_lock_irqsave(&priv->driver_lock, flags);
1913 /* In-progress command? */
2008 if (priv->cur_cmd) { 1914 if (priv->cur_cmd) {
2009 allowed = 0; 1915 allowed = 0;
2010 lbs_deb_host("cur_cmd was set\n"); 1916 lbs_deb_host("cur_cmd was set\n");
2011 } 1917 }
2012 if (priv->intcounter > 0) { 1918
1919 /* Pending events or command responses? */
1920 if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
2013 allowed = 0; 1921 allowed = 0;
2014 lbs_deb_host("intcounter %d\n", priv->intcounter); 1922 lbs_deb_host("pending events or command responses\n");
2015 } 1923 }
2016 spin_unlock_irqrestore(&priv->driver_lock, flags); 1924 spin_unlock_irqrestore(&priv->driver_lock, flags);
2017 1925
2018 if (allowed) { 1926 if (allowed) {
2019 lbs_deb_host("sending lbs_ps_confirm_sleep\n"); 1927 lbs_deb_host("sending lbs_ps_confirm_sleep\n");
2020 sendconfirmsleep(priv, (u8 *) & priv->lbs_ps_confirm_sleep, 1928 lbs_send_confirmsleep(priv);
2021 sizeof(struct PS_CMD_ConfirmSleep));
2022 } else { 1929 } else {
2023 lbs_deb_host("sleep confirm has been delayed\n"); 1930 lbs_deb_host("sleep confirm has been delayed\n");
2024 } 1931 }
@@ -2027,39 +1934,10 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
2027} 1934}
2028 1935
2029 1936
2030/** 1937static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
2031 * @brief Simple callback that copies response back into command 1938 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
2032 * 1939 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
2033 * @param priv A pointer to struct lbs_private structure 1940 unsigned long callback_arg)
2034 * @param extra A pointer to the original command structure for which
2035 * 'resp' is a response
2036 * @param resp A pointer to the command response
2037 *
2038 * @return 0 on success, error on failure
2039 */
2040int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
2041 struct cmd_header *resp)
2042{
2043 struct cmd_header *buf = (void *)extra;
2044 uint16_t copy_len;
2045
2046 lbs_deb_enter(LBS_DEB_CMD);
2047
2048 copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
2049 lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, "
2050 "copy back buffer was %u bytes\n", copy_len,
2051 le16_to_cpu(resp->size), le16_to_cpu(buf->size));
2052 memcpy(buf, resp, copy_len);
2053
2054 lbs_deb_leave(LBS_DEB_CMD);
2055 return 0;
2056}
2057EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
2058
2059struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
2060 struct cmd_header *in_cmd, int in_cmd_size,
2061 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
2062 unsigned long callback_arg)
2063{ 1941{
2064 struct cmd_ctrl_node *cmdnode; 1942 struct cmd_ctrl_node *cmdnode;
2065 1943
@@ -2096,9 +1974,6 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command
2096 1974
2097 lbs_deb_host("PREP_CMD: command 0x%04x\n", command); 1975 lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
2098 1976
2099 /* here was the big old switch() statement, which is now obsolete,
2100 * because the caller of lbs_cmd() sets up all of *cmd for us. */
2101
2102 cmdnode->cmdwaitqwoken = 0; 1977 cmdnode->cmdwaitqwoken = 0;
2103 lbs_queue_cmd(priv, cmdnode); 1978 lbs_queue_cmd(priv, cmdnode);
2104 wake_up_interruptible(&priv->waitq); 1979 wake_up_interruptible(&priv->waitq);
@@ -2108,6 +1983,15 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command
2108 return cmdnode; 1983 return cmdnode;
2109} 1984}
2110 1985
1986void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
1987 struct cmd_header *in_cmd, int in_cmd_size)
1988{
1989 lbs_deb_enter(LBS_DEB_CMD);
1990 __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
1991 lbs_cmd_async_callback, 0);
1992 lbs_deb_leave(LBS_DEB_CMD);
1993}
1994
2111int __lbs_cmd(struct lbs_private *priv, uint16_t command, 1995int __lbs_cmd(struct lbs_private *priv, uint16_t command,
2112 struct cmd_header *in_cmd, int in_cmd_size, 1996 struct cmd_header *in_cmd, int in_cmd_size,
2113 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 1997 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),