net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / core / rtw_mlme_ext.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *                                        
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_MLME_EXT_C_
21
22 #include <drv_types.h>
23 #ifdef CONFIG_IOCTL_CFG80211
24 #include <rtw_wifi_regd.h>
25 #endif //CONFIG_IOCTL_CFG80211
26 #include <hal_data.h>
27
28
29 struct mlme_handler mlme_sta_tbl[]={
30         {WIFI_ASSOCREQ,         "OnAssocReq",   &OnAssocReq},
31         {WIFI_ASSOCRSP,         "OnAssocRsp",   &OnAssocRsp},
32         {WIFI_REASSOCREQ,       "OnReAssocReq", &OnAssocReq},
33         {WIFI_REASSOCRSP,       "OnReAssocRsp", &OnAssocRsp},
34         {WIFI_PROBEREQ,         "OnProbeReq",   &OnProbeReq},
35         {WIFI_PROBERSP,         "OnProbeRsp",           &OnProbeRsp},
36
37         /*----------------------------------------------------------
38                                         below 2 are reserved
39         -----------------------------------------------------------*/
40         {0,                                     "DoReserved",           &DoReserved},
41         {0,                                     "DoReserved",           &DoReserved},
42         {WIFI_BEACON,           "OnBeacon",             &OnBeacon},
43         {WIFI_ATIM,                     "OnATIM",               &OnAtim},
44         {WIFI_DISASSOC,         "OnDisassoc",           &OnDisassoc},
45         {WIFI_AUTH,                     "OnAuth",               &OnAuthClient},
46         {WIFI_DEAUTH,           "OnDeAuth",             &OnDeAuth},
47         {WIFI_ACTION,           "OnAction",             &OnAction},
48         {WIFI_ACTION_NOACK,"OnActionNoAck",     &OnAction},
49 };
50
51 #ifdef _CONFIG_NATIVEAP_MLME_
52 struct mlme_handler mlme_ap_tbl[]={
53         {WIFI_ASSOCREQ,         "OnAssocReq",   &OnAssocReq},
54         {WIFI_ASSOCRSP,         "OnAssocRsp",   &OnAssocRsp},
55         {WIFI_REASSOCREQ,       "OnReAssocReq", &OnAssocReq},
56         {WIFI_REASSOCRSP,       "OnReAssocRsp", &OnAssocRsp},
57         {WIFI_PROBEREQ,         "OnProbeReq",   &OnProbeReq},
58         {WIFI_PROBERSP,         "OnProbeRsp",           &OnProbeRsp},
59
60         /*----------------------------------------------------------
61                                         below 2 are reserved
62         -----------------------------------------------------------*/
63         {0,                                     "DoReserved",           &DoReserved},
64         {0,                                     "DoReserved",           &DoReserved},
65         {WIFI_BEACON,           "OnBeacon",             &OnBeacon},
66         {WIFI_ATIM,                     "OnATIM",               &OnAtim},
67         {WIFI_DISASSOC,         "OnDisassoc",           &OnDisassoc},
68         {WIFI_AUTH,                     "OnAuth",               &OnAuth},
69         {WIFI_DEAUTH,           "OnDeAuth",             &OnDeAuth},
70         {WIFI_ACTION,           "OnAction",             &OnAction},
71         {WIFI_ACTION_NOACK,"OnActionNoAck",     &OnAction},
72 };
73 #endif
74
75 struct action_handler OnAction_tbl[]={
76         {RTW_WLAN_CATEGORY_SPECTRUM_MGMT,        "ACTION_SPECTRUM_MGMT", on_action_spct},
77         {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
78         {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
79         {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
80         {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
81         {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
82         {RTW_WLAN_CATEGORY_FT, "ACTION_FT",     &DoReserved},
83         {RTW_WLAN_CATEGORY_HT,  "ACTION_HT",    &OnAction_ht},
84 #ifdef CONFIG_IEEE80211W
85         {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
86 #else
87         {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
88 #endif //CONFIG_IEEE80211W
89         //add for CONFIG_IEEE80211W
90         {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
91         {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
92         {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
93         {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
94         {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},   
95 };
96
97
98 u8      null_addr[ETH_ALEN]= {0,0,0,0,0,0};
99
100 /**************************************************
101 OUI definitions for the vendor specific IE
102 ***************************************************/
103 unsigned char   RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
104 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
105 unsigned char   WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
106 unsigned char   P2P_OUI[] = {0x50,0x6F,0x9A,0x09};
107 unsigned char   WFD_OUI[] = {0x50,0x6F,0x9A,0x0A};
108
109 unsigned char   WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
110 unsigned char   WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
111
112 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
113 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
114
115 extern unsigned char REALTEK_96B_IE[];
116
117 #ifdef LEGACY_CHANNEL_PLAN_REF
118 /********************************************************
119 ChannelPlan definitions
120 *********************************************************/
121 static RT_CHANNEL_PLAN legacy_channel_plan[] = {
122         /* 0x00, RTW_CHPLAN_FCC */                                              {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 32},
123         /* 0x01, RTW_CHPLAN_IC */                                               {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 31},
124         /* 0x02, RTW_CHPLAN_ETSI */                                             {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32},
125         /* 0x03, RTW_CHPLAN_SPAIN */                                            {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
126         /* 0x04, RTW_CHPLAN_FRANCE */                                   {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
127         /* 0x05, RTW_CHPLAN_MKK */                                              {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
128         /* 0x06, RTW_CHPLAN_MKK1 */                                             {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
129         /* 0x07, RTW_CHPLAN_ISRAEL */                                   {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},
130         /* 0x08, RTW_CHPLAN_TELEC */                                            {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},
131         /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */                    {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
132         /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */                    {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
133         /* 0x0B, RTW_CHPLAN_TAIWAN */                                   {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 26},
134         /* 0x0C, RTW_CHPLAN_CHINA */                                    {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 149, 153, 157, 161, 165}, 18},
135         /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */   {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24},
136         /* 0x0E, RTW_CHPLAN_KOREA */                                    {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 31},
137         /* 0x0F, RTW_CHPLAN_TURKEY */                                   {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19},
138         /* 0x10, RTW_CHPLAN_JAPAN */                                            {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32},
139         /* 0x11, RTW_CHPLAN_FCC_NO_DFS */                               {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, 157, 161, 165}, 20},
140         /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */                             {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48}, 17},
141         /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */                    {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 37},
142         /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */                    {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 149, 153, 157, 161, 165}, 19},
143 };
144 #endif
145
146 static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[] = {
147         /* 0, RTW_RD_2G_NULL */         {{}, 0},
148         /* 1, RTW_RD_2G_WORLD */        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
149         /* 2, RTW_RD_2G_ETSI1 */                {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
150         /* 3, RTW_RD_2G_FCC1 */         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
151         /* 4, RTW_RD_2G_MKK1 */         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
152         /* 5, RTW_RD_2G_ETSI2 */                {{10, 11, 12, 13}, 4},
153         /* 6, RTW_RD_2G_GLOBAL */       {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
154         /* 7, RTW_RD_2G_MKK2 */         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
155         /* 8, RTW_RD_2G_FCC2 */         {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
156 };
157
158 static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[] = {
159         /* 0, RTW_RD_5G_NULL */         {{}, 0},
160         /* 1, RTW_RD_5G_ETSI1 */                {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},
161         /* 2, RTW_RD_5G_ETSI2 */                {{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},
162         /* 3, RTW_RD_5G_ETSI3 */                {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
163         /* 4, RTW_RD_5G_FCC1 */         {{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},
164         /* 5, RTW_RD_5G_FCC2 */         {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
165         /* 6, RTW_RD_5G_FCC3 */         {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
166         /* 7, RTW_RD_5G_FCC4 */         {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
167         /* 8, RTW_RD_5G_FCC5 */         {{149, 153, 157, 161, 165}, 5},
168         /* 9, RTW_RD_5G_FCC6 */         {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
169         /* 10, RTW_RD_5G_FCC7 */        {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
170         /* 11, RTW_RD_5G_KCC1 */        {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161}, 19},
171         /* 12, RTW_RD_5G_MKK1 */        {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},
172         /* 13, RTW_RD_5G_MKK2 */        {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
173         /* 14, RTW_RD_5G_MKK3 */        {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
174         /* 15, RTW_RD_5G_NCC1 */        {{56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 16},
175         /* 16, RTW_RD_5G_NCC2 */        {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
176         /* 17, RTW_RD_5G_NCC3 */        {{149, 153, 157, 161, 165}, 5},
177         /* 18, RTW_RD_5G_ETSI4 */       {{36, 40, 44, 48}, 4},
178         /* 19, RTW_RD_5G_ETSI5 */       {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
179         /* 20, RTW_RD_5G_FCC8 */        {{149, 153, 157, 161}, 4},
180         /* 21, RTW_RD_5G_ETSI6 */       {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
181         /* 22, RTW_RD_5G_ETSI7 */       {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
182         /* 23, RTW_RD_5G_ETSI8 */       {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
183         /* 24, RTW_RD_5G_ETSI9 */       {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
184         /* 25, RTW_RD_5G_ETSI10 */      {{149, 153, 157, 161, 165}, 5},
185         /* 26, RTW_RD_5G_ETSI11 */      {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165}, 16},
186         /* 27, RTW_RD_5G_NCC4 */        {{52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17},
187         /* 28, RTW_RD_5G_ETSI12 */      {{149, 153, 157, 161}, 4},
188         /* 29, RTW_RD_5G_FCC9 */        {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
189         /* 30, RTW_RD_5G_ETSI13 */      {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140}, 16},
190         /* 31, RTW_RD_5G_FCC10 */       {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161}, 20},
191         /* 32, RTW_RD_5G_MKK4 */        {{36, 40, 44, 48}, 4},
192         /* 33, RTW_RD_5G_ETSI14 */      {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140}, 11},
193
194         /* === Below are driver defined for legacy channel plan compatible, NO static index assigned ==== */
195         /* RTW_RD_5G_OLD_FCC1 */        {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20},
196         /* RTW_RD_5G_OLD_NCC1 */        {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15},
197         /* RTW_RD_5G_OLD_KCC1 */        {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20},
198 };
199
200 static RT_CHANNEL_PLAN_MAP      RTW_ChannelPlanMap[] = {
201         /* ===== 0x00 ~ 0x1F, legacy channel plan ===== */
202         {RTW_RD_2G_FCC1,        RTW_RD_5G_KCC1,         TXPWR_LMT_FCC},         /* 0x00, RTW_CHPLAN_FCC */
203         {RTW_RD_2G_FCC1,        RTW_RD_5G_OLD_FCC1,     TXPWR_LMT_FCC},         /* 0x01, RTW_CHPLAN_IC */
204         {RTW_RD_2G_ETSI1,       RTW_RD_5G_ETSI1,        TXPWR_LMT_ETSI},        /* 0x02, RTW_CHPLAN_ETSI */
205         {RTW_RD_2G_ETSI1,       RTW_RD_5G_NULL,         TXPWR_LMT_ETSI},        /* 0x03, RTW_CHPLAN_SPAIN */
206         {RTW_RD_2G_ETSI1,       RTW_RD_5G_NULL,         TXPWR_LMT_ETSI},        /* 0x04, RTW_CHPLAN_FRANCE */
207         {RTW_RD_2G_MKK1,        RTW_RD_5G_NULL,         TXPWR_LMT_MKK},         /* 0x05, RTW_CHPLAN_MKK */
208         {RTW_RD_2G_MKK1,        RTW_RD_5G_NULL,         TXPWR_LMT_MKK},         /* 0x06, RTW_CHPLAN_MKK1 */
209         {RTW_RD_2G_ETSI1,       RTW_RD_5G_FCC6,         TXPWR_LMT_ETSI},        /* 0x07, RTW_CHPLAN_ISRAEL */
210         {RTW_RD_2G_MKK1,        RTW_RD_5G_FCC6,         TXPWR_LMT_MKK},         /* 0x08, RTW_CHPLAN_TELEC */
211         {RTW_RD_2G_MKK1,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */
212         {RTW_RD_2G_WORLD,       RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */
213         {RTW_RD_2G_FCC1,        RTW_RD_5G_OLD_NCC1,     TXPWR_LMT_FCC},         /* 0x0B, RTW_CHPLAN_TAIWAN */
214         {RTW_RD_2G_ETSI1,       RTW_RD_5G_FCC5,         TXPWR_LMT_ETSI},        /* 0x0C, RTW_CHPLAN_CHINA */
215         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC3,         TXPWR_LMT_WW},          /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ /* ETSI:Singapore, India. FCC:Mexico => WW */
216         {RTW_RD_2G_FCC1,        RTW_RD_5G_OLD_KCC1,     TXPWR_LMT_ETSI},        /* 0x0E, RTW_CHPLAN_KOREA */
217         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC6,         TXPWR_LMT_ETSI},        /* 0x0F, RTW_CHPLAN_TURKEY */
218         {RTW_RD_2G_ETSI1,       RTW_RD_5G_ETSI1,        TXPWR_LMT_MKK},         /* 0x10, RTW_CHPLAN_JAPAN */
219         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC2,         TXPWR_LMT_FCC},         /* 0x11, RTW_CHPLAN_FCC_NO_DFS */
220         {RTW_RD_2G_ETSI1,       RTW_RD_5G_FCC7,         TXPWR_LMT_MKK},         /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */
221         {RTW_RD_2G_WORLD,       RTW_RD_5G_FCC1,         TXPWR_LMT_WW},          /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */
222         {RTW_RD_2G_FCC1,        RTW_RD_5G_NCC2,         TXPWR_LMT_FCC},         /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */
223         {RTW_RD_2G_WORLD,       RTW_RD_5G_FCC7,         TXPWR_LMT_ETSI},        /* 0x15, RTW_CHPLAN_ETSI_NO_DFS */
224         {RTW_RD_2G_WORLD,       RTW_RD_5G_NCC1,         TXPWR_LMT_ETSI},        /* 0x16, RTW_CHPLAN_KOREA_NO_DFS */
225         {RTW_RD_2G_MKK1,        RTW_RD_5G_FCC7,         TXPWR_LMT_MKK},         /* 0x17, RTW_CHPLAN_JAPAN_NO_DFS */
226         {RTW_RD_2G_NULL,        RTW_RD_5G_FCC5,         TXPWR_LMT_ETSI},        /* 0x18, RTW_CHPLAN_PAKISTAN_NO_DFS */
227         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC5,         TXPWR_LMT_FCC},         /* 0x19, RTW_CHPLAN_TAIWAN2_NO_DFS */
228         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x1A, */
229         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x1B, */
230         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x1C, */
231         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x1D, */
232         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x1E, */
233         {RTW_RD_2G_NULL,        RTW_RD_5G_FCC1,         TXPWR_LMT_WW},          /* 0x1F, RTW_CHPLAN_WORLD_WIDE_ONLY_5G */
234
235         /* ===== 0x20 ~ 0x7F, new channel plan ===== */
236         {RTW_RD_2G_WORLD,       RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x20, RTW_CHPLAN_WORLD_NULL */
237         {RTW_RD_2G_ETSI1,       RTW_RD_5G_NULL,         TXPWR_LMT_ETSI},        /* 0x21, RTW_CHPLAN_ETSI1_NULL */
238         {RTW_RD_2G_FCC1,        RTW_RD_5G_NULL,         TXPWR_LMT_FCC},         /* 0x22, RTW_CHPLAN_FCC1_NULL */
239         {RTW_RD_2G_MKK1,        RTW_RD_5G_NULL,         TXPWR_LMT_MKK},         /* 0x23, RTW_CHPLAN_MKK1_NULL */
240         {RTW_RD_2G_ETSI2,       RTW_RD_5G_NULL,         TXPWR_LMT_ETSI},        /* 0x24, RTW_CHPLAN_ETSI2_NULL */
241         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC1,         TXPWR_LMT_FCC},         /* 0x25, RTW_CHPLAN_FCC1_FCC1 */
242         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI1,        TXPWR_LMT_ETSI},        /* 0x26, RTW_CHPLAN_WORLD_ETSI1 */
243         {RTW_RD_2G_MKK1,        RTW_RD_5G_MKK1,         TXPWR_LMT_MKK},         /* 0x27, RTW_CHPLAN_MKK1_MKK1 */
244         {RTW_RD_2G_WORLD,       RTW_RD_5G_KCC1,         TXPWR_LMT_ETSI},        /* 0x28, RTW_CHPLAN_WORLD_KCC1 */
245         {RTW_RD_2G_WORLD,       RTW_RD_5G_FCC2,         TXPWR_LMT_FCC},         /* 0x29, RTW_CHPLAN_WORLD_FCC2 */
246         {RTW_RD_2G_FCC2,        RTW_RD_5G_NULL,         TXPWR_LMT_FCC},         /* 0x2A, RTW_CHPLAN_FCC2_NULL */
247         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x2B, */
248         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x2C, */
249         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x2D, */
250         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x2E, */
251         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x2F, */
252         {RTW_RD_2G_WORLD,       RTW_RD_5G_FCC3,         TXPWR_LMT_FCC},         /* 0x30, RTW_CHPLAN_WORLD_FCC3 */
253         {RTW_RD_2G_WORLD,       RTW_RD_5G_FCC4,         TXPWR_LMT_FCC},         /* 0x31, RTW_CHPLAN_WORLD_FCC4 */
254         {RTW_RD_2G_WORLD,       RTW_RD_5G_FCC5,         TXPWR_LMT_FCC},         /* 0x32, RTW_CHPLAN_WORLD_FCC5 */
255         {RTW_RD_2G_WORLD,       RTW_RD_5G_FCC6,         TXPWR_LMT_FCC},         /* 0x33, RTW_CHPLAN_WORLD_FCC6 */
256         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC7,         TXPWR_LMT_FCC},         /* 0x34, RTW_CHPLAN_FCC1_FCC7 */
257         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI2,        TXPWR_LMT_ETSI},        /* 0x35, RTW_CHPLAN_WORLD_ETSI2 */
258         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI3,        TXPWR_LMT_ETSI},        /* 0x36, RTW_CHPLAN_WORLD_ETSI3 */
259         {RTW_RD_2G_MKK1,        RTW_RD_5G_MKK2,         TXPWR_LMT_MKK},         /* 0x37, RTW_CHPLAN_MKK1_MKK2 */
260         {RTW_RD_2G_MKK1,        RTW_RD_5G_MKK3,         TXPWR_LMT_MKK},         /* 0x38, RTW_CHPLAN_MKK1_MKK3 */
261         {RTW_RD_2G_FCC1,        RTW_RD_5G_NCC1,         TXPWR_LMT_FCC},         /* 0x39, RTW_CHPLAN_FCC1_NCC1 */
262         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x3A, */
263         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x3B, */
264         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x3C, */
265         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x3D, */
266         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x3E, */
267         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x3F, */
268         {RTW_RD_2G_FCC1,        RTW_RD_5G_NCC2,         TXPWR_LMT_FCC},         /* 0x40, RTW_CHPLAN_FCC1_NCC2 */
269         {RTW_RD_2G_GLOBAL,      RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x41, RTW_CHPLAN_GLOBAL_NULL */
270         {RTW_RD_2G_ETSI1,       RTW_RD_5G_ETSI4,        TXPWR_LMT_ETSI},        /* 0x42, RTW_CHPLAN_ETSI1_ETSI4 */
271         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC2,         TXPWR_LMT_FCC},         /* 0x43, RTW_CHPLAN_FCC1_FCC2 */
272         {RTW_RD_2G_FCC1,        RTW_RD_5G_NCC3,         TXPWR_LMT_FCC},         /* 0x44, RTW_CHPLAN_FCC1_NCC3 */
273         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI5,        TXPWR_LMT_ETSI},        /* 0x45, RTW_CHPLAN_WORLD_ETSI5 */
274         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC8,         TXPWR_LMT_FCC},         /* 0x46, RTW_CHPLAN_FCC1_FCC8 */
275         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI6,        TXPWR_LMT_ETSI},        /* 0x47, RTW_CHPLAN_WORLD_ETSI6 */
276         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI7,        TXPWR_LMT_ETSI},        /* 0x48, RTW_CHPLAN_WORLD_ETSI7 */
277         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI8,        TXPWR_LMT_ETSI},        /* 0x49, RTW_CHPLAN_WORLD_ETSI8 */
278         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x4A, */
279         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x4B, */
280         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x4C, */
281         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x4D, */
282         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x4E, */
283         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x4F, */
284         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI9,        TXPWR_LMT_ETSI},        /* 0x50, RTW_CHPLAN_WORLD_ETSI9 */
285         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI10,       TXPWR_LMT_ETSI},        /* 0x51, RTW_CHPLAN_WORLD_ETSI10 */
286         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI11,       TXPWR_LMT_ETSI},        /* 0x52, RTW_CHPLAN_WORLD_ETSI11 */
287         {RTW_RD_2G_FCC1,        RTW_RD_5G_NCC4,         TXPWR_LMT_FCC},         /* 0x53, RTW_CHPLAN_FCC1_NCC4 */
288         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI12,       TXPWR_LMT_ETSI},        /* 0x54, RTW_CHPLAN_WORLD_ETSI12 */
289         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC9,         TXPWR_LMT_FCC},         /* 0x55, RTW_CHPLAN_FCC1_FCC9 */
290         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI13,       TXPWR_LMT_ETSI},        /* 0x56, RTW_CHPLAN_WORLD_ETSI13 */
291         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC10,        TXPWR_LMT_FCC},         /* 0x57, RTW_CHPLAN_FCC1_FCC10 */
292         {RTW_RD_2G_MKK2,        RTW_RD_5G_MKK4,         TXPWR_LMT_MKK},         /* 0x58, RTW_CHPLAN_MKK2_MKK4 */
293         {RTW_RD_2G_WORLD,       RTW_RD_5G_ETSI14,       TXPWR_LMT_ETSI},        /* 0x59, RTW_CHPLAN_WORLD_ETSI14 */
294         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x5A, */
295         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x5B, */
296         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x5C, */
297         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x5D, */
298         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x5E, */
299         {RTW_RD_2G_NULL,        RTW_RD_5G_NULL,         TXPWR_LMT_WW},          /* 0x5F, */
300         {RTW_RD_2G_FCC1,        RTW_RD_5G_FCC5,         TXPWR_LMT_FCC},         /* 0x60, RTW_CHPLAN_FCC1_FCC5 */
301 };
302
303 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {
304         RTW_RD_2G_WORLD,        RTW_RD_5G_FCC1,         TXPWR_LMT_FCC           /* 0x7F, Realtek Define */
305 };
306
307 bool rtw_chplan_is_empty(u8 id)
308 {
309         RT_CHANNEL_PLAN_MAP *chplan_map;
310
311         if (id == RTW_CHPLAN_REALTEK_DEFINE)
312                 chplan_map = &RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE;
313         else
314                 chplan_map = &RTW_ChannelPlanMap[id];
315
316         if (chplan_map->Index2G == RTW_RD_2G_NULL
317                 && chplan_map->Index5G == RTW_RD_5G_NULL)
318                 return _TRUE;
319
320         return _FALSE;
321 }
322
323 #ifdef CONFIG_DFS_MASTER
324 void rtw_rfctl_reset_cac(struct rf_ctl_t *rfctl)
325 {
326         if (rtw_is_long_cac_ch(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset))
327                 rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_CE_MS);
328         else
329                 rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_MS);
330 }
331
332 /*
333 * check if channel coverage includes new range and the new range is in DFS range
334 * called after radar_detect_ch,bw,offset is updated
335 */
336 bool rtw_is_cac_reset_needed(_adapter *adapter)
337 {
338         struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
339         bool needed = _FALSE;
340         u32 pre_hi, pre_lo, hi, lo;
341
342         if (0)
343                 DBG_871X("pre_radar_detect_ch:%d, pre_radar_detect_by_sta_link:%d\n"
344                         , rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_by_sta_link);
345
346         if (rfctl->pre_radar_detect_by_sta_link == _TRUE)
347                 goto exit;
348
349         if (rfctl->pre_radar_detect_ch == 0) {
350                 needed = _TRUE;
351                 goto exit;
352         }
353
354         if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &hi, &lo) == _FALSE)
355                 rtw_warn_on(1);
356         if (rtw_chbw_to_freq_range(rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_bw, rfctl->pre_radar_detect_offset, &pre_hi, &pre_lo) == _FALSE)
357                 rtw_warn_on(1);
358
359         if (!rtw_is_range_a_in_b(hi, lo, pre_hi, pre_lo)) {
360                 if (rtw_is_range_a_in_b(pre_hi, pre_lo, hi, lo)) {
361                         /* currrent is supper set of previous */
362                         if (rtw_is_dfs_range(hi, lo))
363                                 needed = _TRUE;
364                 } else if (rtw_is_range_overlap(hi, lo, pre_hi, pre_lo)) {
365                         /* currrent is not supper set of previous, but has overlap */
366                         u32 new_hi, new_lo;
367
368                         if (lo < pre_lo) {
369                                 new_hi = pre_lo;
370                                 new_lo = lo;
371                                 if (hi <= pre_lo || hi >= pre_hi) {
372                                         DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
373                                                 , hi, lo, pre_hi, pre_lo);
374                                         rtw_warn_on(1);
375                                         goto exit;
376                                 }
377                         } else if (hi > pre_hi) {
378                                 new_hi = hi;
379                                 new_lo = pre_hi;
380                                 if (lo >= pre_hi && lo <= pre_lo) {
381                                         DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
382                                                 , hi, lo, pre_hi, pre_lo);
383                                         rtw_warn_on(1);
384                                         goto exit;
385                                 }
386                         } else {
387                                 DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
388                                         , hi, lo, pre_hi, pre_lo);
389                                 rtw_warn_on(1);
390                                 goto exit;
391                         }
392
393                         if (rtw_is_dfs_range(new_hi, new_lo))
394                                 needed = _TRUE;
395                         
396                 } else {
397                         /* no overlap */
398                         if (rtw_is_dfs_range(hi, lo))
399                                 needed = _TRUE;
400                 }
401         }
402
403 exit:
404         return needed;
405 }
406
407 bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
408 {
409         bool ret = _FALSE;
410         u32 hi = 0, lo = 0;
411         u32 r_hi = 0, r_lo = 0;
412         int i;
413
414         if (rfctl->radar_detect_ch == 0)
415                 goto exit;
416
417         if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
418                 rtw_warn_on(1);
419                 goto exit;
420         }
421
422         if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
423                         , rfctl->radar_detect_bw, rfctl->radar_detect_offset
424                         , &r_hi, &r_lo) == _FALSE) {
425                 rtw_warn_on(1);
426                 goto exit;
427         }
428
429         if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
430                 ret = _TRUE;
431
432 exit:
433         return ret;
434 }
435
436 bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
437 {
438         return _rtw_rfctl_overlap_radar_detect_ch(rfctl
439                                 , rfctl_to_dvobj(rfctl)->oper_channel
440                                 , rfctl_to_dvobj(rfctl)->oper_bwmode
441                                 , rfctl_to_dvobj(rfctl)->oper_ch_offset);
442 }
443
444 bool rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t *rfctl)
445 {
446         return (rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_UNDER_CAC(rfctl));
447 }
448
449 bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
450 {
451         bool ret = _FALSE;
452         u32 hi = 0, lo = 0;
453         int i;
454
455         if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
456                 goto exit;
457
458         for (i = 0; ch_set[i].ChannelNum != 0; i++) {
459                 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
460                         rtw_warn_on(1);
461                         continue;
462                 }
463
464                 if (!CH_IS_NON_OCP(&ch_set[i]))
465                         continue;
466
467                 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
468                         && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
469                 ) {
470                         ret = _TRUE;
471                         break;
472                 }
473         }
474
475 exit:
476         return ret;
477 }
478
479 /**
480  * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
481  * @ch_set: the given channel set
482  * @ch: channel number on which radar is detected
483  * @bw: bandwidth on which radar is detected
484  * @offset: bandwidth offset on which radar is detected
485  * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
486  */
487 static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
488 {
489         u32 hi = 0, lo = 0;
490         int i;
491
492         if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
493                 goto exit;
494
495         for (i = 0; ch_set[i].ChannelNum != 0; i++) {
496                 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
497                         rtw_warn_on(1);
498                         continue;
499                 }
500
501                 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
502                         && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
503                 ) {
504                         if (ms >= 0)
505                                 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
506                         else
507                                 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
508                 }
509         }       
510
511 exit:
512         return;
513 }
514
515 inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
516 {
517         _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
518 }
519
520 inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
521 {
522         _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
523 }
524 #endif /* CONFIG_DFS_MASTER */
525
526 bool rtw_choose_available_chbw(_adapter *adapter, u8 req_bw, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset, u8 d_flags)
527 {
528         struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
529         int i;
530
531         if (!dec_ch || !dec_bw || !dec_offset) {
532                 rtw_warn_on(1);
533                 return _FAIL;
534         }
535
536         for (i = 0; i < mlmeext->max_chan_nums; i++) {
537
538                 *dec_ch = mlmeext->channel_set[i].ChannelNum;
539                 *dec_bw = req_bw;
540                 if (*dec_bw == CHANNEL_WIDTH_20)
541                         *dec_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
542                 else
543                         *dec_offset = rtw_get_offset_by_ch(*dec_ch);
544
545                 if ((d_flags & RTW_CHF_2G) && *dec_ch <= 14)
546                         continue;
547
548                 if ((d_flags & RTW_CHF_5G)  && *dec_ch > 14)
549                         continue;
550
551                 rtw_adjust_chbw(adapter, *dec_ch, dec_bw, dec_offset);
552
553                 if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
554                         continue;
555
556                 if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
557                         continue;
558
559                 if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
560                         continue;
561
562                 if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
563                         continue;
564
565                 if (!rtw_chset_is_ch_non_ocp(mlmeext->channel_set, *dec_ch, *dec_bw, *dec_offset))
566                         break;
567         }
568
569         return (i < mlmeext->max_chan_nums)?_TRUE:_FALSE;
570 }
571
572 void dump_country_chplan(void *sel, const struct country_chplan *ent)
573 {
574         DBG_871X_SEL(sel, "\"%c%c\", 0x%02X%s\n"
575                 , ent->alpha2[0], ent->alpha2[1], ent->chplan
576                 , COUNTRY_CHPLAN_EN_11AC(ent) ? " ac" : ""
577         );
578 }
579
580 void dump_country_chplan_map(void *sel)
581 {
582         const struct country_chplan *ent;
583         u8 code[2];
584
585 #if RTW_DEF_MODULE_REGULATORY_CERT
586         DBG_871X_SEL(sel, "RTW_DEF_MODULE_REGULATORY_CERT:0x%x\n", RTW_DEF_MODULE_REGULATORY_CERT);
587 #endif
588 #ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP
589         DBG_871X_SEL(sel, "CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP\n");
590 #endif
591
592         for (code[0] = 'A'; code[0] <= 'Z'; code[0]++) {
593                 for (code[1] = 'A'; code[1] <= 'Z'; code[1]++) {
594                         ent = rtw_get_chplan_from_country(code);
595                         if (!ent)
596                                 continue;
597
598                         dump_country_chplan(sel, ent);
599                 }
600         }
601 }
602
603 void dump_chplan_id_list(void *sel)
604 {
605         int i;
606
607         for (i = 0; i < RTW_CHPLAN_MAX; i++) {
608                 if (!rtw_is_channel_plan_valid(i))
609                         continue;
610
611                 DBG_871X_SEL(sel, "0x%02X ", i);
612         }
613
614         DBG_871X_SEL_NL(sel, "0x7F\n");
615 }
616
617 void dump_chplan_test(void *sel)
618 {
619         int i, j;
620
621         /* check invalid channel */
622         for (i = 0; i < RTW_RD_2G_MAX; i++) {
623                 for (j = 0; j < RTW_ChannelPlan2G[i].Len; j++) {
624                         if (rtw_ch2freq(RTW_ChannelPlan2G[i].Channel[j]) == 0)
625                                 DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan2G[i].Channel[j], i, j);
626                 }
627         }
628
629         for (i = 0; i < RTW_RD_5G_MAX; i++) {
630                 for (j = 0; j < RTW_ChannelPlan5G[i].Len; j++) {
631                         if (rtw_ch2freq(RTW_ChannelPlan5G[i].Channel[j]) == 0)
632                                 DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan5G[i].Channel[j], i, j);
633                 }
634         }
635 }
636
637 void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set)
638 {
639         u8      i;
640
641         for (i = 0; ch_set[i].ChannelNum != 0; i++) {
642                 DBG_871X_SEL_NL(sel, "ch:%3u, freq:%u, scan_type:%d"
643                         , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType);
644         
645                 #ifdef CONFIG_FIND_BEST_CHANNEL
646                 DBG_871X_SEL(sel, ", rx_count:%u", ch_set[i].rx_count);
647                 #endif
648                 
649                 #ifdef CONFIG_DFS_MASTER
650                 if (rtw_is_dfs_ch(ch_set[i].ChannelNum, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
651                         if (CH_IS_NON_OCP(&ch_set[i]))
652                                 DBG_871X_SEL(sel, ", non_ocp:%d"
653                                         , rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()));
654                         else
655                                 DBG_871X_SEL(sel, ", non_ocp:N/A");
656                 }
657                 #endif
658
659                 DBG_871X_SEL(sel, "\n");
660         }
661
662         DBG_871X_SEL_NL(sel, "total ch number:%d\n", i);
663 }
664
665 void dump_cur_chset(void *sel, _adapter *adapter)
666 {
667         struct mlme_priv *mlme = &adapter->mlmepriv;
668         struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
669         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
670
671         if (mlme->country_ent)
672                 dump_country_chplan(sel, mlme->country_ent);
673         else
674                 DBG_871X_SEL_NL(sel, "chplan:0x%02X\n", mlme->ChannelPlan);
675
676         DBG_871X_SEL_NL(sel, "2G_PLS:%u, 5G_PLS:%u\n"
677                 , hal_data->Regulation2_4G, hal_data->Regulation5G);
678         dump_chset(sel, mlmeext->channel_set);
679 }
680
681 /*
682  * Search the @param ch in given @param ch_set
683  * @ch_set: the given channel set
684  * @ch: the given channel number
685  * 
686  * return the index of channel_num in channel_set, -1 if not found
687  */
688 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
689 {
690         int i;
691         for(i=0;ch_set[i].ChannelNum!=0;i++){
692                 if(ch == ch_set[i].ChannelNum)
693                         break;
694         }
695         
696         if(i >= ch_set[i].ChannelNum)
697                 return -1;
698         return i;
699 }
700
701 /*
702  * Check the @param ch is fit with setband setting of @param adapter
703  * @adapter: the given adapter
704  * @ch: the given channel number
705  * 
706  * return _TRUE when check valid, _FALSE not valid
707  */
708 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
709 {
710         if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
711                 || (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
712                 || (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
713         ) {
714                 return _TRUE;
715         }
716         return _FALSE;
717 }
718
719 /****************************************************************************
720
721 Following are the initialization functions for WiFi MLME
722
723 *****************************************************************************/
724
725 int init_hw_mlme_ext(_adapter *padapter)
726 {
727         struct  mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
728
729         //set_opmode_cmd(padapter, infra_client_with_mlme);//removed
730
731         set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
732
733         return _SUCCESS;
734 }
735
736 void init_mlme_default_rate_set(_adapter* padapter)
737 {
738         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
739
740         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};
741         unsigned char   mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
742         unsigned char   supported_mcs_set[16] = {0xff, 0xff, 0xff, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
743
744         _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
745         _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
746
747         _rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
748 }
749
750 static void init_mlme_ext_priv_value(_adapter* padapter)
751 {
752         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
753         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
754
755         ATOMIC_SET(&pmlmeext->event_seq, 0);
756         pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
757 #ifdef CONFIG_IEEE80211W
758         pmlmeext->sa_query_seq = 0;
759         pmlmeext->mgnt_80211w_IPN=0;
760         pmlmeext->mgnt_80211w_IPN_rx=0;
761 #endif //CONFIG_IEEE80211W
762         pmlmeext->cur_channel = padapter->registrypriv.channel;
763         pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
764         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
765         
766         pmlmeext->retry = 0;
767
768         pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
769
770         init_mlme_default_rate_set(padapter);
771
772         if(pmlmeext->cur_channel > 14)
773                 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
774         else
775                 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
776
777         mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
778         pmlmeext->sitesurvey_res.channel_idx = 0;
779         pmlmeext->sitesurvey_res.bss_cnt = 0;
780         pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
781         pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
782         pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
783         #ifdef CONFIG_SCAN_BACKOP
784         mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
785         mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN|SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
786         pmlmeext->sitesurvey_res.scan_cnt = 0;
787         pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
788         pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
789         #endif
790         #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
791         pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
792         #endif
793         pmlmeext->scan_abort = _FALSE;
794
795         pmlmeinfo->state = WIFI_FW_NULL_STATE;
796         pmlmeinfo->reauth_count = 0;
797         pmlmeinfo->reassoc_count = 0;
798         pmlmeinfo->link_count = 0;
799         pmlmeinfo->auth_seq = 0;
800         pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
801         pmlmeinfo->key_index = 0;
802         pmlmeinfo->iv = 0;
803
804         pmlmeinfo->enc_algo = _NO_PRIVACY_;
805         pmlmeinfo->authModeToggle = 0;
806
807         _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
808
809         pmlmeinfo->slotTime = SHORT_SLOT_TIME;
810         pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
811
812         pmlmeinfo->dialogToken = 0;
813
814         pmlmeext->action_public_rxseq = 0xffff;
815         pmlmeext->action_public_dialog_token = 0xff;
816 }
817
818 static int has_channel(RT_CHANNEL_INFO *channel_set,
819                                            u8 chanset_size,
820                                            u8 chan) {
821         int i;
822
823         for (i = 0; i < chanset_size; i++) {
824                 if (channel_set[i].ChannelNum == chan) {
825                         return 1;
826                 }
827         }
828
829         return 0;
830 }
831
832 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
833                                                           u8 chanset_size,
834                                                           struct p2p_channels *channel_list) {
835         struct registry_priv *regsty = adapter_to_regsty(padapter);
836
837         struct p2p_oper_class_map op_class[] = {
838                 { IEEE80211G,  81,   1,  13,  1, BW20 },
839                 { IEEE80211G,  82,  14,  14,  1, BW20 },
840 #if 0 /* Do not enable HT40 on 2 GHz */
841                 { IEEE80211G,  83,   1,   9,  1, BW40PLUS },
842                 { IEEE80211G,  84,   5,  13,  1, BW40MINUS },
843 #endif
844                 { IEEE80211A, 115,  36,  48,  4, BW20 },
845                 { IEEE80211A, 116,  36,  44,  8, BW40PLUS },
846                 { IEEE80211A, 117,  40,  48,  8, BW40MINUS },
847                 { IEEE80211A, 124, 149, 161,  4, BW20 },
848                 { IEEE80211A, 125, 149, 169,  4, BW20 },
849                 { IEEE80211A, 126, 149, 157,  8, BW40PLUS },
850                 { IEEE80211A, 127, 153, 161,  8, BW40MINUS },
851                 { -1, 0, 0, 0, 0, BW20 }
852         };
853
854         int cla, op;
855
856         cla = 0;
857
858         for (op = 0; op_class[op].op_class; op++) {
859                 u8 ch;
860                 struct p2p_oper_class_map *o = &op_class[op];
861                 struct p2p_reg_class *reg = NULL;
862
863                 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
864                         if (!has_channel(channel_set, chanset_size, ch)) {
865                                 continue;
866                         }
867
868                         if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
869                                 continue;
870
871                         if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) &&
872                                 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
873                                 continue;
874
875                         if (reg == NULL) {
876                                 reg = &channel_list->reg_class[cla];
877                                 cla++;
878                                 reg->reg_class = o->op_class;
879                                 reg->channels = 0;
880                         }
881                         reg->channel[reg->channels] = ch;
882                         reg->channels++;
883                 }
884         }
885         channel_list->reg_classes = cla;
886
887 }
888
889 static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
890 {
891         u8      index,chanset_size = 0;
892         u8      b5GBand = _FALSE, b2_4GBand = _FALSE;
893         u8      Index2G = 0, Index5G=0;
894         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
895
896         if (!rtw_is_channel_plan_valid(ChannelPlan)) {
897                 DBG_871X_LEVEL(_drv_err_, "ChannelPlan ID 0x%02X error !!!!!\n", ChannelPlan);
898                 return chanset_size;
899         }
900
901         _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
902
903         if (IsSupported24G(padapter->registrypriv.wireless_mode))
904                 b2_4GBand = _TRUE;
905
906         if (IsSupported5G(padapter->registrypriv.wireless_mode))
907                 b5GBand = _TRUE;
908
909         if (b2_4GBand) {
910                 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
911                         Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
912                 else
913                         Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
914
915                 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
916                         channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
917
918                         if (RTW_CHPLAN_GLOBAL_DOAMIN == ChannelPlan
919                                 || RTW_CHPLAN_GLOBAL_NULL == ChannelPlan
920                         ) {
921                                 /* Channel 1~11 is active, and 12~14 is passive */
922                                 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
923                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
924                                 else if((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
925                                         channel_set[chanset_size].ScanType  = SCAN_PASSIVE;                     
926                         } else if (RTW_CHPLAN_WORLD_WIDE_13 == ChannelPlan
927                                 || RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan
928                                 || RTW_RD_2G_WORLD == Index2G
929                         ) {
930                                 /* channel 12~13, passive scan */
931                                 if(channel_set[chanset_size].ChannelNum <= 11)
932                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
933                                 else
934                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
935                         } else {
936                                 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
937                         }
938
939                         chanset_size++;
940                 }
941         }
942
943         if (b5GBand) {
944                 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
945                         Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
946                 else
947                         Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
948
949                 for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) {
950 #ifdef CONFIG_DFS
951                         channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
952                         if ( channel_set[chanset_size].ChannelNum <= 48 
953                                 || channel_set[chanset_size].ChannelNum >= 149 )
954                         {
955                                 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
956                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
957                                 else
958                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
959                         }
960                         else
961                         {
962                                 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
963                         }
964                         chanset_size++;
965 #else /* CONFIG_DFS */
966                         if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
967                                 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149
968                         ) {
969                                 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
970                                 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
971                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
972                                 else
973                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
974                                 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
975                                 chanset_size++;
976                         }
977 #endif /* CONFIG_DFS */
978                 }
979         }
980
981         if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) {
982                 hal_data->Regulation2_4G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
983                 hal_data->Regulation5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
984         } else {
985                 hal_data->Regulation2_4G = RTW_ChannelPlanMap[ChannelPlan].regd;
986                 hal_data->Regulation5G = RTW_ChannelPlanMap[ChannelPlan].regd;
987         }
988
989         DBG_871X(FUNC_ADPT_FMT" ChannelPlan ID:0x%02x, ch num:%d\n"
990                 , FUNC_ADPT_ARG(padapter), ChannelPlan, chanset_size);
991
992         return chanset_size;
993 }
994
995 int     init_mlme_ext_priv(_adapter* padapter)
996 {
997         int     res = _SUCCESS;
998         struct registry_priv* pregistrypriv = &padapter->registrypriv;
999         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1000         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1001         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1002
1003         // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
1004         //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
1005
1006         pmlmeext->padapter = padapter;
1007
1008         //fill_fwpriv(padapter, &(pmlmeext->fwpriv));
1009
1010         init_mlme_ext_priv_value(padapter);
1011         pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1012         
1013         init_mlme_ext_timer(padapter);
1014
1015 #ifdef CONFIG_AP_MODE
1016         init_mlme_ap_info(padapter);    
1017 #endif
1018
1019         pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
1020         init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
1021         pmlmeext->last_scan_time = 0;
1022         pmlmeext->mlmeext_init = _TRUE;
1023
1024
1025 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK   
1026         pmlmeext->active_keep_alive_check = _TRUE;
1027 #else
1028         pmlmeext->active_keep_alive_check = _FALSE;
1029 #endif
1030
1031 #ifdef DBG_FIXED_CHAN           
1032         pmlmeext->fixed_chan = 0xFF;    
1033 #endif
1034
1035         return res;
1036
1037 }
1038
1039 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
1040 {
1041         _adapter *padapter = pmlmeext->padapter;
1042
1043         if (!padapter)
1044                 return;
1045
1046         if (rtw_is_drv_stopped(padapter)) {
1047                 _cancel_timer_ex(&pmlmeext->survey_timer);
1048                 _cancel_timer_ex(&pmlmeext->link_timer);
1049                 //_cancel_timer_ex(&pmlmeext->ADDBA_timer);
1050         }
1051 }
1052
1053 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
1054 {       // if the channel is same, return 0. else return channel differential   
1055         uint len;
1056         u8 channel;     
1057         u8 *p;          
1058         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);       
1059         if (p)  
1060         {       
1061                 channel = *(p + 2);             
1062                 if(padapter->mlmeextpriv.cur_channel >= channel)                
1063                 {                       
1064                         return (padapter->mlmeextpriv.cur_channel - channel);           
1065                 }               
1066                 else            
1067                 {                       
1068                         return (channel-padapter->mlmeextpriv.cur_channel);             
1069                 }       
1070         }       
1071         else
1072         {               
1073                 return 0;       
1074         }
1075 }
1076
1077 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1078 {
1079         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1080         u8 *pframe = precv_frame->u.hdr.rx_data; 
1081
1082           if(ptable->func)
1083         {
1084          //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1085                 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1086                         !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) 
1087                 {
1088                         return;
1089                 }
1090                 
1091                 ptable->func(padapter, precv_frame);
1092         }
1093         
1094 }
1095
1096 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1097 {
1098         int index;
1099         struct mlme_handler *ptable;
1100 #ifdef CONFIG_AP_MODE
1101         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1102 #endif //CONFIG_AP_MODE
1103         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1104         u8 *pframe = precv_frame->u.hdr.rx_data;
1105         struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
1106         struct dvobj_priv *psdpriv = padapter->dvobj;
1107         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1108
1109         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1110                  ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
1111                   GetFrameType(pframe), GetFrameSubType(pframe)));
1112
1113 #if 0
1114         {
1115                 u8 *pbuf;
1116                 pbuf = GetAddr1Ptr(pframe);
1117                 DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1118                 pbuf = GetAddr2Ptr(pframe);
1119                 DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1120                 pbuf = GetAddr3Ptr(pframe);
1121                 DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1122         }
1123 #endif
1124
1125         if (GetFrameType(pframe) != WIFI_MGT_TYPE)
1126         {
1127                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
1128                 return;
1129         }
1130
1131         //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1132         if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1133                 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1134         {
1135                 return;
1136         }
1137
1138         ptable = mlme_sta_tbl;
1139
1140         index = GetFrameSubType(pframe) >> 4;
1141
1142 #ifdef CONFIG_TDLS
1143         if((index << 4)==WIFI_ACTION){
1144                 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1145                 if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) {
1146                         DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe)));
1147                         On_TDLS_Dis_Rsp(padapter, precv_frame);
1148                 }
1149         }
1150 #endif //CONFIG_TDLS
1151
1152         if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler)))
1153         {
1154                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
1155                 return;
1156         }
1157         ptable += index;
1158
1159 #if 1
1160         if (psta != NULL)
1161         {
1162                 if (GetRetry(pframe))
1163                 {
1164                         if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
1165                         {
1166                                 /* drop the duplicate management frame */
1167                                 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
1168                                 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1169                                 return;
1170                         }
1171                 }
1172                 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1173         }
1174 #else
1175
1176         if(GetRetry(pframe))
1177         {
1178                 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
1179                 //return;
1180         }
1181 #endif
1182
1183 #ifdef CONFIG_AP_MODE
1184         switch (GetFrameSubType(pframe)) 
1185         {
1186                 case WIFI_AUTH:
1187                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1188                                 ptable->func = &OnAuth;
1189                         else
1190                                 ptable->func = &OnAuthClient;
1191                         //pass through
1192                 case WIFI_ASSOCREQ:
1193                 case WIFI_REASSOCREQ:
1194                         _mgt_dispatcher(padapter, ptable, precv_frame); 
1195 #ifdef CONFIG_HOSTAPD_MLME                              
1196                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1197                                 rtw_hostapd_mlme_rx(padapter, precv_frame);
1198 #endif                  
1199                         break;
1200                 case WIFI_PROBEREQ:
1201                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1202                         {
1203 #ifdef CONFIG_HOSTAPD_MLME              
1204                                 rtw_hostapd_mlme_rx(padapter, precv_frame);             
1205 #else
1206                                 _mgt_dispatcher(padapter, ptable, precv_frame);
1207 #endif
1208                         }
1209                         else
1210                                 _mgt_dispatcher(padapter, ptable, precv_frame);
1211                         break;
1212                 case WIFI_BEACON:                       
1213                         _mgt_dispatcher(padapter, ptable, precv_frame);
1214                         break;
1215                 case WIFI_ACTION:
1216                         //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1217                         _mgt_dispatcher(padapter, ptable, precv_frame);         
1218                         break;
1219                 default:
1220                         _mgt_dispatcher(padapter, ptable, precv_frame); 
1221                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1222                                 rtw_hostapd_mlme_rx(padapter, precv_frame);                     
1223                         break;
1224         }
1225 #else
1226
1227         _mgt_dispatcher(padapter, ptable, precv_frame); 
1228         
1229 #endif
1230
1231 }
1232
1233 #ifdef CONFIG_P2P
1234 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1235 {
1236         bool response = _TRUE;
1237
1238 #ifdef CONFIG_IOCTL_CFG80211
1239         if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
1240         {
1241                 if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE
1242                         || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1243                         || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1244                         || padapter->mlmepriv.wps_probe_resp_ie == NULL
1245                         || padapter->mlmepriv.p2p_probe_resp_ie == NULL
1246                 )
1247                 {
1248 #ifdef CONFIG_DEBUG_CFG80211
1249                         DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ",
1250                                 adapter_wdev_data(padapter)->p2p_enabled,
1251                                 padapter->mlmepriv.wps_probe_resp_ie,
1252                                 padapter->mlmepriv.p2p_probe_resp_ie);
1253                         DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n", 
1254                                 padapter->cfg80211_wdinfo.is_ro_ch,
1255                                 rtw_get_oper_ch(padapter),
1256                                 padapter->wdinfo.listen_channel);
1257 #endif
1258                         response = _FALSE;
1259                 }
1260         }
1261         else
1262 #endif //CONFIG_IOCTL_CFG80211
1263         if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1264         {
1265                 //      do nothing if the device name is empty
1266                 if ( !padapter->wdinfo.device_name_len )
1267                 {
1268                         response        = _FALSE;
1269                 }
1270         }
1271
1272         if (response == _TRUE)
1273                 issue_probersp_p2p( padapter, da);
1274         
1275         return _SUCCESS;
1276 }
1277 #endif //CONFIG_P2P
1278
1279
1280 /****************************************************************************
1281
1282 Following are the callback functions for each subtype of the management frames
1283
1284 *****************************************************************************/
1285
1286 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1287 {
1288         unsigned int    ielen;
1289         unsigned char   *p;
1290         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1291         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1292         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1293         WLAN_BSSID_EX   *cur = &(pmlmeinfo->network);
1294         u8 *pframe = precv_frame->u.hdr.rx_data;
1295         uint len = precv_frame->u.hdr.len;
1296         u8 is_valid_p2p_probereq = _FALSE;
1297
1298 #ifdef CONFIG_ATMEL_RC_PATCH
1299         u8 *target_ie=NULL, *wps_ie=NULL;
1300         u8 *start;
1301         uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1302         struct sta_info *psta;
1303         struct sta_priv *pstapriv = &padapter->stapriv;
1304 #endif
1305
1306
1307 #ifdef CONFIG_P2P
1308         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
1309         struct rx_pkt_attrib    *pattrib = &precv_frame->u.hdr.attrib;
1310         u8 wifi_test_chk_rate = 1;
1311
1312 #ifdef CONFIG_IOCTL_CFG80211
1313         if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1314                 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1315                 && (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1316                  ) {
1317                 rtw_cfg80211_rx_probe_request(padapter, pframe, len);
1318                 return _SUCCESS;
1319         }
1320 #endif /* CONFIG_IOCTL_CFG80211 */
1321
1322         if (    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && 
1323                 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) && 
1324                 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1325                 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1326                 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1327            )
1328         {
1329                 //      Commented by Albert 2011/03/17
1330                 //      mcs_rate = 0 -> CCK 1M rate
1331                 //      mcs_rate = 1 -> CCK 2M rate
1332                 //      mcs_rate = 2 -> CCK 5.5M rate
1333                 //      mcs_rate = 3 -> CCK 11M rate
1334                 //      In the P2P mode, the driver should not support the CCK rate
1335
1336                 //      Commented by Kurt 2012/10/16
1337                 //      IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
1338         if (padapter->registrypriv.wifi_spec == 1)
1339         {
1340             if ( pattrib->data_rate <= 3 )
1341             {
1342                 wifi_test_chk_rate = 0;
1343             }
1344         }
1345
1346                 if( wifi_test_chk_rate == 1 )
1347                 {
1348                         if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
1349                         {
1350                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
1351                                 {
1352                                         // FIXME
1353                                         if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1354                                                 report_survey_event(padapter, precv_frame);
1355
1356                                         p2p_listen_state_process( padapter,  get_sa(pframe));
1357
1358                                         return _SUCCESS;        
1359                                 }
1360
1361                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1362                                 {
1363                                         goto _continue;
1364                                 }
1365                         }
1366                 }
1367         }
1368
1369 _continue:
1370 #endif //CONFIG_P2P
1371
1372         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1373         {
1374                 return _SUCCESS;
1375         }
1376
1377         if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE && 
1378                 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
1379         {
1380                 return _SUCCESS;
1381         }
1382
1383
1384         //DBG_871X("+OnProbeReq\n");
1385
1386
1387 #ifdef CONFIG_ATMEL_RC_PATCH
1388                 if ((wps_ie = rtw_get_wps_ie(
1389                         pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1390                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1391                          NULL, &wps_ielen))) {
1392                 
1393                         target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1394                 }
1395                 if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) {
1396                         //psta->flag_atmel_rc = 1;
1397                         unsigned char *sa_addr = get_sa(pframe);
1398                         printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x  \n\n",
1399                                 __func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5));
1400                         _rtw_memcpy(  pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1401                 }
1402 #endif
1403
1404
1405 #ifdef CONFIG_AUTO_AP_MODE
1406         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1407                         pmlmepriv->cur_network.join_res == _TRUE)
1408         {
1409                 _irqL   irqL;
1410                 struct sta_info *psta;
1411                 u8 *mac_addr, *peer_addr;
1412                 struct sta_priv *pstapriv = &padapter->stapriv;
1413                 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
1414                 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
1415
1416                 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1417                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1418
1419                 if(!p || ielen !=14)
1420                         goto _non_rc_device;
1421
1422                 if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
1423                         goto _non_rc_device;
1424
1425                 if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
1426                 {
1427                         DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1428                                 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
1429
1430                         goto _non_rc_device;
1431                 }
1432
1433                 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__,  MAC_ARG(get_sa(pframe)));
1434
1435                 //new a station
1436                 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1437                 if (psta == NULL)
1438                 {
1439                         // allocate a new one
1440                         DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n",  MAC_ARG(get_sa(pframe)));
1441                         psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1442                         if (psta == NULL)
1443                         {
1444                                 //TODO:
1445                                 DBG_871X(" Exceed the upper limit of supported clients...\n");
1446                                 return _SUCCESS;
1447                         }
1448
1449                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1450                         if (rtw_is_list_empty(&psta->asoc_list))
1451                         {
1452                                 psta->expire_to = pstapriv->expire_to;
1453                                 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1454                                 pstapriv->asoc_list_cnt++;
1455                         }
1456                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1457
1458                         //generate pairing ID
1459                         mac_addr = adapter_mac_addr(padapter);
1460                         peer_addr = psta->hwaddr;
1461                         psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
1462
1463                         //update peer stainfo
1464                         psta->isrc = _TRUE;
1465                         //psta->aid = 0;
1466                         //psta->mac_id = 2;
1467
1468                         /* get a unique AID */
1469                         if (psta->aid > 0) {
1470                                 DBG_871X("old AID %d\n", psta->aid);
1471                         } else {
1472                                 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1473                                         if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1474                                                 break;
1475
1476                                 if (psta->aid > pstapriv->max_num_sta) {
1477                                         psta->aid = 0;
1478                                         DBG_871X("no room for more AIDs\n");
1479                                         return _SUCCESS;
1480                                 } else {
1481                                         pstapriv->sta_aid[psta->aid - 1] = psta;
1482                                         DBG_871X("allocate new AID = (%d)\n", psta->aid);
1483                                 }
1484                         }
1485                         
1486                         psta->qos_option = 1;
1487                         psta->bw_mode = CHANNEL_WIDTH_20;
1488                         psta->ieee8021x_blocked = _FALSE;
1489 #ifdef CONFIG_80211N_HT
1490                         psta->htpriv.ht_option = _TRUE;
1491                         psta->htpriv.ampdu_enable = _FALSE;
1492                         psta->htpriv.sgi_20m = _FALSE;
1493                         psta->htpriv.sgi_40m = _FALSE;
1494                         psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1495                         psta->htpriv.agg_enable_bitmap = 0x0;//reset
1496                         psta->htpriv.candidate_tid_bitmap = 0x0;//reset
1497 #endif
1498
1499                         rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1500
1501                         _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1502
1503                         _enter_critical_bh(&psta->lock, &irqL);
1504                         psta->state |= _FW_LINKED;
1505                         _exit_critical_bh(&psta->lock, &irqL);
1506
1507                         report_add_sta_event(padapter, psta->hwaddr);
1508
1509                 }
1510
1511                 issue_probersp(padapter, get_sa(pframe), _FALSE);
1512
1513                 return _SUCCESS;
1514
1515         }
1516
1517 _non_rc_device:
1518
1519         return _SUCCESS;
1520
1521 #endif //CONFIG_AUTO_AP_MODE
1522         
1523
1524 #ifdef CONFIG_CONCURRENT_MODE
1525         if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1526                 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1527         {
1528                 //don't process probe req
1529                 return _SUCCESS;
1530         }
1531 #endif  
1532
1533         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1534                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1535
1536
1537         //check (wildcard) SSID 
1538         if (p != NULL)
1539         {
1540                 if(is_valid_p2p_probereq == _TRUE)
1541                 {
1542                         goto _issue_probersp;
1543                 }
1544
1545                 if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1546                         || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1547                 )
1548                 {
1549                         return _SUCCESS;
1550                 }
1551
1552 _issue_probersp:
1553                 if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && 
1554                         pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1555                 {
1556                         //DBG_871X("+issue_probersp during ap mode\n");
1557                         issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);                
1558                 }
1559
1560         }
1561
1562         return _SUCCESS;
1563
1564 }
1565
1566 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1567 {
1568         struct sta_info         *psta;
1569         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1570         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1571         struct sta_priv         *pstapriv = &padapter->stapriv;
1572         u8      *pframe = precv_frame->u.hdr.rx_data;
1573 #ifdef CONFIG_P2P
1574         struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
1575 #endif
1576
1577
1578 #ifdef CONFIG_P2P
1579         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
1580         {
1581                 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
1582                 {
1583                         if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1584                         {
1585                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
1586                                 {
1587                                         pwdinfo->tx_prov_disc_info.benable = _FALSE;
1588                                         issue_p2p_provision_request( padapter,
1589                                                                                                 pwdinfo->tx_prov_disc_info.ssid.Ssid, 
1590                                                                                                 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1591                                                                                                 pwdinfo->tx_prov_disc_info.peerDevAddr );
1592                                 }
1593                                 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
1594                                 {
1595                                         pwdinfo->tx_prov_disc_info.benable = _FALSE;
1596                                         issue_p2p_provision_request( padapter,
1597                                                                                                 NULL, 
1598                                                                                                 0,
1599                                                                                                 pwdinfo->tx_prov_disc_info.peerDevAddr );
1600                                 }
1601                         }               
1602                 }
1603                 return _SUCCESS;
1604         }
1605         else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
1606         {
1607                 if ( _TRUE == pwdinfo->nego_req_info.benable )
1608                 {
1609                         DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
1610                         if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1611                         {
1612                                 pwdinfo->nego_req_info.benable = _FALSE;
1613                                 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
1614                         }
1615                 }
1616         }
1617         else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
1618         {
1619                 if ( _TRUE == pwdinfo->invitereq_info.benable )
1620                 {
1621                         DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
1622                         if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1623                         {
1624                                 pwdinfo->invitereq_info.benable = _FALSE;
1625                                 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
1626                         }
1627                 }
1628         }
1629 #endif
1630
1631
1632         if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1633                 report_survey_event(padapter, precv_frame);     
1634 #ifdef CONFIG_CONCURRENT_MODE
1635                 report_survey_event(padapter->pbuddy_adapter, precv_frame);     
1636 #endif
1637                 return _SUCCESS;
1638         }
1639
1640         #if 0 //move to validate_recv_mgnt_frame
1641         if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1642         {
1643                 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1644                 {
1645                         if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1646                         {
1647                                 psta->sta_stats.rx_mgnt_pkts++;
1648                         }
1649                 }
1650         }
1651         #endif
1652         
1653         return _SUCCESS;
1654         
1655 }
1656
1657 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1658 {
1659         struct sta_info *psta;
1660         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1661         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1662         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1663         struct sta_priv *pstapriv = &padapter->stapriv;
1664         u8 *pframe = precv_frame->u.hdr.rx_data;
1665         uint len = precv_frame->u.hdr.len;
1666         WLAN_BSSID_EX *pbss;
1667         int ret = _SUCCESS;
1668         u8 *p = NULL;
1669         u32 ielen = 0;
1670 #ifdef CONFIG_TDLS
1671         struct sta_info *ptdls_sta;
1672         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1673 #ifdef CONFIG_TDLS_CH_SW
1674         struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
1675 #endif
1676 #endif /* CONFIG_TDLS */
1677
1678 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1679         p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
1680         if ((p != NULL) && (ielen > 0))
1681         {
1682                 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
1683                 {
1684                         /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */     
1685                         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)));
1686                         *(p + 1) = ielen - 1;
1687                 }
1688         }
1689 #endif
1690
1691         if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1692                 report_survey_event(padapter, precv_frame);
1693 #ifdef CONFIG_CONCURRENT_MODE
1694                 report_survey_event(padapter->pbuddy_adapter, precv_frame);     
1695 #endif
1696                 return _SUCCESS;
1697         }
1698
1699         if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1700         {
1701                 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1702                 {
1703                         //we should update current network before auth, or some IE is wrong
1704                         pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1705                         if (pbss) {
1706                                 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1707                                         struct beacon_keys recv_beacon;
1708
1709                                         update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1710                                         rtw_get_bcn_info(&(pmlmepriv->cur_network));
1711
1712                                         // update bcn keys
1713                                         if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1714                                                 DBG_871X("%s: beacon keys ready\n", __func__);
1715                                                 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1716                                                         &recv_beacon, sizeof(recv_beacon));
1717                                                 pmlmepriv->new_beacon_cnts = 0;
1718                                         }
1719                                         else {
1720                                                 DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__);
1721                                                 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1722                                                 pmlmepriv->new_beacon_cnts = 0;
1723                                         }
1724                                 }
1725                                 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1726                         }
1727
1728                         //check the vendor of the assoc AP
1729                         pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));                         
1730
1731                         //update TSF Value
1732                         update_TSF(pmlmeext, pframe, len);
1733
1734                         //reset for adaptive_early_32k
1735                         pmlmeext->adaptive_tsf_done = _FALSE;
1736                         pmlmeext->DrvBcnEarly = 0xff;
1737                         pmlmeext->DrvBcnTimeOut = 0xff;
1738                         pmlmeext->bcn_cnt = 0;
1739                         _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1740                         _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1741
1742 #ifdef CONFIG_P2P_PS
1743                         process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1744 #endif //CONFIG_P2P_PS
1745
1746 #if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE)
1747                         if (padapter->registrypriv.wifi_spec) {
1748                                 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1749                                         if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
1750                                                 DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n ");
1751                                                 return _SUCCESS;
1752                                         }
1753                                 }
1754                         }
1755 #endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE
1756
1757                         //start auth
1758                         start_clnt_auth(padapter);
1759
1760                         return _SUCCESS;
1761                 }
1762
1763                 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1764                 {
1765                         if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1766                         {
1767                                 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL        
1768                                 //Merge from 8712 FW code
1769                                 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)        
1770                                 {            // join wrong channel, deauth and reconnect           
1771                                         issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1772
1773                                         report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE);
1774                                         pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);                   
1775                                         return _SUCCESS;
1776                                 }        
1777                                 #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
1778
1779                                 ret = rtw_check_bcn_info(padapter, pframe, len);
1780                                 if (!ret) {
1781                                                 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1782                                                 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0);
1783                                                 return _SUCCESS;
1784                                 }
1785                                 //update WMM, ERP in the beacon
1786                                 //todo: the timer is used instead of the number of the beacon received
1787                                 if ((sta_rx_pkts(psta) & 0xf) == 0)
1788                                 {
1789                                         //DBG_871X("update_bcn_info\n");
1790                                         update_beacon_info(padapter, pframe, len, psta);
1791                                 }
1792
1793                                 adaptive_early_32k(pmlmeext, pframe, len);                              
1794                                 
1795 #ifdef CONFIG_TDLS
1796 #ifdef CONFIG_TDLS_CH_SW
1797                                 if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE)
1798                                 {
1799                                         /* Send TDLS Channel Switch Request when receiving Beacon */
1800                                         if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
1801                                                 && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1802                                                 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1803                                                 if (ptdls_sta != NULL) {
1804                                                         if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE) {
1805                                                                 _set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
1806                                                         }
1807                                                 }
1808                                         }
1809                                 }
1810 #endif                          
1811 #endif /* CONFIG_TDLS */
1812
1813 #ifdef CONFIG_DFS
1814                                 process_csa_ie(padapter, pframe, len);  //channel switch announcement
1815 #endif //CONFIG_DFS
1816
1817 #ifdef CONFIG_P2P_PS
1818                                 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1819 #endif //CONFIG_P2P_PS
1820
1821                                 if (pmlmeext->en_hw_update_tsf)
1822                                         rtw_enable_hw_update_tsf_cmd(padapter);
1823
1824                                 #if 0 //move to validate_recv_mgnt_frame
1825                                 psta->sta_stats.rx_mgnt_pkts++;
1826                                 #endif
1827                         }
1828
1829                 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
1830                         _irqL irqL;
1831                         u8 rate_set[16];
1832                         u8 rate_num = 0;
1833
1834                         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1835                         if (psta != NULL) {
1836                                 /*
1837                                 * update WMM, ERP in the beacon
1838                                 * todo: the timer is used instead of the number of the beacon received
1839                                 */
1840                                 if ((sta_rx_pkts(psta) & 0xf) == 0)
1841                                         update_beacon_info(padapter, pframe, len, psta);
1842
1843                                 if (pmlmeext->en_hw_update_tsf)
1844                                         rtw_enable_hw_update_tsf_cmd(padapter);
1845
1846                         } else {
1847                                 rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_, rate_set, &rate_num);
1848                                 if (rate_num == 0) {
1849                                         DBG_871X(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
1850                                         goto _END_ONBEACON_;
1851                                 }
1852
1853                                 psta = rtw_alloc_stainfo(pstapriv, GetAddr2Ptr(pframe));
1854                                 if (psta == NULL) {
1855                                         DBG_871X(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
1856                                         goto _END_ONBEACON_;
1857                                 }
1858
1859                                 psta->expire_to = pstapriv->adhoc_expire_to;
1860
1861                                 _rtw_memcpy(psta->bssrateset, rate_set, rate_num);
1862                                 psta->bssratelen = rate_num;
1863
1864                                 //update TSF Value
1865                                 update_TSF(pmlmeext, pframe, len);                      
1866
1867                                 //report sta add event
1868                                 report_add_sta_event(padapter, GetAddr2Ptr(pframe));
1869                         }
1870                 }
1871         }
1872
1873 _END_ONBEACON_:
1874
1875         return _SUCCESS;
1876
1877 }
1878
1879 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1880 {
1881 #ifdef CONFIG_AP_MODE
1882         _irqL irqL;
1883         unsigned int    auth_mode, seq, ie_len;
1884         unsigned char   *sa, *p;        
1885         u16     algorithm;
1886         int     status;
1887         static struct sta_info stat;    
1888         struct  sta_info        *pstat=NULL;    
1889         struct  sta_priv *pstapriv = &padapter->stapriv;
1890         struct security_priv *psecuritypriv = &padapter->securitypriv;
1891         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1892         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1893         u8 *pframe = precv_frame->u.hdr.rx_data; 
1894         uint len = precv_frame->u.hdr.len;
1895         u8      offset = 0;
1896
1897         
1898 #ifdef CONFIG_CONCURRENT_MODE   
1899         if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1900                 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1901         {
1902                 //don't process auth request;
1903                 return _SUCCESS;
1904         }
1905 #endif //CONFIG_CONCURRENT_MODE
1906
1907         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1908                 return _FAIL;
1909
1910         DBG_871X("+OnAuth\n");
1911
1912         sa = GetAddr2Ptr(pframe);
1913
1914         auth_mode = psecuritypriv->dot11AuthAlgrthm;
1915
1916         if (GetPrivacy(pframe))
1917         {
1918                 u8      *iv;
1919                 struct rx_pkt_attrib     *prxattrib = &(precv_frame->u.hdr.attrib);
1920
1921                 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
1922                 prxattrib->encrypt = _WEP40_;
1923
1924                 iv = pframe+prxattrib->hdrlen;
1925                 prxattrib->key_index = ((iv[3]>>6)&0x3);
1926
1927                 prxattrib->iv_len = 4;
1928                 prxattrib->icv_len = 4;
1929
1930                 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
1931
1932                 offset = 4;
1933         }
1934
1935         algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1936         seq     = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1937
1938         DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
1939
1940         if (auth_mode == 2 &&
1941                         psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1942                         psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1943                 auth_mode = 0;
1944
1945         if ((algorithm > 0 && auth_mode == 0) ||        // rx a shared-key auth but shared not enabled
1946                 (algorithm == 0 && auth_mode == 1) )    // rx a open-system auth but shared-key is enabled
1947         {               
1948                 DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1949                         algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1950                 
1951                 status = _STATS_NO_SUPP_ALG_;
1952                 
1953                 goto auth_fail;
1954         }
1955         
1956 #if 0 //ACL control     
1957         phead = &priv->wlan_acl_list;
1958         plist = phead->next;
1959         //check sa
1960         if (acl_mode == 1)              // 1: positive check, only those on acl_list can be connected.
1961                 res = FAIL;
1962         else
1963                 res = SUCCESS;
1964
1965         while(plist != phead)
1966         {
1967                 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
1968                 plist = plist->next;
1969                 if (!memcmp((void *)sa, paclnode->addr, 6)) {
1970                         if (paclnode->mode & 2) { // deny
1971                                 res = FAIL;
1972                                 break;
1973                         }
1974                         else {
1975                                 res = SUCCESS;
1976                                 break;
1977                         }
1978                 }
1979         }
1980
1981         if (res != SUCCESS) {
1982                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
1983                 return FAIL;
1984         }
1985 #else
1986         if(rtw_access_ctrl(padapter, sa) == _FALSE)
1987         {
1988                 status = _STATS_UNABLE_HANDLE_STA_;
1989                 goto auth_fail;
1990         }       
1991 #endif
1992
1993         pstat = rtw_get_stainfo(pstapriv, sa);
1994         if (pstat == NULL)
1995         {
1996
1997                 // allocate a new one
1998                 DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n",  MAC_ARG(sa));
1999                 pstat = rtw_alloc_stainfo(pstapriv, sa);
2000                 if (pstat == NULL)
2001                 {
2002                         DBG_871X(" Exceed the upper limit of supported clients...\n");
2003                         status = _STATS_UNABLE_HANDLE_STA_;
2004                         goto auth_fail;
2005                 }
2006                 
2007                 pstat->state = WIFI_FW_AUTH_NULL;
2008                 pstat->auth_seq = 0;
2009                 
2010                 //pstat->flags = 0;
2011                 //pstat->capability = 0;
2012         } else {
2013 #ifdef CONFIG_IEEE80211W
2014                 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2015 #endif /* CONFIG_IEEE80211W */
2016                 {
2017
2018                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2019                         if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {                   
2020                                 rtw_list_delete(&pstat->asoc_list);
2021                                 pstapriv->asoc_list_cnt--;
2022                                 if (pstat->expire_to > 0)
2023                                         ;/* TODO: STA re_auth within expire_to */
2024                         }
2025                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2026
2027                         if (seq == 1)
2028                                 ; /* TODO: STA re_auth and auth timeout */
2029
2030                 }
2031         }
2032
2033 #ifdef CONFIG_IEEE80211W
2034         if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2035 #endif /* CONFIG_IEEE80211W */
2036         {
2037                 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2038                 if (rtw_is_list_empty(&pstat->auth_list)) {             
2039         
2040                         rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2041                         pstapriv->auth_list_cnt++;
2042                 }       
2043                 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2044         }
2045
2046         if (pstat->auth_seq == 0)
2047                 pstat->expire_to = pstapriv->auth_to;
2048
2049
2050         if ((pstat->auth_seq + 1) != seq)
2051         {
2052                 DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2053                         seq, pstat->auth_seq+1);
2054                 status = _STATS_OUT_OF_AUTH_SEQ_;
2055                 goto auth_fail;
2056         }
2057
2058         if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
2059         {
2060                 if (seq == 1)
2061                 {
2062 #ifdef CONFIG_IEEE80211W
2063                         if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2064 #endif /* CONFIG_IEEE80211W */
2065                         {
2066                                 pstat->state &= ~WIFI_FW_AUTH_NULL;
2067                                 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2068                                 pstat->expire_to = pstapriv->assoc_to;
2069                         }
2070                         pstat->authalg = algorithm;
2071                 }
2072                 else
2073                 {
2074                         DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2075                                 seq, pstat->auth_seq+1);
2076                         status = _STATS_OUT_OF_AUTH_SEQ_;
2077                         goto auth_fail;
2078                 }
2079         }
2080         else // shared system or auto authentication
2081         {
2082                 if (seq == 1)
2083                 {
2084                         //prepare for the challenging txt...
2085
2086                         //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
2087                         _rtw_memset((void *)pstat->chg_txt, 78, 128);
2088 #ifdef CONFIG_IEEE80211W
2089                         if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2090 #endif /* CONFIG_IEEE80211W */
2091                         {
2092                                 pstat->state &= ~WIFI_FW_AUTH_NULL;
2093                                 pstat->state |= WIFI_FW_AUTH_STATE;
2094                         }
2095                         pstat->authalg = algorithm;
2096                         pstat->auth_seq = 2;
2097                 }
2098                 else if (seq == 3)
2099                 {
2100                         //checking for challenging txt...
2101                         DBG_871X("checking for challenging txt...\n");
2102                         
2103                         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2104                                         len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2105
2106                         if((p==NULL) || (ie_len<=0))
2107                         {
2108                                 DBG_871X("auth rejected because challenge failure!(1)\n");
2109                                 status = _STATS_CHALLENGE_FAIL_;
2110                                 goto auth_fail;
2111                         }
2112                         
2113                         if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
2114                         {
2115 #ifdef CONFIG_IEEE80211W
2116                                 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2117 #endif /* CONFIG_IEEE80211W */
2118                                 {
2119                                         pstat->state &= (~WIFI_FW_AUTH_STATE);
2120                                         pstat->state |= WIFI_FW_AUTH_SUCCESS;
2121                                         /* challenging txt is correct... */
2122                                         pstat->expire_to =  pstapriv->assoc_to;
2123                                 }
2124                         }
2125                         else
2126                         {
2127                                 DBG_871X("auth rejected because challenge failure!\n");
2128                                 status = _STATS_CHALLENGE_FAIL_;
2129                                 goto auth_fail;
2130                         }
2131                 }
2132                 else
2133                 {
2134                         DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2135                                 seq, pstat->auth_seq+1);
2136                         status = _STATS_OUT_OF_AUTH_SEQ_;
2137                         goto auth_fail;
2138                 }
2139         }
2140
2141
2142         // Now, we are going to issue_auth...
2143         pstat->auth_seq = seq + 1;      
2144         
2145 #ifdef CONFIG_NATIVEAP_MLME
2146         issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2147 #endif
2148
2149         if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2150                 pstat->auth_seq = 0;
2151
2152                 
2153         return _SUCCESS;
2154
2155 auth_fail:
2156
2157         if(pstat)
2158                 rtw_free_stainfo(padapter , pstat);
2159         
2160         pstat = &stat;
2161         _rtw_memset((char *)pstat, '\0', sizeof(stat));
2162         pstat->auth_seq = 2;
2163         _rtw_memcpy(pstat->hwaddr, sa, 6);      
2164         
2165 #ifdef CONFIG_NATIVEAP_MLME
2166         issue_auth(padapter, pstat, (unsigned short)status);    
2167 #endif
2168
2169 #endif
2170         return _FAIL;
2171
2172 }
2173
2174 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2175 {
2176         unsigned int    seq, len, status, algthm, offset;
2177         unsigned char   *p;
2178         unsigned int    go2asoc = 0;
2179         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2180         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2181         u8 *pframe = precv_frame->u.hdr.rx_data;
2182         uint pkt_len = precv_frame->u.hdr.len;
2183
2184         DBG_871X("%s\n", __FUNCTION__);
2185
2186         //check A1 matches or not
2187         if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2188                 return _SUCCESS;
2189
2190         if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2191                 return _SUCCESS;
2192
2193         offset = (GetPrivacy(pframe))? 4: 0;
2194
2195         algthm  = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2196         seq     = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2197         status  = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2198
2199         if (status != 0)
2200         {
2201                 DBG_871X("clnt auth fail, status: %d\n", status);
2202                 if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
2203                 {
2204                         if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2205                                 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2206                         else
2207                                 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2208                         //pmlmeinfo->reauth_count = 0;
2209                 }
2210                 
2211                 set_link_timer(pmlmeext, 1);
2212                 goto authclnt_fail;
2213         }
2214
2215         if (seq == 2)
2216         {
2217                 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2218                 {
2219                          // legendary shared system
2220                         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2221                                 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2222
2223                         if (p == NULL)
2224                         {
2225                                 //DBG_871X("marc: no challenge text?\n");
2226                                 goto authclnt_fail;
2227                         }
2228
2229                         _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2230                         pmlmeinfo->auth_seq = 3;
2231                         issue_auth(padapter, NULL, 0);
2232                         set_link_timer(pmlmeext, REAUTH_TO);
2233
2234                         return _SUCCESS;
2235                 }
2236                 else
2237                 {
2238                         // open system
2239                         go2asoc = 1;
2240                 }
2241         }
2242         else if (seq == 4)
2243         {
2244                 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2245                 {
2246                         go2asoc = 1;
2247                 }
2248                 else
2249                 {
2250                         goto authclnt_fail;
2251                 }
2252         }
2253         else
2254         {
2255                 // this is also illegal
2256                 //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
2257                 goto authclnt_fail;
2258         }
2259
2260         if (go2asoc)
2261         {
2262                 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
2263                 start_clnt_assoc(padapter);
2264                 return _SUCCESS;
2265         }
2266
2267 authclnt_fail:
2268
2269         //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
2270
2271         return _FAIL;
2272
2273 }
2274
2275 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2276 {
2277 #ifdef CONFIG_AP_MODE
2278         _irqL irqL;
2279         u16 capab_info, listen_interval;
2280         struct rtw_ieee802_11_elems elems;      
2281         struct sta_info *pstat;
2282         unsigned char           reassoc, *p, *pos, *wpa_ie;
2283         unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2284         int             i, ie_len, wpa_ie_len, left;
2285         u8 rate_set[16];
2286         u8 rate_num;
2287         unsigned short          status = _STATS_SUCCESSFUL_;
2288         unsigned short          frame_type, ie_offset=0;        
2289         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2290         struct security_priv *psecuritypriv = &padapter->securitypriv;
2291         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2292         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);  
2293         WLAN_BSSID_EX   *cur = &(pmlmeinfo->network);
2294         struct sta_priv *pstapriv = &padapter->stapriv;
2295         u8 *pframe = precv_frame->u.hdr.rx_data;
2296         uint pkt_len = precv_frame->u.hdr.len;
2297 #ifdef CONFIG_P2P
2298         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
2299         u8 p2p_status_code = P2P_STATUS_SUCCESS;
2300         u8 *p2pie;
2301         u32 p2pielen = 0;
2302 #endif //CONFIG_P2P
2303
2304 #ifdef CONFIG_CONCURRENT_MODE
2305         if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
2306                 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
2307         {
2308                 //don't process assoc request;
2309                 return _SUCCESS;
2310         }
2311 #endif //CONFIG_CONCURRENT_MODE
2312
2313         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2314                 return _FAIL;
2315         
2316         frame_type = GetFrameSubType(pframe);
2317         if (frame_type == WIFI_ASSOCREQ)
2318         {
2319                 reassoc = 0;
2320                 ie_offset = _ASOCREQ_IE_OFFSET_;
2321         }       
2322         else // WIFI_REASSOCREQ
2323         {
2324                 reassoc = 1;
2325                 ie_offset = _REASOCREQ_IE_OFFSET_;
2326         }
2327         
2328
2329         if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2330                 DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2331                        "\n", reassoc, (unsigned long)pkt_len);
2332                 return _FAIL;
2333         }
2334         
2335         pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2336         if (pstat == (struct sta_info *)NULL)
2337         {
2338                 status = _RSON_CLS2_;
2339                 goto asoc_class2_error;
2340         }
2341
2342         capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
2343         //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));      
2344         //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
2345         listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
2346
2347         left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2348         pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2349         
2350
2351         DBG_871X("%s\n", __FUNCTION__);
2352
2353         // check if this stat has been successfully authenticated/assocated
2354         if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
2355         {
2356                 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
2357                 {
2358                         status = _RSON_CLS2_;
2359                         goto asoc_class2_error;
2360                 }
2361                 else
2362                 {
2363                         pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2364                         pstat->state |= WIFI_FW_ASSOC_STATE;                            
2365                 }
2366         }
2367         else
2368         {
2369                 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2370                 pstat->state |= WIFI_FW_ASSOC_STATE;
2371         }
2372
2373
2374 #if 0// todo:tkip_countermeasures
2375         if (hapd->tkip_countermeasures) {
2376                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2377                 goto fail;
2378         }
2379 #endif
2380
2381         pstat->capability = capab_info;
2382
2383 #if 0//todo:
2384         //check listen_interval
2385         if (listen_interval > hapd->conf->max_listen_interval) {
2386                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2387                                HOSTAPD_LEVEL_DEBUG,
2388                                "Too large Listen Interval (%d)",
2389                                listen_interval);
2390                 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2391                 goto fail;
2392         }
2393         
2394         pstat->listen_interval = listen_interval;
2395 #endif
2396
2397         //now parse all ieee802_11 ie to point to elems
2398         if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2399             !elems.ssid) {
2400                 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
2401                        MAC_ARG(pstat->hwaddr));
2402                 status = _STATS_FAILURE_;               
2403                 goto OnAssocReqFail;
2404         }
2405
2406
2407         // now we should check all the fields...
2408         // checking SSID
2409         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2410                 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2411         if (p == NULL)
2412         {
2413                 status = _STATS_FAILURE_;               
2414         }
2415
2416         if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
2417                 status = _STATS_FAILURE_;
2418         else
2419         {
2420                 // check if ssid match
2421                 if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2422                         status = _STATS_FAILURE_;
2423
2424                 if (ie_len != cur->Ssid.SsidLength)
2425                         status = _STATS_FAILURE_;
2426         }
2427
2428         if(_STATS_SUCCESSFUL_ != status)
2429                 goto OnAssocReqFail;
2430
2431         rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, rate_set, &rate_num);
2432         if (rate_num == 0) {
2433                 DBG_871X(FUNC_ADPT_FMT" RX assoc-req with no supported rate\n", FUNC_ADPT_ARG(padapter));
2434                 status = _STATS_FAILURE_;
2435                 goto OnAssocReqFail;
2436         }
2437         _rtw_memcpy(pstat->bssrateset, rate_set, rate_num);
2438         pstat->bssratelen = rate_num;
2439         UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2440
2441         //check RSN/WPA/WPS
2442         pstat->dot8021xalg = 0;
2443         pstat->wpa_psk = 0;
2444         pstat->wpa_group_cipher = 0;
2445         pstat->wpa2_group_cipher = 0;
2446         pstat->wpa_pairwise_cipher = 0;
2447         pstat->wpa2_pairwise_cipher = 0;
2448         _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2449         if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2450
2451                 int group_cipher=0, pairwise_cipher=0;  
2452                 
2453                 wpa_ie = elems.rsn_ie;
2454                 wpa_ie_len = elems.rsn_ie_len;
2455
2456                 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2457                 {
2458                         pstat->dot8021xalg = 1;//psk,  todo:802.1x                                              
2459                         pstat->wpa_psk |= BIT(1);
2460
2461                         pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;                               
2462                         pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
2463                         
2464                         if(!pstat->wpa2_group_cipher)
2465                                 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2466
2467                         if(!pstat->wpa2_pairwise_cipher)
2468                                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2469                 }
2470                 else
2471                 {
2472                         status = WLAN_STATUS_INVALID_IE;
2473                 }       
2474                         
2475         } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2476
2477                 int group_cipher=0, pairwise_cipher=0;  
2478                 
2479                 wpa_ie = elems.wpa_ie;
2480                 wpa_ie_len = elems.wpa_ie_len;
2481
2482                 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2483                 {
2484                         pstat->dot8021xalg = 1;//psk,  todo:802.1x                                              
2485                         pstat->wpa_psk |= BIT(0);
2486
2487                         pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;                         
2488                         pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
2489                         
2490                         if(!pstat->wpa_group_cipher)
2491                                 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2492
2493                         if(!pstat->wpa_pairwise_cipher)
2494                                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2495                 
2496                 }
2497                 else
2498                 {
2499                         status = WLAN_STATUS_INVALID_IE;
2500                 }
2501                 
2502         } else {
2503                 wpa_ie = NULL;
2504                 wpa_ie_len = 0;
2505         }
2506
2507         if(_STATS_SUCCESSFUL_ != status)
2508                 goto OnAssocReqFail;
2509
2510         pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2511         //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
2512         if(wpa_ie == NULL) {
2513                 if (elems.wps_ie) {
2514                         DBG_871X("STA included WPS IE in "
2515                                    "(Re)Association Request - assume WPS is "
2516                                    "used\n");
2517                         pstat->flags |= WLAN_STA_WPS;
2518                         //wpabuf_free(sta->wps_ie);
2519                         //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
2520                         //                              elems.wps_ie_len - 4);
2521                 } else {
2522                         DBG_871X("STA did not include WPA/RSN IE "
2523                                    "in (Re)Association Request - possible WPS "
2524                                    "use\n");
2525                         pstat->flags |= WLAN_STA_MAYBE_WPS;
2526                 }
2527
2528
2529                 // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
2530                 // that the selected registrar of AP is _FLASE
2531                 if((psecuritypriv->wpa_psk >0)  
2532                         && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
2533                 {
2534                         if(pmlmepriv->wps_beacon_ie)
2535                         {       
2536                                 u8 selected_registrar = 0;
2537                                 
2538                                 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2539
2540                                 if(!selected_registrar)
2541                                 {                                               
2542                                         DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2543                                                 
2544                                         status = _STATS_UNABLE_HANDLE_STA_;
2545                         
2546                                         goto OnAssocReqFail;
2547                                 }                                               
2548                         }                       
2549                 }
2550                         
2551         }
2552         else
2553         {
2554                 int copy_len;
2555
2556                 if(psecuritypriv->wpa_psk == 0)
2557                 {
2558                         DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
2559                         "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2560                         
2561                         status = WLAN_STATUS_INVALID_IE;
2562                         
2563                         goto OnAssocReqFail;
2564
2565                 }
2566
2567                 if (elems.wps_ie) {
2568                         DBG_871X("STA included WPS IE in "
2569                                    "(Re)Association Request - WPS is "
2570                                    "used\n");
2571                         pstat->flags |= WLAN_STA_WPS;
2572                         copy_len=0;
2573                 }
2574                 else
2575                 {
2576                         copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
2577                 }
2578
2579                 
2580                 if(copy_len>0)
2581                         _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
2582                 
2583         }
2584
2585
2586         // check if there is WMM IE & support WWM-PS
2587         pstat->flags &= ~WLAN_STA_WME;
2588         pstat->qos_option = 0;
2589         pstat->qos_info = 0;
2590         pstat->has_legacy_ac = _TRUE;
2591         pstat->uapsd_vo = 0;
2592         pstat->uapsd_vi = 0;
2593         pstat->uapsd_be = 0;
2594         pstat->uapsd_bk = 0;
2595         if (pmlmepriv->qospriv.qos_option) 
2596         {
2597                 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
2598                 for (;;) 
2599                 {
2600                         p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2601                         if (p != NULL) {
2602                                 if (_rtw_memcmp(p+2, WMM_IE, 6)) {
2603
2604                                         pstat->flags |= WLAN_STA_WME;
2605                                         
2606                                         pstat->qos_option = 1;                          
2607                                         pstat->qos_info = *(p+8);
2608                                         
2609                                         pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
2610
2611                                         if((pstat->qos_info&0xf) !=0xf)
2612                                                 pstat->has_legacy_ac = _TRUE;
2613                                         else
2614                                                 pstat->has_legacy_ac = _FALSE;
2615                                         
2616                                         if(pstat->qos_info&0xf)
2617                                         {
2618                                                 if(pstat->qos_info&BIT(0))
2619                                                         pstat->uapsd_vo = BIT(0)|BIT(1);
2620                                                 else
2621                                                         pstat->uapsd_vo = 0;
2622                 
2623                                                 if(pstat->qos_info&BIT(1))
2624                                                         pstat->uapsd_vi = BIT(0)|BIT(1);
2625                                                 else
2626                                                         pstat->uapsd_vi = 0;
2627                         
2628                                                 if(pstat->qos_info&BIT(2))
2629                                                         pstat->uapsd_bk = BIT(0)|BIT(1);
2630                                                 else
2631                                                         pstat->uapsd_bk = 0;
2632                         
2633                                                 if(pstat->qos_info&BIT(3))                      
2634                                                         pstat->uapsd_be = BIT(0)|BIT(1);
2635                                                 else
2636                                                         pstat->uapsd_be = 0;
2637                 
2638                                         }
2639         
2640                                         break;
2641                                 }
2642                         }
2643                         else {
2644                                 break;
2645                         }
2646                         p = p + ie_len + 2;
2647                 }
2648         }
2649
2650
2651 #ifdef CONFIG_80211N_HT
2652         if (pmlmepriv->htpriv.ht_option == _FALSE)
2653                 goto bypass_ht_chk;
2654
2655         /* save HT capabilities in the sta object */
2656         _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2657         if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) 
2658         {
2659                 pstat->flags |= WLAN_STA_HT;
2660                 
2661                 pstat->flags |= WLAN_STA_WME;
2662                 
2663                 _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));                 
2664                 
2665         } else
2666                 pstat->flags &= ~WLAN_STA_HT;
2667 bypass_ht_chk:
2668
2669         if ((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT)) {
2670                 rtw_warn_on(1);
2671                 status = _STATS_FAILURE_;
2672                 goto OnAssocReqFail;
2673         }
2674 #endif /* CONFIG_80211N_HT */
2675
2676 #ifdef CONFIG_80211AC_VHT
2677         if (pmlmepriv->vhtpriv.vht_option == _FALSE)
2678                 goto bypass_vht_chk;
2679
2680         _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
2681         if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
2682                 pstat->flags |= WLAN_STA_VHT;
2683
2684                 _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
2685
2686                 if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) {
2687                         _rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1);
2688                 }
2689                 else // for Frame without Operating Mode notify ie; default: 80M
2690                 {
2691                         pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
2692                 }
2693         }
2694         else {
2695                 pstat->flags &= ~WLAN_STA_VHT;
2696         }
2697 bypass_vht_chk:
2698
2699         if ((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT)) {
2700                 rtw_warn_on(1);
2701                 status = _STATS_FAILURE_;
2702                 goto OnAssocReqFail;
2703         }
2704 #endif /* CONFIG_80211AC_VHT */
2705
2706         if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) && 
2707                 ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || 
2708                 (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2709
2710                 DBG_871X("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr));
2711
2712                 pstat->flags &= ~WLAN_STA_HT;
2713                 pstat->flags &= ~WLAN_STA_VHT;
2714                 /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2715                   * goto OnAssocReqFail;
2716                 */
2717         }
2718
2719
2720        //
2721        //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
2722         pstat->flags |= WLAN_STA_NONERP;        
2723         for (i = 0; i < pstat->bssratelen; i++) {
2724                 if ((pstat->bssrateset[i] & 0x7f) > 22) {
2725                         pstat->flags &= ~WLAN_STA_NONERP;
2726                         break;
2727                 }
2728         }
2729
2730         if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2731                 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2732         else
2733                 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2734
2735         
2736         
2737         if (status != _STATS_SUCCESSFUL_)
2738                 goto OnAssocReqFail;
2739
2740 #ifdef CONFIG_P2P
2741         pstat->is_p2p_device = _FALSE;
2742         if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2743         {               
2744                 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
2745                 {
2746                         pstat->is_p2p_device = _TRUE;
2747                         if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
2748                         {
2749                                 pstat->p2p_status_code = p2p_status_code;
2750                                 status = _STATS_CAP_FAIL_;
2751                                 goto OnAssocReqFail;
2752                         }
2753                 }
2754                 #ifdef CONFIG_WFD
2755                 rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
2756                 #endif
2757         }
2758         pstat->p2p_status_code = p2p_status_code;
2759 #endif //CONFIG_P2P
2760
2761         //TODO: identify_proprietary_vendor_ie();
2762         // Realtek proprietary IE
2763         // identify if this is Broadcom sta
2764         // identify if this is ralink sta
2765         // Customer proprietary IE
2766
2767         
2768
2769         /* get a unique AID */
2770         if (pstat->aid > 0) {
2771                 DBG_871X("  old AID %d\n", pstat->aid);
2772         } else {
2773                 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2774                         if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2775                                 if (pstat->aid > pstapriv->max_num_sta) {
2776                                         pstat->aid = 0;
2777                                 
2778                                         DBG_871X("  no room for more AIDs\n");
2779
2780                                         status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2781                                 
2782                                         goto OnAssocReqFail;
2783                                 
2784                         
2785                                 } else {
2786                                         pstapriv->sta_aid[pstat->aid - 1] = pstat;
2787                                         DBG_871X("allocate new AID = (%d)\n", pstat->aid);
2788                                         break;
2789                                 }                               
2790                         }
2791                 }       
2792         }
2793
2794
2795         pstat->state &= (~WIFI_FW_ASSOC_STATE); 
2796         pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2797         /* DBG_871X("==================%s, %d,  (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2798         , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */
2799 #ifdef CONFIG_IEEE80211W
2800         if (pstat->bpairwise_key_installed != _TRUE)
2801 #endif /* CONFIG_IEEE80211W */
2802         {
2803                 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2804                 if (!rtw_is_list_empty(&pstat->auth_list)) {
2805                         rtw_list_delete(&pstat->auth_list);
2806                         pstapriv->auth_list_cnt--;
2807                 }
2808                 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2809         
2810                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);   
2811                 if (rtw_is_list_empty(&pstat->asoc_list)) {
2812                         pstat->expire_to = pstapriv->expire_to;
2813                         rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2814                         pstapriv->asoc_list_cnt++;
2815                 }
2816                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2817         }
2818
2819         // now the station is qualified to join our BSS...      
2820         if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
2821         {
2822 #ifdef CONFIG_NATIVEAP_MLME
2823 #ifdef CONFIG_IEEE80211W
2824                 if (pstat->bpairwise_key_installed != _TRUE)
2825 #endif /* CONFIG_IEEE80211W */
2826                 {
2827                         /* .1 bss_cap_update & sta_info_update */
2828                         bss_cap_update_on_sta_join(padapter, pstat);
2829                         sta_info_update(padapter, pstat);
2830                 }
2831 #ifdef CONFIG_IEEE80211W
2832                 if (pstat->bpairwise_key_installed == _TRUE)
2833                         status = _STATS_REFUSED_TEMPORARILY_;
2834 #endif /* CONFIG_IEEE80211W */
2835                 //.2 issue assoc rsp before notify station join event.
2836                 if (frame_type == WIFI_ASSOCREQ)
2837                         issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2838                 else
2839                         issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2840
2841 #ifdef CONFIG_IOCTL_CFG80211
2842                 _enter_critical_bh(&pstat->lock, &irqL);
2843                 if(pstat->passoc_req)
2844                 {
2845                         rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2846                         pstat->passoc_req = NULL;
2847                         pstat->assoc_req_len = 0;
2848                 }
2849
2850                 pstat->passoc_req =  rtw_zmalloc(pkt_len);
2851                 if(pstat->passoc_req)
2852                 {
2853                         _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2854                         pstat->assoc_req_len = pkt_len;
2855                 }
2856                 _exit_critical_bh(&pstat->lock, &irqL);
2857 #endif //CONFIG_IOCTL_CFG80211
2858 #ifdef CONFIG_IEEE80211W
2859                 if (pstat->bpairwise_key_installed != _TRUE)
2860 #endif /* CONFIG_IEEE80211W */
2861                 {
2862                         /* .3-(1) report sta add event */
2863                         report_add_sta_event(padapter, pstat->hwaddr);
2864                 }
2865 #ifdef CONFIG_IEEE80211W
2866                 if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) {
2867                         DBG_871X(MAC_FMT"\n", MAC_ARG(pstat->hwaddr));
2868                         issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY);
2869                 }
2870 #endif /* CONFIG_IEEE80211W */
2871 #endif //CONFIG_NATIVEAP_MLME
2872         }
2873
2874         return _SUCCESS;
2875
2876 asoc_class2_error:
2877
2878 #ifdef CONFIG_NATIVEAP_MLME
2879         issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
2880 #endif
2881
2882         return _FAIL;           
2883
2884 OnAssocReqFail:
2885
2886
2887 #ifdef CONFIG_NATIVEAP_MLME
2888         pstat->aid = 0;
2889         if (frame_type == WIFI_ASSOCREQ)
2890                 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2891         else
2892                 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2893 #endif
2894
2895
2896 #endif /* CONFIG_AP_MODE */
2897
2898         return _FAIL;           
2899
2900 }
2901
2902 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2903 {
2904         uint i;
2905         int res;
2906         unsigned short  status;
2907         PNDIS_802_11_VARIABLE_IEs       pIE;
2908         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2909         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2910         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2911         //WLAN_BSSID_EX                 *cur_network = &(pmlmeinfo->network);
2912         u8 *pframe = precv_frame->u.hdr.rx_data;
2913         uint pkt_len = precv_frame->u.hdr.len;
2914         PNDIS_802_11_VARIABLE_IEs       pWapiIE = NULL;
2915
2916         DBG_871X("%s\n", __FUNCTION__);
2917         
2918         //check A1 matches or not
2919         if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2920                 return _SUCCESS;
2921
2922         if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2923                 return _SUCCESS;
2924
2925         if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2926                 return _SUCCESS;
2927
2928         _cancel_timer_ex(&pmlmeext->link_timer);
2929
2930         //status
2931         if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2932         {
2933                 DBG_871X("assoc reject, status code: %d\n", status);
2934                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2935                 res = -4;
2936                 goto report_assoc_result;
2937         }
2938
2939         //get capabilities
2940         pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2941
2942         //set slot time
2943         pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2944
2945         //AID
2946         res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2947
2948         //following are moved to join event callback function
2949         //to handle HT, WMM, rate adaptive, update MAC reg
2950         //for not to handle the synchronous IO in the tasklet
2951         for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2952         {
2953                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2954
2955                 switch (pIE->ElementID)
2956                 {
2957                         case _VENDOR_SPECIFIC_IE_:
2958                                 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6))    //WMM
2959                                 {
2960                                         WMM_param_handler(padapter, pIE);
2961                                 }
2962 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2963                                 else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4))           //WFD
2964                                 {
2965                                         rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
2966                                 }
2967 #endif                          
2968                                 break;
2969
2970 #ifdef CONFIG_WAPI_SUPPORT
2971                         case _WAPI_IE_:
2972                                 pWapiIE = pIE;
2973                                 break;
2974 #endif
2975
2976                         case _HT_CAPABILITY_IE_:        //HT caps
2977                                 HT_caps_handler(padapter, pIE);
2978                                 break;
2979
2980                         case _HT_EXTRA_INFO_IE_:        //HT info
2981                                 HT_info_handler(padapter, pIE);
2982                                 break;
2983
2984 #ifdef CONFIG_80211AC_VHT
2985                         case EID_VHTCapability:
2986                                 VHT_caps_handler(padapter, pIE);
2987                                 break;
2988
2989                         case EID_VHTOperation:
2990                                 VHT_operation_handler(padapter, pIE);
2991                                 break;
2992 #endif
2993
2994                         case _ERPINFO_IE_:
2995                                 ERP_IE_handler(padapter, pIE);
2996                                 break;
2997 #ifdef CONFIG_TDLS
2998                         case _EXT_CAP_IE_:
2999                                 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
3000                                         padapter->tdlsinfo.ap_prohibited = _TRUE;
3001                                 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
3002                                         padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
3003                                 break;
3004 #endif /* CONFIG_TDLS */
3005                         default:
3006                                 break;
3007                 }
3008
3009                 i += (pIE->Length + 2);
3010         }
3011
3012 #ifdef CONFIG_WAPI_SUPPORT
3013         rtw_wapi_on_assoc_ok(padapter, pIE);
3014 #endif
3015
3016         pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3017         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3018
3019         //Update Basic Rate Table for spec, 2010-12-28 , by thomas
3020         UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3021
3022 report_assoc_result:
3023         if (res > 0) {
3024                 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3025         } else {
3026                 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3027         }
3028
3029         report_join_res(padapter, res);
3030
3031         return _SUCCESS;
3032 }
3033
3034 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
3035 {
3036         unsigned short  reason;
3037         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3038         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3039         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3040         u8 *pframe = precv_frame->u.hdr.rx_data;
3041 #ifdef CONFIG_P2P
3042         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3043 #endif //CONFIG_P2P
3044
3045         //check A3
3046         if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3047                 return _SUCCESS;
3048
3049         DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3050
3051 #ifdef CONFIG_P2P
3052         if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3053         {
3054                 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3055                 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3056         }
3057 #endif //CONFIG_P2P
3058
3059         reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3060
3061         rtw_lock_rx_suspend_timeout(8000);
3062
3063 #ifdef CONFIG_AP_MODE
3064         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3065         {               
3066                 _irqL irqL;
3067                 struct sta_info *psta;
3068                 struct sta_priv *pstapriv = &padapter->stapriv;
3069                 
3070                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);                
3071                 //rtw_free_stainfo(padapter, psta);
3072                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);         
3073
3074                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3075                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3076
3077                 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));  
3078                 if(psta)
3079                 {
3080                         u8 updated = _FALSE;
3081                 
3082                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3083                         if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3084                         {                       
3085                                 rtw_list_delete(&psta->asoc_list);
3086                                 pstapriv->asoc_list_cnt--;
3087                                 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3088
3089                         }
3090                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3091
3092                         associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3093                 }
3094                 
3095
3096                 return _SUCCESS;
3097         }
3098         else
3099 #endif
3100         {
3101                 int     ignore_received_deauth = 0;
3102
3103                 //      Commented by Albert 20130604
3104                 //      Before sending the auth frame to start the STA/GC mode connection with AP/GO, 
3105                 //      we will send the deauth first.
3106                 //      However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
3107                 //      Added the following code to avoid this case.
3108                 if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
3109                         ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
3110                 {
3111                         if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
3112                         {
3113                                 ignore_received_deauth = 1;
3114                         } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3115                                 // TODO: 802.11r
3116                                 ignore_received_deauth = 1;
3117                         }
3118                 }
3119
3120                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3121                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth);
3122
3123                 if ( 0 == ignore_received_deauth )
3124                 {
3125                         receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3126                 }
3127         }       
3128         pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3129         return _SUCCESS;
3130
3131 }
3132
3133 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3134 {
3135         unsigned short  reason;
3136         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3137         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3138         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3139         u8 *pframe = precv_frame->u.hdr.rx_data;
3140 #ifdef CONFIG_P2P
3141         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3142 #endif //CONFIG_P2P
3143
3144         //check A3
3145         if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3146                 return _SUCCESS;
3147
3148         DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3149
3150 #ifdef CONFIG_P2P
3151         if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3152         {
3153                 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3154                 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3155         }
3156 #endif //CONFIG_P2P
3157
3158         reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3159
3160         rtw_lock_rx_suspend_timeout(8000);
3161         
3162 #ifdef CONFIG_AP_MODE
3163         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3164         {       
3165                 _irqL irqL;
3166                 struct sta_info *psta;
3167                 struct sta_priv *pstapriv = &padapter->stapriv;
3168                 
3169                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);        
3170                 //rtw_free_stainfo(padapter, psta);
3171                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);         
3172
3173                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3174                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3175
3176                 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));  
3177                 if(psta)
3178                 {
3179                         u8 updated = _FALSE;
3180                         
3181                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3182                         if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3183                         {
3184                                 rtw_list_delete(&psta->asoc_list);
3185                                 pstapriv->asoc_list_cnt--;
3186                                 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3187                         
3188                         }
3189                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3190
3191                         associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3192                 }
3193
3194                 return _SUCCESS;
3195         }
3196         else
3197 #endif
3198         {
3199                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3200                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3201
3202                 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3203         }       
3204         pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3205         return _SUCCESS;
3206
3207 }
3208
3209 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3210 {
3211         DBG_871X("%s\n", __FUNCTION__);
3212         return _SUCCESS;
3213 }
3214
3215 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3216 {
3217         unsigned int ret = _FAIL;
3218         struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3219         struct mlme_ext_info    *pmlmeinfo = &(mlmeext->mlmext_info);
3220
3221         if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3222                 ret = _SUCCESS; 
3223                 goto exit;
3224         }
3225
3226         if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3227                 
3228                 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3229                 int ch_offset = -1;
3230                 u8 bwmode;
3231                 struct ieee80211_info_element *ie;
3232
3233                 DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3234                         FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
3235
3236                 for_each_ie(ie, ies, ies_len) {
3237                         if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3238                                 ch_switch_mode = ie->data[0];
3239                                 ch = ie->data[1];
3240                                 ch_switch_cnt = ie->data[2];
3241                                 DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3242                                         ch_switch_mode, ch, ch_switch_cnt);
3243                         }
3244                         else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3245                                 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3246                                 DBG_871X("ch_offset:%d\n", ch_offset);
3247                         }
3248                 }
3249
3250                 if (ch == -1)
3251                         return _SUCCESS;
3252
3253                 if (ch_offset == -1)
3254                         bwmode = mlmeext->cur_bwmode;
3255                 else
3256                         bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3257                                 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3258
3259                 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3260
3261                 /* todo:
3262                  * 1. the decision of channel switching
3263                  * 2. things after channel switching
3264                  */
3265
3266                 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
3267         }
3268
3269 exit:
3270         return ret;
3271 }
3272
3273 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3274 {
3275         unsigned int ret = _FAIL;
3276         struct sta_info *psta = NULL;
3277         struct sta_priv *pstapriv = &padapter->stapriv;
3278         u8 *pframe = precv_frame->u.hdr.rx_data;
3279         uint frame_len = precv_frame->u.hdr.len;
3280         u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3281         u8 category;
3282         u8 action;
3283
3284         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3285
3286         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3287
3288         if (!psta)
3289                 goto exit;
3290
3291         category = frame_body[0];
3292         if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3293                 goto exit;
3294
3295         action = frame_body[1];
3296         switch (action) {
3297         case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3298         case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3299         case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3300         case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3301                 break;
3302         case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3303                 #ifdef CONFIG_SPCT_CH_SWITCH
3304                 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
3305                         frame_len-(frame_body-pframe)-2);
3306                 #endif
3307                 break;
3308         default:
3309                 break;
3310         }
3311
3312 exit:
3313         return ret;
3314 }
3315
3316 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3317 {
3318         return _SUCCESS;
3319 }
3320
3321 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3322 {
3323         return _SUCCESS;
3324 }
3325
3326 /**
3327  * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3328  * @adapter: the adapter to get target RX AMPDU buffer size
3329  *
3330  * Returns: the target RX AMPDU buffer size
3331  */
3332 u8 rtw_rx_ampdu_size(_adapter *adapter)
3333 {
3334         u8 size;
3335         HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3336
3337         if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) {
3338                 size = adapter->fix_rx_ampdu_size;
3339                 goto exit;
3340         }
3341
3342 #ifdef CONFIG_BT_COEXIST
3343         if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3344                 size = rtw_btcoex_GetAMPDUSize(adapter);
3345                 goto exit;
3346         }
3347 #endif
3348
3349         /* for scan */
3350         if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3351                 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3352                 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3353         ) {
3354                 size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3355                 goto exit;
3356         }
3357
3358         /* default value based on max_rx_ampdu_factor */
3359         if (adapter->driver_rx_ampdu_factor != 0xFF)
3360                 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3361         else
3362                 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3363
3364         if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3365                 size = 64;
3366         else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3367                 size = 32;
3368         else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3369                 size = 16;
3370         else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3371                 size = 8;
3372         else
3373                 size = 64;
3374
3375 exit:
3376
3377         if (size > 127)
3378                 size = 127;
3379
3380         return size;
3381 }
3382
3383 /**
3384  * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3385  * @adapter: the adapter to get the permission if RX AMPDU should be set up
3386  *
3387  * Returns: accept or not
3388  */
3389 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3390 {
3391         bool accept;
3392
3393         if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3394                 accept = adapter->fix_rx_ampdu_accept;
3395                 goto exit;
3396         }
3397
3398 #ifdef CONFIG_BT_COEXIST
3399         if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3400                 accept = _FALSE;
3401                 goto exit;
3402         }
3403 #endif
3404
3405         /* for scan */
3406         if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3407                 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3408                 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3409         ) {
3410                 accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3411                 goto exit;
3412         }
3413
3414         /* default value for other cases */
3415         accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3416
3417 exit:
3418         return accept;
3419 }
3420
3421 /**
3422  * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3423  * @adapter: the adapter to set target RX AMPDU buffer size
3424  * @size: the target RX AMPDU buffer size to set
3425  * @reason: reason for the target RX AMPDU buffer size setting
3426  *
3427  * Returns: whether the target RX AMPDU buffer size is changed
3428  */
3429 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3430 {
3431         bool is_adj = _FALSE;
3432         struct mlme_ext_priv *mlmeext;
3433         struct mlme_ext_info *mlmeinfo;
3434
3435         mlmeext = &adapter->mlmeextpriv;
3436         mlmeinfo = &mlmeext->mlmext_info;
3437
3438         if (reason == RX_AMPDU_DRV_FIXED) {
3439                 if (adapter->fix_rx_ampdu_size != size) {
3440                         adapter->fix_rx_ampdu_size = size;
3441                         is_adj = _TRUE;
3442                         DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3443                 }
3444         } else if (reason == RX_AMPDU_DRV_SCAN) {
3445                 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3446
3447                 if (ss->rx_ampdu_size != size) {
3448                         ss->rx_ampdu_size = size;
3449                         is_adj = _TRUE;
3450                         DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3451                 }
3452         }
3453
3454         return is_adj;
3455 }
3456
3457 /**
3458  * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3459  * @adapter: the adapter to set if RX AMPDU should be set up
3460  * @accept: if RX AMPDU should be set up
3461  * @reason: reason for the permission if RX AMPDU should be set up
3462  *
3463  * Returns: whether the permission if RX AMPDU should be set up is changed
3464  */
3465 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3466 {
3467         bool is_adj = _FALSE;
3468         struct mlme_ext_priv *mlmeext;
3469         struct mlme_ext_info *mlmeinfo;
3470
3471         mlmeext = &adapter->mlmeextpriv;
3472         mlmeinfo = &mlmeext->mlmext_info;
3473
3474         if (reason == RX_AMPDU_DRV_FIXED) {
3475                 if (adapter->fix_rx_ampdu_accept != accept) {
3476                         adapter->fix_rx_ampdu_accept = accept;
3477                         is_adj = _TRUE;
3478                         DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3479                 }
3480         } else if (reason == RX_AMPDU_DRV_SCAN) {
3481                 if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3482                         adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3483                         is_adj = _TRUE;
3484                         DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3485                 }
3486         }
3487
3488         return is_adj;
3489 }
3490
3491 /**
3492  * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3493  * @adapter: the adapter to which @sta belongs
3494  * @sta: the sta to be checked
3495  * @tid: the tid to be checked
3496  * @accept: the target permission if RX AMPDU should be set up
3497  * @size: the target RX AMPDU buffer size
3498  *
3499  * Returns:
3500  * 0: no canceled
3501  * 1: canceled by no permission
3502  * 2: canceled by different buffer size
3503  * 3: canceled by potential mismatched status
3504  *
3505  * Blocking function, may sleep
3506  */
3507 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3508 {
3509         u8 ret = 0;
3510         struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3511
3512         if (reorder_ctl->enable == _FALSE) {
3513                 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3514                         send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3515                         ret = 3;
3516                 }
3517                 goto exit;
3518         }
3519
3520         if (accept == _FALSE) {
3521                 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3522                 ret = 1;
3523         } else if (reorder_ctl->ampdu_size != size) {
3524                 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3525                 ret = 2;
3526         }
3527
3528 exit:
3529         return ret;
3530 }
3531
3532 /**
3533  * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3534  * @adapter: the adapter to which @sta belongs
3535  * @sta: the sta to be checked
3536  * @accept: the target permission if RX AMPDU should be set up
3537  * @size: the target RX AMPDU buffer size
3538  *
3539  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3540  *
3541  * Blocking function, may sleep
3542  */
3543 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3544 {
3545         u8 change_cnt = 0;
3546         int i;
3547
3548         for (i = 0; i < TID_NUM; i++) {
3549                 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3550                         change_cnt++;
3551         }
3552
3553         return change_cnt;
3554 }
3555
3556 /**
3557  * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3558  * @adapter: the adapter to be applied
3559  *
3560  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3561  */
3562 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3563 {
3564         u16 adj_cnt = 0;
3565         struct mlme_ext_priv *mlmeext;
3566         struct sta_info *sta;
3567         u8 accept = rtw_rx_ampdu_is_accept(adapter);
3568         u8 size = rtw_rx_ampdu_size(adapter);
3569
3570         mlmeext = &adapter->mlmeextpriv;
3571
3572         if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3573                 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3574                 if (sta)
3575                         adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3576
3577         } else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3578                 _irqL irqL;
3579                 _list *phead, *plist;
3580                 u8 peer_num = 0;
3581                 char peers[NUM_STA];
3582                 struct sta_priv *pstapriv = &adapter->stapriv;
3583                 int i;
3584
3585                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3586
3587                 phead = &pstapriv->asoc_list;
3588                 plist = get_next(phead);
3589
3590                 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3591                         int stainfo_offset;
3592
3593                         sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3594                         plist = get_next(plist);
3595
3596                         stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3597                         if (stainfo_offset_valid(stainfo_offset))
3598                                 peers[peer_num++] = stainfo_offset;
3599                 }
3600
3601                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3602
3603                 for (i = 0; i < peer_num; i++) {
3604                         sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3605                         if (sta)
3606                                 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3607                 }
3608         }
3609
3610         return adj_cnt;
3611 }
3612
3613 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3614 {
3615         u8 *addr;
3616         struct sta_info *psta=NULL;
3617         struct recv_reorder_ctrl *preorder_ctrl;
3618         unsigned char           *frame_body;
3619         unsigned char           category, action;
3620         unsigned short  tid, status, reason_code = 0;
3621         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3622         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3623         u8 *pframe = precv_frame->u.hdr.rx_data;
3624         struct sta_priv *pstapriv = &padapter->stapriv;
3625 #ifdef CONFIG_80211N_HT
3626
3627         DBG_871X("%s\n", __FUNCTION__);
3628
3629         //check RA matches or not       
3630         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3631                 return _SUCCESS;
3632
3633 /*
3634         //check A1 matches or not
3635         if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3636                 return _SUCCESS;
3637 */
3638
3639         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 
3640                 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3641                         return _SUCCESS;
3642
3643         addr = GetAddr2Ptr(pframe);
3644         psta = rtw_get_stainfo(pstapriv, addr);
3645
3646         if(psta==NULL)
3647                 return _SUCCESS;
3648
3649         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3650
3651         category = frame_body[0];
3652         if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
3653         {
3654 #ifdef CONFIG_TDLS
3655                 if((psta->tdls_sta_state & TDLS_LINKED_STATE) && 
3656                         (psta->htpriv.ht_option==_TRUE) &&
3657                         (psta->htpriv.ampdu_enable==_TRUE))
3658                 {
3659                         DBG_871X("Recv [%s] from direc link\n", __FUNCTION__);
3660                 }
3661                 else
3662 #endif //CONFIG_TDLS
3663                 if (!pmlmeinfo->HT_enable)
3664                 {
3665                         return _SUCCESS;
3666                 }
3667
3668                 action = frame_body[1];
3669                 DBG_871X("%s, action=%d\n", __FUNCTION__, action);
3670                 switch (action)
3671                 {
3672                         case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
3673
3674                                 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3675                                 //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
3676                                 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
3677                                                                 
3678                                 break;
3679
3680                         case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
3681
3682                                 //status = frame_body[3] | (frame_body[4] << 8); //endian issue
3683                                 status = RTW_GET_LE16(&frame_body[3]);
3684                                 tid = ((frame_body[5] >> 2) & 0x7);
3685
3686                                 if (status == 0)
3687                                 {       //successful                                    
3688                                         DBG_871X("agg_enable for TID=%d\n", tid);
3689                                         psta->htpriv.agg_enable_bitmap |= 1 << tid;                                     
3690                                         psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);                         
3691                                 }
3692                                 else
3693                                 {                                       
3694                                         psta->htpriv.agg_enable_bitmap &= ~BIT(tid);                                    
3695                                 }
3696
3697                                 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3698                                 {
3699                                         DBG_871X("%s alive check - rx ADDBA response\n", __func__);
3700                                         psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3701                                         psta->expire_to = pstapriv->expire_to;
3702                                         psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3703                                 }
3704
3705                                 //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
3706                                 break;
3707
3708                         case RTW_WLAN_ACTION_DELBA: //DELBA
3709                                 if ((frame_body[3] & BIT(3)) == 0)
3710                                 {
3711                                         psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3712                                         psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3713                                         
3714                                         //reason_code = frame_body[4] | (frame_body[5] << 8);
3715                                         reason_code = RTW_GET_LE16(&frame_body[4]);
3716                                 }
3717                                 else if((frame_body[3] & BIT(3)) == BIT(3))
3718                                 {                                               
3719                                         tid = (frame_body[3] >> 4) & 0x0F;
3720                                 
3721                                         preorder_ctrl = &psta->recvreorder_ctrl[tid];
3722                                         preorder_ctrl->enable = _FALSE;
3723                                         preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3724                                 }
3725                                 
3726                                 DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
3727                                 //todo: how to notify the host while receiving DELETE BA
3728                                 break;
3729
3730                         default:
3731                                 break;
3732                 }
3733         }
3734 #endif //CONFIG_80211N_HT
3735         return _SUCCESS;
3736 }
3737
3738 #ifdef CONFIG_P2P
3739
3740 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
3741         int cnt = 0;
3742         int i;
3743
3744         for (i = 0; i < channel_list.reg_classes; i++) {
3745                 cnt += channel_list.reg_class[i].channels;
3746         }
3747
3748         return cnt;
3749 }
3750
3751 static void get_channel_cnt_24g_5gl_5gh(  struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
3752 {
3753         int     i = 0;
3754
3755         *p24g_cnt = 0;
3756         *p5gl_cnt = 0;
3757         *p5gh_cnt = 0;  
3758         
3759         for( i = 0; i < pmlmeext->max_chan_nums; i++ )
3760         {
3761                 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
3762                 {
3763                         (*p24g_cnt)++;
3764                 }
3765                 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
3766                 {
3767                         //      Just include the channel 36, 40, 44, 48 channels for 5G low
3768                         (*p5gl_cnt)++;
3769                 }
3770                 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
3771                 {
3772                         //      Just include the channel 149, 153, 157, 161 channels for 5G high
3773                         (*p5gh_cnt)++;
3774                 }
3775         }
3776 }
3777
3778 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
3779 {
3780
3781         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3782         u8                      action = P2P_PUB_ACTION_ACTION;
3783         u32                     p2poui = cpu_to_be32(P2POUI);
3784         u8                      oui_subtype = P2P_GO_NEGO_REQ;
3785         u8                      wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3786         u8                      wpsielen = 0, p2pielen = 0, i;
3787         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3788         u16                     len_channellist_attr = 0;
3789 #ifdef CONFIG_WFD
3790         u32                                     wfdielen = 0;
3791 #endif
3792         
3793         struct xmit_frame                       *pmgntframe;
3794         struct pkt_attrib                       *pattrib;
3795         unsigned char                                   *pframe;
3796         struct rtw_ieee80211_hdr        *pwlanhdr;
3797         unsigned short                          *fctrl;
3798         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
3799         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3800         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3801         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
3802
3803
3804         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3805         {
3806                 return;
3807         }
3808
3809         DBG_871X( "[%s] In\n", __FUNCTION__ );
3810         //update attribute
3811         pattrib = &pmgntframe->attrib;
3812         update_mgntframe_attrib(padapter, pattrib);
3813
3814         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3815
3816         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3817         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3818
3819         fctrl = &(pwlanhdr->frame_ctl);
3820         *(fctrl) = 0;
3821
3822         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3823         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3824         _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3825
3826         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3827         pmlmeext->mgnt_seq++;
3828         SetFrameSubType(pframe, WIFI_ACTION);
3829
3830         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3831         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3832
3833         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3834         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3835         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3836         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
3837         pwdinfo->negotiation_dialog_token = 1;  //      Initialize the dialog value
3838         pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3839
3840         
3841
3842         //      WPS Section
3843         wpsielen = 0;
3844         //      WPS OUI
3845         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3846         wpsielen += 4;
3847
3848         //      WPS version
3849         //      Type:
3850         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3851         wpsielen += 2;
3852
3853         //      Length:
3854         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3855         wpsielen += 2;
3856
3857         //      Value:
3858         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
3859
3860         //      Device Password ID
3861         //      Type:
3862         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3863         wpsielen += 2;
3864
3865         //      Length:
3866         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3867         wpsielen += 2;
3868
3869         //      Value:
3870
3871         if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
3872         {
3873                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3874         }
3875         else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
3876         {
3877                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3878         }
3879         else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
3880         {
3881                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3882         }
3883
3884         wpsielen += 2;
3885
3886         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3887
3888
3889         //      P2P IE Section.
3890
3891         //      P2P OUI
3892         p2pielen = 0;
3893         p2pie[ p2pielen++ ] = 0x50;
3894         p2pie[ p2pielen++ ] = 0x6F;
3895         p2pie[ p2pielen++ ] = 0x9A;
3896         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
3897
3898         //      Commented by Albert 20110306
3899         //      According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
3900         //      1. P2P Capability
3901         //      2. Group Owner Intent
3902         //      3. Configuration Timeout
3903         //      4. Listen Channel
3904         //      5. Extended Listen Timing
3905         //      6. Intended P2P Interface Address
3906         //      7. Channel List
3907         //      8. P2P Device Info
3908         //      9. Operating Channel
3909
3910
3911         //      P2P Capability
3912         //      Type:
3913         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3914
3915         //      Length:
3916         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3917         p2pielen += 2;
3918
3919         //      Value:
3920         //      Device Capability Bitmap, 1 byte
3921         p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3922
3923         //      Group Capability Bitmap, 1 byte
3924         if ( pwdinfo->persistent_supported )
3925         {
3926                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3927         }
3928         else
3929         {
3930                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3931         }
3932
3933
3934         //      Group Owner Intent
3935         //      Type:
3936         p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3937
3938         //      Length:
3939         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3940         p2pielen += 2;
3941
3942         //      Value:
3943         //      Todo the tie breaker bit.
3944         p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) &  0xFE );
3945
3946         //      Configuration Timeout
3947         //      Type:
3948         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3949
3950         //      Length:
3951         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3952         p2pielen += 2;
3953
3954         //      Value:
3955         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
3956         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
3957
3958
3959         //      Listen Channel
3960         //      Type:
3961         p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
3962
3963         //      Length:
3964         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3965         p2pielen += 2;
3966
3967         //      Value:
3968         //      Country String
3969         p2pie[ p2pielen++ ] = 'X';
3970         p2pie[ p2pielen++ ] = 'X';
3971         
3972         //      The third byte should be set to 0x04.
3973         //      Described in the "Operating Channel Attribute" section.
3974         p2pie[ p2pielen++ ] = 0x04;
3975
3976         //      Operating Class
3977         p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
3978         
3979         //      Channel Number
3980         p2pie[ p2pielen++ ] = pwdinfo->listen_channel;  //      listening channel number
3981         
3982
3983         //      Extended Listen Timing ATTR
3984         //      Type:
3985         p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
3986
3987         //      Length:
3988         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
3989         p2pielen += 2;
3990
3991         //      Value:
3992         //      Availability Period
3993         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3994         p2pielen += 2;
3995
3996         //      Availability Interval
3997         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3998         p2pielen += 2;
3999
4000
4001         //      Intended P2P Interface Address
4002         //      Type:
4003         p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4004
4005         //      Length:
4006         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4007         p2pielen += 2;
4008
4009         //      Value:
4010         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4011         p2pielen += ETH_ALEN;
4012
4013
4014         //      Channel List
4015         //      Type:
4016         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4017
4018         // Length:
4019         // Country String(3)
4020         // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4021         // + number of channels in all classes
4022         len_channellist_attr = 3
4023            + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
4024            + get_reg_classes_full_count(pmlmeext->channel_list);
4025
4026 #ifdef CONFIG_CONCURRENT_MODE
4027         if (check_buddy_fwstate(padapter , _FW_LINKED)
4028                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4029         {
4030                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4031         }
4032         else
4033         {
4034                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4035         }
4036 #else
4037
4038         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4039
4040 #endif
4041         p2pielen += 2;
4042
4043         //      Value:
4044         //      Country String
4045         p2pie[ p2pielen++ ] = 'X';
4046         p2pie[ p2pielen++ ] = 'X';
4047         
4048         //      The third byte should be set to 0x04.
4049         //      Described in the "Operating Channel Attribute" section.
4050         p2pie[ p2pielen++ ] = 0x04;
4051
4052         //      Channel Entry List
4053
4054 #ifdef CONFIG_CONCURRENT_MODE
4055         if (check_buddy_fwstate(padapter , _FW_LINKED)
4056                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4057         {
4058                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
4059                 struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4060
4061                 //      Operating Class
4062                 if ( pbuddy_mlmeext->cur_channel > 14 )
4063                 {
4064                         if ( pbuddy_mlmeext->cur_channel >= 149 )
4065                         {
4066                                 p2pie[ p2pielen++ ] = 0x7c;
4067                         }
4068                         else
4069                         {
4070                                 p2pie[ p2pielen++ ] = 0x73;
4071                         }
4072                 }
4073                 else
4074                 {
4075                         p2pie[ p2pielen++ ] = 0x51;
4076                 }
4077
4078                 //      Number of Channels
4079                 //      Just support 1 channel and this channel is AP's channel
4080                 p2pie[ p2pielen++ ] = 1;
4081
4082                 //      Channel List
4083                 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4084         }
4085         else
4086         {
4087                 int i,j;
4088                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4089                         //      Operating Class
4090                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4091
4092                         //      Number of Channels
4093                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4094
4095                         //      Channel List
4096                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4097                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4098                         }
4099                 }
4100         }
4101 #else // CONFIG_CONCURRENT_MODE
4102         {
4103                 int i,j;
4104                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4105                         //      Operating Class
4106                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4107
4108                         //      Number of Channels
4109                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4110
4111                         //      Channel List
4112                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4113                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4114                         }
4115                 }
4116         }
4117 #endif // CONFIG_CONCURRENT_MODE
4118
4119         //      Device Info
4120         //      Type:
4121         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4122
4123         //      Length:
4124         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
4125         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4126         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4127         p2pielen += 2;
4128
4129         //      Value:
4130         //      P2P Device Address
4131         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4132         p2pielen += ETH_ALEN;
4133
4134         //      Config Method
4135         //      This field should be big endian. Noted by P2P specification.
4136
4137         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4138
4139         p2pielen += 2;
4140
4141         //      Primary Device Type
4142         //      Category ID
4143         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4144         p2pielen += 2;
4145
4146         //      OUI
4147         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4148         p2pielen += 4;
4149
4150         //      Sub Category ID
4151         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4152         p2pielen += 2;
4153
4154         //      Number of Secondary Device Types
4155         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
4156
4157         //      Device Name
4158         //      Type:
4159         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4160         p2pielen += 2;
4161
4162         //      Length:
4163         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4164         p2pielen += 2;
4165
4166         //      Value:
4167         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4168         p2pielen += pwdinfo->device_name_len;   
4169         
4170
4171         //      Operating Channel
4172         //      Type:
4173         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4174
4175         //      Length:
4176         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4177         p2pielen += 2;
4178
4179         //      Value:
4180         //      Country String
4181         p2pie[ p2pielen++ ] = 'X';
4182         p2pie[ p2pielen++ ] = 'X';
4183         
4184         //      The third byte should be set to 0x04.
4185         //      Described in the "Operating Channel Attribute" section.
4186         p2pie[ p2pielen++ ] = 0x04;
4187
4188         //      Operating Class
4189         if ( pwdinfo->operating_channel <= 14 )
4190         {
4191                 //      Operating Class
4192                 p2pie[ p2pielen++ ] = 0x51;
4193         }
4194         else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4195         {
4196                 //      Operating Class
4197                 p2pie[ p2pielen++ ] = 0x73;
4198         }
4199         else
4200         {
4201                 //      Operating Class
4202                 p2pie[ p2pielen++ ] = 0x7c;
4203         }
4204
4205         //      Channel Number
4206         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
4207
4208         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );                
4209
4210 #ifdef CONFIG_WFD
4211         wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4212         pframe += wfdielen;
4213         pattrib->pktlen += wfdielen;
4214 #endif
4215
4216         pattrib->last_txcmdsz = pattrib->pktlen;
4217
4218         dump_mgntframe(padapter, pmgntframe);
4219
4220         return;
4221
4222 }
4223
4224
4225 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
4226 {
4227
4228         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4229         u8                      action = P2P_PUB_ACTION_ACTION;
4230         u32                     p2poui = cpu_to_be32(P2POUI);
4231         u8                      oui_subtype = P2P_GO_NEGO_RESP;
4232         u8                      wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4233         u8                      p2pielen = 0, i;
4234         uint                    wpsielen = 0;
4235         u16                     wps_devicepassword_id = 0x0000;
4236         uint                    wps_devicepassword_id_len = 0;
4237         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4238         u16                     len_channellist_attr = 0;
4239         
4240         struct xmit_frame                       *pmgntframe;
4241         struct pkt_attrib                       *pattrib;
4242         unsigned char                                   *pframe;
4243         struct rtw_ieee80211_hdr        *pwlanhdr;
4244         unsigned short                          *fctrl;
4245         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
4246         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4247         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4248         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
4249
4250 #ifdef CONFIG_WFD
4251         u32                                     wfdielen = 0;
4252 #endif
4253
4254         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4255         {
4256                 return;
4257         }
4258
4259         DBG_871X( "[%s] In, result = %d\n", __FUNCTION__,  result );
4260         //update attribute
4261         pattrib = &pmgntframe->attrib;
4262         update_mgntframe_attrib(padapter, pattrib);
4263
4264         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4265
4266         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4267         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4268
4269         fctrl = &(pwlanhdr->frame_ctl);
4270         *(fctrl) = 0;
4271
4272         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4273         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4274         _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4275
4276         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4277         pmlmeext->mgnt_seq++;
4278         SetFrameSubType(pframe, WIFI_ACTION);
4279
4280         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4281         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4282
4283         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4284         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4285         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4286         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
4287         pwdinfo->negotiation_dialog_token = frame_body[7];      //      The Dialog Token of provisioning discovery request frame.
4288         pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4289
4290         //      Commented by Albert 20110328
4291         //      Try to get the device password ID from the WPS IE of group negotiation request frame
4292         //      WiFi Direct test plan 5.1.15
4293         rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4294         rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4295         wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4296
4297         _rtw_memset( wpsie, 0x00, 255 );
4298         wpsielen = 0;
4299
4300         //      WPS Section
4301         wpsielen = 0;
4302         //      WPS OUI
4303         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4304         wpsielen += 4;
4305
4306         //      WPS version
4307         //      Type:
4308         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4309         wpsielen += 2;
4310
4311         //      Length:
4312         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4313         wpsielen += 2;
4314
4315         //      Value:
4316         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
4317
4318         //      Device Password ID
4319         //      Type:
4320         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4321         wpsielen += 2;
4322
4323         //      Length:
4324         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4325         wpsielen += 2;
4326
4327         //      Value:
4328         if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4329         {
4330                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
4331         }
4332         else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4333         {
4334                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
4335         }
4336         else
4337         {
4338                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
4339         }
4340         wpsielen += 2;
4341
4342         //      Commented by Kurt 20120113
4343         //      If some device wants to do p2p handshake without sending prov_disc_req
4344         //      We have to get peer_req_cm from here.
4345         if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
4346         {
4347                 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4348                 {
4349                         _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
4350                 }
4351                 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4352                 {
4353                         _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );     
4354                 }
4355                 else
4356                 {
4357                         _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );     
4358                 }
4359         }
4360
4361         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4362
4363
4364         //      P2P IE Section.
4365
4366         //      P2P OUI
4367         p2pielen = 0;
4368         p2pie[ p2pielen++ ] = 0x50;
4369         p2pie[ p2pielen++ ] = 0x6F;
4370         p2pie[ p2pielen++ ] = 0x9A;
4371         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
4372
4373         //      Commented by Albert 20100908
4374         //      According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
4375         //      1. Status
4376         //      2. P2P Capability
4377         //      3. Group Owner Intent
4378         //      4. Configuration Timeout
4379         //      5. Operating Channel
4380         //      6. Intended P2P Interface Address
4381         //      7. Channel List
4382         //      8. Device Info
4383         //      9. Group ID     ( Only GO )
4384
4385
4386         //      ToDo:
4387
4388         //      P2P Status
4389         //      Type:
4390         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4391
4392         //      Length:
4393         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4394         p2pielen += 2;
4395
4396         //      Value:
4397         p2pie[ p2pielen++ ] = result;
4398         
4399         //      P2P Capability
4400         //      Type:
4401         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4402
4403         //      Length:
4404         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4405         p2pielen += 2;
4406
4407         //      Value:
4408         //      Device Capability Bitmap, 1 byte
4409
4410         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4411         {
4412                 //      Commented by Albert 2011/03/08
4413                 //      According to the P2P specification
4414                 //      if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
4415                 p2pie[ p2pielen++ ] = 0;
4416         }
4417         else
4418         {
4419                 //      Be group owner or meet the error case
4420                 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4421         }
4422         
4423         //      Group Capability Bitmap, 1 byte
4424         if ( pwdinfo->persistent_supported )
4425         {
4426                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4427         }
4428         else
4429         {
4430                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4431         }
4432
4433         //      Group Owner Intent
4434         //      Type:
4435         p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
4436
4437         //      Length:
4438         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4439         p2pielen += 2;
4440
4441         //      Value:
4442         if ( pwdinfo->peer_intent & 0x01 )
4443         {
4444                 //      Peer's tie breaker bit is 1, our tie breaker bit should be 0
4445                 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
4446         }
4447         else
4448         {
4449                 //      Peer's tie breaker bit is 0, our tie breaker bit should be 1
4450                 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
4451         }
4452
4453
4454         //      Configuration Timeout
4455         //      Type:
4456         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4457
4458         //      Length:
4459         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4460         p2pielen += 2;
4461
4462         //      Value:
4463         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
4464         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
4465
4466         //      Operating Channel
4467         //      Type:
4468         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4469
4470         //      Length:
4471         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4472         p2pielen += 2;
4473
4474         //      Value:
4475         //      Country String
4476         p2pie[ p2pielen++ ] = 'X';
4477         p2pie[ p2pielen++ ] = 'X';
4478         
4479         //      The third byte should be set to 0x04.
4480         //      Described in the "Operating Channel Attribute" section.
4481         p2pie[ p2pielen++ ] = 0x04;
4482
4483         //      Operating Class
4484         if ( pwdinfo->operating_channel <= 14 )
4485         {
4486                 //      Operating Class
4487                 p2pie[ p2pielen++ ] = 0x51;
4488         }
4489         else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4490         {
4491                 //      Operating Class
4492                 p2pie[ p2pielen++ ] = 0x73;
4493         }
4494         else
4495         {
4496                 //      Operating Class
4497                 p2pie[ p2pielen++ ] = 0x7c;
4498         }
4499         
4500         //      Channel Number
4501         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
4502
4503         //      Intended P2P Interface Address  
4504         //      Type:
4505         p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4506
4507         //      Length:
4508         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4509         p2pielen += 2;
4510
4511         //      Value:
4512         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4513         p2pielen += ETH_ALEN;
4514
4515         //      Channel List
4516         //      Type:
4517         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4518
4519         // Country String(3)
4520         // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4521         // + number of channels in all classes
4522         len_channellist_attr = 3
4523            + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4524            + get_reg_classes_full_count(pmlmeext->channel_list);
4525
4526 #ifdef CONFIG_CONCURRENT_MODE
4527         if (check_buddy_fwstate(padapter , _FW_LINKED)
4528                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4529         {
4530                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4531         }
4532         else
4533         {
4534                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4535         }
4536 #else
4537
4538         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4539
4540  #endif
4541         p2pielen += 2;
4542
4543         //      Value:
4544         //      Country String
4545         p2pie[ p2pielen++ ] = 'X';
4546         p2pie[ p2pielen++ ] = 'X';
4547         
4548         //      The third byte should be set to 0x04.
4549         //      Described in the "Operating Channel Attribute" section.
4550         p2pie[ p2pielen++ ] = 0x04;
4551
4552         //      Channel Entry List
4553
4554 #ifdef CONFIG_CONCURRENT_MODE
4555         if (check_buddy_fwstate(padapter , _FW_LINKED)
4556                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4557         {
4558                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
4559                 struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4560
4561                 //      Operating Class
4562                 if ( pbuddy_mlmeext->cur_channel > 14 )
4563                 {
4564                         if ( pbuddy_mlmeext->cur_channel >= 149 )
4565                         {
4566                                 p2pie[ p2pielen++ ] = 0x7c;
4567                         }
4568                         else
4569                         {
4570                                 p2pie[ p2pielen++ ] = 0x73;
4571                         }
4572                 }
4573                 else
4574                 {
4575                         p2pie[ p2pielen++ ] = 0x51;
4576                 }
4577
4578                 //      Number of Channels
4579                 //      Just support 1 channel and this channel is AP's channel
4580                 p2pie[ p2pielen++ ] = 1;
4581
4582                 //      Channel List
4583                 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4584         }
4585         else
4586         {
4587                 int i, j;
4588                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4589                         //      Operating Class
4590                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4591
4592                         //      Number of Channels
4593                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4594
4595                         //      Channel List
4596                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4597                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4598                         }
4599                 }
4600         }
4601 #else // CONFIG_CONCURRENT_MODE
4602         {
4603                 int i, j;
4604                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4605                         //      Operating Class
4606                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4607
4608                         //      Number of Channels
4609                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4610
4611                         //      Channel List
4612                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4613                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4614                         }
4615                 }
4616         }
4617 #endif // CONFIG_CONCURRENT_MODE
4618
4619         
4620         //      Device Info
4621         //      Type:
4622         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4623
4624         //      Length:
4625         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
4626         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4627         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4628         p2pielen += 2;
4629
4630         //      Value:
4631         //      P2P Device Address
4632         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4633         p2pielen += ETH_ALEN;
4634
4635         //      Config Method
4636         //      This field should be big endian. Noted by P2P specification.
4637
4638         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4639
4640         p2pielen += 2;
4641
4642         //      Primary Device Type
4643         //      Category ID
4644         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4645         p2pielen += 2;
4646
4647         //      OUI
4648         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4649         p2pielen += 4;
4650
4651         //      Sub Category ID
4652         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4653         p2pielen += 2;
4654
4655         //      Number of Secondary Device Types
4656         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
4657
4658         //      Device Name
4659         //      Type:
4660         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4661         p2pielen += 2;
4662
4663         //      Length:
4664         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4665         p2pielen += 2;
4666
4667         //      Value:
4668         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4669         p2pielen += pwdinfo->device_name_len;   
4670         
4671         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4672         {
4673                 //      Group ID Attribute
4674                 //      Type:
4675                 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4676
4677                 //      Length:
4678                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4679                 p2pielen += 2;
4680
4681                 //      Value:
4682                 //      p2P Device Address
4683                 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4684                 p2pielen += ETH_ALEN;
4685
4686                 //      SSID
4687                 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4688                 p2pielen += pwdinfo->nego_ssidlen;
4689                 
4690         }
4691         
4692         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
4693         
4694 #ifdef CONFIG_WFD
4695         wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4696         pframe += wfdielen;
4697         pattrib->pktlen += wfdielen;
4698 #endif
4699
4700         pattrib->last_txcmdsz = pattrib->pktlen;
4701
4702         dump_mgntframe(padapter, pmgntframe);
4703
4704         return;
4705
4706 }
4707
4708 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
4709 {
4710
4711         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4712         u8                      action = P2P_PUB_ACTION_ACTION;
4713         u32                     p2poui = cpu_to_be32(P2POUI);
4714         u8                      oui_subtype = P2P_GO_NEGO_CONF;
4715         u8                      wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4716         u8                      wpsielen = 0, p2pielen = 0;
4717         
4718         struct xmit_frame                       *pmgntframe;
4719         struct pkt_attrib                       *pattrib;
4720         unsigned char                                   *pframe;
4721         struct rtw_ieee80211_hdr        *pwlanhdr;
4722         unsigned short                          *fctrl;
4723         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
4724         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4725         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4726         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
4727 #ifdef CONFIG_WFD
4728         u32                                     wfdielen = 0;
4729 #endif
4730
4731         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4732         {
4733                 return;
4734         }
4735
4736         DBG_871X( "[%s] In\n", __FUNCTION__ );
4737         //update attribute
4738         pattrib = &pmgntframe->attrib;
4739         update_mgntframe_attrib(padapter, pattrib);
4740
4741         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4742
4743         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4744         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4745
4746         fctrl = &(pwlanhdr->frame_ctl);
4747         *(fctrl) = 0;
4748
4749         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4750         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4751         _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4752
4753         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4754         pmlmeext->mgnt_seq++;
4755         SetFrameSubType(pframe, WIFI_ACTION);
4756
4757         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4758         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4759
4760         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4761         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4762         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4763         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
4764         pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4765
4766         
4767
4768         //      P2P IE Section.
4769
4770         //      P2P OUI
4771         p2pielen = 0;
4772         p2pie[ p2pielen++ ] = 0x50;
4773         p2pie[ p2pielen++ ] = 0x6F;
4774         p2pie[ p2pielen++ ] = 0x9A;
4775         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
4776
4777         //      Commented by Albert 20110306
4778         //      According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
4779         //      1. Status
4780         //      2. P2P Capability
4781         //      3. Operating Channel
4782         //      4. Channel List
4783         //      5. Group ID     ( if this WiFi is GO )
4784
4785         //      P2P Status
4786         //      Type:
4787         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4788
4789         //      Length:
4790         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4791         p2pielen += 2;
4792
4793         //      Value:
4794         p2pie[ p2pielen++ ] = result;
4795
4796         //      P2P Capability
4797         //      Type:
4798         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4799
4800         //      Length:
4801         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4802         p2pielen += 2;
4803
4804         //      Value:
4805         //      Device Capability Bitmap, 1 byte
4806         p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4807         
4808         //      Group Capability Bitmap, 1 byte
4809         if ( pwdinfo->persistent_supported )
4810         {
4811                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4812         }
4813         else
4814         {
4815                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4816         }
4817
4818
4819         //      Operating Channel
4820         //      Type:
4821         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4822
4823         //      Length:
4824         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4825         p2pielen += 2;
4826
4827         //      Value:
4828         //      Country String
4829         p2pie[ p2pielen++ ] = 'X';
4830         p2pie[ p2pielen++ ] = 'X';
4831         
4832         //      The third byte should be set to 0x04.
4833         //      Described in the "Operating Channel Attribute" section.
4834         p2pie[ p2pielen++ ] = 0x04;
4835
4836
4837         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4838         {
4839                 if ( pwdinfo->peer_operating_ch <= 14 )
4840                 {
4841                         //      Operating Class
4842                         p2pie[ p2pielen++ ] = 0x51;
4843                 }
4844                 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4845                 {
4846                         //      Operating Class
4847                         p2pie[ p2pielen++ ] = 0x73;
4848                 }
4849                 else
4850                 {
4851                         //      Operating Class
4852                         p2pie[ p2pielen++ ] = 0x7c;
4853                 }
4854                 
4855                 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4856         }
4857         else
4858         {
4859                 if ( pwdinfo->operating_channel <= 14 )
4860                 {
4861                         //      Operating Class
4862                         p2pie[ p2pielen++ ] = 0x51;
4863                 }
4864                 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4865                 {
4866                         //      Operating Class
4867                         p2pie[ p2pielen++ ] = 0x73;
4868                 }
4869                 else
4870                 {
4871                         //      Operating Class
4872                         p2pie[ p2pielen++ ] = 0x7c;
4873                 }
4874                 
4875                 //      Channel Number
4876                 p2pie[ p2pielen++ ] = pwdinfo->operating_channel;               //      Use the listen channel as the operating channel
4877         }
4878
4879
4880         //      Channel List
4881         //      Type:
4882         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4883
4884         *(u16*) ( p2pie + p2pielen ) = 6;
4885         p2pielen += 2;
4886
4887         //      Country String
4888         p2pie[ p2pielen++ ] = 'X';
4889         p2pie[ p2pielen++ ] = 'X';
4890         
4891         //      The third byte should be set to 0x04.
4892         //      Described in the "Operating Channel Attribute" section.
4893         p2pie[ p2pielen++ ] = 0x04;
4894
4895         //      Value:
4896         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4897         {
4898                 if ( pwdinfo->peer_operating_ch <= 14 )
4899                 {
4900                         //      Operating Class
4901                         p2pie[ p2pielen++ ] = 0x51;
4902                 }
4903                 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4904                 {
4905                         //      Operating Class
4906                         p2pie[ p2pielen++ ] = 0x73;
4907                 }
4908                 else
4909                 {
4910                         //      Operating Class
4911                         p2pie[ p2pielen++ ] = 0x7c;
4912                 }
4913                 p2pie[ p2pielen++ ] = 1;
4914                 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4915         }
4916         else
4917         {
4918                 if ( pwdinfo->operating_channel <= 14 )
4919                 {
4920                         //      Operating Class
4921                         p2pie[ p2pielen++ ] = 0x51;
4922                 }
4923                 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4924                 {
4925                         //      Operating Class
4926                         p2pie[ p2pielen++ ] = 0x73;
4927                 }
4928                 else
4929                 {
4930                         //      Operating Class
4931                         p2pie[ p2pielen++ ] = 0x7c;
4932                 }
4933                 
4934                 //      Channel Number
4935                 p2pie[ p2pielen++ ] = 1;
4936                 p2pie[ p2pielen++ ] = pwdinfo->operating_channel;               //      Use the listen channel as the operating channel
4937         }
4938
4939         if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4940         {
4941                 //      Group ID Attribute
4942                 //      Type:
4943                 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4944
4945                 //      Length:
4946                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4947                 p2pielen += 2;
4948
4949                 //      Value:
4950                 //      p2P Device Address
4951                 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4952                 p2pielen += ETH_ALEN;
4953
4954                 //      SSID
4955                 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4956                 p2pielen += pwdinfo->nego_ssidlen;
4957         }
4958         
4959         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4960         
4961 #ifdef CONFIG_WFD
4962         wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4963         pframe += wfdielen;
4964         pattrib->pktlen += wfdielen;
4965 #endif
4966
4967         pattrib->last_txcmdsz = pattrib->pktlen;
4968
4969         dump_mgntframe(padapter, pmgntframe);
4970
4971         return;
4972
4973 }
4974
4975 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
4976 {
4977
4978         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4979         u8                      action = P2P_PUB_ACTION_ACTION;
4980         u32                     p2poui = cpu_to_be32(P2POUI);
4981         u8                      oui_subtype = P2P_INVIT_REQ;
4982         u8                      p2pie[ 255 ] = { 0x00 };
4983         u8                      p2pielen = 0, i;
4984         u8                      dialogToken = 3;
4985         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4986         u16                     len_channellist_attr = 0;       
4987 #ifdef CONFIG_WFD
4988         u32                                     wfdielen = 0;
4989 #endif
4990 #ifdef CONFIG_CONCURRENT_MODE
4991         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
4992         struct wifidirect_info  *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4993         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4994         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4995 #endif
4996
4997         struct xmit_frame                       *pmgntframe;
4998         struct pkt_attrib                       *pattrib;
4999         unsigned char                                   *pframe;
5000         struct rtw_ieee80211_hdr        *pwlanhdr;
5001         unsigned short                          *fctrl;
5002         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
5003         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5004         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5005         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
5006
5007
5008         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5009         {
5010                 return;
5011         }
5012
5013         //update attribute
5014         pattrib = &pmgntframe->attrib;
5015         update_mgntframe_attrib(padapter, pattrib);
5016
5017         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5018
5019         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5020         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5021
5022         fctrl = &(pwlanhdr->frame_ctl);
5023         *(fctrl) = 0;
5024
5025         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5026         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5027         _rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
5028
5029         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5030         pmlmeext->mgnt_seq++;
5031         SetFrameSubType(pframe, WIFI_ACTION);
5032
5033         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5034         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5035
5036         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5037         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5038         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5039         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
5040         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5041
5042         //      P2P IE Section.
5043
5044         //      P2P OUI
5045         p2pielen = 0;
5046         p2pie[ p2pielen++ ] = 0x50;
5047         p2pie[ p2pielen++ ] = 0x6F;
5048         p2pie[ p2pielen++ ] = 0x9A;
5049         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
5050
5051         //      Commented by Albert 20101011
5052         //      According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
5053         //      1. Configuration Timeout
5054         //      2. Invitation Flags
5055         //      3. Operating Channel    ( Only GO )
5056         //      4. P2P Group BSSID      ( Should be included if I am the GO )
5057         //      5. Channel List
5058         //      6. P2P Group ID
5059         //      7. P2P Device Info
5060
5061         //      Configuration Timeout
5062         //      Type:
5063         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5064
5065         //      Length:
5066         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5067         p2pielen += 2;
5068
5069         //      Value:
5070         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
5071         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
5072
5073         //      Invitation Flags
5074         //      Type:
5075         p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
5076
5077         //      Length:
5078         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5079         p2pielen += 2;
5080
5081         //      Value:
5082         p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
5083
5084
5085         //      Operating Channel
5086         //      Type:
5087         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5088
5089         //      Length:
5090         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5091         p2pielen += 2;
5092
5093         //      Value:
5094         //      Country String
5095         p2pie[ p2pielen++ ] = 'X';
5096         p2pie[ p2pielen++ ] = 'X';
5097         
5098         //      The third byte should be set to 0x04.
5099         //      Described in the "Operating Channel Attribute" section.
5100         p2pie[ p2pielen++ ] = 0x04;
5101
5102         //      Operating Class
5103         if ( pwdinfo->invitereq_info.operating_ch <= 14 )
5104                 p2pie[ p2pielen++ ] = 0x51;
5105         else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
5106                 p2pie[ p2pielen++ ] = 0x73;
5107         else
5108                 p2pie[ p2pielen++ ] = 0x7c;
5109         
5110         //      Channel Number
5111         p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch;     //      operating channel number
5112
5113         if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
5114         {
5115                 //      P2P Group BSSID
5116                 //      Type:
5117                 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5118
5119                 //      Length:
5120                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5121                 p2pielen += 2;
5122
5123                 //      Value:
5124                 //      P2P Device Address for GO
5125                 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5126                 p2pielen += ETH_ALEN;
5127         }
5128
5129         //      Channel List
5130         //      Type:
5131         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5132
5133         
5134         //      Length:
5135         // Country String(3)
5136         // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5137         // + number of channels in all classes
5138         len_channellist_attr = 3
5139            + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5140            + get_reg_classes_full_count(pmlmeext->channel_list);
5141
5142 #ifdef CONFIG_CONCURRENT_MODE
5143         if (check_buddy_fwstate(padapter , _FW_LINKED)
5144                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5145         {
5146                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5147         }
5148         else
5149         {
5150                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5151         }
5152 #else
5153
5154         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5155
5156  #endif
5157         p2pielen += 2;
5158
5159         //      Value:
5160         //      Country String
5161         p2pie[ p2pielen++ ] = 'X';
5162         p2pie[ p2pielen++ ] = 'X';
5163         
5164         //      The third byte should be set to 0x04.
5165         //      Described in the "Operating Channel Attribute" section.
5166         p2pie[ p2pielen++ ] = 0x04;
5167
5168         //      Channel Entry List
5169 #ifdef CONFIG_CONCURRENT_MODE
5170         if (check_buddy_fwstate(padapter, _FW_LINKED)
5171                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5172         {
5173                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
5174                 struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5175
5176                 //      Operating Class
5177                 if ( pbuddy_mlmeext->cur_channel > 14 )
5178                 {
5179                         if ( pbuddy_mlmeext->cur_channel >= 149 )
5180                         {
5181                                 p2pie[ p2pielen++ ] = 0x7c;
5182                         }
5183                         else
5184                         {
5185                                 p2pie[ p2pielen++ ] = 0x73;
5186                         }
5187                 }
5188                 else
5189                 {
5190                         p2pie[ p2pielen++ ] = 0x51;
5191                 }
5192
5193                 //      Number of Channels
5194                 //      Just support 1 channel and this channel is AP's channel
5195                 p2pie[ p2pielen++ ] = 1;
5196
5197                 //      Channel List
5198                 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5199         }
5200         else
5201         {
5202                 int i, j;
5203                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5204                         //      Operating Class
5205                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5206
5207                         //      Number of Channels
5208                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5209
5210                         //      Channel List
5211                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5212                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5213                         }
5214                 }
5215         }
5216 #else // CONFIG_CONCURRENT_MODE
5217         {
5218                 int i, j;
5219                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5220                         //      Operating Class
5221                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5222
5223                         //      Number of Channels
5224                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5225
5226                         //      Channel List
5227                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5228                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5229                         }
5230                 }
5231         }
5232 #endif // CONFIG_CONCURRENT_MODE
5233
5234
5235         //      P2P Group ID
5236         //      Type:
5237         p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
5238
5239         //      Length:
5240         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
5241         p2pielen += 2;
5242
5243         //      Value:
5244         //      P2P Device Address for GO
5245         _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5246         p2pielen += ETH_ALEN;
5247
5248         //      SSID
5249         _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
5250         p2pielen += pwdinfo->invitereq_info.ssidlen;
5251         
5252
5253         //      Device Info
5254         //      Type:
5255         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
5256
5257         //      Length:
5258         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
5259         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
5260         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
5261         p2pielen += 2;
5262         
5263         //      Value:
5264         //      P2P Device Address
5265         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5266         p2pielen += ETH_ALEN;
5267
5268         //      Config Method
5269         //      This field should be big endian. Noted by P2P specification.
5270         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
5271         p2pielen += 2;
5272
5273         //      Primary Device Type
5274         //      Category ID
5275         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5276         p2pielen += 2;
5277
5278         //      OUI
5279         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
5280         p2pielen += 4;
5281
5282         //      Sub Category ID
5283         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5284         p2pielen += 2;
5285
5286         //      Number of Secondary Device Types
5287         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
5288
5289         //      Device Name
5290         //      Type:
5291         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5292         p2pielen += 2;
5293
5294         //      Length:
5295         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
5296         p2pielen += 2;
5297
5298         //      Value:
5299         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
5300         p2pielen += pwdinfo->device_name_len;
5301                 
5302         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
5303
5304 #ifdef CONFIG_WFD
5305         wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5306         pframe += wfdielen;
5307         pattrib->pktlen += wfdielen;
5308 #endif
5309
5310         pattrib->last_txcmdsz = pattrib->pktlen;
5311
5312         dump_mgntframe(padapter, pmgntframe);
5313
5314         return;
5315
5316 }
5317
5318 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
5319 {
5320
5321         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5322         u8                      action = P2P_PUB_ACTION_ACTION;
5323         u32                     p2poui = cpu_to_be32(P2POUI);
5324         u8                      oui_subtype = P2P_INVIT_RESP;
5325         u8                      p2pie[ 255 ] = { 0x00 };
5326         u8                      p2pielen = 0, i;
5327         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5328         u16                     len_channellist_attr = 0;
5329 #ifdef CONFIG_CONCURRENT_MODE
5330         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
5331         struct wifidirect_info  *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5332         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5333         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5334 #endif  
5335 #ifdef CONFIG_WFD
5336         u32                                     wfdielen = 0;
5337 #endif
5338         
5339         struct xmit_frame                       *pmgntframe;
5340         struct pkt_attrib                       *pattrib;
5341         unsigned char                                   *pframe;
5342         struct rtw_ieee80211_hdr        *pwlanhdr;
5343         unsigned short                          *fctrl;
5344         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
5345         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5346         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5347         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
5348
5349
5350         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5351         {
5352                 return;
5353         }
5354
5355         //update attribute
5356         pattrib = &pmgntframe->attrib;
5357         update_mgntframe_attrib(padapter, pattrib);
5358
5359         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5360
5361         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5362         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5363
5364         fctrl = &(pwlanhdr->frame_ctl);
5365         *(fctrl) = 0;
5366
5367         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5368         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5369         _rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
5370
5371         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5372         pmlmeext->mgnt_seq++;
5373         SetFrameSubType(pframe, WIFI_ACTION);
5374
5375         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5376         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5377
5378         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5379         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5380         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5381         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
5382         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5383
5384         //      P2P IE Section.
5385
5386         //      P2P OUI
5387         p2pielen = 0;
5388         p2pie[ p2pielen++ ] = 0x50;
5389         p2pie[ p2pielen++ ] = 0x6F;
5390         p2pie[ p2pielen++ ] = 0x9A;
5391         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
5392
5393         //      Commented by Albert 20101005
5394         //      According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
5395         //      1. Status
5396         //      2. Configuration Timeout
5397         //      3. Operating Channel    ( Only GO )
5398         //      4. P2P Group BSSID      ( Only GO )
5399         //      5. Channel List
5400
5401         //      P2P Status
5402         //      Type:
5403         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
5404
5405         //      Length:
5406         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5407         p2pielen += 2;
5408
5409         //      Value:
5410         //      When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
5411         //      Sent the event receiving the P2P Invitation Req frame to DMP UI.
5412         //      DMP had to compare the MAC address to find out the profile.
5413         //      So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
5414         //      If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
5415         //      to NB to rebuild the persistent group.
5416         p2pie[ p2pielen++ ] = status_code;
5417         
5418         //      Configuration Timeout
5419         //      Type:
5420         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5421
5422         //      Length:
5423         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5424         p2pielen += 2;
5425
5426         //      Value:
5427         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
5428         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
5429
5430         if( status_code == P2P_STATUS_SUCCESS )
5431         {
5432                 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
5433                 {
5434                         //      The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
5435                         //      In this case, the P2P Invitation response frame should carry the two more P2P attributes.
5436                         //      First one is operating channel attribute.
5437                         //      Second one is P2P Group BSSID attribute.
5438
5439                         //      Operating Channel
5440                         //      Type:
5441                         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5442
5443                         //      Length:
5444                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5445                         p2pielen += 2;
5446
5447                         //      Value:
5448                         //      Country String
5449                         p2pie[ p2pielen++ ] = 'X';
5450                         p2pie[ p2pielen++ ] = 'X';
5451                 
5452                         //      The third byte should be set to 0x04.
5453                         //      Described in the "Operating Channel Attribute" section.
5454                         p2pie[ p2pielen++ ] = 0x04;
5455
5456                         //      Operating Class
5457                         p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
5458                 
5459                         //      Channel Number
5460                         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
5461                         
5462
5463                         //      P2P Group BSSID
5464                         //      Type:
5465                         p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5466
5467                         //      Length:
5468                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5469                         p2pielen += 2;
5470
5471                         //      Value:
5472                         //      P2P Device Address for GO
5473                         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5474                         p2pielen += ETH_ALEN;
5475
5476                 }
5477
5478                 //      Channel List
5479                 //      Type:
5480                 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5481
5482                 //      Length:
5483                 // Country String(3)
5484                 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5485                 // + number of channels in all classes
5486                 len_channellist_attr = 3
5487                         + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5488                         + get_reg_classes_full_count(pmlmeext->channel_list);
5489
5490 #ifdef CONFIG_CONCURRENT_MODE
5491                 if (check_buddy_fwstate(padapter, _FW_LINKED)
5492                         && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5493                 {
5494                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5495                 }
5496                 else
5497                 {
5498                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5499                 }
5500 #else
5501
5502                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5503
5504 #endif
5505                 p2pielen += 2;
5506
5507                 //      Value:
5508                 //      Country String
5509                 p2pie[ p2pielen++ ] = 'X';
5510                 p2pie[ p2pielen++ ] = 'X';
5511
5512                 //      The third byte should be set to 0x04.
5513                 //      Described in the "Operating Channel Attribute" section.
5514                 p2pie[ p2pielen++ ] = 0x04;
5515
5516                 //      Channel Entry List
5517 #ifdef CONFIG_CONCURRENT_MODE
5518                 if (check_buddy_fwstate(padapter , _FW_LINKED)
5519                         && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5520                 {
5521                         _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
5522                         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5523
5524                         //      Operating Class
5525                         if ( pbuddy_mlmeext->cur_channel > 14 )
5526                         {
5527                                 if ( pbuddy_mlmeext->cur_channel >= 149 )
5528                                 {
5529                                         p2pie[ p2pielen++ ] = 0x7c;
5530                                 }
5531                                 else
5532                                 {
5533                                         p2pie[ p2pielen++ ] = 0x73;
5534                                 }
5535                         }
5536                         else
5537                         {
5538                                 p2pie[ p2pielen++ ] = 0x51;
5539                         }
5540
5541                         //      Number of Channels
5542                         //      Just support 1 channel and this channel is AP's channel
5543                         p2pie[ p2pielen++ ] = 1;
5544
5545                         //      Channel List
5546                         p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5547                 }
5548                 else
5549                 {
5550                         int i, j;
5551                         for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5552                                 //      Operating Class
5553                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5554
5555                                 //      Number of Channels
5556                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5557
5558                                 //      Channel List
5559                                 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5560                                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5561                                 }
5562                         }
5563                 }
5564 #else // CONFIG_CONCURRENT_MODE
5565                 {
5566                         int i, j;
5567                         for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5568                                 //      Operating Class
5569                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5570
5571                                 //      Number of Channels
5572                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5573
5574                                 //      Channel List
5575                                 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5576                                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5577                                 }
5578                         }
5579                 }
5580 #endif // CONFIG_CONCURRENT_MODE
5581         }
5582                 
5583         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
5584         
5585 #ifdef CONFIG_WFD
5586         wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5587         pframe += wfdielen;
5588         pattrib->pktlen += wfdielen;
5589 #endif
5590
5591         pattrib->last_txcmdsz = pattrib->pktlen;
5592
5593         dump_mgntframe(padapter, pmgntframe);
5594
5595         return;
5596
5597 }
5598
5599 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
5600 {
5601         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5602         u8                      action = P2P_PUB_ACTION_ACTION;
5603         u8                      dialogToken = 1;
5604         u32                     p2poui = cpu_to_be32(P2POUI);
5605         u8                      oui_subtype = P2P_PROVISION_DISC_REQ;
5606         u8                      wpsie[ 100 ] = { 0x00 };
5607         u8                      wpsielen = 0;
5608         u32                     p2pielen = 0;
5609 #ifdef CONFIG_WFD
5610         u32                                     wfdielen = 0;
5611 #endif
5612         
5613         struct xmit_frame                       *pmgntframe;
5614         struct pkt_attrib                       *pattrib;
5615         unsigned char                                   *pframe;
5616         struct rtw_ieee80211_hdr        *pwlanhdr;
5617         unsigned short                          *fctrl;
5618         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
5619         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5620         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5621         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
5622
5623
5624         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5625         {
5626                 return;
5627         }
5628
5629         DBG_871X( "[%s] In\n", __FUNCTION__ );
5630         //update attribute
5631         pattrib = &pmgntframe->attrib;
5632         update_mgntframe_attrib(padapter, pattrib);
5633
5634         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5635
5636         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5637         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5638
5639         fctrl = &(pwlanhdr->frame_ctl);
5640         *(fctrl) = 0;
5641
5642         _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5643         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5644         _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5645
5646         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5647         pmlmeext->mgnt_seq++;
5648         SetFrameSubType(pframe, WIFI_ACTION);
5649
5650         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5651         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5652
5653         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5654         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5655         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5656         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
5657         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));               
5658
5659         p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
5660
5661         pframe += p2pielen;
5662         pattrib->pktlen += p2pielen;
5663
5664         wpsielen = 0;
5665         //      WPS OUI
5666         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5667         wpsielen += 4;
5668
5669         //      WPS version
5670         //      Type:
5671         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5672         wpsielen += 2;
5673
5674         //      Length:
5675         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5676         wpsielen += 2;
5677
5678         //      Value:
5679         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
5680
5681         //      Config Method
5682         //      Type:
5683         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5684         wpsielen += 2;
5685
5686         //      Length:
5687         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5688         wpsielen += 2;
5689
5690         //      Value:
5691         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
5692         wpsielen += 2;
5693
5694         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5695
5696
5697 #ifdef CONFIG_WFD
5698         wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5699         pframe += wfdielen;
5700         pattrib->pktlen += wfdielen;
5701 #endif
5702
5703         pattrib->last_txcmdsz = pattrib->pktlen;
5704
5705         dump_mgntframe(padapter, pmgntframe);
5706
5707         return;
5708
5709 }
5710
5711
5712 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
5713 {
5714         u8 i, match_result = 0;
5715
5716         DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5717                     peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
5718         
5719         for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
5720         {
5721                DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5722                             profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);             
5723                 if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
5724                 {
5725                         match_result = 1;
5726                         DBG_871X( "[%s] Match!\n", __FUNCTION__ );
5727                         break;
5728                 }
5729         }
5730         
5731         return (match_result );
5732 }
5733
5734 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5735 {
5736         struct xmit_frame                       *pmgntframe;
5737         struct pkt_attrib                       *pattrib;
5738         unsigned char                                   *pframe;
5739         struct rtw_ieee80211_hdr        *pwlanhdr;
5740         unsigned short                          *fctrl; 
5741         unsigned char                                   *mac;
5742         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
5743         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5744         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5745         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5746         //WLAN_BSSID_EX                 *cur_network = &(pmlmeinfo->network);
5747         u16                                     beacon_interval = 100;
5748         u16                                     capInfo = 0;
5749         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
5750         u8                                      wpsie[255] = { 0x00 };
5751         u32                                     wpsielen = 0, p2pielen = 0;
5752 #ifdef CONFIG_WFD
5753         u32                                     wfdielen = 0;
5754 #endif
5755 #ifdef CONFIG_INTEL_WIDI
5756         u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5757 #endif //CONFIG_INTEL_WIDI
5758
5759         //DBG_871X("%s\n", __FUNCTION__);
5760         
5761         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5762         {
5763                 return;
5764         }
5765         
5766         //update attribute
5767         pattrib = &pmgntframe->attrib;
5768         update_mgntframe_attrib(padapter, pattrib);     
5769         
5770         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5771                 
5772         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5773         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
5774         
5775         mac = adapter_mac_addr(padapter);
5776         
5777         fctrl = &(pwlanhdr->frame_ctl);
5778         *(fctrl) = 0;
5779         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5780         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5781         
5782         //      Use the device address for BSSID field. 
5783         _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5784
5785         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5786         pmlmeext->mgnt_seq++;
5787         SetFrameSubType(fctrl, WIFI_PROBERSP);
5788         
5789         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5790         pattrib->pktlen = pattrib->hdrlen;
5791         pframe += pattrib->hdrlen;
5792
5793         //timestamp will be inserted by hardware
5794         pframe += 8;
5795         pattrib->pktlen += 8;
5796
5797         // beacon interval: 2 bytes
5798         _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2); 
5799         pframe += 2;
5800         pattrib->pktlen += 2;
5801
5802         //      capability info: 2 bytes
5803         //      ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
5804         capInfo |= cap_ShortPremble;
5805         capInfo |= cap_ShortSlot;
5806         
5807         _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5808         pframe += 2;
5809         pattrib->pktlen += 2;
5810
5811
5812         // SSID
5813         pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5814
5815         // supported rates...
5816         //      Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5817         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5818
5819         // DS parameter set
5820         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5821
5822 #ifdef CONFIG_IOCTL_CFG80211
5823         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5824         {
5825                 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
5826                 {
5827                         //WPS IE
5828                         _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5829                         pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5830                         pframe += pmlmepriv->wps_probe_resp_ie_len;
5831
5832                         //P2P IE
5833                         _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5834                         pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5835                         pframe += pmlmepriv->p2p_probe_resp_ie_len;
5836                 }
5837         }
5838         else
5839 #endif //CONFIG_IOCTL_CFG80211          
5840         {
5841
5842                 //      Todo: WPS IE
5843                 //      Noted by Albert 20100907
5844                 //      According to the WPS specification, all the WPS attribute is presented by Big Endian.
5845
5846                 wpsielen = 0;
5847                 //      WPS OUI
5848                 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5849                 wpsielen += 4;
5850
5851                 //      WPS version
5852                 //      Type:
5853                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5854                 wpsielen += 2;
5855
5856                 //      Length:
5857                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5858                 wpsielen += 2;
5859
5860                 //      Value:
5861                 wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
5862
5863 #ifdef CONFIG_INTEL_WIDI
5864                 //      Commented by Kurt
5865                 //      Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
5866                 if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE 
5867                         || pmlmepriv->num_p2p_sdt != 0 )
5868                 {
5869                         //Sec dev type
5870                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
5871                         wpsielen += 2;
5872
5873                         //      Length:
5874                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5875                         wpsielen += 2;
5876
5877                         //      Value:
5878                         //      Category ID
5879                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
5880                         wpsielen += 2;
5881
5882                         //      OUI
5883                         *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
5884                         wpsielen += 4;
5885
5886                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
5887                         wpsielen += 2;
5888
5889                         if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
5890                         {
5891                                 //      Vendor Extension
5892                                 _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
5893                                 wpsielen += L2SDTA_SERVICE_VE_LEN;
5894                         }
5895                 }
5896 #endif //CONFIG_INTEL_WIDI
5897
5898                 //      WiFi Simple Config State
5899                 //      Type:
5900                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
5901                 wpsielen += 2;
5902
5903                 //      Length:
5904                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5905                 wpsielen += 2;
5906
5907                 //      Value:
5908                 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;   //      Not Configured.
5909
5910                 //      Response Type
5911                 //      Type:
5912                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
5913                 wpsielen += 2;
5914
5915                 //      Length:
5916                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5917                 wpsielen += 2;
5918
5919                 //      Value:
5920                 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5921
5922                 //      UUID-E
5923                 //      Type:
5924                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5925                 wpsielen += 2;
5926
5927                 //      Length:
5928                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5929                 wpsielen += 2;
5930
5931                 //      Value:
5932                 if (pwdinfo->external_uuid == 0) {
5933                         _rtw_memset( wpsie + wpsielen, 0x0, 16 );
5934                         _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5935                 } else {
5936                         _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5937                 }
5938                 wpsielen += 0x10;
5939
5940                 //      Manufacturer
5941                 //      Type:
5942                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
5943                 wpsielen += 2;
5944
5945                 //      Length:
5946                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
5947                 wpsielen += 2;
5948
5949                 //      Value:
5950                 _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
5951                 wpsielen += 7;
5952
5953                 //      Model Name
5954                 //      Type:
5955                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
5956                 wpsielen += 2;
5957
5958                 //      Length:
5959                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
5960                 wpsielen += 2;  
5961
5962                 //      Value:
5963                 _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
5964                 wpsielen += 6;
5965
5966                 //      Model Number
5967                 //      Type:
5968                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
5969                 wpsielen += 2;
5970
5971                 //      Length:
5972                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5973                 wpsielen += 2;
5974
5975                 //      Value:
5976                 wpsie[ wpsielen++ ] = 0x31;             //      character 1
5977
5978                 //      Serial Number
5979                 //      Type:
5980                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
5981                 wpsielen += 2;
5982
5983                 //      Length:
5984                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
5985                 wpsielen += 2;
5986
5987                 //      Value:
5988                 _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
5989                 wpsielen += ETH_ALEN;
5990
5991                 //      Primary Device Type
5992                 //      Type:
5993                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5994                 wpsielen += 2;
5995
5996                 //      Length:
5997                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5998                 wpsielen += 2;
5999
6000                 //      Value:
6001                 //      Category ID
6002                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
6003                 wpsielen += 2;
6004
6005                 //      OUI
6006                 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6007                 wpsielen += 4;
6008
6009                 //      Sub Category ID
6010                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
6011                 wpsielen += 2;
6012
6013                 //      Device Name
6014                 //      Type:
6015                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6016                 wpsielen += 2;
6017
6018                 //      Length:
6019                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6020                 wpsielen += 2;
6021
6022                 //      Value:
6023                 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6024                 wpsielen += pwdinfo->device_name_len;
6025
6026                 //      Config Method
6027                 //      Type:
6028                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6029                 wpsielen += 2;
6030
6031                 //      Length:
6032                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6033                 wpsielen += 2;
6034
6035                 //      Value:
6036                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6037                 wpsielen += 2;
6038                 
6039
6040                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6041                 
6042
6043                 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6044                 pframe += p2pielen;
6045                 pattrib->pktlen += p2pielen;
6046         }
6047
6048 #ifdef CONFIG_WFD
6049         wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6050         pframe += wfdielen;
6051         pattrib->pktlen += wfdielen;
6052 #endif
6053
6054         pattrib->last_txcmdsz = pattrib->pktlen;
6055         
6056
6057         dump_mgntframe(padapter, pmgntframe);
6058         
6059         return;
6060
6061 }
6062
6063 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6064 {
6065         int ret = _FAIL;
6066         struct xmit_frame               *pmgntframe;
6067         struct pkt_attrib               *pattrib;
6068         unsigned char                   *pframe;
6069         struct rtw_ieee80211_hdr        *pwlanhdr;
6070         unsigned short          *fctrl;
6071         unsigned char                   *mac;
6072         unsigned char                   bssrate[NumRates];
6073         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
6074         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
6075         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
6076         int     bssrate_len = 0;
6077         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6078         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo); 
6079         u8                                      wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
6080         u16                                     wpsielen = 0, p2pielen = 0;
6081 #ifdef CONFIG_WFD
6082         u32                                     wfdielen = 0;
6083 #endif
6084
6085         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6086
6087
6088         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6089         {
6090                 goto exit;
6091         }
6092
6093         //update attribute
6094         pattrib = &pmgntframe->attrib;
6095         update_mgntframe_attrib(padapter, pattrib);
6096
6097
6098         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6099
6100         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6101         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6102
6103         mac = adapter_mac_addr(padapter);
6104
6105         fctrl = &(pwlanhdr->frame_ctl);
6106         *(fctrl) = 0;
6107
6108         if (da) {
6109                 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6110                 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6111         } else {
6112                 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
6113                 {
6114                         //      This two flags will be set when this is only the P2P client mode.
6115                         _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6116                         _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6117                 }
6118                 else
6119                 {
6120                         //      broadcast probe request frame
6121                         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6122                         _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6123                 }
6124         }
6125         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6126
6127         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6128         pmlmeext->mgnt_seq++;
6129         SetFrameSubType(pframe, WIFI_PROBEREQ);
6130
6131         pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6132         pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6133
6134         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6135         {
6136                 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6137         }
6138         else
6139         {
6140                 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6141         }
6142         //      Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
6143         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6144
6145 #ifdef CONFIG_IOCTL_CFG80211
6146         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
6147         {
6148                 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
6149                 {
6150                         //WPS IE
6151                         _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6152                         pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6153                         pframe += pmlmepriv->wps_probe_req_ie_len;
6154
6155                         //P2P IE
6156                         _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6157                         pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6158                         pframe += pmlmepriv->p2p_probe_req_ie_len;
6159                 }
6160         }
6161         else
6162 #endif //CONFIG_IOCTL_CFG80211
6163         {
6164
6165                 //      WPS IE
6166                 //      Noted by Albert 20110221
6167                 //      According to the WPS specification, all the WPS attribute is presented by Big Endian.
6168
6169                 wpsielen = 0;
6170                 //      WPS OUI
6171                 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
6172                 wpsielen += 4;
6173
6174                 //      WPS version
6175                 //      Type:
6176                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
6177                 wpsielen += 2;
6178
6179                 //      Length:
6180                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
6181                 wpsielen += 2;
6182
6183                 //      Value:
6184                 wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
6185
6186                 if( pmlmepriv->wps_probe_req_ie == NULL )
6187                 {
6188                         //      UUID-E
6189                         //      Type:
6190                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
6191                         wpsielen += 2;
6192
6193                         //      Length:
6194                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
6195                         wpsielen += 2;
6196
6197                         //      Value:
6198                         if (pwdinfo->external_uuid == 0) {
6199                                 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
6200                                 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6201                         } else {
6202                                 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
6203                         }
6204                         wpsielen += 0x10;
6205
6206                         //      Config Method
6207                         //      Type:
6208                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6209                         wpsielen += 2;
6210
6211                         //      Length:
6212                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6213                         wpsielen += 2;
6214
6215                         //      Value:
6216                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6217                         wpsielen += 2;
6218                 }
6219
6220                 //      Device Name
6221                 //      Type:
6222                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6223                 wpsielen += 2;
6224
6225                 //      Length:
6226                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6227                 wpsielen += 2;
6228
6229                 //      Value:
6230                 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6231                 wpsielen += pwdinfo->device_name_len;
6232
6233                 //      Primary Device Type
6234                 //      Type:
6235                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6236                 wpsielen += 2;
6237
6238                 //      Length:
6239                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6240                 wpsielen += 2;
6241
6242                 //      Value:
6243                 //      Category ID
6244                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
6245                 wpsielen += 2;
6246
6247                 //      OUI
6248                 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6249                 wpsielen += 4;
6250
6251                 //      Sub Category ID
6252                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
6253                 wpsielen += 2;
6254
6255                 //      Device Password ID
6256                 //      Type:
6257                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
6258                 wpsielen += 2;
6259
6260                 //      Length:
6261                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6262                 wpsielen += 2;
6263
6264                 //      Value:
6265                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );  //      Registrar-specified
6266                 wpsielen += 2;  
6267
6268                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6269                 
6270                 //      P2P OUI
6271                 p2pielen = 0;
6272                 p2pie[ p2pielen++ ] = 0x50;
6273                 p2pie[ p2pielen++ ] = 0x6F;
6274                 p2pie[ p2pielen++ ] = 0x9A;
6275                 p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
6276
6277                 //      Commented by Albert 20110221
6278                 //      According to the P2P Specification, the probe request frame should contain 5 P2P attributes
6279                 //      1. P2P Capability
6280                 //      2. P2P Device ID if this probe request wants to find the specific P2P device
6281                 //      3. Listen Channel
6282                 //      4. Extended Listen Timing
6283                 //      5. Operating Channel if this WiFi is working as the group owner now
6284
6285                 //      P2P Capability
6286                 //      Type:
6287                 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
6288
6289                 //      Length:
6290                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
6291                 p2pielen += 2;
6292
6293                 //      Value:
6294                 //      Device Capability Bitmap, 1 byte
6295                 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
6296                 
6297                 //      Group Capability Bitmap, 1 byte
6298                 if ( pwdinfo->persistent_supported )
6299                         p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6300                 else
6301                         p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
6302
6303                 //      Listen Channel
6304                 //      Type:
6305                 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
6306
6307                 //      Length:
6308                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6309                 p2pielen += 2;
6310
6311                 //      Value:
6312                 //      Country String
6313                 p2pie[ p2pielen++ ] = 'X';
6314                 p2pie[ p2pielen++ ] = 'X';
6315                 
6316                 //      The third byte should be set to 0x04.
6317                 //      Described in the "Operating Channel Attribute" section.
6318                 p2pie[ p2pielen++ ] = 0x04;
6319
6320                 //      Operating Class
6321                 p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
6322                 
6323                 //      Channel Number
6324                 p2pie[ p2pielen++ ] = pwdinfo->listen_channel;  //      listen channel
6325                 
6326
6327                 //      Extended Listen Timing
6328                 //      Type:
6329                 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
6330
6331                 //      Length:
6332                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
6333                 p2pielen += 2;
6334
6335                 //      Value:
6336                 //      Availability Period
6337                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6338                 p2pielen += 2;
6339
6340                 //      Availability Interval
6341                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6342                 p2pielen += 2;
6343
6344                 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
6345                 {
6346                         //      Operating Channel (if this WiFi is working as the group owner now)
6347                         //      Type:
6348                         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
6349
6350                         //      Length:
6351                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6352                         p2pielen += 2;
6353
6354                         //      Value:
6355                         //      Country String
6356                         p2pie[ p2pielen++ ] = 'X';
6357                         p2pie[ p2pielen++ ] = 'X';
6358                 
6359                         //      The third byte should be set to 0x04.
6360                         //      Described in the "Operating Channel Attribute" section.
6361                         p2pie[ p2pielen++ ] = 0x04;
6362
6363                         //      Operating Class
6364                         p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
6365                 
6366                         //      Channel Number
6367                         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
6368                         
6369                 }
6370                 
6371                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
6372
6373         }
6374
6375 #ifdef CONFIG_WFD
6376         wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6377         pframe += wfdielen;
6378         pattrib->pktlen += wfdielen;
6379 #endif
6380
6381         pattrib->last_txcmdsz = pattrib->pktlen;
6382
6383         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6384
6385         if (wait_ack) {
6386                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6387         } else {
6388                 dump_mgntframe(padapter, pmgntframe);
6389                 ret = _SUCCESS;
6390         }
6391
6392 exit:
6393         return ret;
6394 }
6395
6396 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6397 {
6398         _issue_probereq_p2p(adapter, da, _FALSE);
6399 }
6400
6401 /*
6402  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6403  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
6404  * try_cnt means the maximal TX count to try
6405  */
6406 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6407 {
6408         int ret;
6409         int i = 0;
6410         u32 start = rtw_get_current_time();
6411
6412         do
6413         {
6414                 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
6415
6416                 i++;
6417
6418                 if (RTW_CANNOT_RUN(adapter))
6419                         break;
6420
6421                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6422                         rtw_msleep_os(wait_ms);
6423
6424         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6425
6426         if (ret != _FAIL) {
6427                 ret = _SUCCESS;
6428                 #ifndef DBG_XMIT_ACK
6429                 goto exit;
6430                 #endif
6431         }
6432
6433         if (try_cnt && wait_ms) {
6434                 if (da)
6435                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6436                                 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6437                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6438                 else
6439                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6440                                 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6441                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6442         }
6443 exit:
6444         return ret;
6445 }
6446
6447 #endif //CONFIG_P2P
6448
6449 s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
6450 {
6451         _adapter *adapter = rframe->u.hdr.adapter;
6452         struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6453         u8 *frame = rframe->u.hdr.rx_data;
6454         u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num&0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
6455         u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
6456
6457         if (GetRetry(frame)) {
6458                 if ((seq_ctrl == mlmeext->action_public_rxseq)
6459                         && (token == mlmeext->action_public_dialog_token)
6460                 ) {
6461                         DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6462                                 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6463                         return _FAIL;
6464                 }
6465         }
6466
6467         /* TODO: per sta seq & token */
6468         mlmeext->action_public_rxseq = seq_ctrl;
6469         mlmeext->action_public_dialog_token = token;
6470
6471         return _SUCCESS;
6472 }
6473
6474 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6475 {
6476         _adapter *padapter = precv_frame->u.hdr.adapter;
6477         u8 *pframe = precv_frame->u.hdr.rx_data;
6478         uint len = precv_frame->u.hdr.len;
6479         u8 *frame_body;
6480 #ifdef CONFIG_P2P
6481         u8 *p2p_ie;
6482         u32     p2p_ielen, wps_ielen;
6483         struct  wifidirect_info *pwdinfo = &( padapter->wdinfo );
6484         u8      result = P2P_STATUS_SUCCESS;
6485         u8      empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6486         u8 *merged_p2pie = NULL;
6487         u32 merged_p2p_ielen= 0;
6488 #endif //CONFIG_P2P
6489
6490         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6491
6492 #ifdef CONFIG_P2P
6493         _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
6494 #ifdef CONFIG_IOCTL_CFG80211
6495         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6496         {
6497                 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
6498         }
6499         else
6500 #endif //CONFIG_IOCTL_CFG80211
6501         {
6502                 //      Do nothing if the driver doesn't enable the P2P function.
6503                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6504                         return _SUCCESS;
6505
6506                 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6507
6508                 switch( frame_body[ 6 ] )//OUI Subtype
6509                 {
6510                         case P2P_GO_NEGO_REQ:
6511                         {
6512                                 DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6513                                 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
6514
6515                                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6516                                 {
6517                                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6518                                 }
6519
6520                                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6521                                 {
6522                                         //      Commented by Albert 20110526
6523                                         //      In this case, this means the previous nego fail doesn't be reset yet.
6524                                         _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6525                                         //      Restore the previous p2p state
6526                                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6527                                         DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );                                                
6528                                 }                                       
6529 #ifdef CONFIG_CONCURRENT_MODE
6530                                 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
6531                                 {
6532                                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6533                                 }
6534 #endif // CONFIG_CONCURRENT_MODE
6535
6536                                 //      Commented by Kurt 20110902
6537                                 //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6538                                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6539                                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6540
6541                                 //      Commented by Kurt 20120113
6542                                 //      Get peer_dev_addr here if peer doesn't issue prov_disc frame.
6543                                 if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
6544                                         _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6545
6546                                 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
6547                                 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
6548 #ifdef CONFIG_INTEL_WIDI
6549                                 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6550                                         padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6551                                         _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6552                                         intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6553                                 }
6554 #endif //CONFIG_INTEL_WIDI
6555
6556                                 //      Commented by Albert 20110718
6557                                 //      No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
6558 #ifdef CONFIG_CONCURRENT_MODE
6559                                 //      Commented by Albert 20120107
6560                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6561 #else // CONFIG_CONCURRENT_MODE
6562                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6563 #endif // CONFIG_CONCURRENT_MODE
6564                                 break;                                  
6565                         }
6566                         case P2P_GO_NEGO_RESP:
6567                         {
6568                                 DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6569
6570                                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6571                                 {
6572                                         //      Commented by Albert 20110425
6573                                         //      The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
6574                                         _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6575                                         pwdinfo->nego_req_info.benable = _FALSE;
6576                                         result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
6577                                         issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
6578                                         if ( P2P_STATUS_SUCCESS == result )
6579                                         {
6580                                                 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6581                                                 {
6582                                                         pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6583                                                         #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6584                                                         pwdinfo->p2p_info.operation_ch[ 1 ] = 1;        //Check whether GO is operating in channel 1;
6585                                                         pwdinfo->p2p_info.operation_ch[ 2 ] = 6;        //Check whether GO is operating in channel 6;
6586                                                         pwdinfo->p2p_info.operation_ch[ 3 ] = 11;       //Check whether GO is operating in channel 11;
6587                                                         #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6588                                                         pwdinfo->p2p_info.scan_op_ch_only = 1;
6589                                                         _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6590                                                 }
6591                                         }
6592
6593                                         //      Reset the dialog token for group negotiation frames.
6594                                         pwdinfo->negotiation_dialog_token = 1;
6595
6596                                         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6597                                         {
6598                                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6599                                         }
6600                                 }
6601                                 else
6602                                 {
6603                                         DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6604                                 }
6605                                 
6606                                 break;
6607                         }
6608                         case P2P_GO_NEGO_CONF:
6609                         {
6610                                 DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6611                                 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
6612                                 if ( P2P_STATUS_SUCCESS == result )
6613                                 {
6614                                         if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6615                                         {
6616                                                 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6617                                                 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6618                                                 pwdinfo->p2p_info.operation_ch[ 1 ] = 1;        //Check whether GO is operating in channel 1;
6619                                                 pwdinfo->p2p_info.operation_ch[ 2 ] = 6;        //Check whether GO is operating in channel 6;
6620                                                 pwdinfo->p2p_info.operation_ch[ 3 ] = 11;       //Check whether GO is operating in channel 11;
6621                                                 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6622                                                 pwdinfo->p2p_info.scan_op_ch_only = 1;
6623                                                 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6624                                         }
6625                                 }
6626                                 break;
6627                         }
6628                         case P2P_INVIT_REQ:
6629                         {
6630                                 //      Added by Albert 2010/10/05
6631                                 //      Received the P2P Invite Request frame.
6632                                 
6633                                 DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
6634                                 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6635                                 {
6636                                         //      Parse the necessary information from the P2P Invitation Request frame.
6637                                         //      For example: The MAC address of sending this P2P Invitation Request frame.
6638                                         u32     attr_contentlen = 0;
6639                                         u8      status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6640                                         struct group_id_info group_id;
6641                                         u8      invitation_flag = 0;
6642                                         int j=0;
6643
6644                                         merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6645
6646                                         merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2);       // 2 is for EID and Length
6647                                         if (merged_p2pie == NULL)
6648                                         {
6649                                                 DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
6650                                                 goto exit;
6651                                         }
6652                                         _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);                                      
6653
6654                                         merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6655
6656                                         rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6657                                         if ( attr_contentlen )
6658                                         {
6659
6660                                                 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6661                                                 //      Commented by Albert 20120510
6662                                                 //      Copy to the pwdinfo->p2p_peer_interface_addr.
6663                                                 //      So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
6664                                                 //      #> iwpriv wlan0 p2p_get peer_ifa
6665                                                 //      After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
6666
6667                                                 if ( attr_contentlen )
6668                                                 {
6669                                                         DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6670                                                                         pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6671                                                                         pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6672                                                                         pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
6673                                                 }                                                               
6674
6675                                                 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
6676                                                 {
6677                                                         //      Re-invoke the persistent group.
6678                                                         
6679                                                         _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6680                                                         rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6681                                                         if ( attr_contentlen )
6682                                                         {
6683                                                                 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6684                                                                 {
6685                                                                         //      The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
6686                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
6687                                                                         rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
6688                                                                         status_code = P2P_STATUS_SUCCESS;
6689                                                                 }
6690                                                                 else
6691                                                                 {
6692                                                                         //      The p2p device sending this p2p invitation request wants to be the persistent GO.
6693                                                                         if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
6694                                                                         {
6695                                                                                 u8 operatingch_info[5] = { 0x00 };
6696                                                                                 if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
6697                                                                                 {
6698                                                                                         if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
6699                                                                                         {
6700                                                                                                 //      The operating channel is acceptable for this device.
6701                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
6702                                                                                                 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6703                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[1]= 1;          //Check whether GO is operating in channel 1;
6704                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[2]= 6;          //Check whether GO is operating in channel 6;
6705                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[3]= 11;         //Check whether GO is operating in channel 11;
6706                                                                                                 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6707                                                                                                 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6708                                                                                                 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
6709                                                                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6710                                                                                                 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6711                                                                                                 status_code = P2P_STATUS_SUCCESS;
6712                                                                                         }
6713                                                                                         else
6714                                                                                         {
6715                                                                                                 //      The operating channel isn't supported by this device.
6716                                                                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6717                                                                                                 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
6718                                                                                                 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6719                                                                                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6720                                                                                         }
6721                                                                                 }
6722                                                                                 else
6723                                                                                 {
6724                                                                                         //      Commented by Albert 20121130
6725                                                                                         //      Intel will use the different P2P IE to store the operating channel information
6726                                                                                         //      Workaround for Intel WiDi 3.5
6727                                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6728                                                                                         rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6729                                                                                         status_code = P2P_STATUS_SUCCESS;
6730                                                                                 }                                                               
6731                                                                         }
6732                                                                         else
6733                                                                         {
6734                                                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6735                                                                                 #ifdef CONFIG_INTEL_WIDI
6736                                                                                 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6737                                                                                 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6738                                                                                 #endif //CONFIG_INTEL_WIDI
6739
6740                                                                                 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6741                                                                         }
6742                                                                 }
6743                                                         }
6744                                                         else
6745                                                         {
6746                                                                 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6747                                                                 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6748                                                         }                                                                       
6749                                                 }
6750                                                 else
6751                                                 {
6752                                                         //      Received the invitation to join a P2P group.
6753
6754                                                         _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6755                                                         rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6756                                                         if ( attr_contentlen )
6757                                                         {
6758                                                                 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6759                                                                 {
6760                                                                         //      In this case, the GO can't be myself.
6761                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6762                                                                         status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6763                                                                 }
6764                                                                 else
6765                                                                 {
6766                                                                         //      The p2p device sending this p2p invitation request wants to join an existing P2P group
6767                                                                         //      Commented by Albert 2012/06/28
6768                                                                         //      In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
6769                                                                         //      The peer device address should be the destination address for the provisioning discovery request.
6770                                                                         //      Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
6771                                                                         //      The peer interface address should be the address for WPS mac address
6772                                                                         _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );                                                                                       
6773                                                                         rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6774                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
6775                                                                         status_code = P2P_STATUS_SUCCESS;
6776                                                                 }
6777                                                         }
6778                                                         else
6779                                                         {
6780                                                                 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6781                                                                 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6782                                                         }
6783                                                 }
6784                                         }
6785                                         else
6786                                         {
6787                                                 DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
6788                                                 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6789                                         }                                                       
6790
6791                                         DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
6792
6793                                         pwdinfo->inviteresp_info.token = frame_body[ 7 ];
6794                                         issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
6795                                         _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6796                                 }
6797 #ifdef CONFIG_INTEL_WIDI
6798                                 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6799                                         padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6800                                         _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6801                                         intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6802                                 }
6803 #endif //CONFIG_INTEL_WIDI
6804                                 break;
6805                         }
6806                         case P2P_INVIT_RESP:
6807                         {
6808                                 u8      attr_content = 0x00;
6809                                 u32     attr_contentlen = 0;
6810                                 
6811                                 DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
6812                                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6813                                 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6814                                 {
6815                                         rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6816                                                                         
6817                                         if ( attr_contentlen == 1 )
6818                                         {
6819                                                 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
6820                                                 pwdinfo->invitereq_info.benable = _FALSE;
6821
6822                                                 if ( attr_content == P2P_STATUS_SUCCESS )
6823                                                 {
6824                                                         if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6825                                                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
6826                                                         else
6827                                                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6828
6829                                                         rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
6830                                                 }
6831                                                 else
6832                                                 {
6833                                                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6834                                                         rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6835                                                 }
6836                                         }
6837                                         else
6838                                         {
6839                                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6840                                                 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6841                                         }
6842                                 }
6843                                 else
6844                                 {
6845                                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6846                                         rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6847                                 }
6848
6849                                 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
6850                                 {
6851                                         _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6852                                 }
6853                                 break;
6854                         }
6855                         case P2P_DEVDISC_REQ:
6856
6857                                 process_p2p_devdisc_req(pwdinfo, pframe, len);
6858
6859                                 break;
6860
6861                         case P2P_DEVDISC_RESP:
6862
6863                                 process_p2p_devdisc_resp(pwdinfo, pframe, len);
6864
6865                                 break;
6866
6867                         case P2P_PROVISION_DISC_REQ:
6868                                 DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
6869                                 process_p2p_provdisc_req(pwdinfo, pframe, len);
6870                                 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6871
6872                                 //20110902 Kurt
6873                                 //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6874                                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6875                                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6876                                 
6877                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6878                                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6879 #ifdef CONFIG_INTEL_WIDI
6880                                 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6881                                         padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6882                                         _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6883                                         intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6884                                 }
6885 #endif //CONFIG_INTEL_WIDI
6886                                 break;
6887
6888                         case P2P_PROVISION_DISC_RESP:
6889                                 //      Commented by Albert 20110707
6890                                 //      Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
6891                                 DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
6892                                 //      Commented by Albert 20110426
6893                                 //      The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
6894                                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6895                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6896                                 process_p2p_provdisc_resp(pwdinfo, pframe);
6897                                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6898                                 break;
6899
6900                 }
6901         }
6902
6903
6904 exit:
6905
6906         if(merged_p2pie)
6907         {
6908                 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6909         }
6910 #endif //CONFIG_P2P
6911         return _SUCCESS;
6912 }
6913
6914 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6915 {
6916         unsigned int ret = _FAIL;
6917         u8 *pframe = precv_frame->u.hdr.rx_data;
6918         uint frame_len = precv_frame->u.hdr.len;
6919         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6920
6921         if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6922                 if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
6923                         goto exit;
6924
6925                 if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
6926                         rtw_rframe_del_wfd_ie(precv_frame, 8);
6927
6928                 ret = on_action_public_p2p(precv_frame);
6929         }
6930
6931 exit:
6932         return ret;
6933 }
6934
6935 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6936 {
6937         unsigned int ret = _FAIL;
6938         u8 *pframe = precv_frame->u.hdr.rx_data;
6939         uint frame_len = precv_frame->u.hdr.len;
6940         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6941         u8 token;
6942         _adapter *adapter = precv_frame->u.hdr.adapter;
6943         int cnt = 0;
6944         char msg[64];
6945
6946         token = frame_body[2];
6947
6948         if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
6949                 goto exit;
6950
6951         #ifdef CONFIG_IOCTL_CFG80211
6952         cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
6953         rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
6954         #endif
6955
6956         ret = _SUCCESS;
6957         
6958 exit:
6959         return ret;
6960 }
6961
6962 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6963 {
6964         unsigned int ret = _FAIL;
6965         u8 *pframe = precv_frame->u.hdr.rx_data;
6966         uint frame_len = precv_frame->u.hdr.len;
6967         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6968         u8 category, action;
6969
6970         /* check RA matches or not */
6971         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6972                 goto exit;
6973
6974         category = frame_body[0];
6975         if (category != RTW_WLAN_CATEGORY_PUBLIC)
6976                 goto exit;
6977
6978         action = frame_body[1];
6979         switch (action) {
6980         case ACT_PUBLIC_BSSCOEXIST:
6981 #ifdef CONFIG_80211N_HT
6982 #ifdef CONFIG_AP_MODE
6983                 /*20/40 BSS Coexistence Management frame is a Public Action frame*/
6984                 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6985                         rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6986 #endif /*CONFIG_AP_MODE*/
6987 #endif /*CONFIG_80211N_HT*/
6988                 break;
6989         case ACT_PUBLIC_VENDOR:
6990                 ret = on_action_public_vendor(precv_frame);
6991                 break;
6992         default:
6993                 ret = on_action_public_default(precv_frame, action);
6994                 break;
6995         }
6996
6997 exit:
6998         return ret;
6999 }
7000
7001 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7002 {
7003         u8 *pframe = precv_frame->u.hdr.rx_data;
7004         uint frame_len = precv_frame->u.hdr.len;
7005         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7006         u8 category, action;
7007
7008         /* check RA matches or not */
7009         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7010                 goto exit;
7011
7012         category = frame_body[0];
7013         if (category != RTW_WLAN_CATEGORY_HT)
7014                 goto exit;
7015
7016         action = frame_body[1];
7017         switch (action) {
7018         case RTW_WLAN_ACTION_HT_SM_PS:
7019 #ifdef CONFIG_80211N_HT
7020 #ifdef CONFIG_AP_MODE
7021                 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7022                         rtw_process_ht_action_smps(padapter, GetAddr2Ptr(pframe), frame_body[2]);
7023 #endif /*CONFIG_AP_MODE*/
7024 #endif /*CONFIG_80211N_HT*/             
7025                         break;
7026         case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7027 #ifdef CONFIG_BEAMFORMING
7028                 /*DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7029                 beamforming_get_report_frame(padapter, precv_frame);
7030 #endif /*CONFIG_BEAMFORMING*/
7031                 break;
7032         default:
7033                 break;
7034         }
7035
7036 exit:
7037
7038         return _SUCCESS;
7039 }
7040
7041 #ifdef CONFIG_IEEE80211W
7042 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7043 {
7044         u8 *pframe = precv_frame->u.hdr.rx_data;
7045         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7046         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7047         struct sta_info         *psta;
7048         struct sta_priv         *pstapriv = &padapter->stapriv;
7049         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7050         u16 tid;
7051         //Baron
7052         
7053         DBG_871X("OnAction_sa_query\n");
7054         
7055         switch (pframe[WLAN_HDR_A3_LEN+1])
7056         {
7057                 case 0: //SA Query req
7058                         _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7059                         DBG_871X("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7060                         , pframe[WLAN_HDR_A3_LEN+1], tid, pframe[WLAN_HDR_A3_LEN+2], pframe[WLAN_HDR_A3_LEN+3]);
7061                         issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7062                         break;
7063
7064                 case 1: //SA Query rsp
7065                         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
7066                         if (psta != NULL)
7067                                 _cancel_timer_ex(&psta->dot11w_expire_timer);
7068                         
7069                         _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7070                         DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], tid);
7071                         break;
7072                 default:
7073                         break;
7074         }
7075         if(0)
7076         {
7077                 int pp;
7078                 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7079                 for(pp=0;pp< pattrib->pkt_len; pp++)
7080                         printk(" %02x ", pframe[pp]);
7081                 printk("\n");
7082         }       
7083         
7084         return _SUCCESS;
7085 }
7086 #endif //CONFIG_IEEE80211W
7087
7088 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7089 {
7090         return _SUCCESS;
7091 }
7092
7093 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7094 {
7095 #ifdef CONFIG_80211AC_VHT
7096         struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
7097         u8 *pframe = precv_frame->u.hdr.rx_data;
7098         uint frame_len = precv_frame->u.hdr.len;
7099         struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7100         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7101         u8 category, action;
7102         struct sta_info *psta = NULL;
7103
7104         /* check RA matches or not */
7105         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7106                 goto exit;
7107
7108         category = frame_body[0];
7109         if(category != RTW_WLAN_CATEGORY_VHT)
7110                 goto exit;
7111
7112         action = frame_body[1];
7113         switch (action) {
7114         case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7115 #ifdef CONFIG_BEAMFORMING
7116                 /*DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7117                 beamforming_get_report_frame(padapter, precv_frame);
7118 #endif /*CONFIG_BEAMFORMING*/
7119                 break;
7120         case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7121                 // CategoryCode(1) + ActionCode(1) + OpModeNotification(1)
7122                 //DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n");
7123                 psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7124                 if (psta)
7125                         rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7126                 break;
7127         default:
7128                 break;
7129         }
7130
7131 exit:
7132 #endif //CONFIG_80211AC_VHT
7133
7134         return _SUCCESS;
7135 }
7136
7137 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7138 {
7139 #ifdef CONFIG_P2P
7140         u8 *frame_body;
7141         u8 category, OUI_Subtype, dialogToken=0;
7142         u8 *pframe = precv_frame->u.hdr.rx_data;
7143         uint len = precv_frame->u.hdr.len;
7144         struct  wifidirect_info *pwdinfo = &( padapter->wdinfo );
7145
7146         //check RA matches or not
7147         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7148                 return _SUCCESS;
7149
7150         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7151
7152         category = frame_body[0];
7153         if(category != RTW_WLAN_CATEGORY_P2P)
7154                 return _SUCCESS;
7155
7156         if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
7157                 return _SUCCESS;
7158
7159 #ifdef CONFIG_IOCTL_CFG80211
7160         if (adapter_wdev_data(padapter)->p2p_enabled
7161                 && pwdinfo->driver_interface == DRIVER_CFG80211
7162                 ) {
7163                 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
7164                 return _SUCCESS;
7165         }
7166         else
7167 #endif //CONFIG_IOCTL_CFG80211
7168         {
7169                 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7170                 OUI_Subtype = frame_body[5];
7171                 dialogToken = frame_body[6];
7172
7173                 switch(OUI_Subtype)
7174                 {
7175                         case P2P_NOTICE_OF_ABSENCE:
7176                                 
7177                                 break;
7178                                 
7179                         case P2P_PRESENCE_REQUEST:
7180
7181                                 process_p2p_presence_req(pwdinfo, pframe, len);                 
7182                                 
7183                                 break;
7184                                 
7185                         case P2P_PRESENCE_RESPONSE:
7186                                 
7187                                 break;
7188                                 
7189                         case P2P_GO_DISC_REQUEST:
7190                                 
7191                                 break;
7192                                 
7193                         default:
7194                                 break;
7195                                 
7196                 }
7197         }
7198 #endif //CONFIG_P2P
7199
7200         return _SUCCESS;
7201
7202 }
7203
7204 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7205 {
7206         int i;
7207         unsigned char   category;
7208         struct action_handler *ptable;
7209         unsigned char   *frame_body;
7210         u8 *pframe = precv_frame->u.hdr.rx_data; 
7211
7212         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7213         
7214         category = frame_body[0];
7215         
7216         for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++) 
7217         {
7218                 ptable = &OnAction_tbl[i];
7219                 
7220                 if(category == ptable->num)
7221                         ptable->func(padapter, precv_frame);
7222         
7223         }
7224
7225         return _SUCCESS;
7226
7227 }
7228
7229 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7230 {
7231
7232         //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
7233         return _SUCCESS;
7234 }
7235
7236 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7237 {
7238         struct xmit_frame *pmgntframe;
7239         struct xmit_buf *pxmitbuf;
7240
7241         if (once)
7242                 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7243         else
7244                 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7245
7246         if (pmgntframe == NULL) {
7247                 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7248                 goto exit;
7249         }
7250
7251         if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
7252                 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7253                 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7254                 pmgntframe = NULL;
7255                 goto exit;
7256         }
7257
7258         pmgntframe->frame_tag = MGNT_FRAMETAG;
7259         pmgntframe->pxmitbuf = pxmitbuf;
7260         pmgntframe->buf_addr = pxmitbuf->pbuf;
7261         pxmitbuf->priv_data = pmgntframe;
7262
7263 exit:
7264         return pmgntframe;
7265
7266 }
7267
7268 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7269 {
7270         return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7271 }
7272
7273 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7274 {
7275         return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7276 }
7277
7278
7279 /****************************************************************************
7280
7281 Following are some TX fuctions for WiFi MLME
7282
7283 *****************************************************************************/
7284
7285 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7286 {
7287         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7288
7289         pmlmeext->tx_rate = rate;
7290         //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
7291 }
7292
7293
7294 void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7295 {
7296         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
7297         u8      wireless_mode;
7298         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7299         struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
7300         struct sta_info         *psta = NULL;
7301         struct sta_priv         *pstapriv = &padapter->stapriv;
7302         struct sta_info *pbcmc_sta = NULL;
7303
7304         psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7305         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7306
7307         pattrib->hdrlen = 24;
7308         pattrib->nr_frags = 1;
7309         pattrib->priority = 7;
7310
7311         if (pbcmc_sta)
7312                 pattrib->mac_id = pbcmc_sta->mac_id;
7313         else {
7314                 pattrib->mac_id = 0;
7315                 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7316         }
7317         pattrib->qsel = QSLT_MGNT;
7318
7319         pattrib->pktlen = 0;
7320
7321         if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7322                 wireless_mode = WIRELESS_11B;
7323         else
7324                 wireless_mode = WIRELESS_11G;
7325
7326         pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7327         #ifdef CONFIG_80211AC_VHT
7328                 if (pHalData->rf_type == RF_1T1R)
7329                         pattrib->raid = RATEID_IDX_VHT_1SS;
7330                 else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
7331                         pattrib->raid = RATEID_IDX_VHT_2SS;
7332                 else if (pHalData->rf_type == RF_3T3R)
7333                         pattrib->raid = RATEID_IDX_VHT_3SS;
7334                 else
7335                         pattrib->raid = RATEID_IDX_BGN_40M_1SS;
7336         #endif
7337
7338         #ifdef CONFIG_80211AC_VHT
7339                 pattrib->rate = MGN_VHT1SS_MCS9;
7340         #else
7341                 pattrib->rate = MGN_MCS7;
7342         #endif
7343
7344         pattrib->encrypt = _NO_PRIVACY_;
7345         pattrib->bswenc = _FALSE;
7346
7347         pattrib->qos_en = _FALSE;
7348         pattrib->ht_en = 1;
7349         pattrib->bwmode = CHANNEL_WIDTH_20;
7350         pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7351         pattrib->sgi = _FALSE;
7352
7353         pattrib->seqnum = pmlmeext->mgnt_seq;
7354
7355         pattrib->retry_ctrl = _TRUE;
7356
7357         pattrib->mbssid = 0;
7358         pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7359
7360 }
7361
7362
7363 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7364 {
7365         u8      wireless_mode;
7366         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7367         struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
7368         struct sta_info         *psta = NULL;
7369         struct sta_priv         *pstapriv = &padapter->stapriv;
7370         struct sta_info *pbcmc_sta = NULL;
7371         //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
7372
7373         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7374
7375         pattrib->hdrlen = 24;
7376         pattrib->nr_frags = 1;
7377         pattrib->priority = 7;
7378
7379         if (pbcmc_sta)
7380                 pattrib->mac_id = pbcmc_sta->mac_id;
7381         else {
7382                 pattrib->mac_id = 0;
7383                 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7384         }
7385         pattrib->qsel = QSLT_MGNT;
7386
7387         pattrib->pktlen = 0;
7388
7389         if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7390                 wireless_mode = WIRELESS_11B;
7391         else
7392                 wireless_mode = WIRELESS_11G;
7393         pattrib->raid =  rtw_get_mgntframe_raid(padapter, wireless_mode);
7394         pattrib->rate = pmlmeext->tx_rate;
7395
7396         pattrib->encrypt = _NO_PRIVACY_;
7397         pattrib->bswenc = _FALSE;       
7398
7399         pattrib->qos_en = _FALSE;
7400         pattrib->ht_en = _FALSE;
7401         pattrib->bwmode = CHANNEL_WIDTH_20;
7402         pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7403         pattrib->sgi = _FALSE;
7404
7405         pattrib->seqnum = pmlmeext->mgnt_seq;
7406
7407         pattrib->retry_ctrl = _TRUE;
7408
7409         pattrib->mbssid = 0;
7410         pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7411
7412         #ifdef CONFIG_BEAMFORMING
7413         psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7414         if (psta)
7415                 update_attrib_txbf_info(padapter, pattrib, psta);
7416         #endif
7417
7418 }
7419
7420 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7421 {
7422         u8      *pframe;
7423         struct pkt_attrib       *pattrib = &pmgntframe->attrib;
7424
7425         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7426
7427         _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7428         _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
7429 }
7430
7431 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7432 {
7433         if (RTW_CANNOT_RUN(padapter)) {
7434                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7435                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7436                 return;
7437         }
7438
7439         rtw_hal_mgnt_xmit(padapter, pmgntframe);
7440 }
7441
7442 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7443 {
7444         s32 ret = _FAIL;
7445         _irqL irqL;
7446         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;      
7447         struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7448         struct submit_ctx sctx;
7449
7450         if (RTW_CANNOT_RUN(padapter)) {
7451                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7452                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7453                 return ret;
7454         }
7455
7456         rtw_sctx_init(&sctx, timeout_ms);
7457         pxmitbuf->sctx = &sctx;
7458
7459         ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7460
7461         if (ret == _SUCCESS)
7462                 ret = rtw_sctx_wait(&sctx, __func__);
7463
7464         _enter_critical(&pxmitpriv->lock_sctx, &irqL);
7465         pxmitbuf->sctx = NULL;
7466         _exit_critical(&pxmitpriv->lock_sctx, &irqL);
7467
7468          return ret;
7469 }
7470
7471 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7472 {
7473 #ifdef CONFIG_XMIT_ACK
7474         static u8 seq_no = 0;
7475         s32 ret = _FAIL;
7476         u32 timeout_ms = 500;//  500ms
7477         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
7478         #ifdef CONFIG_CONCURRENT_MODE
7479         if (padapter->pbuddy_adapter && !padapter->isprimary)
7480                 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7481         #endif
7482
7483         if (RTW_CANNOT_RUN(padapter)) {
7484                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7485                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7486                 return -1;
7487         }
7488
7489         _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7490         pxmitpriv->ack_tx = _TRUE;
7491         pxmitpriv->seq_no = seq_no++;
7492         pmgntframe->ack_report = 1;
7493         rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7494         if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7495 #ifdef CONFIG_XMIT_ACK_POLLING
7496                 ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7497 #else
7498                 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7499 #endif
7500         }
7501
7502         pxmitpriv->ack_tx = _FALSE;
7503         _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7504
7505          return ret;
7506 #else //!CONFIG_XMIT_ACK
7507         dump_mgntframe(padapter, pmgntframe);
7508         rtw_msleep_os(50);
7509         return _SUCCESS;
7510 #endif //!CONFIG_XMIT_ACK        
7511 }
7512
7513 s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7514 {
7515 #ifdef CONFIG_XMIT_ACK
7516         static u8 seq_no = 0;
7517         s32 ret = _FAIL;
7518         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
7519         #ifdef CONFIG_CONCURRENT_MODE
7520         if (padapter->pbuddy_adapter && !padapter->isprimary)
7521                 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7522         #endif
7523
7524         if (RTW_CANNOT_RUN(padapter)) {
7525                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7526                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7527                 return -1;
7528         }
7529
7530         _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7531         pxmitpriv->ack_tx = _TRUE;
7532         pxmitpriv->seq_no = seq_no++;
7533         pmgntframe->ack_report = 1;
7534         rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7535         if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7536 #ifdef CONFIG_XMIT_ACK_POLLING
7537                 ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7538 #else
7539                 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7540 #endif
7541         }
7542
7543         pxmitpriv->ack_tx = _FALSE;
7544         _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7545
7546          return ret;
7547 #else //!CONFIG_XMIT_ACK
7548         dump_mgntframe(padapter, pmgntframe);
7549         rtw_msleep_os(50);
7550         return _SUCCESS;
7551 #endif //!CONFIG_XMIT_ACK        
7552 }
7553
7554 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7555 {
7556         u8 *ssid_ie;
7557         sint ssid_len_ori;
7558         int len_diff = 0;
7559         
7560         ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
7561
7562         //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
7563         
7564         if(ssid_ie && ssid_len_ori>0)
7565         {
7566                 switch(hidden_ssid_mode)
7567                 {
7568                         case 1:
7569                         {
7570                                 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7571                                 u32 remain_len = 0;
7572                                 
7573                                 remain_len = ies_len -(next_ie-ies);
7574                                 
7575                                 ssid_ie[1] = 0;                         
7576                                 _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
7577                                 len_diff -= ssid_len_ori;
7578                                 
7579                                 break;
7580                         }               
7581                         case 2:
7582                                 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7583                                 break;
7584                         default:
7585                                 break;
7586                 }
7587         }
7588
7589         return len_diff;
7590 }
7591
7592 void issue_beacon(_adapter *padapter, int timeout_ms)
7593 {
7594         struct xmit_frame       *pmgntframe;
7595         struct pkt_attrib       *pattrib;
7596         unsigned char   *pframe;
7597         struct rtw_ieee80211_hdr *pwlanhdr;
7598         unsigned short *fctrl;
7599         unsigned int    rate_len;
7600         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
7601 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7602         _irqL irqL;
7603         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7604 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7605         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7606         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
7607         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
7608         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7609 #ifdef CONFIG_P2P
7610         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
7611 #endif //CONFIG_P2P
7612
7613
7614         //DBG_871X("%s\n", __FUNCTION__);
7615
7616 #ifdef CONFIG_BCN_ICF
7617         if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL)
7618 #else
7619         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7620 #endif
7621         {
7622                 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7623                 return;
7624         }
7625 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7626         _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7627 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7628
7629         //update attribute
7630         pattrib = &pmgntframe->attrib;
7631         update_mgntframe_attrib(padapter, pattrib);
7632         pattrib->qsel = QSLT_BEACON;
7633         #ifdef CONFIG_CONCURRENT_MODE
7634         if(padapter->iface_type == IFACE_PORT1) 
7635                 pattrib->mbssid = 1;
7636         #endif  
7637         
7638         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7639                 
7640         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7641         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
7642         
7643         
7644         fctrl = &(pwlanhdr->frame_ctl);
7645         *(fctrl) = 0;
7646         
7647         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7648         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7649         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7650
7651         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7652         //pmlmeext->mgnt_seq++;
7653         SetFrameSubType(pframe, WIFI_BEACON);
7654         
7655         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);       
7656         pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7657         
7658         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7659         {
7660                 //DBG_871X("ie len=%d\n", cur_network->IELength);
7661 #ifdef CONFIG_P2P
7662                 // for P2P : Primary Device Type & Device Name
7663                 u32 wpsielen=0, insert_len=0;
7664                 u8 *wpsie=NULL;         
7665                 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
7666                 
7667                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
7668                 {
7669                         uint wps_offset, remainder_ielen;
7670                         u8 *premainder_ie, *pframe_wscie;
7671         
7672                         wps_offset = (uint)(wpsie - cur_network->IEs);
7673
7674                         premainder_ie = wpsie + wpsielen;
7675
7676                         remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7677
7678 #ifdef CONFIG_IOCTL_CFG80211
7679                         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7680                         {
7681                                 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
7682                                 {
7683                                         _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7684                                         pframe += wps_offset;
7685                                         pattrib->pktlen += wps_offset;
7686
7687                                         _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7688                                         pframe += pmlmepriv->wps_beacon_ie_len;
7689                                         pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7690
7691                                         //copy remainder_ie to pframe
7692                                         _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7693                                         pframe += remainder_ielen;              
7694                                         pattrib->pktlen += remainder_ielen;
7695                                 }
7696                                 else
7697                                 {
7698                                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7699                                         pframe += cur_network->IELength;
7700                                         pattrib->pktlen += cur_network->IELength;
7701                                 }
7702                         }
7703                         else
7704 #endif //CONFIG_IOCTL_CFG80211
7705                         {
7706                                 pframe_wscie = pframe + wps_offset;
7707                                 _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);                     
7708                                 pframe += (wps_offset + wpsielen);              
7709                                 pattrib->pktlen += (wps_offset + wpsielen);
7710
7711                                 //now pframe is end of wsc ie, insert Primary Device Type & Device Name
7712                                 //      Primary Device Type
7713                                 //      Type:
7714                                 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
7715                                 insert_len += 2;
7716                                 
7717                                 //      Length:
7718                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
7719                                 insert_len += 2;
7720                                 
7721                                 //      Value:
7722                                 //      Category ID
7723                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7724                                 insert_len += 2;
7725
7726                                 //      OUI
7727                                 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
7728                                 insert_len += 4;
7729
7730                                 //      Sub Category ID
7731                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7732                                 insert_len += 2;
7733
7734
7735                                 //      Device Name
7736                                 //      Type:
7737                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7738                                 insert_len += 2;
7739
7740                                 //      Length:
7741                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
7742                                 insert_len += 2;
7743
7744                                 //      Value:
7745                                 _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
7746                                 insert_len += pwdinfo->device_name_len;
7747
7748
7749                                 //update wsc ie length
7750                                 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
7751
7752                                 //pframe move to end
7753                                 pframe+=insert_len;
7754                                 pattrib->pktlen += insert_len;
7755
7756                                 //copy remainder_ie to pframe
7757                                 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7758                                 pframe += remainder_ielen;              
7759                                 pattrib->pktlen += remainder_ielen;
7760                         }
7761                 }
7762                 else
7763 #endif //CONFIG_P2P
7764                 {
7765                         int len_diff;
7766                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7767                         len_diff = update_hidden_ssid(
7768                                 pframe+_BEACON_IE_OFFSET_
7769                                 , cur_network->IELength-_BEACON_IE_OFFSET_
7770                                 , pmlmeinfo->hidden_ssid_mode
7771                         );
7772                         pframe += (cur_network->IELength+len_diff);
7773                         pattrib->pktlen += (cur_network->IELength+len_diff);
7774                 }
7775
7776                 {
7777                         u8 *wps_ie;
7778                         uint wps_ielen;
7779                         u8 sr = 0;
7780                         wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
7781                                 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
7782                         if (wps_ie && wps_ielen>0) {
7783                                 rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
7784                         }
7785                         if (sr != 0)
7786                                 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7787                         else
7788                                 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7789                 }
7790
7791 #ifdef CONFIG_P2P
7792                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
7793                 {
7794                         u32 len;
7795 #ifdef CONFIG_IOCTL_CFG80211
7796                         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7797                         {
7798                                 len = pmlmepriv->p2p_beacon_ie_len;
7799                                 if(pmlmepriv->p2p_beacon_ie && len>0)                           
7800                                         _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7801                         }
7802                         else
7803 #endif //CONFIG_IOCTL_CFG80211
7804                         {
7805                                 len = build_beacon_p2p_ie(pwdinfo, pframe);
7806                         }
7807
7808                         pframe += len;
7809                         pattrib->pktlen += len;
7810
7811                         #ifdef CONFIG_WFD
7812                         len = rtw_append_beacon_wfd_ie(padapter, pframe);
7813                         pframe += len;
7814                         pattrib->pktlen += len;
7815                         #endif
7816                 }
7817 #endif //CONFIG_P2P
7818
7819                 goto _issue_bcn;
7820
7821         }
7822
7823         //below for ad-hoc mode
7824
7825         //timestamp will be inserted by hardware
7826         pframe += 8;
7827         pattrib->pktlen += 8;
7828
7829         // beacon interval: 2 bytes
7830
7831         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
7832
7833         pframe += 2;
7834         pattrib->pktlen += 2;
7835
7836         // capability info: 2 bytes
7837
7838         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7839
7840         pframe += 2;
7841         pattrib->pktlen += 2;
7842
7843         // SSID
7844         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7845
7846         // supported rates...
7847         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7848         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7849
7850         // DS parameter set
7851         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7852
7853         //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7854         {
7855                 u8 erpinfo=0;
7856                 u32 ATIMWindow;
7857                 // IBSS Parameter Set...
7858                 //ATIMWindow = cur->Configuration.ATIMWindow;
7859                 ATIMWindow = 0;
7860                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7861
7862                 //ERP IE
7863                 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7864         }       
7865
7866
7867         // EXTERNDED SUPPORTED RATE
7868         if (rate_len > 8)
7869         {
7870                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7871         }
7872
7873
7874         //todo:HT for adhoc
7875
7876 _issue_bcn:
7877
7878 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7879         pmlmepriv->update_bcn = _FALSE;
7880         
7881         _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);  
7882 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7883
7884         if ((pattrib->pktlen + TXDESC_SIZE) > 512)
7885         {
7886                 DBG_871X("beacon frame too large\n");
7887                 return;
7888         }
7889         
7890         pattrib->last_txcmdsz = pattrib->pktlen;
7891
7892         //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
7893         if(timeout_ms > 0)
7894                 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7895         else
7896                 dump_mgntframe(padapter, pmgntframe);
7897
7898 }
7899
7900 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7901 {
7902         struct xmit_frame                       *pmgntframe;
7903         struct pkt_attrib                       *pattrib;
7904         unsigned char                                   *pframe;
7905         struct rtw_ieee80211_hdr        *pwlanhdr;
7906         unsigned short                          *fctrl; 
7907         unsigned char                                   *mac, *bssid;
7908         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
7909 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7910         u8 *pwps_ie;
7911         uint wps_ielen;
7912         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7913 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7914         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7915         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
7916         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
7917         unsigned int    rate_len;
7918 #ifdef CONFIG_P2P
7919         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
7920 #ifdef CONFIG_WFD
7921         u32                                     wfdielen = 0;
7922 #endif
7923 #endif //CONFIG_P2P
7924
7925         //DBG_871X("%s\n", __FUNCTION__);
7926
7927         if(da == NULL)
7928                 return;
7929
7930         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
7931                 return;
7932
7933         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7934         {
7935                 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7936                 return;
7937         }
7938
7939
7940         //update attribute
7941         pattrib = &pmgntframe->attrib;
7942         update_mgntframe_attrib(padapter, pattrib);     
7943         
7944         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7945                 
7946         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7947         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
7948         
7949         mac = adapter_mac_addr(padapter);
7950         bssid = cur_network->MacAddress;
7951         
7952         fctrl = &(pwlanhdr->frame_ctl);
7953         *(fctrl) = 0;
7954         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7955         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7956         _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7957
7958         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7959         pmlmeext->mgnt_seq++;
7960         SetFrameSubType(fctrl, WIFI_PROBERSP);
7961         
7962         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7963         pattrib->pktlen = pattrib->hdrlen;
7964         pframe += pattrib->hdrlen;
7965
7966
7967         if(cur_network->IELength>MAX_IE_SZ)
7968                 return;
7969         
7970 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7971         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7972         {
7973                 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
7974         
7975                 //inerset & update wps_probe_resp_ie
7976                 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
7977                 {
7978                         uint wps_offset, remainder_ielen;
7979                         u8 *premainder_ie;              
7980         
7981                         wps_offset = (uint)(pwps_ie - cur_network->IEs);
7982
7983                         premainder_ie = pwps_ie + wps_ielen;
7984
7985                         remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
7986
7987                         _rtw_memcpy(pframe, cur_network->IEs, wps_offset);              
7988                         pframe += wps_offset;           
7989                         pattrib->pktlen += wps_offset;          
7990
7991                         wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
7992                         if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
7993                         {
7994                                 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
7995                                 pframe += wps_ielen+2;          
7996                                 pattrib->pktlen += wps_ielen+2; 
7997                         }
7998
7999                         if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
8000                         {
8001                                 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8002                                 pframe += remainder_ielen;              
8003                                 pattrib->pktlen += remainder_ielen;     
8004                         }
8005                 }
8006                 else
8007                 {
8008                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8009                         pframe += cur_network->IELength;
8010                         pattrib->pktlen += cur_network->IELength;
8011                 }
8012
8013                 /* retrieve SSID IE from cur_network->Ssid */
8014                 {
8015                         u8 *ssid_ie;
8016                         sint ssid_ielen;
8017                         sint ssid_ielen_diff;
8018                         u8 buf[MAX_IE_SZ];
8019                         u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
8020
8021                         ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
8022                                 (pframe-ies)-_FIXED_IE_LENGTH_);
8023
8024                         ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
8025
8026                         if (ssid_ie &&  cur_network->Ssid.SsidLength) {
8027                                 uint remainder_ielen;
8028                                 u8 *remainder_ie;
8029                                 remainder_ie = ssid_ie+2;
8030                                 remainder_ielen = (pframe-remainder_ie);
8031
8032                                 if (remainder_ielen > MAX_IE_SZ) {
8033                                         DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
8034                                         remainder_ielen = MAX_IE_SZ;
8035                                 }
8036
8037                                 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
8038                                 _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
8039                                 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
8040                                 _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8041
8042                                 pframe += ssid_ielen_diff;
8043                                 pattrib->pktlen += ssid_ielen_diff;
8044                         }
8045                 }
8046         }       
8047         else            
8048 #endif          
8049         {
8050         
8051                 //timestamp will be inserted by hardware
8052                 pframe += 8;
8053                 pattrib->pktlen += 8;
8054
8055                 // beacon interval: 2 bytes
8056
8057                 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
8058
8059                 pframe += 2;
8060                 pattrib->pktlen += 2;
8061
8062                 // capability info: 2 bytes
8063
8064                 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8065
8066                 pframe += 2;
8067                 pattrib->pktlen += 2;
8068
8069                 //below for ad-hoc mode
8070
8071                 // SSID
8072                 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8073
8074                 // supported rates...
8075                 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8076                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8077
8078                 // DS parameter set
8079                 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8080
8081                 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
8082                 {
8083                         u8 erpinfo=0;
8084                         u32 ATIMWindow;
8085                         // IBSS Parameter Set...
8086                         //ATIMWindow = cur->Configuration.ATIMWindow;
8087                         ATIMWindow = 0;
8088                         pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8089
8090                         //ERP IE
8091                         pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8092                 }
8093
8094                 
8095                 // EXTERNDED SUPPORTED RATE
8096                 if (rate_len > 8)
8097                 {
8098                         pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8099                 }
8100
8101
8102                 //todo:HT for adhoc
8103
8104         }       
8105
8106 #ifdef CONFIG_P2P
8107         if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8108                 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8109                 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec))
8110         {
8111                 u32 len;
8112 #ifdef CONFIG_IOCTL_CFG80211
8113                 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8114                 {
8115                         //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
8116                         len = pmlmepriv->p2p_go_probe_resp_ie_len;
8117                         if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
8118                                 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8119                 }
8120                 else
8121 #endif //CONFIG_IOCTL_CFG80211
8122                 {
8123                         len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8124                 }
8125
8126                 pframe += len;
8127                 pattrib->pktlen += len;
8128                 
8129                 #ifdef CONFIG_WFD
8130                 len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8131                 pframe += len;
8132                 pattrib->pktlen += len;
8133                 #endif
8134         }
8135 #endif //CONFIG_P2P
8136
8137
8138 #ifdef CONFIG_AUTO_AP_MODE
8139 {
8140         struct sta_info *psta;
8141         struct sta_priv *pstapriv = &padapter->stapriv;
8142
8143         DBG_871X("(%s)\n", __FUNCTION__);
8144
8145         //check rc station
8146         psta = rtw_get_stainfo(pstapriv, da);
8147         if (psta && psta->isrc && psta->pid>0)
8148         {
8149                 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
8150                 u8 RC_INFO[14] = {0};
8151                 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
8152                 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8153
8154                 DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8155                         psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
8156
8157                 //append vendor specific ie
8158                 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8159                 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8160                 _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
8161                 _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
8162
8163                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8164         }
8165 }
8166 #endif //CONFIG_AUTO_AP_MODE
8167
8168
8169         pattrib->last_txcmdsz = pattrib->pktlen;
8170         
8171
8172         dump_mgntframe(padapter, pmgntframe);
8173         
8174         return;
8175
8176 }
8177
8178 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
8179 {
8180         int ret = _FAIL;
8181         struct xmit_frame               *pmgntframe;
8182         struct pkt_attrib               *pattrib;
8183         unsigned char                   *pframe;
8184         struct rtw_ieee80211_hdr        *pwlanhdr;
8185         unsigned short          *fctrl;
8186         unsigned char                   *mac;
8187         unsigned char                   bssrate[NumRates];
8188         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
8189         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8190         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8191         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8192         int     bssrate_len = 0;
8193         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8194
8195         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8196                 goto exit;
8197
8198         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8199         {
8200                 goto exit;
8201         }
8202
8203         //update attribute
8204         pattrib = &pmgntframe->attrib;
8205         update_mgntframe_attrib(padapter, pattrib);
8206
8207
8208         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8209
8210         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8211         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8212
8213         mac = adapter_mac_addr(padapter);
8214
8215         fctrl = &(pwlanhdr->frame_ctl);
8216         *(fctrl) = 0;
8217
8218         if (da)
8219         {
8220                 //      unicast probe request frame
8221                 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8222                 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8223         }
8224         else
8225         {
8226                 //      broadcast probe request frame
8227                 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8228                 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8229         }
8230
8231         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8232
8233         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8234         pmlmeext->mgnt_seq++;
8235         SetFrameSubType(pframe, WIFI_PROBEREQ);
8236
8237         pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
8238         pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
8239
8240         if(pssid)
8241                 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8242         else
8243                 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8244
8245         get_rate_set(padapter, bssrate, &bssrate_len);
8246
8247         if (bssrate_len > 8)
8248         {
8249                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8250                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8251         }
8252         else
8253         {
8254                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8255         }
8256
8257         if (ch)
8258                 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8259
8260         if (append_wps) {
8261                 //add wps_ie for wps2.0
8262                 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
8263                 {
8264                         _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8265                         pframe += pmlmepriv->wps_probe_req_ie_len;
8266                         pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8267                         //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
8268                 }
8269         }
8270
8271         pattrib->last_txcmdsz = pattrib->pktlen;
8272
8273         RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
8274
8275         if (wait_ack) {
8276                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8277         } else {
8278                 dump_mgntframe(padapter, pmgntframe);
8279                 ret = _SUCCESS;
8280         }
8281
8282 exit:
8283         return ret;
8284 }
8285
8286 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
8287 {
8288         _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8289 }
8290
8291 /*
8292  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8293  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
8294  * try_cnt means the maximal TX count to try
8295  */
8296 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
8297         int try_cnt, int wait_ms)
8298 {
8299         int ret = _FAIL;
8300         int i = 0;
8301         u32 start = rtw_get_current_time();
8302
8303         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8304                 goto exit;
8305
8306         do
8307         {
8308                 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE);
8309
8310                 i++;
8311
8312                 if (RTW_CANNOT_RUN(padapter))
8313                         break;
8314
8315                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8316                         rtw_msleep_os(wait_ms);
8317
8318         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8319
8320         if (ret != _FAIL) {
8321                 ret = _SUCCESS;
8322                 #ifndef DBG_XMIT_ACK
8323                 goto exit;
8324                 #endif
8325         }
8326
8327         if (try_cnt && wait_ms) {
8328                 if (da)
8329                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8330                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8331                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8332                 else
8333                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8334                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8335                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8336         }
8337 exit:
8338         return ret;
8339 }
8340
8341 // if psta == NULL, indiate we are station(client) now...
8342 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8343 {
8344         struct xmit_frame                       *pmgntframe;
8345         struct pkt_attrib                       *pattrib;
8346         unsigned char                                   *pframe;
8347         struct rtw_ieee80211_hdr        *pwlanhdr;
8348         unsigned short                          *fctrl;
8349         unsigned int                                    val32;
8350         unsigned short                          val16;
8351         int use_shared_key = 0;
8352         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
8353         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8354         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8355
8356         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8357                 return;
8358
8359         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8360         {
8361                 return;
8362         }
8363
8364         //update attribute
8365         pattrib = &pmgntframe->attrib;
8366         update_mgntframe_attrib(padapter, pattrib);
8367
8368         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8369
8370         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8371         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8372
8373         fctrl = &(pwlanhdr->frame_ctl);
8374         *(fctrl) = 0;
8375
8376         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8377         pmlmeext->mgnt_seq++;
8378         SetFrameSubType(pframe, WIFI_AUTH);
8379
8380         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8381         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8382
8383
8384         if(psta)// for AP mode
8385         {
8386 #ifdef CONFIG_NATIVEAP_MLME
8387
8388                 _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);           
8389                 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8390                 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8391
8392         
8393                 // setting auth algo number
8394                 val16 = (u16)psta->authalg;
8395
8396                 if(status != _STATS_SUCCESSFUL_)
8397                         val16 = 0;
8398
8399                 if (val16)      {
8400                         val16 = cpu_to_le16(val16);     
8401                         use_shared_key = 1;
8402                 }
8403
8404                 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8405
8406                 // setting auth seq number
8407                 val16 =(u16)psta->auth_seq;
8408                 val16 = cpu_to_le16(val16);     
8409                 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8410
8411                 // setting status code...
8412                 val16 = status;
8413                 val16 = cpu_to_le16(val16);     
8414                 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8415
8416                 // added challenging text...
8417                 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8418                 {
8419                         pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8420                 }
8421 #endif
8422         }
8423         else
8424         {               
8425                 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8426                 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8427                 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8428         
8429                 // setting auth algo number             
8430                 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
8431                 if (val16)      {
8432                         val16 = cpu_to_le16(val16);     
8433                         use_shared_key = 1;
8434                 }       
8435                 //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
8436                 
8437                 //setting IV for auth seq #3
8438                 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8439                 {
8440                         //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
8441                         val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8442                         val32 = cpu_to_le32(val32);
8443                         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8444
8445                         pattrib->iv_len = 4;
8446                 }
8447
8448                 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8449                 
8450                 // setting auth seq number
8451                 val16 = pmlmeinfo->auth_seq;
8452                 val16 = cpu_to_le16(val16);     
8453                 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8454
8455                 
8456                 // setting status code...
8457                 val16 = status;
8458                 val16 = cpu_to_le16(val16);     
8459                 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8460
8461                 // then checking to see if sending challenging text...
8462                 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8463                 {
8464                         pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8465
8466                         SetPrivacy(fctrl);
8467                         
8468                         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);                       
8469                         
8470                         pattrib->encrypt = _WEP40_;
8471
8472                         pattrib->icv_len = 4;
8473                         
8474                         pattrib->pktlen += pattrib->icv_len;                    
8475                         
8476                 }
8477                 
8478         }
8479
8480         pattrib->last_txcmdsz = pattrib->pktlen;
8481
8482         rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8483         DBG_871X("%s\n", __FUNCTION__);
8484         dump_mgntframe(padapter, pmgntframe);
8485
8486         return;
8487 }
8488
8489
8490 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8491 {
8492 #ifdef CONFIG_AP_MODE
8493         struct xmit_frame       *pmgntframe;
8494         struct rtw_ieee80211_hdr        *pwlanhdr;
8495         struct pkt_attrib *pattrib;
8496         unsigned char   *pbuf, *pframe;
8497         unsigned short val, ie_status;          
8498         unsigned short *fctrl;
8499         struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8500         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8501         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8502         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);  
8503         WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8504         u8 *ie = pnetwork->IEs; 
8505 #ifdef CONFIG_P2P
8506         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
8507 #ifdef CONFIG_WFD
8508         u32                                     wfdielen = 0;
8509 #endif
8510
8511 #endif //CONFIG_P2P
8512
8513         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8514                 return;
8515
8516         DBG_871X("%s\n", __FUNCTION__);
8517
8518         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8519         {
8520                 return;
8521         }
8522
8523         //update attribute
8524         pattrib = &pmgntframe->attrib;
8525         update_mgntframe_attrib(padapter, pattrib);
8526
8527
8528         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8529
8530         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8531         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8532
8533         fctrl = &(pwlanhdr->frame_ctl);
8534         *(fctrl) = 0;
8535
8536         _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
8537         _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8538         _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8539
8540
8541         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8542         pmlmeext->mgnt_seq++;
8543         if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8544                 SetFrameSubType(pwlanhdr, pkt_type);            
8545         else
8546                 return;
8547
8548         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8549         pattrib->pktlen += pattrib->hdrlen;
8550         pframe += pattrib->hdrlen;
8551
8552         //capability
8553         val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8554
8555         pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8556
8557         ie_status = cpu_to_le16(status);
8558         pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8559         
8560         val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
8561         pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8562
8563         if (pstat->bssratelen <= 8)
8564         {
8565                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8566         }       
8567         else 
8568         {
8569                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8570                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
8571         }
8572
8573 #ifdef CONFIG_IEEE80211W        
8574         if (status == _STATS_REFUSED_TEMPORARILY_) {
8575                 u8 timeout_itvl[5];
8576                 u32 timeout_interval = 3000;
8577                 /* Association Comeback time */
8578                 timeout_itvl[0] = 0x03;
8579                 timeout_interval = cpu_to_le32(timeout_interval);
8580                 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
8581                 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8582         }
8583 #endif /* CONFIG_IEEE80211W */
8584
8585 #ifdef CONFIG_80211N_HT
8586         if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
8587         {
8588                 uint ie_len=0;
8589                 
8590                 //FILL HT CAP INFO IE
8591                 //p = hostapd_eid_ht_capabilities_info(hapd, p);
8592                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8593                 if(pbuf && ie_len>0)
8594                 {
8595                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8596                         pframe += (ie_len+2);
8597                         pattrib->pktlen +=(ie_len+2);
8598                 }
8599
8600                 //FILL HT ADD INFO IE
8601                 //p = hostapd_eid_ht_operation(hapd, p);
8602                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8603                 if(pbuf && ie_len>0)
8604                 {
8605                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8606                         pframe += (ie_len+2);
8607                         pattrib->pktlen +=(ie_len+2);
8608                 }
8609                 
8610         }       
8611 #endif
8612
8613         /*adding EXT_CAPAB_IE */
8614         if (pmlmepriv->ext_capab_ie_len > 0) {
8615                 uint ie_len = 0;
8616                 
8617                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8618                 if (pbuf && ie_len > 0) {
8619                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8620                         pframe += (ie_len+2);
8621                         pattrib->pktlen += (ie_len+2);
8622                 }
8623         }       
8624         
8625 #ifdef CONFIG_80211AC_VHT
8626         if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8627                 && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8628                 && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP))
8629         {
8630                 u32 ie_len=0;
8631
8632                 //FILL VHT CAP IE
8633                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8634                 if(pbuf && ie_len>0)
8635                 {
8636                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8637                         pframe += (ie_len+2);
8638                         pattrib->pktlen +=(ie_len+2);
8639                 }
8640
8641                 //FILL VHT OPERATION IE
8642                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8643                 if(pbuf && ie_len>0)
8644                 {
8645                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8646                         pframe += (ie_len+2);
8647                         pattrib->pktlen +=(ie_len+2);
8648                 }
8649         }
8650 #endif //CONFIG_80211AC_VHT
8651
8652         //FILL WMM IE
8653         if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
8654         {
8655                 uint ie_len=0;
8656                 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};     
8657                 
8658                 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
8659                 {                       
8660                         pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));       
8661                         if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6)) 
8662                         {                               
8663                                 _rtw_memcpy(pframe, pbuf, ie_len+2);
8664                                 pframe += (ie_len+2);
8665                                 pattrib->pktlen +=(ie_len+2);
8666                                 
8667                                 break;                          
8668                         }
8669                         
8670                         if ((pbuf == NULL) || (ie_len == 0))
8671                         {
8672                                 break;
8673                         }                       
8674                 }
8675                 
8676         }
8677
8678
8679         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8680         {
8681                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8682         }
8683
8684         //add WPS IE ie for wps 2.0
8685         if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
8686         {
8687                 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8688                 
8689                 pframe += pmlmepriv->wps_assoc_resp_ie_len;
8690                 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8691         }
8692
8693 #ifdef CONFIG_P2P
8694         if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
8695                 u32 len;
8696
8697                 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
8698                         len = 0;
8699                         if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
8700                                 len = pmlmepriv->p2p_assoc_resp_ie_len;
8701                                 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
8702                         }
8703                 } else {
8704                         len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8705                 }
8706                 pframe += len;
8707                 pattrib->pktlen += len;
8708         }
8709
8710         #ifdef CONFIG_WFD
8711         if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8712                 wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
8713                 pframe += wfdielen;
8714                 pattrib->pktlen += wfdielen;
8715         }
8716         #endif
8717
8718 #endif /* CONFIG_P2P */
8719
8720         pattrib->last_txcmdsz = pattrib->pktlen;
8721         
8722         dump_mgntframe(padapter, pmgntframe);
8723         
8724 #endif
8725 }
8726
8727 void issue_assocreq(_adapter *padapter)
8728 {
8729         int ret = _FAIL;
8730         struct xmit_frame                               *pmgntframe;
8731         struct pkt_attrib                               *pattrib;
8732         unsigned char                                   *pframe, *p;
8733         struct rtw_ieee80211_hdr                        *pwlanhdr;
8734         unsigned short                          *fctrl;
8735         unsigned short                          val16;
8736         unsigned int                                    i, j, ie_len, index=0;
8737         unsigned char                                   rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8738         PNDIS_802_11_VARIABLE_IEs       pIE;
8739         struct registry_priv    *pregpriv = &padapter->registrypriv;
8740         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
8741         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8742         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8743         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8744         int     bssrate_len = 0, sta_bssrate_len = 0;
8745         u8      vs_ie_length = 0;
8746 #ifdef CONFIG_P2P
8747         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
8748         u8                                      p2pie[ 255 ] = { 0x00 };
8749         u16                                     p2pielen = 0;   
8750 #ifdef CONFIG_WFD
8751         u32                                     wfdielen = 0;
8752 #endif
8753 #endif //CONFIG_P2P
8754
8755 #ifdef CONFIG_DFS
8756         u16     cap;
8757
8758         /* Dot H */
8759         u8 pow_cap_ele[2] = { 0x00 };
8760         u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2;      //For supported channel
8761 #endif //CONFIG_DFS
8762
8763         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8764                 goto exit;
8765
8766         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8767                 goto exit;
8768
8769         //update attribute
8770         pattrib = &pmgntframe->attrib;
8771         update_mgntframe_attrib(padapter, pattrib);
8772
8773
8774         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8775
8776         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8777         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8778
8779         fctrl = &(pwlanhdr->frame_ctl);
8780         *(fctrl) = 0;
8781         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8782         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8783         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8784
8785         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8786         pmlmeext->mgnt_seq++;
8787         SetFrameSubType(pframe, WIFI_ASSOCREQ);
8788
8789         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8790         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8791
8792         //caps
8793
8794 #ifdef CONFIG_DFS
8795         _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8796         cap |= cap_SpecMgmt;
8797         _rtw_memcpy(pframe, &cap, 2);
8798 #else
8799         _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8800 #endif //CONFIG_DFS
8801
8802         pframe += 2;
8803         pattrib->pktlen += 2;
8804
8805         //listen interval
8806         //todo: listen interval for power saving
8807         val16 = cpu_to_le16(3);
8808         _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
8809         pframe += 2;
8810         pattrib->pktlen += 2;
8811
8812         //SSID
8813         pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8814
8815 #ifdef CONFIG_DFS
8816         /* Dot H */
8817         if(pmlmeext->cur_channel > 14)
8818         {
8819                 pow_cap_ele[0] = 13;    // Minimum transmit power capability
8820                 pow_cap_ele[1] = 21;    // Maximum transmit power capability
8821                 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8822
8823                 //supported channels
8824                 do{
8825                         if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
8826                         {
8827                                 sup_ch[0] = 1;  //First channel number
8828                                 sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;       //Number of channel
8829                         }
8830                         else
8831                         {
8832                                 sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8833                                 sup_ch[idx_5g++] = 1;
8834                         }
8835                         sup_ch_idx++;
8836                 }
8837                 while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
8838                 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8839         }
8840 #endif //CONFIG_DFS
8841
8842         //supported rate & extended supported rate
8843
8844 #if 1   // Check if the AP's supported rates are also supported by STA.
8845         get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8846         //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
8847         
8848         if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK) 
8849         {
8850                 sta_bssrate_len = 4;
8851         }
8852
8853         
8854         //for (i = 0; i < sta_bssrate_len; i++) {
8855         //      DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
8856         //}
8857
8858         for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8859                 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8860                 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8861         }
8862         
8863
8864         for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8865                 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8866
8867                 
8868                 // Check if the AP's supported rates are also supported by STA.
8869                 for (j=0; j < sta_bssrate_len; j++) {
8870                          // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8871                         if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK) 
8872                                         == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
8873                                 //DBG_871X("match i = %d, j=%d\n", i, j);
8874                                 break;
8875                         } else {
8876                                 //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
8877                         }
8878                 }
8879                 
8880                 if (j == sta_bssrate_len) {
8881                         // the rate is not supported by STA
8882                         DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8883                 } else {
8884                         // the rate is supported by STA
8885                         bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8886                 }
8887         }
8888         
8889         bssrate_len = index;
8890         DBG_871X("bssrate_len = %d\n", bssrate_len);
8891
8892 #else   // Check if the AP's supported rates are also supported by STA.
8893 #if 0
8894         get_rate_set(padapter, bssrate, &bssrate_len);
8895 #else
8896         for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8897                 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
8898
8899                 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8900                         break;
8901
8902                 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8903         }
8904 #endif
8905 #endif  // Check if the AP's supported rates are also supported by STA.
8906
8907         if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8908                 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8909                 rtw_free_xmitframe(pxmitpriv, pmgntframe);
8910                 goto exit; //don't connect to AP if no joint supported rate
8911         }
8912
8913
8914         if (bssrate_len > 8)
8915         {
8916                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8917                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8918         }
8919         else if (bssrate_len > 0)
8920         {
8921                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8922         } else {
8923                 DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n",__FUNCTION__);
8924         }
8925
8926         //vendor specific IE, such as WPA, WMM, WPS
8927         for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
8928         {
8929                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8930
8931                 switch (pIE->ElementID)
8932                 {
8933                         case _VENDOR_SPECIFIC_IE_:
8934                                 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8935                                                 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8936                                                 (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8937                                 {       
8938                                         vs_ie_length = pIE->Length;
8939                                         if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8940                                         {
8941                                                 //Commented by Kurt 20110629
8942                                                 //In some older APs, WPS handshake
8943                                                 //would be fail if we append vender extensions informations to AP
8944
8945                                                 vs_ie_length = 14;
8946                                         }
8947                                         
8948                                         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8949                                 }
8950                                 break;
8951
8952                         case EID_WPA2:
8953                                 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8954                                 break;
8955 #ifdef CONFIG_80211N_HT
8956                         case EID_HTCapability:
8957                                 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8958                                         if (!(is_ap_in_tkip(padapter)))
8959                                         {
8960                                                 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8961
8962                                                 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8963
8964                                                 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8965                                         }
8966                                 }
8967                                 break;
8968
8969                         case EID_EXTCapability:
8970                                 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8971                                         pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8972                                 }
8973                                 break;
8974 #endif //CONFIG_80211N_HT
8975 #ifdef CONFIG_80211AC_VHT
8976                         case EID_VHTCapability:
8977                                 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8978                                         pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8979                                 }
8980                                 break;
8981
8982                         case EID_OpModeNotification:
8983                                 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8984                                         pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
8985                                 }
8986                                 break;
8987 #endif // CONFIG_80211AC_VHT
8988                         default:
8989                                 break;
8990                 }
8991
8992                 i += (pIE->Length + 2);
8993         }
8994
8995         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8996         {
8997                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8998         }
8999
9000
9001 #ifdef CONFIG_WAPI_SUPPORT
9002         rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
9003 #endif
9004
9005
9006 #ifdef CONFIG_P2P
9007
9008 #ifdef CONFIG_IOCTL_CFG80211
9009         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
9010         {
9011                 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
9012                 {
9013                         _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
9014                         pframe += pmlmepriv->p2p_assoc_req_ie_len;
9015                         pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
9016                 }
9017         }
9018         else
9019 #endif //CONFIG_IOCTL_CFG80211
9020         {
9021                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
9022                 {
9023                         //      Should add the P2P IE in the association request frame. 
9024                         //      P2P OUI
9025                         
9026                         p2pielen = 0;
9027                         p2pie[ p2pielen++ ] = 0x50;
9028                         p2pie[ p2pielen++ ] = 0x6F;
9029                         p2pie[ p2pielen++ ] = 0x9A;
9030                         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
9031
9032                         //      Commented by Albert 20101109
9033                         //      According to the P2P Specification, the association request frame should contain 3 P2P attributes
9034                         //      1. P2P Capability
9035                         //      2. Extended Listen Timing
9036                         //      3. Device Info
9037                         //      Commented by Albert 20110516
9038                         //      4. P2P Interface
9039
9040                         //      P2P Capability
9041                         //      Type:
9042                         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
9043
9044                         //      Length:
9045                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
9046                         p2pielen += 2;
9047
9048                         //      Value:
9049                         //      Device Capability Bitmap, 1 byte
9050                         p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
9051
9052                         //      Group Capability Bitmap, 1 byte
9053                         if ( pwdinfo->persistent_supported )
9054                                 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9055                         else
9056                                 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
9057
9058                         //      Extended Listen Timing
9059                         //      Type:
9060                         p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
9061
9062                         //      Length:
9063                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
9064                         p2pielen += 2;
9065
9066                         //      Value:
9067                         //      Availability Period
9068                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9069                         p2pielen += 2;
9070
9071                         //      Availability Interval
9072                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9073                         p2pielen += 2;
9074
9075                         //      Device Info
9076                         //      Type:
9077                         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
9078
9079                         //      Length:
9080                         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
9081                         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
9082                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
9083                         p2pielen += 2;
9084
9085                         //      Value:
9086                         //      P2P Device Address
9087                         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9088                         p2pielen += ETH_ALEN;
9089
9090                         //      Config Method
9091                         //      This field should be big endian. Noted by P2P specification.
9092                         if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
9093                                 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
9094                         {
9095                                 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
9096                         }
9097                         else
9098                         {
9099                                 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
9100                         }
9101
9102                         p2pielen += 2;
9103
9104                         //      Primary Device Type
9105                         //      Category ID
9106                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
9107                         p2pielen += 2;
9108
9109                         //      OUI
9110                         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
9111                         p2pielen += 4;
9112
9113                         //      Sub Category ID
9114                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
9115                         p2pielen += 2;
9116
9117                         //      Number of Secondary Device Types
9118                         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
9119
9120                         //      Device Name
9121                         //      Type:
9122                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
9123                         p2pielen += 2;
9124
9125                         //      Length:
9126                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
9127                         p2pielen += 2;
9128
9129                         //      Value:
9130                         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
9131                         p2pielen += pwdinfo->device_name_len;
9132                 
9133                         //      P2P Interface
9134                         //      Type:
9135                         p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
9136                         
9137                         //      Length:
9138                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
9139                         p2pielen += 2;
9140                         
9141                         //      Value:
9142                         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );        //      P2P Device Address
9143                         p2pielen += ETH_ALEN;
9144
9145                         p2pie[ p2pielen++ ] = 1;        //      P2P Interface Address Count
9146                         
9147                         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );        //      P2P Interface Address List
9148                         p2pielen += ETH_ALEN;
9149                 
9150                         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
9151                 }
9152         }
9153
9154 #endif //CONFIG_P2P
9155
9156 #ifdef CONFIG_WFD
9157         wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
9158         pframe += wfdielen;
9159         pattrib->pktlen += wfdielen;
9160 #endif
9161
9162         pattrib->last_txcmdsz = pattrib->pktlen;
9163         dump_mgntframe(padapter, pmgntframe);
9164
9165         ret = _SUCCESS;
9166
9167 exit:
9168         if (ret == _SUCCESS)
9169                 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9170         else
9171                 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9172
9173         return;
9174 }
9175
9176 //when wait_ack is ture, this function shoule be called at process context
9177 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9178 {
9179         int ret = _FAIL;
9180         struct xmit_frame                       *pmgntframe;
9181         struct pkt_attrib                       *pattrib;
9182         unsigned char                                   *pframe;
9183         struct rtw_ieee80211_hdr        *pwlanhdr;
9184         unsigned short                          *fctrl;
9185         struct xmit_priv        *pxmitpriv;
9186         struct mlme_ext_priv    *pmlmeext;
9187         struct mlme_ext_info    *pmlmeinfo;
9188
9189         //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
9190
9191         if(!padapter)
9192                 goto exit;
9193
9194         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9195                 goto exit;
9196
9197         pxmitpriv = &(padapter->xmitpriv);
9198         pmlmeext = &(padapter->mlmeextpriv);
9199         pmlmeinfo = &(pmlmeext->mlmext_info);
9200
9201         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9202         {
9203                 goto exit;
9204         }
9205
9206         //update attribute
9207         pattrib = &pmgntframe->attrib;
9208         update_mgntframe_attrib(padapter, pattrib);
9209         pattrib->retry_ctrl = _FALSE;
9210
9211         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9212
9213         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9214         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9215
9216         fctrl = &(pwlanhdr->frame_ctl);
9217         *(fctrl) = 0;
9218
9219         if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9220         {
9221                 SetFrDs(fctrl);
9222         }
9223         else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9224         {
9225                 SetToDs(fctrl);
9226         }
9227         
9228         if (power_mode)
9229         {
9230                 SetPwrMgt(fctrl);
9231         }
9232
9233         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9234         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9235         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9236
9237         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9238         pmlmeext->mgnt_seq++;
9239         SetFrameSubType(pframe, WIFI_DATA_NULL);
9240
9241         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9242         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9243
9244         pattrib->last_txcmdsz = pattrib->pktlen;
9245
9246         if(wait_ack)
9247         {
9248                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9249         }
9250         else
9251         {
9252                 dump_mgntframe(padapter, pmgntframe);
9253                 ret = _SUCCESS;
9254         }
9255
9256 exit:
9257         return ret;
9258 }
9259
9260 /*
9261  * [IMPORTANT] Don't call this function in interrupt context
9262  *
9263  * When wait_ms > 0, this function should be called at process context
9264  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9265  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9266  * try_cnt means the maximal TX count to try
9267  * da == NULL for station mode
9268  */
9269 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9270 {
9271         int ret = _FAIL;
9272         int i = 0;
9273         u32 start = rtw_get_current_time();
9274         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9275         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9276         struct sta_info *psta;
9277
9278         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9279                 goto exit;
9280
9281         /* da == NULL, assum it's null data for sta to ap*/
9282         if (da == NULL)
9283                 da = get_my_bssid(&(pmlmeinfo->network));
9284
9285         psta = rtw_get_stainfo(&padapter->stapriv, da);
9286         if (psta) {
9287                 if (power_mode)
9288                         rtw_hal_macid_sleep(padapter, psta->mac_id);
9289                 else
9290                         rtw_hal_macid_wakeup(padapter, psta->mac_id);
9291         } else {
9292                 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
9293                         FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
9294                 rtw_warn_on(1);
9295         }
9296
9297         do {
9298                 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
9299
9300                 i++;
9301
9302                 if (RTW_CANNOT_RUN(padapter))
9303                         break;
9304
9305                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9306                         rtw_msleep_os(wait_ms);
9307
9308         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9309
9310         if (ret != _FAIL) {
9311                 ret = _SUCCESS;
9312                 #ifndef DBG_XMIT_ACK
9313                 goto exit;
9314                 #endif
9315         }
9316
9317         if (try_cnt && wait_ms) {
9318                 if (da)
9319                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9320                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9321                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9322                 else
9323                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9324                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9325                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9326         }
9327 exit:
9328         return ret;
9329 }
9330
9331 /*
9332  * [IMPORTANT] This function run in interrupt context
9333  *
9334  * The null data packet would be sent without power bit,
9335  * and not guarantee success.
9336  */
9337 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
9338 {
9339         int ret;
9340         struct mlme_ext_priv *pmlmeext;
9341         struct mlme_ext_info *pmlmeinfo;
9342
9343
9344         pmlmeext = &padapter->mlmeextpriv;
9345         pmlmeinfo = &pmlmeext->mlmext_info;
9346
9347         /* da == NULL, assum it's null data for sta to ap*/
9348         if (da == NULL)
9349                 da = get_my_bssid(&(pmlmeinfo->network));
9350
9351         ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
9352
9353         return ret;
9354 }
9355
9356 //when wait_ack is ture, this function shoule be called at process context
9357 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
9358 {
9359         int ret = _FAIL;
9360         struct xmit_frame                       *pmgntframe;
9361         struct pkt_attrib                       *pattrib;
9362         unsigned char                                   *pframe;
9363         struct rtw_ieee80211_hdr        *pwlanhdr;
9364         unsigned short                          *fctrl, *qc;
9365         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
9366         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9367         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9368
9369         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9370                 goto exit;
9371
9372         DBG_871X("%s\n", __FUNCTION__);
9373
9374         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9375         {
9376                 goto exit;
9377         }
9378
9379         //update attribute
9380         pattrib = &pmgntframe->attrib;
9381         update_mgntframe_attrib(padapter, pattrib);
9382
9383         pattrib->hdrlen +=2;
9384         pattrib->qos_en = _TRUE;
9385         pattrib->eosp = 1;
9386         pattrib->ack_policy = 0;
9387         pattrib->mdata = 0;
9388
9389         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9390
9391         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9392         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9393
9394         fctrl = &(pwlanhdr->frame_ctl);
9395         *(fctrl) = 0;
9396
9397         if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9398         {
9399                 SetFrDs(fctrl);
9400         }
9401         else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9402         {
9403                 SetToDs(fctrl);
9404         }
9405
9406         if(pattrib->mdata)
9407                 SetMData(fctrl);
9408
9409         qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9410         
9411         SetPriority(qc, tid);
9412
9413         SetEOSP(qc, pattrib->eosp);
9414
9415         SetAckpolicy(qc, pattrib->ack_policy);
9416
9417         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9418         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9419         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9420
9421         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9422         pmlmeext->mgnt_seq++;
9423         SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
9424
9425         pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9426         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9427
9428         pattrib->last_txcmdsz = pattrib->pktlen;
9429         
9430         if(wait_ack)
9431         {
9432                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9433         }
9434         else
9435         {
9436                 dump_mgntframe(padapter, pmgntframe);
9437                 ret = _SUCCESS;
9438         }
9439
9440 exit:
9441         return ret;
9442 }
9443
9444 /*
9445  * when wait_ms >0 , this function should be called at process context
9446  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9447  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9448  * try_cnt means the maximal TX count to try
9449  * da == NULL for station mode
9450  */
9451 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
9452 {
9453         int ret = _FAIL;
9454         int i = 0;
9455         u32 start = rtw_get_current_time();
9456         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9457         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9458
9459         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9460                 goto exit;
9461
9462         /* da == NULL, assum it's null data for sta to ap*/
9463         if (da == NULL)
9464                 da = get_my_bssid(&(pmlmeinfo->network));
9465         
9466         do
9467         {
9468                 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
9469
9470                 i++;
9471
9472                 if (RTW_CANNOT_RUN(padapter))
9473                         break;
9474
9475                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9476                         rtw_msleep_os(wait_ms);
9477
9478         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9479
9480         if (ret != _FAIL) {
9481                 ret = _SUCCESS;
9482                 #ifndef DBG_XMIT_ACK
9483                 goto exit;
9484                 #endif
9485         }
9486
9487         if (try_cnt && wait_ms) {
9488                 if (da)
9489                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9490                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9491                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9492                 else
9493                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9494                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9495                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9496         }
9497 exit:
9498         return ret;
9499 }
9500
9501 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9502 {
9503         struct xmit_frame                       *pmgntframe;
9504         struct pkt_attrib                       *pattrib;
9505         unsigned char                                   *pframe;
9506         struct rtw_ieee80211_hdr        *pwlanhdr;
9507         unsigned short                          *fctrl;
9508         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
9509         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9510         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9511         int ret = _FAIL;
9512 #ifdef CONFIG_P2P
9513         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
9514 #endif //CONFIG_P2P     
9515
9516         //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9517
9518 #ifdef CONFIG_P2P
9519         if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
9520         {
9521                 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
9522                 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
9523         }
9524 #endif //CONFIG_P2P
9525
9526         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9527                 goto exit;
9528
9529         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9530         {
9531                 goto exit;
9532         }
9533
9534         //update attribute
9535         pattrib = &pmgntframe->attrib;
9536         update_mgntframe_attrib(padapter, pattrib);
9537         pattrib->retry_ctrl = _FALSE;
9538         pattrib->key_type = key_type;
9539         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9540
9541         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9542         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9543
9544         fctrl = &(pwlanhdr->frame_ctl);
9545         *(fctrl) = 0;
9546
9547         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9548         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9549         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9550
9551         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9552         pmlmeext->mgnt_seq++;
9553         SetFrameSubType(pframe, WIFI_DEAUTH);
9554
9555         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9556         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9557
9558         reason = cpu_to_le16(reason);
9559         pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9560
9561         pattrib->last_txcmdsz = pattrib->pktlen;
9562
9563
9564         if(wait_ack)
9565         {
9566                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9567         }
9568         else
9569         {
9570                 dump_mgntframe(padapter, pmgntframe);
9571                 ret = _SUCCESS;
9572         }
9573
9574 exit:
9575         return ret;
9576 }
9577
9578 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9579 {
9580         DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9581         return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9582 }
9583
9584 #ifdef CONFIG_IEEE80211W
9585 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9586 {
9587         DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9588         return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9589 }
9590 #endif /* CONFIG_IEEE80211W */
9591
9592 /*
9593  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9594  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9595  * try_cnt means the maximal TX count to try
9596  */
9597 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9598         int wait_ms)
9599 {
9600         int ret = _FAIL;
9601         int i = 0;
9602         u32 start = rtw_get_current_time();
9603
9604         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9605                 goto exit;
9606
9607         do
9608         {
9609                 ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE:_FALSE, IEEE80211W_RIGHT_KEY);
9610
9611                 i++;
9612
9613                 if (RTW_CANNOT_RUN(padapter))
9614                         break;
9615
9616                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9617                         rtw_msleep_os(wait_ms);
9618
9619         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9620
9621         if (ret != _FAIL) {
9622                 ret = _SUCCESS;
9623                 #ifndef DBG_XMIT_ACK
9624                 goto exit;
9625                 #endif
9626         }
9627
9628         if (try_cnt && wait_ms) {
9629                 if (da)
9630                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9631                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9632                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9633                 else
9634                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9635                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9636                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9637         }
9638 exit:
9639         return ret;
9640 }
9641
9642 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9643 {       
9644         _irqL   irqL;
9645         _list           *plist, *phead;
9646         struct xmit_frame                       *pmgntframe;
9647         struct pkt_attrib                       *pattrib;
9648         unsigned char                           *pframe;
9649         struct rtw_ieee80211_hdr        *pwlanhdr;
9650         unsigned short                  *fctrl;
9651         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
9652         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9653         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9654         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9655
9656         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9657                 return;
9658
9659         DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9660                 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9661
9662         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9663                 return;
9664
9665         //update attribute
9666         pattrib = &pmgntframe->attrib;
9667         update_mgntframe_attrib(padapter, pattrib);
9668
9669         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9670
9671         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9672         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9673
9674         fctrl = &(pwlanhdr->frame_ctl);
9675         *(fctrl) = 0;
9676
9677         _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9678         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9679         _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9680
9681         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9682         pmlmeext->mgnt_seq++;
9683         SetFrameSubType(pframe, WIFI_ACTION);
9684
9685         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9686         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9687
9688         /* category, action */
9689         {
9690                 u8 category, action;
9691                 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9692                 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9693
9694                 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9695                 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9696         }
9697
9698         pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9699         pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9700                 hal_ch_offset_to_secondary_ch_offset(ch_offset));
9701
9702         pattrib->last_txcmdsz = pattrib->pktlen;
9703
9704         dump_mgntframe(padapter, pmgntframe);
9705
9706 }
9707
9708 #ifdef CONFIG_IEEE80211W
9709 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9710 {
9711         u8      category = RTW_WLAN_CATEGORY_SA_QUERY;
9712         u16     reason_code;
9713         struct xmit_frame               *pmgntframe;
9714         struct pkt_attrib               *pattrib;
9715         u8                                      *pframe;
9716         struct rtw_ieee80211_hdr        *pwlanhdr;
9717         u16                                     *fctrl;
9718         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
9719         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9720         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9721         struct sta_info         *psta;
9722         struct sta_priv         *pstapriv = &padapter->stapriv;
9723         struct registry_priv            *pregpriv = &padapter->registrypriv;
9724         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9725
9726         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9727                 return;
9728
9729         DBG_871X("%s, %04x\n", __FUNCTION__, tid);
9730
9731         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9732         {
9733                 DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9734                 return;
9735         }
9736
9737         //update attribute
9738         pattrib = &pmgntframe->attrib;
9739         update_mgntframe_attrib(padapter, pattrib);
9740         pattrib->key_type = key_type;
9741         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9742
9743         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9744         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9745
9746         fctrl = &(pwlanhdr->frame_ctl);
9747         *(fctrl) = 0;
9748
9749         if(raddr)
9750                 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9751         else
9752                 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9753         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9754         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9755
9756         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9757         pmlmeext->mgnt_seq++;
9758         SetFrameSubType(pframe, WIFI_ACTION);
9759
9760         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9761         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9762
9763         pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9764         pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9765
9766         switch (action)
9767         {
9768                 case 0: //SA Query req
9769                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9770                         pmlmeext->sa_query_seq++;
9771                         /* send sa query request to AP, AP should reply sa query response in 1 second */
9772                         if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9773                                 psta = rtw_get_stainfo(pstapriv, raddr);
9774                                 if (psta != NULL) {
9775                                         /* DBG_871X("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9776                                         _set_timer(&psta->dot11w_expire_timer, 1000);
9777                                 }
9778                         }
9779                         break;
9780
9781                 case 1: //SA Query rsp
9782                         tid = cpu_to_le16(tid);
9783                         /* DBG_871X("rtw_set_fixed_ie, %04x\n", tid); */
9784                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9785                         break;
9786                 default:
9787                         break;
9788         }
9789
9790         pattrib->last_txcmdsz = pattrib->pktlen;
9791
9792         dump_mgntframe(padapter, pmgntframe);
9793 }
9794 #endif //CONFIG_IEEE80211W
9795
9796 /**
9797  * issue_action_ba - internal function to TX Block Ack action frame
9798  * @padapter: the adapter to TX
9799  * @raddr: receiver address
9800  * @action: Block Ack Action
9801  * @tid: tid
9802  * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9803  * @status: status/reason code. used by ADDBA_RESP, DELBA
9804  * @initiator: if we are the initiator of AMPDU association. used by DELBA
9805  * @wait_ack: used xmit ack
9806  *
9807  * Returns:
9808  * _SUCCESS: No xmit ack is used or acked
9809  * _FAIL: not acked when using xmit ack
9810  */
9811 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9812         , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9813 {
9814         int ret = _FAIL;
9815         u8      category = RTW_WLAN_CATEGORY_BACK;
9816         u16     start_seq;
9817         u16     BA_para_set;
9818         u16     BA_timeout_value;
9819         u16     BA_starting_seqctrl;
9820         struct xmit_frame               *pmgntframe;
9821         struct pkt_attrib               *pattrib;
9822         u8                                      *pframe;
9823         struct rtw_ieee80211_hdr        *pwlanhdr;
9824         u16                                     *fctrl;
9825         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
9826         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9827         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9828         struct sta_info         *psta;
9829         struct sta_priv         *pstapriv = &padapter->stapriv;
9830         struct registry_priv            *pregpriv = &padapter->registrypriv;
9831
9832 #ifdef CONFIG_80211N_HT
9833
9834         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9835                 goto exit;
9836
9837         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9838                 goto exit;
9839
9840         //update attribute
9841         pattrib = &pmgntframe->attrib;
9842         update_mgntframe_attrib(padapter, pattrib);
9843
9844         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9845
9846         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9847         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9848
9849         fctrl = &(pwlanhdr->frame_ctl);
9850         *(fctrl) = 0;
9851
9852         //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9853         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9854         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9855         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9856
9857         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9858         pmlmeext->mgnt_seq++;
9859         SetFrameSubType(pframe, WIFI_ACTION);
9860
9861         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9862         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9863
9864         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9865         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9866
9867         if (category == 3)
9868         {
9869                 switch (action)
9870                 {
9871                         case RTW_WLAN_ACTION_ADDBA_REQ:
9872                                 do {
9873                                         pmlmeinfo->dialogToken++;
9874                                 } while (pmlmeinfo->dialogToken == 0);
9875                                 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9876
9877                                 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9878                                 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9879                                 #else
9880                                 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9881                                 #endif
9882
9883                                 BA_para_set = cpu_to_le16(BA_para_set);
9884                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9885
9886                                 //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
9887                                 BA_timeout_value = 5000;//~ 5ms
9888                                 BA_timeout_value = cpu_to_le16(BA_timeout_value);
9889                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9890
9891                                 //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
9892                                 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
9893                                 {
9894                                         start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1;
9895
9896                                         DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9897                                         
9898                                         psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9899                                         
9900                                         BA_starting_seqctrl = start_seq << 4;
9901                                 }
9902                                 
9903                                 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9904                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9905                                 break;
9906
9907                         case RTW_WLAN_ACTION_ADDBA_RESP:
9908                                 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9909                                 status = cpu_to_le16(status);
9910                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9911
9912                                 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9913
9914                                 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9915                                 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9916
9917                                 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9918                                 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9919
9920                                 if (!padapter->registrypriv.wifi_spec) {
9921                                         if(pregpriv->ampdu_amsdu==0)//disabled
9922                                                 BA_para_set &= ~BIT(0);
9923                                         else if(pregpriv->ampdu_amsdu==1)//enabled
9924                                                 BA_para_set |= BIT(0);
9925                                 }
9926
9927                                 BA_para_set = cpu_to_le16(BA_para_set);
9928
9929                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9930                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9931                                 break;
9932
9933                         case RTW_WLAN_ACTION_DELBA:
9934                                 BA_para_set = 0;
9935                                 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9936                                 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9937
9938                                 BA_para_set = cpu_to_le16(BA_para_set);                         
9939                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9940                                 status = cpu_to_le16(status);
9941                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9942                                 break;
9943                         default:
9944                                 break;
9945                 }
9946         }
9947
9948         pattrib->last_txcmdsz = pattrib->pktlen;
9949
9950         if (wait_ack) {
9951                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9952         } else {
9953                 dump_mgntframe(padapter, pmgntframe);
9954                 ret = _SUCCESS;
9955         }
9956
9957 exit:
9958 #endif //CONFIG_80211N_HT
9959         return ret;
9960 }
9961
9962 /**
9963  * issue_addba_req - TX ADDBA_REQ
9964  * @adapter: the adapter to TX
9965  * @ra: receiver address
9966  * @tid: tid
9967  */
9968 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
9969 {
9970         issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
9971                 , tid
9972                 , 0 /* unused */
9973                 , 0 /* unused */
9974                 , 0 /* unused */
9975                 , _FALSE
9976         );
9977         DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
9978                 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
9979
9980 }
9981
9982 /**
9983  * issue_addba_rsp - TX ADDBA_RESP
9984  * @adapter: the adapter to TX
9985  * @ra: receiver address
9986  * @tid: tid
9987  * @status: status code
9988  * @size: the announced AMPDU buffer size
9989  */
9990 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
9991 {
9992         issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9993                 , tid
9994                 , size
9995                 , status
9996                 , 0 /* unused */
9997                 , _FALSE
9998         );
9999         DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
10000                 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
10001 }
10002
10003 /**
10004  * issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
10005  * @adapter: the adapter to TX
10006  * @ra: receiver address
10007  * @tid: tid
10008  * @status: status code
10009  * @size: the announced AMPDU buffer size
10010  * @try_cnt: the maximal TX count to try
10011  * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10012  *           > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10013  */
10014 inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
10015 {
10016         int ret = _FAIL;
10017         int i = 0;
10018         u32 start = rtw_get_current_time();
10019
10020         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
10021                 goto exit;
10022
10023         do {
10024                 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10025                         , tid
10026                         , size
10027                         , status
10028                         , 0 /* unused */
10029                         , _TRUE
10030                 );
10031
10032                 i++;
10033
10034                 if (RTW_CANNOT_RUN(adapter))
10035                         break;
10036
10037                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10038                         rtw_msleep_os(wait_ms);
10039
10040         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10041
10042         if (ret != _FAIL) {
10043                 ret = _SUCCESS;
10044         #ifndef DBG_XMIT_ACK
10045                 /* goto exit; */
10046         #endif
10047         }
10048
10049         if (try_cnt && wait_ms) {
10050                 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u%s, %d/%d in %u ms\n"
10051                         , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid
10052                         , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10053         }
10054
10055 exit:
10056         return ret;
10057 }
10058
10059 /**
10060  * issue_del_ba - TX DELBA
10061  * @adapter: the adapter to TX
10062  * @ra: receiver address
10063  * @tid: tid
10064  * @reason: reason code
10065  * @initiator: if we are the initiator of AMPDU association. used by DELBA
10066  */
10067 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10068 {
10069         issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10070                 , tid
10071                 , 0 /* unused */
10072                 , reason
10073                 , initiator
10074                 , _FALSE
10075         );
10076         DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10077                 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10078 }
10079
10080 /**
10081  * issue_del_ba_ex - TX DELBA with xmit ack options
10082  * @adapter: the adapter to TX
10083  * @ra: receiver address
10084  * @tid: tid
10085  * @reason: reason code
10086  * @initiator: if we are the initiator of AMPDU association. used by DELBA
10087  * @try_cnt: the maximal TX count to try
10088  * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10089  *           > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10090  */
10091 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10092         , int try_cnt, int wait_ms)
10093 {
10094         int ret = _FAIL;
10095         int i = 0;
10096         u32 start = rtw_get_current_time();
10097
10098         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
10099                 goto exit;
10100
10101         do {
10102                 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10103                         , tid
10104                         , 0 /* unused */
10105                         , reason
10106                         , initiator
10107                         , wait_ms > 0?_TRUE:_FALSE
10108                 );
10109
10110                 i++;
10111
10112                 if (RTW_CANNOT_RUN(adapter))
10113                         break;
10114
10115                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10116                         rtw_msleep_os(wait_ms);
10117
10118         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10119
10120         if (ret != _FAIL) {
10121                 ret = _SUCCESS;
10122         #ifndef DBG_XMIT_ACK
10123                 /* goto exit; */
10124         #endif
10125         }
10126
10127         if (try_cnt && wait_ms) {
10128                 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
10129                         , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
10130                         , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10131         }
10132 exit:
10133         return ret;
10134 }
10135
10136 static void issue_action_BSSCoexistPacket(_adapter *padapter)
10137 {       
10138         _irqL   irqL;
10139         _list           *plist, *phead;
10140         unsigned char category, action;
10141         struct xmit_frame                       *pmgntframe;
10142         struct pkt_attrib                       *pattrib;
10143         unsigned char                           *pframe;
10144         struct rtw_ieee80211_hdr        *pwlanhdr;
10145         unsigned short                  *fctrl;
10146         struct  wlan_network    *pnetwork = NULL;
10147         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
10148         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10149         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
10150         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10151         _queue          *queue  = &(pmlmepriv->scanned_queue);
10152         u8 InfoContent[16] = {0};
10153         u8 ICS[8][15];
10154 #ifdef CONFIG_80211N_HT 
10155         if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
10156                 return;
10157
10158         if(_TRUE == pmlmeinfo->bwmode_updated)
10159                 return;
10160
10161         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10162                 return; 
10163
10164         DBG_871X("%s\n", __FUNCTION__);
10165
10166
10167         category = RTW_WLAN_CATEGORY_PUBLIC;
10168         action = ACT_PUBLIC_BSSCOEXIST;
10169
10170         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10171         {
10172                 return;
10173         }
10174
10175         //update attribute
10176         pattrib = &pmgntframe->attrib;
10177         update_mgntframe_attrib(padapter, pattrib);
10178
10179         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10180
10181         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10182         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10183
10184         fctrl = &(pwlanhdr->frame_ctl);
10185         *(fctrl) = 0;
10186
10187         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10188         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10189         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10190
10191         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10192         pmlmeext->mgnt_seq++;
10193         SetFrameSubType(pframe, WIFI_ACTION);
10194
10195         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10196         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10197
10198         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10199         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10200
10201
10202         //
10203         if(pmlmepriv->num_FortyMHzIntolerant>0)
10204         {
10205                 u8 iedata=0;
10206                 
10207                 iedata |= BIT(2);//20 MHz BSS Width Request
10208
10209                 pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &(pattrib->pktlen));
10210                 
10211         }
10212         
10213
10214         //
10215         _rtw_memset(ICS, 0, sizeof(ICS));
10216         if(pmlmepriv->num_sta_no_ht>0)
10217         {       
10218                 int i;
10219         
10220                 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10221
10222                 phead = get_list_head(queue);
10223                 plist = get_next(phead);
10224        
10225                 while(1)
10226                 {
10227                         int len;
10228                         u8 *p;
10229                         WLAN_BSSID_EX *pbss_network;
10230         
10231                         if (rtw_end_of_queue_search(phead,plist)== _TRUE)
10232                                 break;          
10233
10234                         pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);      
10235                 
10236                         plist = get_next(plist);
10237
10238                         pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10239
10240                         p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10241                         if((p==NULL) || (len==0))//non-HT
10242                         {
10243                                 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
10244                                         continue;
10245                                 
10246                                 ICS[0][pbss_network->Configuration.DSConfig]=1;
10247                                 
10248                                 if(ICS[0][0] == 0)
10249                                         ICS[0][0] = 1;          
10250                         }               
10251         
10252                 }        
10253
10254                 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10255
10256
10257                 for(i= 0;i<8;i++)
10258                 {
10259                         if(ICS[i][0] == 1)
10260                         {
10261                                 int j, k = 0;
10262                                 
10263                                 InfoContent[k] = i;                             
10264                                 //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
10265                                 k++;
10266                                 
10267                                 for(j=1;j<=14;j++)
10268                                 {
10269                                         if(ICS[i][j]==1)
10270                                         {
10271                                                 if(k<16)
10272                                                 {
10273                                                         InfoContent[k] = j; //channel number
10274                                                         //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
10275                                                         k++;
10276                                                 }       
10277                                         }       
10278                                 }       
10279
10280                                 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10281                                 
10282                         }
10283                         
10284                 }
10285                 
10286
10287         }
10288                 
10289
10290         pattrib->last_txcmdsz = pattrib->pktlen;
10291
10292         dump_mgntframe(padapter, pmgntframe);
10293 #endif //CONFIG_80211N_HT
10294 }
10295
10296 // Spatial Multiplexing Powersave (SMPS) action frame
10297 int _issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode ,  u8 wait_ack)
10298 {
10299
10300         int ret = _FAIL;
10301         unsigned char category = RTW_WLAN_CATEGORY_HT;
10302         u8 action = RTW_WLAN_ACTION_HT_SM_PS;   
10303         u8 sm_power_control=0;
10304         struct xmit_frame                       *pmgntframe;
10305         struct pkt_attrib                       *pattrib;
10306         unsigned char                                   *pframe;
10307         struct rtw_ieee80211_hdr        *pwlanhdr;
10308         unsigned short                          *fctrl;
10309         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
10310         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
10311         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10312
10313
10314         if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED)
10315         {
10316                 sm_power_control = sm_power_control  & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable 
10317         }
10318         else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC)
10319         {
10320                 sm_power_control = sm_power_control | BIT(0);    // SM Power Save Enable = 1 SM Power Save Enable  
10321                 sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode
10322         }
10323         else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC)
10324         {
10325                 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable  
10326                 sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode
10327         }
10328         else 
10329                 return ret;
10330
10331         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10332                 return ret;
10333
10334         DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode );
10335     
10336         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10337                 return ret;
10338
10339         //update attribute
10340         pattrib = &pmgntframe->attrib;
10341         update_mgntframe_attrib(padapter, pattrib);
10342
10343         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10344
10345         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10346         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10347
10348         fctrl = &(pwlanhdr->frame_ctl);
10349         *(fctrl) = 0;
10350
10351         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10352         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10353         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10354
10355         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10356         pmlmeext->mgnt_seq++;
10357         SetFrameSubType(pframe, WIFI_ACTION);
10358
10359         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10360         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10361
10362         /* category, action */
10363         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10364         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10365
10366         pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10367
10368         pattrib->last_txcmdsz = pattrib->pktlen;
10369
10370         if(wait_ack)
10371         {
10372                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10373         }
10374         else
10375         {
10376                 dump_mgntframe(padapter, pmgntframe);
10377                 ret = _SUCCESS;
10378         }
10379
10380         if (ret != _SUCCESS)
10381             DBG_8192C("%s, ack to\n", __func__);
10382
10383         return ret;
10384 }
10385
10386 /*
10387  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10388  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10389  * try_cnt means the maximal TX count to try
10390  */
10391 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10392 {
10393         int ret = _FAIL;
10394         int i = 0;
10395         u32 start = rtw_get_current_time();
10396
10397         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10398                 goto exit;
10399
10400         do {
10401                 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE );
10402
10403                 i++;
10404
10405                 if (RTW_CANNOT_RUN(padapter))
10406                         break;
10407
10408                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
10409                         rtw_msleep_os(wait_ms);
10410
10411         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
10412
10413         if (ret != _FAIL) {
10414                 ret = _SUCCESS;
10415                 #ifndef DBG_XMIT_ACK
10416                 goto exit;
10417                 #endif
10418         }
10419
10420         if (try_cnt && wait_ms) {
10421                 if (raddr)
10422                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10423                                 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10424                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10425                 else
10426                         DBG_871X(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10427                                 FUNC_ADPT_ARG(padapter),
10428                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10429         }
10430 exit:
10431
10432         return ret;
10433 }
10434
10435 int issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode )
10436 {
10437         DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10438         return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE );
10439 }
10440
10441 /**
10442  * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10443  * @adapter: the adapter to which @sta belongs
10444  * @initiator: if we are the initiator of AMPDU association
10445  * @sta: the sta to be checked
10446  * @tid: the tid to be checked
10447  * @force: cancel and send DELBA even when no AMPDU association is setup
10448  * @wait_ack: send delba with xmit ack (valid when initiator == 0)
10449  *
10450  * Returns:
10451  * _FAIL if sta is NULL
10452  * when initiator is 1, always _SUCCESS
10453  * when initiator is 0, _SUCCESS if DELBA is acked
10454  */
10455 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10456         , u8 force, int wait_ack)
10457 {
10458         int ret = _SUCCESS;
10459
10460         if (sta == NULL) {
10461                 ret = _FAIL;
10462                 goto exit;
10463         }
10464
10465         if (initiator == 0) {
10466                 /* recipient */
10467                 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10468                         u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10469
10470                         sta->recvreorder_ctrl[tid].enable = _FALSE;
10471                         sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10472
10473                         if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10474                                 ret = _FAIL;
10475                         else if (wait_ack)
10476                                 ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
10477                         else
10478                                 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10479
10480                         if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10481                                 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10482                 }
10483         } else if (initiator == 1) {
10484                 /* originator */
10485 #ifdef CONFIG_80211N_HT
10486                 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10487                         sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10488                         sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10489                         issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10490                 }
10491 #endif
10492         }
10493
10494 exit:
10495         return ret;
10496 }
10497
10498 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10499         , u8 force)
10500 {
10501         return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10502 }
10503
10504 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10505         , u8 force)
10506 {
10507         return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10508 }
10509
10510 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10511 {
10512         struct sta_priv *pstapriv = &padapter->stapriv;
10513         struct sta_info *psta = NULL;
10514         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10515         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10516         u16 tid;
10517
10518         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
10519                 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10520                         return _SUCCESS;
10521
10522         psta = rtw_get_stainfo(pstapriv, addr);
10523         if(psta==NULL)
10524                 return _SUCCESS;
10525
10526         #if 0
10527         DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR");
10528         if (initiator == 1) /* originator */
10529                 DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10530         #endif
10531
10532         for (tid = 0; tid < TID_NUM; tid++)
10533                 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10534
10535         return _SUCCESS;
10536 }
10537
10538 unsigned int send_beacon(_adapter *padapter)
10539 {
10540         u8      bxmitok = _FALSE;
10541         int     issue=0;
10542         int poll = 0;
10543 #if defined(CONFIG_PCI_HCI) && defined(RTL8814AE_SW_BCN)
10544         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
10545 #endif
10546 //#ifdef CONFIG_CONCURRENT_MODE
10547         //struct mlme_ext_priv  *pmlmeext = &(padapter->mlmeextpriv);
10548         //struct mlme_ext_info  *pmlmeinfo = &(pmlmeext->mlmext_info);
10549         //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
10550         //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
10551 //#endif                
10552
10553 #ifdef CONFIG_PCI_HCI
10554         //DBG_871X("%s\n", __FUNCTION__);
10555
10556         rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10557
10558         /* 8192EE Port select for Beacon DL */
10559         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10560
10561         issue_beacon(padapter, 0);
10562
10563 #ifdef RTL8814AE_SW_BCN
10564         if (pHalData->bCorrectBCN != 0)
10565                 DBG_871X("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
10566         pHalData->bCorrectBCN = 1;
10567 #endif
10568
10569         return _SUCCESS;
10570 #endif
10571
10572 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10573         u32 start = rtw_get_current_time();
10574
10575         rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10576         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10577         do{
10578                 issue_beacon(padapter, 100);
10579                 issue++;
10580                 do {
10581                         rtw_yield_os();
10582                         rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10583                         poll++;
10584                 } while ((poll%10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10585
10586         } while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter));
10587
10588         if (RTW_CANNOT_RUN(padapter))
10589                 return _FAIL;
10590
10591         
10592         if(_FALSE == bxmitok)
10593         {
10594                 DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10595                 return _FAIL;
10596         }
10597         else
10598         {
10599                 u32 passing_time = rtw_get_passing_time_ms(start);
10600
10601                 if(passing_time > 100 || issue > 3)
10602                         DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10603                 //else
10604                 //      DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10605                 
10606                 rtw_hal_fw_correct_bcn(padapter);
10607
10608                 return _SUCCESS;
10609         }
10610
10611 #endif
10612
10613 }
10614
10615 /****************************************************************************
10616
10617 Following are some utitity fuctions for WiFi MLME
10618
10619 *****************************************************************************/
10620
10621 BOOLEAN IsLegal5GChannel(
10622         IN PADAPTER                     Adapter,
10623         IN u8                   channel)
10624 {
10625         
10626         int i=0;
10627         u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
10628                 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
10629                 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
10630                 161,163,165};
10631         for(i=0;i<sizeof(Channel_5G);i++)
10632                 if(channel == Channel_5G[i])
10633                         return _TRUE;
10634         return _FALSE;
10635 }
10636
10637 //collect bss info from Beacon and Probe request/response frames.
10638 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10639 {
10640         int     i;
10641         u32     len;
10642         u8      *p;
10643         u16     val16, subtype;
10644         u8      *pframe = precv_frame->u.hdr.rx_data;
10645         u32     packet_len = precv_frame->u.hdr.len;
10646         u8 ie_offset;
10647         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
10648         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10649         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10650
10651         len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10652
10653         if (len > MAX_IE_SZ)
10654         {
10655                 //DBG_871X("IE too long for survey event\n");
10656                 return _FAIL;
10657         }
10658
10659         _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10660
10661         subtype = GetFrameSubType(pframe);
10662
10663         if(subtype==WIFI_BEACON) {
10664                 bssid->Reserved[0] = 1;
10665                 ie_offset = _BEACON_IE_OFFSET_;
10666         } else {
10667                 // FIXME : more type
10668                 if (subtype == WIFI_PROBERSP) {
10669                         ie_offset = _PROBERSP_IE_OFFSET_;
10670                         bssid->Reserved[0] = 3;
10671                 }
10672                 else if (subtype == WIFI_PROBEREQ) {
10673                         ie_offset = _PROBEREQ_IE_OFFSET_;
10674                         bssid->Reserved[0] = 2;
10675                 }
10676                 else {
10677                         bssid->Reserved[0] = 0;
10678                         ie_offset = _FIXED_IE_LENGTH_;
10679                 }
10680         }
10681                 
10682         bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10683
10684         //below is to copy the information element
10685         bssid->IELength = len;
10686         _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10687
10688         //get the signal strength
10689         //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
10690         bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data    
10691         bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage 
10692         bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
10693 #ifdef CONFIG_ANTENNA_DIVERSITY
10694         rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
10695 #endif
10696
10697         // checking SSID
10698         if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
10699         {
10700                 DBG_871X("marc: cannot find SSID for survey event\n");
10701                 return _FAIL;
10702         }
10703
10704         if (*(p + 1))
10705         {
10706                 if (len > NDIS_802_11_LENGTH_SSID)
10707                 {
10708                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10709                         return _FAIL;
10710                 }
10711                 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10712                 bssid->Ssid.SsidLength = *(p + 1);
10713         }
10714         else
10715         {
10716                 bssid->Ssid.SsidLength = 0;
10717         }
10718
10719         _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10720
10721         //checking rate info...
10722         i = 0;
10723         p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10724         if (p != NULL)
10725         {
10726                 if (len > NDIS_802_11_LENGTH_RATES_EX)
10727                 {
10728                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10729                         return _FAIL;
10730                 }
10731                 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10732                 i = len;
10733         }
10734
10735         p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10736         if (p != NULL)
10737         {
10738                 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
10739                 {
10740                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10741                         return _FAIL;
10742                 }
10743                 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10744         }
10745
10746         //todo:
10747 #if 0
10748         if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10749         {
10750                 bssid->NetworkTypeInUse = Ndis802_11DS;
10751         }
10752         else
10753 #endif
10754         {
10755                 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10756         }
10757
10758 #ifdef CONFIG_P2P
10759         if (subtype == WIFI_PROBEREQ)
10760         {
10761                 u8 *p2p_ie;
10762                 u32     p2p_ielen;
10763                 // Set Listion Channel
10764                 if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen)))
10765                 {
10766                         u32     attr_contentlen = 0;
10767                         u8 listen_ch[5] = { 0x00 };
10768
10769                         rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10770                         bssid->Configuration.DSConfig = listen_ch[4];
10771                 } else
10772                 { // use current channel
10773                         bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10774                         DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10775                 }
10776
10777                 // FIXME
10778                 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10779                 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10780                 bssid->Privacy = 1;
10781                 return _SUCCESS;
10782         }
10783 #endif //CONFIG_P2P
10784
10785         if (bssid->IELength < 12)
10786                 return _FAIL;
10787
10788         // Checking for DSConfig
10789         p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10790
10791         bssid->Configuration.DSConfig = 0;
10792         bssid->Configuration.Length = 0;
10793
10794         if (p)
10795         {
10796                 bssid->Configuration.DSConfig = *(p + 2);
10797         }
10798         else
10799         {// In 5G, some ap do not have DSSET IE
10800                 // checking HT info for channel
10801                 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10802                 if(p)
10803                 {
10804                         struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10805                         bssid->Configuration.DSConfig = HT_info->primary_channel;
10806                 }
10807                 else
10808                 { // use current channel
10809                         bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
10810                 }
10811         }
10812
10813         _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
10814         bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
10815
10816         val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
10817
10818         if (val16 & BIT(0))
10819         {
10820                 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10821                 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10822         }
10823         else
10824         {
10825                 bssid->InfrastructureMode = Ndis802_11IBSS;
10826                 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10827         }
10828
10829         if (val16 & BIT(4))
10830                 bssid->Privacy = 1;
10831         else
10832                 bssid->Privacy = 0;
10833
10834         bssid->Configuration.ATIMWindow = 0;
10835
10836         //20/40 BSS Coexistence check
10837         if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
10838         {       
10839                 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10840 #ifdef CONFIG_80211N_HT
10841                 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10842                 if(p && len>0)
10843                 {
10844                         struct HT_caps_element  *pHT_caps;
10845                         pHT_caps = (struct HT_caps_element      *)(p + 2);
10846                         
10847                         if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
10848                         {                               
10849                                 pmlmepriv->num_FortyMHzIntolerant++;
10850                         }
10851                 }
10852                 else
10853                 {
10854                         pmlmepriv->num_sta_no_ht++;
10855                 }
10856 #endif //CONFIG_80211N_HT
10857                 
10858         }
10859
10860 #ifdef CONFIG_INTEL_WIDI
10861         //process_intel_widi_query_or_tigger(padapter, bssid);
10862         if(process_intel_widi_query_or_tigger(padapter, bssid))
10863         {
10864                 return _FAIL;
10865         }
10866 #endif // CONFIG_INTEL_WIDI
10867
10868         #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10869         if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10870                 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10871                         , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10872                         , rtw_get_oper_ch(padapter)
10873                         , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10874                 );
10875         }
10876         #endif
10877
10878         // mark bss info receving from nearby channel as SignalQuality 101
10879         if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10880         {
10881                 bssid->PhyInfo.SignalQuality= 101;
10882         }
10883
10884         return _SUCCESS;
10885 }
10886
10887 void start_create_ibss(_adapter* padapter)
10888 {
10889         unsigned short  caps;
10890         u8      val8;
10891         u8      join_type;
10892         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10893         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10894         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10895         u8 doiqk = _FALSE;
10896         pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10897         pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10898
10899         //update wireless mode
10900         update_wireless_mode(padapter);
10901
10902         //udpate capability
10903         caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10904         update_capinfo(padapter, caps);
10905         if(caps&cap_IBSS)//adhoc master
10906         {
10907                 //set_opmode_cmd(padapter, adhoc);//removed
10908
10909                 val8 = 0xcf;
10910                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10911
10912                 doiqk = _TRUE;
10913                 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10914
10915                 //switch channel
10916                 //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
10917                 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10918
10919                 doiqk = _FALSE;
10920                 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10921
10922                 beacon_timing_control(padapter);
10923
10924                 //set msr to WIFI_FW_ADHOC_STATE
10925                 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10926                 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10927
10928                 //issue beacon
10929                 if(send_beacon(padapter)==_FAIL)
10930                 {
10931                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
10932
10933                         report_join_res(padapter, -1);
10934                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
10935                 }
10936                 else
10937                 {
10938                         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10939                         join_type = 0;
10940                         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10941
10942                         report_join_res(padapter, 1);
10943                         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10944                         rtw_indicate_connect(padapter);
10945                 }
10946         }
10947         else
10948         {
10949                 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
10950                 return;
10951         }
10952         //update bc/mc sta_info
10953         update_bmc_sta(padapter);
10954
10955 }
10956
10957 void start_clnt_join(_adapter* padapter)
10958 {
10959         unsigned short  caps;
10960         u8      val8;
10961         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10962         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10963         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10964         int beacon_timeout;
10965         u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
10966
10967         //update wireless mode
10968         update_wireless_mode(padapter);
10969
10970         //udpate capability
10971         caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10972         update_capinfo(padapter, caps);
10973         
10974         //check if sta is ASIX peer and fix IOT issue if it is.
10975         if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
10976                 u8 iot_flag = _TRUE;
10977                 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10978         }
10979         
10980         if (caps&cap_ESS)
10981         {
10982                 Set_MSR(padapter, WIFI_FW_STATION_STATE);
10983
10984                 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
10985
10986 #ifdef CONFIG_WAPI_SUPPORT
10987                 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
10988                 {
10989                         //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
10990                         val8 = 0x4c;
10991                 }
10992 #endif
10993                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10994
10995                 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10996                 // Because of AP's not receiving deauth before
10997                 // AP may: 1)not response auth or 2)deauth us after link is complete
10998                 // issue deauth before issuing auth to deal with the situation
10999
11000                 //      Commented by Albert 2012/07/21
11001                 //      For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
11002                 {
11003                         #ifdef CONFIG_P2P
11004                         _queue *queue = &(padapter->mlmepriv.scanned_queue);
11005                         _list   *head = get_list_head(queue);
11006                         _list *pos = get_next(head);
11007                         struct wlan_network *scanned = NULL;
11008                         u8 ie_offset = 0;
11009                         _irqL irqL;
11010                         bool has_p2p_ie = _FALSE;
11011
11012                         _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11013
11014                         for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
11015                                 
11016                                 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
11017
11018                                 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
11019                                         && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
11020                                 ) {
11021                                         ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
11022                                         if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
11023                                                 has_p2p_ie = _TRUE;
11024                                         break;
11025                                 }
11026                         }
11027         
11028                         _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11029
11030                         if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
11031                         #endif /* CONFIG_P2P */
11032                                 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
11033                                 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
11034                 }
11035                 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11036
11037                 //here wait for receiving the beacon to start auth
11038                 //and enable a timer
11039                 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11040                 set_link_timer(pmlmeext, beacon_timeout);       
11041                 _set_timer( &padapter->mlmepriv.assoc_timer, 
11042                         (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
11043                 
11044                 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11045         }
11046         else if (caps&cap_IBSS) //adhoc client
11047         {
11048                 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11049
11050                 val8 = 0xcf;
11051                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11052
11053                 beacon_timing_control(padapter);
11054
11055                 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11056
11057                 report_join_res(padapter, 1);
11058         }
11059         else
11060         {
11061                 //DBG_871X("marc: invalid cap:%x\n", caps);
11062                 return;
11063         }
11064
11065 }
11066
11067 void start_clnt_auth(_adapter* padapter)
11068 {
11069         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11070         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11071
11072         _cancel_timer_ex(&pmlmeext->link_timer);
11073
11074         pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
11075         pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
11076
11077         pmlmeinfo->auth_seq = 1;
11078         pmlmeinfo->reauth_count = 0;
11079         pmlmeinfo->reassoc_count = 0;
11080         pmlmeinfo->link_count = 0;
11081         pmlmeext->retry = 0;
11082
11083
11084         DBG_871X_LEVEL(_drv_always_, "start auth\n");
11085         issue_auth(padapter, NULL, 0);
11086
11087         set_link_timer(pmlmeext, REAUTH_TO);
11088
11089 }
11090
11091
11092 void start_clnt_assoc(_adapter* padapter)
11093 {
11094         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11095         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11096
11097         _cancel_timer_ex(&pmlmeext->link_timer);
11098
11099         pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
11100         pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
11101
11102         issue_assocreq(padapter);
11103
11104         set_link_timer(pmlmeext, REASSOC_TO);
11105 }
11106
11107 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
11108 {
11109         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11110         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11111
11112         if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
11113                 return _SUCCESS;
11114
11115         DBG_871X("%s\n", __FUNCTION__);
11116
11117         if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11118         {
11119                 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11120                 {
11121                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
11122                         report_del_sta_event(padapter, MacAddr, reason, _TRUE);
11123
11124                 }
11125                 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
11126                 {
11127                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
11128                         report_join_res(padapter, -2);
11129                 } else
11130                         DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
11131         }
11132
11133         return _SUCCESS;
11134 }
11135
11136 #ifdef CONFIG_80211D
11137 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
11138 {
11139         struct registry_priv *pregistrypriv;
11140         struct mlme_ext_priv *pmlmeext;
11141         RT_CHANNEL_INFO *chplan_new;
11142         u8 channel;
11143         u8 i;
11144
11145
11146         pregistrypriv = &padapter->registrypriv;
11147         pmlmeext = &padapter->mlmeextpriv;
11148
11149         // Adjust channel plan by AP Country IE
11150         if (pregistrypriv->enable80211d &&
11151                 (!pmlmeext->update_channel_plan_by_ap_done))
11152         {
11153                 u8 *ie, *p;
11154                 u32 len;
11155                 RT_CHANNEL_PLAN chplan_ap;
11156                 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
11157                 u8 country[4];
11158                 u8 fcn; // first channel number
11159                 u8 noc; // number of channel
11160                 u8 j, k;
11161
11162                 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11163                 if (!ie) return;
11164                 if (len < 6) return;
11165
11166                 ie += 2;
11167                 p = ie;
11168                 ie += len;
11169
11170                 _rtw_memset(country, 0, 4);
11171                 _rtw_memcpy(country, p, 3);
11172                 p += 3;
11173                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11174                                 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
11175
11176                 i = 0;
11177                 while ((ie - p) >= 3)
11178                 {
11179                         fcn = *(p++);
11180                         noc = *(p++);
11181                         p++;
11182
11183                         for (j = 0; j < noc; j++)
11184                         {
11185                                 if (fcn <= 14) channel = fcn + j; // 2.4 GHz
11186                                 else channel = fcn + j*4; // 5 GHz
11187
11188                                 chplan_ap.Channel[i++] = channel;
11189                         }
11190                 }
11191                 chplan_ap.Len = i;
11192
11193 #ifdef CONFIG_DEBUG_RTL871X
11194                 i = 0;
11195                 DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11196                 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
11197                 {
11198                         DBG_8192C("%02d,", chplan_ap.Channel[i]);
11199                         i++;
11200                 }
11201                 DBG_871X("}\n");
11202 #endif
11203
11204                 _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
11205 #ifdef CONFIG_DEBUG_RTL871X
11206                 i = 0;
11207                 DBG_871X("%s: STA channel plan {", __FUNCTION__);
11208                 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11209                 {
11210                         DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
11211                         i++;
11212                 }
11213                 DBG_871X("}\n");
11214 #endif
11215
11216                 _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
11217                 chplan_new = pmlmeext->channel_set;
11218
11219                 i = j = k = 0;
11220                 if (pregistrypriv->wireless_mode & WIRELESS_11G)
11221                 {
11222                         do {
11223                                 if ((i == MAX_CHANNEL_NUM) ||
11224                                         (chplan_sta[i].ChannelNum == 0) ||
11225                                         (chplan_sta[i].ChannelNum > 14))
11226                                         break;
11227
11228                                 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11229                                         break;
11230
11231                                 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11232                                 {
11233                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11234                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11235                                         i++;
11236                                         j++;
11237                                         k++;
11238                                 }
11239                                 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11240                                 {
11241                                         chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11242 //                                      chplan_new[k].ScanType = chplan_sta[i].ScanType;
11243                                         chplan_new[k].ScanType = SCAN_PASSIVE;
11244                                         i++;
11245                                         k++;
11246                                 }
11247                                 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11248                                 {
11249                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11250                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11251                                         j++;
11252                                         k++;
11253                                 }
11254                         } while (1);
11255
11256                         // change AP not support channel to Passive scan
11257                         while ((i < MAX_CHANNEL_NUM) &&
11258                                 (chplan_sta[i].ChannelNum != 0) &&
11259                                 (chplan_sta[i].ChannelNum <= 14))
11260                         {
11261                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11262 //                              chplan_new[k].ScanType = chplan_sta[i].ScanType;
11263                                 chplan_new[k].ScanType = SCAN_PASSIVE;
11264                                 i++;
11265                                 k++;
11266                         }
11267
11268                         // add channel AP supported
11269                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11270                         {
11271                                 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11272                                 chplan_new[k].ScanType = SCAN_ACTIVE;
11273                                 j++;
11274                                 k++;
11275                         }
11276                 }
11277                 else
11278                 {
11279                         // keep original STA 2.4G channel plan
11280                         while ((i < MAX_CHANNEL_NUM) &&
11281                                 (chplan_sta[i].ChannelNum != 0) &&
11282                                 (chplan_sta[i].ChannelNum <= 14))
11283                         {
11284                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11285                                 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11286                                 i++;
11287                                 k++;
11288                         }
11289
11290                         // skip AP 2.4G channel plan
11291                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11292                         {
11293                                 j++;
11294                         }
11295                 }
11296
11297                 if (pregistrypriv->wireless_mode & WIRELESS_11A)
11298                 {
11299                         do {
11300                                 if ((i >= MAX_CHANNEL_NUM) ||
11301                                         (chplan_sta[i].ChannelNum == 0))
11302                                         break;
11303
11304                                 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11305                                         break;
11306
11307                                 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11308                                 {
11309                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11310                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11311                                         i++;
11312                                         j++;
11313                                         k++;
11314                                 }
11315                                 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11316                                 {
11317                                         chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11318 //                                      chplan_new[k].ScanType = chplan_sta[i].ScanType;
11319                                         chplan_new[k].ScanType = SCAN_PASSIVE;
11320                                         i++;
11321                                         k++;
11322                                 }
11323                                 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11324                                 {
11325                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11326                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11327                                         j++;
11328                                         k++;
11329                                 }
11330                         } while (1);
11331
11332                         // change AP not support channel to Passive scan
11333                         while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11334                         {
11335                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11336 //                              chplan_new[k].ScanType = chplan_sta[i].ScanType;
11337                                 chplan_new[k].ScanType = SCAN_PASSIVE;
11338                                 i++;
11339                                 k++;
11340                         }
11341
11342                         // add channel AP supported
11343                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
11344                         {
11345                                 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11346                                 chplan_new[k].ScanType = SCAN_ACTIVE;
11347                                 j++;
11348                                 k++;
11349                         }
11350                 }
11351                 else
11352                 {
11353                         // keep original STA 5G channel plan
11354                         while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11355                         {
11356                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11357                                 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11358                                 i++;
11359                                 k++;
11360                         }
11361                 }
11362
11363                 pmlmeext->update_channel_plan_by_ap_done = 1;
11364
11365 #ifdef CONFIG_DEBUG_RTL871X
11366                 k = 0;
11367                 DBG_871X("%s: new STA channel plan {", __FUNCTION__);
11368                 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11369                 {
11370                         DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
11371                         k++;
11372                 }
11373                 DBG_871X("}\n");
11374 #endif
11375
11376 #if 0
11377                 // recover the right channel index
11378                 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11379                 k = 0;
11380                 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11381                 {
11382                         if (chplan_new[k].ChannelNum == channel) {
11383                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11384                                                  ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11385                                                   __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
11386                                 pmlmeext->sitesurvey_res.channel_idx = k;
11387                                 break;
11388                         }
11389                         k++;
11390                 }
11391 #endif
11392         }
11393
11394         // If channel is used by AP, set channel scan type to active
11395         channel = bssid->Configuration.DSConfig;
11396         chplan_new = pmlmeext->channel_set;
11397         i = 0;
11398         while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
11399         {
11400                 if (chplan_new[i].ChannelNum == channel)
11401                 {
11402                         if (chplan_new[i].ScanType == SCAN_PASSIVE)
11403                         {
11404                                 //5G Bnad 2, 3 (DFS) doesn't change to active scan
11405                                 if(channel >= 52 && channel <= 144)
11406                                         break;
11407                                 
11408                                 chplan_new[i].ScanType = SCAN_ACTIVE;
11409                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11410                                                  ("%s: change channel %d scan type from passive to active\n",
11411                                                   __FUNCTION__, channel));
11412                         }
11413                         break;
11414                 }
11415                 i++;
11416         }
11417 }
11418 #endif
11419
11420 /****************************************************************************
11421
11422 Following are the functions to report events
11423
11424 *****************************************************************************/
11425
11426 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11427 {
11428         struct cmd_obj *pcmd_obj;
11429         u8      *pevtcmd;
11430         u32 cmdsz;
11431         struct survey_event     *psurvey_evt;
11432         struct C2HEvent_Header *pc2h_evt_hdr;
11433         struct mlme_ext_priv *pmlmeext;
11434         struct cmd_priv *pcmdpriv;
11435         //u8 *pframe = precv_frame->u.hdr.rx_data;
11436         //uint len = precv_frame->u.hdr.len;
11437
11438         if(!padapter)
11439                 return;
11440
11441         pmlmeext = &padapter->mlmeextpriv;
11442         pcmdpriv = &padapter->cmdpriv;
11443         
11444
11445         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11446         {
11447                 return;
11448         }
11449
11450         cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11451         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11452         {
11453                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11454                 return;
11455         }
11456
11457         _rtw_init_listhead(&pcmd_obj->list);
11458
11459         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11460         pcmd_obj->cmdsz = cmdsz;
11461         pcmd_obj->parmbuf = pevtcmd;
11462
11463         pcmd_obj->rsp = NULL;
11464         pcmd_obj->rspsz  = 0;
11465
11466         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11467         pc2h_evt_hdr->len = sizeof(struct survey_event);
11468         pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11469         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11470
11471         psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11472
11473         if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
11474         {
11475                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11476                 rtw_mfree((u8 *)pevtcmd, cmdsz);
11477                 return;
11478         }
11479
11480 #ifdef CONFIG_80211D
11481         process_80211d(padapter, &psurvey_evt->bss);
11482 #endif
11483
11484         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11485
11486         pmlmeext->sitesurvey_res.bss_cnt++;
11487
11488         return;
11489
11490 }
11491
11492 void report_surveydone_event(_adapter *padapter)
11493 {
11494         struct cmd_obj *pcmd_obj;
11495         u8      *pevtcmd;
11496         u32 cmdsz;
11497         struct surveydone_event *psurveydone_evt;
11498         struct C2HEvent_Header  *pc2h_evt_hdr;
11499         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11500         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11501
11502         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11503         {
11504                 return;
11505         }
11506
11507         cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11508         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11509         {
11510                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11511                 return;
11512         }
11513
11514         _rtw_init_listhead(&pcmd_obj->list);
11515
11516         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11517         pcmd_obj->cmdsz = cmdsz;
11518         pcmd_obj->parmbuf = pevtcmd;
11519
11520         pcmd_obj->rsp = NULL;
11521         pcmd_obj->rspsz  = 0;
11522
11523         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11524         pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11525         pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11526         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11527
11528         psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11529         psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11530
11531         DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11532
11533         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11534
11535         return;
11536
11537 }
11538
11539 void report_join_res(_adapter *padapter, int res)
11540 {
11541         struct cmd_obj *pcmd_obj;
11542         u8      *pevtcmd;
11543         u32 cmdsz;
11544         struct joinbss_event            *pjoinbss_evt;
11545         struct C2HEvent_Header  *pc2h_evt_hdr;
11546         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11547         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11548         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11549
11550         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11551         {
11552                 return;
11553         }
11554
11555         cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11556         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11557         {
11558                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11559                 return;
11560         }
11561
11562         _rtw_init_listhead(&pcmd_obj->list);
11563
11564         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11565         pcmd_obj->cmdsz = cmdsz;
11566         pcmd_obj->parmbuf = pevtcmd;
11567
11568         pcmd_obj->rsp = NULL;
11569         pcmd_obj->rspsz  = 0;
11570
11571         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11572         pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11573         pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11574         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11575
11576         pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11577         _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11578         pjoinbss_evt->network.join_res  = pjoinbss_evt->network.aid = res;
11579
11580         DBG_871X("report_join_res(%d)\n", res);
11581         
11582         
11583         rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11584         
11585         
11586         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11587
11588         return;
11589
11590 }
11591
11592 void report_wmm_edca_update(_adapter *padapter)
11593 {
11594         struct cmd_obj *pcmd_obj;
11595         u8      *pevtcmd;
11596         u32 cmdsz;
11597         struct wmm_event                *pwmm_event;
11598         struct C2HEvent_Header  *pc2h_evt_hdr;
11599         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11600         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11601         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11602
11603         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11604         {
11605                 return;
11606         }
11607
11608         cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11609         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11610         {
11611                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11612                 return;
11613         }
11614
11615         _rtw_init_listhead(&pcmd_obj->list);
11616
11617         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11618         pcmd_obj->cmdsz = cmdsz;
11619         pcmd_obj->parmbuf = pevtcmd;
11620
11621         pcmd_obj->rsp = NULL;
11622         pcmd_obj->rspsz  = 0;
11623
11624         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11625         pc2h_evt_hdr->len = sizeof(struct wmm_event);
11626         pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11627         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11628
11629         pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11630         pwmm_event->wmm =0;
11631         
11632         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11633
11634         return;
11635
11636 }
11637
11638 void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue)
11639 {
11640         struct cmd_obj *pcmd_obj;
11641         u8      *pevtcmd;
11642         u32 cmdsz;
11643         struct sta_info *psta;
11644         int     mac_id = -1;
11645         struct stadel_event                     *pdel_sta_evt;
11646         struct C2HEvent_Header  *pc2h_evt_hdr;
11647         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11648         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11649         u8 res = _SUCCESS;
11650
11651         /* prepare cmd parameter */
11652         cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11653         pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11654         if (pevtcmd == NULL) {
11655                 res = _FAIL;
11656                 goto exit;
11657         }
11658
11659         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11660         pc2h_evt_hdr->len = sizeof(struct stadel_event);
11661         pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11662         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11663
11664         pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11665         _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11666         _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
11667         psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11668         if(psta)
11669                 mac_id = (int)psta->mac_id;     
11670         else
11671                 mac_id = (-1);
11672         pdel_sta_evt->mac_id = mac_id;
11673
11674         if (!enqueue) {
11675                 /* do directly */
11676                 rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11677                 rtw_mfree(pevtcmd, cmdsz);
11678         } else {
11679                 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11680                 if (pcmd_obj == NULL) {
11681                         rtw_mfree(pevtcmd, cmdsz);
11682                         res = _FAIL;
11683                         goto exit;
11684                 }
11685
11686                 _rtw_init_listhead(&pcmd_obj->list);
11687                 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11688                 pcmd_obj->cmdsz = cmdsz;
11689                 pcmd_obj->parmbuf = pevtcmd;
11690
11691                 pcmd_obj->rsp = NULL;
11692                 pcmd_obj->rspsz  = 0;
11693
11694                 res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11695         }
11696
11697 exit:
11698
11699         DBG_871X(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11700                 , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11701
11702         return;
11703 }
11704
11705 void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
11706 {
11707         struct cmd_obj *pcmd_obj;
11708         u8      *pevtcmd;
11709         u32 cmdsz;
11710         struct stassoc_event            *padd_sta_evt;
11711         struct C2HEvent_Header  *pc2h_evt_hdr;
11712         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11713         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11714
11715         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11716         {
11717                 return;
11718         }
11719
11720         cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11721         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11722         {
11723                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11724                 return;
11725         }
11726
11727         _rtw_init_listhead(&pcmd_obj->list);
11728
11729         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11730         pcmd_obj->cmdsz = cmdsz;
11731         pcmd_obj->parmbuf = pevtcmd;
11732
11733         pcmd_obj->rsp = NULL;
11734         pcmd_obj->rspsz  = 0;
11735
11736         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11737         pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11738         pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11739         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11740
11741         padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11742         _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11743
11744         DBG_871X("report_add_sta_event: add STA\n");
11745
11746         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11747
11748         return;
11749 }
11750
11751
11752 bool rtw_port_switch_chk(_adapter *adapter)
11753 {
11754         bool switch_needed = _FALSE;
11755 #ifdef CONFIG_CONCURRENT_MODE
11756 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11757         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11758         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11759         _adapter *if_port0 = NULL;
11760         _adapter *if_port1 = NULL;
11761         struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11762         struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11763         int i;
11764
11765         for (i = 0; i < dvobj->iface_nums; i++) {
11766                 if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) {
11767                         if_port0 = dvobj->padapters[i];
11768                         if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11769                 }
11770                 else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) {
11771                         if_port1 = dvobj->padapters[i];
11772                         if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11773                 }
11774         }
11775
11776         if (if_port0 == NULL) {
11777                 rtw_warn_on(1);
11778                 goto exit;
11779         }
11780
11781         if (if_port1 == NULL) {
11782                 rtw_warn_on(1);
11783                 goto exit;
11784         }
11785
11786 #ifdef DBG_RUNTIME_PORT_SWITCH
11787         DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11788                 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11789                 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11790                 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11791                 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11792                 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11793 #endif /* DBG_RUNTIME_PORT_SWITCH */
11794
11795 #ifdef CONFIG_WOWLAN
11796         /* WOWLAN interface(primary, for now) should be port0 */
11797         if (pwrctl->wowlan_mode == _TRUE) {
11798                 if(!is_primary_adapter(if_port0)) {
11799                         DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11800                         switch_needed = _TRUE;
11801                 }
11802                 goto exit;
11803         }
11804 #endif /* CONFIG_WOWLAN */
11805
11806         /* AP should use port0 for ctl frame's ack */
11807         if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11808                 DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11809                 switch_needed = _TRUE;
11810                 goto exit;
11811         }
11812
11813         /* GC should use port0 for p2p ps */    
11814         if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11815                 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11816                 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11817                 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11818         ) {
11819                 DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11820                 switch_needed = _TRUE;
11821                 goto exit;
11822         }
11823
11824         /* port1 linked, but port0 not linked */
11825         if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11826                 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11827                 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11828         ) {
11829                 DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11830                 switch_needed = _TRUE;
11831                 goto exit;
11832         }
11833
11834 exit:
11835 #ifdef DBG_RUNTIME_PORT_SWITCH
11836         DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11837 #endif /* DBG_RUNTIME_PORT_SWITCH */
11838 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11839 #endif /* CONFIG_CONCURRENT_MODE */
11840         return switch_needed;
11841 }
11842
11843 /****************************************************************************
11844
11845 Following are the event callback functions
11846
11847 *****************************************************************************/
11848
11849 //for sta/adhoc mode
11850 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11851 {
11852         _irqL   irqL;
11853         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11854         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11855         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11856
11857         //ERP
11858         VCS_update(padapter, psta);
11859
11860 #ifdef CONFIG_80211N_HT
11861         //HT
11862         if(pmlmepriv->htpriv.ht_option)
11863         {
11864                 psta->htpriv.ht_option = _TRUE;
11865
11866                 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11867
11868                 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
11869
11870                 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11871                         psta->htpriv.sgi_20m = _TRUE;
11872
11873                 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11874                         psta->htpriv.sgi_40m = _TRUE;
11875
11876                 psta->qos_option = _TRUE;
11877
11878                 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11879                 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11880                 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11881
11882                 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11883         }
11884         else
11885 #endif //CONFIG_80211N_HT
11886         {
11887 #ifdef CONFIG_80211N_HT
11888                 psta->htpriv.ht_option = _FALSE;
11889
11890                 psta->htpriv.ampdu_enable = _FALSE;
11891                 
11892                 psta->htpriv.sgi_20m = _FALSE;
11893                 psta->htpriv.sgi_40m = _FALSE;
11894 #endif //CONFIG_80211N_HT
11895                 psta->qos_option = _FALSE;
11896
11897         }
11898
11899 #ifdef CONFIG_80211N_HT
11900         psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11901         
11902         psta->htpriv.agg_enable_bitmap = 0x0;//reset
11903         psta->htpriv.candidate_tid_bitmap = 0x0;//reset
11904 #endif //CONFIG_80211N_HT
11905
11906         psta->bw_mode = pmlmeext->cur_bwmode;
11907
11908         //QoS
11909         if(pmlmepriv->qospriv.qos_option)
11910                 psta->qos_option = _TRUE;
11911
11912 #ifdef CONFIG_80211AC_VHT
11913         _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11914 #endif //CONFIG_80211AC_VHT
11915
11916         update_ldpc_stbc_cap(psta);
11917
11918         _enter_critical_bh(&psta->lock, &irqL);
11919         psta->state = _FW_LINKED;
11920         _exit_critical_bh(&psta->lock, &irqL);
11921
11922 }
11923
11924 static void rtw_mlmeext_disconnect(_adapter *padapter)
11925 {
11926         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
11927         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11928         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11929         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11930         u8 state_backup = (pmlmeinfo->state&0x03);
11931         u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
11932
11933         //set_opmode_cmd(padapter, infra_client_with_mlme);
11934
11935         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11936         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11937
11938         //set MSR to no link state -> infra. mode
11939         Set_MSR(padapter, _HW_STATE_STATION_);
11940
11941         //check if sta is ASIX peer and fix IOT issue if it is.
11942         if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
11943                 u8 iot_flag = _FALSE;
11944                 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11945         }
11946         pmlmeinfo->state = WIFI_FW_NULL_STATE;
11947
11948         if(state_backup == WIFI_FW_STATION_STATE)
11949         {
11950                 if (rtw_port_switch_chk(padapter) == _TRUE) {
11951                         rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11952                         #ifdef CONFIG_LPS
11953                         {
11954                                 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11955                                 if (port0_iface)
11956                                         rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11957                         }
11958                         #endif
11959                 }
11960         }
11961
11962         /* switch to the 20M Hz mode after disconnect */
11963         pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11964         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11965
11966 #ifdef CONFIG_FCS_MODE
11967         if (EN_FCS(padapter))
11968                 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11969 #endif
11970
11971 #ifdef CONFIG_DFS_MASTER
11972         if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
11973                 rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);
11974         else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
11975                 rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED);
11976 #endif
11977
11978         {
11979                 u8 ch, bw, offset;
11980
11981                 if (rtw_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
11982                         set_channel_bwmode(padapter, ch, offset, bw);
11983         }
11984
11985         flush_all_cam_entry(padapter);
11986
11987         _cancel_timer_ex(&pmlmeext->link_timer);
11988
11989         //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE;
11990         pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11991         pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11992
11993 #ifdef CONFIG_TDLS
11994         padapter->tdlsinfo.ap_prohibited = _FALSE;
11995
11996         /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11997         if (padapter->registrypriv.wifi_spec == 1)
11998         {
11999                 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
12000         }
12001 #endif /* CONFIG_TDLS */
12002
12003 }
12004
12005 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
12006 {
12007         struct sta_info         *psta, *psta_bmc;
12008         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12009         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12010         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
12011         struct sta_priv         *pstapriv = &padapter->stapriv;
12012         u8      join_type;
12013 #ifdef CONFIG_ARP_KEEP_ALIVE
12014         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
12015 #endif
12016         struct security_priv *psecuritypriv = &padapter->securitypriv;
12017
12018         if(join_res < 0)
12019         {
12020                 join_type = 1;
12021                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12022                 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12023
12024                 goto exit_mlmeext_joinbss_event_callback;
12025         }
12026 #ifdef CONFIG_ARP_KEEP_ALIVE
12027         pmlmepriv->bGetGateway = 1;
12028 #endif
12029
12030         if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
12031         {
12032                 //update bc/mc sta_info
12033                 update_bmc_sta(padapter);
12034         }
12035
12036
12037         //turn on dynamic functions
12038         /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12039
12040         // update IOT-releated issue
12041         update_IOT_info(padapter);
12042
12043         rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12044
12045         //BCN interval
12046         rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12047
12048         //udpate capability
12049         update_capinfo(padapter, pmlmeinfo->capability);
12050
12051         //WMM, Update EDCA param
12052         WMMOnAssocRsp(padapter);
12053
12054         //HT
12055         HTOnAssocRsp(padapter);
12056
12057 #ifdef CONFIG_80211AC_VHT
12058         //VHT
12059         VHTOnAssocRsp(padapter);
12060 #endif
12061
12062         psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12063         if (psta) //only for infra. mode
12064         {
12065                 //DBG_871X("set_sta_rate\n");
12066
12067                 psta->wireless_mode = pmlmeext->cur_wireless_mode;
12068         
12069                 //set per sta rate after updating HT cap.
12070                 set_sta_rate(padapter, psta);
12071                 
12072                 rtw_sta_media_status_rpt(padapter, psta, 1);
12073
12074                 /* wakeup macid after join bss successfully to ensure 
12075                         the subsequent data frames can be sent out normally */
12076                 rtw_hal_macid_wakeup(padapter, psta->mac_id);
12077         }
12078
12079 #ifndef CONFIG_IOCTL_CFG80211
12080         if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12081                 rtw_sec_restore_wep_key(padapter);
12082 #endif /* CONFIG_IOCTL_CFG80211 */
12083
12084         if (rtw_port_switch_chk(padapter) == _TRUE)
12085                 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12086
12087         join_type = 2;
12088         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12089
12090         if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12091         {
12092                 // correcting TSF
12093                 correct_TSF(padapter, pmlmeext);
12094         
12095                 //set_link_timer(pmlmeext, DISCONNECT_TO);
12096         }
12097
12098 #ifdef CONFIG_LPS
12099         if(get_iface_type(padapter) == IFACE_PORT0)
12100                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
12101 #endif
12102
12103 #ifdef CONFIG_BEAMFORMING
12104         if (psta)
12105                 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12106 #endif/*CONFIG_BEAMFORMING*/
12107
12108 exit_mlmeext_joinbss_event_callback:
12109
12110         rtw_join_done_chk_ch(padapter, join_res);
12111
12112         DBG_871X("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12113 }
12114
12115 //currently only adhoc mode will go here
12116 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12117 {
12118         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12119         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12120         u8      join_type;
12121
12122         DBG_871X("%s\n", __FUNCTION__);
12123
12124         if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
12125         {
12126                 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
12127                 {
12128                         //nothing to do
12129                 }
12130                 else//adhoc client
12131                 {
12132                         //update TSF Value
12133                         //update_TSF(pmlmeext, pframe, len);                    
12134
12135                         // correcting TSF
12136                         correct_TSF(padapter, pmlmeext);
12137
12138                         //start beacon
12139                         if (send_beacon(padapter) == _FAIL)
12140                                 rtw_warn_on(1);
12141
12142                         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12143                 }
12144
12145                 join_type = 2;
12146                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12147         }
12148
12149         //update adhoc sta_info
12150         update_sta_info(padapter, psta);
12151
12152         rtw_hal_update_sta_rate_mask(padapter, psta);
12153
12154         // ToDo: HT for Ad-hoc 
12155         psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12156         psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
12157
12158         //rate radaptive
12159         Update_RA_Entry(padapter, psta);
12160 }
12161
12162 void mlmeext_sta_del_event_callback(_adapter *padapter)
12163 {
12164         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12165         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12166
12167         if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12168         {
12169                 rtw_mlmeext_disconnect(padapter);
12170         }
12171
12172 }
12173
12174 /****************************************************************************
12175
12176 Following are the functions for the timer handlers
12177
12178 *****************************************************************************/
12179 void _linked_info_dump(_adapter *padapter)
12180 {
12181         int i;
12182         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12183         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12184         HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
12185         int UndecoratedSmoothedPWDB = 0;
12186         
12187         if(padapter->bLinkInfoDump){
12188
12189                 DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter));    
12190
12191                 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12192                 {
12193                         rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);      
12194                 
12195                         DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
12196                                 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB);
12197                 }
12198                 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
12199                 {
12200                         _irqL irqL;
12201                         _list   *phead, *plist;
12202         
12203                         struct sta_info *psta=NULL;     
12204                         struct sta_priv *pstapriv = &padapter->stapriv;
12205                         
12206                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);   
12207                         phead = &pstapriv->asoc_list;
12208                         plist = get_next(phead);
12209                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12210                         {
12211                                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
12212                                 plist = get_next(plist);                        
12213                                 
12214                                 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n", 
12215                                         MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB);
12216                         }
12217                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);            
12218                         
12219                 }
12220                 
12221                 /*============  tx info ============    */
12222                 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
12223
12224                 rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
12225
12226         }
12227
12228
12229 }
12230 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12231 {
12232         int     i = 0;
12233         int ret = _SUCCESS;
12234         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12235         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12236
12237         /*
12238                 IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12239                 AP is originator.AP does not transmit unicast packets when STA response its BAR.
12240                 This case probably occur ap issue BAR after AP builds BA. 
12241                                 
12242                 Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12243                 The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12244         */
12245         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12246                 for (i = 0; i < TID_NUM ; i++) {                                
12247                         if (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) {                      
12248                                 if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12249                                         if (psta->recvreorder_ctrl[i].enable) {                                         
12250                                                 /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */              
12251                                                 if (!from_timer)
12252                                                         ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1);
12253                                                 else
12254                                                         issue_del_ba(padapter,  psta->hwaddr, i, 39, 0);                                                        
12255                                                         psta->recvreorder_ctrl[i].enable = _FALSE;
12256                                                 if (ret != _FAIL)
12257                                                         psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12258                                                         rtw_reset_continual_no_rx_packet(psta, i);
12259                                                 }                               
12260                                         }
12261                                 }
12262                         else{   
12263                                 /* The inactivity timer is reset when MPDUs to the TID is received. */
12264                                 rtw_reset_continual_no_rx_packet(psta, i);      
12265                         }
12266                 }
12267         }
12268 }
12269
12270 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12271 {
12272         u8 ret = _FALSE;
12273         int i = 0;
12274         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12275         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12276
12277         #ifdef DBG_EXPIRATION_CHK
12278         DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12279                                 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12280                                 ", retry:%u\n"
12281                 , FUNC_ADPT_ARG(padapter)
12282                 , STA_RX_PKTS_DIFF_ARG(psta)
12283                 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12284                 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12285                 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12286                 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12287                 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12288                 , pmlmeinfo->bcn_interval*/
12289                 , pmlmeext->retry
12290         );
12291
12292         DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12293                 , padapter->xmitpriv.tx_pkts
12294                 , pmlmeinfo->link_count
12295         );
12296         #endif
12297
12298         if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12299                 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12300                 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12301         )
12302         {
12303                 ret = _FALSE;
12304         }
12305         else
12306         {
12307                 ret = _TRUE;
12308         }
12309
12310         sta_update_last_rx_pkts(psta);
12311
12312         /*
12313                 record last rx data packets for every tid.
12314         */
12315         for (i = 0; i < TID_NUM; i++)   
12316                 psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i];
12317
12318         return ret;
12319 }
12320
12321 u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
12322 {
12323         u8 ret = _TRUE;
12324
12325         #ifdef DBG_EXPIRATION_CHK
12326         DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12327                 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12328                 ", expire_to:%u\n"
12329                 , MAC_ARG(psta->hwaddr)
12330                 , psta->rssi_stat.UndecoratedSmoothedPWDB
12331                 , STA_RX_PKTS_DIFF_ARG(psta)
12332                 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12333                 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12334                 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12335                 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12336                 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12337                 , pmlmeinfo->bcn_interval*/
12338                 , psta->expire_to
12339         );
12340         #endif
12341
12342         if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
12343                 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12344                 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
12345                 ret = _FALSE;
12346
12347         sta_update_last_rx_pkts(psta);
12348
12349         return ret;
12350 }
12351
12352 #ifdef CONFIG_TDLS
12353 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12354 {
12355         if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12356                 && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12357                 return _FALSE;
12358
12359         return _TRUE;
12360 }
12361
12362 void linked_status_chk_tdls(_adapter *padapter)
12363 {
12364         struct candidate_pool {
12365                 struct sta_info *psta;
12366                 u8 addr[ETH_ALEN];
12367         };
12368         struct sta_priv *pstapriv = &padapter->stapriv;
12369         _irqL irqL;
12370         u8 ack_chk;
12371         struct sta_info *psta;
12372         int i, num_teardown=0, num_checkalive=0;
12373         _list   *plist, *phead;
12374         struct tdls_txmgmt txmgmt;
12375         struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
12376         struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
12377         u8 tdls_sta_max = _FALSE;
12378
12379 #define ALIVE_MIN 2
12380 #define ALIVE_MAX 5
12381
12382         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12383         _rtw_memset(checkalive, 0x00, sizeof(checkalive));
12384         _rtw_memset(teardown, 0x00, sizeof(teardown));
12385
12386         if((padapter->tdlsinfo.link_established == _TRUE)){
12387                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12388                 for(i=0; i< NUM_STA; i++)
12389                 {
12390                         phead = &(pstapriv->sta_hash[i]);
12391                         plist = get_next(phead);
12392                         
12393                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12394                         {
12395                                 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12396                                 plist = get_next(plist);
12397
12398                                 if(psta->tdls_sta_state & TDLS_LINKED_STATE)
12399                                 {
12400                                         psta->alive_count++;
12401                                         if(psta->alive_count >= ALIVE_MIN)
12402                                         {
12403                                                 if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12404                                                         if (psta->alive_count < ALIVE_MAX) {
12405                                                                 _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12406                                                                 checkalive[num_checkalive].psta = psta;
12407                                                                 num_checkalive++;
12408                                                         }
12409                                                         else
12410                                                         {
12411                                                                 _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12412                                                                 teardown[num_teardown].psta = psta;
12413                                                                 num_teardown++;
12414                                                         }
12415                                                 }
12416                                                 else
12417                                                 {
12418                                                         psta->alive_count = 0;
12419                                                 }
12420                                         }
12421                                         psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12422                                         psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12423
12424                                         if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
12425                                                 tdls_sta_max = _TRUE;
12426                                                 break;
12427                                         }
12428                                 }
12429                         }
12430
12431                         if (tdls_sta_max == _TRUE)
12432                                 break;
12433                 }
12434                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12435
12436                 if (num_checkalive > 0) {
12437                         for (i = 0; i < num_checkalive; i++) {
12438                                 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12439                                 issue_tdls_dis_req(padapter, &txmgmt);
12440                                 issue_tdls_dis_req(padapter, &txmgmt);
12441                                 issue_tdls_dis_req(padapter, &txmgmt);
12442                         }
12443                 }
12444
12445                 if(num_teardown > 0)
12446                 {
12447                         for(i=0; i< num_teardown; i++)
12448                         {
12449                                 DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12450                                 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12451                                 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12452                                 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12453                         }
12454                 }
12455         }
12456
12457 }
12458 #endif //CONFIG_TDLS
12459
12460 //from_timer == 1 means driver is in LPS
12461 void linked_status_chk(_adapter *padapter, u8 from_timer)
12462 {
12463         u32     i;
12464         struct sta_info         *psta;
12465         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
12466         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12467         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12468         struct sta_priv         *pstapriv = &padapter->stapriv;
12469 #ifdef CONFIG_ARP_KEEP_ALIVE
12470         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
12471 #endif
12472         
12473
12474         if (is_client_associated_to_ap(padapter))
12475         {
12476                 //linked infrastructure client mode
12477
12478                 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12479                 int rx_chk_limit;
12480                 int link_count_limit;
12481
12482                 #if defined(DBG_ROAMING_TEST)
12483                 rx_chk_limit = 1;
12484                 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12485                 rx_chk_limit = 4;
12486                 #else
12487                 rx_chk_limit = 8;
12488                 #endif
12489 #ifdef CONFIG_ARP_KEEP_ALIVE
12490                 if (!from_timer && pmlmepriv->bGetGateway == 1) {
12491                         DBG_871X("do rtw_gw_addr_query()");
12492                         if (rtw_gw_addr_query(padapter) == 0) {
12493                                 pmlmepriv->bGetGateway = 0;
12494                         } else {
12495                                 _rtw_memset(pmlmepriv->gw_ip, 0, 4);
12496                                 _rtw_memset(pmlmepriv->gw_mac_addr, 0, 6);
12497                         }
12498                 }
12499 #endif
12500 #ifdef CONFIG_P2P
12501                 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12502                 {
12503                         if(!from_timer)
12504                                 link_count_limit = 3; // 8 sec
12505                         else
12506                                 link_count_limit = 15; // 32 sec
12507                 }
12508                 else
12509 #endif // CONFIG_P2P
12510                 {
12511                         if(!from_timer)
12512                                 link_count_limit = 7; // 16 sec
12513                         else
12514                                 link_count_limit = 29; // 60 sec
12515                 }               
12516
12517 #ifdef CONFIG_TDLS
12518 #ifdef CONFIG_TDLS_CH_SW
12519                 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12520                         return;
12521 #endif /* CONFIG_TDLS_CH_SW */
12522
12523 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12524                 linked_status_chk_tdls(padapter);
12525 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12526 #endif /* CONFIG_TDLS */
12527
12528                 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12529                 {
12530                         bool is_p2p_enable = _FALSE;
12531                         #ifdef CONFIG_P2P
12532                         is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12533                         #endif
12534
12535                         /*issue delba when ap does not tx data packet that is Broadcom ap */
12536                         rtw_delba_check(padapter, psta, from_timer);
12537
12538                         if (chk_ap_is_alive(padapter, psta) == _FALSE)
12539                                 rx_chk = _FAIL;
12540
12541                         if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12542                                 tx_chk = _FAIL;
12543
12544                         #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12545                         if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
12546                                 u8 backup_oper_channel=0;
12547
12548                                 /* switch to correct channel of current network  before issue keep-alive frames */
12549                                 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12550                                         backup_oper_channel = rtw_get_oper_ch(padapter);
12551                                         SelectChannel(padapter, pmlmeext->cur_channel);
12552                                 }
12553
12554                                 if (rx_chk != _SUCCESS)
12555                                         issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12556
12557                                 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12558                                         tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12559                                         /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12560                                         if (tx_chk == _SUCCESS && !is_p2p_enable)
12561                                                 rx_chk = _SUCCESS;
12562                                 }
12563
12564                                 /* back to the original operation channel */
12565                                 if(backup_oper_channel>0)
12566                                         SelectChannel(padapter, backup_oper_channel);
12567
12568                         }
12569                         else
12570                         #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12571                         {
12572                                 if (rx_chk != _SUCCESS) {
12573                                         if (pmlmeext->retry == 0) {
12574                                                 #ifdef DBG_EXPIRATION_CHK
12575                                                 DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12576                                                 #endif
12577                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12578                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12579                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12580                                         }
12581                                 }
12582
12583                                 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
12584                                         #ifdef DBG_EXPIRATION_CHK
12585                                         DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0);
12586                                         #endif
12587                                         tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0);
12588                                 }
12589                         }
12590
12591                         if (rx_chk == _FAIL) {
12592                                 pmlmeext->retry++;
12593                                 if (pmlmeext->retry > rx_chk_limit) {
12594                                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
12595                                                 FUNC_ADPT_ARG(padapter));
12596                                         receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12597                                                 , WLAN_REASON_EXPIRATION_CHK);
12598                                         return;
12599                                 }
12600                         } else {
12601                                 pmlmeext->retry = 0;
12602                         }
12603
12604                         if (tx_chk == _FAIL) {
12605                                 pmlmeinfo->link_count %= (link_count_limit+1);
12606                         } else {
12607                                 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12608                                 pmlmeinfo->link_count = 0;
12609                         }
12610
12611                 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12612
12613         } else if (is_client_associated_to_ibss(padapter)) {
12614                 _irqL irqL;
12615                 _list *phead, *plist, dlist;
12616
12617                 _rtw_init_listhead(&dlist);
12618
12619                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12620
12621                 for (i = 0; i < NUM_STA; i++) {
12622
12623                         phead = &(pstapriv->sta_hash[i]);
12624                         plist = get_next(phead);
12625                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12626                                 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12627                                 plist = get_next(plist);
12628
12629                                 if (is_broadcast_mac_addr(psta->hwaddr))
12630                                         continue;
12631
12632                                 if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
12633                                         psta->expire_to = pstapriv->adhoc_expire_to;
12634                                 else
12635                                         psta->expire_to--;
12636
12637                                 if (psta->expire_to <= 0) {
12638                                         rtw_list_delete(&psta->list);
12639                                         rtw_list_insert_tail(&psta->list, &dlist);
12640                                 }
12641                         }
12642                 }
12643
12644                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12645
12646                 plist = get_next(&dlist);
12647                 while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
12648                         psta = LIST_CONTAINOR(plist, struct sta_info, list);
12649                         plist = get_next(plist);
12650                         rtw_list_delete(&psta->list);
12651                         DBG_871X(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
12652                                 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->hwaddr));
12653                         report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE);
12654                 }
12655         }
12656
12657 }
12658
12659 void survey_timer_hdl(_adapter *padapter)
12660 {
12661         struct cmd_obj *cmd;
12662         struct sitesurvey_parm *psurveyPara;
12663         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12664         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12665 #ifdef CONFIG_P2P
12666         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12667 #endif
12668
12669         if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12670                 cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12671                 if (cmd == NULL) {
12672                         rtw_warn_on(1);
12673                         goto exit;
12674                 }
12675
12676                 psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12677                 if (psurveyPara == NULL) {
12678                         rtw_warn_on(1);
12679                         rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12680                         goto exit;
12681                 }
12682
12683                 init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12684                 rtw_enqueue_cmd(pcmdpriv, cmd);
12685         }
12686
12687 exit:
12688         return;
12689 }
12690
12691 void link_timer_hdl(_adapter *padapter)
12692 {
12693         //static unsigned int           rx_pkt = 0;
12694         //static u64                            tx_cnt = 0;
12695         //struct xmit_priv              *pxmitpriv = &(padapter->xmitpriv);
12696         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12697         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12698         //struct sta_priv               *pstapriv = &padapter->stapriv;
12699
12700
12701         if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
12702         {
12703                 DBG_871X("link_timer_hdl:no beacon while connecting\n");
12704                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12705                 report_join_res(padapter, -3);
12706         }
12707         else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
12708         {
12709                 //re-auth timer
12710                 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
12711                 {
12712                         //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
12713                         //{
12714                                 pmlmeinfo->state = 0;
12715                                 report_join_res(padapter, -1);
12716                                 return;
12717                         //}
12718                         //else
12719                         //{
12720                         //      pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
12721                         //      pmlmeinfo->reauth_count = 0;
12722                         //}
12723                 }
12724                 
12725                 DBG_871X("link_timer_hdl: auth timeout and try again\n");
12726                 pmlmeinfo->auth_seq = 1;
12727                 issue_auth(padapter, NULL, 0);
12728                 set_link_timer(pmlmeext, REAUTH_TO);
12729         }
12730         else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
12731         {
12732                 //re-assoc timer
12733                 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
12734                 {
12735                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
12736                         report_join_res(padapter, -2);
12737                         return;
12738                 }
12739
12740                 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
12741                 issue_assocreq(padapter);
12742                 set_link_timer(pmlmeext, REASSOC_TO);
12743         }
12744
12745         return;
12746 }
12747
12748 void addba_timer_hdl(struct sta_info *psta)
12749 {
12750 #ifdef CONFIG_80211N_HT
12751         struct ht_priv  *phtpriv;
12752
12753         if(!psta)
12754                 return;
12755         
12756         phtpriv = &psta->htpriv;
12757
12758         if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) 
12759         {
12760                 if(phtpriv->candidate_tid_bitmap)
12761                         phtpriv->candidate_tid_bitmap=0x0;
12762                 
12763         }
12764 #endif //CONFIG_80211N_HT
12765 }
12766
12767 #ifdef CONFIG_IEEE80211W
12768 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
12769 {
12770         struct cmd_obj *pcmd_obj;
12771         u8      *pevtcmd;
12772         u32 cmdsz;
12773         struct sta_info *psta;
12774         int     mac_id;
12775         struct stadel_event                     *pdel_sta_evt;
12776         struct C2HEvent_Header  *pc2h_evt_hdr;
12777         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
12778         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12779         
12780         pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12781         if (pcmd_obj == NULL)
12782                 return;
12783
12784         cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
12785         pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12786         if (pevtcmd == NULL) {
12787                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12788                 return;
12789         }
12790
12791         _rtw_init_listhead(&pcmd_obj->list);
12792
12793         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
12794         pcmd_obj->cmdsz = cmdsz;
12795         pcmd_obj->parmbuf = pevtcmd;
12796
12797         pcmd_obj->rsp = NULL;
12798         pcmd_obj->rspsz  = 0;
12799
12800         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
12801         pc2h_evt_hdr->len = sizeof(struct stadel_event);
12802         pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
12803         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12804
12805         pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
12806         _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12807         _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12808
12809
12810         psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12811         if (psta)
12812                 mac_id = (int)psta->mac_id;     
12813         else
12814                 mac_id = (-1);
12815
12816         pdel_sta_evt->mac_id = mac_id;
12817
12818         DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
12819
12820         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12821
12822         return;
12823 }
12824
12825 void clnt_sa_query_timeout(_adapter *padapter)
12826 {
12827
12828         rtw_disassoc_cmd(padapter, 0, _TRUE);
12829         rtw_indicate_disconnect(padapter);
12830         rtw_free_assoc_resources(padapter, 1);  
12831
12832         DBG_871X("SA query timeout client disconnect\n");
12833 }
12834
12835 void sa_query_timer_hdl(struct sta_info *psta)
12836 {
12837         _adapter *padapter = psta->padapter;
12838         _irqL irqL;
12839         struct sta_priv *pstapriv = &padapter->stapriv;
12840         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12841
12842         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
12843                                         check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12844                 clnt_sa_query_timeout(padapter);
12845         else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
12846                 report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID);
12847 }
12848
12849 #endif //CONFIG_IEEE80211W
12850
12851 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
12852 {
12853         return H2C_SUCCESS;
12854 }
12855
12856 #ifdef CONFIG_AUTO_AP_MODE
12857 void rtw_start_auto_ap(_adapter *adapter)
12858 {
12859         DBG_871X("%s\n", __FUNCTION__);
12860
12861         rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
12862
12863         rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE);
12864 }
12865
12866 static int rtw_auto_ap_start_beacon(_adapter *adapter)
12867 {
12868         int ret=0;
12869         u8 *pbuf = NULL;
12870         uint len;
12871         u8      supportRate[16];
12872         int     sz = 0, rateLen;
12873         u8 *    ie;
12874         u8      wireless_mode, oper_channel;
12875         u8 ssid[3] = {0}; //hidden ssid
12876         u32 ssid_len = sizeof(ssid);
12877         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
12878
12879
12880         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
12881                 return -EINVAL;
12882
12883
12884         len = 128;
12885         pbuf = rtw_zmalloc(len);
12886         if(!pbuf)
12887                 return -ENOMEM;
12888
12889
12890         //generate beacon
12891         ie = pbuf;
12892
12893         //timestamp will be inserted by hardware
12894         sz += 8;
12895         ie += sz;
12896
12897         //beacon interval : 2bytes
12898         *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
12899         sz += 2;
12900         ie += 2;
12901
12902         //capability info
12903         *(u16*)ie = 0;
12904         *(u16*)ie |= cpu_to_le16(cap_ESS);
12905         *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
12906         //*(u16*)ie |= cpu_to_le16(cap_Privacy);
12907         sz += 2;
12908         ie += 2;
12909
12910         //SSID
12911         ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
12912
12913         //supported rates
12914         wireless_mode = WIRELESS_11BG_24N;
12915         rtw_set_supported_rate(supportRate, wireless_mode) ;
12916         rateLen = rtw_get_rateset_len(supportRate);
12917         if (rateLen > 8)
12918         {
12919                 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
12920         }
12921         else
12922         {
12923                 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
12924         }
12925
12926
12927         //DS parameter set
12928         if(check_buddy_fwstate(adapter, _FW_LINKED) &&
12929                 check_buddy_fwstate(adapter, WIFI_STATION_STATE))
12930         {
12931                 PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
12932                 struct mlme_ext_priv *pbuddy_mlmeext  = &pbuddy_adapter->mlmeextpriv;
12933
12934                 oper_channel = pbuddy_mlmeext->cur_channel;
12935         }
12936         else
12937         {
12938                 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
12939         }
12940         ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
12941
12942         //ext supported rates
12943         if (rateLen > 8)
12944         {
12945                 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
12946         }
12947
12948         DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
12949
12950         //lunch ap mode & start to issue beacon
12951         if(rtw_check_beacon_data(adapter, pbuf,  sz) == _SUCCESS)
12952         {
12953
12954         }
12955         else
12956         {
12957                 ret = -EINVAL;
12958         }
12959
12960
12961         rtw_mfree(pbuf, len);
12962
12963         return ret;
12964
12965 }
12966 #endif//CONFIG_AUTO_AP_MODE
12967
12968 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
12969 {
12970         u8      type;
12971         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12972         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12973         struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
12974
12975         if(psetop->mode == Ndis802_11APMode)
12976         {
12977                 pmlmeinfo->state = WIFI_FW_AP_STATE;
12978                 type = _HW_STATE_AP_;
12979 #ifdef CONFIG_NATIVEAP_MLME
12980                 //start_ap_mode(padapter);
12981 #endif
12982         }
12983         else if(psetop->mode == Ndis802_11Infrastructure)
12984         {
12985                 pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
12986                 pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to      STATION_STATE
12987                 type = _HW_STATE_STATION_;
12988         }
12989         else if(psetop->mode == Ndis802_11IBSS)
12990         {
12991                 type = _HW_STATE_ADHOC_;
12992         } else if (psetop->mode == Ndis802_11Monitor) {
12993                 type = _HW_STATE_MONITOR_;
12994         }
12995         else
12996         {
12997                 type = _HW_STATE_NOLINK_;
12998         }
12999
13000         rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
13001         //Set_NETYPE0_MSR(padapter, type);
13002
13003
13004 #ifdef CONFIG_AUTO_AP_MODE
13005         if(psetop->mode == Ndis802_11APMode)
13006                 rtw_auto_ap_start_beacon(padapter);
13007 #endif
13008
13009         if (rtw_port_switch_chk(padapter) == _TRUE)
13010         {
13011                 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
13012
13013                 if(psetop->mode == Ndis802_11APMode)
13014                         adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages
13015                 else if (psetop->mode == Ndis802_11Infrastructure) {
13016                         #ifdef CONFIG_LPS
13017                         _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
13018                         if (port0_iface)
13019                                 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
13020                         #endif  
13021                 }
13022         }       
13023
13024 #ifdef CONFIG_BT_COEXIST
13025         if (psetop->mode == Ndis802_11APMode)
13026         {
13027                 // Do this after port switch to
13028                 // prevent from downloading rsvd page to wrong port
13029                 rtw_btcoex_MediaStatusNotify(padapter, 1); //connect 
13030         }
13031 #endif // CONFIG_BT_COEXIST
13032
13033         return H2C_SUCCESS;
13034         
13035 }
13036
13037 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
13038 {
13039         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13040         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
13041         WLAN_BSSID_EX   *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13042         WLAN_BSSID_EX   *pdev_network = &padapter->registrypriv.dev_network;
13043         struct createbss_parm *parm = (struct createbss_parm *)pbuf;
13044         u8 ret = H2C_SUCCESS;
13045         //u8    initialgain;
13046         
13047 #ifdef CONFIG_AP_MODE
13048         if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
13049                 start_bss_network(padapter, parm);
13050                 goto exit;
13051         }
13052 #endif
13053
13054         /* below is for ad-hoc master */
13055         if (parm->adhoc) {
13056                 rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
13057                 rtw_joinbss_reset(padapter);
13058         
13059                 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13060                 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;       
13061                 pmlmeinfo->ERP_enable = 0;
13062                 pmlmeinfo->WMM_enable = 0;
13063                 pmlmeinfo->HT_enable = 0;
13064                 pmlmeinfo->HT_caps_enable = 0;
13065                 pmlmeinfo->HT_info_enable = 0;
13066                 pmlmeinfo->agg_enable_bitmap = 0;
13067                 pmlmeinfo->candidate_tid_bitmap = 0;
13068
13069                 //config the initial gain under linking, need to write the BB registers
13070                 //initialgain = 0x1E;
13071                 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13072
13073                 //disable dynamic functions, such as high power, DIG
13074                 rtw_phydm_ability_backup(padapter);
13075                 rtw_phydm_func_disable_all(padapter);
13076                 
13077                 //cancel link timer 
13078                 _cancel_timer_ex(&pmlmeext->link_timer);
13079
13080                 //clear CAM
13081                 flush_all_cam_entry(padapter);  
13082
13083                 pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
13084                 _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13085                 pnetwork->IELength = pdev_network->IELength;
13086
13087                 if (pnetwork->IELength > MAX_IE_SZ) {
13088                         ret = H2C_PARAMETERS_ERROR;
13089                         goto ibss_post_hdl;
13090                 }
13091
13092                 _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
13093                 start_create_ibss(padapter);
13094         } else {
13095                 rtw_warn_on(1);
13096                 ret = H2C_PARAMETERS_ERROR;
13097         }
13098
13099 ibss_post_hdl:
13100         rtw_create_ibss_post_hdl(padapter, ret);
13101
13102 exit:
13103         return ret;
13104 }
13105
13106 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13107 {
13108         u8      join_type;
13109         PNDIS_802_11_VARIABLE_IEs       pIE;
13110         struct registry_priv    *pregpriv = &padapter->registrypriv;
13111         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13112         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
13113         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13114 #ifdef CONFIG_ANTENNA_DIVERSITY
13115         struct joinbss_parm     *pparm = (struct joinbss_parm *)pbuf;
13116 #endif //CONFIG_ANTENNA_DIVERSITY
13117         u32 i;
13118         //u8    initialgain;
13119         //u32   acparm;
13120         u8 u_ch, u_bw, u_offset;
13121         u8 doiqk = _FALSE;
13122
13123         //check already connecting to AP or not
13124         if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
13125         {
13126                 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13127                 {
13128                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13129                 }
13130                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13131                 
13132                 //clear CAM
13133                 flush_all_cam_entry(padapter);          
13134                 
13135                 _cancel_timer_ex(&pmlmeext->link_timer);
13136                 
13137                 //set MSR to nolink -> infra. mode              
13138                 //Set_MSR(padapter, _HW_STATE_NOLINK_);
13139                 Set_MSR(padapter, _HW_STATE_STATION_);  
13140                 
13141
13142                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13143         }
13144
13145 #ifdef CONFIG_ANTENNA_DIVERSITY
13146         rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13147 #endif
13148
13149 #ifdef CONFIG_WAPI_SUPPORT
13150         rtw_wapi_clear_all_cam_entry(padapter);
13151 #endif
13152
13153         rtw_joinbss_reset(padapter);
13154
13155         pmlmeinfo->ERP_enable = 0;
13156         pmlmeinfo->WMM_enable = 0;
13157         pmlmeinfo->HT_enable = 0;
13158         pmlmeinfo->HT_caps_enable = 0;
13159         pmlmeinfo->HT_info_enable = 0;
13160         pmlmeinfo->agg_enable_bitmap = 0;
13161         pmlmeinfo->candidate_tid_bitmap = 0;
13162         pmlmeinfo->bwmode_updated = _FALSE;
13163         //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
13164         pmlmeinfo->VHT_enable = 0;
13165
13166         _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength)); 
13167         pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13168         
13169         if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
13170                 return H2C_PARAMETERS_ERROR;    
13171         
13172         if (pnetwork->IELength < 2) {
13173                 report_join_res(padapter, (-4));
13174                 return H2C_SUCCESS;
13175         }
13176         _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength); 
13177
13178         pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13179
13180         //Check AP vendor to move rtw_joinbss_cmd()
13181         //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
13182
13183         //sizeof(NDIS_802_11_FIXED_IEs) 
13184         for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13185                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13186
13187                 switch (pIE->ElementID)
13188                 {
13189                         case _VENDOR_SPECIFIC_IE_://Get WMM IE.
13190                                 if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
13191                                 {
13192                                         WMM_param_handler(padapter, pIE);
13193                                 }
13194                                 break;
13195
13196 #ifdef CONFIG_80211N_HT
13197                         case _HT_CAPABILITY_IE_:        //Get HT Cap IE.
13198                                 pmlmeinfo->HT_caps_enable = 1;
13199                                 break;
13200
13201                         case _HT_EXTRA_INFO_IE_:        //Get HT Info IE.
13202                                 pmlmeinfo->HT_info_enable = 1;
13203                                 break;
13204 #endif /* CONFIG_80211N_HT */
13205
13206 #ifdef CONFIG_80211AC_VHT
13207                         case EID_VHTCapability://Get VHT Cap IE.
13208                                 pmlmeinfo->VHT_enable = 1;
13209                                 break;
13210
13211                         case EID_VHTOperation://Get VHT Operation IE.
13212                                 break;
13213 #endif /* CONFIG_80211AC_VHT */
13214                         default:
13215                                 break;
13216                 }
13217
13218                 i += (pIE->Length + 2);
13219         }
13220
13221         rtw_bss_get_chbw(pnetwork
13222                 , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13223
13224         rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13225
13226 #if 0
13227         if (padapter->registrypriv.wifi_spec) {
13228                 // for WiFi test, follow WMM test plan spec
13229                 acparm = 0x002F431C; // VO
13230                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13231                 acparm = 0x005E541C; // VI
13232                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13233                 acparm = 0x0000A525; // BE
13234                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13235                 acparm = 0x0000A549; // BK
13236                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13237         
13238                 // for WiFi test, mixed mode with intel STA under bg mode throughput issue
13239                 if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
13240                         acparm = 0x00004320;
13241                         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13242                 }
13243         }
13244         else {
13245                 acparm = 0x002F3217; // VO
13246                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13247                 acparm = 0x005E4317; // VI
13248                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13249                 acparm = 0x00105320; // BE
13250                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13251                 acparm = 0x0000A444; // BK
13252                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13253         }
13254 #endif
13255
13256         /* check channel, bandwidth, offset and switch */
13257         if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
13258                 report_join_res(padapter, (-4));
13259                 return H2C_SUCCESS;
13260         }
13261
13262         //disable dynamic functions, such as high power, DIG
13263         /*rtw_phydm_func_disable_all(padapter);*/
13264
13265         //config the initial gain under linking, need to write the BB registers
13266         //initialgain = 0x1E;
13267         /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13268
13269         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
13270         join_type = 0;
13271         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13272         doiqk = _TRUE;
13273         rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13274
13275         set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
13276
13277         doiqk = _FALSE;
13278         rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13279
13280         //cancel link timer 
13281         _cancel_timer_ex(&pmlmeext->link_timer);
13282         
13283         start_clnt_join(padapter);
13284         
13285         return H2C_SUCCESS;
13286         
13287 }
13288
13289 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
13290 {
13291         struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
13292         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13293         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
13294         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13295         u8 val8;
13296
13297         if (is_client_associated_to_ap(padapter))
13298         {
13299 #ifdef CONFIG_DFS
13300                 if(padapter->mlmepriv.handle_dfs == _FALSE)
13301 #endif //CONFIG_DFS
13302 #ifdef CONFIG_PLATFORM_ROCKCHIPS
13303                         //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
13304                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13305 #else
13306                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
13307 #endif //CONFIG_PLATFORM_ROCKCHIPS
13308         }
13309
13310 #ifdef CONFIG_DFS
13311         if( padapter->mlmepriv.handle_dfs == _TRUE )
13312                 padapter->mlmepriv.handle_dfs = _FALSE;
13313 #endif //CONFIG_DFS
13314
13315         if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13316         {
13317                 //Stop BCN
13318                 val8 = 0;
13319                 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13320         }
13321
13322         rtw_mlmeext_disconnect(padapter);
13323
13324         rtw_free_uc_swdec_pending_queue(padapter);
13325
13326         return  H2C_SUCCESS;
13327 }
13328
13329 static const char * const _scan_state_str[] = {
13330         "SCAN_DISABLE",
13331         "SCAN_START",
13332         "SCAN_PS_ANNC_WAIT",
13333         "SCAN_ENTER",
13334         "SCAN_PROCESS",
13335         "SCAN_BACKING_OP",
13336         "SCAN_BACK_OP",
13337         "SCAN_LEAVING_OP",
13338         "SCAN_LEAVE_OP",
13339         "SCAN_SW_ANTDIV_BL",
13340         "SCAN_TO_P2P_LISTEN",
13341         "SCAN_P2P_LISTEN",
13342         "SCAN_COMPLETE",
13343         "SCAN_STATE_MAX",
13344 };
13345
13346 const char *scan_state_str(u8 state)
13347 {
13348         state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
13349         return _scan_state_str[state];
13350 }
13351
13352 static bool scan_abort_hdl(_adapter *adapter)
13353 {
13354         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13355         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13356         struct ss_res *ss = &pmlmeext->sitesurvey_res;
13357 #ifdef CONFIG_P2P
13358         struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13359 #endif
13360         bool ret = _FALSE;
13361
13362         if (pmlmeext->scan_abort == _TRUE) {
13363                 #ifdef CONFIG_P2P
13364                 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
13365                         rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
13366                         ss->channel_idx = 3;
13367                         DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
13368                                 , ss->channel_idx
13369                                 , pwdinfo->find_phase_state_exchange_cnt
13370                         );
13371                 } else
13372                 #endif
13373                 {
13374                         ss->channel_idx = ss->ch_num;
13375                         DBG_871X("%s idx:%d\n", __FUNCTION__
13376                                 , ss->channel_idx
13377                         );
13378                 }
13379                 pmlmeext->scan_abort = _FALSE;
13380                 ret = _TRUE;
13381         }
13382
13383         return ret;
13384 }
13385
13386 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13387 {
13388 /* interval larger than this is treated as backgroud scan */
13389 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13390 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13391 #endif
13392
13393 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13394 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13395 #endif
13396 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13397 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13398 #endif
13399
13400 #define SCAN_SPARSE_CH_NUM_INVALID 255
13401
13402         static u8 token = 255;
13403         u32 interval;
13404         bool busy_traffic = _FALSE;
13405         bool miracast_enabled = _FALSE;
13406         bool bg_scan = _FALSE;
13407         u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13408         u8 scan_division_num;
13409         u8 ret_num = ch_num;
13410         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13411         struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13412
13413         if (regsty->wifi_spec)
13414                 goto exit;
13415
13416         /* assume ch_num > 6 is normal scan */
13417         if (ch_num <= 6)
13418                 goto exit;
13419
13420         if (mlmeext->last_scan_time == 0)
13421                 mlmeext->last_scan_time = rtw_get_current_time();
13422
13423         interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13424
13425         if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE
13426                 #ifdef CONFIG_CONCURRENT_MODE
13427                 || (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
13428                 #endif
13429         )
13430                         busy_traffic = _TRUE;
13431
13432         if (is_miracast_enabled(adapter)
13433                 #ifdef CONFIG_CONCURRENT_MODE
13434                 || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter))
13435                 #endif
13436         )
13437                 miracast_enabled = _TRUE;
13438
13439         if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13440                 bg_scan = _TRUE;
13441
13442         /* max_allow_ch by conditions*/
13443
13444         #if RTW_SCAN_SPARSE_MIRACAST
13445         if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13446                 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13447         #endif
13448
13449         #if RTW_SCAN_SPARSE_BG
13450         if (bg_scan == _TRUE)
13451                 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13452         #endif
13453
13454
13455         if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13456                 int i;
13457                 int k = 0;
13458
13459                 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0);
13460                 token = (token + 1) % scan_division_num;
13461                 
13462                 if (0)
13463                         DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token);
13464                 
13465                 for (i = 0; i < ch_num; i++) {
13466                         if (ch[i].hw_value && (i % scan_division_num) == token
13467                         ) {
13468                                 if (i != k)
13469                                         _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13470                                 k++;
13471                         }
13472                 }
13473
13474                 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13475
13476                 ret_num = k;
13477                 mlmeext->last_scan_time = rtw_get_current_time();
13478         }
13479
13480 exit:
13481         return ret_num;
13482 }
13483
13484 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13485         u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13486 {
13487         int i, j;
13488         int scan_ch_num = 0;
13489         int set_idx;
13490         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13491
13492         /* clear first */
13493         _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
13494
13495         /* acquire channels from in */
13496         j = 0;
13497         for (i=0;i<in_num;i++) {
13498
13499                 if (0)
13500                         DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13501
13502                 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
13503                         && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
13504                         && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE
13505                 )
13506                 {
13507                         if (j >= out_num) {
13508                                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13509                                         FUNC_ADPT_ARG(padapter), out_num);
13510                                 break;
13511                         }
13512
13513                         _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13514                         
13515                         if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13516                                 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13517                                 
13518                         j++;
13519                 }
13520                 if(j>=out_num)
13521                         break;
13522         }
13523         
13524         /* if out is empty, use channel_set as default */
13525         if(j == 0) {
13526                 for (i=0;i<pmlmeext->max_chan_nums;i++) {
13527
13528                         if (0)
13529                                 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
13530
13531                         if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) {
13532
13533                                 if (j >= out_num) {
13534                                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13535                                                 FUNC_ADPT_ARG(padapter), out_num);
13536                                         break;
13537                                 }
13538
13539                                 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
13540                         
13541                                 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
13542                                         out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13543
13544                                 j++;
13545                         }
13546                 }
13547         }
13548
13549         /* scan_sparse */
13550         j = rtw_scan_sparse(padapter, out, j);
13551
13552         return j;
13553 }
13554
13555 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
13556 {
13557         struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
13558         int i;
13559
13560         ss->bss_cnt = 0;
13561         ss->channel_idx = 0;
13562 #ifdef CONFIG_SCAN_BACKOP
13563         ss->scan_cnt = 0;
13564 #endif
13565 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
13566         ss->is_sw_antdiv_bl_scan = 0;
13567 #endif
13568         
13569         for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13570                 if (parm->ssid[i].SsidLength) {
13571                         _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
13572                         ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
13573                 } else {
13574                         ss->ssid[i].SsidLength = 0;
13575                 }
13576         }
13577
13578         ss->ch_num = rtw_scan_ch_decision(adapter
13579                 , ss->ch, RTW_CHANNEL_SCAN_AMOUNT
13580                 , parm->ch, parm->ch_num
13581         );
13582
13583         ss->scan_mode = parm->scan_mode;
13584 }
13585
13586 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
13587 {
13588         u8 next_state;
13589         u8 scan_ch = 0;
13590         RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
13591         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13592         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
13593         struct ss_res *ss = &pmlmeext->sitesurvey_res;
13594
13595 #ifdef CONFIG_P2P
13596         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13597 #endif
13598
13599         /* handle scan abort request */
13600         scan_abort_hdl(padapter);
13601
13602 #ifdef CONFIG_P2P
13603         if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
13604                 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
13605                         scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
13606                 else
13607                         scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
13608                 scan_type = SCAN_ACTIVE;
13609         } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
13610                 /*
13611                 * Commented by Albert 2011/06/03
13612                 * The driver is in the find phase, it should go through the social channel.
13613                 */
13614                 int ch_set_idx;
13615
13616                 scan_ch = pwdinfo->social_chan[ss->channel_idx];
13617                 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch);
13618                 if (ch_set_idx >= 0)
13619                         scan_type = pmlmeext->channel_set[ch_set_idx].ScanType;
13620                 else
13621                         scan_type = SCAN_ACTIVE;
13622         } else
13623 #endif /* CONFIG_P2P */
13624         {
13625                 struct rtw_ieee80211_channel *ch;
13626
13627                 if (ss->channel_idx < ss->ch_num) {
13628                         ch = &ss->ch[ss->channel_idx];
13629                         scan_ch = ch->hw_value;
13630                         scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
13631                 }
13632         }
13633
13634         if (scan_ch != 0) {
13635                 next_state = SCAN_PROCESS;
13636                 #ifdef CONFIG_SCAN_BACKOP
13637                 {
13638                         u8 sta_num;
13639                         u8 ld_sta_num;
13640                         u8 ap_num;
13641                         u8 ld_ap_num;
13642                         u8 backop_flags = 0;
13643
13644                         rtw_dev_iface_status(padapter, &sta_num, &ld_sta_num, NULL, &ap_num, &ld_ap_num);
13645
13646                         if ((ld_sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN))
13647                                         || (sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL))
13648                         ) {
13649                                 backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext);
13650                         }
13651
13652                         if ((ld_ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN))
13653                                         || (ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL))
13654                         ) {
13655                                 backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext);
13656                         }
13657
13658                         if (backop_flags) {
13659                                 if (ss->scan_cnt < ss->scan_cnt_max) {
13660                                         ss->scan_cnt++;
13661                                 } else {
13662                                         mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
13663                                         next_state = SCAN_BACKING_OP;
13664                                 }
13665                         }
13666                 }
13667                 #endif /* CONFIG_SCAN_BACKOP */
13668         } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
13669                 /* go p2p listen */
13670                 next_state = SCAN_TO_P2P_LISTEN;
13671
13672         #ifdef CONFIG_ANTENNA_DIVERSITY
13673         } else if (rtw_hal_antdiv_before_linked(padapter)) {
13674                 /* go sw antdiv before link */
13675                 next_state = SCAN_SW_ANTDIV_BL;
13676         #endif
13677         } else {
13678                 next_state = SCAN_COMPLETE;
13679
13680                 #if defined(DBG_SCAN_SW_ANTDIV_BL)
13681                 {
13682                         /* for SCAN_SW_ANTDIV_BL state testing */
13683                         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13684                         int i;
13685                         bool is_linked = _FALSE;
13686
13687                         for (i = 0; i < dvobj->iface_nums; i++) {
13688                                 if (rtw_linked_check(dvobj->padapters[i]))
13689                                         is_linked = _TRUE;
13690                         }
13691
13692                         if (!is_linked) {
13693                                 static bool fake_sw_antdiv_bl_state = 0;
13694
13695                                 if (fake_sw_antdiv_bl_state == 0) {
13696                                         next_state = SCAN_SW_ANTDIV_BL;
13697                                         fake_sw_antdiv_bl_state = 1;
13698                                 } else {
13699                                         fake_sw_antdiv_bl_state = 0;
13700                                 }
13701                         }
13702                 }
13703                 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
13704         }
13705
13706         #ifdef CONFIG_SCAN_BACKOP
13707         if (next_state != SCAN_PROCESS)
13708                 ss->scan_cnt = 0;
13709         #endif
13710
13711
13712 #ifdef DBG_FIXED_CHAN
13713         if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
13714                 scan_ch = pmlmeext->fixed_chan;
13715 #endif
13716
13717         if (ch)
13718                 *ch = scan_ch;
13719         if (type)
13720                 *type = scan_type;
13721
13722         return next_state;
13723 }
13724
13725 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
13726 {
13727         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13728         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13729
13730 #ifdef CONFIG_P2P
13731         struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
13732 #endif
13733
13734         if (survey_channel != 0) {
13735                 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
13736
13737                 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13738                 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
13739                         ACS_OP acs_op = ACS_RESET;
13740
13741                         rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
13742                         rtw_set_acs_channel(padapter, survey_channel);
13743                         #ifdef DBG_AUTO_CHNL_SEL_NHM
13744                         DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n",
13745                                 ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
13746                         #endif
13747                 }
13748                 #endif
13749
13750                 if (ScanType == SCAN_ACTIVE) {
13751                         #ifdef CONFIG_P2P
13752                         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || 
13753                                 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
13754                         ) {
13755                                 issue_probereq_p2p(padapter, NULL);
13756                                 issue_probereq_p2p(padapter, NULL);
13757                                 issue_probereq_p2p(padapter, NULL);
13758                         } else
13759                         #endif /* CONFIG_P2P */
13760                         {
13761                                 int i;
13762
13763                                 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13764                                         if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
13765                                                 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13766                                                 if (padapter->registrypriv.wifi_spec)
13767                                                         issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13768                                                 else
13769                                                         issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
13770                                                 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13771                                         }
13772                                 }
13773
13774                                 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
13775                                         /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13776                                         if (padapter->registrypriv.wifi_spec)
13777                                                 issue_probereq(padapter, NULL, NULL);
13778                                         else
13779                                                 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
13780                                         issue_probereq(padapter, NULL, NULL);
13781                                 }
13782                         }
13783                 }
13784         } else {
13785                 /* channel number is 0 or this channel is not valid. */
13786                 rtw_warn_on(1);
13787         }
13788
13789         return;
13790 }
13791
13792 void survey_done_set_ch_bw(_adapter *padapter)
13793 {
13794         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13795         u8 cur_channel = 0;
13796         u8 cur_bwmode;
13797         u8 cur_ch_offset;
13798         
13799         if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
13800                 if (0)
13801                         DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
13802                                 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13803         } else {
13804                 #ifdef CONFIG_P2P
13805                 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13806                 _adapter *iface;
13807                 int i;
13808
13809                 for (i = 0; i < dvobj->iface_nums; i++) {
13810                         iface = dvobj->padapters[i];
13811                         if (!iface)
13812                                 continue;
13813
13814                         #ifdef CONFIG_IOCTL_CFG80211
13815                         if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
13816                                 continue;
13817                         #endif
13818
13819                         if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
13820                                 cur_channel = iface->wdinfo.listen_channel;
13821                                 cur_bwmode = CHANNEL_WIDTH_20;
13822                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13823                                 if (0)
13824                                         DBG_871X(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
13825                                                 FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
13826                                 break;
13827                         }
13828                 }
13829                 #endif /* CONFIG_P2P */
13830
13831                 if (cur_channel == 0) {
13832                         cur_channel = pmlmeext->cur_channel;
13833                         cur_bwmode = pmlmeext->cur_bwmode;
13834                         cur_ch_offset = pmlmeext->cur_ch_offset;
13835                         if (0)
13836                                 DBG_871X(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
13837                                         FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13838                 }
13839         }
13840
13841         set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
13842 }
13843
13844 /**
13845  * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
13846  * @dvobj: the dvobj to check
13847  * @ps: power saving or not
13848  *
13849  * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
13850  */
13851 u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps)
13852 {
13853         _adapter *adapter;
13854         int i;
13855         u8 ps_anc = 0;
13856
13857         for (i = 0; i < dvobj->iface_nums; i++) {
13858                 adapter = dvobj->padapters[i];
13859                 if (!adapter)
13860                         continue;
13861
13862                 if (ps) {
13863                         if (is_client_associated_to_ap(adapter) == _TRUE) {
13864                                 /* TODO: TDLS peers */
13865                                 issue_nulldata(adapter, NULL, 1, 3, 500);
13866                                 ps_anc = 1;
13867                         }
13868                 } else {
13869                         if (is_client_associated_to_ap(adapter) == _TRUE) {
13870                                 /* TODO: TDLS peers */
13871                                 issue_nulldata(adapter, NULL, 0, 3, 500);
13872                                 ps_anc = 1;
13873                         }
13874                 }
13875         }
13876
13877         return ps_anc;
13878 }
13879
13880 void sitesurvey_set_igi(_adapter *adapter, bool enter)
13881 {
13882         u8 igi;
13883 #ifdef CONFIG_P2P
13884         struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13885 #endif
13886
13887         if (enter) {
13888 #ifdef CONFIG_P2P
13889 #ifdef CONFIG_IOCTL_CFG80211
13890                 if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211)
13891                         igi = 0x30;
13892                 else
13893 #endif /* CONFIG_IOCTL_CFG80211 */
13894                 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
13895                         igi = 0x28;
13896                 else
13897 #endif /* CONFIG_P2P */
13898                         igi = 0x1e;
13899         } else {
13900                         igi = 0xff; /* restore RX GAIN */
13901         }
13902
13903         rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
13904 }
13905
13906 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
13907 {
13908         struct sitesurvey_parm  *pparm = (struct sitesurvey_parm *)pbuf;
13909         struct dvobj_priv *dvobj = padapter->dvobj;
13910         struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
13911         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13912         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13913         struct ss_res *ss = &pmlmeext->sitesurvey_res;
13914         u8 val8;
13915
13916 #ifdef CONFIG_P2P
13917         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13918 #endif
13919
13920 #ifdef DBG_CHECK_FW_PS_STATE
13921         if (rtw_fw_ps_state(padapter) == _FAIL) {
13922                 DBG_871X("scan without leave 32k\n");
13923                 pdbgpriv->dbg_scan_pwr_state_cnt++;
13924         }
13925 #endif /* DBG_CHECK_FW_PS_STATE */
13926
13927         /* increase channel idx */
13928         if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
13929                 ss->channel_idx++;
13930
13931         /* update scan state to next state (assigned by previous cmd hdl) */
13932         if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
13933                 mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
13934
13935 operation_by_state:
13936         switch (mlmeext_scan_state(pmlmeext)) {
13937
13938         case SCAN_DISABLE:
13939                 /* 
13940                 * SW parameter initialization
13941                 */
13942
13943                 sitesurvey_res_reset(padapter, pparm);
13944                 mlmeext_set_scan_state(pmlmeext, SCAN_START);
13945                 goto operation_by_state;
13946
13947         case SCAN_START:
13948                 /*
13949                 * prepare to leave operating channel
13950                 */
13951
13952                 /* apply rx ampdu setting */
13953                 if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
13954                         || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID
13955                 ) {
13956                         rtw_rx_ampdu_apply(padapter);
13957                 }
13958
13959                 /* clear HW TX queue before scan */
13960                 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
13961
13962                 /* power save state announcement */
13963                 if (sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)) {
13964                         mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
13965                         mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
13966                         set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
13967                 } else {
13968                         mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
13969                         goto operation_by_state;
13970                 }
13971
13972                 break;
13973
13974         case SCAN_ENTER:
13975                 /*
13976                 * HW register and DM setting for enter scan
13977                 */
13978
13979                 /* config the initial gain under scanning */
13980                 sitesurvey_set_igi(padapter, 1);
13981                 
13982                 /* disable dynamic functions, such as high power, DIG */
13983                 rtw_phydm_ability_backup(padapter);
13984                 rtw_phydm_func_for_offchannel(padapter);
13985                 /* set MSR to no link state */
13986                 Set_MSR(padapter, _HW_STATE_NOLINK_);
13987                 val8 = 1; /* under site survey */
13988                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
13989
13990                 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
13991                 goto operation_by_state;
13992
13993         case SCAN_PROCESS:
13994         {
13995                 u8 scan_ch;
13996                 RT_SCAN_TYPE scan_type;
13997                 u8 next_state;
13998                 u32 scan_ms;
13999
14000                 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14001                 if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) {
14002                         ACS_OP acs_op = ACS_SELECT;
14003
14004                         rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
14005                 }
14006                 #endif
14007
14008                 next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
14009                 if (next_state != SCAN_PROCESS) {
14010                         #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14011                         if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
14012                                 rtw_set_acs_channel(padapter, 0);
14013                                 #ifdef DBG_AUTO_CHNL_SEL_NHM
14014                                 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
14015                                 #endif
14016                         }
14017                         #endif
14018
14019                         mlmeext_set_scan_state(pmlmeext, next_state);
14020                         goto operation_by_state;
14021                 }
14022
14023                 /* still SCAN_PROCESS state */
14024                 if (0)
14025                         #ifdef CONFIG_P2P
14026                         DBG_871X(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
14027                                 , FUNC_ADPT_ARG(padapter)
14028                                 , mlmeext_scan_state_str(pmlmeext)
14029                                 , scan_ch
14030                                 , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
14031                                 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14032                                 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14033                                 , ss->ssid[0].SsidLength?'S':' ' 
14034                         );
14035                         #else
14036                         DBG_871X(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n"
14037                                 , FUNC_ADPT_ARG(padapter)
14038                                 , mlmeext_scan_state_str(pmlmeext)
14039                                 , scan_ch
14040                                 , ss->channel_idx
14041                                 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14042                                 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14043                                 , ss->ssid[0].SsidLength?'S':' '
14044                         );
14045                         #endif /* CONFIG_P2P */
14046
14047                 #ifdef DBG_FIXED_CHAN
14048                 if (pmlmeext->fixed_chan != 0xff)
14049                         DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
14050                 #endif
14051
14052                 site_survey(padapter, scan_ch, scan_type);
14053
14054                 #if defined(CONFIG_ATMEL_RC_PATCH)
14055                 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
14056                         scan_ms = 20;
14057                 else
14058                         scan_ms = 40;
14059                 #else
14060                 scan_ms = ss->scan_ch_ms;
14061                 #endif
14062
14063                 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14064                 if (ss->is_sw_antdiv_bl_scan)
14065                         scan_ms = scan_ms/2;
14066                 #endif
14067
14068                 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14069                 {
14070                         struct noise_info info;
14071
14072                         info.bPauseDIG = _FALSE;
14073                         info.IGIValue = 0;
14074                         info.max_time = scan_ms/2;
14075                         info.chan = scan_ch;
14076                         rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE); 
14077                 }
14078                 #endif
14079
14080                 set_survey_timer(pmlmeext, scan_ms);
14081                 break;
14082         }
14083
14084         #ifdef CONFIG_SCAN_BACKOP
14085         case SCAN_BACKING_OP:
14086         {
14087                 u8 back_ch, back_bw, back_ch_offset;
14088
14089                 if (rtw_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
14090                         rtw_warn_on(1);
14091
14092                 if (0)
14093                         DBG_871X(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
14094                                 , FUNC_ADPT_ARG(padapter)
14095                                 , mlmeext_scan_state_str(pmlmeext)
14096                                 , back_ch, back_bw, back_ch_offset
14097                                 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14098                         );
14099
14100                 set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
14101
14102                 Set_MSR(padapter, (pmlmeinfo->state & 0x3));            
14103                 val8 = 0; /* survey done */
14104                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14105
14106                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14107                         sitesurvey_set_igi(padapter, 0);
14108                         sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14109                 }
14110
14111                 mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
14112                 ss->backop_time = rtw_get_current_time();
14113
14114                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME)) {
14115                         int     i;
14116
14117                         /* resume TX */
14118                         for (i = 0; i < dvobj->iface_nums; i++) {
14119                                 if (!dvobj->padapters[i])
14120                                         continue;
14121
14122                                 rtw_os_xmit_schedule(dvobj->padapters[i]);
14123                         }
14124                 }
14125
14126                 goto operation_by_state;
14127         }
14128         
14129         case SCAN_BACK_OP:
14130                 if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
14131                         || pmlmeext->scan_abort
14132                 ) {
14133                         mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
14134                         goto operation_by_state;
14135                 }
14136                 set_survey_timer(pmlmeext, 50);
14137                 break;
14138
14139         case SCAN_LEAVING_OP:
14140                 /*
14141                 * prepare to leave operating channel
14142                 */
14143
14144                 /* clear HW TX queue before scan */
14145                 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14146
14147                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
14148                         && sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)
14149                 ) {
14150                         mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14151                         mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
14152                         set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14153                 } else {
14154                         mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
14155                         goto operation_by_state;
14156                 }
14157
14158                 break;
14159
14160         case SCAN_LEAVE_OP:
14161                 /*
14162                 * HW register and DM setting for enter scan
14163                 */
14164
14165                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14166                         /* config the initial gain under scanning */
14167                         sitesurvey_set_igi(padapter, 1);
14168                 }
14169
14170                 /* set MSR to no link state */
14171                 Set_MSR(padapter, _HW_STATE_NOLINK_);
14172                 val8 = 1; //under site survey
14173                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14174
14175                 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14176                 goto operation_by_state;
14177
14178         #endif /* CONFIG_SCAN_BACKOP */
14179
14180         #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14181         case SCAN_SW_ANTDIV_BL:
14182                 /*
14183                 * 20100721
14184                 * For SW antenna diversity before link, it needs to switch to another antenna and scan again.
14185                 * It compares the scan result and select better one to do connection.
14186                 */
14187                 ss->bss_cnt = 0;
14188                 ss->channel_idx = 0;
14189                 ss->is_sw_antdiv_bl_scan = 1;
14190
14191                 mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
14192                 set_survey_timer(pmlmeext, ss->scan_ch_ms);
14193                 break;
14194         #endif
14195
14196         #ifdef CONFIG_P2P
14197         case SCAN_TO_P2P_LISTEN:
14198                 /*
14199                 * Set the P2P State to the listen state of find phase
14200                 * and set the current channel to the listen channel
14201                 */
14202                 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14203                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
14204         
14205                 /* turn on phy-dynamic functions */
14206                 rtw_phydm_ability_restore(padapter);
14207
14208                 sitesurvey_set_igi(padapter, 0);
14209
14210                 mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
14211                 _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
14212                 break;
14213
14214         case SCAN_P2P_LISTEN:
14215                 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14216                 ss->channel_idx = 0;
14217                 goto operation_by_state;
14218         #endif /* CONFIG_P2P */
14219
14220         case SCAN_COMPLETE:             
14221                 #ifdef CONFIG_P2P
14222                 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14223                         || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14224                 ) {
14225                         #ifdef CONFIG_CONCURRENT_MODE
14226                         if (pwdinfo->driver_interface == DRIVER_WEXT) {
14227                                 if (check_buddy_fwstate(padapter, _FW_LINKED))
14228                                         _set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
14229                         }
14230                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14231                         #else
14232                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14233                         #endif
14234                 }
14235                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
14236                 #endif /* CONFIG_P2P */
14237
14238                 /* switch channel */
14239                 survey_done_set_ch_bw(padapter);
14240
14241                 /* config MSR */
14242                 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14243                 val8 = 0; /* survey done */
14244                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14245
14246                 /* turn on phy-dynamic functions */
14247                 rtw_phydm_ability_restore(padapter);
14248
14249                 sitesurvey_set_igi(padapter, 0);
14250
14251                 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14252
14253                 /* apply rx ampdu setting */
14254                 rtw_rx_ampdu_apply(padapter);
14255
14256                 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
14257
14258                 report_surveydone_event(padapter);
14259
14260                 issue_action_BSSCoexistPacket(padapter);
14261                 issue_action_BSSCoexistPacket(padapter);
14262                 issue_action_BSSCoexistPacket(padapter);
14263         }
14264
14265         return H2C_SUCCESS;
14266 }
14267
14268 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
14269 {
14270         struct setauth_parm             *pparm = (struct setauth_parm *)pbuf;
14271         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14272         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14273         
14274         if (pparm->mode < 4)
14275         {
14276                 pmlmeinfo->auth_algo = pparm->mode;
14277         }
14278
14279         return  H2C_SUCCESS;
14280 }
14281
14282 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
14283 {
14284         u16     ctrl = 0;
14285         s16 cam_id = 0;
14286         struct setkey_parm              *pparm = (struct setkey_parm *)pbuf;
14287         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14288         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14289         unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14290         struct set_stakey_parm  sta_pparm;
14291         struct security_priv *psecuritypriv = &padapter->securitypriv;
14292         u8 *addr;
14293         bool used;
14294
14295         //main tx key for wep.
14296         if(pparm->set_tx)
14297                 pmlmeinfo->key_index = pparm->keyid;
14298
14299         cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used);
14300
14301         if (cam_id < 0)
14302                 goto enable_mc;
14303
14304         if (cam_id > 3) /* not default key, searched by A2 */
14305                 addr = get_bssid(&padapter->mlmepriv);
14306         else
14307                 addr = null_addr;
14308
14309         #ifdef DYNAMIC_CAMID_ALLOC
14310         /* cam entry searched is pairwise key */
14311         if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
14312                 s16 camid_clr;
14313
14314                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
14315                         , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
14316
14317                 /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
14318                 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14319                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14320
14321                 /* clear group key */
14322                 while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
14323                         DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
14324                         clear_cam_entry(padapter, camid_clr);
14325                         rtw_camid_free(padapter, camid_clr);
14326                 }
14327
14328                 goto enable_mc;
14329         }
14330         #endif
14331
14332         ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
14333         DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
14334                 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
14335         write_cam(padapter, cam_id, ctrl, addr, pparm->key);
14336
14337         #ifdef DYNAMIC_CAMID_ALLOC
14338         if (cam_id >=0 && cam_id <=3)
14339                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE);
14340         #endif
14341         /* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
14342         if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC) && is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm)) {
14343                 struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
14344
14345                 sta_pparm.algorithm = pparm->algorithm;
14346                 sta_pparm.keyid = pparm->keyid;
14347                 _rtw_memcpy(sta_pparm.key, pparm->key, 16);
14348                 _rtw_memcpy(sta_pparm.addr, get_bssid(pmlmepriv), ETH_ALEN);
14349                 set_stakey_hdl(padapter, (u8 *) &sta_pparm);
14350         }
14351
14352 enable_mc:
14353         //allow multicast packets to driver
14354         rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
14355
14356         return H2C_SUCCESS;
14357 }
14358
14359 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
14360 {
14361         u16 ctrl = 0;
14362         s16 cam_id = 0;
14363         bool used;
14364         u8 ret = H2C_SUCCESS;
14365         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14366         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14367         struct set_stakey_parm  *pparm = (struct set_stakey_parm *)pbuf;
14368         struct sta_priv *pstapriv = &padapter->stapriv;
14369         struct sta_info *psta;
14370
14371         if(pparm->algorithm == _NO_PRIVACY_)
14372                 goto write_to_cam;
14373
14374         psta = rtw_get_stainfo(pstapriv, pparm->addr);
14375         if (!psta) {
14376                 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
14377                 ret = H2C_REJECTED;
14378                 goto exit;
14379         }
14380
14381         pmlmeinfo->enc_algo = pparm->algorithm;
14382         cam_id = rtw_camid_alloc(padapter, psta, 0, &used);
14383         if (cam_id < 0)
14384                 goto exit;
14385
14386         #ifdef DYNAMIC_CAMID_ALLOC
14387         /* cam entry searched is group key */
14388         if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
14389                 s16 camid_clr;
14390
14391                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
14392                         , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
14393
14394                 /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
14395                 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14396                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14397
14398                 /* clear group key */
14399                 while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
14400                         DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
14401                         clear_cam_entry(padapter, camid_clr);
14402                         rtw_camid_free(padapter, camid_clr);
14403                 }
14404         }
14405         #endif
14406
14407 write_to_cam:
14408         if(pparm->algorithm == _NO_PRIVACY_) {
14409                 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
14410                         DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
14411                         clear_cam_entry(padapter, cam_id);
14412                         rtw_camid_free(padapter,cam_id);
14413                 }
14414         } else {
14415                 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
14416                         cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
14417                 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
14418                 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
14419         }
14420         ret = H2C_SUCCESS_RSP;
14421
14422 exit:
14423         return ret;
14424 }
14425
14426 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
14427 {
14428         struct addBaReq_parm    *pparm = (struct addBaReq_parm *)pbuf;
14429         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14430         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14431
14432         struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
14433         
14434         if(!psta)
14435                 return  H2C_SUCCESS;
14436                 
14437 #ifdef CONFIG_80211N_HT
14438         if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
14439                 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
14440         {
14441                 //pmlmeinfo->ADDBA_retry_count = 0;
14442                 //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);               
14443                 //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
14444                 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14445                 //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
14446                 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14447         }
14448 #ifdef CONFIG_TDLS
14449         else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&& 
14450                 (psta->htpriv.ht_option==_TRUE) && 
14451                 (psta->htpriv.ampdu_enable==_TRUE) )
14452         {
14453                 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14454                 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14455         }
14456 #endif //CONFIG
14457         else
14458         {               
14459                 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);          
14460         }
14461 #endif //CONFIG_80211N_HT
14462         return  H2C_SUCCESS;
14463 }
14464
14465
14466 u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
14467 {
14468         struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
14469         u8 ret = _TRUE, i = 0, try_cnt = 3, wait_ms = 50;
14470         struct recv_reorder_ctrl *preorder_ctrl;
14471         struct sta_priv *pstapriv = &padapter->stapriv;
14472         struct sta_info *psta;
14473
14474         psta = rtw_get_stainfo(pstapriv, pparm->addr);
14475         if (!psta)
14476                 goto exit;
14477
14478         preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
14479         ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
14480
14481         #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
14482         /* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
14483         if (pparm->status == 0) {
14484                 preorder_ctrl->indicate_seq = pparm->start_seq;
14485                 #ifdef DBG_RX_SEQ
14486                 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __func__, __LINE__,
14487                         preorder_ctrl->indicate_seq, pparm->start_seq);
14488                 #endif
14489         }
14490         #else
14491         preorder_ctrl->indicate_seq = 0xffff;
14492         #endif
14493
14494         /*
14495           * status = 0 means accept this addba req
14496           * status = 37 means reject this addba req
14497           */
14498         if (pparm->status == 0) {
14499                 preorder_ctrl->enable = _TRUE;
14500                 preorder_ctrl->ampdu_size = pparm->size;
14501         } else if (pparm->status == 37)
14502                 preorder_ctrl->enable = _FALSE;
14503
14504 exit:
14505         return H2C_SUCCESS;
14506 }
14507
14508 u8 chk_bmc_sleepq_cmd(_adapter* padapter)
14509 {
14510         struct cmd_obj *ph2c;
14511         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14512         u8 res = _SUCCESS;
14513
14514 _func_enter_;
14515
14516         if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14517         {
14518                 res= _FAIL;
14519                 goto exit;
14520         }
14521
14522         init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
14523
14524         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14525
14526 exit:
14527
14528 _func_exit_;
14529
14530         return res;
14531 }
14532
14533 u8 set_tx_beacon_cmd(_adapter* padapter)
14534 {
14535         struct cmd_obj  *ph2c;
14536         struct Tx_Beacon_param  *ptxBeacon_parm;        
14537         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14538         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14539         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14540         u8      res = _SUCCESS;
14541         int len_diff = 0;
14542         
14543 _func_enter_;   
14544
14545         if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14546         {
14547                 res= _FAIL;
14548                 goto exit;
14549         }
14550
14551         if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
14552         {
14553                 rtw_mfree((unsigned char *)ph2c, sizeof(struct  cmd_obj));
14554                 res= _FAIL;
14555                 goto exit;
14556         }
14557
14558         _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
14559
14560         len_diff = update_hidden_ssid(
14561                 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
14562                 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
14563                 , pmlmeinfo->hidden_ssid_mode
14564         );
14565         ptxBeacon_parm->network.IELength += len_diff;
14566
14567         init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
14568
14569         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14570
14571         
14572 exit:
14573         
14574 _func_exit_;
14575
14576         return res;
14577 }
14578
14579
14580 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
14581 {
14582         u8 evt_code, evt_seq;
14583         u16 evt_sz;
14584         uint    *peventbuf;
14585         void (*event_callback)(_adapter *dev, u8 *pbuf);
14586         struct evt_priv *pevt_priv = &(padapter->evtpriv);
14587
14588         if (pbuf == NULL)
14589                 goto _abort_event_;
14590
14591         peventbuf = (uint*)pbuf;
14592         evt_sz = (u16)(*peventbuf&0xffff);
14593         evt_seq = (u8)((*peventbuf>>24)&0x7f);
14594         evt_code = (u8)((*peventbuf>>16)&0xff);
14595         
14596                 
14597         #ifdef CHECK_EVENT_SEQ
14598         // checking event sequence...           
14599         if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
14600         {
14601                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("Evetn Seq Error! %d vs %d\n", (evt_seq & 0x7f), (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)));
14602         
14603                 pevt_priv->event_seq = (evt_seq+1)&0x7f;
14604
14605                 goto _abort_event_;
14606         }
14607         #endif
14608
14609         // checking if event code is valid
14610         if (evt_code >= MAX_C2HEVT)
14611         {
14612                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
14613                 goto _abort_event_;
14614         }
14615
14616         // checking if event size match the event parm size     
14617         if ((wlanevents[evt_code].parmsize != 0) && 
14618                         (wlanevents[evt_code].parmsize != evt_sz))
14619         {
14620                         
14621                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n", 
14622                         evt_code, wlanevents[evt_code].parmsize, evt_sz));
14623                 goto _abort_event_;     
14624                         
14625         }
14626
14627         ATOMIC_INC(&pevt_priv->event_seq);
14628
14629         peventbuf += 2;
14630                                 
14631         if(peventbuf)
14632         {
14633                 event_callback = wlanevents[evt_code].event_callback;
14634                 event_callback(padapter, (u8*)peventbuf);
14635
14636                 pevt_priv->evt_done_cnt++;
14637         }
14638
14639
14640 _abort_event_:
14641
14642
14643         return H2C_SUCCESS;
14644                 
14645 }
14646
14647 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
14648 {
14649         if(!pbuf)
14650                 return H2C_PARAMETERS_ERROR;
14651
14652         return H2C_SUCCESS;
14653 }
14654
14655 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
14656 {
14657 #ifdef CONFIG_AP_MODE
14658         _irqL irqL;
14659         struct sta_info *psta_bmc;
14660         _list   *xmitframe_plist, *xmitframe_phead;
14661         struct xmit_frame *pxmitframe=NULL;
14662         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
14663         struct sta_priv  *pstapriv = &padapter->stapriv;
14664
14665         //for BC/MC Frames
14666         psta_bmc = rtw_get_bcmc_stainfo(padapter);
14667         if(!psta_bmc)
14668                 return H2C_SUCCESS;
14669
14670         if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
14671         {
14672 #ifndef CONFIG_PCI_HCI
14673                 rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
14674 #endif
14675                 //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14676                 _enter_critical_bh(&pxmitpriv->lock, &irqL);
14677
14678                 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
14679                 xmitframe_plist = get_next(xmitframe_phead);
14680
14681                 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
14682                 {
14683                         pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
14684
14685                         xmitframe_plist = get_next(xmitframe_plist);
14686
14687                         rtw_list_delete(&pxmitframe->list);
14688
14689                         psta_bmc->sleepq_len--;
14690                         if(psta_bmc->sleepq_len>0)
14691                                 pxmitframe->attrib.mdata = 1;
14692                         else
14693                                 pxmitframe->attrib.mdata = 0;
14694
14695                         pxmitframe->attrib.triggered=1;
14696
14697                         if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
14698                                 pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ
14699
14700                         #if 0
14701                         _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14702                         if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
14703                         {
14704                                 rtw_os_xmit_complete(padapter, pxmitframe);
14705                         }
14706                         _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14707                         #endif
14708                         rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
14709                 }
14710
14711                 //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14712                 _exit_critical_bh(&pxmitpriv->lock, &irqL);
14713
14714                 if (rtw_get_intf_type(padapter) != RTW_PCIE) {
14715                         /* check hi queue and bmc_sleepq */
14716                         rtw_chk_hi_queue_cmd(padapter);
14717                 }
14718         }
14719 #endif
14720
14721         return H2C_SUCCESS;
14722 }
14723
14724 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
14725 {
14726         if(send_beacon(padapter)==_FAIL)
14727         {
14728                 DBG_871X("issue_beacon, fail!\n");
14729                 return H2C_PARAMETERS_ERROR;
14730         }
14731
14732
14733         if (padapter->registrypriv.wifi_spec == 1)
14734                 return H2C_SUCCESS;
14735         
14736         /* tx bc/mc frames after update TIM */
14737         chk_bmc_sleepq_hdl(padapter, NULL);
14738
14739         return H2C_SUCCESS;
14740 }
14741
14742 /*
14743 * according to channel
14744 * add/remove WLAN_BSSID_EX.IEs's ERP ie
14745 * set WLAN_BSSID_EX.SupportedRates
14746 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
14747 */
14748 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
14749 {
14750         u8      network_type,rate_len, total_rate_len,remainder_rate_len;
14751         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
14752         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14753         u8      erpinfo=0x4;
14754
14755         if (ch >= 36) {
14756                 network_type = WIRELESS_11A;
14757                 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
14758                 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
14759         } else {
14760                 network_type = WIRELESS_11BG;
14761                 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
14762                 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
14763         }
14764
14765         rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
14766
14767         UpdateBrateTbl(padapter, pnetwork->SupportedRates);
14768
14769         if(total_rate_len > 8)
14770         {
14771                 rate_len = 8;
14772                 remainder_rate_len = total_rate_len - 8;
14773         }
14774         else
14775         {
14776                 rate_len = total_rate_len;
14777                 remainder_rate_len = 0;
14778         }
14779
14780         rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
14781
14782         if(remainder_rate_len)
14783         {
14784                 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
14785         }
14786         else
14787         {
14788                 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
14789         }
14790
14791         pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
14792 }
14793
14794 #ifdef CONFIG_CONCURRENT_MODE
14795 sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
14796 {
14797         PADAPTER pbuddy_adapter;
14798         struct mlme_ext_priv *pbuddy_mlmeext;
14799         struct mlme_ext_info *pbuddy_mlmeinfo;
14800
14801         if(padapter == NULL)
14802                 return _FALSE;  
14803         
14804         pbuddy_adapter = padapter->pbuddy_adapter;
14805
14806         if(pbuddy_adapter == NULL)
14807                 return _FALSE;  
14808
14809
14810         pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
14811         pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
14812                 
14813         if((pbuddy_mlmeinfo->state&0x03) == state)
14814                 return _TRUE;           
14815
14816         return _FALSE;
14817         
14818 }
14819 #endif /* CONFIG_CONCURRENT_MODE */
14820
14821 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
14822 {
14823 #define DUMP_ADAPTERS_STATUS 0
14824
14825         struct dvobj_priv *dvobj;
14826         _adapter *iface;
14827         struct mlme_priv *mlme;
14828         struct mlme_ext_priv *mlmeext;
14829         u8 u_ch, u_offset, u_bw;
14830         int i;
14831
14832         dvobj = adapter_to_dvobj(adapter);
14833
14834         if (DUMP_ADAPTERS_STATUS) {
14835                 DBG_871X(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
14836                 dump_adapters_status(RTW_DBGDUMP , dvobj);
14837         }
14838
14839         if (join_res >= 0) {
14840                 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14841                         dump_adapters_status(RTW_DBGDUMP , dvobj);
14842                         rtw_warn_on(1);
14843                 }
14844
14845                 for (i = 0; i < dvobj->iface_nums; i++) {
14846                         iface = dvobj->padapters[i];
14847                         mlme = &iface->mlmepriv;
14848                         mlmeext = &iface->mlmeextpriv;
14849
14850                         if (!iface || iface == adapter)
14851                                 continue;
14852
14853                         if (check_fwstate(mlme, WIFI_AP_STATE)
14854                                 && check_fwstate(mlme, WIFI_ASOC_STATE)
14855                         ) {
14856                                 bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
14857                                         , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14858
14859                                 if (is_grouped == _FALSE) {
14860                                         /* handle AP which need to switch ch setting */
14861
14862                                         /* restore original bw, adjust bw by registry setting on target ch */
14863                                         mlmeext->cur_bwmode = mlme->ori_bw;
14864                                         mlmeext->cur_channel = u_ch;
14865                                         rtw_adjust_chbw(iface
14866                                                 , mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
14867                                         
14868                                         rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
14869                                                 , &u_ch, &u_bw, &u_offset);
14870
14871                                         rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
14872                                                 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14873
14874                                         _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
14875
14876                                         rtw_start_bss_hdl_after_chbw_decided(iface);
14877                                 }
14878
14879                                 update_beacon(iface, 0, NULL, _TRUE);
14880                         }
14881
14882                         clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14883                 }
14884
14885                 #ifdef CONFIG_DFS_MASTER
14886                 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED);
14887                 #endif
14888         } else {
14889                 for (i = 0; i < dvobj->iface_nums; i++) {
14890                         iface = dvobj->padapters[i];
14891                         mlme = &iface->mlmepriv;
14892                         mlmeext = &iface->mlmeextpriv;
14893
14894                         if (!iface || iface == adapter)
14895                                 continue;
14896
14897                         if (check_fwstate(mlme, WIFI_AP_STATE)
14898                                 && check_fwstate(mlme, WIFI_ASOC_STATE))
14899                                 update_beacon(iface, 0, NULL, _TRUE);
14900
14901                         clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14902                 }
14903                 #ifdef CONFIG_DFS_MASTER
14904                 rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED);
14905                 #endif
14906         }
14907
14908         if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
14909                 set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
14910
14911         if (DUMP_ADAPTERS_STATUS) {
14912                 DBG_871X(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
14913                 dump_adapters_status(RTW_DBGDUMP , dvobj);
14914         }
14915 }
14916
14917 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
14918 {
14919         bool chbw_allow = _TRUE;
14920         bool connect_allow = _TRUE;
14921         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
14922         u8 cur_ch, cur_bw, cur_ch_offset;
14923         u8 u_ch, u_offset, u_bw;
14924
14925         u_ch = cur_ch = pmlmeext->cur_channel;
14926         u_bw = cur_bw = pmlmeext->cur_bwmode;
14927         u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
14928
14929         if (!ch || !bw || !offset) {
14930                 connect_allow = _FALSE;
14931                 rtw_warn_on(1);
14932                 goto exit;
14933         }
14934
14935         if (cur_ch == 0) {
14936                 connect_allow = _FALSE;
14937                 DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n"
14938                         , FUNC_ADPT_ARG(adapter), cur_ch);
14939                 rtw_warn_on(1);
14940                 goto exit;
14941         }
14942         DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14943
14944 #ifdef CONFIG_CONCURRENT_MODE
14945 {
14946         struct dvobj_priv *dvobj;
14947         _adapter *iface;
14948         struct mlme_priv *mlme;
14949         struct mlme_ext_priv *mlmeext;
14950         u8 sta_num;
14951         u8 ld_sta_num;
14952         u8 lg_sta_num;
14953         u8 ap_num;
14954         u8 ld_ap_num;
14955         int i;
14956
14957         dvobj = adapter_to_dvobj(adapter);
14958
14959         rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num);
14960         DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n"
14961                 , FUNC_ADPT_ARG(adapter), ld_sta_num, ap_num);
14962
14963         if (!ld_sta_num && !ap_num) {
14964                 /* consider linking STA? */
14965                 goto connect_allow_hdl;
14966         }
14967
14968         if (rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14969                 dump_adapters_status(RTW_DBGDUMP , dvobj);
14970                 rtw_warn_on(1);
14971         }
14972         DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
14973                 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14974
14975         /* chbw_allow? */
14976         chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
14977                 , u_ch, u_bw, u_offset);
14978
14979         DBG_871X(FUNC_ADPT_FMT" chbw_allow:%d\n"
14980                 , FUNC_ADPT_ARG(adapter), chbw_allow);
14981
14982         if (chbw_allow == _TRUE) {
14983                 rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
14984                 rtw_warn_on(cur_ch != pmlmeext->cur_channel);
14985                 rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
14986                 rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
14987                 goto connect_allow_hdl;
14988         }
14989
14990         /* chbw_allow is _FALSE, connect allow? */
14991         for (i = 0; i < dvobj->iface_nums; i++) {
14992                 iface = dvobj->padapters[i];
14993                 mlme = &iface->mlmepriv;
14994                 mlmeext = &iface->mlmeextpriv;
14995
14996                 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
14997                 if (check_fwstate(mlme, WIFI_STATION_STATE)
14998                         && check_fwstate(mlme, WIFI_ASOC_STATE)
14999                         #if defined(CONFIG_P2P)
15000                         && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
15001                         #endif
15002                 ) {
15003                         connect_allow = _FALSE;
15004                         break;
15005                 }
15006                 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
15007         }
15008         DBG_871X(FUNC_ADPT_FMT" connect_allow:%d\n"
15009                 , FUNC_ADPT_ARG(adapter), connect_allow);
15010
15011         if (connect_allow == _FALSE)
15012                 goto exit;
15013
15014 connect_allow_hdl:
15015         /* connect_allow == _TRUE */
15016
15017         #ifdef CONFIG_DFS_MASTER
15018         rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING);
15019         #endif
15020
15021         if (chbw_allow == _FALSE) {
15022                 u_ch = cur_ch;
15023                 u_bw = cur_bw;
15024                 u_offset = cur_ch_offset;
15025
15026                 for (i = 0; i < dvobj->iface_nums; i++) {
15027                         iface = dvobj->padapters[i];
15028                         mlme = &iface->mlmepriv;
15029                         mlmeext = &iface->mlmeextpriv;
15030
15031                         if (!iface || iface == adapter)
15032                                 continue;
15033
15034                         if (check_fwstate(mlme, WIFI_AP_STATE)
15035                                 && check_fwstate(mlme, WIFI_ASOC_STATE)
15036                         ) {
15037                                 #ifdef CONFIG_SPCT_CH_SWITCH
15038                                 if (1)
15039                                         rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
15040                                 else
15041                                 #endif
15042                                         rtw_sta_flush(iface, _FALSE);
15043
15044                                 rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
15045                                 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15046                         } else if (check_fwstate(mlme, WIFI_STATION_STATE)
15047                                 && check_fwstate(mlme, WIFI_ASOC_STATE)
15048                         ) {
15049                                 rtw_disassoc_cmd(iface, 500, _FALSE);
15050                                 rtw_indicate_disconnect(iface);
15051                                 rtw_free_assoc_resources(iface, 1);
15052                         }
15053                 }
15054         }
15055 }
15056 #endif /* CONFIG_CONCURRENT_MODE */
15057
15058 exit:
15059
15060         if (connect_allow == _TRUE) {
15061                 DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15062                 *ch = u_ch;
15063                 *bw = u_bw;
15064                 *offset = u_offset;
15065         }
15066
15067         return connect_allow == _TRUE ? _SUCCESS : _FAIL;
15068 }
15069
15070 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
15071 int _rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
15072 {
15073         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15074         _adapter *iface;
15075         struct mlme_ext_priv *mlmeext;
15076         int i;
15077         u8 ch_ret = 0;
15078         u8 bw_ret = CHANNEL_WIDTH_20;
15079         u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15080         int num = 0;
15081
15082         if (ch) *ch = 0;
15083         if (bw) *bw = CHANNEL_WIDTH_20;
15084         if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15085
15086         for (i = 0; i<dvobj->iface_nums; i++) {
15087                 iface = dvobj->padapters[i];
15088                 mlmeext = &iface->mlmeextpriv;
15089
15090                 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
15091                         continue;
15092
15093                 if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
15094                         continue;
15095
15096                 if (include_self == _FALSE && adapter == iface)
15097                         continue;
15098
15099                 if (num == 0) {
15100                         ch_ret = mlmeext->cur_channel;
15101                         bw_ret = mlmeext->cur_bwmode;
15102                         offset_ret = mlmeext->cur_ch_offset;
15103                         num++;
15104                         continue;
15105                 }
15106
15107                 if (ch_ret != mlmeext->cur_channel) {
15108                         num = 0;
15109                         break;
15110                 }
15111
15112                 if (bw_ret < mlmeext->cur_bwmode) {
15113                         bw_ret = mlmeext->cur_bwmode;
15114                         offset_ret = mlmeext->cur_ch_offset;
15115                 } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
15116                         num = 0;
15117                         break;
15118                 }
15119
15120                 num++;
15121         }
15122
15123         if (num) {
15124                 if (ch) *ch = ch_ret;
15125                 if (bw) *bw = bw_ret;
15126                 if (offset) *offset = offset_ret;
15127         }
15128
15129         return num;
15130 }
15131
15132 inline int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15133 {
15134         return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 1);
15135 }
15136
15137 inline int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15138 {
15139         return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 0);
15140 }
15141
15142 void _rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15143         , u8 *ap_num, u8 *ld_ap_num, bool include_self)
15144 {
15145         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15146         _adapter *iface;
15147         struct mlme_ext_priv *mlmeext;
15148         struct mlme_ext_info *mlmeextinfo;
15149         int i;
15150         u8 sta_num_ret = 0;
15151         u8 ld_sta_num_ret = 0;
15152         u8 lg_sta_num_ret = 0;
15153         u8 ap_num_ret = 0;
15154         u8 ld_ap_num_ret = 0;
15155
15156         if (sta_num)
15157                 *sta_num = 0;
15158         if (ld_sta_num)
15159                 *ld_sta_num = 0;
15160         if (lg_sta_num)
15161                 *lg_sta_num = 0;
15162         if (ap_num)
15163                 *ap_num = 0;
15164         if (ld_ap_num)
15165                 *ld_ap_num = 0;
15166
15167         for (i = 0; i < dvobj->iface_nums; i++) {
15168                 iface = dvobj->padapters[i];
15169
15170                 if (include_self == _FALSE && iface == adapter)
15171                         continue;
15172
15173                 mlmeext = &iface->mlmeextpriv;
15174
15175                 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
15176                         sta_num_ret++;
15177                         if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
15178                                 ld_sta_num_ret++;
15179                         if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
15180                                 lg_sta_num_ret++;
15181                 }
15182
15183                 if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
15184                         && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
15185                 ) {
15186                         ap_num_ret++;
15187                         if (iface->stapriv.asoc_sta_count > 2)
15188                                 ld_ap_num_ret++;
15189                 }
15190         }
15191
15192         if (sta_num)
15193                 *sta_num = sta_num_ret;
15194         if (ld_sta_num)
15195                 *ld_sta_num = ld_sta_num_ret;
15196         if (lg_sta_num)
15197                 *lg_sta_num = lg_sta_num_ret;
15198         if (ap_num)
15199                 *ap_num = ap_num_ret;
15200         if (ld_ap_num)
15201                 *ld_ap_num = ld_ap_num_ret;
15202 }
15203
15204 inline void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15205         , u8 *ap_num, u8 *ld_ap_num)
15206 {
15207         return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 1);
15208 }
15209
15210 inline void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15211         , u8 *ap_num, u8 *ld_ap_num)
15212 {
15213         return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 0);
15214 }
15215
15216 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
15217 {
15218         struct set_ch_parm *set_ch_parm;
15219         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
15220         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
15221
15222         if(!pbuf)
15223                 return H2C_PARAMETERS_ERROR;
15224
15225         set_ch_parm = (struct set_ch_parm *)pbuf;
15226
15227         DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
15228                 FUNC_NDEV_ARG(padapter->pnetdev),
15229                 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
15230
15231         pmlmeext->cur_channel = set_ch_parm->ch;
15232         pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
15233         pmlmeext->cur_bwmode = set_ch_parm->bw;
15234
15235         set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
15236
15237         return  H2C_SUCCESS;
15238 }
15239
15240 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
15241 {
15242         struct SetChannelPlan_param *setChannelPlan_param;
15243         struct mlme_priv *mlme = &padapter->mlmepriv;
15244         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15245
15246         if(!pbuf)
15247                 return H2C_PARAMETERS_ERROR;
15248
15249         setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
15250
15251         if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) {
15252                 return H2C_PARAMETERS_ERROR;
15253         }
15254
15255         mlme->country_ent = setChannelPlan_param->country_ent;
15256         mlme->ChannelPlan = setChannelPlan_param->channel_plan;
15257
15258         pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
15259         init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);   
15260
15261         rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE);
15262         
15263 #ifdef CONFIG_IOCTL_CFG80211
15264         rtw_reg_notify_by_driver(padapter);
15265 #endif //CONFIG_IOCTL_CFG80211
15266
15267         return  H2C_SUCCESS;
15268 }
15269
15270 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
15271 {
15272         struct LedBlink_param *ledBlink_param;
15273
15274         if(!pbuf)
15275                 return H2C_PARAMETERS_ERROR;
15276
15277         ledBlink_param = (struct LedBlink_param *)pbuf;
15278
15279         #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
15280         BlinkHandler((PLED_DATA)ledBlink_param->pLed);
15281         #endif
15282
15283         return  H2C_SUCCESS;
15284 }
15285
15286 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
15287 {
15288 #ifdef CONFIG_DFS
15289         struct SetChannelSwitch_param *setChannelSwitch_param;
15290         u8 new_ch_no;
15291         u8 gval8 = 0x00, sval8 = 0xff;
15292
15293         if(!pbuf)
15294                 return H2C_PARAMETERS_ERROR;
15295
15296         setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
15297         new_ch_no = setChannelSwitch_param->new_ch_no;
15298
15299         rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15300
15301         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
15302
15303         DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
15304         SelectChannel(padapter, new_ch_no);
15305
15306         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15307
15308         rtw_disassoc_cmd(padapter, 0, _FALSE);
15309         rtw_indicate_disconnect(padapter);
15310         rtw_free_assoc_resources(padapter, 1);
15311         rtw_free_network_queue(padapter, _TRUE);
15312
15313         if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
15314                 DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
15315         }
15316
15317         return  H2C_SUCCESS;
15318 #else
15319         return  H2C_REJECTED;
15320 #endif //CONFIG_DFS
15321
15322 }
15323
15324 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
15325 {
15326 #ifdef CONFIG_TDLS
15327         _irqL irqL;
15328         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
15329         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
15330 #ifdef CONFIG_TDLS_CH_SW        
15331         struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
15332 #endif
15333         struct TDLSoption_param *TDLSoption;
15334         struct sta_info *ptdls_sta = NULL;
15335         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15336         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
15337         u8 survey_channel, i, min, option;
15338         struct tdls_txmgmt txmgmt;
15339         u32 setchtime, resp_sleep = 0, wait_time;
15340         u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15341         u8 ret;
15342         u8 doiqk;
15343
15344         if (!pbuf)
15345                 return H2C_PARAMETERS_ERROR;
15346
15347         TDLSoption = (struct TDLSoption_param *)pbuf;
15348         option = TDLSoption->option;
15349
15350         if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
15351                 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
15352                 if (ptdls_sta == NULL) {
15353                         return H2C_REJECTED;
15354                 }
15355         } else {
15356                 if (!(option == TDLS_RS_RCR))
15357                         return H2C_REJECTED;
15358         }
15359
15360         //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15361         //DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
15362                 
15363         switch (option) {
15364         case TDLS_ESTABLISHED:
15365         {
15366                 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
15367                 /* So we can receive all kinds of data frames. */
15368                 u8 sta_band = 0;
15369
15370                 //leave ALL PS when TDLS is established
15371                         rtw_pwr_wakeup(padapter);
15372
15373                 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
15374                 DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
15375
15376                 /* Set TDLS sta rate. */
15377                 /* Update station supportRate */
15378                 rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
15379                 if (pmlmeext->cur_channel > 14) {
15380                         if (ptdls_sta->ra_mask & 0xffff000)
15381                                 sta_band |= WIRELESS_11_5N ;
15382
15383                         if (ptdls_sta->ra_mask & 0xff0)
15384                                 sta_band |= WIRELESS_11A;
15385
15386                         /* 5G band */
15387                         #ifdef CONFIG_80211AC_VHT
15388                         if (ptdls_sta->vhtpriv.vht_option)
15389                                 sta_band = WIRELESS_11_5AC;
15390                         #endif
15391                         
15392                 } else {
15393                         if (ptdls_sta->ra_mask & 0xffff000)
15394                                 sta_band |= WIRELESS_11_24N;
15395
15396                         if (ptdls_sta->ra_mask & 0xff0)
15397                                 sta_band |= WIRELESS_11G;
15398
15399                         if (ptdls_sta->ra_mask & 0x0f)
15400                                 sta_band |= WIRELESS_11B;
15401                 }
15402                 ptdls_sta->wireless_mode = sta_band;
15403                 ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta);
15404                 set_sta_rate(padapter, ptdls_sta);
15405                 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
15406                 /* Sta mode */
15407                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE);
15408                 break;
15409         }
15410         case TDLS_ISSUE_PTI:
15411                 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
15412                 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
15413                 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
15414                 break;
15415 #ifdef CONFIG_TDLS_CH_SW                
15416         case TDLS_CH_SW_RESP:
15417                 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15418                 txmgmt.status_code = 0;
15419                 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15420
15421                 issue_nulldata(padapter, NULL, 1, 3, 3);
15422
15423                 DBG_871X("[TDLS ] issue tdls channel switch response\n");
15424                 ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
15425
15426                 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
15427                 /* then we just SelectChannel to AP's channel*/
15428                 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
15429                         rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
15430                         break;
15431                 }
15432
15433                 if (ret == _SUCCESS)
15434                         rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_OFF_CHNL);
15435                 else
15436                         DBG_871X("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
15437                 
15438                 break;
15439         case TDLS_CH_SW_PREPARE:
15440                 pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
15441
15442                 /* to collect IQK info of off-chnl */
15443                 doiqk = _TRUE;
15444                 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15445                 set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
15446                 doiqk = _FALSE;
15447                 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15448
15449                 /* switch back to base-chnl */
15450                 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
15451
15452                 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
15453
15454                 pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
15455                 
15456                 break;
15457         case TDLS_CH_SW_START:
15458                 rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
15459                 break;
15460         case TDLS_CH_SW_TO_OFF_CHNL:
15461                 issue_nulldata(padapter, NULL, 1, 3, 3);
15462
15463                 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15464                         _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) /1000);
15465
15466                 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num, 
15467                         pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
15468                                 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15469                                 if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
15470                                         if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 1, 3) == _FAIL)
15471                                                 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15472                                 }
15473                 }
15474                 else {
15475                         u8 bcancelled;
15476                                         
15477                         if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15478                                 _cancel_timer(&ptdls_sta->ch_sw_timer,&bcancelled);
15479                 }
15480                         
15481                 
15482                 break;
15483         case TDLS_CH_SW_END:    
15484         case TDLS_CH_SW_END_TO_BASE_CHNL:
15485                 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15486                 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
15487                 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
15488                 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
15489 #if 0
15490                 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
15491                 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
15492 #endif
15493
15494                 if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
15495                         rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15496
15497                 break;
15498         case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
15499         case TDLS_CH_SW_TO_BASE_CHNL:   
15500                 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
15501
15502                 if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
15503                         if (ptdls_sta != NULL) {
15504                                 /* Send unsolicited channel switch rsp. to peer */ 
15505                                 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15506                                 txmgmt.status_code = 0;
15507                                 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15508                                 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
15509                         }
15510                 }
15511
15512                 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel, 
15513                         pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
15514                         issue_nulldata(padapter, NULL, 0, 3, 3);
15515                         /* set ch sw monitor timer for responder */
15516                         if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15517                                 _set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
15518                 }
15519
15520                 break;
15521 #endif          
15522         case TDLS_RS_RCR:
15523                 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
15524                 DBG_871X("[TDLS] wirte REG_RCR, set bit6 on\n");
15525                 break;
15526         case TDLS_TEAR_STA:
15527 #ifdef CONFIG_TDLS_CH_SW        
15528                 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
15529                         pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
15530                                                                                 TDLS_CH_SWITCH_ON_STATE |
15531                                                                                 TDLS_PEER_AT_OFF_STATE);
15532                         rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15533                         _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
15534                 }
15535 #endif          
15536                 rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
15537                 free_tdls_sta(padapter, ptdls_sta);
15538                 break;                  
15539         }
15540
15541         //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15542
15543         return H2C_SUCCESS;
15544 #else
15545         return H2C_REJECTED;
15546 #endif /* CONFIG_TDLS */
15547
15548 }
15549
15550 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
15551 {
15552         struct RunInThread_param *p;
15553
15554
15555         if (NULL == pbuf)
15556                 return H2C_PARAMETERS_ERROR;
15557         p = (struct RunInThread_param*)pbuf;
15558
15559         if (p->func)
15560                 p->func(p->context);
15561
15562         return H2C_SUCCESS;
15563 }
15564
15565 u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf)
15566 {
15567
15568         struct readMAC_parm *preadmacparm = NULL;
15569         u8 sz = 0;
15570         u32     addr = 0;
15571         u32     value = 0;
15572
15573         if (!pbuf)
15574                 return H2C_PARAMETERS_ERROR;
15575
15576         preadmacparm = (struct readMAC_parm *) pbuf;
15577         sz = preadmacparm->len;
15578         addr = preadmacparm->addr;
15579         value = 0;
15580
15581         switch (sz) {
15582         case 1:
15583                 value = rtw_read8(padapter, addr);
15584                 break;
15585         case 2:
15586                 value = rtw_read16(padapter, addr);
15587                 break;
15588         case 4:
15589                 value = rtw_read32(padapter, addr);
15590                 break;
15591         default:
15592                 DBG_871X("%s: Unknown size\n", __func__);
15593                 break;
15594         }
15595         DBG_871X("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value);
15596
15597         return H2C_SUCCESS;
15598 }
15599