diff options
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 538 |
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 | ||
16 | static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); | 17 | static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); |
17 | static 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 | */ | ||
30 | int 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 | } | ||
40 | EXPORT_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 | */ | ||
53 | static 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 | } |
144 | EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); | 182 | EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); |
145 | 183 | ||
146 | static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv, | 184 | static 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 | ||
341 | static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, | 381 | static 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 | ||
367 | static int lbs_cmd_802_11_key_material(struct lbs_private *priv, | 403 | int 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 | ||
409 | done: | ||
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 | ||
414 | static int lbs_cmd_802_11_reset(struct lbs_private *priv, | 482 | static 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 | ||
429 | static 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 | |||
441 | static 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 | |||
453 | static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv, | 496 | static 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 | ||
573 | static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv, | 616 | static 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 | ||
617 | static int lbs_cmd_802_11_monitor_mode(struct lbs_private *priv, | 659 | static 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 | ||
833 | int 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 | ||
845 | static int lbs_cmd_reg_access(struct lbs_private *priv, | 904 | static 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 | ||
920 | static int lbs_cmd_802_11_mac_address(struct lbs_private *priv, | 978 | static 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 | |||
943 | static 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 | |||
965 | static 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 | ||
1003 | static int lbs_cmd_fwt_access(struct lbs_private *priv, | 1015 | static 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 | ||
1177 | static 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 | ||
1281 | int lbs_set_mac_packet_filter(struct lbs_private *priv) | 1272 | void 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 | */ | ||
1714 | static 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 | ||
1910 | static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size) | 1827 | static 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); | 1851 | out: |
1947 | return ret; | 1852 | lbs_deb_leave(LBS_DEB_HOST); |
1948 | } | 1853 | } |
1949 | 1854 | ||
1950 | void lbs_ps_sleep(struct lbs_private *priv, int wait_option) | 1855 | void 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 | */ |
1995 | void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode) | 1900 | void 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 | /** | 1937 | static 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 | */ | ||
2040 | int 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 | } | ||
2057 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); | ||
2058 | |||
2059 | struct 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 | ||
1986 | void 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 | |||
2111 | int __lbs_cmd(struct lbs_private *priv, uint16_t command, | 1995 | int __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 *), |