diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/cmdevt.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/cmdevt.c | 161 |
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 @@ | |||
37 | static void | 37 | static void |
38 | mwifiex_init_cmd_node(struct mwifiex_private *priv, | 38 | mwifiex_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 | */ | ||
488 | int 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 | */ |
514 | int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, | 494 | int 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 | |||
987 | mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) | 977 | mwifiex_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, |