root/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtw_ch_set_search_ch
  2. rtw_mlme_band_check
  3. init_hw_mlme_ext
  4. init_mlme_default_rate_set
  5. init_mlme_ext_priv_value
  6. has_channel
  7. init_channel_list
  8. init_channel_set
  9. init_mlme_ext_priv
  10. free_mlme_ext_priv
  11. _mgt_dispatcher
  12. mgt_dispatcher
  13. OnProbeReq
  14. OnProbeRsp
  15. OnBeacon
  16. OnAuth
  17. OnAuthClient
  18. OnAssocReq
  19. OnAssocRsp
  20. OnDeAuth
  21. OnDisassoc
  22. OnAtim
  23. on_action_spct
  24. OnAction_back
  25. rtw_action_public_decache
  26. on_action_public_p2p
  27. on_action_public_vendor
  28. on_action_public_default
  29. on_action_public
  30. OnAction_ht
  31. OnAction_sa_query
  32. OnAction
  33. DoReserved
  34. _alloc_mgtxmitframe
  35. alloc_mgtxmitframe
  36. update_mgnt_tx_rate
  37. update_mgntframe_attrib
  38. update_mgntframe_attrib_addr
  39. dump_mgntframe
  40. dump_mgntframe_and_wait
  41. dump_mgntframe_and_wait_ack
  42. update_hidden_ssid
  43. issue_beacon
  44. issue_probersp
  45. _issue_probereq
  46. issue_probereq
  47. issue_probereq_ex
  48. issue_auth
  49. issue_asocrsp
  50. issue_assocreq
  51. _issue_nulldata
  52. issue_nulldata
  53. issue_nulldata_in_interrupt
  54. _issue_qos_nulldata
  55. issue_qos_nulldata
  56. _issue_deauth
  57. issue_deauth
  58. issue_deauth_ex
  59. issue_action_SA_Query
  60. issue_action_BA
  61. issue_action_BSSCoexistPacket
  62. send_delba
  63. send_beacon
  64. site_survey
  65. collect_bss_info
  66. start_create_ibss
  67. start_clnt_join
  68. start_clnt_auth
  69. start_clnt_assoc
  70. receive_disconnect
  71. process_80211d
  72. report_survey_event
  73. report_surveydone_event
  74. report_join_res
  75. report_wmm_edca_update
  76. report_del_sta_event
  77. report_add_sta_event
  78. update_sta_info
  79. rtw_mlmeext_disconnect
  80. mlmeext_joinbss_event_callback
  81. mlmeext_sta_add_event_callback
  82. mlmeext_sta_del_event_callback
  83. _linked_info_dump
  84. chk_ap_is_alive
  85. linked_status_chk
  86. survey_timer_hdl
  87. link_timer_hdl
  88. addba_timer_hdl
  89. sa_query_timer_hdl
  90. NULL_hdl
  91. rtw_auto_ap_start_beacon
  92. setopmode_hdl
  93. createbss_hdl
  94. join_cmd_hdl
  95. disconnect_hdl
  96. rtw_scan_ch_decision
  97. sitesurvey_cmd_hdl
  98. setauth_hdl
  99. setkey_hdl
  100. set_stakey_hdl
  101. add_ba_hdl
  102. chk_bmc_sleepq_cmd
  103. set_tx_beacon_cmd
  104. mlme_evt_hdl
  105. h2c_msg_hdl
  106. chk_bmc_sleepq_hdl
  107. tx_beacon_hdl
  108. rtw_chk_start_clnt_join
  109. rtw_get_ch_setting_union
  110. set_ch_hdl
  111. set_chplan_hdl
  112. led_blink_hdl
  113. set_csa_hdl
  114. tdls_hdl
  115. run_in_thread_hdl

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5  *
   6  ******************************************************************************/
   7 #define _RTW_MLME_EXT_C_
   8 
   9 #include <drv_types.h>
  10 #include <rtw_debug.h>
  11 #include <rtw_wifi_regd.h>
  12 #include <hal_btcoex.h>
  13 #include <linux/kernel.h>
  14 
  15 static struct mlme_handler mlme_sta_tbl[] = {
  16         {WIFI_ASSOCREQ,         "OnAssocReq",   &OnAssocReq},
  17         {WIFI_ASSOCRSP,         "OnAssocRsp",   &OnAssocRsp},
  18         {WIFI_REASSOCREQ,       "OnReAssocReq", &OnAssocReq},
  19         {WIFI_REASSOCRSP,       "OnReAssocRsp", &OnAssocRsp},
  20         {WIFI_PROBEREQ,         "OnProbeReq",   &OnProbeReq},
  21         {WIFI_PROBERSP,         "OnProbeRsp",           &OnProbeRsp},
  22 
  23         /*----------------------------------------------------------
  24                                         below 2 are reserved
  25         -----------------------------------------------------------*/
  26         {0,                                     "DoReserved",           &DoReserved},
  27         {0,                                     "DoReserved",           &DoReserved},
  28         {WIFI_BEACON,           "OnBeacon",             &OnBeacon},
  29         {WIFI_ATIM,                     "OnATIM",               &OnAtim},
  30         {WIFI_DISASSOC,         "OnDisassoc",           &OnDisassoc},
  31         {WIFI_AUTH,                     "OnAuth",               &OnAuthClient},
  32         {WIFI_DEAUTH,           "OnDeAuth",             &OnDeAuth},
  33         {WIFI_ACTION,           "OnAction",             &OnAction},
  34         {WIFI_ACTION_NOACK, "OnActionNoAck",    &OnAction},
  35 };
  36 
  37 static struct action_handler OnAction_tbl[] = {
  38         {RTW_WLAN_CATEGORY_SPECTRUM_MGMT,        "ACTION_SPECTRUM_MGMT", on_action_spct},
  39         {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &DoReserved},
  40         {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &DoReserved},
  41         {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
  42         {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
  43         {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
  44         {RTW_WLAN_CATEGORY_FT, "ACTION_FT",     &DoReserved},
  45         {RTW_WLAN_CATEGORY_HT,  "ACTION_HT",    &OnAction_ht},
  46         {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
  47         {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
  48         {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
  49         {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &DoReserved},
  50         {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &DoReserved},
  51         {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &DoReserved},
  52 };
  53 
  54 static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
  55 
  56 /**************************************************
  57 OUI definitions for the vendor specific IE
  58 ***************************************************/
  59 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
  60 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
  61 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
  62 unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
  63 unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
  64 
  65 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
  66 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
  67 
  68 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
  69 
  70 /********************************************************
  71 ChannelPlan definitions
  72 *********************************************************/
  73 static RT_CHANNEL_PLAN_2G       RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
  74         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},              /*  0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
  75         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},              /*  0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
  76         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},                      /*  0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
  77         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},  /*  0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
  78         {{10, 11, 12, 13}, 4},                                          /*  0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
  79         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},  /*  0x05, RT_CHANNEL_DOMAIN_2G_GLOBAL , Passive scan CH 12, 13, 14 */
  80         {{}, 0},                                                                /*  0x06, RT_CHANNEL_DOMAIN_2G_NULL */
  81 };
  82 
  83 static RT_CHANNEL_PLAN_5G       RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
  84         {{}, 0},                                                                                                                                                                        /*  0x00, RT_CHANNEL_DOMAIN_5G_NULL */
  85         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},                                          /*  0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
  86         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /*  0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
  87         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},                   /*  0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
  88         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /*  0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
  89         {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},                                                                                                         /*  0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
  90         {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},                                                                                        /*  0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
  91         {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},                                                                                             /*  0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
  92         {{149, 153, 157, 161, 165}, 5},                                                                                                                                 /*  0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
  93         {{36, 40, 44, 48, 52, 56, 60, 64}, 8},                                                                                                                          /*  0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
  94         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20},                                     /*  0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
  95         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20},                                     /*  0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
  96         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},                                          /*  0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
  97         {{36, 40, 44, 48, 52, 56, 60, 64}, 8},                                                                                                                          /*  0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
  98         {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},                                                                                  /*  0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
  99         {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15},                                                         /*  0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
 100         {{56, 60, 64, 149, 153, 157, 161, 165}, 8},                                                                                                                     /*  0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
 101         {{149, 153, 157, 161, 165}, 5},                                                                                                                                 /*  0x11, RT_CHANNEL_DOMAIN_5G_NCC3 */
 102         {{36, 40, 44, 48}, 4},                                                                                                                                                  /*  0x12, RT_CHANNEL_DOMAIN_5G_ETSI4 */
 103         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20},                                     /*  0x13, RT_CHANNEL_DOMAIN_5G_ETSI5 */
 104         {{149, 153, 157, 161}, 4},                                                                                                                                              /*  0x14, RT_CHANNEL_DOMAIN_5G_FCC8 */
 105         {{36, 40, 44, 48, 52, 56, 60, 64}, 8},                                                                                                                          /*  0x15, RT_CHANNEL_DOMAIN_5G_ETSI6 */
 106         {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},                                                                                        /*  0x16, RT_CHANNEL_DOMAIN_5G_ETSI7 */
 107         {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},                                                                                                         /*  0x17, RT_CHANNEL_DOMAIN_5G_ETSI8 */
 108         {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},                                                                                  /*  0x18, RT_CHANNEL_DOMAIN_5G_ETSI9 */
 109         {{149, 153, 157, 161, 165}, 5},                                                                                                                                 /*  0x19, RT_CHANNEL_DOMAIN_5G_ETSI10 */
 110         {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165}, 16},                                                                 /*  0x1A, RT_CHANNEL_DOMAIN_5G_ETSI11 */
 111         {{52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17},                                                        /*  0x1B, RT_CHANNEL_DOMAIN_5G_NCC4 */
 112         {{149, 153, 157, 161}, 4},                                                                                                                                              /*  0x1C, RT_CHANNEL_DOMAIN_5G_ETSI12 */
 113         {{36, 40, 44, 48, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17},                                                        /*  0x1D, RT_CHANNEL_DOMAIN_5G_FCC9 */
 114         {{36, 40, 44, 48, 100, 104, 108, 112, 116, 132, 136, 140}, 12},                                                                                 /*  0x1E, RT_CHANNEL_DOMAIN_5G_ETSI13 */
 115         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161}, 20},                                     /*  0x1F, RT_CHANNEL_DOMAIN_5G_FCC10 */
 116 
 117         /*  Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */
 118         {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},                                /*  0x20, RT_CHANNEL_DOMAIN_5G_FCC */
 119         {{36, 40, 44, 48}, 4},                                                                                                                                                  /*  0x21, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
 120         {{36, 40, 44, 48, 149, 153, 157, 161}, 8},                                                                                                                      /*  0x22, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
 121 };
 122 
 123 static RT_CHANNEL_PLAN_MAP      RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
 124         /*  0x00 ~ 0x1F , Old Define ===== */
 125         {0x02, 0x20},   /* 0x00, RT_CHANNEL_DOMAIN_FCC */
 126         {0x02, 0x0A},   /* 0x01, RT_CHANNEL_DOMAIN_IC */
 127         {0x01, 0x01},   /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
 128         {0x01, 0x00},   /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
 129         {0x01, 0x00},   /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
 130         {0x03, 0x00},   /* 0x05, RT_CHANNEL_DOMAIN_MKK */
 131         {0x03, 0x00},   /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
 132         {0x01, 0x09},   /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
 133         {0x03, 0x09},   /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
 134         {0x03, 0x00},   /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
 135         {0x00, 0x00},   /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
 136         {0x02, 0x0F},   /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
 137         {0x01, 0x08},   /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
 138         {0x02, 0x06},   /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
 139         {0x02, 0x0B},   /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
 140         {0x02, 0x09},   /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
 141         {0x01, 0x01},   /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
 142         {0x02, 0x05},   /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
 143         {0x01, 0x21},   /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
 144         {0x00, 0x04},   /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
 145         {0x02, 0x10},   /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
 146         {0x00, 0x21},   /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
 147         {0x00, 0x22},   /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
 148         {0x03, 0x21},   /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
 149         {0x06, 0x08},   /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
 150         {0x02, 0x08},   /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
 151         {0x00, 0x00},   /* 0x1A, */
 152         {0x00, 0x00},   /* 0x1B, */
 153         {0x00, 0x00},   /* 0x1C, */
 154         {0x00, 0x00},   /* 0x1D, */
 155         {0x00, 0x00},   /* 0x1E, */
 156         {0x06, 0x04},   /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
 157         /*  0x20 ~ 0x7F , New Define ===== */
 158         {0x00, 0x00},   /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
 159         {0x01, 0x00},   /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
 160         {0x02, 0x00},   /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
 161         {0x03, 0x00},   /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
 162         {0x04, 0x00},   /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
 163         {0x02, 0x04},   /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
 164         {0x00, 0x01},   /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
 165         {0x03, 0x0C},   /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
 166         {0x00, 0x0B},   /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
 167         {0x00, 0x05},   /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
 168         {0x00, 0x00},   /* 0x2A, */
 169         {0x00, 0x00},   /* 0x2B, */
 170         {0x00, 0x00},   /* 0x2C, */
 171         {0x00, 0x00},   /* 0x2D, */
 172         {0x00, 0x00},   /* 0x2E, */
 173         {0x00, 0x00},   /* 0x2F, */
 174         {0x00, 0x06},   /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
 175         {0x00, 0x07},   /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
 176         {0x00, 0x08},   /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
 177         {0x00, 0x09},   /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
 178         {0x02, 0x0A},   /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
 179         {0x00, 0x02},   /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
 180         {0x00, 0x03},   /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
 181         {0x03, 0x0D},   /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
 182         {0x03, 0x0E},   /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
 183         {0x02, 0x0F},   /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
 184         {0x00, 0x00},   /* 0x3A, */
 185         {0x00, 0x00},   /* 0x3B, */
 186         {0x00, 0x00},   /* 0x3C, */
 187         {0x00, 0x00},   /* 0x3D, */
 188         {0x00, 0x00},   /* 0x3E, */
 189         {0x00, 0x00},   /* 0x3F, */
 190         {0x02, 0x10},   /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
 191         {0x05, 0x00},   /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL */
 192         {0x01, 0x12},   /* 0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4 */
 193         {0x02, 0x05},   /* 0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2 */
 194         {0x02, 0x11},   /* 0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3 */
 195         {0x00, 0x13},   /* 0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5 */
 196         {0x02, 0x14},   /* 0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8 */
 197         {0x00, 0x15},   /* 0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 */
 198         {0x00, 0x16},   /* 0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 */
 199         {0x00, 0x17},   /* 0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 */
 200         {0x00, 0x18},   /* 0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 */
 201         {0x00, 0x19},   /* 0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 */
 202         {0x00, 0x1A},   /* 0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 */
 203         {0x02, 0x1B},   /* 0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4 */
 204         {0x00, 0x1C},   /* 0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12 */
 205         {0x02, 0x1D},   /* 0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 */
 206         {0x00, 0x1E},   /* 0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 */
 207         {0x02, 0x1F},   /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */
 208 };
 209 
 210 static RT_CHANNEL_PLAN_MAP      RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; /* use the conbination for max channel numbers */
 211 
 212 /*
 213  * Search the @param ch in given @param ch_set
 214  * @ch_set: the given channel set
 215  * @ch: the given channel number
 216  *
 217  * return the index of channel_num in channel_set, -1 if not found
 218  */
 219 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
 220 {
 221         int i;
 222         for (i = 0; ch_set[i].ChannelNum != 0; i++) {
 223                 if (ch == ch_set[i].ChannelNum)
 224                         break;
 225         }
 226 
 227         if (i >= ch_set[i].ChannelNum)
 228                 return -1;
 229         return i;
 230 }
 231 
 232 /*
 233  * Check the @param ch is fit with setband setting of @param adapter
 234  * @adapter: the given adapter
 235  * @ch: the given channel number
 236  *
 237  * return true when check valid, false not valid
 238  */
 239 bool rtw_mlme_band_check(struct adapter *adapter, const u32 ch)
 240 {
 241         if (adapter->setband == GHZ24_50 /* 2.4G and 5G */
 242                 || (adapter->setband == GHZ_24 && ch < 35) /* 2.4G only */
 243                 || (adapter->setband == GHZ_50 && ch > 35) /* 5G only */
 244         ) {
 245                 return true;
 246         }
 247         return false;
 248 }
 249 
 250 /****************************************************************************
 251 
 252 Following are the initialization functions for WiFi MLME
 253 
 254 *****************************************************************************/
 255 
 256 int init_hw_mlme_ext(struct adapter *padapter)
 257 {
 258         struct  mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 259 
 260         set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
 261         return _SUCCESS;
 262 }
 263 
 264 void init_mlme_default_rate_set(struct adapter *padapter)
 265 {
 266         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 267 
 268         unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
 269         unsigned char mixed_basicrate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
 270         unsigned char supported_mcs_set[16] = {0xff, 0xff, 0x00, 0x00, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
 271 
 272         memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
 273         memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
 274 
 275         memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
 276 }
 277 
 278 static void init_mlme_ext_priv_value(struct adapter *padapter)
 279 {
 280         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 281         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 282 
 283         atomic_set(&pmlmeext->event_seq, 0);
 284         pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
 285         pmlmeext->sa_query_seq = 0;
 286         pmlmeext->mgnt_80211w_IPN = 0;
 287         pmlmeext->mgnt_80211w_IPN_rx = 0;
 288         pmlmeext->cur_channel = padapter->registrypriv.channel;
 289         pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
 290         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 291 
 292         pmlmeext->retry = 0;
 293 
 294         pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
 295 
 296         init_mlme_default_rate_set(padapter);
 297 
 298         pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
 299         pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
 300         pmlmeext->sitesurvey_res.channel_idx = 0;
 301         pmlmeext->sitesurvey_res.bss_cnt = 0;
 302         pmlmeext->scan_abort = false;
 303 
 304         pmlmeinfo->state = WIFI_FW_NULL_STATE;
 305         pmlmeinfo->reauth_count = 0;
 306         pmlmeinfo->reassoc_count = 0;
 307         pmlmeinfo->link_count = 0;
 308         pmlmeinfo->auth_seq = 0;
 309         pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
 310         pmlmeinfo->key_index = 0;
 311         pmlmeinfo->iv = 0;
 312 
 313         pmlmeinfo->enc_algo = _NO_PRIVACY_;
 314         pmlmeinfo->authModeToggle = 0;
 315 
 316         memset(pmlmeinfo->chg_txt, 0, 128);
 317 
 318         pmlmeinfo->slotTime = SHORT_SLOT_TIME;
 319         pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
 320 
 321         pmlmeinfo->dialogToken = 0;
 322 
 323         pmlmeext->action_public_rxseq = 0xffff;
 324         pmlmeext->action_public_dialog_token = 0xff;
 325 }
 326 
 327 static int has_channel(RT_CHANNEL_INFO *channel_set,
 328                                            u8 chanset_size,
 329                                            u8 chan)
 330 {
 331         int i;
 332 
 333         for (i = 0; i < chanset_size; i++) {
 334                 if (channel_set[i].ChannelNum == chan) {
 335                         return 1;
 336                 }
 337         }
 338 
 339         return 0;
 340 }
 341 
 342 static void init_channel_list(struct adapter *padapter, RT_CHANNEL_INFO *channel_set,
 343                                                           u8 chanset_size,
 344                                                           struct p2p_channels *channel_list)
 345 {
 346 
 347         struct p2p_oper_class_map op_class[] = {
 348                 { IEEE80211G,  81,   1,  13,  1, BW20 },
 349                 { IEEE80211G,  82,  14,  14,  1, BW20 },
 350                 { IEEE80211A, 115,  36,  48,  4, BW20 },
 351                 { IEEE80211A, 116,  36,  44,  8, BW40PLUS },
 352                 { IEEE80211A, 117,  40,  48,  8, BW40MINUS },
 353                 { IEEE80211A, 124, 149, 161,  4, BW20 },
 354                 { IEEE80211A, 125, 149, 169,  4, BW20 },
 355                 { IEEE80211A, 126, 149, 157,  8, BW40PLUS },
 356                 { IEEE80211A, 127, 153, 161,  8, BW40MINUS },
 357                 { -1, 0, 0, 0, 0, BW20 }
 358         };
 359 
 360         int cla, op;
 361 
 362         cla = 0;
 363 
 364         for (op = 0; op_class[op].op_class; op++) {
 365                 u8 ch;
 366                 struct p2p_oper_class_map *o = &op_class[op];
 367                 struct p2p_reg_class *reg = NULL;
 368 
 369                 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
 370                         if (!has_channel(channel_set, chanset_size, ch))
 371                                 continue;
 372 
 373                         if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
 374                                 continue;
 375 
 376                         if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) &&
 377                                 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
 378                                 continue;
 379 
 380                         if (!reg) {
 381                                 reg = &channel_list->reg_class[cla];
 382                                 cla++;
 383                                 reg->reg_class = o->op_class;
 384                                 reg->channels = 0;
 385                         }
 386                         reg->channel[reg->channels] = ch;
 387                         reg->channels++;
 388                 }
 389         }
 390         channel_list->reg_classes = cla;
 391 
 392 }
 393 
 394 static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
 395 {
 396         u8 index, chanset_size = 0;
 397         u8 b5GBand = false, b2_4GBand = false;
 398         u8 Index2G = 0, Index5G = 0;
 399 
 400         memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
 401 
 402         if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
 403                 DBG_871X("ChannelPlan ID %x error !!!!!\n", ChannelPlan);
 404                 return chanset_size;
 405         }
 406 
 407         if (IsSupported24G(padapter->registrypriv.wireless_mode)) {
 408                 b2_4GBand = true;
 409                 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
 410                         Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
 411                 else
 412                         Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
 413         }
 414 
 415         if (b2_4GBand) {
 416                 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
 417                         channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
 418 
 419                         if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */
 420                                 (RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan)) {
 421                                 if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
 422                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
 423                                 else if ((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
 424                                         channel_set[chanset_size].ScanType  = SCAN_PASSIVE;
 425                         } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
 426                                 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
 427                                 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) { /*  channel 12~13, passive scan */
 428                                 if (channel_set[chanset_size].ChannelNum <= 11)
 429                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
 430                                 else
 431                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
 432                         } else
 433                                 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
 434 
 435                         chanset_size++;
 436                 }
 437         }
 438 
 439         if (b5GBand) {
 440                 for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) {
 441                         if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
 442                                 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149) {
 443                                 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
 444                                 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)/* passive scan for all 5G channels */
 445                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
 446                                 else
 447                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
 448                                 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __func__, chanset_size, channel_set[chanset_size].ChannelNum);
 449                                 chanset_size++;
 450                         }
 451                 }
 452         }
 453 
 454         DBG_871X("%s ChannelPlan ID %x Chan num:%d \n", __func__, ChannelPlan, chanset_size);
 455         return chanset_size;
 456 }
 457 
 458 void init_mlme_ext_priv(struct adapter *padapter)
 459 {
 460         struct registry_priv *pregistrypriv = &padapter->registrypriv;
 461         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 462         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 463         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 464 
 465         pmlmeext->padapter = padapter;
 466 
 467         /* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
 468 
 469         init_mlme_ext_priv_value(padapter);
 470         pmlmeinfo->accept_addba_req = pregistrypriv->accept_addba_req;
 471 
 472         init_mlme_ext_timer(padapter);
 473 
 474         init_mlme_ap_info(padapter);
 475 
 476         pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set);
 477         init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
 478         pmlmeext->last_scan_time = 0;
 479         pmlmeext->chan_scan_time = SURVEY_TO;
 480         pmlmeext->mlmeext_init = true;
 481         pmlmeext->active_keep_alive_check = true;
 482 
 483 #ifdef DBG_FIXED_CHAN
 484         pmlmeext->fixed_chan = 0xFF;
 485 #endif
 486 }
 487 
 488 void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
 489 {
 490         struct adapter *padapter = pmlmeext->padapter;
 491 
 492         if (!padapter)
 493                 return;
 494 
 495         if (padapter->bDriverStopped) {
 496                 del_timer_sync(&pmlmeext->survey_timer);
 497                 del_timer_sync(&pmlmeext->link_timer);
 498                 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
 499         }
 500 }
 501 
 502 static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
 503 {
 504         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 505         u8 *pframe = precv_frame->u.hdr.rx_data;
 506 
 507         if (ptable->func) {
 508                 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
 509                 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
 510                     memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
 511                         return;
 512 
 513                 ptable->func(padapter, precv_frame);
 514         }
 515 }
 516 
 517 void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame)
 518 {
 519         int index;
 520         struct mlme_handler *ptable;
 521         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 522         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 523         u8 *pframe = precv_frame->u.hdr.rx_data;
 524         struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
 525         struct dvobj_priv *psdpriv = padapter->dvobj;
 526         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
 527 
 528         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
 529                  ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
 530                   GetFrameType(pframe), GetFrameSubType(pframe)));
 531 
 532         if (GetFrameType(pframe) != WIFI_MGT_TYPE) {
 533                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
 534                 return;
 535         }
 536 
 537         /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
 538         if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
 539                 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) {
 540                 return;
 541         }
 542 
 543         ptable = mlme_sta_tbl;
 544 
 545         index = GetFrameSubType(pframe) >> 4;
 546 
 547         if (index >= ARRAY_SIZE(mlme_sta_tbl)) {
 548                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Currently we do not support reserved sub-fr-type =%d\n", index));
 549                 return;
 550         }
 551         ptable += index;
 552 
 553         if (psta != NULL) {
 554                 if (GetRetry(pframe)) {
 555                         if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) {
 556                                 /* drop the duplicate management frame */
 557                                 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
 558                                 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
 559                                 return;
 560                         }
 561                 }
 562                 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
 563         }
 564 
 565         switch (GetFrameSubType(pframe)) {
 566         case WIFI_AUTH:
 567                 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
 568                         ptable->func = &OnAuth;
 569                 else
 570                         ptable->func = &OnAuthClient;
 571                 /* fall through */
 572         case WIFI_ASSOCREQ:
 573         case WIFI_REASSOCREQ:
 574                 _mgt_dispatcher(padapter, ptable, precv_frame);
 575                 break;
 576         case WIFI_PROBEREQ:
 577                 _mgt_dispatcher(padapter, ptable, precv_frame);
 578                 break;
 579         case WIFI_BEACON:
 580                 _mgt_dispatcher(padapter, ptable, precv_frame);
 581                 break;
 582         case WIFI_ACTION:
 583                 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */
 584                 _mgt_dispatcher(padapter, ptable, precv_frame);
 585                 break;
 586         default:
 587                 _mgt_dispatcher(padapter, ptable, precv_frame);
 588                 break;
 589         }
 590 }
 591 
 592 /****************************************************************************
 593 
 594 Following are the callback functions for each subtype of the management frames
 595 
 596 *****************************************************************************/
 597 
 598 unsigned int OnProbeReq(struct adapter *padapter, union recv_frame *precv_frame)
 599 {
 600         unsigned int    ielen;
 601         unsigned char *p;
 602         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 603         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 604         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 605         struct wlan_bssid_ex    *cur = &pmlmeinfo->network;
 606         u8 *pframe = precv_frame->u.hdr.rx_data;
 607         uint len = precv_frame->u.hdr.len;
 608         u8 is_valid_p2p_probereq = false;
 609 
 610         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
 611                 return _SUCCESS;
 612 
 613         if (check_fwstate(pmlmepriv, _FW_LINKED) == false &&
 614                 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == false) {
 615                 return _SUCCESS;
 616         }
 617 
 618 
 619         /* DBG_871X("+OnProbeReq\n"); */
 620 
 621 #ifdef CONFIG_AUTO_AP_MODE
 622         if (check_fwstate(pmlmepriv, _FW_LINKED) &&
 623                         pmlmepriv->cur_network.join_res) {
 624                 struct sta_info *psta;
 625                 u8 *mac_addr, *peer_addr;
 626                 struct sta_priv *pstapriv = &padapter->stapriv;
 627                 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
 628                 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
 629 
 630                 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
 631                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
 632 
 633                 if (!p || ielen != 14)
 634                         goto _non_rc_device;
 635 
 636                 if (memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
 637                         goto _non_rc_device;
 638 
 639                 if (memcmp(p+6, get_sa(pframe), ETH_ALEN)) {
 640                         DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __func__,
 641                                 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
 642 
 643                         goto _non_rc_device;
 644                 }
 645 
 646                 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __func__,  MAC_ARG(get_sa(pframe)));
 647 
 648                 /* new a station */
 649                 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
 650                 if (psta == NULL) {
 651                         /*  allocate a new one */
 652                         DBG_871X("going to alloc stainfo for rc ="MAC_FMT"\n",  MAC_ARG(get_sa(pframe)));
 653                         psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
 654                         if (!psta) {
 655                                 /* TODO: */
 656                                 DBG_871X(" Exceed the upper limit of supported clients...\n");
 657                                 return _SUCCESS;
 658                         }
 659 
 660                         spin_lock_bh(&pstapriv->asoc_list_lock);
 661                         if (list_empty(&psta->asoc_list)) {
 662                                 psta->expire_to = pstapriv->expire_to;
 663                                 list_add_tail(&psta->asoc_list, &pstapriv->asoc_list);
 664                                 pstapriv->asoc_list_cnt++;
 665                         }
 666                         spin_unlock_bh(&pstapriv->asoc_list_lock);
 667 
 668                         /* generate pairing ID */
 669                         mac_addr = myid(&(padapter->eeprompriv));
 670                         peer_addr = psta->hwaddr;
 671                         psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
 672 
 673                         /* update peer stainfo */
 674                         psta->isrc = true;
 675                         /* psta->aid = 0; */
 676                         /* psta->mac_id = 2; */
 677 
 678                         /* get a unique AID */
 679                         if (psta->aid > 0) {
 680                                 DBG_871X("old AID %d\n", psta->aid);
 681                         } else {
 682                                 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
 683                                         if (pstapriv->sta_aid[psta->aid - 1] == NULL)
 684                                                 break;
 685 
 686                                 if (psta->aid > pstapriv->max_num_sta) {
 687                                         psta->aid = 0;
 688                                         DBG_871X("no room for more AIDs\n");
 689                                         return _SUCCESS;
 690                                 }
 691                                 pstapriv->sta_aid[psta->aid - 1] = psta;
 692                                 DBG_871X("allocate new AID = (%d)\n", psta->aid);
 693                         }
 694 
 695                         psta->qos_option = 1;
 696                         psta->bw_mode = CHANNEL_WIDTH_20;
 697                         psta->ieee8021x_blocked = false;
 698                         psta->htpriv.ht_option = true;
 699                         psta->htpriv.ampdu_enable = false;
 700                         psta->htpriv.sgi_20m = false;
 701                         psta->htpriv.sgi_40m = false;
 702                         psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 703                         psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
 704                         psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
 705 
 706                         rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
 707 
 708                         memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
 709 
 710                         spin_lock_bh(&psta->lock);
 711                         psta->state |= _FW_LINKED;
 712                         spin_unlock_bh(&psta->lock);
 713 
 714                         report_add_sta_event(padapter, psta->hwaddr, psta->aid);
 715 
 716                 }
 717 
 718                 issue_probersp(padapter, get_sa(pframe), false);
 719 
 720                 return _SUCCESS;
 721 
 722         }
 723 
 724 _non_rc_device:
 725 
 726         return _SUCCESS;
 727 
 728 #endif /* CONFIG_AUTO_AP_MODE */
 729 
 730         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
 731                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
 732 
 733 
 734         /* check (wildcard) SSID */
 735         if (p != NULL) {
 736                 if (is_valid_p2p_probereq)
 737                         goto _issue_probersp;
 738 
 739                 if ((ielen != 0 && false == !memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
 740                         || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
 741                 )
 742                         return _SUCCESS;
 743 
 744 _issue_probersp:
 745                 if ((check_fwstate(pmlmepriv, _FW_LINKED)  &&
 746                         pmlmepriv->cur_network.join_res) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 747                         /* DBG_871X("+issue_probersp during ap mode\n"); */
 748                         issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
 749                 }
 750 
 751         }
 752 
 753         return _SUCCESS;
 754 
 755 }
 756 
 757 unsigned int OnProbeRsp(struct adapter *padapter, union recv_frame *precv_frame)
 758 {
 759         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 760 
 761         if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
 762                 report_survey_event(padapter, precv_frame);
 763                 return _SUCCESS;
 764         }
 765 
 766         return _SUCCESS;
 767 
 768 }
 769 
 770 unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame)
 771 {
 772         int cam_idx;
 773         struct sta_info *psta;
 774         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 775         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
 776         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 777         struct sta_priv *pstapriv = &padapter->stapriv;
 778         u8 *pframe = precv_frame->u.hdr.rx_data;
 779         uint len = precv_frame->u.hdr.len;
 780         struct wlan_bssid_ex *pbss;
 781         int ret = _SUCCESS;
 782         u8 *p = NULL;
 783         u32 ielen = 0;
 784 
 785         p = rtw_get_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
 786         if ((p != NULL) && (ielen > 0)) {
 787                 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) {
 788                         /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
 789                         DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe)));
 790                         *(p + 1) = ielen - 1;
 791                 }
 792         }
 793 
 794         if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
 795                 report_survey_event(padapter, precv_frame);
 796                 return _SUCCESS;
 797         }
 798 
 799         if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
 800                 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
 801                         /* we should update current network before auth, or some IE is wrong */
 802                         pbss = rtw_malloc(sizeof(struct wlan_bssid_ex));
 803                         if (pbss) {
 804                                 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
 805                                         update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true);
 806                                         rtw_get_bcn_info(&(pmlmepriv->cur_network));
 807                                 }
 808                                 kfree(pbss);
 809                         }
 810 
 811                         /* check the vendor of the assoc AP */
 812                         pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
 813 
 814                         /* update TSF Value */
 815                         update_TSF(pmlmeext, pframe, len);
 816 
 817                         /* reset for adaptive_early_32k */
 818                         pmlmeext->adaptive_tsf_done = false;
 819                         pmlmeext->DrvBcnEarly = 0xff;
 820                         pmlmeext->DrvBcnTimeOut = 0xff;
 821                         pmlmeext->bcn_cnt = 0;
 822                         memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
 823                         memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
 824 
 825                         /* start auth */
 826                         start_clnt_auth(padapter);
 827 
 828                         return _SUCCESS;
 829                 }
 830 
 831                 if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
 832                         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
 833                         if (psta != NULL) {
 834                                 ret = rtw_check_bcn_info(padapter, pframe, len);
 835                                 if (!ret) {
 836                                                 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
 837                                                 receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
 838                                                 return _SUCCESS;
 839                                 }
 840                                 /* update WMM, ERP in the beacon */
 841                                 /* todo: the timer is used instead of the number of the beacon received */
 842                                 if ((sta_rx_pkts(psta) & 0xf) == 0)
 843                                         /* DBG_871X("update_bcn_info\n"); */
 844                                         update_beacon_info(padapter, pframe, len, psta);
 845 
 846                                 adaptive_early_32k(pmlmeext, pframe, len);
 847                         }
 848                 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
 849                         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
 850                         if (psta != NULL) {
 851                                 /* update WMM, ERP in the beacon */
 852                                 /* todo: the timer is used instead of the number of the beacon received */
 853                                 if ((sta_rx_pkts(psta) & 0xf) == 0) {
 854                                         /* DBG_871X("update_bcn_info\n"); */
 855                                         update_beacon_info(padapter, pframe, len, psta);
 856                                 }
 857                         } else {
 858                                 /* allocate a new CAM entry for IBSS station */
 859                                 cam_idx = allocate_fw_sta_entry(padapter);
 860                                 if (cam_idx == NUM_STA)
 861                                         goto _END_ONBEACON_;
 862 
 863                                 /* get supported rate */
 864                                 if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) {
 865                                         pmlmeinfo->FW_sta_info[cam_idx].status = 0;
 866                                         goto _END_ONBEACON_;
 867                                 }
 868 
 869                                 /* update TSF Value */
 870                                 update_TSF(pmlmeext, pframe, len);
 871 
 872                                 /* report sta add event */
 873                                 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
 874                         }
 875                 }
 876         }
 877 
 878 _END_ONBEACON_:
 879 
 880         return _SUCCESS;
 881 
 882 }
 883 
 884 unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
 885 {
 886         unsigned int    auth_mode, seq, ie_len;
 887         unsigned char *sa, *p;
 888         u16 algorithm;
 889         int     status;
 890         static struct sta_info stat;
 891         struct  sta_info *pstat = NULL;
 892         struct  sta_priv *pstapriv = &padapter->stapriv;
 893         struct security_priv *psecuritypriv = &padapter->securitypriv;
 894         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 895         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
 896         u8 *pframe = precv_frame->u.hdr.rx_data;
 897         uint len = precv_frame->u.hdr.len;
 898         u8 offset = 0;
 899 
 900         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
 901                 return _FAIL;
 902 
 903         DBG_871X("+OnAuth\n");
 904 
 905         sa = GetAddr2Ptr(pframe);
 906 
 907         auth_mode = psecuritypriv->dot11AuthAlgrthm;
 908 
 909         if (GetPrivacy(pframe)) {
 910                 u8 *iv;
 911                 struct rx_pkt_attrib     *prxattrib = &(precv_frame->u.hdr.attrib);
 912 
 913                 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
 914                 prxattrib->encrypt = _WEP40_;
 915 
 916                 iv = pframe+prxattrib->hdrlen;
 917                 prxattrib->key_index = ((iv[3]>>6)&0x3);
 918 
 919                 prxattrib->iv_len = 4;
 920                 prxattrib->icv_len = 4;
 921 
 922                 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
 923 
 924                 offset = 4;
 925         }
 926 
 927         algorithm = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
 928         seq     = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
 929 
 930         DBG_871X("auth alg =%x, seq =%X\n", algorithm, seq);
 931 
 932         if (auth_mode == 2 &&
 933                         psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
 934                         psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
 935                 auth_mode = 0;
 936 
 937         if ((algorithm > 0 && auth_mode == 0) ||        /*  rx a shared-key auth but shared not enabled */
 938                 (algorithm == 0 && auth_mode == 1)) {   /*  rx a open-system auth but shared-key is enabled */
 939                 DBG_871X("auth rejected due to bad alg [alg =%d, auth_mib =%d] %02X%02X%02X%02X%02X%02X\n",
 940                         algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
 941 
 942                 status = _STATS_NO_SUPP_ALG_;
 943 
 944                 goto auth_fail;
 945         }
 946 
 947         if (rtw_access_ctrl(padapter, sa) == false) {
 948                 status = _STATS_UNABLE_HANDLE_STA_;
 949                 goto auth_fail;
 950         }
 951 
 952         pstat = rtw_get_stainfo(pstapriv, sa);
 953         if (pstat == NULL) {
 954 
 955                 /*  allocate a new one */
 956                 DBG_871X("going to alloc stainfo for sa ="MAC_FMT"\n",  MAC_ARG(sa));
 957                 pstat = rtw_alloc_stainfo(pstapriv, sa);
 958                 if (pstat == NULL) {
 959                         DBG_871X(" Exceed the upper limit of supported clients...\n");
 960                         status = _STATS_UNABLE_HANDLE_STA_;
 961                         goto auth_fail;
 962                 }
 963 
 964                 pstat->state = WIFI_FW_AUTH_NULL;
 965                 pstat->auth_seq = 0;
 966 
 967                 /* pstat->flags = 0; */
 968                 /* pstat->capability = 0; */
 969         } else {
 970 
 971                 spin_lock_bh(&pstapriv->asoc_list_lock);
 972                 if (list_empty(&pstat->asoc_list) == false) {
 973                         list_del_init(&pstat->asoc_list);
 974                         pstapriv->asoc_list_cnt--;
 975                         if (pstat->expire_to > 0) {
 976                                 /* TODO: STA re_auth within expire_to */
 977                         }
 978                 }
 979                 spin_unlock_bh(&pstapriv->asoc_list_lock);
 980 
 981                 if (seq == 1) {
 982                         /* TODO: STA re_auth and auth timeout */
 983                 }
 984         }
 985 
 986         spin_lock_bh(&pstapriv->auth_list_lock);
 987         if (list_empty(&pstat->auth_list)) {
 988 
 989                 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
 990                 pstapriv->auth_list_cnt++;
 991         }
 992         spin_unlock_bh(&pstapriv->auth_list_lock);
 993 
 994         if (pstat->auth_seq == 0)
 995                 pstat->expire_to = pstapriv->auth_to;
 996 
 997 
 998         if ((pstat->auth_seq + 1) != seq) {
 999                 DBG_871X("(1)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n",
1000                         seq, pstat->auth_seq+1);
1001                 status = _STATS_OUT_OF_AUTH_SEQ_;
1002                 goto auth_fail;
1003         }
1004 
1005         if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) {
1006                 if (seq == 1) {
1007                         pstat->state &= ~WIFI_FW_AUTH_NULL;
1008                         pstat->state |= WIFI_FW_AUTH_SUCCESS;
1009                         pstat->expire_to = pstapriv->assoc_to;
1010                         pstat->authalg = algorithm;
1011                 } else {
1012                         DBG_871X("(2)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n",
1013                                 seq, pstat->auth_seq+1);
1014                         status = _STATS_OUT_OF_AUTH_SEQ_;
1015                         goto auth_fail;
1016                 }
1017         } else { /*  shared system or auto authentication */
1018                 if (seq == 1) {
1019                         /* prepare for the challenging txt... */
1020                         memset((void *)pstat->chg_txt, 78, 128);
1021 
1022                         pstat->state &= ~WIFI_FW_AUTH_NULL;
1023                         pstat->state |= WIFI_FW_AUTH_STATE;
1024                         pstat->authalg = algorithm;
1025                         pstat->auth_seq = 2;
1026                 } else if (seq == 3) {
1027                         /* checking for challenging txt... */
1028                         DBG_871X("checking for challenging txt...\n");
1029 
1030                         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
1031                                         len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
1032 
1033                         if ((p == NULL) || (ie_len <= 0)) {
1034                                 DBG_871X("auth rejected because challenge failure!(1)\n");
1035                                 status = _STATS_CHALLENGE_FAIL_;
1036                                 goto auth_fail;
1037                         }
1038 
1039                         if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
1040                                 pstat->state &= (~WIFI_FW_AUTH_STATE);
1041                                 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1042                                 /*  challenging txt is correct... */
1043                                 pstat->expire_to =  pstapriv->assoc_to;
1044                         } else {
1045                                 DBG_871X("auth rejected because challenge failure!\n");
1046                                 status = _STATS_CHALLENGE_FAIL_;
1047                                 goto auth_fail;
1048                         }
1049                 } else {
1050                         DBG_871X("(3)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n",
1051                                 seq, pstat->auth_seq+1);
1052                         status = _STATS_OUT_OF_AUTH_SEQ_;
1053                         goto auth_fail;
1054                 }
1055         }
1056 
1057 
1058         /*  Now, we are going to issue_auth... */
1059         pstat->auth_seq = seq + 1;
1060 
1061         issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
1062 
1063         if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1064                 pstat->auth_seq = 0;
1065 
1066 
1067         return _SUCCESS;
1068 
1069 auth_fail:
1070 
1071         if (pstat)
1072                 rtw_free_stainfo(padapter, pstat);
1073 
1074         pstat = &stat;
1075         memset((char *)pstat, '\0', sizeof(stat));
1076         pstat->auth_seq = 2;
1077         memcpy(pstat->hwaddr, sa, 6);
1078 
1079         issue_auth(padapter, pstat, (unsigned short)status);
1080 
1081         return _FAIL;
1082 
1083 }
1084 
1085 unsigned int OnAuthClient(struct adapter *padapter, union recv_frame *precv_frame)
1086 {
1087         unsigned int    seq, len, status, algthm, offset;
1088         unsigned char *p;
1089         unsigned int    go2asoc = 0;
1090         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1091         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1092         u8 *pframe = precv_frame->u.hdr.rx_data;
1093         uint pkt_len = precv_frame->u.hdr.len;
1094 
1095         DBG_871X("%s\n", __func__);
1096 
1097         /* check A1 matches or not */
1098         if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
1099                 return _SUCCESS;
1100 
1101         if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1102                 return _SUCCESS;
1103 
1104         offset = (GetPrivacy(pframe)) ? 4 : 0;
1105 
1106         algthm  = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1107         seq     = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1108         status  = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
1109 
1110         if (status != 0) {
1111                 DBG_871X("clnt auth fail, status: %d\n", status);
1112                 if (status == 13) { /*  pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1113                         if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1114                                 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1115                         else
1116                                 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1117                         /* pmlmeinfo->reauth_count = 0; */
1118                 }
1119 
1120                 set_link_timer(pmlmeext, 1);
1121                 goto authclnt_fail;
1122         }
1123 
1124         if (seq == 2) {
1125                 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1126                          /*  legendary shared system */
1127                         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
1128                                 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
1129 
1130                         if (p == NULL) {
1131                                 /* DBG_871X("marc: no challenge text?\n"); */
1132                                 goto authclnt_fail;
1133                         }
1134 
1135                         memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
1136                         pmlmeinfo->auth_seq = 3;
1137                         issue_auth(padapter, NULL, 0);
1138                         set_link_timer(pmlmeext, REAUTH_TO);
1139 
1140                         return _SUCCESS;
1141                 } else {
1142                         /*  open system */
1143                         go2asoc = 1;
1144                 }
1145         } else if (seq == 4) {
1146                 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1147                         go2asoc = 1;
1148                 } else {
1149                         goto authclnt_fail;
1150                 }
1151         } else {
1152                 /*  this is also illegal */
1153                 /* DBG_871X("marc: clnt auth failed due to illegal seq =%x\n", seq); */
1154                 goto authclnt_fail;
1155         }
1156 
1157         if (go2asoc) {
1158                 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
1159                 start_clnt_assoc(padapter);
1160                 return _SUCCESS;
1161         }
1162 
1163 authclnt_fail:
1164 
1165         /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1166 
1167         return _FAIL;
1168 
1169 }
1170 
1171 unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
1172 {
1173         u16 capab_info, listen_interval;
1174         struct rtw_ieee802_11_elems elems;
1175         struct sta_info *pstat;
1176         unsigned char   reassoc, *p, *pos, *wpa_ie;
1177         unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1178         int             i, ie_len, wpa_ie_len, left;
1179         unsigned char   supportRate[16];
1180         int                                     supportRateNum;
1181         unsigned short          status = _STATS_SUCCESSFUL_;
1182         unsigned short          frame_type, ie_offset = 0;
1183         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1184         struct security_priv *psecuritypriv = &padapter->securitypriv;
1185         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1186         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1187         struct wlan_bssid_ex    *cur = &(pmlmeinfo->network);
1188         struct sta_priv *pstapriv = &padapter->stapriv;
1189         u8 *pframe = precv_frame->u.hdr.rx_data;
1190         uint pkt_len = precv_frame->u.hdr.len;
1191 
1192         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1193                 return _FAIL;
1194 
1195         frame_type = GetFrameSubType(pframe);
1196         if (frame_type == WIFI_ASSOCREQ) {
1197                 reassoc = 0;
1198                 ie_offset = _ASOCREQ_IE_OFFSET_;
1199         } else { /*  WIFI_REASSOCREQ */
1200                 reassoc = 1;
1201                 ie_offset = _REASOCREQ_IE_OFFSET_;
1202         }
1203 
1204 
1205         if (pkt_len < sizeof(struct ieee80211_hdr_3addr) + ie_offset) {
1206                 DBG_871X("handle_assoc(reassoc =%d) - too short payload (len =%lu)"
1207                        "\n", reassoc, (unsigned long)pkt_len);
1208                 return _FAIL;
1209         }
1210 
1211         pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1212         if (!pstat) {
1213                 status = _RSON_CLS2_;
1214                 goto asoc_class2_error;
1215         }
1216 
1217         capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
1218         /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */
1219         /* listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2)); */
1220         listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
1221 
1222         left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
1223         pos = pframe + (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
1224 
1225 
1226         DBG_871X("%s\n", __func__);
1227 
1228         /*  check if this stat has been successfully authenticated/assocated */
1229         if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
1230                 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
1231                         status = _RSON_CLS2_;
1232                         goto asoc_class2_error;
1233                 } else {
1234                         pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1235                         pstat->state |= WIFI_FW_ASSOC_STATE;
1236                 }
1237         } else {
1238                 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1239                 pstat->state |= WIFI_FW_ASSOC_STATE;
1240         }
1241 
1242 
1243         pstat->capability = capab_info;
1244 
1245         /* now parse all ieee802_11 ie to point to elems */
1246         if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
1247             !elems.ssid) {
1248                 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
1249                        MAC_ARG(pstat->hwaddr));
1250                 status = _STATS_FAILURE_;
1251                 goto OnAssocReqFail;
1252         }
1253 
1254         /*  now we should check all the fields... */
1255         /*  checking SSID */
1256         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
1257                 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1258 
1259         if (!p || ie_len == 0) {
1260                 /*  broadcast ssid, however it is not allowed in assocreq */
1261                 status = _STATS_FAILURE_;
1262                 goto OnAssocReqFail;
1263         } else {
1264                 /*  check if ssid match */
1265                 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
1266                         status = _STATS_FAILURE_;
1267 
1268                 if (ie_len != cur->Ssid.SsidLength)
1269                         status = _STATS_FAILURE_;
1270         }
1271 
1272         if (status != _STATS_SUCCESSFUL_)
1273                 goto OnAssocReqFail;
1274 
1275         /*  check if the supported rate is ok */
1276         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1277         if (p == NULL) {
1278                 DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
1279                 /*  use our own rate set as statoin used */
1280                 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1281                 /* supportRateNum = AP_BSSRATE_LEN; */
1282 
1283                 status = _STATS_FAILURE_;
1284                 goto OnAssocReqFail;
1285         } else {
1286                 memcpy(supportRate, p+2, ie_len);
1287                 supportRateNum = ie_len;
1288 
1289                 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
1290                                 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1291                 if (p !=  NULL) {
1292 
1293                         if (supportRateNum <= sizeof(supportRate)) {
1294                                 memcpy(supportRate+supportRateNum, p+2, ie_len);
1295                                 supportRateNum += ie_len;
1296                         }
1297                 }
1298         }
1299 
1300         /* todo: mask supportRate between AP & STA -> move to update raid */
1301         /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1302 
1303         /* update station supportRate */
1304         pstat->bssratelen = supportRateNum;
1305         memcpy(pstat->bssrateset, supportRate, supportRateNum);
1306         UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1307 
1308         /* check RSN/WPA/WPS */
1309         pstat->dot8021xalg = 0;
1310         pstat->wpa_psk = 0;
1311         pstat->wpa_group_cipher = 0;
1312         pstat->wpa2_group_cipher = 0;
1313         pstat->wpa_pairwise_cipher = 0;
1314         pstat->wpa2_pairwise_cipher = 0;
1315         memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1316         if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
1317 
1318                 int group_cipher = 0, pairwise_cipher = 0;
1319 
1320                 wpa_ie = elems.rsn_ie;
1321                 wpa_ie_len = elems.rsn_ie_len;
1322 
1323                 if (rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1324                         pstat->dot8021xalg = 1;/* psk,  todo:802.1x */
1325                         pstat->wpa_psk |= BIT(1);
1326 
1327                         pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
1328                         pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
1329 
1330                         if (!pstat->wpa2_group_cipher)
1331                                 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1332 
1333                         if (!pstat->wpa2_pairwise_cipher)
1334                                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1335                 } else {
1336                         status = WLAN_STATUS_INVALID_IE;
1337                 }
1338 
1339         } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
1340 
1341                 int group_cipher = 0, pairwise_cipher = 0;
1342 
1343                 wpa_ie = elems.wpa_ie;
1344                 wpa_ie_len = elems.wpa_ie_len;
1345 
1346                 if (rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1347                         pstat->dot8021xalg = 1;/* psk,  todo:802.1x */
1348                         pstat->wpa_psk |= BIT(0);
1349 
1350                         pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
1351                         pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
1352 
1353                         if (!pstat->wpa_group_cipher)
1354                                 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1355 
1356                         if (!pstat->wpa_pairwise_cipher)
1357                                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1358 
1359                 } else {
1360                         status = WLAN_STATUS_INVALID_IE;
1361                 }
1362 
1363         } else {
1364                 wpa_ie = NULL;
1365                 wpa_ie_len = 0;
1366         }
1367 
1368         if (status != _STATS_SUCCESSFUL_)
1369                 goto OnAssocReqFail;
1370 
1371         pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1372         if (!wpa_ie) {
1373                 if (elems.wps_ie) {
1374                         DBG_871X("STA included WPS IE in "
1375                                    "(Re)Association Request - assume WPS is "
1376                                    "used\n");
1377                         pstat->flags |= WLAN_STA_WPS;
1378                         /* wpabuf_free(sta->wps_ie); */
1379                         /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */
1380                         /*                              elems.wps_ie_len - 4); */
1381                 } else {
1382                         DBG_871X("STA did not include WPA/RSN IE "
1383                                    "in (Re)Association Request - possible WPS "
1384                                    "use\n");
1385                         pstat->flags |= WLAN_STA_MAYBE_WPS;
1386                 }
1387 
1388 
1389                 /*  AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
1390                 /*  that the selected registrar of AP is _FLASE */
1391                 if ((psecuritypriv->wpa_psk > 0)
1392                         && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
1393                         if (pmlmepriv->wps_beacon_ie) {
1394                                 u8 selected_registrar = 0;
1395 
1396                                 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
1397 
1398                                 if (!selected_registrar) {
1399                                         DBG_871X("selected_registrar is false , or AP is not ready to do WPS\n");
1400 
1401                                         status = _STATS_UNABLE_HANDLE_STA_;
1402 
1403                                         goto OnAssocReqFail;
1404                                 }
1405                         }
1406                 }
1407 
1408         } else {
1409                 int copy_len;
1410 
1411                 if (psecuritypriv->wpa_psk == 0) {
1412                         DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
1413                         "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
1414 
1415                         status = WLAN_STATUS_INVALID_IE;
1416 
1417                         goto OnAssocReqFail;
1418 
1419                 }
1420 
1421                 if (elems.wps_ie) {
1422                         DBG_871X("STA included WPS IE in "
1423                                    "(Re)Association Request - WPS is "
1424                                    "used\n");
1425                         pstat->flags |= WLAN_STA_WPS;
1426                         copy_len = 0;
1427                 } else {
1428                         copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
1429                 }
1430 
1431 
1432                 if (copy_len > 0)
1433                         memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
1434 
1435         }
1436 
1437 
1438         /*  check if there is WMM IE & support WWM-PS */
1439         pstat->flags &= ~WLAN_STA_WME;
1440         pstat->qos_option = 0;
1441         pstat->qos_info = 0;
1442         pstat->has_legacy_ac = true;
1443         pstat->uapsd_vo = 0;
1444         pstat->uapsd_vi = 0;
1445         pstat->uapsd_be = 0;
1446         pstat->uapsd_bk = 0;
1447         if (pmlmepriv->qospriv.qos_option) {
1448                 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
1449                 for (;;) {
1450                         p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1451                         if (p != NULL) {
1452                                 if (!memcmp(p+2, WMM_IE, 6)) {
1453 
1454                                         pstat->flags |= WLAN_STA_WME;
1455 
1456                                         pstat->qos_option = 1;
1457                                         pstat->qos_info = *(p+8);
1458 
1459                                         pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
1460 
1461                                         if ((pstat->qos_info&0xf) != 0xf)
1462                                                 pstat->has_legacy_ac = true;
1463                                         else
1464                                                 pstat->has_legacy_ac = false;
1465 
1466                                         if (pstat->qos_info&0xf) {
1467                                                 if (pstat->qos_info&BIT(0))
1468                                                         pstat->uapsd_vo = BIT(0)|BIT(1);
1469                                                 else
1470                                                         pstat->uapsd_vo = 0;
1471 
1472                                                 if (pstat->qos_info&BIT(1))
1473                                                         pstat->uapsd_vi = BIT(0)|BIT(1);
1474                                                 else
1475                                                         pstat->uapsd_vi = 0;
1476 
1477                                                 if (pstat->qos_info&BIT(2))
1478                                                         pstat->uapsd_bk = BIT(0)|BIT(1);
1479                                                 else
1480                                                         pstat->uapsd_bk = 0;
1481 
1482                                                 if (pstat->qos_info&BIT(3))
1483                                                         pstat->uapsd_be = BIT(0)|BIT(1);
1484                                                 else
1485                                                         pstat->uapsd_be = 0;
1486 
1487                                         }
1488 
1489                                         break;
1490                                 }
1491                         } else {
1492                                 break;
1493                         }
1494                         p = p + ie_len + 2;
1495                 }
1496         }
1497 
1498         /* save HT capabilities in the sta object */
1499         memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
1500         if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) {
1501                 pstat->flags |= WLAN_STA_HT;
1502 
1503                 pstat->flags |= WLAN_STA_WME;
1504 
1505                 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
1506 
1507         } else
1508                 pstat->flags &= ~WLAN_STA_HT;
1509 
1510 
1511         if ((pmlmepriv->htpriv.ht_option == false) && (pstat->flags&WLAN_STA_HT)) {
1512                 status = _STATS_FAILURE_;
1513                 goto OnAssocReqFail;
1514         }
1515 
1516 
1517         if ((pstat->flags & WLAN_STA_HT) &&
1518                     ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1519                       (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP))) {
1520                 DBG_871X("HT: " MAC_FMT " tried to "
1521                                    "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
1522 
1523                 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1524                 /* goto OnAssocReqFail; */
1525         }
1526         pstat->flags |= WLAN_STA_NONERP;
1527         for (i = 0; i < pstat->bssratelen; i++) {
1528                 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1529                         pstat->flags &= ~WLAN_STA_NONERP;
1530                         break;
1531                 }
1532         }
1533 
1534         if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1535                 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1536         else
1537                 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1538 
1539 
1540 
1541         if (status != _STATS_SUCCESSFUL_)
1542                 goto OnAssocReqFail;
1543 
1544         /* TODO: identify_proprietary_vendor_ie(); */
1545         /*  Realtek proprietary IE */
1546         /*  identify if this is Broadcom sta */
1547         /*  identify if this is ralink sta */
1548         /*  Customer proprietary IE */
1549 
1550 
1551 
1552         /* get a unique AID */
1553         if (pstat->aid > 0) {
1554                 DBG_871X("  old AID %d\n", pstat->aid);
1555         } else {
1556                 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1557                         if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1558                                 break;
1559 
1560                 /* if (pstat->aid > NUM_STA) { */
1561                 if (pstat->aid > pstapriv->max_num_sta) {
1562 
1563                         pstat->aid = 0;
1564 
1565                         DBG_871X("  no room for more AIDs\n");
1566 
1567                         status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1568 
1569                         goto OnAssocReqFail;
1570 
1571 
1572                 } else {
1573                         pstapriv->sta_aid[pstat->aid - 1] = pstat;
1574                         DBG_871X("allocate new AID = (%d)\n", pstat->aid);
1575                 }
1576         }
1577 
1578 
1579         pstat->state &= (~WIFI_FW_ASSOC_STATE);
1580         pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1581 
1582         spin_lock_bh(&pstapriv->auth_list_lock);
1583         if (!list_empty(&pstat->auth_list)) {
1584                 list_del_init(&pstat->auth_list);
1585                 pstapriv->auth_list_cnt--;
1586         }
1587         spin_unlock_bh(&pstapriv->auth_list_lock);
1588 
1589         spin_lock_bh(&pstapriv->asoc_list_lock);
1590         if (list_empty(&pstat->asoc_list)) {
1591                 pstat->expire_to = pstapriv->expire_to;
1592                 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1593                 pstapriv->asoc_list_cnt++;
1594         }
1595         spin_unlock_bh(&pstapriv->asoc_list_lock);
1596 
1597         /*  now the station is qualified to join our BSS... */
1598         if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
1599                 /* 1 bss_cap_update & sta_info_update */
1600                 bss_cap_update_on_sta_join(padapter, pstat);
1601                 sta_info_update(padapter, pstat);
1602 
1603                 /* 2 issue assoc rsp before notify station join event. */
1604                 if (frame_type == WIFI_ASSOCREQ)
1605                         issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1606                 else
1607                         issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1608 
1609                 spin_lock_bh(&pstat->lock);
1610                 if (pstat->passoc_req) {
1611                         kfree(pstat->passoc_req);
1612                         pstat->passoc_req = NULL;
1613                         pstat->assoc_req_len = 0;
1614                 }
1615 
1616                 pstat->passoc_req =  rtw_zmalloc(pkt_len);
1617                 if (pstat->passoc_req) {
1618                         memcpy(pstat->passoc_req, pframe, pkt_len);
1619                         pstat->assoc_req_len = pkt_len;
1620                 }
1621                 spin_unlock_bh(&pstat->lock);
1622 
1623                 /* 3-(1) report sta add event */
1624                 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
1625         }
1626 
1627         return _SUCCESS;
1628 
1629 asoc_class2_error:
1630 
1631         issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
1632 
1633         return _FAIL;
1634 
1635 OnAssocReqFail:
1636 
1637         pstat->aid = 0;
1638         if (frame_type == WIFI_ASSOCREQ)
1639                 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1640         else
1641                 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1642 
1643         return _FAIL;
1644 }
1645 
1646 unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame)
1647 {
1648         uint i;
1649         int res;
1650         unsigned short  status;
1651         struct ndis_80211_var_ie *pIE;
1652         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1653         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1654         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1655         /* struct wlan_bssid_ex                 *cur_network = &(pmlmeinfo->network); */
1656         u8 *pframe = precv_frame->u.hdr.rx_data;
1657         uint pkt_len = precv_frame->u.hdr.len;
1658 
1659         DBG_871X("%s\n", __func__);
1660 
1661         /* check A1 matches or not */
1662         if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
1663                 return _SUCCESS;
1664 
1665         if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1666                 return _SUCCESS;
1667 
1668         if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1669                 return _SUCCESS;
1670 
1671         del_timer_sync(&pmlmeext->link_timer);
1672 
1673         /* status */
1674         status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2));
1675         if (status > 0) {
1676                 DBG_871X("assoc reject, status code: %d\n", status);
1677                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1678                 res = -4;
1679                 goto report_assoc_result;
1680         }
1681 
1682         /* get capabilities */
1683         pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1684 
1685         /* set slot time */
1686         pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
1687 
1688         /* AID */
1689         res = pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
1690 
1691         /* following are moved to join event callback function */
1692         /* to handle HT, WMM, rate adaptive, update MAC reg */
1693         /* for not to handle the synchronous IO in the tasklet */
1694         for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
1695                 pIE = (struct ndis_80211_var_ie *)(pframe + i);
1696 
1697                 switch (pIE->ElementID) {
1698                 case _VENDOR_SPECIFIC_IE_:
1699                         if (!memcmp(pIE->data, WMM_PARA_OUI, 6))        /* WMM */
1700                                 WMM_param_handler(padapter, pIE);
1701                         break;
1702 
1703                 case _HT_CAPABILITY_IE_:        /* HT caps */
1704                         HT_caps_handler(padapter, pIE);
1705                         break;
1706 
1707                 case _HT_EXTRA_INFO_IE_:        /* HT info */
1708                         HT_info_handler(padapter, pIE);
1709                         break;
1710 
1711                 case _ERPINFO_IE_:
1712                         ERP_IE_handler(padapter, pIE);
1713 
1714                 default:
1715                         break;
1716                 }
1717 
1718                 i += (pIE->Length + 2);
1719         }
1720 
1721         pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
1722         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1723 
1724         /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1725         UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
1726 
1727 report_assoc_result:
1728         if (res > 0) {
1729                 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
1730         } else {
1731                 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
1732         }
1733 
1734         report_join_res(padapter, res);
1735 
1736         return _SUCCESS;
1737 }
1738 
1739 unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame)
1740 {
1741         unsigned short  reason;
1742         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1743         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1744         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1745         u8 *pframe = precv_frame->u.hdr.rx_data;
1746 
1747         /* check A3 */
1748         if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1749                 return _SUCCESS;
1750 
1751         reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1752 
1753         DBG_871X("%s Reason code(%d)\n", __func__, reason);
1754 
1755         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1756                 struct sta_info *psta;
1757                 struct sta_priv *pstapriv = &padapter->stapriv;
1758 
1759                 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */
1760                 /* rtw_free_stainfo(padapter, psta); */
1761                 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
1762 
1763                 DBG_871X_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
1764                                 reason, GetAddr2Ptr(pframe));
1765 
1766                 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1767                 if (psta) {
1768                         u8 updated = false;
1769 
1770                         spin_lock_bh(&pstapriv->asoc_list_lock);
1771                         if (list_empty(&psta->asoc_list) == false) {
1772                                 list_del_init(&psta->asoc_list);
1773                                 pstapriv->asoc_list_cnt--;
1774                                 updated = ap_free_sta(padapter, psta, false, reason);
1775 
1776                         }
1777                         spin_unlock_bh(&pstapriv->asoc_list_lock);
1778 
1779                         associated_clients_update(padapter, updated);
1780                 }
1781 
1782 
1783                 return _SUCCESS;
1784         } else {
1785                 int     ignore_received_deauth = 0;
1786 
1787                 /*      Commented by Albert 20130604 */
1788                 /*      Before sending the auth frame to start the STA/GC mode connection with AP/GO, */
1789                 /*      we will send the deauth first. */
1790                 /*      However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */
1791                 /*      Added the following code to avoid this case. */
1792                 if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
1793                         (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
1794                         if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) {
1795                                 ignore_received_deauth = 1;
1796                         } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
1797                                 /*  TODO: 802.11r */
1798                                 ignore_received_deauth = 1;
1799                         }
1800                 }
1801 
1802                 DBG_871X_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n",
1803                                 reason, GetAddr3Ptr(pframe), ignore_received_deauth);
1804 
1805                 if (0 == ignore_received_deauth) {
1806                         receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1807                 }
1808         }
1809         pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1810         return _SUCCESS;
1811 
1812 }
1813 
1814 unsigned int OnDisassoc(struct adapter *padapter, union recv_frame *precv_frame)
1815 {
1816         unsigned short  reason;
1817         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1818         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1819         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1820         u8 *pframe = precv_frame->u.hdr.rx_data;
1821 
1822         /* check A3 */
1823         if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1824                 return _SUCCESS;
1825 
1826         reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1827 
1828         DBG_871X("%s Reason code(%d)\n", __func__, reason);
1829 
1830         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1831                 struct sta_info *psta;
1832                 struct sta_priv *pstapriv = &padapter->stapriv;
1833 
1834                 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */
1835                 /* rtw_free_stainfo(padapter, psta); */
1836                 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
1837 
1838                 DBG_871X_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
1839                                 reason, GetAddr2Ptr(pframe));
1840 
1841                 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1842                 if (psta) {
1843                         u8 updated = false;
1844 
1845                         spin_lock_bh(&pstapriv->asoc_list_lock);
1846                         if (list_empty(&psta->asoc_list) == false) {
1847                                 list_del_init(&psta->asoc_list);
1848                                 pstapriv->asoc_list_cnt--;
1849                                 updated = ap_free_sta(padapter, psta, false, reason);
1850 
1851                         }
1852                         spin_unlock_bh(&pstapriv->asoc_list_lock);
1853 
1854                         associated_clients_update(padapter, updated);
1855                 }
1856 
1857                 return _SUCCESS;
1858         } else {
1859                 DBG_871X_LEVEL(_drv_always_, "sta recv disassoc reason code(%d) sta:%pM\n",
1860                                 reason, GetAddr3Ptr(pframe));
1861 
1862                 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1863         }
1864         pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1865         return _SUCCESS;
1866 
1867 }
1868 
1869 unsigned int OnAtim(struct adapter *padapter, union recv_frame *precv_frame)
1870 {
1871         DBG_871X("%s\n", __func__);
1872         return _SUCCESS;
1873 }
1874 
1875 unsigned int on_action_spct(struct adapter *padapter, union recv_frame *precv_frame)
1876 {
1877         struct sta_info *psta = NULL;
1878         struct sta_priv *pstapriv = &padapter->stapriv;
1879         u8 *pframe = precv_frame->u.hdr.rx_data;
1880         u8 *frame_body = (u8 *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1881         u8 category;
1882         u8 action;
1883 
1884         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
1885 
1886         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1887 
1888         if (!psta)
1889                 goto exit;
1890 
1891         category = frame_body[0];
1892         if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
1893                 goto exit;
1894 
1895         action = frame_body[1];
1896         switch (action) {
1897         case RTW_WLAN_ACTION_SPCT_MSR_REQ:
1898         case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
1899         case RTW_WLAN_ACTION_SPCT_TPC_REQ:
1900         case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
1901         case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
1902                 break;
1903         default:
1904                 break;
1905         }
1906 
1907 exit:
1908         return _FAIL;
1909 }
1910 
1911 unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_frame)
1912 {
1913         u8 *addr;
1914         struct sta_info *psta = NULL;
1915         struct recv_reorder_ctrl *preorder_ctrl;
1916         unsigned char   *frame_body;
1917         unsigned char   category, action;
1918         unsigned short  tid, status, reason_code = 0;
1919         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1920         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1921         u8 *pframe = precv_frame->u.hdr.rx_data;
1922         struct sta_priv *pstapriv = &padapter->stapriv;
1923 
1924         DBG_871X("%s\n", __func__);
1925 
1926         /* check RA matches or not */
1927         if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
1928                 return _SUCCESS;
1929 
1930         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1931                 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1932                         return _SUCCESS;
1933 
1934         addr = GetAddr2Ptr(pframe);
1935         psta = rtw_get_stainfo(pstapriv, addr);
1936 
1937         if (!psta)
1938                 return _SUCCESS;
1939 
1940         frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1941 
1942         category = frame_body[0];
1943         if (category == RTW_WLAN_CATEGORY_BACK) {/*  representing Block Ack */
1944                 if (!pmlmeinfo->HT_enable)
1945                         return _SUCCESS;
1946 
1947                 action = frame_body[1];
1948                 DBG_871X("%s, action =%d\n", __func__, action);
1949                 switch (action) {
1950                 case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
1951 
1952                         memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
1953                         /* process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
1954                         process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
1955 
1956                         if (pmlmeinfo->accept_addba_req) {
1957                                 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
1958                         } else {
1959                                 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */
1960                         }
1961 
1962                         break;
1963 
1964                 case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
1965                         status = RTW_GET_LE16(&frame_body[3]);
1966                         tid = ((frame_body[5] >> 2) & 0x7);
1967 
1968                         if (status == 0) {
1969                                 /* successful */
1970                                 DBG_871X("agg_enable for TID =%d\n", tid);
1971                                 psta->htpriv.agg_enable_bitmap |= BIT(tid);
1972                                 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
1973                         } else {
1974                                 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
1975                         }
1976 
1977                         if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1978                                 DBG_871X("%s alive check - rx ADDBA response\n", __func__);
1979                                 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
1980                                 psta->expire_to = pstapriv->expire_to;
1981                                 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1982                         }
1983 
1984                         /* DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */
1985                         break;
1986 
1987                 case RTW_WLAN_ACTION_DELBA: /* DELBA */
1988                         if ((frame_body[3] & BIT(3)) == 0) {
1989                                 psta->htpriv.agg_enable_bitmap &=
1990                                         ~BIT((frame_body[3] >> 4) & 0xf);
1991                                 psta->htpriv.candidate_tid_bitmap &=
1992                                         ~BIT((frame_body[3] >> 4) & 0xf);
1993 
1994                                 /* reason_code = frame_body[4] | (frame_body[5] << 8); */
1995                                 reason_code = RTW_GET_LE16(&frame_body[4]);
1996                         } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
1997                                 tid = (frame_body[3] >> 4) & 0x0F;
1998 
1999                                 preorder_ctrl =  &psta->recvreorder_ctrl[tid];
2000                                 preorder_ctrl->enable = false;
2001                                 preorder_ctrl->indicate_seq = 0xffff;
2002                                 #ifdef DBG_RX_SEQ
2003                                 DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __func__, __LINE__,
2004                                         preorder_ctrl->indicate_seq);
2005                                 #endif
2006                         }
2007 
2008                         DBG_871X("%s(): DELBA: %x(%x)\n", __func__, pmlmeinfo->agg_enable_bitmap, reason_code);
2009                         /* todo: how to notify the host while receiving DELETE BA */
2010                         break;
2011 
2012                 default:
2013                         break;
2014                 }
2015         }
2016         return _SUCCESS;
2017 }
2018 
2019 static s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
2020 {
2021         struct adapter *adapter = recv_frame->u.hdr.adapter;
2022         struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
2023         u8 *frame = recv_frame->u.hdr.rx_data;
2024         u16 seq_ctrl = ((recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
2025                 (recv_frame->u.hdr.attrib.frag_num & 0xf);
2026 
2027         if (GetRetry(frame)) {
2028                 if (token >= 0) {
2029                         if ((seq_ctrl == mlmeext->action_public_rxseq)
2030                                 && (token == mlmeext->action_public_dialog_token)) {
2031                                 DBG_871X(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n",
2032                                         FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
2033                                 return _FAIL;
2034                         }
2035                 } else {
2036                         if (seq_ctrl == mlmeext->action_public_rxseq) {
2037                                 DBG_871X(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x\n",
2038                                         FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
2039                                 return _FAIL;
2040                         }
2041                 }
2042         }
2043 
2044         mlmeext->action_public_rxseq = seq_ctrl;
2045 
2046         if (token >= 0)
2047                 mlmeext->action_public_dialog_token = token;
2048 
2049         return _SUCCESS;
2050 }
2051 
2052 static unsigned int on_action_public_p2p(union recv_frame *precv_frame)
2053 {
2054         u8 *pframe = precv_frame->u.hdr.rx_data;
2055         u8 *frame_body;
2056         u8 dialogToken = 0;
2057 
2058         frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
2059 
2060         dialogToken = frame_body[7];
2061 
2062         if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
2063                 return _FAIL;
2064 
2065         return _SUCCESS;
2066 }
2067 
2068 static unsigned int on_action_public_vendor(union recv_frame *precv_frame)
2069 {
2070         unsigned int ret = _FAIL;
2071         u8 *pframe = precv_frame->u.hdr.rx_data;
2072         u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2073 
2074         if (!memcmp(frame_body + 2, P2P_OUI, 4)) {
2075                 ret = on_action_public_p2p(precv_frame);
2076         }
2077 
2078         return ret;
2079 }
2080 
2081 static unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
2082 {
2083         unsigned int ret = _FAIL;
2084         u8 *pframe = precv_frame->u.hdr.rx_data;
2085         uint frame_len = precv_frame->u.hdr.len;
2086         u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2087         u8 token;
2088         struct adapter *adapter = precv_frame->u.hdr.adapter;
2089         int cnt = 0;
2090         char msg[64];
2091 
2092         token = frame_body[2];
2093 
2094         if (rtw_action_public_decache(precv_frame, token) == _FAIL)
2095                 goto exit;
2096 
2097         cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
2098         rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
2099 
2100         ret = _SUCCESS;
2101 
2102 exit:
2103         return ret;
2104 }
2105 
2106 unsigned int on_action_public(struct adapter *padapter, union recv_frame *precv_frame)
2107 {
2108         unsigned int ret = _FAIL;
2109         u8 *pframe = precv_frame->u.hdr.rx_data;
2110         u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2111         u8 category, action;
2112 
2113         /* check RA matches or not */
2114         if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
2115                 goto exit;
2116 
2117         category = frame_body[0];
2118         if (category != RTW_WLAN_CATEGORY_PUBLIC)
2119                 goto exit;
2120 
2121         action = frame_body[1];
2122         switch (action) {
2123         case ACT_PUBLIC_VENDOR:
2124                 ret = on_action_public_vendor(precv_frame);
2125                 break;
2126         default:
2127                 ret = on_action_public_default(precv_frame, action);
2128                 break;
2129         }
2130 
2131 exit:
2132         return ret;
2133 }
2134 
2135 unsigned int OnAction_ht(struct adapter *padapter, union recv_frame *precv_frame)
2136 {
2137         u8 *pframe = precv_frame->u.hdr.rx_data;
2138         u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2139         u8 category, action;
2140 
2141         /* check RA matches or not */
2142         if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
2143                 goto exit;
2144 
2145         category = frame_body[0];
2146         if (category != RTW_WLAN_CATEGORY_HT)
2147                 goto exit;
2148 
2149         action = frame_body[1];
2150         switch (action) {
2151         case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
2152                 break;
2153         default:
2154                 break;
2155         }
2156 
2157 exit:
2158 
2159         return _SUCCESS;
2160 }
2161 
2162 unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv_frame)
2163 {
2164         u8 *pframe = precv_frame->u.hdr.rx_data;
2165         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2166         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2167         unsigned short tid;
2168         /* Baron */
2169 
2170         DBG_871X("OnAction_sa_query\n");
2171 
2172         switch (pframe[WLAN_HDR_A3_LEN+1]) {
2173         case 0: /* SA Query req */
2174                 memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short));
2175                 DBG_871X("OnAction_sa_query request, action =%d, tid =%04x\n", pframe[WLAN_HDR_A3_LEN+1], tid);
2176                 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid);
2177                 break;
2178 
2179         case 1: /* SA Query rsp */
2180                 del_timer_sync(&pmlmeext->sa_query_timer);
2181                 DBG_871X("OnAction_sa_query response, action =%d, tid =%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], pframe[WLAN_HDR_A3_LEN+2]);
2182                 break;
2183         default:
2184                 break;
2185         }
2186         if (0) {
2187                 int pp;
2188                 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
2189                 for (pp = 0; pp < pattrib->pkt_len; pp++)
2190                         printk(" %02x ", pframe[pp]);
2191                 printk("\n");
2192         }
2193 
2194         return _SUCCESS;
2195 }
2196 
2197 unsigned int OnAction(struct adapter *padapter, union recv_frame *precv_frame)
2198 {
2199         int i;
2200         unsigned char category;
2201         struct action_handler *ptable;
2202         unsigned char *frame_body;
2203         u8 *pframe = precv_frame->u.hdr.rx_data;
2204 
2205         frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
2206 
2207         category = frame_body[0];
2208 
2209         for (i = 0; i < ARRAY_SIZE(OnAction_tbl); i++) {
2210                 ptable = &OnAction_tbl[i];
2211 
2212                 if (category == ptable->num)
2213                         ptable->func(padapter, precv_frame);
2214 
2215         }
2216 
2217         return _SUCCESS;
2218 
2219 }
2220 
2221 unsigned int DoReserved(struct adapter *padapter, union recv_frame *precv_frame)
2222 {
2223 
2224         /* DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
2225         return _SUCCESS;
2226 }
2227 
2228 static struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
2229 {
2230         struct xmit_frame *pmgntframe;
2231         struct xmit_buf *pxmitbuf;
2232 
2233         if (once)
2234                 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
2235         else
2236                 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
2237 
2238         if (pmgntframe == NULL) {
2239                 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
2240                 goto exit;
2241         }
2242 
2243         pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
2244         if (pxmitbuf == NULL) {
2245                 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
2246                 rtw_free_xmitframe(pxmitpriv, pmgntframe);
2247                 pmgntframe = NULL;
2248                 goto exit;
2249         }
2250 
2251         pmgntframe->frame_tag = MGNT_FRAMETAG;
2252         pmgntframe->pxmitbuf = pxmitbuf;
2253         pmgntframe->buf_addr = pxmitbuf->pbuf;
2254         pxmitbuf->priv_data = pmgntframe;
2255 
2256 exit:
2257         return pmgntframe;
2258 
2259 }
2260 
2261 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
2262 {
2263         return _alloc_mgtxmitframe(pxmitpriv, false);
2264 }
2265 
2266 /****************************************************************************
2267 
2268 Following are some TX fuctions for WiFi MLME
2269 
2270 *****************************************************************************/
2271 
2272 void update_mgnt_tx_rate(struct adapter *padapter, u8 rate)
2273 {
2274         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2275 
2276         pmlmeext->tx_rate = rate;
2277         /* DBG_871X("%s(): rate = %x\n", __func__, rate); */
2278 }
2279 
2280 void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib)
2281 {
2282         u8 wireless_mode;
2283         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2284 
2285         /* memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); */
2286 
2287         pattrib->hdrlen = 24;
2288         pattrib->nr_frags = 1;
2289         pattrib->priority = 7;
2290         pattrib->mac_id = 0;
2291         pattrib->qsel = 0x12;
2292 
2293         pattrib->pktlen = 0;
2294 
2295         if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
2296                 wireless_mode = WIRELESS_11B;
2297         else
2298                 wireless_mode = WIRELESS_11G;
2299         pattrib->raid =  rtw_get_mgntframe_raid(padapter, wireless_mode);
2300         pattrib->rate = pmlmeext->tx_rate;
2301 
2302         pattrib->encrypt = _NO_PRIVACY_;
2303         pattrib->bswenc = false;
2304 
2305         pattrib->qos_en = false;
2306         pattrib->ht_en = false;
2307         pattrib->bwmode = CHANNEL_WIDTH_20;
2308         pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2309         pattrib->sgi = false;
2310 
2311         pattrib->seqnum = pmlmeext->mgnt_seq;
2312 
2313         pattrib->retry_ctrl = true;
2314 
2315         pattrib->mbssid = 0;
2316 
2317 }
2318 
2319 void update_mgntframe_attrib_addr(struct adapter *padapter, struct xmit_frame *pmgntframe)
2320 {
2321         u8 *pframe;
2322         struct pkt_attrib       *pattrib = &pmgntframe->attrib;
2323 
2324         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2325 
2326         memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
2327         memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
2328 }
2329 
2330 void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe)
2331 {
2332         if (padapter->bSurpriseRemoved ||
2333                 padapter->bDriverStopped) {
2334                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2335                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2336                 return;
2337         }
2338 
2339         rtw_hal_mgnt_xmit(padapter, pmgntframe);
2340 }
2341 
2342 s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
2343 {
2344         s32 ret = _FAIL;
2345         _irqL irqL;
2346         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2347         struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2348         struct submit_ctx sctx;
2349 
2350         if (padapter->bSurpriseRemoved ||
2351                 padapter->bDriverStopped) {
2352                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2353                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2354                 return ret;
2355         }
2356 
2357         rtw_sctx_init(&sctx, timeout_ms);
2358         pxmitbuf->sctx = &sctx;
2359 
2360         ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
2361 
2362         if (ret == _SUCCESS)
2363                 ret = rtw_sctx_wait(&sctx, __func__);
2364 
2365         spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2366         pxmitbuf->sctx = NULL;
2367         spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2368 
2369         return ret;
2370 }
2371 
2372 s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe)
2373 {
2374         static u8 seq_no;
2375         s32 ret = _FAIL;
2376         u32 timeout_ms = 500;/*   500ms */
2377         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2378 
2379         if (padapter->bSurpriseRemoved ||
2380                 padapter->bDriverStopped) {
2381                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2382                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2383                 return -1;
2384         }
2385 
2386         if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex) == 0) {
2387                 pxmitpriv->ack_tx = true;
2388                 pxmitpriv->seq_no = seq_no++;
2389                 pmgntframe->ack_report = 1;
2390                 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
2391                         ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
2392 
2393                 pxmitpriv->ack_tx = false;
2394                 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2395         }
2396 
2397         return ret;
2398 }
2399 
2400 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2401 {
2402         u8 *ssid_ie;
2403         sint ssid_len_ori;
2404         int len_diff = 0;
2405 
2406         ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
2407 
2408         /* DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2409 
2410         if (ssid_ie && ssid_len_ori > 0) {
2411                 switch (hidden_ssid_mode) {
2412                 case 1:
2413                 {
2414                         u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
2415                         u32 remain_len = 0;
2416 
2417                         remain_len = ies_len - (next_ie-ies);
2418 
2419                         ssid_ie[1] = 0;
2420                         memcpy(ssid_ie+2, next_ie, remain_len);
2421                         len_diff -= ssid_len_ori;
2422 
2423                         break;
2424                 }
2425                 case 2:
2426                         memset(&ssid_ie[2], 0, ssid_len_ori);
2427                         break;
2428                 default:
2429                         break;
2430         }
2431         }
2432 
2433         return len_diff;
2434 }
2435 
2436 void issue_beacon(struct adapter *padapter, int timeout_ms)
2437 {
2438         struct xmit_frame       *pmgntframe;
2439         struct pkt_attrib       *pattrib;
2440         unsigned char *pframe;
2441         struct ieee80211_hdr *pwlanhdr;
2442         __le16 *fctrl;
2443         unsigned int    rate_len;
2444         struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2445         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2446         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2447         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2448         struct wlan_bssid_ex            *cur_network = &(pmlmeinfo->network);
2449         u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2450 
2451         /* DBG_871X("%s\n", __func__); */
2452 
2453         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2454         if (!pmgntframe) {
2455                 DBG_871X("%s, alloc mgnt frame fail\n", __func__);
2456                 return;
2457         }
2458 
2459         spin_lock_bh(&pmlmepriv->bcn_update_lock);
2460 
2461         /* update attribute */
2462         pattrib = &pmgntframe->attrib;
2463         update_mgntframe_attrib(padapter, pattrib);
2464         pattrib->qsel = 0x10;
2465 
2466         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2467 
2468         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2469         pwlanhdr = (struct ieee80211_hdr *)pframe;
2470 
2471 
2472         fctrl = &(pwlanhdr->frame_control);
2473         *(fctrl) = 0;
2474 
2475         memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
2476         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2477         memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
2478 
2479         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
2480         /* pmlmeext->mgnt_seq++; */
2481         SetFrameSubType(pframe, WIFI_BEACON);
2482 
2483         pframe += sizeof(struct ieee80211_hdr_3addr);
2484         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2485 
2486         if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2487                 /* DBG_871X("ie len =%d\n", cur_network->IELength); */
2488                 {
2489                         int len_diff;
2490                         memcpy(pframe, cur_network->IEs, cur_network->IELength);
2491                         len_diff = update_hidden_ssid(
2492                                 pframe+_BEACON_IE_OFFSET_
2493                                 , cur_network->IELength-_BEACON_IE_OFFSET_
2494                                 , pmlmeinfo->hidden_ssid_mode
2495                         );
2496                         pframe += (cur_network->IELength+len_diff);
2497                         pattrib->pktlen += (cur_network->IELength+len_diff);
2498                 }
2499 
2500                 {
2501                         u8 *wps_ie;
2502                         uint wps_ielen;
2503                         u8 sr = 0;
2504                         wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
2505                                 pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
2506                         if (wps_ie && wps_ielen > 0) {
2507                                 rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
2508                         }
2509                         if (sr != 0)
2510                                 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2511                         else
2512                                 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2513                 }
2514 
2515                 goto _issue_bcn;
2516 
2517         }
2518 
2519         /* below for ad-hoc mode */
2520 
2521         /* timestamp will be inserted by hardware */
2522         pframe += 8;
2523         pattrib->pktlen += 8;
2524 
2525         /*  beacon interval: 2 bytes */
2526 
2527         memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
2528 
2529         pframe += 2;
2530         pattrib->pktlen += 2;
2531 
2532         /*  capability info: 2 bytes */
2533 
2534         memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2535 
2536         pframe += 2;
2537         pattrib->pktlen += 2;
2538 
2539         /*  SSID */
2540         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
2541 
2542         /*  supported rates... */
2543         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2544         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
2545 
2546         /*  DS parameter set */
2547         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
2548 
2549         /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2550         {
2551                 u8 erpinfo = 0;
2552                 u32 ATIMWindow;
2553                 /*  IBSS Parameter Set... */
2554                 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2555                 ATIMWindow = 0;
2556                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
2557 
2558                 /* ERP IE */
2559                 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
2560         }
2561 
2562 
2563         /*  EXTERNDED SUPPORTED RATE */
2564         if (rate_len > 8) {
2565                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
2566         }
2567 
2568 
2569         /* todo:HT for adhoc */
2570 
2571 _issue_bcn:
2572 
2573         pmlmepriv->update_bcn = false;
2574 
2575         spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2576 
2577         if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2578                 DBG_871X("beacon frame too large\n");
2579                 return;
2580         }
2581 
2582         pattrib->last_txcmdsz = pattrib->pktlen;
2583 
2584         /* DBG_871X("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2585         if (timeout_ms > 0)
2586                 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
2587         else
2588                 dump_mgntframe(padapter, pmgntframe);
2589 
2590 }
2591 
2592 void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
2593 {
2594         struct xmit_frame                       *pmgntframe;
2595         struct pkt_attrib                       *pattrib;
2596         unsigned char                           *pframe;
2597         struct ieee80211_hdr    *pwlanhdr;
2598         __le16 *fctrl;
2599         unsigned char                           *mac, *bssid;
2600         struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2601 
2602         u8 *pwps_ie;
2603         uint wps_ielen;
2604         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2605         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2606         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2607         struct wlan_bssid_ex            *cur_network = &(pmlmeinfo->network);
2608         unsigned int    rate_len;
2609 
2610         /* DBG_871X("%s\n", __func__); */
2611 
2612         if (da == NULL)
2613                 return;
2614 
2615         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2616         if (pmgntframe == NULL) {
2617                 DBG_871X("%s, alloc mgnt frame fail\n", __func__);
2618                 return;
2619         }
2620 
2621 
2622         /* update attribute */
2623         pattrib = &pmgntframe->attrib;
2624         update_mgntframe_attrib(padapter, pattrib);
2625 
2626         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2627 
2628         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2629         pwlanhdr = (struct ieee80211_hdr *)pframe;
2630 
2631         mac = myid(&(padapter->eeprompriv));
2632         bssid = cur_network->MacAddress;
2633 
2634         fctrl = &(pwlanhdr->frame_control);
2635         *(fctrl) = 0;
2636         memcpy(pwlanhdr->addr1, da, ETH_ALEN);
2637         memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
2638         memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
2639 
2640         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2641         pmlmeext->mgnt_seq++;
2642         SetFrameSubType(fctrl, WIFI_PROBERSP);
2643 
2644         pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2645         pattrib->pktlen = pattrib->hdrlen;
2646         pframe += pattrib->hdrlen;
2647 
2648 
2649         if (cur_network->IELength > MAX_IE_SZ)
2650                 return;
2651 
2652         if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2653                 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
2654 
2655                 /* inerset & update wps_probe_resp_ie */
2656                 if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) {
2657                         uint wps_offset, remainder_ielen;
2658                         u8 *premainder_ie;
2659 
2660                         wps_offset = (uint)(pwps_ie - cur_network->IEs);
2661 
2662                         premainder_ie = pwps_ie + wps_ielen;
2663 
2664                         remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
2665 
2666                         memcpy(pframe, cur_network->IEs, wps_offset);
2667                         pframe += wps_offset;
2668                         pattrib->pktlen += wps_offset;
2669 
2670                         wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
2671                         if ((wps_offset+wps_ielen+2) <= MAX_IE_SZ) {
2672                                 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
2673                                 pframe += wps_ielen+2;
2674                                 pattrib->pktlen += wps_ielen+2;
2675                         }
2676 
2677                         if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
2678                                 memcpy(pframe, premainder_ie, remainder_ielen);
2679                                 pframe += remainder_ielen;
2680                                 pattrib->pktlen += remainder_ielen;
2681                         }
2682                 } else {
2683                         memcpy(pframe, cur_network->IEs, cur_network->IELength);
2684                         pframe += cur_network->IELength;
2685                         pattrib->pktlen += cur_network->IELength;
2686                 }
2687 
2688                 /* retrieve SSID IE from cur_network->Ssid */
2689                 {
2690                         u8 *ssid_ie;
2691                         sint ssid_ielen;
2692                         sint ssid_ielen_diff;
2693                         u8 buf[MAX_IE_SZ];
2694                         u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr);
2695 
2696                         ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
2697                                 (pframe-ies)-_FIXED_IE_LENGTH_);
2698 
2699                         ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
2700 
2701                         if (ssid_ie &&  cur_network->Ssid.SsidLength) {
2702                                 uint remainder_ielen;
2703                                 u8 *remainder_ie;
2704                                 remainder_ie = ssid_ie+2;
2705                                 remainder_ielen = (pframe-remainder_ie);
2706 
2707                                 if (remainder_ielen > MAX_IE_SZ) {
2708                                         DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
2709                                         remainder_ielen = MAX_IE_SZ;
2710                                 }
2711 
2712                                 memcpy(buf, remainder_ie, remainder_ielen);
2713                                 memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
2714                                 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
2715                                 memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
2716 
2717                                 pframe += ssid_ielen_diff;
2718                                 pattrib->pktlen += ssid_ielen_diff;
2719                         }
2720                 }
2721         } else {
2722                 /* timestamp will be inserted by hardware */
2723                 pframe += 8;
2724                 pattrib->pktlen += 8;
2725 
2726                 /*  beacon interval: 2 bytes */
2727 
2728                 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
2729 
2730                 pframe += 2;
2731                 pattrib->pktlen += 2;
2732 
2733                 /*  capability info: 2 bytes */
2734 
2735                 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2736 
2737                 pframe += 2;
2738                 pattrib->pktlen += 2;
2739 
2740                 /* below for ad-hoc mode */
2741 
2742                 /*  SSID */
2743                 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
2744 
2745                 /*  supported rates... */
2746                 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2747                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
2748 
2749                 /*  DS parameter set */
2750                 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
2751 
2752                 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
2753                         u8 erpinfo = 0;
2754                         u32 ATIMWindow;
2755                         /*  IBSS Parameter Set... */
2756                         /* ATIMWindow = cur->Configuration.ATIMWindow; */
2757                         ATIMWindow = 0;
2758                         pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
2759 
2760                         /* ERP IE */
2761                         pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
2762                 }
2763 
2764 
2765                 /*  EXTERNDED SUPPORTED RATE */
2766                 if (rate_len > 8) {
2767                         pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
2768                 }
2769 
2770 
2771                 /* todo:HT for adhoc */
2772 
2773         }
2774 
2775 #ifdef CONFIG_AUTO_AP_MODE
2776 {
2777         struct sta_info *psta;
2778         struct sta_priv *pstapriv = &padapter->stapriv;
2779 
2780         DBG_871X("(%s)\n", __func__);
2781 
2782         /* check rc station */
2783         psta = rtw_get_stainfo(pstapriv, da);
2784         if (psta && psta->isrc && psta->pid > 0) {
2785                 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
2786                 u8 RC_INFO[14] = {0};
2787                 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
2788                 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
2789 
2790                 DBG_871X("%s, reply rc(pid = 0x%x) device "MAC_FMT" in ch =%d\n", __func__,
2791                         psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
2792 
2793                 /* append vendor specific ie */
2794                 memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
2795                 memcpy(&RC_INFO[4], mac, ETH_ALEN);
2796                 memcpy(&RC_INFO[10], (u8 *)&psta->pid, 2);
2797                 memcpy(&RC_INFO[12], (u8 *)&cu_ch, 2);
2798 
2799                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
2800         }
2801 }
2802 #endif /* CONFIG_AUTO_AP_MODE */
2803 
2804 
2805         pattrib->last_txcmdsz = pattrib->pktlen;
2806 
2807 
2808         dump_mgntframe(padapter, pmgntframe);
2809 
2810         return;
2811 
2812 }
2813 
2814 static int _issue_probereq(struct adapter *padapter,
2815                            struct ndis_802_11_ssid *pssid,
2816                            u8 *da, u8 ch, bool append_wps, bool wait_ack)
2817 {
2818         int ret = _FAIL;
2819         struct xmit_frame               *pmgntframe;
2820         struct pkt_attrib               *pattrib;
2821         unsigned char           *pframe;
2822         struct ieee80211_hdr    *pwlanhdr;
2823         __le16 *fctrl;
2824         unsigned char           *mac;
2825         unsigned char           bssrate[NumRates];
2826         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
2827         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2828         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2829         int     bssrate_len = 0;
2830         u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2831 
2832         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+issue_probereq\n"));
2833 
2834         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2835         if (!pmgntframe)
2836                 goto exit;
2837 
2838         /* update attribute */
2839         pattrib = &pmgntframe->attrib;
2840         update_mgntframe_attrib(padapter, pattrib);
2841 
2842 
2843         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2844 
2845         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2846         pwlanhdr = (struct ieee80211_hdr *)pframe;
2847 
2848         mac = myid(&(padapter->eeprompriv));
2849 
2850         fctrl = &(pwlanhdr->frame_control);
2851         *(fctrl) = 0;
2852 
2853         if (da) {
2854                 /*      unicast probe request frame */
2855                 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
2856                 memcpy(pwlanhdr->addr3, da, ETH_ALEN);
2857         } else {
2858                 /*      broadcast probe request frame */
2859                 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
2860                 memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
2861         }
2862 
2863         memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
2864 
2865         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2866         pmlmeext->mgnt_seq++;
2867         SetFrameSubType(pframe, WIFI_PROBEREQ);
2868 
2869         pframe += sizeof(struct ieee80211_hdr_3addr);
2870         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2871 
2872         if (pssid)
2873                 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
2874         else
2875                 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
2876 
2877         get_rate_set(padapter, bssrate, &bssrate_len);
2878 
2879         if (bssrate_len > 8) {
2880                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen));
2881                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
2882         } else {
2883                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen));
2884         }
2885 
2886         if (ch)
2887                 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
2888 
2889         if (append_wps) {
2890                 /* add wps_ie for wps2.0 */
2891                 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
2892                         memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
2893                         pframe += pmlmepriv->wps_probe_req_ie_len;
2894                         pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2895                 }
2896         }
2897 
2898         pattrib->last_txcmdsz = pattrib->pktlen;
2899 
2900         RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2901 
2902         if (wait_ack) {
2903                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
2904         } else {
2905                 dump_mgntframe(padapter, pmgntframe);
2906                 ret = _SUCCESS;
2907         }
2908 
2909 exit:
2910         return ret;
2911 }
2912 
2913 inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da)
2914 {
2915         _issue_probereq(padapter, pssid, da, 0, 1, false);
2916 }
2917 
2918 int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, u8 ch, bool append_wps,
2919         int try_cnt, int wait_ms)
2920 {
2921         int ret;
2922         int i = 0;
2923 
2924         do {
2925                 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms > 0?true:false);
2926 
2927                 i++;
2928 
2929                 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2930                         break;
2931 
2932                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2933                         msleep(wait_ms);
2934 
2935         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2936 
2937         if (ret != _FAIL) {
2938                 ret = _SUCCESS;
2939                 #ifndef DBG_XMIT_ACK
2940                 goto exit;
2941                 #endif
2942         }
2943 
2944         if (try_cnt && wait_ms) {
2945                 if (da)
2946                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
2947                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
2948                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
2949                 else
2950                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
2951                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
2952                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
2953         }
2954 exit:
2955         return ret;
2956 }
2957 
2958 /*  if psta == NULL, indiate we are station(client) now... */
2959 void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status)
2960 {
2961         struct xmit_frame                       *pmgntframe;
2962         struct pkt_attrib                       *pattrib;
2963         unsigned char                           *pframe;
2964         struct ieee80211_hdr    *pwlanhdr;
2965         __le16 *fctrl;
2966         unsigned int                                    val32;
2967         unsigned short                          val16;
2968         int use_shared_key = 0;
2969         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
2970         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2971         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2972         __le16 le_tmp;
2973 
2974         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2975         if (pmgntframe == NULL)
2976                 return;
2977 
2978         /* update attribute */
2979         pattrib = &pmgntframe->attrib;
2980         update_mgntframe_attrib(padapter, pattrib);
2981 
2982         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2983 
2984         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2985         pwlanhdr = (struct ieee80211_hdr *)pframe;
2986 
2987         fctrl = &(pwlanhdr->frame_control);
2988         *(fctrl) = 0;
2989 
2990         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2991         pmlmeext->mgnt_seq++;
2992         SetFrameSubType(pframe, WIFI_AUTH);
2993 
2994         pframe += sizeof(struct ieee80211_hdr_3addr);
2995         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2996 
2997 
2998         if (psta) { /*  for AP mode */
2999                 memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
3000                 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3001                 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
3002 
3003                 /*  setting auth algo number */
3004                 val16 = (u16)psta->authalg;
3005 
3006                 if (status != _STATS_SUCCESSFUL_)
3007                         val16 = 0;
3008 
3009                 if (val16)
3010                         use_shared_key = 1;
3011 
3012                 le_tmp = cpu_to_le16(val16);
3013 
3014                 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3015 
3016                 /*  setting auth seq number */
3017                 val16 = (u16)psta->auth_seq;
3018                 le_tmp = cpu_to_le16(val16);
3019                 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3020 
3021                 /*  setting status code... */
3022                 val16 = status;
3023                 le_tmp = cpu_to_le16(val16);
3024                 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3025 
3026                 /*  added challenging text... */
3027                 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
3028                         pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
3029 
3030         } else {
3031                 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
3032                 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
3033                 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
3034 
3035                 /*  setting auth algo number */
3036                 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/*  0:OPEN System, 1:Shared key */
3037                 if (val16) {
3038                         use_shared_key = 1;
3039                 }
3040                 le_tmp = cpu_to_le16(val16);
3041                 /* DBG_871X("%s auth_algo = %s auth_seq =%d\n", __func__, (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED", pmlmeinfo->auth_seq); */
3042 
3043                 /* setting IV for auth seq #3 */
3044                 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
3045                         __le32 le_tmp32;
3046 
3047                         /* DBG_871X("==> iv(%d), key_index(%d)\n", pmlmeinfo->iv, pmlmeinfo->key_index); */
3048                         val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
3049                         le_tmp32 = cpu_to_le32(val32);
3050                         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &(pattrib->pktlen));
3051 
3052                         pattrib->iv_len = 4;
3053                 }
3054 
3055                 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3056 
3057                 /*  setting auth seq number */
3058                 le_tmp = cpu_to_le16(pmlmeinfo->auth_seq);
3059                 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3060 
3061 
3062                 /*  setting status code... */
3063                 le_tmp = cpu_to_le16(status);
3064                 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3065 
3066                 /*  then checking to see if sending challenging text... */
3067                 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
3068                         pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
3069 
3070                         SetPrivacy(fctrl);
3071 
3072                         pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3073 
3074                         pattrib->encrypt = _WEP40_;
3075 
3076                         pattrib->icv_len = 4;
3077 
3078                         pattrib->pktlen += pattrib->icv_len;
3079 
3080                 }
3081 
3082         }
3083 
3084         pattrib->last_txcmdsz = pattrib->pktlen;
3085 
3086         rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
3087         DBG_871X("%s\n", __func__);
3088         dump_mgntframe(padapter, pmgntframe);
3089 
3090         return;
3091 }
3092 
3093 
3094 void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
3095 {
3096         struct xmit_frame       *pmgntframe;
3097         struct ieee80211_hdr    *pwlanhdr;
3098         struct pkt_attrib *pattrib;
3099         unsigned char *pbuf, *pframe;
3100         unsigned short val;
3101         __le16 *fctrl;
3102         struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3103         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3104         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3105         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3106         struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
3107         u8 *ie = pnetwork->IEs;
3108         __le16 lestatus, le_tmp;
3109 
3110         DBG_871X("%s\n", __func__);
3111 
3112         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3113         if (pmgntframe == NULL)
3114                 return;
3115 
3116         /* update attribute */
3117         pattrib = &pmgntframe->attrib;
3118         update_mgntframe_attrib(padapter, pattrib);
3119 
3120 
3121         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3122 
3123         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3124         pwlanhdr = (struct ieee80211_hdr *)pframe;
3125 
3126         fctrl = &(pwlanhdr->frame_control);
3127         *(fctrl) = 0;
3128 
3129         memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
3130         memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
3131         memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3132 
3133 
3134         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3135         pmlmeext->mgnt_seq++;
3136         if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
3137                 SetFrameSubType(pwlanhdr, pkt_type);
3138         else
3139                 return;
3140 
3141         pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3142         pattrib->pktlen += pattrib->hdrlen;
3143         pframe += pattrib->hdrlen;
3144 
3145         /* capability */
3146         val = *(unsigned short *)rtw_get_capability_from_ie(ie);
3147 
3148         pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &(pattrib->pktlen));
3149 
3150         lestatus = cpu_to_le16(status);
3151         pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &(pattrib->pktlen));
3152 
3153         le_tmp = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3154         pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3155 
3156         if (pstat->bssratelen <= 8) {
3157                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
3158         } else {
3159                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
3160                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
3161         }
3162 
3163         if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
3164                 uint ie_len = 0;
3165 
3166                 /* FILL HT CAP INFO IE */
3167                 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3168                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
3169                 if (pbuf && ie_len > 0) {
3170                         memcpy(pframe, pbuf, ie_len+2);
3171                         pframe += (ie_len+2);
3172                         pattrib->pktlen += (ie_len+2);
3173                 }
3174 
3175                 /* FILL HT ADD INFO IE */
3176                 /* p = hostapd_eid_ht_operation(hapd, p); */
3177                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
3178                 if (pbuf && ie_len > 0) {
3179                         memcpy(pframe, pbuf, ie_len+2);
3180                         pframe += (ie_len+2);
3181                         pattrib->pktlen += (ie_len+2);
3182                 }
3183 
3184         }
3185 
3186         /* FILL WMM IE */
3187         if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
3188                 uint ie_len = 0;
3189                 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
3190 
3191                 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
3192                         pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
3193                         if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6)) {
3194                                 memcpy(pframe, pbuf, ie_len+2);
3195                                 pframe += (ie_len+2);
3196                                 pattrib->pktlen += (ie_len+2);
3197 
3198                                 break;
3199                         }
3200 
3201                         if ((pbuf == NULL) || (ie_len == 0)) {
3202                                 break;
3203                         }
3204                 }
3205 
3206         }
3207 
3208         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3209                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen));
3210         }
3211 
3212         /* add WPS IE ie for wps 2.0 */
3213         if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
3214                 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
3215 
3216                 pframe += pmlmepriv->wps_assoc_resp_ie_len;
3217                 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
3218         }
3219 
3220         pattrib->last_txcmdsz = pattrib->pktlen;
3221 
3222         dump_mgntframe(padapter, pmgntframe);
3223 }
3224 
3225 void issue_assocreq(struct adapter *padapter)
3226 {
3227         int ret = _FAIL;
3228         struct xmit_frame                               *pmgntframe;
3229         struct pkt_attrib                               *pattrib;
3230         unsigned char                           *pframe;
3231         struct ieee80211_hdr                    *pwlanhdr;
3232         __le16 *fctrl;
3233         __le16 val16;
3234         unsigned int                                    i, j, index = 0;
3235         unsigned char bssrate[NumRates], sta_bssrate[NumRates];
3236         struct ndis_80211_var_ie *pIE;
3237         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
3238         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3239         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3240         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3241         int     bssrate_len = 0, sta_bssrate_len = 0;
3242         u8 vs_ie_length = 0;
3243 
3244         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3245         if (pmgntframe == NULL)
3246                 goto exit;
3247 
3248         /* update attribute */
3249         pattrib = &pmgntframe->attrib;
3250         update_mgntframe_attrib(padapter, pattrib);
3251 
3252         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3253 
3254         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3255         pwlanhdr = (struct ieee80211_hdr *)pframe;
3256 
3257         fctrl = &(pwlanhdr->frame_control);
3258         *(fctrl) = 0;
3259         memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3260         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3261         memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3262 
3263         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3264         pmlmeext->mgnt_seq++;
3265         SetFrameSubType(pframe, WIFI_ASSOCREQ);
3266 
3267         pframe += sizeof(struct ieee80211_hdr_3addr);
3268         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3269 
3270         /* caps */
3271         memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
3272 
3273         pframe += 2;
3274         pattrib->pktlen += 2;
3275 
3276         /* listen interval */
3277         /* todo: listen interval for power saving */
3278         val16 = cpu_to_le16(3);
3279         memcpy(pframe, (unsigned char *)&val16, 2);
3280         pframe += 2;
3281         pattrib->pktlen += 2;
3282 
3283         /* SSID */
3284         pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
3285 
3286         /* supported rate & extended supported rate */
3287 
3288         /*  Check if the AP's supported rates are also supported by STA. */
3289         get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
3290         /* DBG_871X("sta_bssrate_len =%d\n", sta_bssrate_len); */
3291 
3292         if (pmlmeext->cur_channel == 14) /*  for JAPAN, channel 14 can only uses B Mode(CCK) */
3293                 sta_bssrate_len = 4;
3294 
3295 
3296         /* for (i = 0; i < sta_bssrate_len; i++) { */
3297         /*      DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3298         /*  */
3299 
3300         for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3301                 if (pmlmeinfo->network.SupportedRates[i] == 0)
3302                         break;
3303                 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
3304         }
3305 
3306 
3307         for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3308                 if (pmlmeinfo->network.SupportedRates[i] == 0)
3309                         break;
3310 
3311 
3312                 /*  Check if the AP's supported rates are also supported by STA. */
3313                 for (j = 0; j < sta_bssrate_len; j++) {
3314                          /*  Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
3315                         if ((pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
3316                                         == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
3317                                 /* DBG_871X("match i = %d, j =%d\n", i, j); */
3318                                 break;
3319                         } else {
3320                                 /* DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
3321                         }
3322                 }
3323 
3324                 if (j == sta_bssrate_len) {
3325                         /*  the rate is not supported by STA */
3326                         DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__, i, pmlmeinfo->network.SupportedRates[i]);
3327                 } else {
3328                         /*  the rate is supported by STA */
3329                         bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3330                 }
3331         }
3332 
3333         bssrate_len = index;
3334         DBG_871X("bssrate_len = %d\n", bssrate_len);
3335 
3336         if (bssrate_len == 0) {
3337                 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
3338                 rtw_free_xmitframe(pxmitpriv, pmgntframe);
3339                 goto exit; /* don't connect to AP if no joint supported rate */
3340         }
3341 
3342 
3343         if (bssrate_len > 8) {
3344                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen));
3345                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
3346         } else
3347                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen));
3348 
3349         /* vendor specific IE, such as WPA, WMM, WPS */
3350         for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.IELength;) {
3351                 pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.IEs + i);
3352 
3353                 switch (pIE->ElementID) {
3354                 case _VENDOR_SPECIFIC_IE_:
3355                         if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
3356                                         (!memcmp(pIE->data, WMM_OUI, 4)) ||
3357                                         (!memcmp(pIE->data, WPS_OUI, 4))) {
3358                                 vs_ie_length = pIE->Length;
3359                                 if ((!padapter->registrypriv.wifi_spec) && (!memcmp(pIE->data, WPS_OUI, 4))) {
3360                                         /* Commented by Kurt 20110629 */
3361                                         /* In some older APs, WPS handshake */
3362                                         /* would be fail if we append vender extensions informations to AP */
3363 
3364                                         vs_ie_length = 14;
3365                                 }
3366 
3367                                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
3368                         }
3369                         break;
3370 
3371                 case EID_WPA2:
3372                         pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
3373                         break;
3374                 case EID_HTCapability:
3375                         if (padapter->mlmepriv.htpriv.ht_option) {
3376                                 if (!(is_ap_in_tkip(padapter))) {
3377                                         memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
3378                                         pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length, (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
3379                                 }
3380                         }
3381                         break;
3382 
3383                 case EID_EXTCapability:
3384                         if (padapter->mlmepriv.htpriv.ht_option)
3385                                 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
3386                         break;
3387                 default:
3388                         break;
3389                 }
3390 
3391                 i += (pIE->Length + 2);
3392         }
3393 
3394         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3395                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen));
3396 
3397 
3398         pattrib->last_txcmdsz = pattrib->pktlen;
3399         dump_mgntframe(padapter, pmgntframe);
3400 
3401         ret = _SUCCESS;
3402 
3403 exit:
3404         if (ret == _SUCCESS)
3405                 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
3406         else
3407                 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
3408 
3409         return;
3410 }
3411 
3412 /* when wait_ack is ture, this function shoule be called at process context */
3413 static int _issue_nulldata(struct adapter *padapter, unsigned char *da,
3414                            unsigned int power_mode, bool wait_ack)
3415 {
3416         int ret = _FAIL;
3417         struct xmit_frame                       *pmgntframe;
3418         struct pkt_attrib                       *pattrib;
3419         unsigned char                           *pframe;
3420         struct ieee80211_hdr    *pwlanhdr;
3421         __le16 *fctrl;
3422         struct xmit_priv *pxmitpriv;
3423         struct mlme_ext_priv *pmlmeext;
3424         struct mlme_ext_info *pmlmeinfo;
3425 
3426         /* DBG_871X("%s:%d\n", __func__, power_mode); */
3427 
3428         if (!padapter)
3429                 goto exit;
3430 
3431         pxmitpriv = &(padapter->xmitpriv);
3432         pmlmeext = &(padapter->mlmeextpriv);
3433         pmlmeinfo = &(pmlmeext->mlmext_info);
3434 
3435         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3436         if (pmgntframe == NULL)
3437                 goto exit;
3438 
3439         /* update attribute */
3440         pattrib = &pmgntframe->attrib;
3441         update_mgntframe_attrib(padapter, pattrib);
3442         pattrib->retry_ctrl = false;
3443 
3444         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3445 
3446         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3447         pwlanhdr = (struct ieee80211_hdr *)pframe;
3448 
3449         fctrl = &(pwlanhdr->frame_control);
3450         *(fctrl) = 0;
3451 
3452         if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3453                 SetFrDs(fctrl);
3454         else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3455                 SetToDs(fctrl);
3456 
3457         if (power_mode)
3458                 SetPwrMgt(fctrl);
3459 
3460         memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3461         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3462         memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3463 
3464         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3465         pmlmeext->mgnt_seq++;
3466         SetFrameSubType(pframe, WIFI_DATA_NULL);
3467 
3468         pframe += sizeof(struct ieee80211_hdr_3addr);
3469         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3470 
3471         pattrib->last_txcmdsz = pattrib->pktlen;
3472 
3473         if (wait_ack) {
3474                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3475         } else {
3476                 dump_mgntframe(padapter, pmgntframe);
3477                 ret = _SUCCESS;
3478         }
3479 
3480 exit:
3481         return ret;
3482 }
3483 
3484 /*
3485  * [IMPORTANT] Don't call this function in interrupt context
3486  *
3487  * When wait_ms > 0, this function shoule be called at process context
3488  * da == NULL for station mode
3489  */
3490 int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
3491 {
3492         int ret;
3493         int i = 0;
3494         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3495         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3496         struct sta_info *psta;
3497 
3498 
3499         /* da == NULL, assum it's null data for sta to ap*/
3500         if (!da)
3501                 da = get_my_bssid(&(pmlmeinfo->network));
3502 
3503         psta = rtw_get_stainfo(&padapter->stapriv, da);
3504         if (psta) {
3505                 if (power_mode)
3506                         rtw_hal_macid_sleep(padapter, psta->mac_id);
3507                 else
3508                         rtw_hal_macid_wakeup(padapter, psta->mac_id);
3509         } else {
3510                 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
3511                         FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
3512                 rtw_warn_on(1);
3513         }
3514 
3515         do {
3516                 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0?true:false);
3517 
3518                 i++;
3519 
3520                 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3521                         break;
3522 
3523                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3524                         msleep(wait_ms);
3525 
3526         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3527 
3528         if (ret != _FAIL) {
3529                 ret = _SUCCESS;
3530                 #ifndef DBG_XMIT_ACK
3531                 goto exit;
3532                 #endif
3533         }
3534 
3535         if (try_cnt && wait_ms) {
3536                 if (da)
3537                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
3538                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
3539                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3540                 else
3541                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3542                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
3543                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3544         }
3545 exit:
3546         return ret;
3547 }
3548 
3549 /*
3550  * [IMPORTANT] This function run in interrupt context
3551  *
3552  * The null data packet would be sent without power bit,
3553  * and not guarantee success.
3554  */
3555 s32 issue_nulldata_in_interrupt(struct adapter *padapter, u8 *da)
3556 {
3557         struct mlme_ext_priv *pmlmeext;
3558         struct mlme_ext_info *pmlmeinfo;
3559 
3560 
3561         pmlmeext = &padapter->mlmeextpriv;
3562         pmlmeinfo = &pmlmeext->mlmext_info;
3563 
3564         /* da == NULL, assum it's null data for sta to ap*/
3565         if (!da)
3566                 da = get_my_bssid(&(pmlmeinfo->network));
3567 
3568         return _issue_nulldata(padapter, da, 0, false);
3569 }
3570 
3571 /* when wait_ack is ture, this function shoule be called at process context */
3572 static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
3573                                u16 tid, bool wait_ack)
3574 {
3575         int ret = _FAIL;
3576         struct xmit_frame                       *pmgntframe;
3577         struct pkt_attrib                       *pattrib;
3578         unsigned char                           *pframe;
3579         struct ieee80211_hdr    *pwlanhdr;
3580         __le16 *fctrl;
3581         u16 *qc;
3582         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
3583         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3584         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3585 
3586         DBG_871X("%s\n", __func__);
3587 
3588         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3589         if (pmgntframe == NULL)
3590                 goto exit;
3591 
3592         /* update attribute */
3593         pattrib = &pmgntframe->attrib;
3594         update_mgntframe_attrib(padapter, pattrib);
3595 
3596         pattrib->hdrlen += 2;
3597         pattrib->qos_en = true;
3598         pattrib->eosp = 1;
3599         pattrib->ack_policy = 0;
3600         pattrib->mdata = 0;
3601 
3602         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3603 
3604         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3605         pwlanhdr = (struct ieee80211_hdr *)pframe;
3606 
3607         fctrl = &(pwlanhdr->frame_control);
3608         *(fctrl) = 0;
3609 
3610         if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3611                 SetFrDs(fctrl);
3612         else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3613                 SetToDs(fctrl);
3614 
3615         if (pattrib->mdata)
3616                 SetMData(fctrl);
3617 
3618         qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3619 
3620         SetPriority(qc, tid);
3621 
3622         SetEOSP(qc, pattrib->eosp);
3623 
3624         SetAckpolicy(qc, pattrib->ack_policy);
3625 
3626         memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3627         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3628         memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3629 
3630         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3631         pmlmeext->mgnt_seq++;
3632         SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3633 
3634         pframe += sizeof(struct ieee80211_qos_hdr);
3635         pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3636 
3637         pattrib->last_txcmdsz = pattrib->pktlen;
3638 
3639         if (wait_ack) {
3640                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3641         } else {
3642                 dump_mgntframe(padapter, pmgntframe);
3643                 ret = _SUCCESS;
3644         }
3645 
3646 exit:
3647         return ret;
3648 }
3649 
3650 /* when wait_ms >0 , this function shoule be called at process context */
3651 /* da == NULL for station mode */
3652 int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
3653 {
3654         int ret;
3655         int i = 0;
3656         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3657         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3658 
3659         /* da == NULL, assum it's null data for sta to ap*/
3660         if (!da)
3661                 da = get_my_bssid(&(pmlmeinfo->network));
3662 
3663         do {
3664                 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0?true:false);
3665 
3666                 i++;
3667 
3668                 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3669                         break;
3670 
3671                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3672                         msleep(wait_ms);
3673 
3674         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3675 
3676         if (ret != _FAIL) {
3677                 ret = _SUCCESS;
3678                 #ifndef DBG_XMIT_ACK
3679                 goto exit;
3680                 #endif
3681         }
3682 
3683         if (try_cnt && wait_ms) {
3684                 if (da)
3685                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
3686                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
3687                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3688                 else
3689                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3690                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
3691                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3692         }
3693 exit:
3694         return ret;
3695 }
3696 
3697 static int _issue_deauth(struct adapter *padapter, unsigned char *da,
3698                          unsigned short reason, bool wait_ack)
3699 {
3700         struct xmit_frame                       *pmgntframe;
3701         struct pkt_attrib                       *pattrib;
3702         unsigned char                           *pframe;
3703         struct ieee80211_hdr    *pwlanhdr;
3704         __le16 *fctrl;
3705         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
3706         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3707         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3708         int ret = _FAIL;
3709         __le16 le_tmp;
3710 
3711         /* DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3712 
3713         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3714         if (pmgntframe == NULL) {
3715                 goto exit;
3716         }
3717 
3718         /* update attribute */
3719         pattrib = &pmgntframe->attrib;
3720         update_mgntframe_attrib(padapter, pattrib);
3721         pattrib->retry_ctrl = false;
3722 
3723         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3724 
3725         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3726         pwlanhdr = (struct ieee80211_hdr *)pframe;
3727 
3728         fctrl = &(pwlanhdr->frame_control);
3729         *(fctrl) = 0;
3730 
3731         memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3732         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3733         memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3734 
3735         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3736         pmlmeext->mgnt_seq++;
3737         SetFrameSubType(pframe, WIFI_DEAUTH);
3738 
3739         pframe += sizeof(struct ieee80211_hdr_3addr);
3740         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3741 
3742         le_tmp = cpu_to_le16(reason);
3743         pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3744 
3745         pattrib->last_txcmdsz = pattrib->pktlen;
3746 
3747 
3748         if (wait_ack) {
3749                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3750         } else {
3751                 dump_mgntframe(padapter, pmgntframe);
3752                 ret = _SUCCESS;
3753         }
3754 
3755 exit:
3756         return ret;
3757 }
3758 
3759 int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason)
3760 {
3761         DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3762         return _issue_deauth(padapter, da, reason, false);
3763 }
3764 
3765 int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
3766         int wait_ms)
3767 {
3768         int ret;
3769         int i = 0;
3770 
3771         do {
3772                 ret = _issue_deauth(padapter, da, reason, wait_ms > 0?true:false);
3773 
3774                 i++;
3775 
3776                 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3777                         break;
3778 
3779                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3780                         mdelay(wait_ms);
3781 
3782         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3783 
3784         if (ret != _FAIL) {
3785                 ret = _SUCCESS;
3786                 #ifndef DBG_XMIT_ACK
3787                 goto exit;
3788                 #endif
3789         }
3790 
3791         if (try_cnt && wait_ms) {
3792                 if (da)
3793                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
3794                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
3795                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3796                 else
3797                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3798                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
3799                                 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms);
3800         }
3801 exit:
3802         return ret;
3803 }
3804 
3805 void issue_action_SA_Query(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid)
3806 {
3807         u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
3808         struct xmit_frame               *pmgntframe;
3809         struct pkt_attrib               *pattrib;
3810         u8                      *pframe;
3811         struct ieee80211_hdr    *pwlanhdr;
3812         __le16 *fctrl;
3813         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
3814         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3815         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3816         __le16 le_tmp;
3817 
3818         DBG_871X("%s\n", __func__);
3819 
3820         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3821         if (pmgntframe == NULL) {
3822                 DBG_871X("%s: alloc_mgtxmitframe fail\n", __func__);
3823                 return;
3824         }
3825 
3826         /* update attribute */
3827         pattrib = &pmgntframe->attrib;
3828         update_mgntframe_attrib(padapter, pattrib);
3829 
3830         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3831 
3832         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3833         pwlanhdr = (struct ieee80211_hdr *)pframe;
3834 
3835         fctrl = &(pwlanhdr->frame_control);
3836         *(fctrl) = 0;
3837 
3838         if (raddr)
3839                 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3840         else
3841                 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3842         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3843         memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3844 
3845         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3846         pmlmeext->mgnt_seq++;
3847         SetFrameSubType(pframe, WIFI_ACTION);
3848 
3849         pframe += sizeof(struct ieee80211_hdr_3addr);
3850         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3851 
3852         pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
3853         pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
3854 
3855         switch (action) {
3856         case 0: /* SA Query req */
3857                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
3858                 pmlmeext->sa_query_seq++;
3859                 /* send sa query request to AP, AP should reply sa query response in 1 second */
3860                 set_sa_query_timer(pmlmeext, 1000);
3861                 break;
3862 
3863         case 1: /* SA Query rsp */
3864                 le_tmp = cpu_to_le16(tid);
3865                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
3866                 break;
3867         default:
3868                 break;
3869         }
3870 
3871         pattrib->last_txcmdsz = pattrib->pktlen;
3872 
3873         dump_mgntframe(padapter, pmgntframe);
3874 }
3875 
3876 void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
3877 {
3878         u8 category = RTW_WLAN_CATEGORY_BACK;
3879         u16 start_seq;
3880         u16 BA_para_set;
3881         u16 reason_code;
3882         u16 BA_timeout_value;
3883         u16 BA_starting_seqctrl = 0;
3884         enum HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3885         struct xmit_frame               *pmgntframe;
3886         struct pkt_attrib               *pattrib;
3887         u8                      *pframe;
3888         struct ieee80211_hdr    *pwlanhdr;
3889         __le16 *fctrl;
3890         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
3891         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3892         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3893         struct sta_info         *psta;
3894         struct sta_priv         *pstapriv = &padapter->stapriv;
3895         struct registry_priv    *pregpriv = &padapter->registrypriv;
3896         __le16 le_tmp;
3897 
3898         DBG_871X("%s, category =%d, action =%d, status =%d\n", __func__, category, action, status);
3899 
3900         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3901         if (!pmgntframe)
3902                 return;
3903 
3904         /* update attribute */
3905         pattrib = &pmgntframe->attrib;
3906         update_mgntframe_attrib(padapter, pattrib);
3907 
3908         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3909 
3910         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3911         pwlanhdr = (struct ieee80211_hdr *)pframe;
3912 
3913         fctrl = &(pwlanhdr->frame_control);
3914         *(fctrl) = 0;
3915 
3916         /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
3917         memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3918         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3919         memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3920 
3921         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3922         pmlmeext->mgnt_seq++;
3923         SetFrameSubType(pframe, WIFI_ACTION);
3924 
3925         pframe += sizeof(struct ieee80211_hdr_3addr);
3926         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3927 
3928         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3929         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3930 
3931         if (category == 3) {
3932                 switch (action) {
3933                 case 0: /* ADDBA req */
3934                         do {
3935                                 pmlmeinfo->dialogToken++;
3936                         } while (pmlmeinfo->dialogToken == 0);
3937                         pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
3938 
3939                         if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter)) {
3940                                 /*  A-MSDU NOT Supported */
3941                                 BA_para_set = 0;
3942                                 /*  immediate Block Ack */
3943                                 BA_para_set |= BIT(1) & IEEE80211_ADDBA_PARAM_POLICY_MASK;
3944                                 /*  TID */
3945                                 BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
3946                                 /*  max buffer size is 8 MSDU */
3947                                 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3948                         } else {
3949                                 BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */
3950                         }
3951                         le_tmp = cpu_to_le16(BA_para_set);
3952                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3953 
3954                         BA_timeout_value = 5000;/*  5ms */
3955                         le_tmp = cpu_to_le16(BA_timeout_value);
3956                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3957 
3958                         /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
3959                         psta = rtw_get_stainfo(pstapriv, raddr);
3960                         if (psta != NULL) {
3961                                 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
3962 
3963                                 DBG_871X("BA_starting_seqctrl = %d for TID =%d\n", start_seq, status & 0x07);
3964 
3965                                 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
3966 
3967                                 BA_starting_seqctrl = start_seq << 4;
3968                         }
3969 
3970                         le_tmp = cpu_to_le16(BA_starting_seqctrl);
3971                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3972                         break;
3973 
3974                 case 1: /* ADDBA rsp */
3975                         pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
3976                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
3977                         if (padapter->driver_rx_ampdu_factor != 0xFF)
3978                                 max_rx_ampdu_factor =
3979                                   (enum HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor;
3980                         else
3981                                 rtw_hal_get_def_var(padapter,
3982                                                     HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3983 
3984                         if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3985                                 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
3986                         else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3987                                 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
3988                         else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3989                                 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
3990                         else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3991                                 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
3992                         else
3993                                 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
3994 
3995                         if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter) &&
3996                             padapter->driver_rx_ampdu_factor == 0xFF) {
3997                                 /*  max buffer size is 8 MSDU */
3998                                 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3999                                 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4000                         }
4001 
4002                         if (pregpriv->ampdu_amsdu == 0)/* disabled */
4003                                 le_tmp = cpu_to_le16(BA_para_set & ~BIT(0));
4004                         else if (pregpriv->ampdu_amsdu == 1)/* enabled */
4005                                 le_tmp = cpu_to_le16(BA_para_set | BIT(0));
4006                         else /* auto */
4007                                 le_tmp = cpu_to_le16(BA_para_set);
4008 
4009                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
4010                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
4011                         break;
4012                 case 2:/* DELBA */
4013                         BA_para_set = (status & 0x1F) << 3;
4014                         le_tmp = cpu_to_le16(BA_para_set);
4015                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
4016 
4017                         reason_code = 37;
4018                         le_tmp = cpu_to_le16(reason_code);
4019                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
4020                         break;
4021                 default:
4022                         break;
4023                 }
4024         }
4025 
4026         pattrib->last_txcmdsz = pattrib->pktlen;
4027 
4028         dump_mgntframe(padapter, pmgntframe);
4029 }
4030 
4031 static void issue_action_BSSCoexistPacket(struct adapter *padapter)
4032 {
4033         struct list_head                *plist, *phead;
4034         unsigned char category, action;
4035         struct xmit_frame                       *pmgntframe;
4036         struct pkt_attrib                       *pattrib;
4037         unsigned char                   *pframe;
4038         struct ieee80211_hdr    *pwlanhdr;
4039         __le16 *fctrl;
4040         struct  wlan_network    *pnetwork = NULL;
4041         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
4042         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4043         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4044         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4045         struct __queue          *queue  = &(pmlmepriv->scanned_queue);
4046         u8 InfoContent[16] = {0};
4047         u8 ICS[8][15];
4048 
4049         if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
4050                 return;
4051 
4052         if (true == pmlmeinfo->bwmode_updated)
4053                 return;
4054 
4055 
4056         DBG_871X("%s\n", __func__);
4057 
4058 
4059         category = RTW_WLAN_CATEGORY_PUBLIC;
4060         action = ACT_PUBLIC_BSSCOEXIST;
4061 
4062         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4063         if (pmgntframe == NULL) {
4064                 return;
4065         }
4066 
4067         /* update attribute */
4068         pattrib = &pmgntframe->attrib;
4069         update_mgntframe_attrib(padapter, pattrib);
4070 
4071         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4072 
4073         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4074         pwlanhdr = (struct ieee80211_hdr *)pframe;
4075 
4076         fctrl = &(pwlanhdr->frame_control);
4077         *(fctrl) = 0;
4078 
4079         memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
4080         memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4081         memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
4082 
4083         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4084         pmlmeext->mgnt_seq++;
4085         SetFrameSubType(pframe, WIFI_ACTION);
4086 
4087         pframe += sizeof(struct ieee80211_hdr_3addr);
4088         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4089 
4090         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4091         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4092 
4093 
4094         /*  */
4095         if (pmlmepriv->num_FortyMHzIntolerant > 0) {
4096                 u8 iedata = 0;
4097 
4098                 iedata |= BIT(2);/* 20 MHz BSS Width Request */
4099 
4100                 pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &(pattrib->pktlen));
4101 
4102         }
4103 
4104 
4105         /*  */
4106         memset(ICS, 0, sizeof(ICS));
4107         if (pmlmepriv->num_sta_no_ht > 0) {
4108                 int i;
4109 
4110                 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
4111 
4112                 phead = get_list_head(queue);
4113                 plist = get_next(phead);
4114 
4115                 while (1) {
4116                         int len;
4117                         u8 *p;
4118                         struct wlan_bssid_ex *pbss_network;
4119 
4120                         if (phead == plist)
4121                                 break;
4122 
4123                         pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4124 
4125                         plist = get_next(plist);
4126 
4127                         pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
4128 
4129                         p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
4130                         if ((p == NULL) || (len == 0)) {/* non-HT */
4131 
4132                                 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
4133                                         continue;
4134 
4135                                 ICS[0][pbss_network->Configuration.DSConfig] = 1;
4136 
4137                                 if (ICS[0][0] == 0)
4138                                         ICS[0][0] = 1;
4139                         }
4140 
4141                 }
4142 
4143                 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
4144 
4145 
4146                 for (i = 0; i < 8; i++) {
4147                         if (ICS[i][0] == 1) {
4148                                 int j, k = 0;
4149 
4150                                 InfoContent[k] = i;
4151                                 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
4152                                 k++;
4153 
4154                                 for (j = 1; j <= 14; j++) {
4155                                         if (ICS[i][j] == 1) {
4156                                                 if (k < 16) {
4157                                                         InfoContent[k] = j; /* channel number */
4158                                                         /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
4159                                                         k++;
4160                                                 }
4161                                         }
4162                                 }
4163 
4164                                 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
4165 
4166                         }
4167 
4168                 }
4169 
4170 
4171         }
4172 
4173 
4174         pattrib->last_txcmdsz = pattrib->pktlen;
4175 
4176         dump_mgntframe(padapter, pmgntframe);
4177 }
4178 
4179 unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
4180 {
4181         struct sta_priv *pstapriv = &padapter->stapriv;
4182         struct sta_info *psta = NULL;
4183         /* struct recv_reorder_ctrl *preorder_ctrl; */
4184         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4185         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4186         u16 tid;
4187 
4188         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
4189                 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4190                         return _SUCCESS;
4191 
4192         psta = rtw_get_stainfo(pstapriv, addr);
4193         if (psta == NULL)
4194                 return _SUCCESS;
4195 
4196         /* DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR"); */
4197 
4198         if (initiator == 0) {/*  recipient */
4199                 for (tid = 0; tid < MAXTID; tid++) {
4200                         if (psta->recvreorder_ctrl[tid].enable) {
4201                                 DBG_871X("rx agg disable tid(%d)\n", tid);
4202                                 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
4203                                 psta->recvreorder_ctrl[tid].enable = false;
4204                                 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
4205                                 #ifdef DBG_RX_SEQ
4206                                 DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __func__, __LINE__,
4207                                         psta->recvreorder_ctrl[tid].indicate_seq);
4208                                 #endif
4209                         }
4210                 }
4211         } else if (initiator == 1) {/*  originator */
4212                 /* DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap); */
4213                 for (tid = 0; tid < MAXTID; tid++) {
4214                         if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
4215                                 DBG_871X("tx agg disable tid(%d)\n", tid);
4216                                 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
4217                                 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4218                                 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4219 
4220                         }
4221                 }
4222         }
4223 
4224         return _SUCCESS;
4225 
4226 }
4227 
4228 unsigned int send_beacon(struct adapter *padapter)
4229 {
4230         u8 bxmitok = false;
4231         int     issue = 0;
4232         int poll = 0;
4233         unsigned long start = jiffies;
4234 
4235         rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
4236         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
4237         do {
4238                 issue_beacon(padapter, 100);
4239                 issue++;
4240                 do {
4241                         cond_resched();
4242                         rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
4243                         poll++;
4244                 } while ((poll%10) != 0 && false == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
4245 
4246         } while (false == bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
4247 
4248         if (padapter->bSurpriseRemoved || padapter->bDriverStopped) {
4249                 return _FAIL;
4250         }
4251 
4252 
4253         if (false == bxmitok) {
4254                 DBG_871X("%s fail! %u ms\n", __func__, jiffies_to_msecs(jiffies - start));
4255                 return _FAIL;
4256         } else {
4257                 unsigned long passing_time = jiffies_to_msecs(jiffies - start);
4258 
4259                 if (passing_time > 100 || issue > 3)
4260                         DBG_871X("%s success, issue:%d, poll:%d, %lu ms\n", __func__, issue, poll, passing_time);
4261                 /* else */
4262                 /*      DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __func__, issue, poll, passing_time); */
4263 
4264                 return _SUCCESS;
4265         }
4266 }
4267 
4268 /****************************************************************************
4269 
4270 Following are some utitity fuctions for WiFi MLME
4271 
4272 *****************************************************************************/
4273 
4274 void site_survey(struct adapter *padapter)
4275 {
4276         unsigned char   survey_channel = 0, val8;
4277         RT_SCAN_TYPE    ScanType = SCAN_PASSIVE;
4278         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4279         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4280         u32 initialgain = 0;
4281         u32 channel_scan_time_ms = 0;
4282 
4283         {
4284                 struct rtw_ieee80211_channel *ch;
4285                 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
4286                         ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4287                         survey_channel = ch->hw_value;
4288                         ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
4289                 }
4290         }
4291 
4292         DBG_871X(FUNC_ADPT_FMT" ch:%u (cnt:%u) at %dms, %c%c%c\n"
4293                  , FUNC_ADPT_ARG(padapter)
4294                  , survey_channel
4295                  , pmlmeext->sitesurvey_res.channel_idx
4296                  , jiffies_to_msecs(jiffies - padapter->mlmepriv.scan_start_time)
4297                  , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
4298                  , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
4299                 );
4300 #ifdef DBG_FIXED_CHAN
4301         DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
4302 #endif
4303 
4304         if (survey_channel != 0) {
4305                 /* PAUSE 4-AC Queue when site_survey */
4306                 /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
4307                 /* val8 |= 0x0f; */
4308                 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
4309                 if (pmlmeext->sitesurvey_res.channel_idx == 0) {
4310 #ifdef DBG_FIXED_CHAN
4311                         if (pmlmeext->fixed_chan != 0xff)
4312                                 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4313                         else
4314 #endif
4315                                 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4316                 } else {
4317 #ifdef DBG_FIXED_CHAN
4318                         if (pmlmeext->fixed_chan != 0xff)
4319                                 SelectChannel(padapter, pmlmeext->fixed_chan);
4320                         else
4321 #endif
4322                                 SelectChannel(padapter, survey_channel);
4323                 }
4324 
4325                 if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */
4326                         {
4327                                 int i;
4328                                 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
4329                                         if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
4330                                                 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
4331                                                 if (padapter->registrypriv.wifi_spec)
4332                                                         issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
4333                                                 else
4334                                                         issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
4335                                                 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
4336                                         }
4337                                 }
4338 
4339                                 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4340                                         /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
4341                                         if (padapter->registrypriv.wifi_spec)
4342                                                 issue_probereq(padapter, NULL, NULL);
4343                                         else
4344                                                 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
4345                                         issue_probereq(padapter, NULL, NULL);
4346                                 }
4347                         }
4348                 }
4349 
4350                 channel_scan_time_ms = pmlmeext->chan_scan_time;
4351 
4352                 set_survey_timer(pmlmeext, channel_scan_time_ms);
4353 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
4354                 {
4355                         struct noise_info info;
4356                         info.bPauseDIG = false;
4357                         info.IGIValue = 0;
4358                         info.max_time = channel_scan_time_ms/2;/* ms */
4359                         info.chan = survey_channel;
4360                         rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, false);
4361                 }
4362 #endif
4363 
4364         } else {
4365 
4366                 /*      channel number is 0 or this channel is not valid. */
4367 
4368                 {
4369                         pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4370 
4371                         /* switch back to the original channel */
4372                         /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
4373 
4374                         set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4375 
4376                         /* flush 4-AC Queue after site_survey */
4377                         /* val8 = 0; */
4378                         /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
4379 
4380                         /* config MSR */
4381                         Set_MSR(padapter, (pmlmeinfo->state & 0x3));
4382 
4383                         initialgain = 0xff; /* restore RX GAIN */
4384                         rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
4385                         /* turn on dynamic functions */
4386                         Restore_DM_Func_Flag(padapter);
4387                         /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
4388 
4389                         if (is_client_associated_to_ap(padapter))
4390                                 issue_nulldata(padapter, NULL, 0, 3, 500);
4391 
4392                         val8 = 0; /* survey done */
4393                         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
4394 
4395                         report_surveydone_event(padapter);
4396 
4397                         pmlmeext->chan_scan_time = SURVEY_TO;
4398                         pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4399 
4400                         issue_action_BSSCoexistPacket(padapter);
4401                         issue_action_BSSCoexistPacket(padapter);
4402                         issue_action_BSSCoexistPacket(padapter);
4403                 }
4404         }
4405 
4406         return;
4407 
4408 }
4409 
4410 /* collect bss info from Beacon and Probe request/response frames. */
4411 u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, struct wlan_bssid_ex *bssid)
4412 {
4413         int     i;
4414         u32 len;
4415         u8 *p;
4416         u16 val16, subtype;
4417         u8 *pframe = precv_frame->u.hdr.rx_data;
4418         u32 packet_len = precv_frame->u.hdr.len;
4419         u8 ie_offset;
4420         struct registry_priv *pregistrypriv = &padapter->registrypriv;
4421         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4422         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4423         __le32 le32_tmp;
4424 
4425         len = packet_len - sizeof(struct ieee80211_hdr_3addr);
4426 
4427         if (len > MAX_IE_SZ) {
4428                 /* DBG_871X("IE too long for survey event\n"); */
4429                 return _FAIL;
4430         }
4431 
4432         memset(bssid, 0, sizeof(struct wlan_bssid_ex));
4433 
4434         subtype = GetFrameSubType(pframe);
4435 
4436         if (subtype == WIFI_BEACON) {
4437                 bssid->Reserved[0] = 1;
4438                 ie_offset = _BEACON_IE_OFFSET_;
4439         } else {
4440                 /*  FIXME : more type */
4441                 if (subtype == WIFI_PROBERSP) {
4442                         ie_offset = _PROBERSP_IE_OFFSET_;
4443                         bssid->Reserved[0] = 3;
4444                 } else if (subtype == WIFI_PROBEREQ) {
4445                         ie_offset = _PROBEREQ_IE_OFFSET_;
4446                         bssid->Reserved[0] = 2;
4447                 } else {
4448                         bssid->Reserved[0] = 0;
4449                         ie_offset = _FIXED_IE_LENGTH_;
4450                 }
4451         }
4452 
4453         bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
4454 
4455         /* below is to copy the information element */
4456         bssid->IELength = len;
4457         memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
4458 
4459         /* get the signal strength */
4460         bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; /*  in dBM.raw data */
4461         bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;/* in percentage */
4462         bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;/* in percentage */
4463 
4464         /*  checking SSID */
4465         p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
4466         if (p == NULL) {
4467                 DBG_871X("marc: cannot find SSID for survey event\n");
4468                 return _FAIL;
4469         }
4470 
4471         if (*(p + 1)) {
4472                 if (len > NDIS_802_11_LENGTH_SSID) {
4473                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
4474                         return _FAIL;
4475                 }
4476                 memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
4477                 bssid->Ssid.SsidLength = *(p + 1);
4478         } else
4479                 bssid->Ssid.SsidLength = 0;
4480 
4481         memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
4482 
4483         /* checking rate info... */
4484         i = 0;
4485         p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
4486         if (p != NULL) {
4487                 if (len > NDIS_802_11_LENGTH_RATES_EX) {
4488                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
4489                         return _FAIL;
4490                 }
4491                 memcpy(bssid->SupportedRates, (p + 2), len);
4492                 i = len;
4493         }
4494 
4495         p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
4496         if (p != NULL) {
4497                 if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4498                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
4499                         return _FAIL;
4500                 }
4501                 memcpy(bssid->SupportedRates + i, (p + 2), len);
4502         }
4503 
4504         bssid->NetworkTypeInUse = Ndis802_11OFDM24;
4505 
4506         if (bssid->IELength < 12)
4507                 return _FAIL;
4508 
4509         /*  Checking for DSConfig */
4510         p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
4511 
4512         bssid->Configuration.DSConfig = 0;
4513         bssid->Configuration.Length = 0;
4514 
4515         if (p) {
4516                 bssid->Configuration.DSConfig = *(p + 2);
4517         } else {
4518                 /*  In 5G, some ap do not have DSSET IE */
4519                 /*  checking HT info for channel */
4520                 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
4521                 if (p) {
4522                         struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
4523                         bssid->Configuration.DSConfig = HT_info->primary_channel;
4524                 } else { /*  use current channel */
4525                         bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
4526                 }
4527         }
4528 
4529         memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
4530         bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp);
4531 
4532         val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid);
4533 
4534         if (val16 & BIT(0)) {
4535                 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4536                 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
4537         } else {
4538                 bssid->InfrastructureMode = Ndis802_11IBSS;
4539                 memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
4540         }
4541 
4542         if (val16 & BIT(4))
4543                 bssid->Privacy = 1;
4544         else
4545                 bssid->Privacy = 0;
4546 
4547         bssid->Configuration.ATIMWindow = 0;
4548 
4549         /* 20/40 BSS Coexistence check */
4550         if ((pregistrypriv->wifi_spec == 1) && (false == pmlmeinfo->bwmode_updated)) {
4551                 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4552 
4553                 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
4554                 if (p && len > 0) {
4555                         struct HT_caps_element  *pHT_caps;
4556                         pHT_caps = (struct HT_caps_element      *)(p + 2);
4557 
4558                         if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14))
4559                                 pmlmepriv->num_FortyMHzIntolerant++;
4560                 } else
4561                         pmlmepriv->num_sta_no_ht++;
4562         }
4563 
4564         #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
4565         if (strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
4566                 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
4567                         , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
4568                         , rtw_get_oper_ch(padapter)
4569                         , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
4570                 );
4571         }
4572         #endif
4573 
4574         /*  mark bss info receving from nearby channel as SignalQuality 101 */
4575         if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
4576                 bssid->PhyInfo.SignalQuality = 101;
4577 
4578         return _SUCCESS;
4579 }
4580 
4581 void start_create_ibss(struct adapter *padapter)
4582 {
4583         unsigned short  caps;
4584         u8 val8;
4585         u8 join_type;
4586         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4587         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4588         struct wlan_bssid_ex            *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4589         pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4590         pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
4591 
4592         /* update wireless mode */
4593         update_wireless_mode(padapter);
4594 
4595         /* udpate capability */
4596         caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
4597         update_capinfo(padapter, caps);
4598         if (caps&cap_IBSS) {/* adhoc master */
4599                 val8 = 0xcf;
4600                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4601 
4602                 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
4603 
4604                 /* switch channel */
4605                 /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4606                 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4607 
4608                 beacon_timing_control(padapter);
4609 
4610                 /* set msr to WIFI_FW_ADHOC_STATE */
4611                 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4612                 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
4613 
4614                 /* issue beacon */
4615                 if (send_beacon(padapter) == _FAIL) {
4616                         RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4617 
4618                         report_join_res(padapter, -1);
4619                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
4620                 } else {
4621                         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
4622                         join_type = 0;
4623                         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4624 
4625                         report_join_res(padapter, 1);
4626                         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4627                         rtw_indicate_connect(padapter);
4628                 }
4629         } else {
4630                 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
4631                 return;
4632         }
4633         /* update bc/mc sta_info */
4634         update_bmc_sta(padapter);
4635 
4636 }
4637 
4638 void start_clnt_join(struct adapter *padapter)
4639 {
4640         unsigned short  caps;
4641         u8 val8;
4642         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4643         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4644         struct wlan_bssid_ex            *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4645         int beacon_timeout;
4646 
4647         /* update wireless mode */
4648         update_wireless_mode(padapter);
4649 
4650         /* udpate capability */
4651         caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
4652         update_capinfo(padapter, caps);
4653         if (caps&cap_ESS) {
4654                 Set_MSR(padapter, WIFI_FW_STATION_STATE);
4655 
4656                 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
4657 
4658                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4659 
4660                 /*  Because of AP's not receiving deauth before */
4661                 /*  AP may: 1)not response auth or 2)deauth us after link is complete */
4662                 /*  issue deauth before issuing auth to deal with the situation */
4663 
4664                 /*      Commented by Albert 2012/07/21 */
4665                 /*      For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
4666                 {
4667                                 /* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
4668                                 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
4669                 }
4670 
4671                 /* here wait for receiving the beacon to start auth */
4672                 /* and enable a timer */
4673                 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
4674                 set_link_timer(pmlmeext, beacon_timeout);
4675                 _set_timer(&padapter->mlmepriv.assoc_timer,
4676                         (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout);
4677 
4678                 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4679         } else if (caps&cap_IBSS) { /* adhoc client */
4680                 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
4681 
4682                 val8 = 0xcf;
4683                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4684 
4685                 beacon_timing_control(padapter);
4686 
4687                 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4688 
4689                 report_join_res(padapter, 1);
4690         } else {
4691                 /* DBG_871X("marc: invalid cap:%x\n", caps); */
4692                 return;
4693         }
4694 
4695 }
4696 
4697 void start_clnt_auth(struct adapter *padapter)
4698 {
4699         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4700         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4701 
4702         del_timer_sync(&pmlmeext->link_timer);
4703 
4704         pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4705         pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4706 
4707         pmlmeinfo->auth_seq = 1;
4708         pmlmeinfo->reauth_count = 0;
4709         pmlmeinfo->reassoc_count = 0;
4710         pmlmeinfo->link_count = 0;
4711         pmlmeext->retry = 0;
4712 
4713 
4714         DBG_871X_LEVEL(_drv_always_, "start auth\n");
4715         issue_auth(padapter, NULL, 0);
4716 
4717         set_link_timer(pmlmeext, REAUTH_TO);
4718 
4719 }
4720 
4721 
4722 void start_clnt_assoc(struct adapter *padapter)
4723 {
4724         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4725         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4726 
4727         del_timer_sync(&pmlmeext->link_timer);
4728 
4729         pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4730         pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4731 
4732         issue_assocreq(padapter);
4733 
4734         set_link_timer(pmlmeext, REASSOC_TO);
4735 }
4736 
4737 unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4738 {
4739         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4740         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4741 
4742         /* check A3 */
4743         if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
4744                 return _SUCCESS;
4745 
4746         DBG_871X("%s\n", __func__);
4747 
4748         if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
4749                 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4750                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
4751                         report_del_sta_event(padapter, MacAddr, reason);
4752 
4753                 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
4754                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
4755                         report_join_res(padapter, -2);
4756                 }
4757         }
4758 
4759         return _SUCCESS;
4760 }
4761 
4762 static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid)
4763 {
4764         struct registry_priv *pregistrypriv;
4765         struct mlme_ext_priv *pmlmeext;
4766         RT_CHANNEL_INFO *chplan_new;
4767         u8 channel;
4768         u8 i;
4769 
4770 
4771         pregistrypriv = &padapter->registrypriv;
4772         pmlmeext = &padapter->mlmeextpriv;
4773 
4774         /*  Adjust channel plan by AP Country IE */
4775         if (pregistrypriv->enable80211d &&
4776                 (!pmlmeext->update_channel_plan_by_ap_done)) {
4777                 u8 *ie, *p;
4778                 u32 len;
4779                 RT_CHANNEL_PLAN chplan_ap;
4780                 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
4781                 u8 country[4];
4782                 u8 fcn; /*  first channel number */
4783                 u8 noc; /*  number of channel */
4784                 u8 j, k;
4785 
4786                 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
4787                 if (!ie)
4788                         return;
4789                 if (len < 6)
4790                         return;
4791 
4792                 ie += 2;
4793                 p = ie;
4794                 ie += len;
4795 
4796                 memset(country, 0, 4);
4797                 memcpy(country, p, 3);
4798                 p += 3;
4799                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4800                                 ("%s: 802.11d country =%s\n", __func__, country));
4801 
4802                 i = 0;
4803                 while ((ie - p) >= 3) {
4804                         fcn = *(p++);
4805                         noc = *(p++);
4806                         p++;
4807 
4808                         for (j = 0; j < noc; j++) {
4809                                 if (fcn <= 14)
4810                                         channel = fcn + j; /*  2.4 GHz */
4811                                 else
4812                                         channel = fcn + j*4; /*  5 GHz */
4813 
4814                                 chplan_ap.Channel[i++] = channel;
4815                         }
4816                 }
4817                 chplan_ap.Len = i;
4818 
4819 #ifdef DEBUG_RTL871X
4820                 i = 0;
4821                 DBG_871X("%s: AP[%s] channel plan {", __func__, bssid->Ssid.Ssid);
4822                 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) {
4823                         DBG_8192C("%02d,", chplan_ap.Channel[i]);
4824                         i++;
4825                 }
4826                 DBG_871X("}\n");
4827 #endif
4828 
4829                 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4830 #ifdef DEBUG_RTL871X
4831                 i = 0;
4832                 DBG_871X("%s: STA channel plan {", __func__);
4833                 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
4834                         DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE?'p':'a');
4835                         i++;
4836                 }
4837                 DBG_871X("}\n");
4838 #endif
4839 
4840                 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4841                 chplan_new = pmlmeext->channel_set;
4842 
4843                 i = j = k = 0;
4844                 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4845                         do {
4846                                 if ((i == MAX_CHANNEL_NUM) ||
4847                                         (chplan_sta[i].ChannelNum == 0) ||
4848                                         (chplan_sta[i].ChannelNum > 14))
4849                                         break;
4850 
4851                                 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
4852                                         break;
4853 
4854                                 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
4855                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4856                                         chplan_new[k].ScanType = SCAN_ACTIVE;
4857                                         i++;
4858                                         j++;
4859                                         k++;
4860                                 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
4861                                         chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4862 /*                                      chplan_new[k].ScanType = chplan_sta[i].ScanType; */
4863                                         chplan_new[k].ScanType = SCAN_PASSIVE;
4864                                         i++;
4865                                         k++;
4866                                 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
4867                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4868                                         chplan_new[k].ScanType = SCAN_ACTIVE;
4869                                         j++;
4870                                         k++;
4871                                 }
4872                         } while (1);
4873 
4874                         /*  change AP not support channel to Passive scan */
4875                         while ((i < MAX_CHANNEL_NUM) &&
4876                                 (chplan_sta[i].ChannelNum != 0) &&
4877                                 (chplan_sta[i].ChannelNum <= 14)) {
4878 
4879                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4880 /*                              chplan_new[k].ScanType = chplan_sta[i].ScanType; */
4881                                 chplan_new[k].ScanType = SCAN_PASSIVE;
4882                                 i++;
4883                                 k++;
4884                         }
4885 
4886                         /*  add channel AP supported */
4887                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
4888                                 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4889                                 chplan_new[k].ScanType = SCAN_ACTIVE;
4890                                 j++;
4891                                 k++;
4892                         }
4893                 } else {
4894                         /*  keep original STA 2.4G channel plan */
4895                         while ((i < MAX_CHANNEL_NUM) &&
4896                                 (chplan_sta[i].ChannelNum != 0) &&
4897                                 (chplan_sta[i].ChannelNum <= 14)) {
4898                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4899                                 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4900                                 i++;
4901                                 k++;
4902                         }
4903 
4904                         /*  skip AP 2.4G channel plan */
4905                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
4906                                 j++;
4907                         }
4908                 }
4909 
4910                 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4911                         do {
4912                                 if ((i == MAX_CHANNEL_NUM) ||
4913                                         (chplan_sta[i].ChannelNum == 0))
4914                                         break;
4915 
4916                                 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
4917                                         break;
4918 
4919                                 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
4920                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4921                                         chplan_new[k].ScanType = SCAN_ACTIVE;
4922                                         i++;
4923                                         j++;
4924                                         k++;
4925                                 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
4926                                         chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4927 /*                                      chplan_new[k].ScanType = chplan_sta[i].ScanType; */
4928                                         chplan_new[k].ScanType = SCAN_PASSIVE;
4929                                         i++;
4930                                         k++;
4931                                 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
4932                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4933                                         chplan_new[k].ScanType = SCAN_ACTIVE;
4934                                         j++;
4935                                         k++;
4936                                 }
4937                         } while (1);
4938 
4939                         /*  change AP not support channel to Passive scan */
4940                         while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
4941                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4942 /*                              chplan_new[k].ScanType = chplan_sta[i].ScanType; */
4943                                 chplan_new[k].ScanType = SCAN_PASSIVE;
4944                                 i++;
4945                                 k++;
4946                         }
4947 
4948                         /*  add channel AP supported */
4949                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
4950                                 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4951                                 chplan_new[k].ScanType = SCAN_ACTIVE;
4952                                 j++;
4953                                 k++;
4954                         }
4955                 } else {
4956                         /*  keep original STA 5G channel plan */
4957                         while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
4958                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4959                                 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4960                                 i++;
4961                                 k++;
4962                         }
4963                 }
4964 
4965                 pmlmeext->update_channel_plan_by_ap_done = 1;
4966 
4967 #ifdef DEBUG_RTL871X
4968                 k = 0;
4969                 DBG_871X("%s: new STA channel plan {", __func__);
4970                 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
4971                         DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE?'p':'c');
4972                         k++;
4973                 }
4974                 DBG_871X("}\n");
4975 #endif
4976         }
4977 
4978         /*  If channel is used by AP, set channel scan type to active */
4979         channel = bssid->Configuration.DSConfig;
4980         chplan_new = pmlmeext->channel_set;
4981         i = 0;
4982         while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
4983                 if (chplan_new[i].ChannelNum == channel) {
4984                         if (chplan_new[i].ScanType == SCAN_PASSIVE) {
4985                                 /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
4986                                 if (channel >= 52 && channel <= 144)
4987                                         break;
4988 
4989                                 chplan_new[i].ScanType = SCAN_ACTIVE;
4990                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4991                                                  ("%s: change channel %d scan type from passive to active\n",
4992                                                   __func__, channel));
4993                         }
4994                         break;
4995                 }
4996                 i++;
4997         }
4998 }
4999 
5000 /****************************************************************************
5001 
5002 Following are the functions to report events
5003 
5004 *****************************************************************************/
5005 
5006 void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame)
5007 {
5008         struct cmd_obj *pcmd_obj;
5009         u8 *pevtcmd;
5010         u32 cmdsz;
5011         struct survey_event     *psurvey_evt;
5012         struct C2HEvent_Header *pc2h_evt_hdr;
5013         struct mlme_ext_priv *pmlmeext;
5014         struct cmd_priv *pcmdpriv;
5015         /* u8 *pframe = precv_frame->u.hdr.rx_data; */
5016         /* uint len = precv_frame->u.hdr.len; */
5017 
5018         if (!padapter)
5019                 return;
5020 
5021         pmlmeext = &padapter->mlmeextpriv;
5022         pcmdpriv = &padapter->cmdpriv;
5023 
5024         pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5025         if (!pcmd_obj)
5026                 return;
5027 
5028         cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
5029         pevtcmd = rtw_zmalloc(cmdsz);
5030         if (!pevtcmd) {
5031                 kfree(pcmd_obj);
5032                 return;
5033         }
5034 
5035         INIT_LIST_HEAD(&pcmd_obj->list);
5036 
5037         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5038         pcmd_obj->cmdsz = cmdsz;
5039         pcmd_obj->parmbuf = pevtcmd;
5040 
5041         pcmd_obj->rsp = NULL;
5042         pcmd_obj->rspsz  = 0;
5043 
5044         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5045         pc2h_evt_hdr->len = sizeof(struct survey_event);
5046         pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
5047         pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5048 
5049         psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5050 
5051         if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) {
5052                 kfree(pcmd_obj);
5053                 kfree(pevtcmd);
5054                 return;
5055         }
5056 
5057         process_80211d(padapter, &psurvey_evt->bss);
5058 
5059         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5060 
5061         pmlmeext->sitesurvey_res.bss_cnt++;
5062 
5063         return;
5064 
5065 }
5066 
5067 void report_surveydone_event(struct adapter *padapter)
5068 {
5069         struct cmd_obj *pcmd_obj;
5070         u8 *pevtcmd;
5071         u32 cmdsz;
5072         struct surveydone_event *psurveydone_evt;
5073         struct C2HEvent_Header  *pc2h_evt_hdr;
5074         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5075         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5076 
5077         pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5078         if (!pcmd_obj)
5079                 return;
5080 
5081         cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
5082         pevtcmd = rtw_zmalloc(cmdsz);
5083         if (!pevtcmd) {
5084                 kfree(pcmd_obj);
5085                 return;
5086         }
5087 
5088         INIT_LIST_HEAD(&pcmd_obj->list);
5089 
5090         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5091         pcmd_obj->cmdsz = cmdsz;
5092         pcmd_obj->parmbuf = pevtcmd;
5093 
5094         pcmd_obj->rsp = NULL;
5095         pcmd_obj->rspsz  = 0;
5096 
5097         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5098         pc2h_evt_hdr->len = sizeof(struct surveydone_event);
5099         pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
5100         pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5101 
5102         psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5103         psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
5104 
5105         DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
5106 
5107         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5108 
5109         return;
5110 
5111 }
5112 
5113 void report_join_res(struct adapter *padapter, int res)
5114 {
5115         struct cmd_obj *pcmd_obj;
5116         u8 *pevtcmd;
5117         u32 cmdsz;
5118         struct joinbss_event            *pjoinbss_evt;
5119         struct C2HEvent_Header  *pc2h_evt_hdr;
5120         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5121         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5122         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5123 
5124         pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5125         if (!pcmd_obj)
5126                 return;
5127 
5128         cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
5129         pevtcmd = rtw_zmalloc(cmdsz);
5130         if (!pevtcmd) {
5131                 kfree(pcmd_obj);
5132                 return;
5133         }
5134 
5135         INIT_LIST_HEAD(&pcmd_obj->list);
5136 
5137         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5138         pcmd_obj->cmdsz = cmdsz;
5139         pcmd_obj->parmbuf = pevtcmd;
5140 
5141         pcmd_obj->rsp = NULL;
5142         pcmd_obj->rspsz  = 0;
5143 
5144         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5145         pc2h_evt_hdr->len = sizeof(struct joinbss_event);
5146         pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
5147         pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5148 
5149         pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5150         memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
5151         pjoinbss_evt->network.join_res  = pjoinbss_evt->network.aid = res;
5152 
5153         DBG_871X("report_join_res(%d)\n", res);
5154 
5155 
5156         rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
5157 
5158 
5159         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5160 
5161         return;
5162 
5163 }
5164 
5165 void report_wmm_edca_update(struct adapter *padapter)
5166 {
5167         struct cmd_obj *pcmd_obj;
5168         u8 *pevtcmd;
5169         u32 cmdsz;
5170         struct wmm_event                *pwmm_event;
5171         struct C2HEvent_Header  *pc2h_evt_hdr;
5172         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5173         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5174 
5175         pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5176         if (!pcmd_obj)
5177                 return;
5178 
5179         cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
5180         pevtcmd = rtw_zmalloc(cmdsz);
5181         if (!pevtcmd) {
5182                 kfree(pcmd_obj);
5183                 return;
5184         }
5185 
5186         INIT_LIST_HEAD(&pcmd_obj->list);
5187 
5188         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5189         pcmd_obj->cmdsz = cmdsz;
5190         pcmd_obj->parmbuf = pevtcmd;
5191 
5192         pcmd_obj->rsp = NULL;
5193         pcmd_obj->rspsz  = 0;
5194 
5195         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5196         pc2h_evt_hdr->len = sizeof(struct wmm_event);
5197         pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
5198         pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5199 
5200         pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5201         pwmm_event->wmm = 0;
5202 
5203         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5204 
5205         return;
5206 
5207 }
5208 
5209 void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
5210 {
5211         struct cmd_obj *pcmd_obj;
5212         u8 *pevtcmd;
5213         u32 cmdsz;
5214         struct sta_info *psta;
5215         int     mac_id;
5216         struct stadel_event                     *pdel_sta_evt;
5217         struct C2HEvent_Header  *pc2h_evt_hdr;
5218         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5219         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5220 
5221         pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5222         if (pcmd_obj == NULL) {
5223                 return;
5224         }
5225 
5226         cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
5227         pevtcmd = rtw_zmalloc(cmdsz);
5228         if (pevtcmd == NULL) {
5229                 kfree(pcmd_obj);
5230                 return;
5231         }
5232 
5233         INIT_LIST_HEAD(&pcmd_obj->list);
5234 
5235         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5236         pcmd_obj->cmdsz = cmdsz;
5237         pcmd_obj->parmbuf = pevtcmd;
5238 
5239         pcmd_obj->rsp = NULL;
5240         pcmd_obj->rspsz  = 0;
5241 
5242         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5243         pc2h_evt_hdr->len = sizeof(struct stadel_event);
5244         pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
5245         pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5246 
5247         pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5248         memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
5249         memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
5250 
5251 
5252         psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
5253         if (psta)
5254                 mac_id = (int)psta->mac_id;
5255         else
5256                 mac_id = (-1);
5257 
5258         pdel_sta_evt->mac_id = mac_id;
5259 
5260         DBG_871X("report_del_sta_event: delete STA, mac_id =%d\n", mac_id);
5261 
5262         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5263 
5264         return;
5265 }
5266 
5267 void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx)
5268 {
5269         struct cmd_obj *pcmd_obj;
5270         u8 *pevtcmd;
5271         u32 cmdsz;
5272         struct stassoc_event            *padd_sta_evt;
5273         struct C2HEvent_Header  *pc2h_evt_hdr;
5274         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5275         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5276 
5277         pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
5278         if (pcmd_obj == NULL)
5279                 return;
5280 
5281         cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
5282         pevtcmd = rtw_zmalloc(cmdsz);
5283         if (pevtcmd == NULL) {
5284                 kfree(pcmd_obj);
5285                 return;
5286         }
5287 
5288         INIT_LIST_HEAD(&pcmd_obj->list);
5289 
5290         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5291         pcmd_obj->cmdsz = cmdsz;
5292         pcmd_obj->parmbuf = pevtcmd;
5293 
5294         pcmd_obj->rsp = NULL;
5295         pcmd_obj->rspsz  = 0;
5296 
5297         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
5298         pc2h_evt_hdr->len = sizeof(struct stassoc_event);
5299         pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
5300         pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5301 
5302         padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
5303         memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
5304         padd_sta_evt->cam_id = cam_idx;
5305 
5306         DBG_871X("report_add_sta_event: add STA\n");
5307 
5308         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
5309 
5310         return;
5311 }
5312 
5313 /****************************************************************************
5314 
5315 Following are the event callback functions
5316 
5317 *****************************************************************************/
5318 
5319 /* for sta/adhoc mode */
5320 void update_sta_info(struct adapter *padapter, struct sta_info *psta)
5321 {
5322         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5323         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5324         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5325 
5326         /* ERP */
5327         VCS_update(padapter, psta);
5328 
5329         /* HT */
5330         if (pmlmepriv->htpriv.ht_option) {
5331                 psta->htpriv.ht_option = true;
5332 
5333                 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5334 
5335                 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
5336 
5337                 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
5338                         psta->htpriv.sgi_20m = true;
5339 
5340                 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
5341                         psta->htpriv.sgi_40m = true;
5342 
5343                 psta->qos_option = true;
5344 
5345                 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
5346                 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
5347                 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
5348 
5349                 memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
5350         } else {
5351                 psta->htpriv.ht_option = false;
5352 
5353                 psta->htpriv.ampdu_enable = false;
5354 
5355                 psta->htpriv.sgi_20m = false;
5356                 psta->htpriv.sgi_40m = false;
5357                 psta->qos_option = false;
5358 
5359         }
5360 
5361         psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5362 
5363         psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5364         psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5365 
5366         psta->bw_mode = pmlmeext->cur_bwmode;
5367 
5368         /* QoS */
5369         if (pmlmepriv->qospriv.qos_option)
5370                 psta->qos_option = true;
5371 
5372         update_ldpc_stbc_cap(psta);
5373 
5374         spin_lock_bh(&psta->lock);
5375         psta->state = _FW_LINKED;
5376         spin_unlock_bh(&psta->lock);
5377 
5378 }
5379 
5380 static void rtw_mlmeext_disconnect(struct adapter *padapter)
5381 {
5382         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
5383         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5384         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5385         struct wlan_bssid_ex            *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
5386 
5387         /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5388 
5389         /*
5390          * For safety, prevent from keeping macid sleep.
5391          * If we can sure all power mode enter/leave are paired,
5392          * this check can be removed.
5393          * Lucas@20131113
5394          */
5395         /* wakeup macid after disconnect. */
5396         {
5397                 struct sta_info *psta;
5398                 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork));
5399                 if (psta)
5400                         rtw_hal_macid_wakeup(padapter, psta->mac_id);
5401         }
5402 
5403         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
5404         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
5405 
5406         /* set MSR to no link state -> infra. mode */
5407         Set_MSR(padapter, _HW_STATE_STATION_);
5408 
5409         pmlmeinfo->state = WIFI_FW_NULL_STATE;
5410 
5411         /* switch to the 20M Hz mode after disconnect */
5412         pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
5413         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5414 
5415         set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5416 
5417         flush_all_cam_entry(padapter);
5418 
5419         del_timer_sync(&pmlmeext->link_timer);
5420 
5421         /* pmlmepriv->LinkDetectInfo.TrafficBusyState = false; */
5422         pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
5423         pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
5424 
5425 }
5426 
5427 void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
5428 {
5429         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5430         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5431         struct wlan_bssid_ex            *cur_network = &(pmlmeinfo->network);
5432         struct sta_priv         *pstapriv = &padapter->stapriv;
5433         u8 join_type;
5434         struct sta_info *psta;
5435         if (join_res < 0) {
5436                 join_type = 1;
5437                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5438                 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
5439 
5440                 goto exit_mlmeext_joinbss_event_callback;
5441         }
5442 
5443         if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5444                 /* update bc/mc sta_info */
5445                 update_bmc_sta(padapter);
5446 
5447 
5448         /* turn on dynamic functions */
5449         Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
5450 
5451         /*  update IOT-releated issue */
5452         update_IOT_info(padapter);
5453 
5454         rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
5455 
5456         /* BCN interval */
5457         rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
5458 
5459         /* udpate capability */
5460         update_capinfo(padapter, pmlmeinfo->capability);
5461 
5462         /* WMM, Update EDCA param */
5463         WMMOnAssocRsp(padapter);
5464 
5465         /* HT */
5466         HTOnAssocRsp(padapter);
5467 
5468         /* Set cur_channel&cur_bwmode&cur_ch_offset */
5469         set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5470 
5471         psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
5472         if (psta) { /* only for infra. mode */
5473 
5474                 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5475 
5476                 /* DBG_871X("set_sta_rate\n"); */
5477 
5478                 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5479 
5480                 /* set per sta rate after updating HT cap. */
5481                 set_sta_rate(padapter, psta);
5482 
5483                 rtw_sta_media_status_rpt(padapter, psta, 1);
5484 
5485                 /* wakeup macid after join bss successfully to ensure
5486                         the subsequent data frames can be sent out normally */
5487                 rtw_hal_macid_wakeup(padapter, psta->mac_id);
5488         }
5489 
5490         join_type = 2;
5491         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5492 
5493         if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5494                 /*  correcting TSF */
5495                 correct_TSF(padapter, pmlmeext);
5496 
5497                 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5498         }
5499 
5500         if (get_iface_type(padapter) == IFACE_PORT0)
5501                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
5502 
5503 exit_mlmeext_joinbss_event_callback:
5504 
5505         DBG_871X("=>%s\n", __func__);
5506 
5507 }
5508 
5509 /* currently only adhoc mode will go here */
5510 void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta)
5511 {
5512         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5513         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5514         u8 join_type;
5515 
5516         DBG_871X("%s\n", __func__);
5517 
5518         if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
5519                 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */
5520 
5521                         /* nothing to do */
5522                 } else { /* adhoc client */
5523                         /* update TSF Value */
5524                         /* update_TSF(pmlmeext, pframe, len); */
5525 
5526                         /*  correcting TSF */
5527                         correct_TSF(padapter, pmlmeext);
5528 
5529                         /* start beacon */
5530                         if (send_beacon(padapter) == _FAIL) {
5531                                 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5532 
5533                                 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5534 
5535                                 return;
5536                         }
5537 
5538                         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5539 
5540                 }
5541 
5542                 join_type = 2;
5543                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5544         }
5545 
5546         pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5547 
5548         psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates);
5549         memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen);
5550 
5551         /* update adhoc sta_info */
5552         update_sta_info(padapter, psta);
5553 
5554         rtw_hal_update_sta_rate_mask(padapter, psta);
5555 
5556         /*  ToDo: HT for Ad-hoc */
5557         psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
5558         psta->raid = networktype_to_raid_ex(padapter, psta);
5559 
5560         /* rate radaptive */
5561         Update_RA_Entry(padapter, psta);
5562 }
5563 
5564 void mlmeext_sta_del_event_callback(struct adapter *padapter)
5565 {
5566         if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
5567                 rtw_mlmeext_disconnect(padapter);
5568 }
5569 
5570 /****************************************************************************
5571 
5572 Following are the functions for the timer handlers
5573 
5574 *****************************************************************************/
5575 void _linked_info_dump(struct adapter *padapter)
5576 {
5577         int i;
5578         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5579         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5580         int UndecoratedSmoothedPWDB;
5581         struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
5582 
5583         if (padapter->bLinkInfoDump) {
5584 
5585                 DBG_871X("\n ============["ADPT_FMT"] linked status check ===================\n", ADPT_ARG(padapter));
5586 
5587                 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5588                         rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
5589 
5590                         DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
5591                                 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress), UndecoratedSmoothedPWDB);
5592                 } else if ((pmlmeinfo->state&0x03) == _HW_STATE_AP_) {
5593                         struct list_head        *phead, *plist;
5594 
5595                         struct sta_info *psta = NULL;
5596                         struct sta_priv *pstapriv = &padapter->stapriv;
5597 
5598                         spin_lock_bh(&pstapriv->asoc_list_lock);
5599                         phead = &pstapriv->asoc_list;
5600                         plist = get_next(phead);
5601                         while (phead != plist) {
5602                                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
5603                                 plist = get_next(plist);
5604 
5605                                 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n",
5606                                         MAC_ARG(psta->hwaddr), psta->rssi_stat.UndecoratedSmoothedPWDB);
5607                         }
5608                         spin_unlock_bh(&pstapriv->asoc_list_lock);
5609 
5610                 }
5611                 for (i = 0; i < NUM_STA; i++) {
5612                         if (pdvobj->macid[i]) {
5613                                 if (i != 1) /* skip bc/mc sta */
5614                                         /*   tx info ============ */
5615                                         rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i);
5616                         }
5617                 }
5618                 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_RX_INFO_DUMP, NULL);
5619 
5620 
5621         }
5622 
5623 
5624 }
5625 
5626 static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta)
5627 {
5628         u8 ret = false;
5629 
5630         #ifdef DBG_EXPIRATION_CHK
5631         DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
5632                                 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
5633                                 ", retry:%u\n"
5634                 , FUNC_ADPT_ARG(padapter)
5635                 , STA_RX_PKTS_DIFF_ARG(psta)
5636                 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
5637                 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
5638                 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
5639                 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
5640                 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
5641                 , pmlmeinfo->bcn_interval*/
5642                 , pmlmeext->retry
5643         );
5644 
5645         DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
5646                 , padapter->xmitpriv.tx_pkts
5647                 , pmlmeinfo->link_count
5648         );
5649         #endif
5650 
5651         if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
5652                 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
5653                 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
5654         ) {
5655                 ret = false;
5656         } else {
5657                 ret = true;
5658         }
5659 
5660         sta_update_last_rx_pkts(psta);
5661 
5662         return ret;
5663 }
5664 
5665 void linked_status_chk(struct adapter *padapter)
5666 {
5667         u32 i;
5668         struct sta_info         *psta;
5669         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
5670         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5671         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5672         struct sta_priv         *pstapriv = &padapter->stapriv;
5673 
5674 
5675         if (is_client_associated_to_ap(padapter)) {
5676                 /* linked infrastructure client mode */
5677 
5678                 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5679                 int rx_chk_limit;
5680                 int link_count_limit;
5681 
5682                 #if defined(DBG_ROAMING_TEST)
5683                 rx_chk_limit = 1;
5684                 #else
5685                 rx_chk_limit = 8;
5686                 #endif
5687                 link_count_limit = 7; /*  16 sec */
5688 
5689                 /*  Marked by Kurt 20130715 */
5690                 /*  For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. */
5691                 /*  todo: To check why we under miracast session, rx_chk would be false */
5692                 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
5693                 if (psta != NULL) {
5694                         if (chk_ap_is_alive(padapter, psta) == false)
5695                                 rx_chk = _FAIL;
5696 
5697                         if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5698                                 tx_chk = _FAIL;
5699 
5700                         {
5701                                 if (rx_chk != _SUCCESS) {
5702                                         if (pmlmeext->retry == 0) {
5703                                                 #ifdef DBG_EXPIRATION_CHK
5704                                                 DBG_871X("issue_probereq to trigger probersp, retry =%d\n", pmlmeext->retry);
5705                                                 #endif
5706                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
5707                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
5708                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
5709                                         }
5710                                 }
5711 
5712                                 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
5713                                         #ifdef DBG_EXPIRATION_CHK
5714                                         DBG_871X("%s issue_nulldata 0\n", __func__);
5715                                         #endif
5716                                         tx_chk = issue_nulldata_in_interrupt(padapter, NULL);
5717                                 }
5718                         }
5719 
5720                         if (rx_chk == _FAIL) {
5721                                 pmlmeext->retry++;
5722                                 if (pmlmeext->retry > rx_chk_limit) {
5723                                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
5724                                                 FUNC_ADPT_ARG(padapter));
5725                                         receive_disconnect(padapter, pmlmeinfo->network.MacAddress
5726                                                 , WLAN_REASON_EXPIRATION_CHK);
5727                                         return;
5728                                 }
5729                         } else {
5730                                 pmlmeext->retry = 0;
5731                         }
5732 
5733                         if (tx_chk == _FAIL) {
5734                                 pmlmeinfo->link_count %= (link_count_limit+1);
5735                         } else {
5736                                 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5737                                 pmlmeinfo->link_count = 0;
5738                         }
5739 
5740                 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
5741         } else if (is_client_associated_to_ibss(padapter)) {
5742                 /* linked IBSS mode */
5743                 /* for each assoc list entry to check the rx pkt counter */
5744                 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
5745                         if (pmlmeinfo->FW_sta_info[i].status == 1) {
5746                                 psta = pmlmeinfo->FW_sta_info[i].psta;
5747 
5748                                 if (NULL == psta)
5749                                         continue;
5750 
5751                                 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) {
5752 
5753                                         if (pmlmeinfo->FW_sta_info[i].retry < 3) {
5754                                                 pmlmeinfo->FW_sta_info[i].retry++;
5755                                         } else {
5756                                                 pmlmeinfo->FW_sta_info[i].retry = 0;
5757                                                 pmlmeinfo->FW_sta_info[i].status = 0;
5758                                                 report_del_sta_event(padapter, psta->hwaddr
5759                                                         , 65535/*  indicate disconnect caused by no rx */
5760                                                 );
5761                                         }
5762                                 } else {
5763                                         pmlmeinfo->FW_sta_info[i].retry = 0;
5764                                         pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5765                                 }
5766                         }
5767                 }
5768 
5769                 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5770 
5771         }
5772 
5773 }
5774 
5775 void survey_timer_hdl(struct timer_list *t)
5776 {
5777         struct adapter *padapter =
5778                 from_timer(padapter, t, mlmeextpriv.survey_timer);
5779         struct cmd_obj  *ph2c;
5780         struct sitesurvey_parm  *psurveyPara;
5781         struct cmd_priv                                 *pcmdpriv = &padapter->cmdpriv;
5782         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5783 
5784         /* DBG_871X("marc: survey timer\n"); */
5785 
5786         /* issue rtw_sitesurvey_cmd */
5787         if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5788                 if (pmlmeext->sitesurvey_res.state ==  SCAN_PROCESS) {
5789                         pmlmeext->sitesurvey_res.channel_idx++;
5790                 }
5791 
5792                 if (pmlmeext->scan_abort) {
5793                         {
5794                                 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
5795                                 DBG_871X("%s idx:%d\n", __func__
5796                                         , pmlmeext->sitesurvey_res.channel_idx
5797                                 );
5798                         }
5799 
5800                         pmlmeext->scan_abort = false;/* reset */
5801                 }
5802 
5803                 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
5804                 if (ph2c == NULL) {
5805                         goto exit_survey_timer_hdl;
5806                 }
5807 
5808                 psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
5809                 if (psurveyPara == NULL) {
5810                         kfree(ph2c);
5811                         goto exit_survey_timer_hdl;
5812                 }
5813 
5814                 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5815                 rtw_enqueue_cmd(pcmdpriv, ph2c);
5816         }
5817 
5818 
5819 exit_survey_timer_hdl:
5820 
5821         return;
5822 }
5823 
5824 void link_timer_hdl(struct timer_list *t)
5825 {
5826         struct adapter *padapter =
5827                 from_timer(padapter, t, mlmeextpriv.link_timer);
5828         /* static unsigned int          rx_pkt = 0; */
5829         /* static u64                           tx_cnt = 0; */
5830         /* struct xmit_priv     *pxmitpriv = &(padapter->xmitpriv); */
5831         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5832         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5833         /* struct sta_priv      *pstapriv = &padapter->stapriv; */
5834 
5835 
5836         if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
5837                 DBG_871X("link_timer_hdl:no beacon while connecting\n");
5838                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5839                 report_join_res(padapter, -3);
5840         } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
5841                 /* re-auth timer */
5842                 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
5843                         /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5844                         /*  */
5845                                 pmlmeinfo->state = 0;
5846                                 report_join_res(padapter, -1);
5847                                 return;
5848                         /*  */
5849                         /* else */
5850                         /*  */
5851                         /*      pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5852                         /*      pmlmeinfo->reauth_count = 0; */
5853                         /*  */
5854                 }
5855 
5856                 DBG_871X("link_timer_hdl: auth timeout and try again\n");
5857                 pmlmeinfo->auth_seq = 1;
5858                 issue_auth(padapter, NULL, 0);
5859                 set_link_timer(pmlmeext, REAUTH_TO);
5860         } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
5861                 /* re-assoc timer */
5862                 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
5863                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
5864                         report_join_res(padapter, -2);
5865                         return;
5866                 }
5867 
5868                 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
5869                 issue_assocreq(padapter);
5870                 set_link_timer(pmlmeext, REASSOC_TO);
5871         }
5872 
5873         return;
5874 }
5875 
5876 void addba_timer_hdl(struct timer_list *t)
5877 {
5878         struct sta_info *psta = from_timer(psta, t, addba_retry_timer);
5879         struct ht_priv *phtpriv;
5880 
5881         if (!psta)
5882                 return;
5883 
5884         phtpriv = &psta->htpriv;
5885 
5886         if (phtpriv->ht_option && phtpriv->ampdu_enable) {
5887                 if (phtpriv->candidate_tid_bitmap)
5888                         phtpriv->candidate_tid_bitmap = 0x0;
5889 
5890         }
5891 }
5892 
5893 void sa_query_timer_hdl(struct timer_list *t)
5894 {
5895         struct adapter *padapter =
5896                 from_timer(padapter, t, mlmeextpriv.sa_query_timer);
5897         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5898         /* disconnect */
5899         spin_lock_bh(&pmlmepriv->lock);
5900 
5901         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
5902                 rtw_disassoc_cmd(padapter, 0, true);
5903                 rtw_indicate_disconnect(padapter);
5904                 rtw_free_assoc_resources(padapter, 1);
5905         }
5906 
5907         spin_unlock_bh(&pmlmepriv->lock);
5908         DBG_871X("SA query timeout disconnect\n");
5909 }
5910 
5911 u8 NULL_hdl(struct adapter *padapter, u8 *pbuf)
5912 {
5913         return H2C_SUCCESS;
5914 }
5915 
5916 #ifdef CONFIG_AUTO_AP_MODE
5917 static int rtw_auto_ap_start_beacon(struct adapter *adapter)
5918 {
5919         int ret = 0;
5920         u8 *pbuf = NULL;
5921         uint len;
5922         u8 supportRate[16];
5923         int     sz = 0, rateLen;
5924         u8 *ie;
5925         u8 wireless_mode, oper_channel;
5926         u8 ssid[3] = {0}; /* hidden ssid */
5927         u32 ssid_len = sizeof(ssid);
5928         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5929 
5930 
5931         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
5932                 return -EINVAL;
5933 
5934 
5935         len = 128;
5936         pbuf = rtw_zmalloc(len);
5937         if (!pbuf)
5938                 return -ENOMEM;
5939 
5940 
5941         /* generate beacon */
5942         ie = pbuf;
5943 
5944         /* timestamp will be inserted by hardware */
5945         sz += 8;
5946         ie += sz;
5947 
5948         /* beacon interval : 2bytes */
5949         *(u16 *)ie = cpu_to_le16((u16)100);/* BCN_INTERVAL = 100; */
5950         sz += 2;
5951         ie += 2;
5952 
5953         /* capability info */
5954         *(u16 *)ie = 0;
5955         *(u16 *)ie |= cpu_to_le16(cap_ESS);
5956         *(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
5957         /* u16*)ie |= cpu_to_le16(cap_Privacy); */
5958         sz += 2;
5959         ie += 2;
5960 
5961         /* SSID */
5962         ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
5963 
5964         /* supported rates */
5965         wireless_mode = WIRELESS_11BG_24N;
5966         rtw_set_supported_rate(supportRate, wireless_mode);
5967         rateLen = rtw_get_rateset_len(supportRate);
5968         if (rateLen > 8) {
5969                 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
5970         } else {
5971                 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
5972         }
5973 
5974 
5975         /* DS parameter set */
5976         if (check_buddy_fwstate(adapter, _FW_LINKED) &&
5977                 check_buddy_fwstate(adapter, WIFI_STATION_STATE)) {
5978                 struct adapter *pbuddystruct adapter = adapter->pbuddystruct adapter;
5979                 struct mlme_ext_priv *pbuddy_mlmeext  = &pbuddystruct adapter->mlmeextpriv;
5980 
5981                 oper_channel = pbuddy_mlmeext->cur_channel;
5982         } else {
5983                 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
5984         }
5985         ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
5986 
5987         /* ext supported rates */
5988         if (rateLen > 8) {
5989                 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
5990         }
5991 
5992         DBG_871X("%s, start auto ap beacon sz =%d\n", __func__, sz);
5993 
5994         /* lunch ap mode & start to issue beacon */
5995         if (rtw_check_beacon_data(adapter, pbuf,  sz) == _SUCCESS) {
5996 
5997         } else {
5998                 ret = -EINVAL;
5999         }
6000 
6001 
6002         kfree(pbuf);
6003 
6004         return ret;
6005 
6006 }
6007 #endif/* CONFIG_AUTO_AP_MODE */
6008 
6009 u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
6010 {
6011         u8 type;
6012         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6013         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6014         struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
6015 
6016         if (psetop->mode == Ndis802_11APMode) {
6017                 pmlmeinfo->state = WIFI_FW_AP_STATE;
6018                 type = _HW_STATE_AP_;
6019                 /* start_ap_mode(padapter); */
6020         } else if (psetop->mode == Ndis802_11Infrastructure) {
6021                 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/*  clear state */
6022                 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to     STATION_STATE */
6023                 type = _HW_STATE_STATION_;
6024         } else if (psetop->mode == Ndis802_11IBSS) {
6025                 type = _HW_STATE_ADHOC_;
6026         } else {
6027                 type = _HW_STATE_NOLINK_;
6028         }
6029 
6030         rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
6031         /* Set_MSR(padapter, type); */
6032 
6033 
6034 #ifdef CONFIG_AUTO_AP_MODE
6035         if (psetop->mode == Ndis802_11APMode)
6036                 rtw_auto_ap_start_beacon(padapter);
6037 #endif
6038 
6039         if (psetop->mode == Ndis802_11APMode) {
6040                 /*  Do this after port switch to */
6041                 /*  prevent from downloading rsvd page to wrong port */
6042                 rtw_btcoex_MediaStatusNotify(padapter, 1); /* connect */
6043         }
6044 
6045         return H2C_SUCCESS;
6046 
6047 }
6048 
6049 u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
6050 {
6051         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6052         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6053         struct wlan_bssid_ex    *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
6054         struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
6055         /* u32 initialgain; */
6056 
6057         if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
6058                 struct wlan_bssid_ex *network = &padapter->mlmepriv.cur_network.network;
6059                 start_bss_network(padapter, (u8 *)network);
6060                 return H2C_SUCCESS;
6061         }
6062 
6063         /* below is for ad-hoc master */
6064         if (pparm->network.InfrastructureMode == Ndis802_11IBSS) {
6065                 rtw_joinbss_reset(padapter);
6066 
6067                 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
6068                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6069                 pmlmeinfo->ERP_enable = 0;
6070                 pmlmeinfo->WMM_enable = 0;
6071                 pmlmeinfo->HT_enable = 0;
6072                 pmlmeinfo->HT_caps_enable = 0;
6073                 pmlmeinfo->HT_info_enable = 0;
6074                 pmlmeinfo->agg_enable_bitmap = 0;
6075                 pmlmeinfo->candidate_tid_bitmap = 0;
6076 
6077                 /* disable dynamic functions, such as high power, DIG */
6078                 Save_DM_Func_Flag(padapter);
6079                 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
6080 
6081                 /* config the initial gain under linking, need to write the BB registers */
6082                 /* initialgain = 0x1E; */
6083                 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
6084 
6085                 /* cancel link timer */
6086                 del_timer_sync(&pmlmeext->link_timer);
6087 
6088                 /* clear CAM */
6089                 flush_all_cam_entry(padapter);
6090 
6091                 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
6092                 pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
6093 
6094                 if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
6095                         return H2C_PARAMETERS_ERROR;
6096 
6097                 memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
6098 
6099                 start_create_ibss(padapter);
6100 
6101         }
6102 
6103         return H2C_SUCCESS;
6104 
6105 }
6106 
6107 u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
6108 {
6109         u8 join_type;
6110         struct ndis_80211_var_ie *pIE;
6111         struct registry_priv *pregpriv = &padapter->registrypriv;
6112         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6113         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6114         struct wlan_bssid_ex            *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
6115         u32 i;
6116         u8 cbw40_enable = 0;
6117         /* u32 initialgain; */
6118         /* u32 acparm; */
6119         u8 ch, bw, offset;
6120 
6121         /* check already connecting to AP or not */
6122         if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
6123                 if (pmlmeinfo->state & WIFI_FW_STATION_STATE) {
6124                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
6125                 }
6126                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
6127 
6128                 /* clear CAM */
6129                 flush_all_cam_entry(padapter);
6130 
6131                 del_timer_sync(&pmlmeext->link_timer);
6132 
6133                 /* set MSR to nolink -> infra. mode */
6134                 /* Set_MSR(padapter, _HW_STATE_NOLINK_); */
6135                 Set_MSR(padapter, _HW_STATE_STATION_);
6136 
6137 
6138                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
6139         }
6140 
6141         rtw_joinbss_reset(padapter);
6142 
6143         pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
6144         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6145         pmlmeinfo->ERP_enable = 0;
6146         pmlmeinfo->WMM_enable = 0;
6147         pmlmeinfo->HT_enable = 0;
6148         pmlmeinfo->HT_caps_enable = 0;
6149         pmlmeinfo->HT_info_enable = 0;
6150         pmlmeinfo->agg_enable_bitmap = 0;
6151         pmlmeinfo->candidate_tid_bitmap = 0;
6152         pmlmeinfo->bwmode_updated = false;
6153         /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
6154         pmlmeinfo->VHT_enable = 0;
6155 
6156         memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
6157         pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
6158 
6159         if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
6160                 return H2C_PARAMETERS_ERROR;
6161 
6162         memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
6163 
6164         pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
6165         pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
6166 
6167         /* Check AP vendor to move rtw_joinbss_cmd() */
6168         /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
6169 
6170         /* sizeof(struct ndis_802_11_fix_ie) */
6171         for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;) {
6172                 pIE = (struct ndis_80211_var_ie *)(pnetwork->IEs + i);
6173 
6174                 switch (pIE->ElementID) {
6175                 case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
6176                         if (!memcmp(pIE->data, WMM_OUI, 4))
6177                                 WMM_param_handler(padapter, pIE);
6178                         break;
6179 
6180                 case _HT_CAPABILITY_IE_:        /* Get HT Cap IE. */
6181                         pmlmeinfo->HT_caps_enable = 1;
6182                         break;
6183 
6184                 case _HT_EXTRA_INFO_IE_:        /* Get HT Info IE. */
6185                         pmlmeinfo->HT_info_enable = 1;
6186 
6187                         /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
6188                         {
6189                                 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
6190 
6191                                 if (pnetwork->Configuration.DSConfig > 14) {
6192                                         if ((pregpriv->bw_mode >> 4) > CHANNEL_WIDTH_20)
6193                                                 cbw40_enable = 1;
6194                                 } else {
6195                                         if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
6196                                                 cbw40_enable = 1;
6197                                 }
6198 
6199                                 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
6200                                         /* switch to the 40M Hz mode according to the AP */
6201                                         pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
6202                                         switch (pht_info->infos[0] & 0x3) {
6203                                         case 1:
6204                                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
6205                                                 break;
6206 
6207                                         case 3:
6208                                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
6209                                                 break;
6210 
6211                                         default:
6212                                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6213                                                 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
6214                                                 break;
6215                                         }
6216 
6217                                         DBG_871X("set HT ch/bw before connected\n");
6218                                 }
6219                         }
6220                         break;
6221                 default:
6222                         break;
6223                 }
6224 
6225                 i += (pIE->Length + 2);
6226         }
6227 
6228         /* check channel, bandwidth, offset and switch */
6229         if (rtw_chk_start_clnt_join(padapter, &ch, &bw, &offset) == _FAIL) {
6230                 report_join_res(padapter, (-4));
6231                 return H2C_SUCCESS;
6232         }
6233 
6234         /* disable dynamic functions, such as high power, DIG */
6235         /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); */
6236 
6237         /* config the initial gain under linking, need to write the BB registers */
6238         /* initialgain = 0x1E; */
6239         /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
6240 
6241         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
6242         join_type = 0;
6243         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
6244         rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
6245 
6246         set_channel_bwmode(padapter, ch, offset, bw);
6247 
6248         /* cancel link timer */
6249         del_timer_sync(&pmlmeext->link_timer);
6250 
6251         start_clnt_join(padapter);
6252 
6253         return H2C_SUCCESS;
6254 
6255 }
6256 
6257 u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
6258 {
6259         struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
6260         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6261         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6262         struct wlan_bssid_ex            *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
6263         u8 val8;
6264 
6265         if (is_client_associated_to_ap(padapter)) {
6266                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
6267         }
6268 
6269         if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
6270                 /* Stop BCN */
6271                 val8 = 0;
6272                 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
6273         }
6274 
6275         rtw_mlmeext_disconnect(padapter);
6276 
6277         rtw_free_uc_swdec_pending_queue(padapter);
6278 
6279         return  H2C_SUCCESS;
6280 }
6281 
6282 static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out,
6283         u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
6284 {
6285         int i, j;
6286         int set_idx;
6287         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6288 
6289         /* clear first */
6290         memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
6291 
6292         /* acquire channels from in */
6293         j = 0;
6294         for (i = 0; i < in_num; i++) {
6295 
6296                 DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
6297 
6298                 set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
6299                 if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
6300                         && set_idx >= 0
6301                         && rtw_mlme_band_check(padapter, in[i].hw_value)
6302                 ) {
6303                         if (j >= out_num) {
6304                                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
6305                                         FUNC_ADPT_ARG(padapter), out_num);
6306                                 break;
6307                         }
6308 
6309                         memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
6310 
6311                         if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
6312                                 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
6313 
6314                         j++;
6315                 }
6316                 if (j >= out_num)
6317                         break;
6318         }
6319 
6320         /* if out is empty, use channel_set as default */
6321         if (j == 0) {
6322                 for (i = 0; i < pmlmeext->max_chan_nums; i++) {
6323 
6324                         DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
6325 
6326                         if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum)) {
6327 
6328                                 if (j >= out_num) {
6329                                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
6330                                                 FUNC_ADPT_ARG(padapter), out_num);
6331                                         break;
6332                                 }
6333 
6334                                 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
6335 
6336                                 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
6337                                         out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
6338 
6339                                 j++;
6340                         }
6341                 }
6342         }
6343 
6344         return j;
6345 }
6346 
6347 u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
6348 {
6349         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6350         struct sitesurvey_parm  *pparm = (struct sitesurvey_parm *)pbuf;
6351         u8 bdelayscan = false;
6352         u8 val8;
6353         u32 initialgain;
6354         u32 i;
6355 
6356         if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
6357                 pmlmeext->sitesurvey_res.state = SCAN_START;
6358                 pmlmeext->sitesurvey_res.bss_cnt = 0;
6359                 pmlmeext->sitesurvey_res.channel_idx = 0;
6360 
6361                 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6362                         if (pparm->ssid[i].SsidLength) {
6363                                 memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
6364                                 pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength;
6365                         } else {
6366                                 pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0;
6367                         }
6368                 }
6369 
6370                 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
6371                         , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
6372                         , pparm->ch, pparm->ch_num
6373                 );
6374 
6375                 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
6376 
6377                 /* issue null data if associating to the AP */
6378                 if (is_client_associated_to_ap(padapter)) {
6379                         pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
6380 
6381                         issue_nulldata(padapter, NULL, 1, 3, 500);
6382 
6383                         bdelayscan = true;
6384                 }
6385                 if (bdelayscan) {
6386                         /* delay 50ms to protect nulldata(1). */
6387                         set_survey_timer(pmlmeext, 50);
6388                         return H2C_SUCCESS;
6389                 }
6390         }
6391 
6392         if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
6393                 /* disable dynamic functions, such as high power, DIG */
6394                 Save_DM_Func_Flag(padapter);
6395                 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
6396 
6397                 /* config the initial gain under scaning, need to write the BB registers */
6398                 initialgain = 0x1e;
6399 
6400                 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
6401 
6402                 /* set MSR to no link state */
6403                 Set_MSR(padapter, _HW_STATE_NOLINK_);
6404 
6405                 val8 = 1; /* under site survey */
6406                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
6407 
6408                 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
6409         }
6410 
6411         site_survey(padapter);
6412 
6413         return H2C_SUCCESS;
6414 
6415 }
6416 
6417 u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf)
6418 {
6419         struct setauth_parm             *pparm = (struct setauth_parm *)pbuf;
6420         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6421         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6422 
6423         if (pparm->mode < 4)
6424                 pmlmeinfo->auth_algo = pparm->mode;
6425 
6426         return  H2C_SUCCESS;
6427 }
6428 
6429 u8 setkey_hdl(struct adapter *padapter, u8 *pbuf)
6430 {
6431         u16 ctrl = 0;
6432         s16 cam_id = 0;
6433         struct setkey_parm              *pparm = (struct setkey_parm *)pbuf;
6434         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6435         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6436         unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6437         u8 *addr;
6438 
6439         /* main tx key for wep. */
6440         if (pparm->set_tx)
6441                 pmlmeinfo->key_index = pparm->keyid;
6442 
6443         cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid);
6444 
6445         if (cam_id < 0) {
6446         } else {
6447                 if (cam_id > 3) /* not default key, searched by A2 */
6448                         addr = get_bssid(&padapter->mlmepriv);
6449                 else
6450                         addr = null_addr;
6451 
6452                 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
6453                 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
6454                 DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
6455                         , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
6456         }
6457 
6458         if (cam_id >= 0 && cam_id <= 3)
6459                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)true);
6460 
6461         /* allow multicast packets to driver */
6462         padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
6463 
6464         return H2C_SUCCESS;
6465 }
6466 
6467 u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
6468 {
6469         u16 ctrl = 0;
6470         s16 cam_id = 0;
6471         u8 ret = H2C_SUCCESS;
6472         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6473         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6474         struct set_stakey_parm  *pparm = (struct set_stakey_parm *)pbuf;
6475         struct sta_priv *pstapriv = &padapter->stapriv;
6476         struct sta_info *psta;
6477 
6478         if (pparm->algorithm == _NO_PRIVACY_)
6479                 goto write_to_cam;
6480 
6481         psta = rtw_get_stainfo(pstapriv, pparm->addr);
6482         if (!psta) {
6483                 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
6484                 ret = H2C_REJECTED;
6485                 goto exit;
6486         }
6487 
6488         pmlmeinfo->enc_algo = pparm->algorithm;
6489         cam_id = rtw_camid_alloc(padapter, psta, 0);
6490         if (cam_id < 0)
6491                 goto exit;
6492 
6493 write_to_cam:
6494         if (pparm->algorithm == _NO_PRIVACY_) {
6495                 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1)) >= 0) {
6496                         DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
6497                         clear_cam_entry(padapter, cam_id);
6498                         rtw_camid_free(padapter, cam_id);
6499                 }
6500         } else {
6501                 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
6502                         cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
6503                 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
6504                 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
6505         }
6506         ret = H2C_SUCCESS_RSP;
6507 
6508 exit:
6509         return ret;
6510 }
6511 
6512 u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
6513 {
6514         struct addBaReq_parm    *pparm = (struct addBaReq_parm *)pbuf;
6515         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6516         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6517 
6518         struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
6519 
6520         if (!psta)
6521                 return  H2C_SUCCESS;
6522 
6523         if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
6524                 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
6525                 /* pmlmeinfo->ADDBA_retry_count = 0; */
6526                 /* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */
6527                 /* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
6528                 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6529                 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
6530                 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
6531         } else {
6532                 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
6533         }
6534         return  H2C_SUCCESS;
6535 }
6536 
6537 
6538 u8 chk_bmc_sleepq_cmd(struct adapter *padapter)
6539 {
6540         struct cmd_obj *ph2c;
6541         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
6542         u8 res = _SUCCESS;
6543 
6544         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
6545         if (ph2c == NULL) {
6546                 res = _FAIL;
6547                 goto exit;
6548         }
6549 
6550         init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
6551 
6552         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
6553 
6554 exit:
6555         return res;
6556 }
6557 
6558 u8 set_tx_beacon_cmd(struct adapter *padapter)
6559 {
6560         struct cmd_obj  *ph2c;
6561         struct Tx_Beacon_param  *ptxBeacon_parm;
6562         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
6563         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6564         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6565         u8 res = _SUCCESS;
6566         int len_diff = 0;
6567 
6568         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
6569         if (ph2c == NULL) {
6570                 res = _FAIL;
6571                 goto exit;
6572         }
6573 
6574         ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param));
6575         if (ptxBeacon_parm == NULL) {
6576                 kfree(ph2c);
6577                 res = _FAIL;
6578                 goto exit;
6579         }
6580 
6581         memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
6582 
6583         len_diff = update_hidden_ssid(
6584                 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
6585                 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
6586                 , pmlmeinfo->hidden_ssid_mode
6587         );
6588         ptxBeacon_parm->network.IELength += len_diff;
6589 
6590         init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
6591 
6592         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
6593 
6594 exit:
6595         return res;
6596 }
6597 
6598 
6599 u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
6600 {
6601         u8 evt_code, evt_seq;
6602         u16 evt_sz;
6603         uint    *peventbuf;
6604         void (*event_callback)(struct adapter *dev, u8 *pbuf);
6605         struct evt_priv *pevt_priv = &(padapter->evtpriv);
6606 
6607         if (pbuf == NULL)
6608                 goto _abort_event_;
6609 
6610         peventbuf = (uint *)pbuf;
6611         evt_sz = (u16)(*peventbuf&0xffff);
6612         evt_seq = (u8)((*peventbuf>>24)&0x7f);
6613         evt_code = (u8)((*peventbuf>>16)&0xff);
6614 
6615 
6616         #ifdef CHECK_EVENT_SEQ
6617         /*  checking event sequence... */
6618         if (evt_seq != (atomic_read(&pevt_priv->event_seq) & 0x7f)) {
6619                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
6620                          ("Event Seq Error! %d vs %d\n", (evt_seq & 0x7f),
6621                           (atomic_read(&pevt_priv->event_seq) & 0x7f)));
6622 
6623                 pevt_priv->event_seq = (evt_seq+1)&0x7f;
6624 
6625                 goto _abort_event_;
6626         }
6627         #endif
6628 
6629         /*  checking if event code is valid */
6630         if (evt_code >= MAX_C2HEVT) {
6631                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
6632                 goto _abort_event_;
6633         }
6634 
6635         /*  checking if event size match the event parm size */
6636         if ((wlanevents[evt_code].parmsize != 0) &&
6637                         (wlanevents[evt_code].parmsize != evt_sz)) {
6638 
6639                 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6640                         evt_code, wlanevents[evt_code].parmsize, evt_sz));
6641                 goto _abort_event_;
6642 
6643         }
6644 
6645         atomic_inc(&pevt_priv->event_seq);
6646 
6647         peventbuf += 2;
6648 
6649         if (peventbuf) {
6650                 event_callback = wlanevents[evt_code].event_callback;
6651                 event_callback(padapter, (u8 *)peventbuf);
6652 
6653                 pevt_priv->evt_done_cnt++;
6654         }
6655 
6656 
6657 _abort_event_:
6658 
6659 
6660         return H2C_SUCCESS;
6661 
6662 }
6663 
6664 u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf)
6665 {
6666         if (!pbuf)
6667                 return H2C_PARAMETERS_ERROR;
6668 
6669         return H2C_SUCCESS;
6670 }
6671 
6672 u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
6673 {
6674         struct sta_info *psta_bmc;
6675         struct list_head        *xmitframe_plist, *xmitframe_phead;
6676         struct xmit_frame *pxmitframe = NULL;
6677         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6678         struct sta_priv  *pstapriv = &padapter->stapriv;
6679 
6680         /* for BC/MC Frames */
6681         psta_bmc = rtw_get_bcmc_stainfo(padapter);
6682         if (!psta_bmc)
6683                 return H2C_SUCCESS;
6684 
6685         if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) {
6686                 msleep(10);/*  10ms, ATIM(HIQ) Windows */
6687 
6688                 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6689                 spin_lock_bh(&pxmitpriv->lock);
6690 
6691                 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
6692                 xmitframe_plist = get_next(xmitframe_phead);
6693 
6694                 while (xmitframe_phead != xmitframe_plist) {
6695                         pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
6696 
6697                         xmitframe_plist = get_next(xmitframe_plist);
6698 
6699                         list_del_init(&pxmitframe->list);
6700 
6701                         psta_bmc->sleepq_len--;
6702                         if (psta_bmc->sleepq_len > 0)
6703                                 pxmitframe->attrib.mdata = 1;
6704                         else
6705                                 pxmitframe->attrib.mdata = 0;
6706 
6707                         pxmitframe->attrib.triggered = 1;
6708 
6709                         if (xmitframe_hiq_filter(pxmitframe))
6710                                 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6711 
6712                         rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
6713                 }
6714 
6715                 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6716                 spin_unlock_bh(&pxmitpriv->lock);
6717 
6718                 /* check hi queue and bmc_sleepq */
6719                 rtw_chk_hi_queue_cmd(padapter);
6720         }
6721 
6722         return H2C_SUCCESS;
6723 }
6724 
6725 u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
6726 {
6727         if (send_beacon(padapter) == _FAIL) {
6728                 DBG_871X("issue_beacon, fail!\n");
6729                 return H2C_PARAMETERS_ERROR;
6730         }
6731 
6732         /* tx bc/mc frames after update TIM */
6733         chk_bmc_sleepq_hdl(padapter, NULL);
6734 
6735         return H2C_SUCCESS;
6736 }
6737 
6738 int rtw_chk_start_clnt_join(struct adapter *padapter, u8 *ch, u8 *bw, u8 *offset)
6739 {
6740         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6741         unsigned char cur_ch = pmlmeext->cur_channel;
6742         unsigned char cur_bw = pmlmeext->cur_bwmode;
6743         unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
6744         bool connect_allow = true;
6745 
6746         if (!ch || !bw || !offset) {
6747                 rtw_warn_on(1);
6748                 connect_allow = false;
6749         }
6750 
6751         if (connect_allow) {
6752                 DBG_871X("start_join_set_ch_bw: ch =%d, bwmode =%d, ch_offset =%d\n", cur_ch, cur_bw, cur_ch_offset);
6753                 *ch = cur_ch;
6754                 *bw = cur_bw;
6755                 *offset = cur_ch_offset;
6756         }
6757 
6758         return connect_allow ? _SUCCESS : _FAIL;
6759 }
6760 
6761 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
6762 int rtw_get_ch_setting_union(struct adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
6763 {
6764         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6765         struct adapter *iface;
6766 
6767         if (ch)
6768                 *ch = 0;
6769         if (bw)
6770                 *bw = CHANNEL_WIDTH_20;
6771         if (offset)
6772                 *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6773 
6774         iface = dvobj->padapters;
6775 
6776         if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
6777                 return 0;
6778 
6779         return 1;
6780 }
6781 
6782 u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf)
6783 {
6784         struct set_ch_parm *set_ch_parm;
6785         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6786 
6787         if (!pbuf)
6788                 return H2C_PARAMETERS_ERROR;
6789 
6790         set_ch_parm = (struct set_ch_parm *)pbuf;
6791 
6792         DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
6793                 FUNC_NDEV_ARG(padapter->pnetdev),
6794                 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
6795 
6796         pmlmeext->cur_channel = set_ch_parm->ch;
6797         pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6798         pmlmeext->cur_bwmode = set_ch_parm->bw;
6799 
6800         set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6801 
6802         return  H2C_SUCCESS;
6803 }
6804 
6805 u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf)
6806 {
6807         struct SetChannelPlan_param *setChannelPlan_param;
6808         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6809 
6810         if (!pbuf)
6811                 return H2C_PARAMETERS_ERROR;
6812 
6813         setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6814 
6815         pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6816         init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6817 
6818         if ((padapter->rtw_wdev != NULL) && (padapter->rtw_wdev->wiphy)) {
6819                 struct regulatory_request request;
6820                 request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
6821                 rtw_reg_notifier(padapter->rtw_wdev->wiphy, &request);
6822         }
6823 
6824         return  H2C_SUCCESS;
6825 }
6826 
6827 u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf)
6828 {
6829         struct LedBlink_param *ledBlink_param;
6830 
6831         if (!pbuf)
6832                 return H2C_PARAMETERS_ERROR;
6833 
6834         ledBlink_param = (struct LedBlink_param *)pbuf;
6835         return  H2C_SUCCESS;
6836 }
6837 
6838 u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf)
6839 {
6840         return  H2C_REJECTED;
6841 }
6842 
6843 /*  TDLS_ESTABLISHED    : write RCR DATA BIT */
6844 /*  TDLS_CS_OFF         : go back to the channel linked with AP, terminating channel switch procedure */
6845 /*  TDLS_INIT_CH_SEN    : init channel sensing, receive all data and mgnt frame */
6846 /*  TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
6847 /*  TDLS_OFF_CH         : first time set channel to off channel */
6848 /*  TDLS_BASE_CH                : go back tp the channel linked with AP when set base channel as target channel */
6849 /*  TDLS_P_OFF_CH       : periodically go to off channel */
6850 /*  TDLS_P_BASE_CH      : periodically go back to base channel */
6851 /*  TDLS_RS_RCR         : restore RCR */
6852 /*  TDLS_TEAR_STA       : free tdls sta */
6853 u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf)
6854 {
6855         return H2C_REJECTED;
6856 }
6857 
6858 u8 run_in_thread_hdl(struct adapter *padapter, u8 *pbuf)
6859 {
6860         struct RunInThread_param *p;
6861 
6862 
6863         if (NULL == pbuf)
6864                 return H2C_PARAMETERS_ERROR;
6865         p = (struct RunInThread_param *)pbuf;
6866 
6867         if (p->func)
6868                 p->func(p->context);
6869 
6870         return H2C_SUCCESS;
6871 }

/* [<][>][^][v][top][bottom][index][help] */