aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/cmdevt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/cmdevt.c')
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c161
1 files changed, 111 insertions, 50 deletions
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 1ddc8b2e3722..1062c918a7bf 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -37,13 +37,12 @@
37static void 37static void
38mwifiex_init_cmd_node(struct mwifiex_private *priv, 38mwifiex_init_cmd_node(struct mwifiex_private *priv,
39 struct cmd_ctrl_node *cmd_node, 39 struct cmd_ctrl_node *cmd_node,
40 u32 cmd_oid, void *data_buf) 40 u32 cmd_oid, void *data_buf, bool sync)
41{ 41{
42 cmd_node->priv = priv; 42 cmd_node->priv = priv;
43 cmd_node->cmd_oid = cmd_oid; 43 cmd_node->cmd_oid = cmd_oid;
44 if (priv->adapter->cmd_wait_q_required) { 44 if (sync) {
45 cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; 45 cmd_node->wait_q_enabled = true;
46 priv->adapter->cmd_wait_q_required = false;
47 cmd_node->cmd_wait_q_woken = false; 46 cmd_node->cmd_wait_q_woken = false;
48 cmd_node->condition = &cmd_node->cmd_wait_q_woken; 47 cmd_node->condition = &cmd_node->cmd_wait_q_woken;
49 } 48 }
@@ -166,8 +165,10 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
166 dev_err(adapter->dev, 165 dev_err(adapter->dev,
167 "DNLD_CMD: FW in reset state, ignore cmd %#x\n", 166 "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
168 cmd_code); 167 cmd_code);
169 mwifiex_complete_cmd(adapter, cmd_node); 168 if (cmd_node->wait_q_enabled)
169 mwifiex_complete_cmd(adapter, cmd_node);
170 mwifiex_recycle_cmd_node(adapter, cmd_node); 170 mwifiex_recycle_cmd_node(adapter, cmd_node);
171 queue_work(adapter->workqueue, &adapter->main_work);
171 return -1; 172 return -1;
172 } 173 }
173 174
@@ -276,11 +277,11 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
276 277
277 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 278 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
278 279
280 adapter->seq_num++;
279 sleep_cfm_buf->seq_num = 281 sleep_cfm_buf->seq_num =
280 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO 282 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
281 (adapter->seq_num, priv->bss_num, 283 (adapter->seq_num, priv->bss_num,
282 priv->bss_type))); 284 priv->bss_type)));
283 adapter->seq_num++;
284 285
285 if (adapter->iface_type == MWIFIEX_USB) { 286 if (adapter->iface_type == MWIFIEX_USB) {
286 sleep_cfm_tmp = 287 sleep_cfm_tmp =
@@ -480,28 +481,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
480} 481}
481 482
482/* 483/*
483 * This function is used to send synchronous command to the firmware. 484 * This function prepares a command and send it to the firmware.
484 *
485 * it allocates a wait queue for the command and wait for the command
486 * response.
487 */
488int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
489 u16 cmd_action, u32 cmd_oid, void *data_buf)
490{
491 int ret = 0;
492 struct mwifiex_adapter *adapter = priv->adapter;
493
494 adapter->cmd_wait_q_required = true;
495
496 ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
497 data_buf);
498
499 return ret;
500}
501
502
503/*
504 * This function prepares a command and asynchronously send it to the firmware.
505 * 485 *
506 * Preparation includes - 486 * Preparation includes -
507 * - Sanity tests to make sure the card is still present or the FW 487 * - Sanity tests to make sure the card is still present or the FW
@@ -511,8 +491,8 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
511 * - Fill up the non-default parameters and buffer pointers 491 * - Fill up the non-default parameters and buffer pointers
512 * - Add the command to pending queue 492 * - Add the command to pending queue
513 */ 493 */
514int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 494int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
515 u16 cmd_action, u32 cmd_oid, void *data_buf) 495 u16 cmd_action, u32 cmd_oid, void *data_buf, bool sync)
516{ 496{
517 int ret; 497 int ret;
518 struct mwifiex_adapter *adapter = priv->adapter; 498 struct mwifiex_adapter *adapter = priv->adapter;
@@ -529,11 +509,21 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
529 return -1; 509 return -1;
530 } 510 }
531 511
512 if (adapter->hs_enabling && cmd_no != HostCmd_CMD_802_11_HS_CFG_ENH) {
513 dev_err(adapter->dev, "PREP_CMD: host entering sleep state\n");
514 return -1;
515 }
516
532 if (adapter->surprise_removed) { 517 if (adapter->surprise_removed) {
533 dev_err(adapter->dev, "PREP_CMD: card is removed\n"); 518 dev_err(adapter->dev, "PREP_CMD: card is removed\n");
534 return -1; 519 return -1;
535 } 520 }
536 521
522 if (adapter->is_cmd_timedout) {
523 dev_err(adapter->dev, "PREP_CMD: FW is in bad state\n");
524 return -1;
525 }
526
537 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) { 527 if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
538 if (cmd_no != HostCmd_CMD_FUNC_INIT) { 528 if (cmd_no != HostCmd_CMD_FUNC_INIT) {
539 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n"); 529 dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
@@ -550,7 +540,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
550 } 540 }
551 541
552 /* Initialize the command node */ 542 /* Initialize the command node */
553 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); 543 mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf, sync);
554 544
555 if (!cmd_node->cmd_skb) { 545 if (!cmd_node->cmd_skb) {
556 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); 546 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
@@ -595,7 +585,8 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
595 } 585 }
596 586
597 /* Send command */ 587 /* Send command */
598 if (cmd_no == HostCmd_CMD_802_11_SCAN) { 588 if (cmd_no == HostCmd_CMD_802_11_SCAN ||
589 cmd_no == HostCmd_CMD_802_11_SCAN_EXT) {
599 mwifiex_queue_scan_cmd(priv, cmd_node); 590 mwifiex_queue_scan_cmd(priv, cmd_node);
600 } else { 591 } else {
601 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); 592 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
@@ -785,7 +776,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
785 unsigned long flags; 776 unsigned long flags;
786 777
787 /* Now we got response from FW, cancel the command timer */ 778 /* Now we got response from FW, cancel the command timer */
788 del_timer(&adapter->cmd_timer); 779 del_timer_sync(&adapter->cmd_timer);
789 780
790 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { 781 if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
791 resp = (struct host_cmd_ds_command *) adapter->upld_buf; 782 resp = (struct host_cmd_ds_command *) adapter->upld_buf;
@@ -794,7 +785,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
794 return -1; 785 return -1;
795 } 786 }
796 787
797 adapter->num_cmd_timeout = 0; 788 adapter->is_cmd_timedout = 0;
798 789
799 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; 790 resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
800 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { 791 if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
@@ -905,8 +896,7 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
905 struct cmd_ctrl_node *cmd_node; 896 struct cmd_ctrl_node *cmd_node;
906 struct timeval tstamp; 897 struct timeval tstamp;
907 898
908 adapter->num_cmd_timeout++; 899 adapter->is_cmd_timedout = 1;
909 adapter->dbg.num_cmd_timeout++;
910 if (!adapter->curr_cmd) { 900 if (!adapter->curr_cmd) {
911 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n"); 901 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
912 return; 902 return;
@@ -929,8 +919,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
929 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", 919 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
930 adapter->dbg.num_cmd_host_to_card_failure); 920 adapter->dbg.num_cmd_host_to_card_failure);
931 921
932 dev_err(adapter->dev, "num_cmd_timeout = %d\n", 922 dev_err(adapter->dev, "is_cmd_timedout = %d\n",
933 adapter->dbg.num_cmd_timeout); 923 adapter->is_cmd_timedout);
934 dev_err(adapter->dev, "num_tx_timeout = %d\n", 924 dev_err(adapter->dev, "num_tx_timeout = %d\n",
935 adapter->dbg.num_tx_timeout); 925 adapter->dbg.num_tx_timeout);
936 926
@@ -987,13 +977,14 @@ void
987mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) 977mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
988{ 978{
989 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node; 979 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
990 unsigned long flags; 980 unsigned long flags, cmd_flags;
981 struct mwifiex_private *priv;
982 int i;
991 983
984 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
992 /* Cancel current cmd */ 985 /* Cancel current cmd */
993 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { 986 if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
994 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
995 adapter->curr_cmd->wait_q_enabled = false; 987 adapter->curr_cmd->wait_q_enabled = false;
996 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
997 adapter->cmd_wait_q.status = -1; 988 adapter->cmd_wait_q.status = -1;
998 mwifiex_complete_cmd(adapter, adapter->curr_cmd); 989 mwifiex_complete_cmd(adapter, adapter->curr_cmd);
999 } 990 }
@@ -1013,6 +1004,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1013 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); 1004 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
1014 } 1005 }
1015 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); 1006 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
1007 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1016 1008
1017 /* Cancel all pending scan command */ 1009 /* Cancel all pending scan command */
1018 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 1010 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
@@ -1027,9 +1019,21 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1027 } 1019 }
1028 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 1020 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1029 1021
1030 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 1022 if (adapter->scan_processing) {
1031 adapter->scan_processing = false; 1023 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1032 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 1024 adapter->scan_processing = false;
1025 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1026 for (i = 0; i < adapter->priv_num; i++) {
1027 priv = adapter->priv[i];
1028 if (!priv)
1029 continue;
1030 if (priv->scan_request) {
1031 dev_dbg(adapter->dev, "info: aborting scan\n");
1032 cfg80211_scan_done(priv->scan_request, 1);
1033 priv->scan_request = NULL;
1034 }
1035 }
1036 }
1033} 1037}
1034 1038
1035/* 1039/*
@@ -1048,7 +1052,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1048 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 1052 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
1049 unsigned long cmd_flags; 1053 unsigned long cmd_flags;
1050 unsigned long scan_pending_q_flags; 1054 unsigned long scan_pending_q_flags;
1051 bool cancel_scan_cmd = false; 1055 struct mwifiex_private *priv;
1056 int i;
1052 1057
1053 if ((adapter->curr_cmd) && 1058 if ((adapter->curr_cmd) &&
1054 (adapter->curr_cmd->wait_q_enabled)) { 1059 (adapter->curr_cmd->wait_q_enabled)) {
@@ -1074,15 +1079,24 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1074 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1079 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1075 spin_lock_irqsave(&adapter->scan_pending_q_lock, 1080 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1076 scan_pending_q_flags); 1081 scan_pending_q_flags);
1077 cancel_scan_cmd = true;
1078 } 1082 }
1079 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1083 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1080 scan_pending_q_flags); 1084 scan_pending_q_flags);
1081 1085
1082 if (cancel_scan_cmd) { 1086 if (adapter->scan_processing) {
1083 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); 1087 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
1084 adapter->scan_processing = false; 1088 adapter->scan_processing = false;
1085 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); 1089 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
1090 for (i = 0; i < adapter->priv_num; i++) {
1091 priv = adapter->priv[i];
1092 if (!priv)
1093 continue;
1094 if (priv->scan_request) {
1095 dev_dbg(adapter->dev, "info: aborting scan\n");
1096 cfg80211_scan_done(priv->scan_request, 1);
1097 priv->scan_request = NULL;
1098 }
1099 }
1086 } 1100 }
1087 adapter->cmd_wait_q.status = -1; 1101 adapter->cmd_wait_q.status = -1;
1088} 1102}
@@ -1454,7 +1468,10 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1454{ 1468{
1455 struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec; 1469 struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
1456 struct mwifiex_adapter *adapter = priv->adapter; 1470 struct mwifiex_adapter *adapter = priv->adapter;
1457 int i; 1471 struct mwifiex_ie_types_header *tlv;
1472 struct hw_spec_fw_api_rev *api_rev;
1473 u16 resp_size, api_id;
1474 int i, left_len, parsed_len = 0;
1458 1475
1459 adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info); 1476 adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info);
1460 1477
@@ -1490,6 +1507,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1490 } 1507 }
1491 1508
1492 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); 1509 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1510 adapter->fw_api_ver = (adapter->fw_release_number >> 16) & 0xff;
1493 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); 1511 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1494 1512
1495 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { 1513 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) {
@@ -1498,8 +1516,10 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1498 /* Copy 11AC cap */ 1516 /* Copy 11AC cap */
1499 adapter->hw_dot_11ac_dev_cap = 1517 adapter->hw_dot_11ac_dev_cap =
1500 le32_to_cpu(hw_spec->dot_11ac_dev_cap); 1518 le32_to_cpu(hw_spec->dot_11ac_dev_cap);
1501 adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap; 1519 adapter->usr_dot_11ac_dev_cap_bg = adapter->hw_dot_11ac_dev_cap
1502 adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap; 1520 & ~MWIFIEX_DEF_11AC_CAP_BF_RESET_MASK;
1521 adapter->usr_dot_11ac_dev_cap_a = adapter->hw_dot_11ac_dev_cap
1522 & ~MWIFIEX_DEF_11AC_CAP_BF_RESET_MASK;
1503 1523
1504 /* Copy 11AC mcs */ 1524 /* Copy 11AC mcs */
1505 adapter->hw_dot_11ac_mcs_support = 1525 adapter->hw_dot_11ac_mcs_support =
@@ -1510,6 +1530,46 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1510 adapter->is_hw_11ac_capable = false; 1530 adapter->is_hw_11ac_capable = false;
1511 } 1531 }
1512 1532
1533 resp_size = le16_to_cpu(resp->size) - S_DS_GEN;
1534 if (resp_size > sizeof(struct host_cmd_ds_get_hw_spec)) {
1535 /* we have variable HW SPEC information */
1536 left_len = resp_size - sizeof(struct host_cmd_ds_get_hw_spec);
1537 while (left_len > sizeof(struct mwifiex_ie_types_header)) {
1538 tlv = (void *)&hw_spec->tlvs + parsed_len;
1539 switch (le16_to_cpu(tlv->type)) {
1540 case TLV_TYPE_FW_API_REV:
1541 api_rev = (struct hw_spec_fw_api_rev *)tlv;
1542 api_id = le16_to_cpu(api_rev->api_id);
1543 switch (api_id) {
1544 case KEY_API_VER_ID:
1545 adapter->fw_key_api_major_ver =
1546 api_rev->major_ver;
1547 adapter->fw_key_api_minor_ver =
1548 api_rev->minor_ver;
1549 dev_dbg(adapter->dev,
1550 "fw_key_api v%d.%d\n",
1551 adapter->fw_key_api_major_ver,
1552 adapter->fw_key_api_minor_ver);
1553 break;
1554 default:
1555 dev_warn(adapter->dev,
1556 "Unknown FW api_id: %d\n",
1557 api_id);
1558 break;
1559 }
1560 break;
1561 default:
1562 dev_warn(adapter->dev,
1563 "Unknown GET_HW_SPEC TLV type: %#x\n",
1564 le16_to_cpu(tlv->type));
1565 break;
1566 }
1567 parsed_len += le16_to_cpu(tlv->len) +
1568 sizeof(struct mwifiex_ie_types_header);
1569 left_len -= parsed_len;
1570 }
1571 }
1572
1513 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", 1573 dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
1514 adapter->fw_release_number); 1574 adapter->fw_release_number);
1515 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", 1575 dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
@@ -1538,6 +1598,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1538 1598
1539 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); 1599 adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
1540 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support; 1600 adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
1601 adapter->user_dev_mcs_support = adapter->hw_dev_mcs_support;
1541 1602
1542 if (adapter->if_ops.update_mp_end_port) 1603 if (adapter->if_ops.update_mp_end_port)
1543 adapter->if_ops.update_mp_end_port(adapter, 1604 adapter->if_ops.update_mp_end_port(adapter,