net: wireless: rockchip_wlan: add rtl8723bs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bs / 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         int i;
896
897         if (!rtw_is_channel_plan_valid(ChannelPlan)) {
898                 DBG_871X_LEVEL(_drv_err_, "ChannelPlan ID 0x%02X error !!!!!\n", ChannelPlan);
899                 return chanset_size;
900         }
901
902         _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
903
904         if (IsSupported24G(padapter->registrypriv.wireless_mode))
905                 b2_4GBand = _TRUE;
906
907         if (IsSupported5G(padapter->registrypriv.wireless_mode))
908                 b5GBand = _TRUE;
909
910         if (b2_4GBand) {
911                 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
912                         Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
913                 else
914                         Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
915
916                 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
917                         channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
918
919                         if (RTW_CHPLAN_GLOBAL_DOAMIN == ChannelPlan
920                                 || RTW_CHPLAN_GLOBAL_NULL == ChannelPlan
921                         ) {
922                                 /* Channel 1~11 is active, and 12~14 is passive */
923                                 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
924                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
925                                 else if((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
926                                         channel_set[chanset_size].ScanType  = SCAN_PASSIVE;                     
927                         } else if (RTW_CHPLAN_WORLD_WIDE_13 == ChannelPlan
928                                 || RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan
929                                 || RTW_RD_2G_WORLD == Index2G
930                         ) {
931                                 /* channel 12~13, passive scan */
932                                 if(channel_set[chanset_size].ChannelNum <= 11)
933                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
934                                 else
935                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
936                         } else {
937                                 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
938                         }
939
940                         chanset_size++;
941                 }
942         }
943
944         if (b5GBand) {
945                 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
946                         Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
947                 else
948                         Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
949
950                 for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) {
951 #ifdef CONFIG_DFS
952                         channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
953                         if ( channel_set[chanset_size].ChannelNum <= 48 
954                                 || channel_set[chanset_size].ChannelNum >= 149 )
955                         {
956                                 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
957                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
958                                 else
959                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
960                         }
961                         else
962                         {
963                                 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
964                         }
965                         chanset_size++;
966 #else /* CONFIG_DFS */
967                         if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
968                                 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149
969                         ) {
970                                 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
971                                 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
972                                         channel_set[chanset_size].ScanType = SCAN_PASSIVE;
973                                 else
974                                         channel_set[chanset_size].ScanType = SCAN_ACTIVE;
975                                 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
976                                 chanset_size++;
977                         }
978 #endif /* CONFIG_DFS */
979                 }
980         }
981
982         if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) {
983                 hal_data->Regulation2_4G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
984                 hal_data->Regulation5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
985         } else {
986                 hal_data->Regulation2_4G = RTW_ChannelPlanMap[ChannelPlan].regd;
987                 hal_data->Regulation5G = RTW_ChannelPlanMap[ChannelPlan].regd;
988         }
989
990 #ifdef CONFIG_DFS_MASTER
991         for (i = 0; i < chanset_size; i++)
992                 channel_set[i].non_ocp_end_time = rtw_get_current_time();
993 #endif
994
995         DBG_871X(FUNC_ADPT_FMT" ChannelPlan ID:0x%02x, ch num:%d\n"
996                 , FUNC_ADPT_ARG(padapter), ChannelPlan, chanset_size);
997
998         return chanset_size;
999 }
1000
1001 int     init_mlme_ext_priv(_adapter* padapter)
1002 {
1003         int     res = _SUCCESS;
1004         struct registry_priv* pregistrypriv = &padapter->registrypriv;
1005         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1006         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1007         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1008
1009         // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
1010         //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
1011
1012         pmlmeext->padapter = padapter;
1013
1014         //fill_fwpriv(padapter, &(pmlmeext->fwpriv));
1015
1016         init_mlme_ext_priv_value(padapter);
1017         pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1018         
1019         init_mlme_ext_timer(padapter);
1020
1021 #ifdef CONFIG_AP_MODE
1022         init_mlme_ap_info(padapter);    
1023 #endif
1024
1025         pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
1026         init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
1027         pmlmeext->last_scan_time = 0;
1028         pmlmeext->mlmeext_init = _TRUE;
1029
1030
1031 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK   
1032         pmlmeext->active_keep_alive_check = _TRUE;
1033 #else
1034         pmlmeext->active_keep_alive_check = _FALSE;
1035 #endif
1036
1037 #ifdef DBG_FIXED_CHAN           
1038         pmlmeext->fixed_chan = 0xFF;    
1039 #endif
1040
1041         return res;
1042
1043 }
1044
1045 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
1046 {
1047         _adapter *padapter = pmlmeext->padapter;
1048
1049         if (!padapter)
1050                 return;
1051
1052         if (rtw_is_drv_stopped(padapter)) {
1053                 _cancel_timer_ex(&pmlmeext->survey_timer);
1054                 _cancel_timer_ex(&pmlmeext->link_timer);
1055                 //_cancel_timer_ex(&pmlmeext->ADDBA_timer);
1056         }
1057 }
1058
1059 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
1060 {       // if the channel is same, return 0. else return channel differential   
1061         uint len;
1062         u8 channel;     
1063         u8 *p;          
1064         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);       
1065         if (p)  
1066         {       
1067                 channel = *(p + 2);             
1068                 if(padapter->mlmeextpriv.cur_channel >= channel)                
1069                 {                       
1070                         return (padapter->mlmeextpriv.cur_channel - channel);           
1071                 }               
1072                 else            
1073                 {                       
1074                         return (channel-padapter->mlmeextpriv.cur_channel);             
1075                 }       
1076         }       
1077         else
1078         {               
1079                 return 0;       
1080         }
1081 }
1082
1083 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1084 {
1085         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1086         u8 *pframe = precv_frame->u.hdr.rx_data; 
1087
1088           if(ptable->func)
1089         {
1090          //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1091                 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1092                         !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) 
1093                 {
1094                         return;
1095                 }
1096                 
1097                 ptable->func(padapter, precv_frame);
1098         }
1099         
1100 }
1101
1102 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1103 {
1104         int index;
1105         struct mlme_handler *ptable;
1106 #ifdef CONFIG_AP_MODE
1107         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1108 #endif //CONFIG_AP_MODE
1109         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1110         u8 *pframe = precv_frame->u.hdr.rx_data;
1111         struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
1112         struct dvobj_priv *psdpriv = padapter->dvobj;
1113         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1114
1115         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1116                  ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
1117                   GetFrameType(pframe), GetFrameSubType(pframe)));
1118
1119 #if 0
1120         {
1121                 u8 *pbuf;
1122                 pbuf = GetAddr1Ptr(pframe);
1123                 DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1124                 pbuf = GetAddr2Ptr(pframe);
1125                 DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1126                 pbuf = GetAddr3Ptr(pframe);
1127                 DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1128         }
1129 #endif
1130
1131         if (GetFrameType(pframe) != WIFI_MGT_TYPE)
1132         {
1133                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
1134                 return;
1135         }
1136
1137         //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1138         if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1139                 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1140         {
1141                 return;
1142         }
1143
1144         ptable = mlme_sta_tbl;
1145
1146         index = GetFrameSubType(pframe) >> 4;
1147
1148 #ifdef CONFIG_TDLS
1149         if((index << 4)==WIFI_ACTION){
1150                 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1151                 if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) {
1152                         DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe)));
1153                         On_TDLS_Dis_Rsp(padapter, precv_frame);
1154                 }
1155         }
1156 #endif //CONFIG_TDLS
1157
1158         if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler)))
1159         {
1160                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
1161                 return;
1162         }
1163         ptable += index;
1164
1165 #if 1
1166         if (psta != NULL)
1167         {
1168                 if (GetRetry(pframe))
1169                 {
1170                         if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
1171                         {
1172                                 /* drop the duplicate management frame */
1173                                 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
1174                                 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1175                                 return;
1176                         }
1177                 }
1178                 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1179         }
1180 #else
1181
1182         if(GetRetry(pframe))
1183         {
1184                 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
1185                 //return;
1186         }
1187 #endif
1188
1189 #ifdef CONFIG_AP_MODE
1190         switch (GetFrameSubType(pframe)) 
1191         {
1192                 case WIFI_AUTH:
1193                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1194                                 ptable->func = &OnAuth;
1195                         else
1196                                 ptable->func = &OnAuthClient;
1197                         //pass through
1198                 case WIFI_ASSOCREQ:
1199                 case WIFI_REASSOCREQ:
1200                         _mgt_dispatcher(padapter, ptable, precv_frame); 
1201 #ifdef CONFIG_HOSTAPD_MLME                              
1202                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1203                                 rtw_hostapd_mlme_rx(padapter, precv_frame);
1204 #endif                  
1205                         break;
1206                 case WIFI_PROBEREQ:
1207                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1208                         {
1209 #ifdef CONFIG_HOSTAPD_MLME              
1210                                 rtw_hostapd_mlme_rx(padapter, precv_frame);             
1211 #else
1212                                 _mgt_dispatcher(padapter, ptable, precv_frame);
1213 #endif
1214                         }
1215                         else
1216                                 _mgt_dispatcher(padapter, ptable, precv_frame);
1217                         break;
1218                 case WIFI_BEACON:                       
1219                         _mgt_dispatcher(padapter, ptable, precv_frame);
1220                         break;
1221                 case WIFI_ACTION:
1222                         //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1223                         _mgt_dispatcher(padapter, ptable, precv_frame);         
1224                         break;
1225                 default:
1226                         _mgt_dispatcher(padapter, ptable, precv_frame); 
1227                         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1228                                 rtw_hostapd_mlme_rx(padapter, precv_frame);                     
1229                         break;
1230         }
1231 #else
1232
1233         _mgt_dispatcher(padapter, ptable, precv_frame); 
1234         
1235 #endif
1236
1237 }
1238
1239 #ifdef CONFIG_P2P
1240 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1241 {
1242         bool response = _TRUE;
1243
1244 #ifdef CONFIG_IOCTL_CFG80211
1245         if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
1246         {
1247                 if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE
1248                         || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1249                         || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1250                         || padapter->mlmepriv.wps_probe_resp_ie == NULL
1251                         || padapter->mlmepriv.p2p_probe_resp_ie == NULL
1252                 )
1253                 {
1254 #ifdef CONFIG_DEBUG_CFG80211
1255                         DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ",
1256                                 adapter_wdev_data(padapter)->p2p_enabled,
1257                                 padapter->mlmepriv.wps_probe_resp_ie,
1258                                 padapter->mlmepriv.p2p_probe_resp_ie);
1259                         DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n", 
1260                                 padapter->cfg80211_wdinfo.is_ro_ch,
1261                                 rtw_get_oper_ch(padapter),
1262                                 padapter->wdinfo.listen_channel);
1263 #endif
1264                         response = _FALSE;
1265                 }
1266         }
1267         else
1268 #endif //CONFIG_IOCTL_CFG80211
1269         if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1270         {
1271                 //      do nothing if the device name is empty
1272                 if ( !padapter->wdinfo.device_name_len )
1273                 {
1274                         response        = _FALSE;
1275                 }
1276         }
1277
1278         if (response == _TRUE)
1279                 issue_probersp_p2p( padapter, da);
1280         
1281         return _SUCCESS;
1282 }
1283 #endif //CONFIG_P2P
1284
1285
1286 /****************************************************************************
1287
1288 Following are the callback functions for each subtype of the management frames
1289
1290 *****************************************************************************/
1291
1292 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1293 {
1294         unsigned int    ielen;
1295         unsigned char   *p;
1296         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1297         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1298         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1299         WLAN_BSSID_EX   *cur = &(pmlmeinfo->network);
1300         u8 *pframe = precv_frame->u.hdr.rx_data;
1301         uint len = precv_frame->u.hdr.len;
1302         u8 is_valid_p2p_probereq = _FALSE;
1303
1304 #ifdef CONFIG_ATMEL_RC_PATCH
1305         u8 *target_ie=NULL, *wps_ie=NULL;
1306         u8 *start;
1307         uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1308         struct sta_info *psta;
1309         struct sta_priv *pstapriv = &padapter->stapriv;
1310 #endif
1311
1312
1313 #ifdef CONFIG_P2P
1314         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
1315         struct rx_pkt_attrib    *pattrib = &precv_frame->u.hdr.attrib;
1316         u8 wifi_test_chk_rate = 1;
1317
1318 #ifdef CONFIG_IOCTL_CFG80211
1319         if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1320                 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1321                 && (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1322                  ) {
1323                 rtw_cfg80211_rx_probe_request(padapter, pframe, len);
1324                 return _SUCCESS;
1325         }
1326 #endif /* CONFIG_IOCTL_CFG80211 */
1327
1328         if (    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && 
1329                 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) && 
1330                 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1331                 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1332                 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1333            )
1334         {
1335                 //      Commented by Albert 2011/03/17
1336                 //      mcs_rate = 0 -> CCK 1M rate
1337                 //      mcs_rate = 1 -> CCK 2M rate
1338                 //      mcs_rate = 2 -> CCK 5.5M rate
1339                 //      mcs_rate = 3 -> CCK 11M rate
1340                 //      In the P2P mode, the driver should not support the CCK rate
1341
1342                 //      Commented by Kurt 2012/10/16
1343                 //      IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
1344         if (padapter->registrypriv.wifi_spec == 1)
1345         {
1346             if ( pattrib->data_rate <= 3 )
1347             {
1348                 wifi_test_chk_rate = 0;
1349             }
1350         }
1351
1352                 if( wifi_test_chk_rate == 1 )
1353                 {
1354                         if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
1355                         {
1356                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
1357                                 {
1358                                         // FIXME
1359                                         if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1360                                                 report_survey_event(padapter, precv_frame);
1361
1362                                         p2p_listen_state_process( padapter,  get_sa(pframe));
1363
1364                                         return _SUCCESS;        
1365                                 }
1366
1367                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1368                                 {
1369                                         goto _continue;
1370                                 }
1371                         }
1372                 }
1373         }
1374
1375 _continue:
1376 #endif //CONFIG_P2P
1377
1378         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1379         {
1380                 return _SUCCESS;
1381         }
1382
1383         if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE && 
1384                 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
1385         {
1386                 return _SUCCESS;
1387         }
1388
1389
1390         //DBG_871X("+OnProbeReq\n");
1391
1392
1393 #ifdef CONFIG_ATMEL_RC_PATCH
1394                 if ((wps_ie = rtw_get_wps_ie(
1395                         pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1396                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1397                          NULL, &wps_ielen))) {
1398                 
1399                         target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1400                 }
1401                 if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) {
1402                         //psta->flag_atmel_rc = 1;
1403                         unsigned char *sa_addr = get_sa(pframe);
1404                         printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x  \n\n",
1405                                 __func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5));
1406                         _rtw_memcpy(  pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1407                 }
1408 #endif
1409
1410
1411 #ifdef CONFIG_AUTO_AP_MODE
1412         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1413                         pmlmepriv->cur_network.join_res == _TRUE)
1414         {
1415                 _irqL   irqL;
1416                 struct sta_info *psta;
1417                 u8 *mac_addr, *peer_addr;
1418                 struct sta_priv *pstapriv = &padapter->stapriv;
1419                 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
1420                 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
1421
1422                 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1423                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1424
1425                 if(!p || ielen !=14)
1426                         goto _non_rc_device;
1427
1428                 if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
1429                         goto _non_rc_device;
1430
1431                 if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
1432                 {
1433                         DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1434                                 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
1435
1436                         goto _non_rc_device;
1437                 }
1438
1439                 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__,  MAC_ARG(get_sa(pframe)));
1440
1441                 //new a station
1442                 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1443                 if (psta == NULL)
1444                 {
1445                         // allocate a new one
1446                         DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n",  MAC_ARG(get_sa(pframe)));
1447                         psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1448                         if (psta == NULL)
1449                         {
1450                                 //TODO:
1451                                 DBG_871X(" Exceed the upper limit of supported clients...\n");
1452                                 return _SUCCESS;
1453                         }
1454
1455                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1456                         if (rtw_is_list_empty(&psta->asoc_list))
1457                         {
1458                                 psta->expire_to = pstapriv->expire_to;
1459                                 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1460                                 pstapriv->asoc_list_cnt++;
1461                         }
1462                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1463
1464                         //generate pairing ID
1465                         mac_addr = adapter_mac_addr(padapter);
1466                         peer_addr = psta->hwaddr;
1467                         psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
1468
1469                         //update peer stainfo
1470                         psta->isrc = _TRUE;
1471                         //psta->aid = 0;
1472                         //psta->mac_id = 2;
1473
1474                         /* get a unique AID */
1475                         if (psta->aid > 0) {
1476                                 DBG_871X("old AID %d\n", psta->aid);
1477                         } else {
1478                                 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1479                                         if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1480                                                 break;
1481
1482                                 if (psta->aid > pstapriv->max_num_sta) {
1483                                         psta->aid = 0;
1484                                         DBG_871X("no room for more AIDs\n");
1485                                         return _SUCCESS;
1486                                 } else {
1487                                         pstapriv->sta_aid[psta->aid - 1] = psta;
1488                                         DBG_871X("allocate new AID = (%d)\n", psta->aid);
1489                                 }
1490                         }
1491                         
1492                         psta->qos_option = 1;
1493                         psta->bw_mode = CHANNEL_WIDTH_20;
1494                         psta->ieee8021x_blocked = _FALSE;
1495 #ifdef CONFIG_80211N_HT
1496                         psta->htpriv.ht_option = _TRUE;
1497                         psta->htpriv.ampdu_enable = _FALSE;
1498                         psta->htpriv.sgi_20m = _FALSE;
1499                         psta->htpriv.sgi_40m = _FALSE;
1500                         psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1501                         psta->htpriv.agg_enable_bitmap = 0x0;//reset
1502                         psta->htpriv.candidate_tid_bitmap = 0x0;//reset
1503 #endif
1504
1505                         rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1506
1507                         _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1508
1509                         _enter_critical_bh(&psta->lock, &irqL);
1510                         psta->state |= _FW_LINKED;
1511                         _exit_critical_bh(&psta->lock, &irqL);
1512
1513                         report_add_sta_event(padapter, psta->hwaddr);
1514
1515                 }
1516
1517                 issue_probersp(padapter, get_sa(pframe), _FALSE);
1518
1519                 return _SUCCESS;
1520
1521         }
1522
1523 _non_rc_device:
1524
1525         return _SUCCESS;
1526
1527 #endif //CONFIG_AUTO_AP_MODE
1528         
1529
1530 #ifdef CONFIG_CONCURRENT_MODE
1531         if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1532                 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1533         {
1534                 //don't process probe req
1535                 return _SUCCESS;
1536         }
1537 #endif  
1538
1539         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1540                         len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1541
1542
1543         //check (wildcard) SSID 
1544         if (p != NULL)
1545         {
1546                 if(is_valid_p2p_probereq == _TRUE)
1547                 {
1548                         goto _issue_probersp;
1549                 }
1550
1551                 if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1552                         || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1553                 )
1554                 {
1555                         return _SUCCESS;
1556                 }
1557
1558 _issue_probersp:
1559                 if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && 
1560                         pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1561                 {
1562                         //DBG_871X("+issue_probersp during ap mode\n");
1563                         issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);                
1564                 }
1565
1566         }
1567
1568         return _SUCCESS;
1569
1570 }
1571
1572 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1573 {
1574         struct sta_info         *psta;
1575         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1576         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1577         struct sta_priv         *pstapriv = &padapter->stapriv;
1578         u8      *pframe = precv_frame->u.hdr.rx_data;
1579 #ifdef CONFIG_P2P
1580         struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
1581 #endif
1582
1583
1584 #ifdef CONFIG_P2P
1585         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
1586         {
1587                 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
1588                 {
1589                         if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1590                         {
1591                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
1592                                 {
1593                                         pwdinfo->tx_prov_disc_info.benable = _FALSE;
1594                                         issue_p2p_provision_request( padapter,
1595                                                                                                 pwdinfo->tx_prov_disc_info.ssid.Ssid, 
1596                                                                                                 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1597                                                                                                 pwdinfo->tx_prov_disc_info.peerDevAddr );
1598                                 }
1599                                 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
1600                                 {
1601                                         pwdinfo->tx_prov_disc_info.benable = _FALSE;
1602                                         issue_p2p_provision_request( padapter,
1603                                                                                                 NULL, 
1604                                                                                                 0,
1605                                                                                                 pwdinfo->tx_prov_disc_info.peerDevAddr );
1606                                 }
1607                         }               
1608                 }
1609                 return _SUCCESS;
1610         }
1611         else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
1612         {
1613                 if ( _TRUE == pwdinfo->nego_req_info.benable )
1614                 {
1615                         DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
1616                         if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1617                         {
1618                                 pwdinfo->nego_req_info.benable = _FALSE;
1619                                 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
1620                         }
1621                 }
1622         }
1623         else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
1624         {
1625                 if ( _TRUE == pwdinfo->invitereq_info.benable )
1626                 {
1627                         DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
1628                         if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1629                         {
1630                                 pwdinfo->invitereq_info.benable = _FALSE;
1631                                 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
1632                         }
1633                 }
1634         }
1635 #endif
1636
1637
1638         if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1639                 report_survey_event(padapter, precv_frame);     
1640 #ifdef CONFIG_CONCURRENT_MODE
1641                 report_survey_event(padapter->pbuddy_adapter, precv_frame);     
1642 #endif
1643                 return _SUCCESS;
1644         }
1645
1646         #if 0 //move to validate_recv_mgnt_frame
1647         if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1648         {
1649                 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1650                 {
1651                         if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1652                         {
1653                                 psta->sta_stats.rx_mgnt_pkts++;
1654                         }
1655                 }
1656         }
1657         #endif
1658         
1659         return _SUCCESS;
1660         
1661 }
1662
1663 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1664 {
1665         struct sta_info *psta;
1666         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1667         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1668         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1669         struct sta_priv *pstapriv = &padapter->stapriv;
1670         u8 *pframe = precv_frame->u.hdr.rx_data;
1671         uint len = precv_frame->u.hdr.len;
1672         WLAN_BSSID_EX *pbss;
1673         int ret = _SUCCESS;
1674         u8 *p = NULL;
1675         u32 ielen = 0;
1676 #ifdef CONFIG_TDLS
1677         struct sta_info *ptdls_sta;
1678         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1679 #ifdef CONFIG_TDLS_CH_SW
1680         struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
1681 #endif
1682 #endif /* CONFIG_TDLS */
1683
1684 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1685         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_);
1686         if ((p != NULL) && (ielen > 0))
1687         {
1688                 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
1689                 {
1690                         /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */     
1691                         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)));
1692                         *(p + 1) = ielen - 1;
1693                 }
1694         }
1695 #endif
1696
1697         if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1698                 report_survey_event(padapter, precv_frame);
1699 #ifdef CONFIG_CONCURRENT_MODE
1700                 report_survey_event(padapter->pbuddy_adapter, precv_frame);     
1701 #endif
1702                 return _SUCCESS;
1703         }
1704
1705         if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1706         {
1707                 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1708                 {
1709                         //we should update current network before auth, or some IE is wrong
1710                         pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1711                         if (pbss) {
1712                                 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1713                                         struct beacon_keys recv_beacon;
1714
1715                                         update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1716                                         rtw_get_bcn_info(&(pmlmepriv->cur_network));
1717
1718                                         // update bcn keys
1719                                         if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1720                                                 DBG_871X("%s: beacon keys ready\n", __func__);
1721                                                 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1722                                                         &recv_beacon, sizeof(recv_beacon));
1723                                                 pmlmepriv->new_beacon_cnts = 0;
1724                                         }
1725                                         else {
1726                                                 DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__);
1727                                                 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1728                                                 pmlmepriv->new_beacon_cnts = 0;
1729                                         }
1730                                 }
1731                                 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1732                         }
1733
1734                         //check the vendor of the assoc AP
1735                         pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));                         
1736
1737                         //update TSF Value
1738                         update_TSF(pmlmeext, pframe, len);
1739
1740                         //reset for adaptive_early_32k
1741                         pmlmeext->adaptive_tsf_done = _FALSE;
1742                         pmlmeext->DrvBcnEarly = 0xff;
1743                         pmlmeext->DrvBcnTimeOut = 0xff;
1744                         pmlmeext->bcn_cnt = 0;
1745                         _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1746                         _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1747
1748 #ifdef CONFIG_P2P_PS
1749                         process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1750 #endif //CONFIG_P2P_PS
1751
1752 #if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE)
1753                         if (padapter->registrypriv.wifi_spec) {
1754                                 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1755                                         if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
1756                                                 DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n ");
1757                                                 return _SUCCESS;
1758                                         }
1759                                 }
1760                         }
1761 #endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE
1762
1763                         //start auth
1764                         start_clnt_auth(padapter);
1765
1766                         return _SUCCESS;
1767                 }
1768
1769                 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1770                 {
1771                         if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1772                         {
1773                                 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL        
1774                                 //Merge from 8712 FW code
1775                                 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)        
1776                                 {            // join wrong channel, deauth and reconnect           
1777                                         issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1778
1779                                         report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE, _FALSE);
1780                                         pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);                   
1781                                         return _SUCCESS;
1782                                 }        
1783                                 #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
1784
1785                                 ret = rtw_check_bcn_info(padapter, pframe, len);
1786                                 if (!ret) {
1787                                                 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1788                                                 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
1789                                                 return _SUCCESS;
1790                                 }
1791                                 //update WMM, ERP in the beacon
1792                                 //todo: the timer is used instead of the number of the beacon received
1793                                 if ((sta_rx_pkts(psta) & 0xf) == 0)
1794                                 {
1795                                         //DBG_871X("update_bcn_info\n");
1796                                         update_beacon_info(padapter, pframe, len, psta);
1797                                 }
1798
1799                                 adaptive_early_32k(pmlmeext, pframe, len);                              
1800                                 
1801 #ifdef CONFIG_TDLS
1802 #ifdef CONFIG_TDLS_CH_SW
1803                                 if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE)
1804                                 {
1805                                         /* Send TDLS Channel Switch Request when receiving Beacon */
1806                                         if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
1807                                                 && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1808                                                 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1809                                                 if (ptdls_sta != NULL) {
1810                                                         if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
1811                                                                 _set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
1812                                                 }
1813                                         }
1814                                 }
1815 #endif                          
1816 #endif /* CONFIG_TDLS */
1817
1818 #ifdef CONFIG_DFS
1819                                 process_csa_ie(padapter, pframe, len);  //channel switch announcement
1820 #endif //CONFIG_DFS
1821
1822 #ifdef CONFIG_P2P_PS
1823                                 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1824 #endif //CONFIG_P2P_PS
1825
1826                                 if (pmlmeext->en_hw_update_tsf)
1827                                         rtw_enable_hw_update_tsf_cmd(padapter);
1828
1829                                 #if 0 //move to validate_recv_mgnt_frame
1830                                 psta->sta_stats.rx_mgnt_pkts++;
1831                                 #endif
1832                         }
1833
1834                 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
1835                         _irqL irqL;
1836                         u8 rate_set[16];
1837                         u8 rate_num = 0;
1838
1839                         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1840                         if (psta != NULL) {
1841                                 /*
1842                                 * update WMM, ERP in the beacon
1843                                 * todo: the timer is used instead of the number of the beacon received
1844                                 */
1845                                 if ((sta_rx_pkts(psta) & 0xf) == 0)
1846                                         update_beacon_info(padapter, pframe, len, psta);
1847
1848                                 if (pmlmeext->en_hw_update_tsf)
1849                                         rtw_enable_hw_update_tsf_cmd(padapter);
1850
1851                         } else {
1852                                 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);
1853                                 if (rate_num == 0) {
1854                                         DBG_871X(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
1855                                         goto _END_ONBEACON_;
1856                                 }
1857
1858                                 psta = rtw_alloc_stainfo(pstapriv, GetAddr2Ptr(pframe));
1859                                 if (psta == NULL) {
1860                                         DBG_871X(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
1861                                         goto _END_ONBEACON_;
1862                                 }
1863
1864                                 psta->expire_to = pstapriv->adhoc_expire_to;
1865
1866                                 _rtw_memcpy(psta->bssrateset, rate_set, rate_num);
1867                                 psta->bssratelen = rate_num;
1868
1869                                 //update TSF Value
1870                                 update_TSF(pmlmeext, pframe, len);                      
1871
1872                                 //report sta add event
1873                                 report_add_sta_event(padapter, GetAddr2Ptr(pframe));
1874                         }
1875                 }
1876         }
1877
1878 _END_ONBEACON_:
1879
1880         return _SUCCESS;
1881
1882 }
1883
1884 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1885 {
1886 #ifdef CONFIG_AP_MODE
1887         _irqL irqL;
1888         unsigned int    auth_mode, seq, ie_len;
1889         unsigned char   *sa, *p;        
1890         u16     algorithm;
1891         int     status;
1892         static struct sta_info stat;    
1893         struct  sta_info        *pstat=NULL;    
1894         struct  sta_priv *pstapriv = &padapter->stapriv;
1895         struct security_priv *psecuritypriv = &padapter->securitypriv;
1896         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1897         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1898         u8 *pframe = precv_frame->u.hdr.rx_data; 
1899         uint len = precv_frame->u.hdr.len;
1900         u8      offset = 0;
1901
1902         
1903 #ifdef CONFIG_CONCURRENT_MODE   
1904         if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1905                 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1906         {
1907                 //don't process auth request;
1908                 return _SUCCESS;
1909         }
1910 #endif //CONFIG_CONCURRENT_MODE
1911
1912         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1913                 return _FAIL;
1914
1915         DBG_871X("+OnAuth\n");
1916
1917         sa = GetAddr2Ptr(pframe);
1918
1919         auth_mode = psecuritypriv->dot11AuthAlgrthm;
1920
1921         if (GetPrivacy(pframe))
1922         {
1923                 u8      *iv;
1924                 struct rx_pkt_attrib     *prxattrib = &(precv_frame->u.hdr.attrib);
1925
1926                 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
1927                 prxattrib->encrypt = _WEP40_;
1928
1929                 iv = pframe+prxattrib->hdrlen;
1930                 prxattrib->key_index = ((iv[3]>>6)&0x3);
1931
1932                 prxattrib->iv_len = 4;
1933                 prxattrib->icv_len = 4;
1934
1935                 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
1936
1937                 offset = 4;
1938         }
1939
1940         algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1941         seq     = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1942
1943         DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
1944
1945         if (auth_mode == 2 &&
1946                         psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1947                         psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1948                 auth_mode = 0;
1949
1950         if ((algorithm > 0 && auth_mode == 0) ||        // rx a shared-key auth but shared not enabled
1951                 (algorithm == 0 && auth_mode == 1) )    // rx a open-system auth but shared-key is enabled
1952         {               
1953                 DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1954                         algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1955                 
1956                 status = _STATS_NO_SUPP_ALG_;
1957                 
1958                 goto auth_fail;
1959         }
1960         
1961 #if 0 //ACL control     
1962         phead = &priv->wlan_acl_list;
1963         plist = phead->next;
1964         //check sa
1965         if (acl_mode == 1)              // 1: positive check, only those on acl_list can be connected.
1966                 res = FAIL;
1967         else
1968                 res = SUCCESS;
1969
1970         while(plist != phead)
1971         {
1972                 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
1973                 plist = plist->next;
1974                 if (!memcmp((void *)sa, paclnode->addr, 6)) {
1975                         if (paclnode->mode & 2) { // deny
1976                                 res = FAIL;
1977                                 break;
1978                         }
1979                         else {
1980                                 res = SUCCESS;
1981                                 break;
1982                         }
1983                 }
1984         }
1985
1986         if (res != SUCCESS) {
1987                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
1988                 return FAIL;
1989         }
1990 #else
1991         if(rtw_access_ctrl(padapter, sa) == _FALSE)
1992         {
1993                 status = _STATS_UNABLE_HANDLE_STA_;
1994                 goto auth_fail;
1995         }       
1996 #endif
1997
1998         pstat = rtw_get_stainfo(pstapriv, sa);
1999         if (pstat == NULL)
2000         {
2001
2002                 // allocate a new one
2003                 DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n",  MAC_ARG(sa));
2004                 pstat = rtw_alloc_stainfo(pstapriv, sa);
2005                 if (pstat == NULL)
2006                 {
2007                         DBG_871X(" Exceed the upper limit of supported clients...\n");
2008                         status = _STATS_UNABLE_HANDLE_STA_;
2009                         goto auth_fail;
2010                 }
2011                 
2012                 pstat->state = WIFI_FW_AUTH_NULL;
2013                 pstat->auth_seq = 0;
2014                 
2015                 //pstat->flags = 0;
2016                 //pstat->capability = 0;
2017         } else {
2018 #ifdef CONFIG_IEEE80211W
2019                 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2020 #endif /* CONFIG_IEEE80211W */
2021                 {
2022
2023                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2024                         if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {                   
2025                                 rtw_list_delete(&pstat->asoc_list);
2026                                 pstapriv->asoc_list_cnt--;
2027                                 if (pstat->expire_to > 0)
2028                                         ;/* TODO: STA re_auth within expire_to */
2029                         }
2030                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2031
2032                         if (seq == 1)
2033                                 ; /* TODO: STA re_auth and auth timeout */
2034
2035                 }
2036         }
2037
2038 #ifdef CONFIG_IEEE80211W
2039         if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2040 #endif /* CONFIG_IEEE80211W */
2041         {
2042                 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2043                 if (rtw_is_list_empty(&pstat->auth_list)) {             
2044         
2045                         rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2046                         pstapriv->auth_list_cnt++;
2047                 }       
2048                 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2049         }
2050
2051         if (pstat->auth_seq == 0)
2052                 pstat->expire_to = pstapriv->auth_to;
2053
2054
2055         if ((pstat->auth_seq + 1) != seq)
2056         {
2057                 DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2058                         seq, pstat->auth_seq+1);
2059                 status = _STATS_OUT_OF_AUTH_SEQ_;
2060                 goto auth_fail;
2061         }
2062
2063         if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
2064         {
2065                 if (seq == 1)
2066                 {
2067 #ifdef CONFIG_IEEE80211W
2068                         if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2069 #endif /* CONFIG_IEEE80211W */
2070                         {
2071                                 pstat->state &= ~WIFI_FW_AUTH_NULL;
2072                                 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2073                                 pstat->expire_to = pstapriv->assoc_to;
2074                         }
2075                         pstat->authalg = algorithm;
2076                 }
2077                 else
2078                 {
2079                         DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2080                                 seq, pstat->auth_seq+1);
2081                         status = _STATS_OUT_OF_AUTH_SEQ_;
2082                         goto auth_fail;
2083                 }
2084         }
2085         else // shared system or auto authentication
2086         {
2087                 if (seq == 1)
2088                 {
2089                         //prepare for the challenging txt...
2090
2091                         //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
2092                         _rtw_memset((void *)pstat->chg_txt, 78, 128);
2093 #ifdef CONFIG_IEEE80211W
2094                         if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2095 #endif /* CONFIG_IEEE80211W */
2096                         {
2097                                 pstat->state &= ~WIFI_FW_AUTH_NULL;
2098                                 pstat->state |= WIFI_FW_AUTH_STATE;
2099                         }
2100                         pstat->authalg = algorithm;
2101                         pstat->auth_seq = 2;
2102                 }
2103                 else if (seq == 3)
2104                 {
2105                         //checking for challenging txt...
2106                         DBG_871X("checking for challenging txt...\n");
2107                         
2108                         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2109                                         len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2110
2111                         if((p==NULL) || (ie_len<=0))
2112                         {
2113                                 DBG_871X("auth rejected because challenge failure!(1)\n");
2114                                 status = _STATS_CHALLENGE_FAIL_;
2115                                 goto auth_fail;
2116                         }
2117                         
2118                         if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
2119                         {
2120 #ifdef CONFIG_IEEE80211W
2121                                 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS)) 
2122 #endif /* CONFIG_IEEE80211W */
2123                                 {
2124                                         pstat->state &= (~WIFI_FW_AUTH_STATE);
2125                                         pstat->state |= WIFI_FW_AUTH_SUCCESS;
2126                                         /* challenging txt is correct... */
2127                                         pstat->expire_to =  pstapriv->assoc_to;
2128                                 }
2129                         }
2130                         else
2131                         {
2132                                 DBG_871X("auth rejected because challenge failure!\n");
2133                                 status = _STATS_CHALLENGE_FAIL_;
2134                                 goto auth_fail;
2135                         }
2136                 }
2137                 else
2138                 {
2139                         DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2140                                 seq, pstat->auth_seq+1);
2141                         status = _STATS_OUT_OF_AUTH_SEQ_;
2142                         goto auth_fail;
2143                 }
2144         }
2145
2146
2147         // Now, we are going to issue_auth...
2148         pstat->auth_seq = seq + 1;      
2149         
2150 #ifdef CONFIG_NATIVEAP_MLME
2151         issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2152 #endif
2153
2154         if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2155                 pstat->auth_seq = 0;
2156
2157                 
2158         return _SUCCESS;
2159
2160 auth_fail:
2161
2162         if(pstat)
2163                 rtw_free_stainfo(padapter , pstat);
2164         
2165         pstat = &stat;
2166         _rtw_memset((char *)pstat, '\0', sizeof(stat));
2167         pstat->auth_seq = 2;
2168         _rtw_memcpy(pstat->hwaddr, sa, 6);      
2169         
2170 #ifdef CONFIG_NATIVEAP_MLME
2171         issue_auth(padapter, pstat, (unsigned short)status);    
2172 #endif
2173
2174 #endif
2175         return _FAIL;
2176
2177 }
2178
2179 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2180 {
2181         unsigned int    seq, len, status, algthm, offset;
2182         unsigned char   *p;
2183         unsigned int    go2asoc = 0;
2184         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2185         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2186         u8 *pframe = precv_frame->u.hdr.rx_data;
2187         uint pkt_len = precv_frame->u.hdr.len;
2188
2189         DBG_871X("%s\n", __FUNCTION__);
2190
2191         //check A1 matches or not
2192         if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2193                 return _SUCCESS;
2194
2195         if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2196                 return _SUCCESS;
2197
2198         offset = (GetPrivacy(pframe))? 4: 0;
2199
2200         algthm  = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2201         seq     = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2202         status  = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2203
2204         if (status != 0)
2205         {
2206                 DBG_871X("clnt auth fail, status: %d\n", status);
2207                 if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
2208                 {
2209                         if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2210                                 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2211                         else
2212                                 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2213                         //pmlmeinfo->reauth_count = 0;
2214                 }
2215                 
2216                 set_link_timer(pmlmeext, 1);
2217                 goto authclnt_fail;
2218         }
2219
2220         if (seq == 2)
2221         {
2222                 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2223                 {
2224                          // legendary shared system
2225                         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2226                                 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2227
2228                         if (p == NULL)
2229                         {
2230                                 //DBG_871X("marc: no challenge text?\n");
2231                                 goto authclnt_fail;
2232                         }
2233
2234                         _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2235                         pmlmeinfo->auth_seq = 3;
2236                         issue_auth(padapter, NULL, 0);
2237                         set_link_timer(pmlmeext, REAUTH_TO);
2238
2239                         return _SUCCESS;
2240                 }
2241                 else
2242                 {
2243                         // open system
2244                         go2asoc = 1;
2245                 }
2246         }
2247         else if (seq == 4)
2248         {
2249                 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2250                 {
2251                         go2asoc = 1;
2252                 }
2253                 else
2254                 {
2255                         goto authclnt_fail;
2256                 }
2257         }
2258         else
2259         {
2260                 // this is also illegal
2261                 //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
2262                 goto authclnt_fail;
2263         }
2264
2265         if (go2asoc)
2266         {
2267                 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
2268                 start_clnt_assoc(padapter);
2269                 return _SUCCESS;
2270         }
2271
2272 authclnt_fail:
2273
2274         //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
2275
2276         return _FAIL;
2277
2278 }
2279
2280 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2281 {
2282 #ifdef CONFIG_AP_MODE
2283         _irqL irqL;
2284         u16 capab_info, listen_interval;
2285         struct rtw_ieee802_11_elems elems;      
2286         struct sta_info *pstat;
2287         unsigned char           reassoc, *p, *pos, *wpa_ie;
2288         unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2289         int             i, ie_len, wpa_ie_len, left;
2290         u8 rate_set[16];
2291         u8 rate_num;
2292         unsigned short          status = _STATS_SUCCESSFUL_;
2293         unsigned short          frame_type, ie_offset=0;        
2294         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2295         struct security_priv *psecuritypriv = &padapter->securitypriv;
2296         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2297         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);  
2298         WLAN_BSSID_EX   *cur = &(pmlmeinfo->network);
2299         struct sta_priv *pstapriv = &padapter->stapriv;
2300         u8 *pframe = precv_frame->u.hdr.rx_data;
2301         uint pkt_len = precv_frame->u.hdr.len;
2302 #ifdef CONFIG_P2P
2303         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
2304         u8 p2p_status_code = P2P_STATUS_SUCCESS;
2305         u8 *p2pie;
2306         u32 p2pielen = 0;
2307 #endif //CONFIG_P2P
2308
2309 #ifdef CONFIG_CONCURRENT_MODE
2310         if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
2311                 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
2312         {
2313                 //don't process assoc request;
2314                 return _SUCCESS;
2315         }
2316 #endif //CONFIG_CONCURRENT_MODE
2317
2318         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2319                 return _FAIL;
2320         
2321         frame_type = GetFrameSubType(pframe);
2322         if (frame_type == WIFI_ASSOCREQ)
2323         {
2324                 reassoc = 0;
2325                 ie_offset = _ASOCREQ_IE_OFFSET_;
2326         }       
2327         else // WIFI_REASSOCREQ
2328         {
2329                 reassoc = 1;
2330                 ie_offset = _REASOCREQ_IE_OFFSET_;
2331         }
2332         
2333
2334         if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2335                 DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2336                        "\n", reassoc, (unsigned long)pkt_len);
2337                 return _FAIL;
2338         }
2339         
2340         pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2341         if (pstat == (struct sta_info *)NULL)
2342         {
2343                 status = _RSON_CLS2_;
2344                 goto asoc_class2_error;
2345         }
2346
2347         capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
2348         //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));      
2349         //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
2350         listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
2351
2352         left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2353         pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2354         
2355
2356         DBG_871X("%s\n", __FUNCTION__);
2357
2358         // check if this stat has been successfully authenticated/assocated
2359         if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
2360         {
2361                 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
2362                 {
2363                         status = _RSON_CLS2_;
2364                         goto asoc_class2_error;
2365                 }
2366                 else
2367                 {
2368                         pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2369                         pstat->state |= WIFI_FW_ASSOC_STATE;                            
2370                 }
2371         }
2372         else
2373         {
2374                 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2375                 pstat->state |= WIFI_FW_ASSOC_STATE;
2376         }
2377
2378
2379 #if 0// todo:tkip_countermeasures
2380         if (hapd->tkip_countermeasures) {
2381                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2382                 goto fail;
2383         }
2384 #endif
2385
2386         pstat->capability = capab_info;
2387
2388 #if 0//todo:
2389         //check listen_interval
2390         if (listen_interval > hapd->conf->max_listen_interval) {
2391                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2392                                HOSTAPD_LEVEL_DEBUG,
2393                                "Too large Listen Interval (%d)",
2394                                listen_interval);
2395                 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2396                 goto fail;
2397         }
2398         
2399         pstat->listen_interval = listen_interval;
2400 #endif
2401
2402         //now parse all ieee802_11 ie to point to elems
2403         if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2404             !elems.ssid) {
2405                 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
2406                        MAC_ARG(pstat->hwaddr));
2407                 status = _STATS_FAILURE_;               
2408                 goto OnAssocReqFail;
2409         }
2410
2411
2412         // now we should check all the fields...
2413         // checking SSID
2414         p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2415                 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2416         if (p == NULL)
2417         {
2418                 status = _STATS_FAILURE_;               
2419         }
2420
2421         if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
2422                 status = _STATS_FAILURE_;
2423         else
2424         {
2425                 // check if ssid match
2426                 if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2427                         status = _STATS_FAILURE_;
2428
2429                 if (ie_len != cur->Ssid.SsidLength)
2430                         status = _STATS_FAILURE_;
2431         }
2432
2433         if(_STATS_SUCCESSFUL_ != status)
2434                 goto OnAssocReqFail;
2435
2436         rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, rate_set, &rate_num);
2437         if (rate_num == 0) {
2438                 DBG_871X(FUNC_ADPT_FMT" RX assoc-req with no supported rate\n", FUNC_ADPT_ARG(padapter));
2439                 status = _STATS_FAILURE_;
2440                 goto OnAssocReqFail;
2441         }
2442         _rtw_memcpy(pstat->bssrateset, rate_set, rate_num);
2443         pstat->bssratelen = rate_num;
2444         UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2445
2446         //check RSN/WPA/WPS
2447         pstat->dot8021xalg = 0;
2448         pstat->wpa_psk = 0;
2449         pstat->wpa_group_cipher = 0;
2450         pstat->wpa2_group_cipher = 0;
2451         pstat->wpa_pairwise_cipher = 0;
2452         pstat->wpa2_pairwise_cipher = 0;
2453         _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2454         if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2455
2456                 int group_cipher=0, pairwise_cipher=0;  
2457                 
2458                 wpa_ie = elems.rsn_ie;
2459                 wpa_ie_len = elems.rsn_ie_len;
2460
2461                 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2462                 {
2463                         pstat->dot8021xalg = 1;//psk,  todo:802.1x                                              
2464                         pstat->wpa_psk |= BIT(1);
2465
2466                         pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;                               
2467                         pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
2468                         
2469                         if(!pstat->wpa2_group_cipher)
2470                                 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2471
2472                         if(!pstat->wpa2_pairwise_cipher)
2473                                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2474                 }
2475                 else
2476                 {
2477                         status = WLAN_STATUS_INVALID_IE;
2478                 }       
2479                         
2480         } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2481
2482                 int group_cipher=0, pairwise_cipher=0;  
2483                 
2484                 wpa_ie = elems.wpa_ie;
2485                 wpa_ie_len = elems.wpa_ie_len;
2486
2487                 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2488                 {
2489                         pstat->dot8021xalg = 1;//psk,  todo:802.1x                                              
2490                         pstat->wpa_psk |= BIT(0);
2491
2492                         pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;                         
2493                         pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
2494                         
2495                         if(!pstat->wpa_group_cipher)
2496                                 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2497
2498                         if(!pstat->wpa_pairwise_cipher)
2499                                 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2500                 
2501                 }
2502                 else
2503                 {
2504                         status = WLAN_STATUS_INVALID_IE;
2505                 }
2506                 
2507         } else {
2508                 wpa_ie = NULL;
2509                 wpa_ie_len = 0;
2510         }
2511
2512         if(_STATS_SUCCESSFUL_ != status)
2513                 goto OnAssocReqFail;
2514
2515         pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2516         //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
2517         if(wpa_ie == NULL) {
2518                 if (elems.wps_ie) {
2519                         DBG_871X("STA included WPS IE in "
2520                                    "(Re)Association Request - assume WPS is "
2521                                    "used\n");
2522                         pstat->flags |= WLAN_STA_WPS;
2523                         //wpabuf_free(sta->wps_ie);
2524                         //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
2525                         //                              elems.wps_ie_len - 4);
2526                 } else {
2527                         DBG_871X("STA did not include WPA/RSN IE "
2528                                    "in (Re)Association Request - possible WPS "
2529                                    "use\n");
2530                         pstat->flags |= WLAN_STA_MAYBE_WPS;
2531                 }
2532
2533
2534                 // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
2535                 // that the selected registrar of AP is _FLASE
2536                 if((psecuritypriv->wpa_psk >0)  
2537                         && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
2538                 {
2539                         if(pmlmepriv->wps_beacon_ie)
2540                         {       
2541                                 u8 selected_registrar = 0;
2542                                 
2543                                 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2544
2545                                 if(!selected_registrar)
2546                                 {                                               
2547                                         DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2548                                                 
2549                                         status = _STATS_UNABLE_HANDLE_STA_;
2550                         
2551                                         goto OnAssocReqFail;
2552                                 }                                               
2553                         }                       
2554                 }
2555                         
2556         }
2557         else
2558         {
2559                 int copy_len;
2560
2561                 if(psecuritypriv->wpa_psk == 0)
2562                 {
2563                         DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
2564                         "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2565                         
2566                         status = WLAN_STATUS_INVALID_IE;
2567                         
2568                         goto OnAssocReqFail;
2569
2570                 }
2571
2572                 if (elems.wps_ie) {
2573                         DBG_871X("STA included WPS IE in "
2574                                    "(Re)Association Request - WPS is "
2575                                    "used\n");
2576                         pstat->flags |= WLAN_STA_WPS;
2577                         copy_len=0;
2578                 }
2579                 else
2580                 {
2581                         copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
2582                 }
2583
2584                 
2585                 if(copy_len>0)
2586                         _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
2587                 
2588         }
2589
2590
2591         // check if there is WMM IE & support WWM-PS
2592         pstat->flags &= ~WLAN_STA_WME;
2593         pstat->qos_option = 0;
2594         pstat->qos_info = 0;
2595         pstat->has_legacy_ac = _TRUE;
2596         pstat->uapsd_vo = 0;
2597         pstat->uapsd_vi = 0;
2598         pstat->uapsd_be = 0;
2599         pstat->uapsd_bk = 0;
2600         if (pmlmepriv->qospriv.qos_option) 
2601         {
2602                 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
2603                 for (;;) 
2604                 {
2605                         p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2606                         if (p != NULL) {
2607                                 if (_rtw_memcmp(p+2, WMM_IE, 6)) {
2608
2609                                         pstat->flags |= WLAN_STA_WME;
2610                                         
2611                                         pstat->qos_option = 1;                          
2612                                         pstat->qos_info = *(p+8);
2613                                         
2614                                         pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
2615
2616                                         if((pstat->qos_info&0xf) !=0xf)
2617                                                 pstat->has_legacy_ac = _TRUE;
2618                                         else
2619                                                 pstat->has_legacy_ac = _FALSE;
2620                                         
2621                                         if(pstat->qos_info&0xf)
2622                                         {
2623                                                 if(pstat->qos_info&BIT(0))
2624                                                         pstat->uapsd_vo = BIT(0)|BIT(1);
2625                                                 else
2626                                                         pstat->uapsd_vo = 0;
2627                 
2628                                                 if(pstat->qos_info&BIT(1))
2629                                                         pstat->uapsd_vi = BIT(0)|BIT(1);
2630                                                 else
2631                                                         pstat->uapsd_vi = 0;
2632                         
2633                                                 if(pstat->qos_info&BIT(2))
2634                                                         pstat->uapsd_bk = BIT(0)|BIT(1);
2635                                                 else
2636                                                         pstat->uapsd_bk = 0;
2637                         
2638                                                 if(pstat->qos_info&BIT(3))                      
2639                                                         pstat->uapsd_be = BIT(0)|BIT(1);
2640                                                 else
2641                                                         pstat->uapsd_be = 0;
2642                 
2643                                         }
2644         
2645                                         break;
2646                                 }
2647                         }
2648                         else {
2649                                 break;
2650                         }
2651                         p = p + ie_len + 2;
2652                 }
2653         }
2654
2655
2656 #ifdef CONFIG_80211N_HT
2657         /* save HT capabilities in the sta object */
2658         _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2659         if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) 
2660         {
2661                 pstat->flags |= WLAN_STA_HT;
2662                 
2663                 pstat->flags |= WLAN_STA_WME;
2664                 
2665                 _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));                 
2666                 
2667         } else
2668                 pstat->flags &= ~WLAN_STA_HT;
2669
2670         
2671         if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
2672         {
2673                 status = _STATS_FAILURE_;
2674                 goto OnAssocReqFail;
2675         }
2676                 
2677 #endif /* CONFIG_80211N_HT */
2678
2679 #ifdef CONFIG_80211AC_VHT
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
2698         if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT))
2699         {
2700                 status = _STATS_FAILURE_;
2701                 goto OnAssocReqFail;
2702         }
2703 #endif /* CONFIG_80211AC_VHT */
2704
2705         if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) && 
2706                 ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) || 
2707                 (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2708
2709                 DBG_871X("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr));
2710
2711                 pstat->flags &= ~WLAN_STA_HT;
2712                 pstat->flags &= ~WLAN_STA_VHT;
2713                 /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2714                   * goto OnAssocReqFail;
2715                 */
2716         }
2717
2718
2719        //
2720        //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
2721         pstat->flags |= WLAN_STA_NONERP;        
2722         for (i = 0; i < pstat->bssratelen; i++) {
2723                 if ((pstat->bssrateset[i] & 0x7f) > 22) {
2724                         pstat->flags &= ~WLAN_STA_NONERP;
2725                         break;
2726                 }
2727         }
2728
2729         if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2730                 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2731         else
2732                 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2733
2734         
2735         
2736         if (status != _STATS_SUCCESSFUL_)
2737                 goto OnAssocReqFail;
2738
2739 #ifdef CONFIG_P2P
2740         pstat->is_p2p_device = _FALSE;
2741         if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2742         {               
2743                 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
2744                 {
2745                         pstat->is_p2p_device = _TRUE;
2746                         if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
2747                         {
2748                                 pstat->p2p_status_code = p2p_status_code;
2749                                 status = _STATS_CAP_FAIL_;
2750                                 goto OnAssocReqFail;
2751                         }
2752                 }
2753                 #ifdef CONFIG_WFD
2754                 rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
2755                 #endif
2756         }
2757         pstat->p2p_status_code = p2p_status_code;
2758 #endif //CONFIG_P2P
2759
2760         //TODO: identify_proprietary_vendor_ie();
2761         // Realtek proprietary IE
2762         // identify if this is Broadcom sta
2763         // identify if this is ralink sta
2764         // Customer proprietary IE
2765
2766         
2767
2768         /* get a unique AID */
2769         if (pstat->aid > 0) {
2770                 DBG_871X("  old AID %d\n", pstat->aid);
2771         } else {
2772                 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2773                         if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2774                                 if (pstat->aid > pstapriv->max_num_sta) {
2775                                         pstat->aid = 0;
2776                                 
2777                                         DBG_871X("  no room for more AIDs\n");
2778
2779                                         status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2780                                 
2781                                         goto OnAssocReqFail;
2782                                 
2783                         
2784                                 } else {
2785                                         pstapriv->sta_aid[pstat->aid - 1] = pstat;
2786                                         DBG_871X("allocate new AID = (%d)\n", pstat->aid);
2787                                         break;
2788                                 }                               
2789                         }
2790                 }       
2791         }
2792
2793
2794         pstat->state &= (~WIFI_FW_ASSOC_STATE); 
2795         pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2796         /* DBG_871X("==================%s, %d,  (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2797         , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */
2798 #ifdef CONFIG_IEEE80211W
2799         if (pstat->bpairwise_key_installed != _TRUE)
2800 #endif /* CONFIG_IEEE80211W */
2801         {
2802                 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2803                 if (!rtw_is_list_empty(&pstat->auth_list)) {
2804                         rtw_list_delete(&pstat->auth_list);
2805                         pstapriv->auth_list_cnt--;
2806                 }
2807                 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2808         
2809                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);   
2810                 if (rtw_is_list_empty(&pstat->asoc_list)) {
2811                         pstat->expire_to = pstapriv->expire_to;
2812                         rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2813                         pstapriv->asoc_list_cnt++;
2814                 }
2815                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2816         }
2817
2818         // now the station is qualified to join our BSS...      
2819         if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
2820         {
2821 #ifdef CONFIG_NATIVEAP_MLME
2822 #ifdef CONFIG_IEEE80211W
2823                 if (pstat->bpairwise_key_installed != _TRUE)
2824 #endif /* CONFIG_IEEE80211W */
2825                 {
2826                         /* .1 bss_cap_update & sta_info_update */
2827                         bss_cap_update_on_sta_join(padapter, pstat);
2828                         sta_info_update(padapter, pstat);
2829                 }
2830 #ifdef CONFIG_IEEE80211W
2831                 if (pstat->bpairwise_key_installed == _TRUE)
2832                         status = _STATS_REFUSED_TEMPORARILY_;
2833 #endif /* CONFIG_IEEE80211W */
2834                 //.2 issue assoc rsp before notify station join event.
2835                 if (frame_type == WIFI_ASSOCREQ)
2836                         issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2837                 else
2838                         issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2839
2840 #ifdef CONFIG_IOCTL_CFG80211
2841                 _enter_critical_bh(&pstat->lock, &irqL);
2842                 if(pstat->passoc_req)
2843                 {
2844                         rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2845                         pstat->passoc_req = NULL;
2846                         pstat->assoc_req_len = 0;
2847                 }
2848
2849                 pstat->passoc_req =  rtw_zmalloc(pkt_len);
2850                 if(pstat->passoc_req)
2851                 {
2852                         _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2853                         pstat->assoc_req_len = pkt_len;
2854                 }
2855                 _exit_critical_bh(&pstat->lock, &irqL);
2856 #endif //CONFIG_IOCTL_CFG80211
2857 #ifdef CONFIG_IEEE80211W
2858                 if (pstat->bpairwise_key_installed != _TRUE)
2859 #endif /* CONFIG_IEEE80211W */
2860                 {
2861                         /* .3-(1) report sta add event */
2862                         report_add_sta_event(padapter, pstat->hwaddr);
2863                 }
2864 #ifdef CONFIG_IEEE80211W
2865                 if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) {
2866                         DBG_871X(MAC_FMT"\n", MAC_ARG(pstat->hwaddr));
2867                         issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY);
2868                 }
2869 #endif /* CONFIG_IEEE80211W */
2870 #endif //CONFIG_NATIVEAP_MLME
2871         }
2872
2873         return _SUCCESS;
2874
2875 asoc_class2_error:
2876
2877 #ifdef CONFIG_NATIVEAP_MLME
2878         issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
2879 #endif
2880
2881         return _FAIL;           
2882
2883 OnAssocReqFail:
2884
2885
2886 #ifdef CONFIG_NATIVEAP_MLME
2887         pstat->aid = 0;
2888         if (frame_type == WIFI_ASSOCREQ)
2889                 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2890         else
2891                 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2892 #endif
2893
2894
2895 #endif /* CONFIG_AP_MODE */
2896
2897         return _FAIL;           
2898
2899 }
2900
2901 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2902 {
2903         uint i;
2904         int res;
2905         unsigned short  status;
2906         PNDIS_802_11_VARIABLE_IEs       pIE;
2907         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2908         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2909         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2910         //WLAN_BSSID_EX                 *cur_network = &(pmlmeinfo->network);
2911         u8 *pframe = precv_frame->u.hdr.rx_data;
2912         uint pkt_len = precv_frame->u.hdr.len;
2913         PNDIS_802_11_VARIABLE_IEs       pWapiIE = NULL;
2914
2915         DBG_871X("%s\n", __FUNCTION__);
2916         
2917         //check A1 matches or not
2918         if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2919                 return _SUCCESS;
2920
2921         if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2922                 return _SUCCESS;
2923
2924         if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2925                 return _SUCCESS;
2926
2927         _cancel_timer_ex(&pmlmeext->link_timer);
2928
2929         //status
2930         if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2931         {
2932                 DBG_871X("assoc reject, status code: %d\n", status);
2933                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2934                 res = -4;
2935                 goto report_assoc_result;
2936         }
2937
2938         //get capabilities
2939         pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2940
2941         //set slot time
2942         pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2943
2944         //AID
2945         res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2946
2947         //following are moved to join event callback function
2948         //to handle HT, WMM, rate adaptive, update MAC reg
2949         //for not to handle the synchronous IO in the tasklet
2950         for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2951         {
2952                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2953
2954                 switch (pIE->ElementID)
2955                 {
2956                         case _VENDOR_SPECIFIC_IE_:
2957                                 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6))    //WMM
2958                                 {
2959                                         WMM_param_handler(padapter, pIE);
2960                                 }
2961 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2962                                 else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4))           //WFD
2963                                 {
2964                                         rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
2965                                 }
2966 #endif                          
2967                                 break;
2968
2969 #ifdef CONFIG_WAPI_SUPPORT
2970                         case _WAPI_IE_:
2971                                 pWapiIE = pIE;
2972                                 break;
2973 #endif
2974
2975                         case _HT_CAPABILITY_IE_:        //HT caps
2976                                 HT_caps_handler(padapter, pIE);
2977                                 break;
2978
2979                         case _HT_EXTRA_INFO_IE_:        //HT info
2980                                 HT_info_handler(padapter, pIE);
2981                                 break;
2982
2983 #ifdef CONFIG_80211AC_VHT
2984                         case EID_VHTCapability:
2985                                 VHT_caps_handler(padapter, pIE);
2986                                 break;
2987
2988                         case EID_VHTOperation:
2989                                 VHT_operation_handler(padapter, pIE);
2990                                 break;
2991 #endif
2992
2993                         case _ERPINFO_IE_:
2994                                 ERP_IE_handler(padapter, pIE);
2995                                 break;
2996 #ifdef CONFIG_TDLS
2997                         case _EXT_CAP_IE_:
2998                                 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2999                                         padapter->tdlsinfo.ap_prohibited = _TRUE;
3000                                 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
3001                                         padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
3002                                 break;
3003 #endif /* CONFIG_TDLS */
3004                         default:
3005                                 break;
3006                 }
3007
3008                 i += (pIE->Length + 2);
3009         }
3010
3011 #ifdef CONFIG_WAPI_SUPPORT
3012         rtw_wapi_on_assoc_ok(padapter, pIE);
3013 #endif
3014
3015         pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3016         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3017
3018         //Update Basic Rate Table for spec, 2010-12-28 , by thomas
3019         UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3020
3021 report_assoc_result:
3022         if (res > 0) {
3023                 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3024         } else {
3025                 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3026         }
3027
3028         report_join_res(padapter, res);
3029
3030         return _SUCCESS;
3031 }
3032
3033 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
3034 {
3035         unsigned short  reason;
3036         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3037         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3038         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3039         u8 *pframe = precv_frame->u.hdr.rx_data;
3040 #ifdef CONFIG_P2P
3041         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3042 #endif //CONFIG_P2P
3043
3044         //check A3
3045         if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3046                 return _SUCCESS;
3047
3048         DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3049
3050 #ifdef CONFIG_P2P
3051         if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3052         {
3053                 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3054                 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3055         }
3056 #endif //CONFIG_P2P
3057
3058         reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3059
3060         rtw_lock_rx_suspend_timeout(8000);
3061
3062 #ifdef CONFIG_AP_MODE
3063         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3064         {               
3065                 _irqL irqL;
3066                 struct sta_info *psta;
3067                 struct sta_priv *pstapriv = &padapter->stapriv;
3068                 
3069                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);                
3070                 //rtw_free_stainfo(padapter, psta);
3071                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);         
3072
3073                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3074                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3075
3076                 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));  
3077                 if(psta)
3078                 {
3079                         u8 updated = _FALSE;
3080                 
3081                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3082                         if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3083                         {                       
3084                                 rtw_list_delete(&psta->asoc_list);
3085                                 pstapriv->asoc_list_cnt--;
3086                                 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3087
3088                         }
3089                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3090
3091                         associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3092                 }
3093                 
3094
3095                 return _SUCCESS;
3096         }
3097         else
3098 #endif
3099         {
3100                 int     ignore_received_deauth = 0;
3101
3102                 //      Commented by Albert 20130604
3103                 //      Before sending the auth frame to start the STA/GC mode connection with AP/GO, 
3104                 //      we will send the deauth first.
3105                 //      However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
3106                 //      Added the following code to avoid this case.
3107                 if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
3108                         ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
3109                 {
3110                         if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
3111                         {
3112                                 ignore_received_deauth = 1;
3113                         } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3114                                 // TODO: 802.11r
3115                                 ignore_received_deauth = 1;
3116                         }
3117                 }
3118
3119                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3120                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth);
3121
3122                 if ( 0 == ignore_received_deauth )
3123                 {
3124                         receive_disconnect(padapter, GetAddr2Ptr(pframe), reason, _FALSE);
3125                 }
3126         }       
3127         pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3128         return _SUCCESS;
3129
3130 }
3131
3132 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3133 {
3134         unsigned short  reason;
3135         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3136         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3137         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3138         u8 *pframe = precv_frame->u.hdr.rx_data;
3139 #ifdef CONFIG_P2P
3140         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3141 #endif //CONFIG_P2P
3142
3143         //check A3
3144         if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3145                 return _SUCCESS;
3146
3147         DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3148
3149 #ifdef CONFIG_P2P
3150         if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3151         {
3152                 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3153                 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3154         }
3155 #endif //CONFIG_P2P
3156
3157         reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3158
3159         rtw_lock_rx_suspend_timeout(8000);
3160         
3161 #ifdef CONFIG_AP_MODE
3162         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3163         {       
3164                 _irqL irqL;
3165                 struct sta_info *psta;
3166                 struct sta_priv *pstapriv = &padapter->stapriv;
3167                 
3168                 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);        
3169                 //rtw_free_stainfo(padapter, psta);
3170                 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);         
3171
3172                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3173                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3174
3175                 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));  
3176                 if(psta)
3177                 {
3178                         u8 updated = _FALSE;
3179                         
3180                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3181                         if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3182                         {
3183                                 rtw_list_delete(&psta->asoc_list);
3184                                 pstapriv->asoc_list_cnt--;
3185                                 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3186                         
3187                         }
3188                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3189
3190                         associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3191                 }
3192
3193                 return _SUCCESS;
3194         }
3195         else
3196 #endif
3197         {
3198                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3199                         , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3200
3201                 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason, _FALSE);
3202         }       
3203         pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3204         return _SUCCESS;
3205
3206 }
3207
3208 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3209 {
3210         DBG_871X("%s\n", __FUNCTION__);
3211         return _SUCCESS;
3212 }
3213
3214 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3215 {
3216         unsigned int ret = _FAIL;
3217         struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3218         struct mlme_ext_info    *pmlmeinfo = &(mlmeext->mlmext_info);
3219
3220         if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3221                 ret = _SUCCESS; 
3222                 goto exit;
3223         }
3224
3225         if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3226                 
3227                 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3228                 int ch_offset = -1;
3229                 u8 bwmode;
3230                 struct ieee80211_info_element *ie;
3231
3232                 DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3233                         FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
3234
3235                 for_each_ie(ie, ies, ies_len) {
3236                         if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3237                                 ch_switch_mode = ie->data[0];
3238                                 ch = ie->data[1];
3239                                 ch_switch_cnt = ie->data[2];
3240                                 DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3241                                         ch_switch_mode, ch, ch_switch_cnt);
3242                         }
3243                         else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3244                                 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3245                                 DBG_871X("ch_offset:%d\n", ch_offset);
3246                         }
3247                 }
3248
3249                 if (ch == -1)
3250                         return _SUCCESS;
3251
3252                 if (ch_offset == -1)
3253                         bwmode = mlmeext->cur_bwmode;
3254                 else
3255                         bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3256                                 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3257
3258                 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3259
3260                 /* todo:
3261                  * 1. the decision of channel switching
3262                  * 2. things after channel switching
3263                  */
3264
3265                 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
3266         }
3267
3268 exit:
3269         return ret;
3270 }
3271
3272 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3273 {
3274         unsigned int ret = _FAIL;
3275         struct sta_info *psta = NULL;
3276         struct sta_priv *pstapriv = &padapter->stapriv;
3277         u8 *pframe = precv_frame->u.hdr.rx_data;
3278         uint frame_len = precv_frame->u.hdr.len;
3279         u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3280         u8 category;
3281         u8 action;
3282
3283         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3284
3285         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3286
3287         if (!psta)
3288                 goto exit;
3289
3290         category = frame_body[0];
3291         if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3292                 goto exit;
3293
3294         action = frame_body[1];
3295         switch (action) {
3296         case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3297         case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3298         case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3299         case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3300                 break;
3301         case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3302                 #ifdef CONFIG_SPCT_CH_SWITCH
3303                 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
3304                         frame_len-(frame_body-pframe)-2);
3305                 #endif
3306                 break;
3307         default:
3308                 break;
3309         }
3310
3311 exit:
3312         return ret;
3313 }
3314
3315 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3316 {
3317         return _SUCCESS;
3318 }
3319
3320 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3321 {
3322         return _SUCCESS;
3323 }
3324
3325 /**
3326  * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3327  * @adapter: the adapter to get target RX AMPDU buffer size
3328  *
3329  * Returns: the target RX AMPDU buffer size
3330  */
3331 u8 rtw_rx_ampdu_size(_adapter *adapter)
3332 {
3333         u8 size;
3334         HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3335
3336         if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) {
3337                 size = adapter->fix_rx_ampdu_size;
3338                 goto exit;
3339         }
3340
3341 #ifdef CONFIG_BT_COEXIST
3342         if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3343                 size = rtw_btcoex_GetAMPDUSize(adapter);
3344                 goto exit;
3345         }
3346 #endif
3347
3348         /* for scan */
3349         if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3350                 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3351                 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3352         ) {
3353                 size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3354                 goto exit;
3355         }
3356
3357         /* default value based on max_rx_ampdu_factor */
3358         if (adapter->driver_rx_ampdu_factor != 0xFF)
3359                 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3360         else
3361                 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3362
3363         if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3364                 size = 64;
3365         else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3366                 size = 32;
3367         else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3368                 size = 16;
3369         else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3370                 size = 8;
3371         else
3372                 size = 64;
3373
3374 exit:
3375
3376         if (size > 127)
3377                 size = 127;
3378
3379         return size;
3380 }
3381
3382 /**
3383  * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3384  * @adapter: the adapter to get the permission if RX AMPDU should be set up
3385  *
3386  * Returns: accept or not
3387  */
3388 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3389 {
3390         bool accept;
3391
3392         if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3393                 accept = adapter->fix_rx_ampdu_accept;
3394                 goto exit;
3395         }
3396
3397 #ifdef CONFIG_BT_COEXIST
3398         if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3399                 accept = _FALSE;
3400                 goto exit;
3401         }
3402 #endif
3403
3404         /* for scan */
3405         if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3406                 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3407                 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3408         ) {
3409                 accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3410                 goto exit;
3411         }
3412
3413         /* default value for other cases */
3414         accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3415
3416 exit:
3417         return accept;
3418 }
3419
3420 /**
3421  * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3422  * @adapter: the adapter to set target RX AMPDU buffer size
3423  * @size: the target RX AMPDU buffer size to set
3424  * @reason: reason for the target RX AMPDU buffer size setting
3425  *
3426  * Returns: whether the target RX AMPDU buffer size is changed
3427  */
3428 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3429 {
3430         bool is_adj = _FALSE;
3431         struct mlme_ext_priv *mlmeext;
3432         struct mlme_ext_info *mlmeinfo;
3433
3434         mlmeext = &adapter->mlmeextpriv;
3435         mlmeinfo = &mlmeext->mlmext_info;
3436
3437         if (reason == RX_AMPDU_DRV_FIXED) {
3438                 if (adapter->fix_rx_ampdu_size != size) {
3439                         adapter->fix_rx_ampdu_size = size;
3440                         is_adj = _TRUE;
3441                         DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3442                 }
3443         } else if (reason == RX_AMPDU_DRV_SCAN) {
3444                 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3445
3446                 if (ss->rx_ampdu_size != size) {
3447                         ss->rx_ampdu_size = size;
3448                         is_adj = _TRUE;
3449                         DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3450                 }
3451         }
3452
3453         return is_adj;
3454 }
3455
3456 /**
3457  * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3458  * @adapter: the adapter to set if RX AMPDU should be set up
3459  * @accept: if RX AMPDU should be set up
3460  * @reason: reason for the permission if RX AMPDU should be set up
3461  *
3462  * Returns: whether the permission if RX AMPDU should be set up is changed
3463  */
3464 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3465 {
3466         bool is_adj = _FALSE;
3467         struct mlme_ext_priv *mlmeext;
3468         struct mlme_ext_info *mlmeinfo;
3469
3470         mlmeext = &adapter->mlmeextpriv;
3471         mlmeinfo = &mlmeext->mlmext_info;
3472
3473         if (reason == RX_AMPDU_DRV_FIXED) {
3474                 if (adapter->fix_rx_ampdu_accept != accept) {
3475                         adapter->fix_rx_ampdu_accept = accept;
3476                         is_adj = _TRUE;
3477                         DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3478                 }
3479         } else if (reason == RX_AMPDU_DRV_SCAN) {
3480                 if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3481                         adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3482                         is_adj = _TRUE;
3483                         DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3484                 }
3485         }
3486
3487         return is_adj;
3488 }
3489
3490 /**
3491  * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3492  * @adapter: the adapter to which @sta belongs
3493  * @sta: the sta to be checked
3494  * @tid: the tid to be checked
3495  * @accept: the target permission if RX AMPDU should be set up
3496  * @size: the target RX AMPDU buffer size
3497  *
3498  * Returns:
3499  * 0: no canceled
3500  * 1: canceled by no permission
3501  * 2: canceled by different buffer size
3502  * 3: canceled by potential mismatched status
3503  *
3504  * Blocking function, may sleep
3505  */
3506 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3507 {
3508         u8 ret = 0;
3509         struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3510
3511         if (reorder_ctl->enable == _FALSE) {
3512                 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3513                         send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3514                         ret = 3;
3515                 }
3516                 goto exit;
3517         }
3518
3519         if (accept == _FALSE) {
3520                 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3521                 ret = 1;
3522         } else if (reorder_ctl->ampdu_size != size) {
3523                 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3524                 ret = 2;
3525         }
3526
3527 exit:
3528         return ret;
3529 }
3530
3531 /**
3532  * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3533  * @adapter: the adapter to which @sta belongs
3534  * @sta: the sta to be checked
3535  * @accept: the target permission if RX AMPDU should be set up
3536  * @size: the target RX AMPDU buffer size
3537  *
3538  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3539  *
3540  * Blocking function, may sleep
3541  */
3542 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3543 {
3544         u8 change_cnt = 0;
3545         int i;
3546
3547         for (i = 0; i < TID_NUM; i++) {
3548                 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3549                         change_cnt++;
3550         }
3551
3552         return change_cnt;
3553 }
3554
3555 /**
3556  * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3557  * @adapter: the adapter to be applied
3558  *
3559  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3560  */
3561 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3562 {
3563         u16 adj_cnt = 0;
3564         struct mlme_ext_priv *mlmeext;
3565         struct sta_info *sta;
3566         u8 accept = rtw_rx_ampdu_is_accept(adapter);
3567         u8 size = rtw_rx_ampdu_size(adapter);
3568
3569         mlmeext = &adapter->mlmeextpriv;
3570
3571         if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3572                 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3573                 if (sta)
3574                         adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3575
3576         } else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3577                 _irqL irqL;
3578                 _list *phead, *plist;
3579                 u8 peer_num = 0;
3580                 char peers[NUM_STA];
3581                 struct sta_priv *pstapriv = &adapter->stapriv;
3582                 int i;
3583
3584                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3585
3586                 phead = &pstapriv->asoc_list;
3587                 plist = get_next(phead);
3588
3589                 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3590                         int stainfo_offset;
3591
3592                         sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3593                         plist = get_next(plist);
3594
3595                         stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3596                         if (stainfo_offset_valid(stainfo_offset))
3597                                 peers[peer_num++] = stainfo_offset;
3598                 }
3599
3600                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3601
3602                 for (i = 0; i < peer_num; i++) {
3603                         sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3604                         if (sta)
3605                                 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3606                 }
3607         }
3608
3609         return adj_cnt;
3610 }
3611
3612 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3613 {
3614         u8 *addr;
3615         struct sta_info *psta=NULL;
3616         struct recv_reorder_ctrl *preorder_ctrl;
3617         unsigned char           *frame_body;
3618         unsigned char           category, action;
3619         unsigned short  tid, status, reason_code = 0;
3620         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3621         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3622         u8 *pframe = precv_frame->u.hdr.rx_data;
3623         struct sta_priv *pstapriv = &padapter->stapriv;
3624 #ifdef CONFIG_80211N_HT
3625
3626         DBG_871X("%s\n", __FUNCTION__);
3627
3628         //check RA matches or not       
3629         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3630                 return _SUCCESS;
3631
3632 /*
3633         //check A1 matches or not
3634         if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3635                 return _SUCCESS;
3636 */
3637
3638         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 
3639                 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3640                         return _SUCCESS;
3641
3642         addr = GetAddr2Ptr(pframe);
3643         psta = rtw_get_stainfo(pstapriv, addr);
3644
3645         if(psta==NULL)
3646                 return _SUCCESS;
3647
3648         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3649
3650         category = frame_body[0];
3651         if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
3652         {
3653 #ifdef CONFIG_TDLS
3654                 if((psta->tdls_sta_state & TDLS_LINKED_STATE) && 
3655                         (psta->htpriv.ht_option==_TRUE) &&
3656                         (psta->htpriv.ampdu_enable==_TRUE))
3657                 {
3658                         DBG_871X("Recv [%s] from direc link\n", __FUNCTION__);
3659                 }
3660                 else
3661 #endif //CONFIG_TDLS
3662                 if (!pmlmeinfo->HT_enable)
3663                 {
3664                         return _SUCCESS;
3665                 }
3666
3667                 action = frame_body[1];
3668                 DBG_871X("%s, action=%d\n", __FUNCTION__, action);
3669                 switch (action)
3670                 {
3671                         case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
3672
3673                                 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3674                                 //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
3675                                 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
3676                                                                 
3677                                 break;
3678
3679                         case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
3680
3681                                 //status = frame_body[3] | (frame_body[4] << 8); //endian issue
3682                                 status = RTW_GET_LE16(&frame_body[3]);
3683                                 tid = ((frame_body[5] >> 2) & 0x7);
3684
3685                                 if (status == 0)
3686                                 {       //successful                                    
3687                                         DBG_871X("agg_enable for TID=%d\n", tid);
3688                                         psta->htpriv.agg_enable_bitmap |= 1 << tid;                                     
3689                                         psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);                         
3690                                 }
3691                                 else
3692                                 {                                       
3693                                         psta->htpriv.agg_enable_bitmap &= ~BIT(tid);                                    
3694                                 }
3695
3696                                 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3697                                 {
3698                                         DBG_871X("%s alive check - rx ADDBA response\n", __func__);
3699                                         psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3700                                         psta->expire_to = pstapriv->expire_to;
3701                                         psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3702                                 }
3703
3704                                 //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
3705                                 break;
3706
3707                         case RTW_WLAN_ACTION_DELBA: //DELBA
3708                                 if ((frame_body[3] & BIT(3)) == 0)
3709                                 {
3710                                         psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3711                                         psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3712                                         
3713                                         //reason_code = frame_body[4] | (frame_body[5] << 8);
3714                                         reason_code = RTW_GET_LE16(&frame_body[4]);
3715                                 }
3716                                 else if((frame_body[3] & BIT(3)) == BIT(3))
3717                                 {                                               
3718                                         tid = (frame_body[3] >> 4) & 0x0F;
3719                                 
3720                                         preorder_ctrl = &psta->recvreorder_ctrl[tid];
3721                                         preorder_ctrl->enable = _FALSE;
3722                                         preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3723                                 }
3724                                 
3725                                 DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
3726                                 //todo: how to notify the host while receiving DELETE BA
3727                                 break;
3728
3729                         default:
3730                                 break;
3731                 }
3732         }
3733 #endif //CONFIG_80211N_HT
3734         return _SUCCESS;
3735 }
3736
3737 #ifdef CONFIG_P2P
3738
3739 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
3740         int cnt = 0;
3741         int i;
3742
3743         for (i = 0; i < channel_list.reg_classes; i++) {
3744                 cnt += channel_list.reg_class[i].channels;
3745         }
3746
3747         return cnt;
3748 }
3749
3750 static void get_channel_cnt_24g_5gl_5gh(  struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
3751 {
3752         int     i = 0;
3753
3754         *p24g_cnt = 0;
3755         *p5gl_cnt = 0;
3756         *p5gh_cnt = 0;  
3757         
3758         for( i = 0; i < pmlmeext->max_chan_nums; i++ )
3759         {
3760                 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
3761                 {
3762                         (*p24g_cnt)++;
3763                 }
3764                 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
3765                 {
3766                         //      Just include the channel 36, 40, 44, 48 channels for 5G low
3767                         (*p5gl_cnt)++;
3768                 }
3769                 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
3770                 {
3771                         //      Just include the channel 149, 153, 157, 161 channels for 5G high
3772                         (*p5gh_cnt)++;
3773                 }
3774         }
3775 }
3776
3777 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
3778 {
3779
3780         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3781         u8                      action = P2P_PUB_ACTION_ACTION;
3782         u32                     p2poui = cpu_to_be32(P2POUI);
3783         u8                      oui_subtype = P2P_GO_NEGO_REQ;
3784         u8                      wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3785         u8                      wpsielen = 0, p2pielen = 0, i;
3786         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3787         u16                     len_channellist_attr = 0;
3788 #ifdef CONFIG_WFD
3789         u32                                     wfdielen = 0;
3790 #endif
3791         
3792         struct xmit_frame                       *pmgntframe;
3793         struct pkt_attrib                       *pattrib;
3794         unsigned char                                   *pframe;
3795         struct rtw_ieee80211_hdr        *pwlanhdr;
3796         unsigned short                          *fctrl;
3797         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
3798         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3799         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3800         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
3801
3802
3803         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3804         {
3805                 return;
3806         }
3807
3808         DBG_871X( "[%s] In\n", __FUNCTION__ );
3809         //update attribute
3810         pattrib = &pmgntframe->attrib;
3811         update_mgntframe_attrib(padapter, pattrib);
3812
3813         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3814
3815         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3816         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3817
3818         fctrl = &(pwlanhdr->frame_ctl);
3819         *(fctrl) = 0;
3820
3821         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3822         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3823         _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3824
3825         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3826         pmlmeext->mgnt_seq++;
3827         SetFrameSubType(pframe, WIFI_ACTION);
3828
3829         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3830         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3831
3832         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3833         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3834         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3835         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
3836         pwdinfo->negotiation_dialog_token = 1;  //      Initialize the dialog value
3837         pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3838
3839         
3840
3841         //      WPS Section
3842         wpsielen = 0;
3843         //      WPS OUI
3844         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3845         wpsielen += 4;
3846
3847         //      WPS version
3848         //      Type:
3849         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3850         wpsielen += 2;
3851
3852         //      Length:
3853         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3854         wpsielen += 2;
3855
3856         //      Value:
3857         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
3858
3859         //      Device Password ID
3860         //      Type:
3861         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3862         wpsielen += 2;
3863
3864         //      Length:
3865         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3866         wpsielen += 2;
3867
3868         //      Value:
3869
3870         if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
3871         {
3872                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3873         }
3874         else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
3875         {
3876                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3877         }
3878         else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
3879         {
3880                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3881         }
3882
3883         wpsielen += 2;
3884
3885         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3886
3887
3888         //      P2P IE Section.
3889
3890         //      P2P OUI
3891         p2pielen = 0;
3892         p2pie[ p2pielen++ ] = 0x50;
3893         p2pie[ p2pielen++ ] = 0x6F;
3894         p2pie[ p2pielen++ ] = 0x9A;
3895         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
3896
3897         //      Commented by Albert 20110306
3898         //      According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
3899         //      1. P2P Capability
3900         //      2. Group Owner Intent
3901         //      3. Configuration Timeout
3902         //      4. Listen Channel
3903         //      5. Extended Listen Timing
3904         //      6. Intended P2P Interface Address
3905         //      7. Channel List
3906         //      8. P2P Device Info
3907         //      9. Operating Channel
3908
3909
3910         //      P2P Capability
3911         //      Type:
3912         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3913
3914         //      Length:
3915         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3916         p2pielen += 2;
3917
3918         //      Value:
3919         //      Device Capability Bitmap, 1 byte
3920         p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3921
3922         //      Group Capability Bitmap, 1 byte
3923         if ( pwdinfo->persistent_supported )
3924         {
3925                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3926         }
3927         else
3928         {
3929                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3930         }
3931
3932
3933         //      Group Owner Intent
3934         //      Type:
3935         p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3936
3937         //      Length:
3938         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3939         p2pielen += 2;
3940
3941         //      Value:
3942         //      Todo the tie breaker bit.
3943         p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) &  0xFE );
3944
3945         //      Configuration Timeout
3946         //      Type:
3947         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3948
3949         //      Length:
3950         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3951         p2pielen += 2;
3952
3953         //      Value:
3954         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
3955         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
3956
3957
3958         //      Listen Channel
3959         //      Type:
3960         p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
3961
3962         //      Length:
3963         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3964         p2pielen += 2;
3965
3966         //      Value:
3967         //      Country String
3968         p2pie[ p2pielen++ ] = 'X';
3969         p2pie[ p2pielen++ ] = 'X';
3970         
3971         //      The third byte should be set to 0x04.
3972         //      Described in the "Operating Channel Attribute" section.
3973         p2pie[ p2pielen++ ] = 0x04;
3974
3975         //      Operating Class
3976         p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
3977         
3978         //      Channel Number
3979         p2pie[ p2pielen++ ] = pwdinfo->listen_channel;  //      listening channel number
3980         
3981
3982         //      Extended Listen Timing ATTR
3983         //      Type:
3984         p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
3985
3986         //      Length:
3987         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
3988         p2pielen += 2;
3989
3990         //      Value:
3991         //      Availability Period
3992         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3993         p2pielen += 2;
3994
3995         //      Availability Interval
3996         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3997         p2pielen += 2;
3998
3999
4000         //      Intended P2P Interface Address
4001         //      Type:
4002         p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4003
4004         //      Length:
4005         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4006         p2pielen += 2;
4007
4008         //      Value:
4009         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4010         p2pielen += ETH_ALEN;
4011
4012
4013         //      Channel List
4014         //      Type:
4015         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4016
4017         // Length:
4018         // Country String(3)
4019         // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4020         // + number of channels in all classes
4021         len_channellist_attr = 3
4022            + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
4023            + get_reg_classes_full_count(pmlmeext->channel_list);
4024
4025 #ifdef CONFIG_CONCURRENT_MODE
4026         if (check_buddy_fwstate(padapter , _FW_LINKED)
4027                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4028         {
4029                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4030         }
4031         else
4032         {
4033                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4034         }
4035 #else
4036
4037         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4038
4039 #endif
4040         p2pielen += 2;
4041
4042         //      Value:
4043         //      Country String
4044         p2pie[ p2pielen++ ] = 'X';
4045         p2pie[ p2pielen++ ] = 'X';
4046         
4047         //      The third byte should be set to 0x04.
4048         //      Described in the "Operating Channel Attribute" section.
4049         p2pie[ p2pielen++ ] = 0x04;
4050
4051         //      Channel Entry List
4052
4053 #ifdef CONFIG_CONCURRENT_MODE
4054         if (check_buddy_fwstate(padapter , _FW_LINKED)
4055                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4056         {
4057                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
4058                 struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4059
4060                 //      Operating Class
4061                 if ( pbuddy_mlmeext->cur_channel > 14 )
4062                 {
4063                         if ( pbuddy_mlmeext->cur_channel >= 149 )
4064                         {
4065                                 p2pie[ p2pielen++ ] = 0x7c;
4066                         }
4067                         else
4068                         {
4069                                 p2pie[ p2pielen++ ] = 0x73;
4070                         }
4071                 }
4072                 else
4073                 {
4074                         p2pie[ p2pielen++ ] = 0x51;
4075                 }
4076
4077                 //      Number of Channels
4078                 //      Just support 1 channel and this channel is AP's channel
4079                 p2pie[ p2pielen++ ] = 1;
4080
4081                 //      Channel List
4082                 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4083         }
4084         else
4085         {
4086                 int i,j;
4087                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4088                         //      Operating Class
4089                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4090
4091                         //      Number of Channels
4092                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4093
4094                         //      Channel List
4095                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4096                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4097                         }
4098                 }
4099         }
4100 #else // CONFIG_CONCURRENT_MODE
4101         {
4102                 int i,j;
4103                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4104                         //      Operating Class
4105                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4106
4107                         //      Number of Channels
4108                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4109
4110                         //      Channel List
4111                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4112                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4113                         }
4114                 }
4115         }
4116 #endif // CONFIG_CONCURRENT_MODE
4117
4118         //      Device Info
4119         //      Type:
4120         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4121
4122         //      Length:
4123         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
4124         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4125         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4126         p2pielen += 2;
4127
4128         //      Value:
4129         //      P2P Device Address
4130         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4131         p2pielen += ETH_ALEN;
4132
4133         //      Config Method
4134         //      This field should be big endian. Noted by P2P specification.
4135
4136         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4137
4138         p2pielen += 2;
4139
4140         //      Primary Device Type
4141         //      Category ID
4142         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4143         p2pielen += 2;
4144
4145         //      OUI
4146         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4147         p2pielen += 4;
4148
4149         //      Sub Category ID
4150         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4151         p2pielen += 2;
4152
4153         //      Number of Secondary Device Types
4154         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
4155
4156         //      Device Name
4157         //      Type:
4158         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4159         p2pielen += 2;
4160
4161         //      Length:
4162         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4163         p2pielen += 2;
4164
4165         //      Value:
4166         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4167         p2pielen += pwdinfo->device_name_len;   
4168         
4169
4170         //      Operating Channel
4171         //      Type:
4172         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4173
4174         //      Length:
4175         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4176         p2pielen += 2;
4177
4178         //      Value:
4179         //      Country String
4180         p2pie[ p2pielen++ ] = 'X';
4181         p2pie[ p2pielen++ ] = 'X';
4182         
4183         //      The third byte should be set to 0x04.
4184         //      Described in the "Operating Channel Attribute" section.
4185         p2pie[ p2pielen++ ] = 0x04;
4186
4187         //      Operating Class
4188         if ( pwdinfo->operating_channel <= 14 )
4189         {
4190                 //      Operating Class
4191                 p2pie[ p2pielen++ ] = 0x51;
4192         }
4193         else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4194         {
4195                 //      Operating Class
4196                 p2pie[ p2pielen++ ] = 0x73;
4197         }
4198         else
4199         {
4200                 //      Operating Class
4201                 p2pie[ p2pielen++ ] = 0x7c;
4202         }
4203
4204         //      Channel Number
4205         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
4206
4207         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );                
4208
4209 #ifdef CONFIG_WFD
4210         wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4211         pframe += wfdielen;
4212         pattrib->pktlen += wfdielen;
4213 #endif
4214
4215         pattrib->last_txcmdsz = pattrib->pktlen;
4216
4217         dump_mgntframe(padapter, pmgntframe);
4218
4219         return;
4220
4221 }
4222
4223
4224 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
4225 {
4226
4227         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4228         u8                      action = P2P_PUB_ACTION_ACTION;
4229         u32                     p2poui = cpu_to_be32(P2POUI);
4230         u8                      oui_subtype = P2P_GO_NEGO_RESP;
4231         u8                      wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4232         u8                      p2pielen = 0, i;
4233         uint                    wpsielen = 0;
4234         u16                     wps_devicepassword_id = 0x0000;
4235         uint                    wps_devicepassword_id_len = 0;
4236         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4237         u16                     len_channellist_attr = 0;
4238         
4239         struct xmit_frame                       *pmgntframe;
4240         struct pkt_attrib                       *pattrib;
4241         unsigned char                                   *pframe;
4242         struct rtw_ieee80211_hdr        *pwlanhdr;
4243         unsigned short                          *fctrl;
4244         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
4245         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4246         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4247         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
4248
4249 #ifdef CONFIG_WFD
4250         u32                                     wfdielen = 0;
4251 #endif
4252
4253         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4254         {
4255                 return;
4256         }
4257
4258         DBG_871X( "[%s] In, result = %d\n", __FUNCTION__,  result );
4259         //update attribute
4260         pattrib = &pmgntframe->attrib;
4261         update_mgntframe_attrib(padapter, pattrib);
4262
4263         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4264
4265         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4266         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4267
4268         fctrl = &(pwlanhdr->frame_ctl);
4269         *(fctrl) = 0;
4270
4271         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4272         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4273         _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4274
4275         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4276         pmlmeext->mgnt_seq++;
4277         SetFrameSubType(pframe, WIFI_ACTION);
4278
4279         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4280         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4281
4282         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4283         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4284         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4285         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
4286         pwdinfo->negotiation_dialog_token = frame_body[7];      //      The Dialog Token of provisioning discovery request frame.
4287         pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4288
4289         //      Commented by Albert 20110328
4290         //      Try to get the device password ID from the WPS IE of group negotiation request frame
4291         //      WiFi Direct test plan 5.1.15
4292         rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4293         rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4294         wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4295
4296         _rtw_memset( wpsie, 0x00, 255 );
4297         wpsielen = 0;
4298
4299         //      WPS Section
4300         wpsielen = 0;
4301         //      WPS OUI
4302         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4303         wpsielen += 4;
4304
4305         //      WPS version
4306         //      Type:
4307         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4308         wpsielen += 2;
4309
4310         //      Length:
4311         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4312         wpsielen += 2;
4313
4314         //      Value:
4315         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
4316
4317         //      Device Password ID
4318         //      Type:
4319         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4320         wpsielen += 2;
4321
4322         //      Length:
4323         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4324         wpsielen += 2;
4325
4326         //      Value:
4327         if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4328         {
4329                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
4330         }
4331         else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4332         {
4333                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
4334         }
4335         else
4336         {
4337                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
4338         }
4339         wpsielen += 2;
4340
4341         //      Commented by Kurt 20120113
4342         //      If some device wants to do p2p handshake without sending prov_disc_req
4343         //      We have to get peer_req_cm from here.
4344         if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
4345         {
4346                 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4347                 {
4348                         _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
4349                 }
4350                 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4351                 {
4352                         _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );     
4353                 }
4354                 else
4355                 {
4356                         _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );     
4357                 }
4358         }
4359
4360         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4361
4362
4363         //      P2P IE Section.
4364
4365         //      P2P OUI
4366         p2pielen = 0;
4367         p2pie[ p2pielen++ ] = 0x50;
4368         p2pie[ p2pielen++ ] = 0x6F;
4369         p2pie[ p2pielen++ ] = 0x9A;
4370         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
4371
4372         //      Commented by Albert 20100908
4373         //      According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
4374         //      1. Status
4375         //      2. P2P Capability
4376         //      3. Group Owner Intent
4377         //      4. Configuration Timeout
4378         //      5. Operating Channel
4379         //      6. Intended P2P Interface Address
4380         //      7. Channel List
4381         //      8. Device Info
4382         //      9. Group ID     ( Only GO )
4383
4384
4385         //      ToDo:
4386
4387         //      P2P Status
4388         //      Type:
4389         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4390
4391         //      Length:
4392         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4393         p2pielen += 2;
4394
4395         //      Value:
4396         p2pie[ p2pielen++ ] = result;
4397         
4398         //      P2P Capability
4399         //      Type:
4400         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4401
4402         //      Length:
4403         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4404         p2pielen += 2;
4405
4406         //      Value:
4407         //      Device Capability Bitmap, 1 byte
4408
4409         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4410         {
4411                 //      Commented by Albert 2011/03/08
4412                 //      According to the P2P specification
4413                 //      if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
4414                 p2pie[ p2pielen++ ] = 0;
4415         }
4416         else
4417         {
4418                 //      Be group owner or meet the error case
4419                 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4420         }
4421         
4422         //      Group Capability Bitmap, 1 byte
4423         if ( pwdinfo->persistent_supported )
4424         {
4425                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4426         }
4427         else
4428         {
4429                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4430         }
4431
4432         //      Group Owner Intent
4433         //      Type:
4434         p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
4435
4436         //      Length:
4437         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4438         p2pielen += 2;
4439
4440         //      Value:
4441         if ( pwdinfo->peer_intent & 0x01 )
4442         {
4443                 //      Peer's tie breaker bit is 1, our tie breaker bit should be 0
4444                 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
4445         }
4446         else
4447         {
4448                 //      Peer's tie breaker bit is 0, our tie breaker bit should be 1
4449                 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
4450         }
4451
4452
4453         //      Configuration Timeout
4454         //      Type:
4455         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4456
4457         //      Length:
4458         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4459         p2pielen += 2;
4460
4461         //      Value:
4462         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
4463         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
4464
4465         //      Operating Channel
4466         //      Type:
4467         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4468
4469         //      Length:
4470         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4471         p2pielen += 2;
4472
4473         //      Value:
4474         //      Country String
4475         p2pie[ p2pielen++ ] = 'X';
4476         p2pie[ p2pielen++ ] = 'X';
4477         
4478         //      The third byte should be set to 0x04.
4479         //      Described in the "Operating Channel Attribute" section.
4480         p2pie[ p2pielen++ ] = 0x04;
4481
4482         //      Operating Class
4483         if ( pwdinfo->operating_channel <= 14 )
4484         {
4485                 //      Operating Class
4486                 p2pie[ p2pielen++ ] = 0x51;
4487         }
4488         else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4489         {
4490                 //      Operating Class
4491                 p2pie[ p2pielen++ ] = 0x73;
4492         }
4493         else
4494         {
4495                 //      Operating Class
4496                 p2pie[ p2pielen++ ] = 0x7c;
4497         }
4498         
4499         //      Channel Number
4500         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
4501
4502         //      Intended P2P Interface Address  
4503         //      Type:
4504         p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4505
4506         //      Length:
4507         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4508         p2pielen += 2;
4509
4510         //      Value:
4511         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4512         p2pielen += ETH_ALEN;
4513
4514         //      Channel List
4515         //      Type:
4516         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4517
4518         // Country String(3)
4519         // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4520         // + number of channels in all classes
4521         len_channellist_attr = 3
4522            + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4523            + get_reg_classes_full_count(pmlmeext->channel_list);
4524
4525 #ifdef CONFIG_CONCURRENT_MODE
4526         if (check_buddy_fwstate(padapter , _FW_LINKED)
4527                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4528         {
4529                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4530         }
4531         else
4532         {
4533                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4534         }
4535 #else
4536
4537         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4538
4539  #endif
4540         p2pielen += 2;
4541
4542         //      Value:
4543         //      Country String
4544         p2pie[ p2pielen++ ] = 'X';
4545         p2pie[ p2pielen++ ] = 'X';
4546         
4547         //      The third byte should be set to 0x04.
4548         //      Described in the "Operating Channel Attribute" section.
4549         p2pie[ p2pielen++ ] = 0x04;
4550
4551         //      Channel Entry List
4552
4553 #ifdef CONFIG_CONCURRENT_MODE
4554         if (check_buddy_fwstate(padapter , _FW_LINKED)
4555                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4556         {
4557                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
4558                 struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4559
4560                 //      Operating Class
4561                 if ( pbuddy_mlmeext->cur_channel > 14 )
4562                 {
4563                         if ( pbuddy_mlmeext->cur_channel >= 149 )
4564                         {
4565                                 p2pie[ p2pielen++ ] = 0x7c;
4566                         }
4567                         else
4568                         {
4569                                 p2pie[ p2pielen++ ] = 0x73;
4570                         }
4571                 }
4572                 else
4573                 {
4574                         p2pie[ p2pielen++ ] = 0x51;
4575                 }
4576
4577                 //      Number of Channels
4578                 //      Just support 1 channel and this channel is AP's channel
4579                 p2pie[ p2pielen++ ] = 1;
4580
4581                 //      Channel List
4582                 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4583         }
4584         else
4585         {
4586                 int i, j;
4587                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4588                         //      Operating Class
4589                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4590
4591                         //      Number of Channels
4592                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4593
4594                         //      Channel List
4595                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4596                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4597                         }
4598                 }
4599         }
4600 #else // CONFIG_CONCURRENT_MODE
4601         {
4602                 int i, j;
4603                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4604                         //      Operating Class
4605                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4606
4607                         //      Number of Channels
4608                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4609
4610                         //      Channel List
4611                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4612                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4613                         }
4614                 }
4615         }
4616 #endif // CONFIG_CONCURRENT_MODE
4617
4618         
4619         //      Device Info
4620         //      Type:
4621         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4622
4623         //      Length:
4624         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
4625         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4626         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4627         p2pielen += 2;
4628
4629         //      Value:
4630         //      P2P Device Address
4631         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4632         p2pielen += ETH_ALEN;
4633
4634         //      Config Method
4635         //      This field should be big endian. Noted by P2P specification.
4636
4637         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4638
4639         p2pielen += 2;
4640
4641         //      Primary Device Type
4642         //      Category ID
4643         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4644         p2pielen += 2;
4645
4646         //      OUI
4647         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4648         p2pielen += 4;
4649
4650         //      Sub Category ID
4651         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4652         p2pielen += 2;
4653
4654         //      Number of Secondary Device Types
4655         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
4656
4657         //      Device Name
4658         //      Type:
4659         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4660         p2pielen += 2;
4661
4662         //      Length:
4663         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4664         p2pielen += 2;
4665
4666         //      Value:
4667         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4668         p2pielen += pwdinfo->device_name_len;   
4669         
4670         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4671         {
4672                 //      Group ID Attribute
4673                 //      Type:
4674                 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4675
4676                 //      Length:
4677                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4678                 p2pielen += 2;
4679
4680                 //      Value:
4681                 //      p2P Device Address
4682                 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4683                 p2pielen += ETH_ALEN;
4684
4685                 //      SSID
4686                 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4687                 p2pielen += pwdinfo->nego_ssidlen;
4688                 
4689         }
4690         
4691         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
4692         
4693 #ifdef CONFIG_WFD
4694         wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4695         pframe += wfdielen;
4696         pattrib->pktlen += wfdielen;
4697 #endif
4698
4699         pattrib->last_txcmdsz = pattrib->pktlen;
4700
4701         dump_mgntframe(padapter, pmgntframe);
4702
4703         return;
4704
4705 }
4706
4707 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
4708 {
4709
4710         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4711         u8                      action = P2P_PUB_ACTION_ACTION;
4712         u32                     p2poui = cpu_to_be32(P2POUI);
4713         u8                      oui_subtype = P2P_GO_NEGO_CONF;
4714         u8                      wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4715         u8                      wpsielen = 0, p2pielen = 0;
4716         
4717         struct xmit_frame                       *pmgntframe;
4718         struct pkt_attrib                       *pattrib;
4719         unsigned char                                   *pframe;
4720         struct rtw_ieee80211_hdr        *pwlanhdr;
4721         unsigned short                          *fctrl;
4722         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
4723         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4724         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4725         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
4726 #ifdef CONFIG_WFD
4727         u32                                     wfdielen = 0;
4728 #endif
4729
4730         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4731         {
4732                 return;
4733         }
4734
4735         DBG_871X( "[%s] In\n", __FUNCTION__ );
4736         //update attribute
4737         pattrib = &pmgntframe->attrib;
4738         update_mgntframe_attrib(padapter, pattrib);
4739
4740         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4741
4742         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4743         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4744
4745         fctrl = &(pwlanhdr->frame_ctl);
4746         *(fctrl) = 0;
4747
4748         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4749         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4750         _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4751
4752         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4753         pmlmeext->mgnt_seq++;
4754         SetFrameSubType(pframe, WIFI_ACTION);
4755
4756         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4757         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4758
4759         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4760         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4761         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4762         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
4763         pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4764
4765         
4766
4767         //      P2P IE Section.
4768
4769         //      P2P OUI
4770         p2pielen = 0;
4771         p2pie[ p2pielen++ ] = 0x50;
4772         p2pie[ p2pielen++ ] = 0x6F;
4773         p2pie[ p2pielen++ ] = 0x9A;
4774         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
4775
4776         //      Commented by Albert 20110306
4777         //      According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
4778         //      1. Status
4779         //      2. P2P Capability
4780         //      3. Operating Channel
4781         //      4. Channel List
4782         //      5. Group ID     ( if this WiFi is GO )
4783
4784         //      P2P Status
4785         //      Type:
4786         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4787
4788         //      Length:
4789         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4790         p2pielen += 2;
4791
4792         //      Value:
4793         p2pie[ p2pielen++ ] = result;
4794
4795         //      P2P Capability
4796         //      Type:
4797         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4798
4799         //      Length:
4800         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4801         p2pielen += 2;
4802
4803         //      Value:
4804         //      Device Capability Bitmap, 1 byte
4805         p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4806         
4807         //      Group Capability Bitmap, 1 byte
4808         if ( pwdinfo->persistent_supported )
4809         {
4810                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4811         }
4812         else
4813         {
4814                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4815         }
4816
4817
4818         //      Operating Channel
4819         //      Type:
4820         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4821
4822         //      Length:
4823         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4824         p2pielen += 2;
4825
4826         //      Value:
4827         //      Country String
4828         p2pie[ p2pielen++ ] = 'X';
4829         p2pie[ p2pielen++ ] = 'X';
4830         
4831         //      The third byte should be set to 0x04.
4832         //      Described in the "Operating Channel Attribute" section.
4833         p2pie[ p2pielen++ ] = 0x04;
4834
4835
4836         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4837         {
4838                 if ( pwdinfo->peer_operating_ch <= 14 )
4839                 {
4840                         //      Operating Class
4841                         p2pie[ p2pielen++ ] = 0x51;
4842                 }
4843                 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4844                 {
4845                         //      Operating Class
4846                         p2pie[ p2pielen++ ] = 0x73;
4847                 }
4848                 else
4849                 {
4850                         //      Operating Class
4851                         p2pie[ p2pielen++ ] = 0x7c;
4852                 }
4853                 
4854                 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4855         }
4856         else
4857         {
4858                 if ( pwdinfo->operating_channel <= 14 )
4859                 {
4860                         //      Operating Class
4861                         p2pie[ p2pielen++ ] = 0x51;
4862                 }
4863                 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4864                 {
4865                         //      Operating Class
4866                         p2pie[ p2pielen++ ] = 0x73;
4867                 }
4868                 else
4869                 {
4870                         //      Operating Class
4871                         p2pie[ p2pielen++ ] = 0x7c;
4872                 }
4873                 
4874                 //      Channel Number
4875                 p2pie[ p2pielen++ ] = pwdinfo->operating_channel;               //      Use the listen channel as the operating channel
4876         }
4877
4878
4879         //      Channel List
4880         //      Type:
4881         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4882
4883         *(u16*) ( p2pie + p2pielen ) = 6;
4884         p2pielen += 2;
4885
4886         //      Country String
4887         p2pie[ p2pielen++ ] = 'X';
4888         p2pie[ p2pielen++ ] = 'X';
4889         
4890         //      The third byte should be set to 0x04.
4891         //      Described in the "Operating Channel Attribute" section.
4892         p2pie[ p2pielen++ ] = 0x04;
4893
4894         //      Value:
4895         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4896         {
4897                 if ( pwdinfo->peer_operating_ch <= 14 )
4898                 {
4899                         //      Operating Class
4900                         p2pie[ p2pielen++ ] = 0x51;
4901                 }
4902                 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4903                 {
4904                         //      Operating Class
4905                         p2pie[ p2pielen++ ] = 0x73;
4906                 }
4907                 else
4908                 {
4909                         //      Operating Class
4910                         p2pie[ p2pielen++ ] = 0x7c;
4911                 }
4912                 p2pie[ p2pielen++ ] = 1;
4913                 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4914         }
4915         else
4916         {
4917                 if ( pwdinfo->operating_channel <= 14 )
4918                 {
4919                         //      Operating Class
4920                         p2pie[ p2pielen++ ] = 0x51;
4921                 }
4922                 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4923                 {
4924                         //      Operating Class
4925                         p2pie[ p2pielen++ ] = 0x73;
4926                 }
4927                 else
4928                 {
4929                         //      Operating Class
4930                         p2pie[ p2pielen++ ] = 0x7c;
4931                 }
4932                 
4933                 //      Channel Number
4934                 p2pie[ p2pielen++ ] = 1;
4935                 p2pie[ p2pielen++ ] = pwdinfo->operating_channel;               //      Use the listen channel as the operating channel
4936         }
4937
4938         if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4939         {
4940                 //      Group ID Attribute
4941                 //      Type:
4942                 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4943
4944                 //      Length:
4945                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4946                 p2pielen += 2;
4947
4948                 //      Value:
4949                 //      p2P Device Address
4950                 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4951                 p2pielen += ETH_ALEN;
4952
4953                 //      SSID
4954                 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4955                 p2pielen += pwdinfo->nego_ssidlen;
4956         }
4957         
4958         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4959         
4960 #ifdef CONFIG_WFD
4961         wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4962         pframe += wfdielen;
4963         pattrib->pktlen += wfdielen;
4964 #endif
4965
4966         pattrib->last_txcmdsz = pattrib->pktlen;
4967
4968         dump_mgntframe(padapter, pmgntframe);
4969
4970         return;
4971
4972 }
4973
4974 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
4975 {
4976
4977         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4978         u8                      action = P2P_PUB_ACTION_ACTION;
4979         u32                     p2poui = cpu_to_be32(P2POUI);
4980         u8                      oui_subtype = P2P_INVIT_REQ;
4981         u8                      p2pie[ 255 ] = { 0x00 };
4982         u8                      p2pielen = 0, i;
4983         u8                      dialogToken = 3;
4984         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4985         u16                     len_channellist_attr = 0;       
4986 #ifdef CONFIG_WFD
4987         u32                                     wfdielen = 0;
4988 #endif
4989 #ifdef CONFIG_CONCURRENT_MODE
4990         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
4991         struct wifidirect_info  *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4992         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4993         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4994 #endif
4995
4996         struct xmit_frame                       *pmgntframe;
4997         struct pkt_attrib                       *pattrib;
4998         unsigned char                                   *pframe;
4999         struct rtw_ieee80211_hdr        *pwlanhdr;
5000         unsigned short                          *fctrl;
5001         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
5002         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5003         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5004         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
5005
5006
5007         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5008         {
5009                 return;
5010         }
5011
5012         //update attribute
5013         pattrib = &pmgntframe->attrib;
5014         update_mgntframe_attrib(padapter, pattrib);
5015
5016         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5017
5018         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5019         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5020
5021         fctrl = &(pwlanhdr->frame_ctl);
5022         *(fctrl) = 0;
5023
5024         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5025         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5026         _rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
5027
5028         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5029         pmlmeext->mgnt_seq++;
5030         SetFrameSubType(pframe, WIFI_ACTION);
5031
5032         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5033         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5034
5035         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5036         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5037         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5038         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
5039         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5040
5041         //      P2P IE Section.
5042
5043         //      P2P OUI
5044         p2pielen = 0;
5045         p2pie[ p2pielen++ ] = 0x50;
5046         p2pie[ p2pielen++ ] = 0x6F;
5047         p2pie[ p2pielen++ ] = 0x9A;
5048         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
5049
5050         //      Commented by Albert 20101011
5051         //      According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
5052         //      1. Configuration Timeout
5053         //      2. Invitation Flags
5054         //      3. Operating Channel    ( Only GO )
5055         //      4. P2P Group BSSID      ( Should be included if I am the GO )
5056         //      5. Channel List
5057         //      6. P2P Group ID
5058         //      7. P2P Device Info
5059
5060         //      Configuration Timeout
5061         //      Type:
5062         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5063
5064         //      Length:
5065         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5066         p2pielen += 2;
5067
5068         //      Value:
5069         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
5070         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
5071
5072         //      Invitation Flags
5073         //      Type:
5074         p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
5075
5076         //      Length:
5077         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5078         p2pielen += 2;
5079
5080         //      Value:
5081         p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
5082
5083
5084         //      Operating Channel
5085         //      Type:
5086         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5087
5088         //      Length:
5089         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5090         p2pielen += 2;
5091
5092         //      Value:
5093         //      Country String
5094         p2pie[ p2pielen++ ] = 'X';
5095         p2pie[ p2pielen++ ] = 'X';
5096         
5097         //      The third byte should be set to 0x04.
5098         //      Described in the "Operating Channel Attribute" section.
5099         p2pie[ p2pielen++ ] = 0x04;
5100
5101         //      Operating Class
5102         if ( pwdinfo->invitereq_info.operating_ch <= 14 )
5103                 p2pie[ p2pielen++ ] = 0x51;
5104         else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
5105                 p2pie[ p2pielen++ ] = 0x73;
5106         else
5107                 p2pie[ p2pielen++ ] = 0x7c;
5108         
5109         //      Channel Number
5110         p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch;     //      operating channel number
5111
5112         if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
5113         {
5114                 //      P2P Group BSSID
5115                 //      Type:
5116                 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5117
5118                 //      Length:
5119                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5120                 p2pielen += 2;
5121
5122                 //      Value:
5123                 //      P2P Device Address for GO
5124                 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5125                 p2pielen += ETH_ALEN;
5126         }
5127
5128         //      Channel List
5129         //      Type:
5130         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5131
5132         
5133         //      Length:
5134         // Country String(3)
5135         // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5136         // + number of channels in all classes
5137         len_channellist_attr = 3
5138            + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5139            + get_reg_classes_full_count(pmlmeext->channel_list);
5140
5141 #ifdef CONFIG_CONCURRENT_MODE
5142         if (check_buddy_fwstate(padapter , _FW_LINKED)
5143                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5144         {
5145                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5146         }
5147         else
5148         {
5149                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5150         }
5151 #else
5152
5153         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5154
5155  #endif
5156         p2pielen += 2;
5157
5158         //      Value:
5159         //      Country String
5160         p2pie[ p2pielen++ ] = 'X';
5161         p2pie[ p2pielen++ ] = 'X';
5162         
5163         //      The third byte should be set to 0x04.
5164         //      Described in the "Operating Channel Attribute" section.
5165         p2pie[ p2pielen++ ] = 0x04;
5166
5167         //      Channel Entry List
5168 #ifdef CONFIG_CONCURRENT_MODE
5169         if (check_buddy_fwstate(padapter, _FW_LINKED)
5170                 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5171         {
5172                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
5173                 struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5174
5175                 //      Operating Class
5176                 if ( pbuddy_mlmeext->cur_channel > 14 )
5177                 {
5178                         if ( pbuddy_mlmeext->cur_channel >= 149 )
5179                         {
5180                                 p2pie[ p2pielen++ ] = 0x7c;
5181                         }
5182                         else
5183                         {
5184                                 p2pie[ p2pielen++ ] = 0x73;
5185                         }
5186                 }
5187                 else
5188                 {
5189                         p2pie[ p2pielen++ ] = 0x51;
5190                 }
5191
5192                 //      Number of Channels
5193                 //      Just support 1 channel and this channel is AP's channel
5194                 p2pie[ p2pielen++ ] = 1;
5195
5196                 //      Channel List
5197                 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5198         }
5199         else
5200         {
5201                 int i, j;
5202                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5203                         //      Operating Class
5204                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5205
5206                         //      Number of Channels
5207                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5208
5209                         //      Channel List
5210                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5211                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5212                         }
5213                 }
5214         }
5215 #else // CONFIG_CONCURRENT_MODE
5216         {
5217                 int i, j;
5218                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5219                         //      Operating Class
5220                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5221
5222                         //      Number of Channels
5223                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5224
5225                         //      Channel List
5226                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5227                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5228                         }
5229                 }
5230         }
5231 #endif // CONFIG_CONCURRENT_MODE
5232
5233
5234         //      P2P Group ID
5235         //      Type:
5236         p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
5237
5238         //      Length:
5239         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
5240         p2pielen += 2;
5241
5242         //      Value:
5243         //      P2P Device Address for GO
5244         _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5245         p2pielen += ETH_ALEN;
5246
5247         //      SSID
5248         _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
5249         p2pielen += pwdinfo->invitereq_info.ssidlen;
5250         
5251
5252         //      Device Info
5253         //      Type:
5254         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
5255
5256         //      Length:
5257         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
5258         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
5259         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
5260         p2pielen += 2;
5261         
5262         //      Value:
5263         //      P2P Device Address
5264         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5265         p2pielen += ETH_ALEN;
5266
5267         //      Config Method
5268         //      This field should be big endian. Noted by P2P specification.
5269         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
5270         p2pielen += 2;
5271
5272         //      Primary Device Type
5273         //      Category ID
5274         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5275         p2pielen += 2;
5276
5277         //      OUI
5278         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
5279         p2pielen += 4;
5280
5281         //      Sub Category ID
5282         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5283         p2pielen += 2;
5284
5285         //      Number of Secondary Device Types
5286         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
5287
5288         //      Device Name
5289         //      Type:
5290         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5291         p2pielen += 2;
5292
5293         //      Length:
5294         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
5295         p2pielen += 2;
5296
5297         //      Value:
5298         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
5299         p2pielen += pwdinfo->device_name_len;
5300                 
5301         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
5302
5303 #ifdef CONFIG_WFD
5304         wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5305         pframe += wfdielen;
5306         pattrib->pktlen += wfdielen;
5307 #endif
5308
5309         pattrib->last_txcmdsz = pattrib->pktlen;
5310
5311         dump_mgntframe(padapter, pmgntframe);
5312
5313         return;
5314
5315 }
5316
5317 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
5318 {
5319
5320         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5321         u8                      action = P2P_PUB_ACTION_ACTION;
5322         u32                     p2poui = cpu_to_be32(P2POUI);
5323         u8                      oui_subtype = P2P_INVIT_RESP;
5324         u8                      p2pie[ 255 ] = { 0x00 };
5325         u8                      p2pielen = 0, i;
5326         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5327         u16                     len_channellist_attr = 0;
5328 #ifdef CONFIG_CONCURRENT_MODE
5329         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
5330         struct wifidirect_info  *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5331         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5332         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5333 #endif  
5334 #ifdef CONFIG_WFD
5335         u32                                     wfdielen = 0;
5336 #endif
5337         
5338         struct xmit_frame                       *pmgntframe;
5339         struct pkt_attrib                       *pattrib;
5340         unsigned char                                   *pframe;
5341         struct rtw_ieee80211_hdr        *pwlanhdr;
5342         unsigned short                          *fctrl;
5343         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
5344         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5345         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5346         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
5347
5348
5349         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5350         {
5351                 return;
5352         }
5353
5354         //update attribute
5355         pattrib = &pmgntframe->attrib;
5356         update_mgntframe_attrib(padapter, pattrib);
5357
5358         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5359
5360         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5361         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5362
5363         fctrl = &(pwlanhdr->frame_ctl);
5364         *(fctrl) = 0;
5365
5366         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5367         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5368         _rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
5369
5370         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5371         pmlmeext->mgnt_seq++;
5372         SetFrameSubType(pframe, WIFI_ACTION);
5373
5374         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5375         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5376
5377         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5378         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5379         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5380         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
5381         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5382
5383         //      P2P IE Section.
5384
5385         //      P2P OUI
5386         p2pielen = 0;
5387         p2pie[ p2pielen++ ] = 0x50;
5388         p2pie[ p2pielen++ ] = 0x6F;
5389         p2pie[ p2pielen++ ] = 0x9A;
5390         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
5391
5392         //      Commented by Albert 20101005
5393         //      According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
5394         //      1. Status
5395         //      2. Configuration Timeout
5396         //      3. Operating Channel    ( Only GO )
5397         //      4. P2P Group BSSID      ( Only GO )
5398         //      5. Channel List
5399
5400         //      P2P Status
5401         //      Type:
5402         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
5403
5404         //      Length:
5405         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5406         p2pielen += 2;
5407
5408         //      Value:
5409         //      When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
5410         //      Sent the event receiving the P2P Invitation Req frame to DMP UI.
5411         //      DMP had to compare the MAC address to find out the profile.
5412         //      So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
5413         //      If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
5414         //      to NB to rebuild the persistent group.
5415         p2pie[ p2pielen++ ] = status_code;
5416         
5417         //      Configuration Timeout
5418         //      Type:
5419         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5420
5421         //      Length:
5422         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5423         p2pielen += 2;
5424
5425         //      Value:
5426         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
5427         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
5428
5429         if( status_code == P2P_STATUS_SUCCESS )
5430         {
5431                 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
5432                 {
5433                         //      The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
5434                         //      In this case, the P2P Invitation response frame should carry the two more P2P attributes.
5435                         //      First one is operating channel attribute.
5436                         //      Second one is P2P Group BSSID attribute.
5437
5438                         //      Operating Channel
5439                         //      Type:
5440                         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5441
5442                         //      Length:
5443                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5444                         p2pielen += 2;
5445
5446                         //      Value:
5447                         //      Country String
5448                         p2pie[ p2pielen++ ] = 'X';
5449                         p2pie[ p2pielen++ ] = 'X';
5450                 
5451                         //      The third byte should be set to 0x04.
5452                         //      Described in the "Operating Channel Attribute" section.
5453                         p2pie[ p2pielen++ ] = 0x04;
5454
5455                         //      Operating Class
5456                         p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
5457                 
5458                         //      Channel Number
5459                         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
5460                         
5461
5462                         //      P2P Group BSSID
5463                         //      Type:
5464                         p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5465
5466                         //      Length:
5467                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5468                         p2pielen += 2;
5469
5470                         //      Value:
5471                         //      P2P Device Address for GO
5472                         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5473                         p2pielen += ETH_ALEN;
5474
5475                 }
5476
5477                 //      Channel List
5478                 //      Type:
5479                 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5480
5481                 //      Length:
5482                 // Country String(3)
5483                 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5484                 // + number of channels in all classes
5485                 len_channellist_attr = 3
5486                         + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5487                         + get_reg_classes_full_count(pmlmeext->channel_list);
5488
5489 #ifdef CONFIG_CONCURRENT_MODE
5490                 if (check_buddy_fwstate(padapter, _FW_LINKED)
5491                         && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5492                 {
5493                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5494                 }
5495                 else
5496                 {
5497                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5498                 }
5499 #else
5500
5501                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5502
5503 #endif
5504                 p2pielen += 2;
5505
5506                 //      Value:
5507                 //      Country String
5508                 p2pie[ p2pielen++ ] = 'X';
5509                 p2pie[ p2pielen++ ] = 'X';
5510
5511                 //      The third byte should be set to 0x04.
5512                 //      Described in the "Operating Channel Attribute" section.
5513                 p2pie[ p2pielen++ ] = 0x04;
5514
5515                 //      Channel Entry List
5516 #ifdef CONFIG_CONCURRENT_MODE
5517                 if (check_buddy_fwstate(padapter , _FW_LINKED)
5518                         && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5519                 {
5520                         _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
5521                         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5522
5523                         //      Operating Class
5524                         if ( pbuddy_mlmeext->cur_channel > 14 )
5525                         {
5526                                 if ( pbuddy_mlmeext->cur_channel >= 149 )
5527                                 {
5528                                         p2pie[ p2pielen++ ] = 0x7c;
5529                                 }
5530                                 else
5531                                 {
5532                                         p2pie[ p2pielen++ ] = 0x73;
5533                                 }
5534                         }
5535                         else
5536                         {
5537                                 p2pie[ p2pielen++ ] = 0x51;
5538                         }
5539
5540                         //      Number of Channels
5541                         //      Just support 1 channel and this channel is AP's channel
5542                         p2pie[ p2pielen++ ] = 1;
5543
5544                         //      Channel List
5545                         p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5546                 }
5547                 else
5548                 {
5549                         int i, j;
5550                         for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5551                                 //      Operating Class
5552                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5553
5554                                 //      Number of Channels
5555                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5556
5557                                 //      Channel List
5558                                 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5559                                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5560                                 }
5561                         }
5562                 }
5563 #else // CONFIG_CONCURRENT_MODE
5564                 {
5565                         int i, j;
5566                         for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5567                                 //      Operating Class
5568                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5569
5570                                 //      Number of Channels
5571                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5572
5573                                 //      Channel List
5574                                 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5575                                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5576                                 }
5577                         }
5578                 }
5579 #endif // CONFIG_CONCURRENT_MODE
5580         }
5581                 
5582         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
5583         
5584 #ifdef CONFIG_WFD
5585         wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5586         pframe += wfdielen;
5587         pattrib->pktlen += wfdielen;
5588 #endif
5589
5590         pattrib->last_txcmdsz = pattrib->pktlen;
5591
5592         dump_mgntframe(padapter, pmgntframe);
5593
5594         return;
5595
5596 }
5597
5598 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
5599 {
5600         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5601         u8                      action = P2P_PUB_ACTION_ACTION;
5602         u8                      dialogToken = 1;
5603         u32                     p2poui = cpu_to_be32(P2POUI);
5604         u8                      oui_subtype = P2P_PROVISION_DISC_REQ;
5605         u8                      wpsie[ 100 ] = { 0x00 };
5606         u8                      wpsielen = 0;
5607         u32                     p2pielen = 0;
5608 #ifdef CONFIG_WFD
5609         u32                                     wfdielen = 0;
5610 #endif
5611         
5612         struct xmit_frame                       *pmgntframe;
5613         struct pkt_attrib                       *pattrib;
5614         unsigned char                                   *pframe;
5615         struct rtw_ieee80211_hdr        *pwlanhdr;
5616         unsigned short                          *fctrl;
5617         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
5618         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5619         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5620         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
5621
5622
5623         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5624         {
5625                 return;
5626         }
5627
5628         DBG_871X( "[%s] In\n", __FUNCTION__ );
5629         //update attribute
5630         pattrib = &pmgntframe->attrib;
5631         update_mgntframe_attrib(padapter, pattrib);
5632
5633         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5634
5635         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5636         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5637
5638         fctrl = &(pwlanhdr->frame_ctl);
5639         *(fctrl) = 0;
5640
5641         _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5642         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5643         _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5644
5645         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5646         pmlmeext->mgnt_seq++;
5647         SetFrameSubType(pframe, WIFI_ACTION);
5648
5649         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5650         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5651
5652         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5653         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5654         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5655         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
5656         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));               
5657
5658         p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
5659
5660         pframe += p2pielen;
5661         pattrib->pktlen += p2pielen;
5662
5663         wpsielen = 0;
5664         //      WPS OUI
5665         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5666         wpsielen += 4;
5667
5668         //      WPS version
5669         //      Type:
5670         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5671         wpsielen += 2;
5672
5673         //      Length:
5674         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5675         wpsielen += 2;
5676
5677         //      Value:
5678         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
5679
5680         //      Config Method
5681         //      Type:
5682         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5683         wpsielen += 2;
5684
5685         //      Length:
5686         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5687         wpsielen += 2;
5688
5689         //      Value:
5690         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
5691         wpsielen += 2;
5692
5693         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5694
5695
5696 #ifdef CONFIG_WFD
5697         wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5698         pframe += wfdielen;
5699         pattrib->pktlen += wfdielen;
5700 #endif
5701
5702         pattrib->last_txcmdsz = pattrib->pktlen;
5703
5704         dump_mgntframe(padapter, pmgntframe);
5705
5706         return;
5707
5708 }
5709
5710
5711 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
5712 {
5713         u8 i, match_result = 0;
5714
5715         DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5716                     peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
5717         
5718         for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
5719         {
5720                DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5721                             profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);             
5722                 if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
5723                 {
5724                         match_result = 1;
5725                         DBG_871X( "[%s] Match!\n", __FUNCTION__ );
5726                         break;
5727                 }
5728         }
5729         
5730         return (match_result );
5731 }
5732
5733 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5734 {
5735         struct xmit_frame                       *pmgntframe;
5736         struct pkt_attrib                       *pattrib;
5737         unsigned char                                   *pframe;
5738         struct rtw_ieee80211_hdr        *pwlanhdr;
5739         unsigned short                          *fctrl; 
5740         unsigned char                                   *mac;
5741         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
5742         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5743         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
5744         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5745         //WLAN_BSSID_EX                 *cur_network = &(pmlmeinfo->network);
5746         u16                                     beacon_interval = 100;
5747         u16                                     capInfo = 0;
5748         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
5749         u8                                      wpsie[255] = { 0x00 };
5750         u32                                     wpsielen = 0, p2pielen = 0;
5751 #ifdef CONFIG_WFD
5752         u32                                     wfdielen = 0;
5753 #endif
5754 #ifdef CONFIG_INTEL_WIDI
5755         u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5756 #endif //CONFIG_INTEL_WIDI
5757
5758         //DBG_871X("%s\n", __FUNCTION__);
5759         
5760         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5761         {
5762                 return;
5763         }
5764         
5765         //update attribute
5766         pattrib = &pmgntframe->attrib;
5767         update_mgntframe_attrib(padapter, pattrib);     
5768         
5769         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5770                 
5771         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5772         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
5773         
5774         mac = adapter_mac_addr(padapter);
5775         
5776         fctrl = &(pwlanhdr->frame_ctl);
5777         *(fctrl) = 0;
5778         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5779         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5780         
5781         //      Use the device address for BSSID field. 
5782         _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5783
5784         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5785         pmlmeext->mgnt_seq++;
5786         SetFrameSubType(fctrl, WIFI_PROBERSP);
5787         
5788         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5789         pattrib->pktlen = pattrib->hdrlen;
5790         pframe += pattrib->hdrlen;
5791
5792         //timestamp will be inserted by hardware
5793         pframe += 8;
5794         pattrib->pktlen += 8;
5795
5796         // beacon interval: 2 bytes
5797         _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2); 
5798         pframe += 2;
5799         pattrib->pktlen += 2;
5800
5801         //      capability info: 2 bytes
5802         //      ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
5803         capInfo |= cap_ShortPremble;
5804         capInfo |= cap_ShortSlot;
5805         
5806         _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5807         pframe += 2;
5808         pattrib->pktlen += 2;
5809
5810
5811         // SSID
5812         pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5813
5814         // supported rates...
5815         //      Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5816         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5817
5818         // DS parameter set
5819         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5820
5821 #ifdef CONFIG_IOCTL_CFG80211
5822         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5823         {
5824                 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
5825                 {
5826                         //WPS IE
5827                         _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5828                         pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5829                         pframe += pmlmepriv->wps_probe_resp_ie_len;
5830
5831                         //P2P IE
5832                         _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5833                         pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5834                         pframe += pmlmepriv->p2p_probe_resp_ie_len;
5835                 }
5836         }
5837         else
5838 #endif //CONFIG_IOCTL_CFG80211          
5839         {
5840
5841                 //      Todo: WPS IE
5842                 //      Noted by Albert 20100907
5843                 //      According to the WPS specification, all the WPS attribute is presented by Big Endian.
5844
5845                 wpsielen = 0;
5846                 //      WPS OUI
5847                 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5848                 wpsielen += 4;
5849
5850                 //      WPS version
5851                 //      Type:
5852                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5853                 wpsielen += 2;
5854
5855                 //      Length:
5856                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5857                 wpsielen += 2;
5858
5859                 //      Value:
5860                 wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
5861
5862 #ifdef CONFIG_INTEL_WIDI
5863                 //      Commented by Kurt
5864                 //      Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
5865                 if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE 
5866                         || pmlmepriv->num_p2p_sdt != 0 )
5867                 {
5868                         //Sec dev type
5869                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
5870                         wpsielen += 2;
5871
5872                         //      Length:
5873                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5874                         wpsielen += 2;
5875
5876                         //      Value:
5877                         //      Category ID
5878                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
5879                         wpsielen += 2;
5880
5881                         //      OUI
5882                         *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
5883                         wpsielen += 4;
5884
5885                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
5886                         wpsielen += 2;
5887
5888                         if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
5889                         {
5890                                 //      Vendor Extension
5891                                 _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
5892                                 wpsielen += L2SDTA_SERVICE_VE_LEN;
5893                         }
5894                 }
5895 #endif //CONFIG_INTEL_WIDI
5896
5897                 //      WiFi Simple Config State
5898                 //      Type:
5899                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
5900                 wpsielen += 2;
5901
5902                 //      Length:
5903                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5904                 wpsielen += 2;
5905
5906                 //      Value:
5907                 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;   //      Not Configured.
5908
5909                 //      Response Type
5910                 //      Type:
5911                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
5912                 wpsielen += 2;
5913
5914                 //      Length:
5915                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5916                 wpsielen += 2;
5917
5918                 //      Value:
5919                 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5920
5921                 //      UUID-E
5922                 //      Type:
5923                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5924                 wpsielen += 2;
5925
5926                 //      Length:
5927                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5928                 wpsielen += 2;
5929
5930                 //      Value:
5931                 if (pwdinfo->external_uuid == 0) {
5932                         _rtw_memset( wpsie + wpsielen, 0x0, 16 );
5933                         _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5934                 } else {
5935                         _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5936                 }
5937                 wpsielen += 0x10;
5938
5939                 //      Manufacturer
5940                 //      Type:
5941                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
5942                 wpsielen += 2;
5943
5944                 //      Length:
5945                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
5946                 wpsielen += 2;
5947
5948                 //      Value:
5949                 _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
5950                 wpsielen += 7;
5951
5952                 //      Model Name
5953                 //      Type:
5954                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
5955                 wpsielen += 2;
5956
5957                 //      Length:
5958                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
5959                 wpsielen += 2;  
5960
5961                 //      Value:
5962                 _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
5963                 wpsielen += 6;
5964
5965                 //      Model Number
5966                 //      Type:
5967                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
5968                 wpsielen += 2;
5969
5970                 //      Length:
5971                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5972                 wpsielen += 2;
5973
5974                 //      Value:
5975                 wpsie[ wpsielen++ ] = 0x31;             //      character 1
5976
5977                 //      Serial Number
5978                 //      Type:
5979                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
5980                 wpsielen += 2;
5981
5982                 //      Length:
5983                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
5984                 wpsielen += 2;
5985
5986                 //      Value:
5987                 _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
5988                 wpsielen += ETH_ALEN;
5989
5990                 //      Primary Device Type
5991                 //      Type:
5992                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5993                 wpsielen += 2;
5994
5995                 //      Length:
5996                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5997                 wpsielen += 2;
5998
5999                 //      Value:
6000                 //      Category ID
6001                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
6002                 wpsielen += 2;
6003
6004                 //      OUI
6005                 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6006                 wpsielen += 4;
6007
6008                 //      Sub Category ID
6009                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
6010                 wpsielen += 2;
6011
6012                 //      Device Name
6013                 //      Type:
6014                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6015                 wpsielen += 2;
6016
6017                 //      Length:
6018                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6019                 wpsielen += 2;
6020
6021                 //      Value:
6022                 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6023                 wpsielen += pwdinfo->device_name_len;
6024
6025                 //      Config Method
6026                 //      Type:
6027                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6028                 wpsielen += 2;
6029
6030                 //      Length:
6031                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6032                 wpsielen += 2;
6033
6034                 //      Value:
6035                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6036                 wpsielen += 2;
6037                 
6038
6039                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6040                 
6041
6042                 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6043                 pframe += p2pielen;
6044                 pattrib->pktlen += p2pielen;
6045         }
6046
6047 #ifdef CONFIG_WFD
6048         wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6049         pframe += wfdielen;
6050         pattrib->pktlen += wfdielen;
6051 #endif
6052
6053         pattrib->last_txcmdsz = pattrib->pktlen;
6054         
6055
6056         dump_mgntframe(padapter, pmgntframe);
6057         
6058         return;
6059
6060 }
6061
6062 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6063 {
6064         int ret = _FAIL;
6065         struct xmit_frame               *pmgntframe;
6066         struct pkt_attrib               *pattrib;
6067         unsigned char                   *pframe;
6068         struct rtw_ieee80211_hdr        *pwlanhdr;
6069         unsigned short          *fctrl;
6070         unsigned char                   *mac;
6071         unsigned char                   bssrate[NumRates];
6072         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
6073         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
6074         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
6075         int     bssrate_len = 0;
6076         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6077         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo); 
6078         u8                                      wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
6079         u16                                     wpsielen = 0, p2pielen = 0;
6080 #ifdef CONFIG_WFD
6081         u32                                     wfdielen = 0;
6082 #endif
6083
6084         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6085
6086
6087         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6088         {
6089                 goto exit;
6090         }
6091
6092         //update attribute
6093         pattrib = &pmgntframe->attrib;
6094         update_mgntframe_attrib(padapter, pattrib);
6095
6096
6097         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6098
6099         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6100         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6101
6102         mac = adapter_mac_addr(padapter);
6103
6104         fctrl = &(pwlanhdr->frame_ctl);
6105         *(fctrl) = 0;
6106
6107         if (da) {
6108                 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6109                 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6110         } else {
6111                 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
6112                 {
6113                         //      This two flags will be set when this is only the P2P client mode.
6114                         _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6115                         _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6116                 }
6117                 else
6118                 {
6119                         //      broadcast probe request frame
6120                         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6121                         _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6122                 }
6123         }
6124         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6125
6126         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6127         pmlmeext->mgnt_seq++;
6128         SetFrameSubType(pframe, WIFI_PROBEREQ);
6129
6130         pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6131         pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6132
6133         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6134         {
6135                 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6136         }
6137         else
6138         {
6139                 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6140         }
6141         //      Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
6142         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6143
6144 #ifdef CONFIG_IOCTL_CFG80211
6145         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
6146         {
6147                 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
6148                 {
6149                         //WPS IE
6150                         _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6151                         pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6152                         pframe += pmlmepriv->wps_probe_req_ie_len;
6153
6154                         //P2P IE
6155                         _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6156                         pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6157                         pframe += pmlmepriv->p2p_probe_req_ie_len;
6158                 }
6159         }
6160         else
6161 #endif //CONFIG_IOCTL_CFG80211
6162         {
6163
6164                 //      WPS IE
6165                 //      Noted by Albert 20110221
6166                 //      According to the WPS specification, all the WPS attribute is presented by Big Endian.
6167
6168                 wpsielen = 0;
6169                 //      WPS OUI
6170                 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
6171                 wpsielen += 4;
6172
6173                 //      WPS version
6174                 //      Type:
6175                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
6176                 wpsielen += 2;
6177
6178                 //      Length:
6179                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
6180                 wpsielen += 2;
6181
6182                 //      Value:
6183                 wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
6184
6185                 if( pmlmepriv->wps_probe_req_ie == NULL )
6186                 {
6187                         //      UUID-E
6188                         //      Type:
6189                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
6190                         wpsielen += 2;
6191
6192                         //      Length:
6193                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
6194                         wpsielen += 2;
6195
6196                         //      Value:
6197                         if (pwdinfo->external_uuid == 0) {
6198                                 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
6199                                 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6200                         } else {
6201                                 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
6202                         }
6203                         wpsielen += 0x10;
6204
6205                         //      Config Method
6206                         //      Type:
6207                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6208                         wpsielen += 2;
6209
6210                         //      Length:
6211                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6212                         wpsielen += 2;
6213
6214                         //      Value:
6215                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6216                         wpsielen += 2;
6217                 }
6218
6219                 //      Device Name
6220                 //      Type:
6221                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6222                 wpsielen += 2;
6223
6224                 //      Length:
6225                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6226                 wpsielen += 2;
6227
6228                 //      Value:
6229                 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6230                 wpsielen += pwdinfo->device_name_len;
6231
6232                 //      Primary Device Type
6233                 //      Type:
6234                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6235                 wpsielen += 2;
6236
6237                 //      Length:
6238                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6239                 wpsielen += 2;
6240
6241                 //      Value:
6242                 //      Category ID
6243                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
6244                 wpsielen += 2;
6245
6246                 //      OUI
6247                 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6248                 wpsielen += 4;
6249
6250                 //      Sub Category ID
6251                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
6252                 wpsielen += 2;
6253
6254                 //      Device Password ID
6255                 //      Type:
6256                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
6257                 wpsielen += 2;
6258
6259                 //      Length:
6260                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6261                 wpsielen += 2;
6262
6263                 //      Value:
6264                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );  //      Registrar-specified
6265                 wpsielen += 2;  
6266
6267                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6268                 
6269                 //      P2P OUI
6270                 p2pielen = 0;
6271                 p2pie[ p2pielen++ ] = 0x50;
6272                 p2pie[ p2pielen++ ] = 0x6F;
6273                 p2pie[ p2pielen++ ] = 0x9A;
6274                 p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
6275
6276                 //      Commented by Albert 20110221
6277                 //      According to the P2P Specification, the probe request frame should contain 5 P2P attributes
6278                 //      1. P2P Capability
6279                 //      2. P2P Device ID if this probe request wants to find the specific P2P device
6280                 //      3. Listen Channel
6281                 //      4. Extended Listen Timing
6282                 //      5. Operating Channel if this WiFi is working as the group owner now
6283
6284                 //      P2P Capability
6285                 //      Type:
6286                 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
6287
6288                 //      Length:
6289                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
6290                 p2pielen += 2;
6291
6292                 //      Value:
6293                 //      Device Capability Bitmap, 1 byte
6294                 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
6295                 
6296                 //      Group Capability Bitmap, 1 byte
6297                 if ( pwdinfo->persistent_supported )
6298                         p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6299                 else
6300                         p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
6301
6302                 //      Listen Channel
6303                 //      Type:
6304                 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
6305
6306                 //      Length:
6307                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6308                 p2pielen += 2;
6309
6310                 //      Value:
6311                 //      Country String
6312                 p2pie[ p2pielen++ ] = 'X';
6313                 p2pie[ p2pielen++ ] = 'X';
6314                 
6315                 //      The third byte should be set to 0x04.
6316                 //      Described in the "Operating Channel Attribute" section.
6317                 p2pie[ p2pielen++ ] = 0x04;
6318
6319                 //      Operating Class
6320                 p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
6321                 
6322                 //      Channel Number
6323                 p2pie[ p2pielen++ ] = pwdinfo->listen_channel;  //      listen channel
6324                 
6325
6326                 //      Extended Listen Timing
6327                 //      Type:
6328                 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
6329
6330                 //      Length:
6331                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
6332                 p2pielen += 2;
6333
6334                 //      Value:
6335                 //      Availability Period
6336                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6337                 p2pielen += 2;
6338
6339                 //      Availability Interval
6340                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6341                 p2pielen += 2;
6342
6343                 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
6344                 {
6345                         //      Operating Channel (if this WiFi is working as the group owner now)
6346                         //      Type:
6347                         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
6348
6349                         //      Length:
6350                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6351                         p2pielen += 2;
6352
6353                         //      Value:
6354                         //      Country String
6355                         p2pie[ p2pielen++ ] = 'X';
6356                         p2pie[ p2pielen++ ] = 'X';
6357                 
6358                         //      The third byte should be set to 0x04.
6359                         //      Described in the "Operating Channel Attribute" section.
6360                         p2pie[ p2pielen++ ] = 0x04;
6361
6362                         //      Operating Class
6363                         p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
6364                 
6365                         //      Channel Number
6366                         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
6367                         
6368                 }
6369                 
6370                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );        
6371
6372         }
6373
6374 #ifdef CONFIG_WFD
6375         wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6376         pframe += wfdielen;
6377         pattrib->pktlen += wfdielen;
6378 #endif
6379
6380         pattrib->last_txcmdsz = pattrib->pktlen;
6381
6382         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6383
6384         if (wait_ack) {
6385                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6386         } else {
6387                 dump_mgntframe(padapter, pmgntframe);
6388                 ret = _SUCCESS;
6389         }
6390
6391 exit:
6392         return ret;
6393 }
6394
6395 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6396 {
6397         _issue_probereq_p2p(adapter, da, _FALSE);
6398 }
6399
6400 /*
6401  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6402  * 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
6403  * try_cnt means the maximal TX count to try
6404  */
6405 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6406 {
6407         int ret;
6408         int i = 0;
6409         u32 start = rtw_get_current_time();
6410
6411         do
6412         {
6413                 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
6414
6415                 i++;
6416
6417                 if (RTW_CANNOT_RUN(adapter))
6418                         break;
6419
6420                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6421                         rtw_msleep_os(wait_ms);
6422
6423         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6424
6425         if (ret != _FAIL) {
6426                 ret = _SUCCESS;
6427                 #ifndef DBG_XMIT_ACK
6428                 goto exit;
6429                 #endif
6430         }
6431
6432         if (try_cnt && wait_ms) {
6433                 if (da)
6434                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6435                                 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6436                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6437                 else
6438                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6439                                 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6440                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6441         }
6442 exit:
6443         return ret;
6444 }
6445
6446 #endif //CONFIG_P2P
6447
6448 s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
6449 {
6450         _adapter *adapter = rframe->u.hdr.adapter;
6451         struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6452         u8 *frame = rframe->u.hdr.rx_data;
6453         u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num&0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
6454         u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
6455
6456         if (GetRetry(frame)) {
6457                 if ((seq_ctrl == mlmeext->action_public_rxseq)
6458                         && (token == mlmeext->action_public_dialog_token)
6459                 ) {
6460                         DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6461                                 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6462                         return _FAIL;
6463                 }
6464         }
6465
6466         /* TODO: per sta seq & token */
6467         mlmeext->action_public_rxseq = seq_ctrl;
6468         mlmeext->action_public_dialog_token = token;
6469
6470         return _SUCCESS;
6471 }
6472
6473 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6474 {
6475         _adapter *padapter = precv_frame->u.hdr.adapter;
6476         u8 *pframe = precv_frame->u.hdr.rx_data;
6477         uint len = precv_frame->u.hdr.len;
6478         u8 *frame_body;
6479 #ifdef CONFIG_P2P
6480         u8 *p2p_ie;
6481         u32     p2p_ielen, wps_ielen;
6482         struct  wifidirect_info *pwdinfo = &( padapter->wdinfo );
6483         u8      result = P2P_STATUS_SUCCESS;
6484         u8      empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6485         u8 *merged_p2pie = NULL;
6486         u32 merged_p2p_ielen= 0;
6487 #endif //CONFIG_P2P
6488
6489         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6490
6491 #ifdef CONFIG_P2P
6492         _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
6493 #ifdef CONFIG_IOCTL_CFG80211
6494         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6495         {
6496                 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
6497         }
6498         else
6499 #endif //CONFIG_IOCTL_CFG80211
6500         {
6501                 //      Do nothing if the driver doesn't enable the P2P function.
6502                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6503                         return _SUCCESS;
6504
6505                 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6506
6507                 switch( frame_body[ 6 ] )//OUI Subtype
6508                 {
6509                         case P2P_GO_NEGO_REQ:
6510                         {
6511                                 DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6512                                 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
6513
6514                                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6515                                 {
6516                                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6517                                 }
6518
6519                                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6520                                 {
6521                                         //      Commented by Albert 20110526
6522                                         //      In this case, this means the previous nego fail doesn't be reset yet.
6523                                         _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6524                                         //      Restore the previous p2p state
6525                                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6526                                         DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );                                                
6527                                 }                                       
6528 #ifdef CONFIG_CONCURRENT_MODE
6529                                 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
6530                                 {
6531                                         _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6532                                 }
6533 #endif // CONFIG_CONCURRENT_MODE
6534
6535                                 //      Commented by Kurt 20110902
6536                                 //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6537                                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6538                                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6539
6540                                 //      Commented by Kurt 20120113
6541                                 //      Get peer_dev_addr here if peer doesn't issue prov_disc frame.
6542                                 if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
6543                                         _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6544
6545                                 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
6546                                 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
6547 #ifdef CONFIG_INTEL_WIDI
6548                                 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6549                                         padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6550                                         _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6551                                         intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6552                                 }
6553 #endif //CONFIG_INTEL_WIDI
6554
6555                                 //      Commented by Albert 20110718
6556                                 //      No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
6557 #ifdef CONFIG_CONCURRENT_MODE
6558                                 //      Commented by Albert 20120107
6559                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6560 #else // CONFIG_CONCURRENT_MODE
6561                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6562 #endif // CONFIG_CONCURRENT_MODE
6563                                 break;                                  
6564                         }
6565                         case P2P_GO_NEGO_RESP:
6566                         {
6567                                 DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6568
6569                                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6570                                 {
6571                                         //      Commented by Albert 20110425
6572                                         //      The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
6573                                         _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6574                                         pwdinfo->nego_req_info.benable = _FALSE;
6575                                         result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
6576                                         issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
6577                                         if ( P2P_STATUS_SUCCESS == result )
6578                                         {
6579                                                 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6580                                                 {
6581                                                         pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6582                                                         #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6583                                                         pwdinfo->p2p_info.operation_ch[ 1 ] = 1;        //Check whether GO is operating in channel 1;
6584                                                         pwdinfo->p2p_info.operation_ch[ 2 ] = 6;        //Check whether GO is operating in channel 6;
6585                                                         pwdinfo->p2p_info.operation_ch[ 3 ] = 11;       //Check whether GO is operating in channel 11;
6586                                                         #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6587                                                         pwdinfo->p2p_info.scan_op_ch_only = 1;
6588                                                         _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6589                                                 }
6590                                         }
6591
6592                                         //      Reset the dialog token for group negotiation frames.
6593                                         pwdinfo->negotiation_dialog_token = 1;
6594
6595                                         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6596                                         {
6597                                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6598                                         }
6599                                 }
6600                                 else
6601                                 {
6602                                         DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6603                                 }
6604                                 
6605                                 break;
6606                         }
6607                         case P2P_GO_NEGO_CONF:
6608                         {
6609                                 DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6610                                 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
6611                                 if ( P2P_STATUS_SUCCESS == result )
6612                                 {
6613                                         if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6614                                         {
6615                                                 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6616                                                 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6617                                                 pwdinfo->p2p_info.operation_ch[ 1 ] = 1;        //Check whether GO is operating in channel 1;
6618                                                 pwdinfo->p2p_info.operation_ch[ 2 ] = 6;        //Check whether GO is operating in channel 6;
6619                                                 pwdinfo->p2p_info.operation_ch[ 3 ] = 11;       //Check whether GO is operating in channel 11;
6620                                                 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6621                                                 pwdinfo->p2p_info.scan_op_ch_only = 1;
6622                                                 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6623                                         }
6624                                 }
6625                                 break;
6626                         }
6627                         case P2P_INVIT_REQ:
6628                         {
6629                                 //      Added by Albert 2010/10/05
6630                                 //      Received the P2P Invite Request frame.
6631                                 
6632                                 DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
6633                                 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6634                                 {
6635                                         //      Parse the necessary information from the P2P Invitation Request frame.
6636                                         //      For example: The MAC address of sending this P2P Invitation Request frame.
6637                                         u32     attr_contentlen = 0;
6638                                         u8      status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6639                                         struct group_id_info group_id;
6640                                         u8      invitation_flag = 0;
6641                                         int j=0;
6642
6643                                         merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6644
6645                                         merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2);       // 2 is for EID and Length
6646                                         if (merged_p2pie == NULL)
6647                                         {
6648                                                 DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
6649                                                 goto exit;
6650                                         }
6651                                         _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);                                      
6652
6653                                         merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6654
6655                                         rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6656                                         if ( attr_contentlen )
6657                                         {
6658
6659                                                 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6660                                                 //      Commented by Albert 20120510
6661                                                 //      Copy to the pwdinfo->p2p_peer_interface_addr.
6662                                                 //      So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
6663                                                 //      #> iwpriv wlan0 p2p_get peer_ifa
6664                                                 //      After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
6665
6666                                                 if ( attr_contentlen )
6667                                                 {
6668                                                         DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6669                                                                         pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6670                                                                         pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6671                                                                         pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
6672                                                 }                                                               
6673
6674                                                 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
6675                                                 {
6676                                                         //      Re-invoke the persistent group.
6677                                                         
6678                                                         _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6679                                                         rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6680                                                         if ( attr_contentlen )
6681                                                         {
6682                                                                 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6683                                                                 {
6684                                                                         //      The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
6685                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
6686                                                                         rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
6687                                                                         status_code = P2P_STATUS_SUCCESS;
6688                                                                 }
6689                                                                 else
6690                                                                 {
6691                                                                         //      The p2p device sending this p2p invitation request wants to be the persistent GO.
6692                                                                         if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
6693                                                                         {
6694                                                                                 u8 operatingch_info[5] = { 0x00 };
6695                                                                                 if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
6696                                                                                 {
6697                                                                                         if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
6698                                                                                         {
6699                                                                                                 //      The operating channel is acceptable for this device.
6700                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
6701                                                                                                 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6702                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[1]= 1;          //Check whether GO is operating in channel 1;
6703                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[2]= 6;          //Check whether GO is operating in channel 6;
6704                                                                                                 pwdinfo->rx_invitereq_info.operation_ch[3]= 11;         //Check whether GO is operating in channel 11;
6705                                                                                                 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6706                                                                                                 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6707                                                                                                 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
6708                                                                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6709                                                                                                 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6710                                                                                                 status_code = P2P_STATUS_SUCCESS;
6711                                                                                         }
6712                                                                                         else
6713                                                                                         {
6714                                                                                                 //      The operating channel isn't supported by this device.
6715                                                                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6716                                                                                                 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
6717                                                                                                 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6718                                                                                                 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6719                                                                                         }
6720                                                                                 }
6721                                                                                 else
6722                                                                                 {
6723                                                                                         //      Commented by Albert 20121130
6724                                                                                         //      Intel will use the different P2P IE to store the operating channel information
6725                                                                                         //      Workaround for Intel WiDi 3.5
6726                                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6727                                                                                         rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6728                                                                                         status_code = P2P_STATUS_SUCCESS;
6729                                                                                 }                                                               
6730                                                                         }
6731                                                                         else
6732                                                                         {
6733                                                                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6734                                                                                 #ifdef CONFIG_INTEL_WIDI
6735                                                                                 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6736                                                                                 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6737                                                                                 #endif //CONFIG_INTEL_WIDI
6738
6739                                                                                 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6740                                                                         }
6741                                                                 }
6742                                                         }
6743                                                         else
6744                                                         {
6745                                                                 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6746                                                                 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6747                                                         }                                                                       
6748                                                 }
6749                                                 else
6750                                                 {
6751                                                         //      Received the invitation to join a P2P group.
6752
6753                                                         _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6754                                                         rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6755                                                         if ( attr_contentlen )
6756                                                         {
6757                                                                 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6758                                                                 {
6759                                                                         //      In this case, the GO can't be myself.
6760                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6761                                                                         status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6762                                                                 }
6763                                                                 else
6764                                                                 {
6765                                                                         //      The p2p device sending this p2p invitation request wants to join an existing P2P group
6766                                                                         //      Commented by Albert 2012/06/28
6767                                                                         //      In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
6768                                                                         //      The peer device address should be the destination address for the provisioning discovery request.
6769                                                                         //      Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
6770                                                                         //      The peer interface address should be the address for WPS mac address
6771                                                                         _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );                                                                                       
6772                                                                         rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6773                                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
6774                                                                         status_code = P2P_STATUS_SUCCESS;
6775                                                                 }
6776                                                         }
6777                                                         else
6778                                                         {
6779                                                                 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6780                                                                 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6781                                                         }
6782                                                 }
6783                                         }
6784                                         else
6785                                         {
6786                                                 DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
6787                                                 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6788                                         }                                                       
6789
6790                                         DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
6791
6792                                         pwdinfo->inviteresp_info.token = frame_body[ 7 ];
6793                                         issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
6794                                         _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6795                                 }
6796 #ifdef CONFIG_INTEL_WIDI
6797                                 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6798                                         padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6799                                         _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6800                                         intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6801                                 }
6802 #endif //CONFIG_INTEL_WIDI
6803                                 break;
6804                         }
6805                         case P2P_INVIT_RESP:
6806                         {
6807                                 u8      attr_content = 0x00;
6808                                 u32     attr_contentlen = 0;
6809                                 
6810                                 DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
6811                                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6812                                 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6813                                 {
6814                                         rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6815                                                                         
6816                                         if ( attr_contentlen == 1 )
6817                                         {
6818                                                 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
6819                                                 pwdinfo->invitereq_info.benable = _FALSE;
6820
6821                                                 if ( attr_content == P2P_STATUS_SUCCESS )
6822                                                 {
6823                                                         if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6824                                                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
6825                                                         else
6826                                                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6827
6828                                                         rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
6829                                                 }
6830                                                 else
6831                                                 {
6832                                                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6833                                                         rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6834                                                 }
6835                                         }
6836                                         else
6837                                         {
6838                                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6839                                                 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6840                                         }
6841                                 }
6842                                 else
6843                                 {
6844                                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6845                                         rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6846                                 }
6847
6848                                 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
6849                                 {
6850                                         _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6851                                 }
6852                                 break;
6853                         }
6854                         case P2P_DEVDISC_REQ:
6855
6856                                 process_p2p_devdisc_req(pwdinfo, pframe, len);
6857
6858                                 break;
6859
6860                         case P2P_DEVDISC_RESP:
6861
6862                                 process_p2p_devdisc_resp(pwdinfo, pframe, len);
6863
6864                                 break;
6865
6866                         case P2P_PROVISION_DISC_REQ:
6867                                 DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
6868                                 process_p2p_provdisc_req(pwdinfo, pframe, len);
6869                                 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6870
6871                                 //20110902 Kurt
6872                                 //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6873                                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6874                                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6875                                 
6876                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6877                                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6878 #ifdef CONFIG_INTEL_WIDI
6879                                 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6880                                         padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6881                                         _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6882                                         intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6883                                 }
6884 #endif //CONFIG_INTEL_WIDI
6885                                 break;
6886
6887                         case P2P_PROVISION_DISC_RESP:
6888                                 //      Commented by Albert 20110707
6889                                 //      Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
6890                                 DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
6891                                 //      Commented by Albert 20110426
6892                                 //      The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
6893                                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6894                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6895                                 process_p2p_provdisc_resp(pwdinfo, pframe);
6896                                 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6897                                 break;
6898
6899                 }
6900         }
6901
6902
6903 exit:
6904
6905         if(merged_p2pie)
6906         {
6907                 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6908         }
6909 #endif //CONFIG_P2P
6910         return _SUCCESS;
6911 }
6912
6913 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6914 {
6915         unsigned int ret = _FAIL;
6916         u8 *pframe = precv_frame->u.hdr.rx_data;
6917         uint frame_len = precv_frame->u.hdr.len;
6918         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6919
6920         if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6921                 if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
6922                         goto exit;
6923
6924                 if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
6925                         rtw_rframe_del_wfd_ie(precv_frame, 8);
6926
6927                 ret = on_action_public_p2p(precv_frame);
6928         }
6929
6930 exit:
6931         return ret;
6932 }
6933
6934 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6935 {
6936         unsigned int ret = _FAIL;
6937         u8 *pframe = precv_frame->u.hdr.rx_data;
6938         uint frame_len = precv_frame->u.hdr.len;
6939         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6940         u8 token;
6941         _adapter *adapter = precv_frame->u.hdr.adapter;
6942         int cnt = 0;
6943         char msg[64];
6944
6945         token = frame_body[2];
6946
6947         if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
6948                 goto exit;
6949
6950         #ifdef CONFIG_IOCTL_CFG80211
6951         cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
6952         rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
6953         #endif
6954
6955         ret = _SUCCESS;
6956         
6957 exit:
6958         return ret;
6959 }
6960
6961 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6962 {
6963         unsigned int ret = _FAIL;
6964         u8 *pframe = precv_frame->u.hdr.rx_data;
6965         uint frame_len = precv_frame->u.hdr.len;
6966         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6967         u8 category, action;
6968
6969         /* check RA matches or not */
6970         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6971                 goto exit;
6972
6973         category = frame_body[0];
6974         if (category != RTW_WLAN_CATEGORY_PUBLIC)
6975                 goto exit;
6976
6977         action = frame_body[1];
6978         switch (action) {
6979         case ACT_PUBLIC_BSSCOEXIST:
6980 #ifdef CONFIG_80211N_HT
6981 #ifdef CONFIG_AP_MODE
6982                 /*20/40 BSS Coexistence Management frame is a Public Action frame*/
6983                 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6984                         rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6985 #endif /*CONFIG_AP_MODE*/
6986 #endif /*CONFIG_80211N_HT*/
6987                 break;
6988         case ACT_PUBLIC_VENDOR:
6989                 ret = on_action_public_vendor(precv_frame);
6990                 break;
6991         default:
6992                 ret = on_action_public_default(precv_frame, action);
6993                 break;
6994         }
6995
6996 exit:
6997         return ret;
6998 }
6999
7000 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7001 {
7002         u8 *pframe = precv_frame->u.hdr.rx_data;
7003         uint frame_len = precv_frame->u.hdr.len;
7004         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7005         u8 category, action;
7006
7007         /* check RA matches or not */
7008         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7009                 goto exit;
7010
7011         category = frame_body[0];
7012         if (category != RTW_WLAN_CATEGORY_HT)
7013                 goto exit;
7014
7015         action = frame_body[1];
7016         switch (action) {
7017         case RTW_WLAN_ACTION_HT_SM_PS:
7018 #ifdef CONFIG_80211N_HT
7019 #ifdef CONFIG_AP_MODE
7020                 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7021                         rtw_process_ht_action_smps(padapter, GetAddr2Ptr(pframe), frame_body[2]);
7022 #endif /*CONFIG_AP_MODE*/
7023 #endif /*CONFIG_80211N_HT*/             
7024                         break;
7025         case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7026 #ifdef CONFIG_BEAMFORMING
7027                 /*DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7028                 beamforming_get_report_frame(padapter, precv_frame);
7029 #endif /*CONFIG_BEAMFORMING*/
7030                 break;
7031         default:
7032                 break;
7033         }
7034
7035 exit:
7036
7037         return _SUCCESS;
7038 }
7039
7040 #ifdef CONFIG_IEEE80211W
7041 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7042 {
7043         u8 *pframe = precv_frame->u.hdr.rx_data;
7044         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7045         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7046         struct sta_info         *psta;
7047         struct sta_priv         *pstapriv = &padapter->stapriv;
7048         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7049         u16 tid;
7050         //Baron
7051         
7052         DBG_871X("OnAction_sa_query\n");
7053         
7054         switch (pframe[WLAN_HDR_A3_LEN+1])
7055         {
7056                 case 0: //SA Query req
7057                         _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7058                         DBG_871X("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7059                         , pframe[WLAN_HDR_A3_LEN+1], tid, pframe[WLAN_HDR_A3_LEN+2], pframe[WLAN_HDR_A3_LEN+3]);
7060                         issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7061                         break;
7062
7063                 case 1: //SA Query rsp
7064                         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
7065                         if (psta != NULL)
7066                                 _cancel_timer_ex(&psta->dot11w_expire_timer);
7067                         
7068                         _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7069                         DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], tid);
7070                         break;
7071                 default:
7072                         break;
7073         }
7074         if(0)
7075         {
7076                 int pp;
7077                 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7078                 for(pp=0;pp< pattrib->pkt_len; pp++)
7079                         printk(" %02x ", pframe[pp]);
7080                 printk("\n");
7081         }       
7082         
7083         return _SUCCESS;
7084 }
7085 #endif //CONFIG_IEEE80211W
7086
7087 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7088 {
7089         return _SUCCESS;
7090 }
7091
7092 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7093 {
7094 #ifdef CONFIG_80211AC_VHT
7095         struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
7096         u8 *pframe = precv_frame->u.hdr.rx_data;
7097         uint frame_len = precv_frame->u.hdr.len;
7098         struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7099         u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7100         u8 category, action;
7101         struct sta_info *psta = NULL;
7102
7103         /* check RA matches or not */
7104         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7105                 goto exit;
7106
7107         category = frame_body[0];
7108         if(category != RTW_WLAN_CATEGORY_VHT)
7109                 goto exit;
7110
7111         action = frame_body[1];
7112         switch (action) {
7113         case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7114 #ifdef CONFIG_BEAMFORMING
7115                 /*DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7116                 beamforming_get_report_frame(padapter, precv_frame);
7117 #endif /*CONFIG_BEAMFORMING*/
7118                 break;
7119         case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7120                 // CategoryCode(1) + ActionCode(1) + OpModeNotification(1)
7121                 //DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n");
7122                 psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7123                 if (psta)
7124                         rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7125                 break;
7126         default:
7127                 break;
7128         }
7129
7130 exit:
7131 #endif //CONFIG_80211AC_VHT
7132
7133         return _SUCCESS;
7134 }
7135
7136 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7137 {
7138 #ifdef CONFIG_P2P
7139         u8 *frame_body;
7140         u8 category, OUI_Subtype, dialogToken=0;
7141         u8 *pframe = precv_frame->u.hdr.rx_data;
7142         uint len = precv_frame->u.hdr.len;
7143         struct  wifidirect_info *pwdinfo = &( padapter->wdinfo );
7144
7145         //check RA matches or not
7146         if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7147                 return _SUCCESS;
7148
7149         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7150
7151         category = frame_body[0];
7152         if(category != RTW_WLAN_CATEGORY_P2P)
7153                 return _SUCCESS;
7154
7155         if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
7156                 return _SUCCESS;
7157
7158 #ifdef CONFIG_IOCTL_CFG80211
7159         if (adapter_wdev_data(padapter)->p2p_enabled
7160                 && pwdinfo->driver_interface == DRIVER_CFG80211
7161                 ) {
7162                 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
7163                 return _SUCCESS;
7164         }
7165         else
7166 #endif //CONFIG_IOCTL_CFG80211
7167         {
7168                 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7169                 OUI_Subtype = frame_body[5];
7170                 dialogToken = frame_body[6];
7171
7172                 switch(OUI_Subtype)
7173                 {
7174                         case P2P_NOTICE_OF_ABSENCE:
7175                                 
7176                                 break;
7177                                 
7178                         case P2P_PRESENCE_REQUEST:
7179
7180                                 process_p2p_presence_req(pwdinfo, pframe, len);                 
7181                                 
7182                                 break;
7183                                 
7184                         case P2P_PRESENCE_RESPONSE:
7185                                 
7186                                 break;
7187                                 
7188                         case P2P_GO_DISC_REQUEST:
7189                                 
7190                                 break;
7191                                 
7192                         default:
7193                                 break;
7194                                 
7195                 }
7196         }
7197 #endif //CONFIG_P2P
7198
7199         return _SUCCESS;
7200
7201 }
7202
7203 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7204 {
7205         int i;
7206         unsigned char   category;
7207         struct action_handler *ptable;
7208         unsigned char   *frame_body;
7209         u8 *pframe = precv_frame->u.hdr.rx_data; 
7210
7211         frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7212         
7213         category = frame_body[0];
7214         
7215         for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++) 
7216         {
7217                 ptable = &OnAction_tbl[i];
7218                 
7219                 if(category == ptable->num)
7220                         ptable->func(padapter, precv_frame);
7221         
7222         }
7223
7224         return _SUCCESS;
7225
7226 }
7227
7228 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7229 {
7230
7231         //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
7232         return _SUCCESS;
7233 }
7234
7235 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7236 {
7237         struct xmit_frame *pmgntframe;
7238         struct xmit_buf *pxmitbuf;
7239
7240         if (once)
7241                 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7242         else
7243                 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7244
7245         if (pmgntframe == NULL) {
7246                 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7247                 goto exit;
7248         }
7249
7250         if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
7251                 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7252                 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7253                 pmgntframe = NULL;
7254                 goto exit;
7255         }
7256
7257         pmgntframe->frame_tag = MGNT_FRAMETAG;
7258         pmgntframe->pxmitbuf = pxmitbuf;
7259         pmgntframe->buf_addr = pxmitbuf->pbuf;
7260         pxmitbuf->priv_data = pmgntframe;
7261
7262 exit:
7263         return pmgntframe;
7264
7265 }
7266
7267 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7268 {
7269         return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7270 }
7271
7272 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7273 {
7274         return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7275 }
7276
7277
7278 /****************************************************************************
7279
7280 Following are some TX fuctions for WiFi MLME
7281
7282 *****************************************************************************/
7283
7284 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7285 {
7286         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7287
7288         pmlmeext->tx_rate = rate;
7289         //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
7290 }
7291
7292
7293 void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7294 {
7295         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
7296         u8      wireless_mode;
7297         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7298         struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
7299         struct sta_info         *psta = NULL;
7300         struct sta_priv         *pstapriv = &padapter->stapriv;
7301         struct sta_info *pbcmc_sta = NULL;
7302
7303         psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7304         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7305
7306         pattrib->hdrlen = 24;
7307         pattrib->nr_frags = 1;
7308         pattrib->priority = 7;
7309
7310         if (pbcmc_sta)
7311                 pattrib->mac_id = pbcmc_sta->mac_id;
7312         else {
7313                 pattrib->mac_id = 0;
7314                 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7315         }
7316         pattrib->qsel = QSLT_MGNT;
7317
7318         pattrib->pktlen = 0;
7319
7320         if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7321                 wireless_mode = WIRELESS_11B;
7322         else
7323                 wireless_mode = WIRELESS_11G;
7324
7325         pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7326         #ifdef CONFIG_80211AC_VHT
7327                 if (pHalData->rf_type == RF_1T1R)
7328                         pattrib->raid = RATEID_IDX_VHT_1SS;
7329                 else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
7330                         pattrib->raid = RATEID_IDX_VHT_2SS;
7331                 else if (pHalData->rf_type == RF_3T3R)
7332                         pattrib->raid = RATEID_IDX_VHT_3SS;
7333                 else
7334                         pattrib->raid = RATEID_IDX_BGN_40M_1SS;
7335         #endif
7336
7337         #ifdef CONFIG_80211AC_VHT
7338                 pattrib->rate = MGN_VHT1SS_MCS9;
7339         #else
7340                 pattrib->rate = MGN_MCS7;
7341         #endif
7342
7343         pattrib->encrypt = _NO_PRIVACY_;
7344         pattrib->bswenc = _FALSE;
7345
7346         pattrib->qos_en = _FALSE;
7347         pattrib->ht_en = 1;
7348         pattrib->bwmode = CHANNEL_WIDTH_20;
7349         pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7350         pattrib->sgi = _FALSE;
7351
7352         pattrib->seqnum = pmlmeext->mgnt_seq;
7353
7354         pattrib->retry_ctrl = _TRUE;
7355
7356         pattrib->mbssid = 0;
7357         pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7358
7359 }
7360
7361
7362 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7363 {
7364         u8      wireless_mode;
7365         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7366         struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
7367         struct sta_info         *psta = NULL;
7368         struct sta_priv         *pstapriv = &padapter->stapriv;
7369         struct sta_info *pbcmc_sta = NULL;
7370         //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
7371
7372         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7373
7374         pattrib->hdrlen = 24;
7375         pattrib->nr_frags = 1;
7376         pattrib->priority = 7;
7377
7378         if (pbcmc_sta)
7379                 pattrib->mac_id = pbcmc_sta->mac_id;
7380         else {
7381                 pattrib->mac_id = 0;
7382                 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7383         }
7384         pattrib->qsel = QSLT_MGNT;
7385
7386         pattrib->pktlen = 0;
7387
7388         if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7389                 wireless_mode = WIRELESS_11B;
7390         else
7391                 wireless_mode = WIRELESS_11G;
7392         pattrib->raid =  rtw_get_mgntframe_raid(padapter, wireless_mode);
7393         pattrib->rate = pmlmeext->tx_rate;
7394
7395         pattrib->encrypt = _NO_PRIVACY_;
7396         pattrib->bswenc = _FALSE;       
7397
7398         pattrib->qos_en = _FALSE;
7399         pattrib->ht_en = _FALSE;
7400         pattrib->bwmode = CHANNEL_WIDTH_20;
7401         pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7402         pattrib->sgi = _FALSE;
7403
7404         pattrib->seqnum = pmlmeext->mgnt_seq;
7405
7406         pattrib->retry_ctrl = _TRUE;
7407
7408         pattrib->mbssid = 0;
7409         pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7410
7411         #ifdef CONFIG_BEAMFORMING
7412         psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7413         if (psta)
7414                 update_attrib_txbf_info(padapter, pattrib, psta);
7415         #endif
7416
7417 }
7418
7419 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7420 {
7421         u8      *pframe;
7422         struct pkt_attrib       *pattrib = &pmgntframe->attrib;
7423
7424         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7425
7426         _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7427         _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
7428 }
7429
7430 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7431 {
7432         if (RTW_CANNOT_RUN(padapter)) {
7433                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7434                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7435                 return;
7436         }
7437
7438         rtw_hal_mgnt_xmit(padapter, pmgntframe);
7439 }
7440
7441 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7442 {
7443         s32 ret = _FAIL;
7444         _irqL irqL;
7445         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;      
7446         struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7447         struct submit_ctx sctx;
7448
7449         if (RTW_CANNOT_RUN(padapter)) {
7450                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7451                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7452                 return ret;
7453         }
7454
7455         rtw_sctx_init(&sctx, timeout_ms);
7456         pxmitbuf->sctx = &sctx;
7457
7458         ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7459
7460         if (ret == _SUCCESS)
7461                 ret = rtw_sctx_wait(&sctx, __func__);
7462
7463         _enter_critical(&pxmitpriv->lock_sctx, &irqL);
7464         pxmitbuf->sctx = NULL;
7465         _exit_critical(&pxmitpriv->lock_sctx, &irqL);
7466
7467          return ret;
7468 }
7469
7470 s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7471 {
7472 #ifdef CONFIG_XMIT_ACK
7473         static u8 seq_no = 0;
7474         s32 ret = _FAIL;
7475         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
7476         #ifdef CONFIG_CONCURRENT_MODE
7477         if (padapter->pbuddy_adapter && !padapter->isprimary)
7478                 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7479         #endif
7480
7481         if (RTW_CANNOT_RUN(padapter)) {
7482                 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7483                 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7484                 return -1;
7485         }
7486
7487         _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7488         pxmitpriv->ack_tx = _TRUE;
7489         pxmitpriv->seq_no = seq_no++;
7490         pmgntframe->ack_report = 1;
7491         rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7492         if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7493 #ifdef CONFIG_XMIT_ACK_POLLING
7494                 ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7495 #else
7496                 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7497 #endif
7498         }
7499
7500         pxmitpriv->ack_tx = _FALSE;
7501         _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7502
7503          return ret;
7504 #else /* !CONFIG_XMIT_ACK */
7505         dump_mgntframe(padapter, pmgntframe);
7506         rtw_msleep_os(50);
7507         return _SUCCESS;
7508 #endif /* !CONFIG_XMIT_ACK */
7509 }
7510
7511 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7512 {
7513         /* In this case, use 500 ms as the default wait_ack timeout */
7514         return dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 500);
7515 }
7516
7517
7518 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7519 {
7520         u8 *ssid_ie;
7521         sint ssid_len_ori;
7522         int len_diff = 0;
7523         
7524         ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
7525
7526         //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
7527         
7528         if(ssid_ie && ssid_len_ori>0)
7529         {
7530                 switch(hidden_ssid_mode)
7531                 {
7532                         case 1:
7533                         {
7534                                 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7535                                 u32 remain_len = 0;
7536                                 
7537                                 remain_len = ies_len -(next_ie-ies);
7538                                 
7539                                 ssid_ie[1] = 0;                         
7540                                 _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
7541                                 len_diff -= ssid_len_ori;
7542                                 
7543                                 break;
7544                         }               
7545                         case 2:
7546                                 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7547                                 break;
7548                         default:
7549                                 break;
7550                 }
7551         }
7552
7553         return len_diff;
7554 }
7555
7556 void issue_beacon(_adapter *padapter, int timeout_ms)
7557 {
7558         struct xmit_frame       *pmgntframe;
7559         struct pkt_attrib       *pattrib;
7560         unsigned char   *pframe;
7561         struct rtw_ieee80211_hdr *pwlanhdr;
7562         unsigned short *fctrl;
7563         unsigned int    rate_len;
7564         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
7565 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7566         _irqL irqL;
7567         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7568 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7569         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7570         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
7571         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
7572         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7573 #ifdef CONFIG_P2P
7574         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
7575 #endif //CONFIG_P2P
7576
7577
7578         //DBG_871X("%s\n", __FUNCTION__);
7579
7580 #ifdef CONFIG_BCN_ICF
7581         if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL)
7582 #else
7583         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7584 #endif
7585         {
7586                 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7587                 return;
7588         }
7589 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7590         _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7591 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7592
7593         //update attribute
7594         pattrib = &pmgntframe->attrib;
7595         update_mgntframe_attrib(padapter, pattrib);
7596         pattrib->qsel = QSLT_BEACON;
7597         #ifdef CONFIG_CONCURRENT_MODE
7598         if(padapter->iface_type == IFACE_PORT1) 
7599                 pattrib->mbssid = 1;
7600         #endif  
7601         
7602         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7603                 
7604         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7605         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
7606         
7607         
7608         fctrl = &(pwlanhdr->frame_ctl);
7609         *(fctrl) = 0;
7610         
7611         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7612         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7613         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7614
7615         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7616         //pmlmeext->mgnt_seq++;
7617         SetFrameSubType(pframe, WIFI_BEACON);
7618         
7619         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);       
7620         pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7621         
7622         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7623         {
7624                 //DBG_871X("ie len=%d\n", cur_network->IELength);
7625 #ifdef CONFIG_P2P
7626                 // for P2P : Primary Device Type & Device Name
7627                 u32 wpsielen=0, insert_len=0;
7628                 u8 *wpsie=NULL;         
7629                 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
7630                 
7631                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
7632                 {
7633                         uint wps_offset, remainder_ielen;
7634                         u8 *premainder_ie, *pframe_wscie;
7635         
7636                         wps_offset = (uint)(wpsie - cur_network->IEs);
7637
7638                         premainder_ie = wpsie + wpsielen;
7639
7640                         remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7641
7642 #ifdef CONFIG_IOCTL_CFG80211
7643                         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7644                         {
7645                                 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
7646                                 {
7647                                         _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7648                                         pframe += wps_offset;
7649                                         pattrib->pktlen += wps_offset;
7650
7651                                         _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7652                                         pframe += pmlmepriv->wps_beacon_ie_len;
7653                                         pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7654
7655                                         //copy remainder_ie to pframe
7656                                         _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7657                                         pframe += remainder_ielen;              
7658                                         pattrib->pktlen += remainder_ielen;
7659                                 }
7660                                 else
7661                                 {
7662                                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7663                                         pframe += cur_network->IELength;
7664                                         pattrib->pktlen += cur_network->IELength;
7665                                 }
7666                         }
7667                         else
7668 #endif //CONFIG_IOCTL_CFG80211
7669                         {
7670                                 pframe_wscie = pframe + wps_offset;
7671                                 _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);                     
7672                                 pframe += (wps_offset + wpsielen);              
7673                                 pattrib->pktlen += (wps_offset + wpsielen);
7674
7675                                 //now pframe is end of wsc ie, insert Primary Device Type & Device Name
7676                                 //      Primary Device Type
7677                                 //      Type:
7678                                 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
7679                                 insert_len += 2;
7680                                 
7681                                 //      Length:
7682                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
7683                                 insert_len += 2;
7684                                 
7685                                 //      Value:
7686                                 //      Category ID
7687                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7688                                 insert_len += 2;
7689
7690                                 //      OUI
7691                                 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
7692                                 insert_len += 4;
7693
7694                                 //      Sub Category ID
7695                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7696                                 insert_len += 2;
7697
7698
7699                                 //      Device Name
7700                                 //      Type:
7701                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7702                                 insert_len += 2;
7703
7704                                 //      Length:
7705                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
7706                                 insert_len += 2;
7707
7708                                 //      Value:
7709                                 _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
7710                                 insert_len += pwdinfo->device_name_len;
7711
7712
7713                                 //update wsc ie length
7714                                 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
7715
7716                                 //pframe move to end
7717                                 pframe+=insert_len;
7718                                 pattrib->pktlen += insert_len;
7719
7720                                 //copy remainder_ie to pframe
7721                                 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7722                                 pframe += remainder_ielen;              
7723                                 pattrib->pktlen += remainder_ielen;
7724                         }
7725                 }
7726                 else
7727 #endif //CONFIG_P2P
7728                 {
7729                         int len_diff;
7730                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7731                         len_diff = update_hidden_ssid(
7732                                 pframe+_BEACON_IE_OFFSET_
7733                                 , cur_network->IELength-_BEACON_IE_OFFSET_
7734                                 , pmlmeinfo->hidden_ssid_mode
7735                         );
7736                         pframe += (cur_network->IELength+len_diff);
7737                         pattrib->pktlen += (cur_network->IELength+len_diff);
7738                 }
7739
7740                 {
7741                         u8 *wps_ie;
7742                         uint wps_ielen;
7743                         u8 sr = 0;
7744                         wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
7745                                 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
7746                         if (wps_ie && wps_ielen>0) {
7747                                 rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
7748                         }
7749                         if (sr != 0)
7750                                 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7751                         else
7752                                 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7753                 }
7754
7755 #ifdef CONFIG_P2P
7756                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
7757                 {
7758                         u32 len;
7759 #ifdef CONFIG_IOCTL_CFG80211
7760                         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7761                         {
7762                                 len = pmlmepriv->p2p_beacon_ie_len;
7763                                 if(pmlmepriv->p2p_beacon_ie && len>0)                           
7764                                         _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7765                         }
7766                         else
7767 #endif //CONFIG_IOCTL_CFG80211
7768                         {
7769                                 len = build_beacon_p2p_ie(pwdinfo, pframe);
7770                         }
7771
7772                         pframe += len;
7773                         pattrib->pktlen += len;
7774
7775                         #ifdef CONFIG_WFD
7776                         len = rtw_append_beacon_wfd_ie(padapter, pframe);
7777                         pframe += len;
7778                         pattrib->pktlen += len;
7779                         #endif
7780                 }
7781 #endif //CONFIG_P2P
7782
7783                 goto _issue_bcn;
7784
7785         }
7786
7787         //below for ad-hoc mode
7788
7789         //timestamp will be inserted by hardware
7790         pframe += 8;
7791         pattrib->pktlen += 8;
7792
7793         // beacon interval: 2 bytes
7794
7795         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
7796
7797         pframe += 2;
7798         pattrib->pktlen += 2;
7799
7800         // capability info: 2 bytes
7801
7802         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7803
7804         pframe += 2;
7805         pattrib->pktlen += 2;
7806
7807         // SSID
7808         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7809
7810         // supported rates...
7811         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7812         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7813
7814         // DS parameter set
7815         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7816
7817         //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7818         {
7819                 u8 erpinfo=0;
7820                 u32 ATIMWindow;
7821                 // IBSS Parameter Set...
7822                 //ATIMWindow = cur->Configuration.ATIMWindow;
7823                 ATIMWindow = 0;
7824                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7825
7826                 //ERP IE
7827                 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7828         }       
7829
7830
7831         // EXTERNDED SUPPORTED RATE
7832         if (rate_len > 8)
7833         {
7834                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7835         }
7836
7837
7838         //todo:HT for adhoc
7839
7840 _issue_bcn:
7841
7842 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7843         pmlmepriv->update_bcn = _FALSE;
7844         
7845         _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);  
7846 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7847
7848         if ((pattrib->pktlen + TXDESC_SIZE) > 512)
7849         {
7850                 DBG_871X("beacon frame too large\n");
7851                 return;
7852         }
7853         
7854         pattrib->last_txcmdsz = pattrib->pktlen;
7855
7856         //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
7857         if(timeout_ms > 0)
7858                 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7859         else
7860                 dump_mgntframe(padapter, pmgntframe);
7861
7862 }
7863
7864 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7865 {
7866         struct xmit_frame                       *pmgntframe;
7867         struct pkt_attrib                       *pattrib;
7868         unsigned char                                   *pframe;
7869         struct rtw_ieee80211_hdr        *pwlanhdr;
7870         unsigned short                          *fctrl; 
7871         unsigned char                                   *mac, *bssid;
7872         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
7873 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7874         u8 *pwps_ie;
7875         uint wps_ielen;
7876         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7877 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7878         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
7879         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
7880         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
7881         unsigned int    rate_len;
7882 #ifdef CONFIG_P2P
7883         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
7884 #ifdef CONFIG_WFD
7885         u32                                     wfdielen = 0;
7886 #endif
7887 #endif //CONFIG_P2P
7888
7889         //DBG_871X("%s\n", __FUNCTION__);
7890
7891         if(da == NULL)
7892                 return;
7893
7894         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
7895                 return;
7896
7897         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7898         {
7899                 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7900                 return;
7901         }
7902
7903
7904         //update attribute
7905         pattrib = &pmgntframe->attrib;
7906         update_mgntframe_attrib(padapter, pattrib);     
7907         
7908         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7909                 
7910         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7911         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
7912         
7913         mac = adapter_mac_addr(padapter);
7914         bssid = cur_network->MacAddress;
7915         
7916         fctrl = &(pwlanhdr->frame_ctl);
7917         *(fctrl) = 0;
7918         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7919         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7920         _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7921
7922         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7923         pmlmeext->mgnt_seq++;
7924         SetFrameSubType(fctrl, WIFI_PROBERSP);
7925         
7926         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7927         pattrib->pktlen = pattrib->hdrlen;
7928         pframe += pattrib->hdrlen;
7929
7930
7931         if(cur_network->IELength>MAX_IE_SZ)
7932                 return;
7933         
7934 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7935         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7936         {
7937                 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
7938         
7939                 //inerset & update wps_probe_resp_ie
7940                 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
7941                 {
7942                         uint wps_offset, remainder_ielen;
7943                         u8 *premainder_ie;              
7944         
7945                         wps_offset = (uint)(pwps_ie - cur_network->IEs);
7946
7947                         premainder_ie = pwps_ie + wps_ielen;
7948
7949                         remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
7950
7951                         _rtw_memcpy(pframe, cur_network->IEs, wps_offset);              
7952                         pframe += wps_offset;           
7953                         pattrib->pktlen += wps_offset;          
7954
7955                         wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
7956                         if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
7957                         {
7958                                 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
7959                                 pframe += wps_ielen+2;          
7960                                 pattrib->pktlen += wps_ielen+2; 
7961                         }
7962
7963                         if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
7964                         {
7965                                 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7966                                 pframe += remainder_ielen;              
7967                                 pattrib->pktlen += remainder_ielen;     
7968                         }
7969                 }
7970                 else
7971                 {
7972                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7973                         pframe += cur_network->IELength;
7974                         pattrib->pktlen += cur_network->IELength;
7975                 }
7976
7977                 /* retrieve SSID IE from cur_network->Ssid */
7978                 {
7979                         u8 *ssid_ie;
7980                         sint ssid_ielen;
7981                         sint ssid_ielen_diff;
7982                         u8 buf[MAX_IE_SZ];
7983                         u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
7984
7985                         ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
7986                                 (pframe-ies)-_FIXED_IE_LENGTH_);
7987
7988                         ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
7989
7990                         if (ssid_ie &&  cur_network->Ssid.SsidLength) {
7991                                 uint remainder_ielen;
7992                                 u8 *remainder_ie;
7993                                 remainder_ie = ssid_ie+2;
7994                                 remainder_ielen = (pframe-remainder_ie);
7995
7996                                 if (remainder_ielen > MAX_IE_SZ) {
7997                                         DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
7998                                         remainder_ielen = MAX_IE_SZ;
7999                                 }
8000
8001                                 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
8002                                 _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
8003                                 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
8004                                 _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8005
8006                                 pframe += ssid_ielen_diff;
8007                                 pattrib->pktlen += ssid_ielen_diff;
8008                         }
8009                 }
8010         }       
8011         else            
8012 #endif          
8013         {
8014         
8015                 //timestamp will be inserted by hardware
8016                 pframe += 8;
8017                 pattrib->pktlen += 8;
8018
8019                 // beacon interval: 2 bytes
8020
8021                 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
8022
8023                 pframe += 2;
8024                 pattrib->pktlen += 2;
8025
8026                 // capability info: 2 bytes
8027
8028                 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8029
8030                 pframe += 2;
8031                 pattrib->pktlen += 2;
8032
8033                 //below for ad-hoc mode
8034
8035                 // SSID
8036                 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8037
8038                 // supported rates...
8039                 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8040                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8041
8042                 // DS parameter set
8043                 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8044
8045                 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
8046                 {
8047                         u8 erpinfo=0;
8048                         u32 ATIMWindow;
8049                         // IBSS Parameter Set...
8050                         //ATIMWindow = cur->Configuration.ATIMWindow;
8051                         ATIMWindow = 0;
8052                         pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8053
8054                         //ERP IE
8055                         pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8056                 }
8057
8058                 
8059                 // EXTERNDED SUPPORTED RATE
8060                 if (rate_len > 8)
8061                 {
8062                         pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8063                 }
8064
8065
8066                 //todo:HT for adhoc
8067
8068         }       
8069
8070 #ifdef CONFIG_P2P
8071         if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8072                 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8073                 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec))
8074         {
8075                 u32 len;
8076 #ifdef CONFIG_IOCTL_CFG80211
8077                 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8078                 {
8079                         //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
8080                         len = pmlmepriv->p2p_go_probe_resp_ie_len;
8081                         if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
8082                                 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8083                 }
8084                 else
8085 #endif //CONFIG_IOCTL_CFG80211
8086                 {
8087                         len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8088                 }
8089
8090                 pframe += len;
8091                 pattrib->pktlen += len;
8092                 
8093                 #ifdef CONFIG_WFD
8094                 len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8095                 pframe += len;
8096                 pattrib->pktlen += len;
8097                 #endif
8098         }
8099 #endif //CONFIG_P2P
8100
8101
8102 #ifdef CONFIG_AUTO_AP_MODE
8103 {
8104         struct sta_info *psta;
8105         struct sta_priv *pstapriv = &padapter->stapriv;
8106
8107         DBG_871X("(%s)\n", __FUNCTION__);
8108
8109         //check rc station
8110         psta = rtw_get_stainfo(pstapriv, da);
8111         if (psta && psta->isrc && psta->pid>0)
8112         {
8113                 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
8114                 u8 RC_INFO[14] = {0};
8115                 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
8116                 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8117
8118                 DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8119                         psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
8120
8121                 //append vendor specific ie
8122                 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8123                 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8124                 _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
8125                 _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
8126
8127                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8128         }
8129 }
8130 #endif //CONFIG_AUTO_AP_MODE
8131
8132
8133         pattrib->last_txcmdsz = pattrib->pktlen;
8134         
8135
8136         dump_mgntframe(padapter, pmgntframe);
8137         
8138         return;
8139
8140 }
8141
8142 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
8143 {
8144         int ret = _FAIL;
8145         struct xmit_frame               *pmgntframe;
8146         struct pkt_attrib               *pattrib;
8147         unsigned char                   *pframe;
8148         struct rtw_ieee80211_hdr        *pwlanhdr;
8149         unsigned short          *fctrl;
8150         unsigned char                   *mac;
8151         unsigned char                   bssrate[NumRates];
8152         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
8153         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8154         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8155         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8156         int     bssrate_len = 0;
8157         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8158
8159         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8160                 goto exit;
8161
8162         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8163         {
8164                 goto exit;
8165         }
8166
8167         //update attribute
8168         pattrib = &pmgntframe->attrib;
8169         update_mgntframe_attrib(padapter, pattrib);
8170
8171
8172         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8173
8174         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8175         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8176
8177         mac = adapter_mac_addr(padapter);
8178
8179         fctrl = &(pwlanhdr->frame_ctl);
8180         *(fctrl) = 0;
8181
8182         if (da)
8183         {
8184                 //      unicast probe request frame
8185                 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8186                 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8187         }
8188         else
8189         {
8190                 //      broadcast probe request frame
8191                 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8192                 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8193         }
8194
8195         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8196
8197         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8198         pmlmeext->mgnt_seq++;
8199         SetFrameSubType(pframe, WIFI_PROBEREQ);
8200
8201         pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
8202         pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
8203
8204         if(pssid)
8205                 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8206         else
8207                 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8208
8209         get_rate_set(padapter, bssrate, &bssrate_len);
8210
8211         if (bssrate_len > 8)
8212         {
8213                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8214                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8215         }
8216         else
8217         {
8218                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8219         }
8220
8221         if (ch)
8222                 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8223
8224         if (append_wps) {
8225                 //add wps_ie for wps2.0
8226                 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
8227                 {
8228                         _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8229                         pframe += pmlmepriv->wps_probe_req_ie_len;
8230                         pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8231                         //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
8232                 }
8233         }
8234
8235         pattrib->last_txcmdsz = pattrib->pktlen;
8236
8237         RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
8238
8239         if (wait_ack) {
8240                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8241         } else {
8242                 dump_mgntframe(padapter, pmgntframe);
8243                 ret = _SUCCESS;
8244         }
8245
8246 exit:
8247         return ret;
8248 }
8249
8250 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
8251 {
8252         _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8253 }
8254
8255 /*
8256  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8257  * 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
8258  * try_cnt means the maximal TX count to try
8259  */
8260 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
8261         int try_cnt, int wait_ms)
8262 {
8263         int ret = _FAIL;
8264         int i = 0;
8265         u32 start = rtw_get_current_time();
8266
8267         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8268                 goto exit;
8269
8270         do
8271         {
8272                 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE);
8273
8274                 i++;
8275
8276                 if (RTW_CANNOT_RUN(padapter))
8277                         break;
8278
8279                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8280                         rtw_msleep_os(wait_ms);
8281
8282         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8283
8284         if (ret != _FAIL) {
8285                 ret = _SUCCESS;
8286                 #ifndef DBG_XMIT_ACK
8287                 goto exit;
8288                 #endif
8289         }
8290
8291         if (try_cnt && wait_ms) {
8292                 if (da)
8293                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8294                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8295                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8296                 else
8297                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8298                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8299                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8300         }
8301 exit:
8302         return ret;
8303 }
8304
8305 // if psta == NULL, indiate we are station(client) now...
8306 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8307 {
8308         struct xmit_frame                       *pmgntframe;
8309         struct pkt_attrib                       *pattrib;
8310         unsigned char                                   *pframe;
8311         struct rtw_ieee80211_hdr        *pwlanhdr;
8312         unsigned short                          *fctrl;
8313         unsigned int                                    val32;
8314         unsigned short                          val16;
8315         int use_shared_key = 0;
8316         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
8317         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8318         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8319
8320         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8321                 return;
8322
8323         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8324         {
8325                 return;
8326         }
8327
8328         //update attribute
8329         pattrib = &pmgntframe->attrib;
8330         update_mgntframe_attrib(padapter, pattrib);
8331
8332         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8333
8334         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8335         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8336
8337         fctrl = &(pwlanhdr->frame_ctl);
8338         *(fctrl) = 0;
8339
8340         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8341         pmlmeext->mgnt_seq++;
8342         SetFrameSubType(pframe, WIFI_AUTH);
8343
8344         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8345         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8346
8347
8348         if(psta)// for AP mode
8349         {
8350 #ifdef CONFIG_NATIVEAP_MLME
8351
8352                 _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);           
8353                 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8354                 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8355
8356         
8357                 // setting auth algo number
8358                 val16 = (u16)psta->authalg;
8359
8360                 if(status != _STATS_SUCCESSFUL_)
8361                         val16 = 0;
8362
8363                 if (val16)      {
8364                         val16 = cpu_to_le16(val16);     
8365                         use_shared_key = 1;
8366                 }
8367
8368                 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8369
8370                 // setting auth seq number
8371                 val16 =(u16)psta->auth_seq;
8372                 val16 = cpu_to_le16(val16);     
8373                 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8374
8375                 // setting status code...
8376                 val16 = status;
8377                 val16 = cpu_to_le16(val16);     
8378                 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8379
8380                 // added challenging text...
8381                 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8382                 {
8383                         pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8384                 }
8385 #endif
8386         }
8387         else
8388         {               
8389                 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8390                 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8391                 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8392         
8393                 // setting auth algo number             
8394                 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
8395                 if (val16)      {
8396                         val16 = cpu_to_le16(val16);     
8397                         use_shared_key = 1;
8398                 }       
8399                 //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
8400                 
8401                 //setting IV for auth seq #3
8402                 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8403                 {
8404                         //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
8405                         val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8406                         val32 = cpu_to_le32(val32);
8407                         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8408
8409                         pattrib->iv_len = 4;
8410                 }
8411
8412                 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8413                 
8414                 // setting auth seq number
8415                 val16 = pmlmeinfo->auth_seq;
8416                 val16 = cpu_to_le16(val16);     
8417                 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8418
8419                 
8420                 // setting status code...
8421                 val16 = status;
8422                 val16 = cpu_to_le16(val16);     
8423                 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8424
8425                 // then checking to see if sending challenging text...
8426                 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8427                 {
8428                         pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8429
8430                         SetPrivacy(fctrl);
8431                         
8432                         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);                       
8433                         
8434                         pattrib->encrypt = _WEP40_;
8435
8436                         pattrib->icv_len = 4;
8437                         
8438                         pattrib->pktlen += pattrib->icv_len;                    
8439                         
8440                 }
8441                 
8442         }
8443
8444         pattrib->last_txcmdsz = pattrib->pktlen;
8445
8446         rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8447         DBG_871X("%s\n", __FUNCTION__);
8448         dump_mgntframe(padapter, pmgntframe);
8449
8450         return;
8451 }
8452
8453
8454 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8455 {
8456 #ifdef CONFIG_AP_MODE
8457         struct xmit_frame       *pmgntframe;
8458         struct rtw_ieee80211_hdr        *pwlanhdr;
8459         struct pkt_attrib *pattrib;
8460         unsigned char   *pbuf, *pframe;
8461         unsigned short val, ie_status;          
8462         unsigned short *fctrl;
8463         struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8464         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8465         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8466         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);  
8467         WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8468         u8 *ie = pnetwork->IEs; 
8469 #ifdef CONFIG_P2P
8470         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
8471 #ifdef CONFIG_WFD
8472         u32                                     wfdielen = 0;
8473 #endif
8474
8475 #endif //CONFIG_P2P
8476
8477         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8478                 return;
8479
8480         DBG_871X("%s\n", __FUNCTION__);
8481
8482         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8483         {
8484                 return;
8485         }
8486
8487         //update attribute
8488         pattrib = &pmgntframe->attrib;
8489         update_mgntframe_attrib(padapter, pattrib);
8490
8491
8492         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8493
8494         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8495         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8496
8497         fctrl = &(pwlanhdr->frame_ctl);
8498         *(fctrl) = 0;
8499
8500         _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
8501         _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8502         _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8503
8504
8505         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8506         pmlmeext->mgnt_seq++;
8507         if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8508                 SetFrameSubType(pwlanhdr, pkt_type);            
8509         else
8510                 return;
8511
8512         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8513         pattrib->pktlen += pattrib->hdrlen;
8514         pframe += pattrib->hdrlen;
8515
8516         //capability
8517         val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8518
8519         pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8520
8521         ie_status = cpu_to_le16(status);
8522         pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8523         
8524         val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
8525         pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8526
8527         if (pstat->bssratelen <= 8)
8528         {
8529                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8530         }       
8531         else 
8532         {
8533                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8534                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
8535         }
8536
8537 #ifdef CONFIG_IEEE80211W        
8538         if (status == _STATS_REFUSED_TEMPORARILY_) {
8539                 u8 timeout_itvl[5];
8540                 u32 timeout_interval = 3000;
8541                 /* Association Comeback time */
8542                 timeout_itvl[0] = 0x03;
8543                 timeout_interval = cpu_to_le32(timeout_interval);
8544                 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
8545                 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8546         }
8547 #endif /* CONFIG_IEEE80211W */
8548
8549 #ifdef CONFIG_80211N_HT
8550         if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
8551         {
8552                 uint ie_len=0;
8553                 
8554                 //FILL HT CAP INFO IE
8555                 //p = hostapd_eid_ht_capabilities_info(hapd, p);
8556                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8557                 if(pbuf && ie_len>0)
8558                 {
8559                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8560                         pframe += (ie_len+2);
8561                         pattrib->pktlen +=(ie_len+2);
8562                 }
8563
8564                 //FILL HT ADD INFO IE
8565                 //p = hostapd_eid_ht_operation(hapd, p);
8566                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8567                 if(pbuf && ie_len>0)
8568                 {
8569                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8570                         pframe += (ie_len+2);
8571                         pattrib->pktlen +=(ie_len+2);
8572                 }
8573                 
8574         }       
8575 #endif
8576
8577         /*adding EXT_CAPAB_IE */
8578         if (pmlmepriv->ext_capab_ie_len > 0) {
8579                 uint ie_len = 0;
8580                 
8581                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8582                 if (pbuf && ie_len > 0) {
8583                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8584                         pframe += (ie_len+2);
8585                         pattrib->pktlen += (ie_len+2);
8586                 }
8587         }       
8588         
8589 #ifdef CONFIG_80211AC_VHT
8590         if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8591                 && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8592                 && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP))
8593         {
8594                 u32 ie_len=0;
8595
8596                 //FILL VHT CAP IE
8597                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8598                 if(pbuf && ie_len>0)
8599                 {
8600                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8601                         pframe += (ie_len+2);
8602                         pattrib->pktlen +=(ie_len+2);
8603                 }
8604
8605                 //FILL VHT OPERATION IE
8606                 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8607                 if(pbuf && ie_len>0)
8608                 {
8609                         _rtw_memcpy(pframe, pbuf, ie_len+2);
8610                         pframe += (ie_len+2);
8611                         pattrib->pktlen +=(ie_len+2);
8612                 }
8613         }
8614 #endif //CONFIG_80211AC_VHT
8615
8616         //FILL WMM IE
8617         if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
8618         {
8619                 uint ie_len=0;
8620                 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};     
8621                 
8622                 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
8623                 {                       
8624                         pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));       
8625                         if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6)) 
8626                         {                               
8627                                 _rtw_memcpy(pframe, pbuf, ie_len+2);
8628                                 pframe += (ie_len+2);
8629                                 pattrib->pktlen +=(ie_len+2);
8630                                 
8631                                 break;                          
8632                         }
8633                         
8634                         if ((pbuf == NULL) || (ie_len == 0))
8635                         {
8636                                 break;
8637                         }                       
8638                 }
8639                 
8640         }
8641
8642
8643         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8644         {
8645                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8646         }
8647
8648         //add WPS IE ie for wps 2.0
8649         if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
8650         {
8651                 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8652                 
8653                 pframe += pmlmepriv->wps_assoc_resp_ie_len;
8654                 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8655         }
8656
8657 #ifdef CONFIG_P2P
8658         if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
8659                 u32 len;
8660
8661                 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
8662                         len = 0;
8663                         if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
8664                                 len = pmlmepriv->p2p_assoc_resp_ie_len;
8665                                 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
8666                         }
8667                 } else {
8668                         len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8669                 }
8670                 pframe += len;
8671                 pattrib->pktlen += len;
8672         }
8673
8674         #ifdef CONFIG_WFD
8675         if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8676                 wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
8677                 pframe += wfdielen;
8678                 pattrib->pktlen += wfdielen;
8679         }
8680         #endif
8681
8682 #endif /* CONFIG_P2P */
8683
8684         pattrib->last_txcmdsz = pattrib->pktlen;
8685         
8686         dump_mgntframe(padapter, pmgntframe);
8687         
8688 #endif
8689 }
8690
8691 void issue_assocreq(_adapter *padapter)
8692 {
8693         int ret = _FAIL;
8694         struct xmit_frame                               *pmgntframe;
8695         struct pkt_attrib                               *pattrib;
8696         unsigned char                                   *pframe, *p;
8697         struct rtw_ieee80211_hdr                        *pwlanhdr;
8698         unsigned short                          *fctrl;
8699         unsigned short                          val16;
8700         unsigned int                                    i, j, ie_len, index=0;
8701         unsigned char                                   rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8702         PNDIS_802_11_VARIABLE_IEs       pIE;
8703         struct registry_priv    *pregpriv = &padapter->registrypriv;
8704         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
8705         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8706         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
8707         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
8708         int     bssrate_len = 0, sta_bssrate_len = 0;
8709         u8      vs_ie_length = 0;
8710 #ifdef CONFIG_P2P
8711         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
8712         u8                                      p2pie[ 255 ] = { 0x00 };
8713         u16                                     p2pielen = 0;   
8714 #ifdef CONFIG_WFD
8715         u32                                     wfdielen = 0;
8716 #endif
8717 #endif //CONFIG_P2P
8718
8719 #ifdef CONFIG_DFS
8720         u16     cap;
8721
8722         /* Dot H */
8723         u8 pow_cap_ele[2] = { 0x00 };
8724         u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2;      //For supported channel
8725 #endif //CONFIG_DFS
8726
8727         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8728                 goto exit;
8729
8730         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8731                 goto exit;
8732
8733         //update attribute
8734         pattrib = &pmgntframe->attrib;
8735         update_mgntframe_attrib(padapter, pattrib);
8736
8737
8738         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8739
8740         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8741         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8742
8743         fctrl = &(pwlanhdr->frame_ctl);
8744         *(fctrl) = 0;
8745         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8746         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8747         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8748
8749         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8750         pmlmeext->mgnt_seq++;
8751         SetFrameSubType(pframe, WIFI_ASSOCREQ);
8752
8753         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8754         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8755
8756         //caps
8757
8758 #ifdef CONFIG_DFS
8759         _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8760         cap |= cap_SpecMgmt;
8761         _rtw_memcpy(pframe, &cap, 2);
8762 #else
8763         _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8764 #endif //CONFIG_DFS
8765
8766         pframe += 2;
8767         pattrib->pktlen += 2;
8768
8769         //listen interval
8770         //todo: listen interval for power saving
8771         val16 = cpu_to_le16(3);
8772         _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
8773         pframe += 2;
8774         pattrib->pktlen += 2;
8775
8776         //SSID
8777         pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8778
8779 #ifdef CONFIG_DFS
8780         /* Dot H */
8781         if(pmlmeext->cur_channel > 14)
8782         {
8783                 pow_cap_ele[0] = 13;    // Minimum transmit power capability
8784                 pow_cap_ele[1] = 21;    // Maximum transmit power capability
8785                 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8786
8787                 //supported channels
8788                 do{
8789                         if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
8790                         {
8791                                 sup_ch[0] = 1;  //First channel number
8792                                 sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;       //Number of channel
8793                         }
8794                         else
8795                         {
8796                                 sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8797                                 sup_ch[idx_5g++] = 1;
8798                         }
8799                         sup_ch_idx++;
8800                 }
8801                 while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
8802                 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8803         }
8804 #endif //CONFIG_DFS
8805
8806         //supported rate & extended supported rate
8807
8808 #if 1   // Check if the AP's supported rates are also supported by STA.
8809         get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8810         //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
8811         
8812         if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK) 
8813         {
8814                 sta_bssrate_len = 4;
8815         }
8816
8817         
8818         //for (i = 0; i < sta_bssrate_len; i++) {
8819         //      DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
8820         //}
8821
8822         for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8823                 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8824                 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8825         }
8826         
8827
8828         for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8829                 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8830
8831                 
8832                 // Check if the AP's supported rates are also supported by STA.
8833                 for (j=0; j < sta_bssrate_len; j++) {
8834                          // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8835                         if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK) 
8836                                         == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
8837                                 //DBG_871X("match i = %d, j=%d\n", i, j);
8838                                 break;
8839                         } else {
8840                                 //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
8841                         }
8842                 }
8843                 
8844                 if (j == sta_bssrate_len) {
8845                         // the rate is not supported by STA
8846                         DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8847                 } else {
8848                         // the rate is supported by STA
8849                         bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8850                 }
8851         }
8852         
8853         bssrate_len = index;
8854         DBG_871X("bssrate_len = %d\n", bssrate_len);
8855
8856 #else   // Check if the AP's supported rates are also supported by STA.
8857 #if 0
8858         get_rate_set(padapter, bssrate, &bssrate_len);
8859 #else
8860         for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8861                 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
8862
8863                 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8864                         break;
8865
8866                 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8867         }
8868 #endif
8869 #endif  // Check if the AP's supported rates are also supported by STA.
8870
8871         if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8872                 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8873                 rtw_free_xmitframe(pxmitpriv, pmgntframe);
8874                 goto exit; //don't connect to AP if no joint supported rate
8875         }
8876
8877
8878         if (bssrate_len > 8)
8879         {
8880                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8881                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8882         }
8883         else if (bssrate_len > 0)
8884         {
8885                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8886         } else {
8887                 DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n",__FUNCTION__);
8888         }
8889
8890         //vendor specific IE, such as WPA, WMM, WPS
8891         for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
8892         {
8893                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8894
8895                 switch (pIE->ElementID)
8896                 {
8897                         case _VENDOR_SPECIFIC_IE_:
8898                                 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8899                                                 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8900                                                 (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8901                                 {       
8902                                         vs_ie_length = pIE->Length;
8903                                         if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8904                                         {
8905                                                 //Commented by Kurt 20110629
8906                                                 //In some older APs, WPS handshake
8907                                                 //would be fail if we append vender extensions informations to AP
8908
8909                                                 vs_ie_length = 14;
8910                                         }
8911                                         
8912                                         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8913                                 }
8914                                 break;
8915
8916                         case EID_WPA2:
8917                                 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8918                                 break;
8919 #ifdef CONFIG_80211N_HT
8920                         case EID_HTCapability:
8921                                 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8922                                         if (!(is_ap_in_tkip(padapter)))
8923                                         {
8924                                                 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8925
8926                                                 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8927
8928                                                 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8929                                         }
8930                                 }
8931                                 break;
8932
8933                         case EID_EXTCapability:
8934                                 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8935                                         pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8936                                 }
8937                                 break;
8938 #endif //CONFIG_80211N_HT
8939 #ifdef CONFIG_80211AC_VHT
8940                         case EID_VHTCapability:
8941                                 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8942                                         pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8943                                 }
8944                                 break;
8945
8946                         case EID_OpModeNotification:
8947                                 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8948                                         pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
8949                                 }
8950                                 break;
8951 #endif // CONFIG_80211AC_VHT
8952                         default:
8953                                 break;
8954                 }
8955
8956                 i += (pIE->Length + 2);
8957         }
8958
8959         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8960         {
8961                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8962         }
8963
8964
8965 #ifdef CONFIG_WAPI_SUPPORT
8966         rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
8967 #endif
8968
8969
8970 #ifdef CONFIG_P2P
8971
8972 #ifdef CONFIG_IOCTL_CFG80211
8973         if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8974         {
8975                 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
8976                 {
8977                         _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
8978                         pframe += pmlmepriv->p2p_assoc_req_ie_len;
8979                         pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
8980                 }
8981         }
8982         else
8983 #endif //CONFIG_IOCTL_CFG80211
8984         {
8985                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
8986                 {
8987                         //      Should add the P2P IE in the association request frame. 
8988                         //      P2P OUI
8989                         
8990                         p2pielen = 0;
8991                         p2pie[ p2pielen++ ] = 0x50;
8992                         p2pie[ p2pielen++ ] = 0x6F;
8993                         p2pie[ p2pielen++ ] = 0x9A;
8994                         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
8995
8996                         //      Commented by Albert 20101109
8997                         //      According to the P2P Specification, the association request frame should contain 3 P2P attributes
8998                         //      1. P2P Capability
8999                         //      2. Extended Listen Timing
9000                         //      3. Device Info
9001                         //      Commented by Albert 20110516
9002                         //      4. P2P Interface
9003
9004                         //      P2P Capability
9005                         //      Type:
9006                         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
9007
9008                         //      Length:
9009                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
9010                         p2pielen += 2;
9011
9012                         //      Value:
9013                         //      Device Capability Bitmap, 1 byte
9014                         p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
9015
9016                         //      Group Capability Bitmap, 1 byte
9017                         if ( pwdinfo->persistent_supported )
9018                                 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9019                         else
9020                                 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
9021
9022                         //      Extended Listen Timing
9023                         //      Type:
9024                         p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
9025
9026                         //      Length:
9027                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
9028                         p2pielen += 2;
9029
9030                         //      Value:
9031                         //      Availability Period
9032                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9033                         p2pielen += 2;
9034
9035                         //      Availability Interval
9036                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9037                         p2pielen += 2;
9038
9039                         //      Device Info
9040                         //      Type:
9041                         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
9042
9043                         //      Length:
9044                         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
9045                         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
9046                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
9047                         p2pielen += 2;
9048
9049                         //      Value:
9050                         //      P2P Device Address
9051                         _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9052                         p2pielen += ETH_ALEN;
9053
9054                         //      Config Method
9055                         //      This field should be big endian. Noted by P2P specification.
9056                         if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
9057                                 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
9058                         {
9059                                 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
9060                         }
9061                         else
9062                         {
9063                                 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
9064                         }
9065
9066                         p2pielen += 2;
9067
9068                         //      Primary Device Type
9069                         //      Category ID
9070                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
9071                         p2pielen += 2;
9072
9073                         //      OUI
9074                         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
9075                         p2pielen += 4;
9076
9077                         //      Sub Category ID
9078                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
9079                         p2pielen += 2;
9080
9081                         //      Number of Secondary Device Types
9082                         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
9083
9084                         //      Device Name
9085                         //      Type:
9086                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
9087                         p2pielen += 2;
9088
9089                         //      Length:
9090                         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
9091                         p2pielen += 2;
9092
9093                         //      Value:
9094                         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
9095                         p2pielen += pwdinfo->device_name_len;
9096                 
9097                         //      P2P Interface
9098                         //      Type:
9099                         p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
9100                         
9101                         //      Length:
9102                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
9103                         p2pielen += 2;
9104                         
9105                         //      Value:
9106                         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );        //      P2P Device Address
9107                         p2pielen += ETH_ALEN;
9108
9109                         p2pie[ p2pielen++ ] = 1;        //      P2P Interface Address Count
9110                         
9111                         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );        //      P2P Interface Address List
9112                         p2pielen += ETH_ALEN;
9113                 
9114                         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
9115                 }
9116         }
9117
9118 #endif //CONFIG_P2P
9119
9120 #ifdef CONFIG_WFD
9121         wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
9122         pframe += wfdielen;
9123         pattrib->pktlen += wfdielen;
9124 #endif
9125
9126         pattrib->last_txcmdsz = pattrib->pktlen;
9127         dump_mgntframe(padapter, pmgntframe);
9128
9129         ret = _SUCCESS;
9130
9131 exit:
9132         if (ret == _SUCCESS)
9133                 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9134         else
9135                 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9136
9137         return;
9138 }
9139
9140 //when wait_ack is ture, this function shoule be called at process context
9141 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9142 {
9143         int ret = _FAIL;
9144         struct xmit_frame                       *pmgntframe;
9145         struct pkt_attrib                       *pattrib;
9146         unsigned char                                   *pframe;
9147         struct rtw_ieee80211_hdr        *pwlanhdr;
9148         unsigned short                          *fctrl;
9149         struct xmit_priv        *pxmitpriv;
9150         struct mlme_ext_priv    *pmlmeext;
9151         struct mlme_ext_info    *pmlmeinfo;
9152
9153         //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
9154
9155         if(!padapter)
9156                 goto exit;
9157
9158         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9159                 goto exit;
9160
9161         pxmitpriv = &(padapter->xmitpriv);
9162         pmlmeext = &(padapter->mlmeextpriv);
9163         pmlmeinfo = &(pmlmeext->mlmext_info);
9164
9165         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9166         {
9167                 goto exit;
9168         }
9169
9170         //update attribute
9171         pattrib = &pmgntframe->attrib;
9172         update_mgntframe_attrib(padapter, pattrib);
9173         pattrib->retry_ctrl = _FALSE;
9174
9175         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9176
9177         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9178         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9179
9180         fctrl = &(pwlanhdr->frame_ctl);
9181         *(fctrl) = 0;
9182
9183         if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9184         {
9185                 SetFrDs(fctrl);
9186         }
9187         else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9188         {
9189                 SetToDs(fctrl);
9190         }
9191         
9192         if (power_mode)
9193         {
9194                 SetPwrMgt(fctrl);
9195         }
9196
9197         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9198         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9199         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9200
9201         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9202         pmlmeext->mgnt_seq++;
9203         SetFrameSubType(pframe, WIFI_DATA_NULL);
9204
9205         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9206         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9207
9208         pattrib->last_txcmdsz = pattrib->pktlen;
9209
9210         if(wait_ack)
9211         {
9212                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9213         }
9214         else
9215         {
9216                 dump_mgntframe(padapter, pmgntframe);
9217                 ret = _SUCCESS;
9218         }
9219
9220 exit:
9221         return ret;
9222 }
9223
9224 /*
9225  * [IMPORTANT] Don't call this function in interrupt context
9226  *
9227  * When wait_ms > 0, this function should be called at process context
9228  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9229  * 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
9230  * try_cnt means the maximal TX count to try
9231  * da == NULL for station mode
9232  */
9233 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9234 {
9235         int ret = _FAIL;
9236         int i = 0;
9237         u32 start = rtw_get_current_time();
9238         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9239         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9240         struct sta_info *psta;
9241
9242         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9243                 goto exit;
9244
9245         /* da == NULL, assum it's null data for sta to ap*/
9246         if (da == NULL)
9247                 da = get_my_bssid(&(pmlmeinfo->network));
9248
9249         psta = rtw_get_stainfo(&padapter->stapriv, da);
9250         if (psta) {
9251                 if (power_mode)
9252                         rtw_hal_macid_sleep(padapter, psta->mac_id);
9253                 else
9254                         rtw_hal_macid_wakeup(padapter, psta->mac_id);
9255         } else {
9256                 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
9257                         FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
9258                 rtw_warn_on(1);
9259         }
9260
9261         do {
9262                 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
9263
9264                 i++;
9265
9266                 if (RTW_CANNOT_RUN(padapter))
9267                         break;
9268
9269                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9270                         rtw_msleep_os(wait_ms);
9271
9272         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9273
9274         if (ret != _FAIL) {
9275                 ret = _SUCCESS;
9276                 #ifndef DBG_XMIT_ACK
9277                 goto exit;
9278                 #endif
9279         }
9280
9281         if (try_cnt && wait_ms) {
9282                 if (da)
9283                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9284                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9285                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9286                 else
9287                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9288                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9289                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9290         }
9291 exit:
9292         return ret;
9293 }
9294
9295 /*
9296  * [IMPORTANT] This function run in interrupt context
9297  *
9298  * The null data packet would be sent without power bit,
9299  * and not guarantee success.
9300  */
9301 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
9302 {
9303         int ret;
9304         struct mlme_ext_priv *pmlmeext;
9305         struct mlme_ext_info *pmlmeinfo;
9306
9307
9308         pmlmeext = &padapter->mlmeextpriv;
9309         pmlmeinfo = &pmlmeext->mlmext_info;
9310
9311         /* da == NULL, assum it's null data for sta to ap*/
9312         if (da == NULL)
9313                 da = get_my_bssid(&(pmlmeinfo->network));
9314
9315         ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
9316
9317         return ret;
9318 }
9319
9320 //when wait_ack is ture, this function shoule be called at process context
9321 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
9322 {
9323         int ret = _FAIL;
9324         struct xmit_frame                       *pmgntframe;
9325         struct pkt_attrib                       *pattrib;
9326         unsigned char                                   *pframe;
9327         struct rtw_ieee80211_hdr        *pwlanhdr;
9328         unsigned short                          *fctrl, *qc;
9329         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
9330         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9331         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9332
9333         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9334                 goto exit;
9335
9336         DBG_871X("%s\n", __FUNCTION__);
9337
9338         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9339         {
9340                 goto exit;
9341         }
9342
9343         //update attribute
9344         pattrib = &pmgntframe->attrib;
9345         update_mgntframe_attrib(padapter, pattrib);
9346
9347         pattrib->hdrlen +=2;
9348         pattrib->qos_en = _TRUE;
9349         pattrib->eosp = 1;
9350         pattrib->ack_policy = 0;
9351         pattrib->mdata = 0;
9352
9353         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9354
9355         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9356         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9357
9358         fctrl = &(pwlanhdr->frame_ctl);
9359         *(fctrl) = 0;
9360
9361         if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9362         {
9363                 SetFrDs(fctrl);
9364         }
9365         else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9366         {
9367                 SetToDs(fctrl);
9368         }
9369
9370         if(pattrib->mdata)
9371                 SetMData(fctrl);
9372
9373         qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9374         
9375         SetPriority(qc, tid);
9376
9377         SetEOSP(qc, pattrib->eosp);
9378
9379         SetAckpolicy(qc, pattrib->ack_policy);
9380
9381         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9382         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9383         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9384
9385         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9386         pmlmeext->mgnt_seq++;
9387         SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
9388
9389         pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9390         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9391
9392         pattrib->last_txcmdsz = pattrib->pktlen;
9393         
9394         if(wait_ack)
9395         {
9396                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9397         }
9398         else
9399         {
9400                 dump_mgntframe(padapter, pmgntframe);
9401                 ret = _SUCCESS;
9402         }
9403
9404 exit:
9405         return ret;
9406 }
9407
9408 /*
9409  * when wait_ms >0 , this function should be called at process context
9410  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9411  * 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
9412  * try_cnt means the maximal TX count to try
9413  * da == NULL for station mode
9414  */
9415 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
9416 {
9417         int ret = _FAIL;
9418         int i = 0;
9419         u32 start = rtw_get_current_time();
9420         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9421         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9422
9423         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9424                 goto exit;
9425
9426         /* da == NULL, assum it's null data for sta to ap*/
9427         if (da == NULL)
9428                 da = get_my_bssid(&(pmlmeinfo->network));
9429         
9430         do
9431         {
9432                 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
9433
9434                 i++;
9435
9436                 if (RTW_CANNOT_RUN(padapter))
9437                         break;
9438
9439                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9440                         rtw_msleep_os(wait_ms);
9441
9442         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9443
9444         if (ret != _FAIL) {
9445                 ret = _SUCCESS;
9446                 #ifndef DBG_XMIT_ACK
9447                 goto exit;
9448                 #endif
9449         }
9450
9451         if (try_cnt && wait_ms) {
9452                 if (da)
9453                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9454                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9455                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9456                 else
9457                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9458                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9459                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9460         }
9461 exit:
9462         return ret;
9463 }
9464
9465 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9466 {
9467         struct xmit_frame                       *pmgntframe;
9468         struct pkt_attrib                       *pattrib;
9469         unsigned char                                   *pframe;
9470         struct rtw_ieee80211_hdr        *pwlanhdr;
9471         unsigned short                          *fctrl;
9472         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
9473         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9474         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9475         int ret = _FAIL;
9476 #ifdef CONFIG_P2P
9477         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
9478 #endif //CONFIG_P2P     
9479
9480         //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9481
9482 #ifdef CONFIG_P2P
9483         if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
9484         {
9485                 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
9486                 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
9487         }
9488 #endif //CONFIG_P2P
9489
9490         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9491                 goto exit;
9492
9493         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9494         {
9495                 goto exit;
9496         }
9497
9498         //update attribute
9499         pattrib = &pmgntframe->attrib;
9500         update_mgntframe_attrib(padapter, pattrib);
9501         pattrib->retry_ctrl = _FALSE;
9502         pattrib->key_type = key_type;
9503         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9504
9505         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9506         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9507
9508         fctrl = &(pwlanhdr->frame_ctl);
9509         *(fctrl) = 0;
9510
9511         _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9512         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9513         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9514
9515         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9516         pmlmeext->mgnt_seq++;
9517         SetFrameSubType(pframe, WIFI_DEAUTH);
9518
9519         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9520         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9521
9522         reason = cpu_to_le16(reason);
9523         pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9524
9525         pattrib->last_txcmdsz = pattrib->pktlen;
9526
9527
9528         if(wait_ack)
9529         {
9530                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9531         }
9532         else
9533         {
9534                 dump_mgntframe(padapter, pmgntframe);
9535                 ret = _SUCCESS;
9536         }
9537
9538 exit:
9539         return ret;
9540 }
9541
9542 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9543 {
9544         DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9545         return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9546 }
9547
9548 #ifdef CONFIG_IEEE80211W
9549 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9550 {
9551         DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9552         return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9553 }
9554 #endif /* CONFIG_IEEE80211W */
9555
9556 /*
9557  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9558  * 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
9559  * try_cnt means the maximal TX count to try
9560  */
9561 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9562         int wait_ms)
9563 {
9564         int ret = _FAIL;
9565         int i = 0;
9566         u32 start = rtw_get_current_time();
9567
9568         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9569                 goto exit;
9570
9571         do
9572         {
9573                 ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE:_FALSE, IEEE80211W_RIGHT_KEY);
9574
9575                 i++;
9576
9577                 if (RTW_CANNOT_RUN(padapter))
9578                         break;
9579
9580                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9581                         rtw_msleep_os(wait_ms);
9582
9583         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9584
9585         if (ret != _FAIL) {
9586                 ret = _SUCCESS;
9587                 #ifndef DBG_XMIT_ACK
9588                 goto exit;
9589                 #endif
9590         }
9591
9592         if (try_cnt && wait_ms) {
9593                 if (da)
9594                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9595                                 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9596                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9597                 else
9598                         DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9599                                 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9600                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9601         }
9602 exit:
9603         return ret;
9604 }
9605
9606 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9607 {       
9608         _irqL   irqL;
9609         _list           *plist, *phead;
9610         struct xmit_frame                       *pmgntframe;
9611         struct pkt_attrib                       *pattrib;
9612         unsigned char                           *pframe;
9613         struct rtw_ieee80211_hdr        *pwlanhdr;
9614         unsigned short                  *fctrl;
9615         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
9616         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9617         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9618         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9619
9620         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9621                 return;
9622
9623         DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9624                 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9625
9626         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9627                 return;
9628
9629         //update attribute
9630         pattrib = &pmgntframe->attrib;
9631         update_mgntframe_attrib(padapter, pattrib);
9632
9633         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9634
9635         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9636         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9637
9638         fctrl = &(pwlanhdr->frame_ctl);
9639         *(fctrl) = 0;
9640
9641         _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9642         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9643         _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9644
9645         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9646         pmlmeext->mgnt_seq++;
9647         SetFrameSubType(pframe, WIFI_ACTION);
9648
9649         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9650         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9651
9652         /* category, action */
9653         {
9654                 u8 category, action;
9655                 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9656                 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9657
9658                 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9659                 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9660         }
9661
9662         pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9663         pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9664                 hal_ch_offset_to_secondary_ch_offset(ch_offset));
9665
9666         pattrib->last_txcmdsz = pattrib->pktlen;
9667
9668         dump_mgntframe(padapter, pmgntframe);
9669
9670 }
9671
9672 #ifdef CONFIG_IEEE80211W
9673 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9674 {
9675         u8      category = RTW_WLAN_CATEGORY_SA_QUERY;
9676         u16     reason_code;
9677         struct xmit_frame               *pmgntframe;
9678         struct pkt_attrib               *pattrib;
9679         u8                                      *pframe;
9680         struct rtw_ieee80211_hdr        *pwlanhdr;
9681         u16                                     *fctrl;
9682         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
9683         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9684         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9685         struct sta_info         *psta;
9686         struct sta_priv         *pstapriv = &padapter->stapriv;
9687         struct registry_priv            *pregpriv = &padapter->registrypriv;
9688         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9689
9690         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9691                 return;
9692
9693         DBG_871X("%s, %04x\n", __FUNCTION__, tid);
9694
9695         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9696         {
9697                 DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9698                 return;
9699         }
9700
9701         //update attribute
9702         pattrib = &pmgntframe->attrib;
9703         update_mgntframe_attrib(padapter, pattrib);
9704         pattrib->key_type = key_type;
9705         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9706
9707         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9708         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9709
9710         fctrl = &(pwlanhdr->frame_ctl);
9711         *(fctrl) = 0;
9712
9713         if(raddr)
9714                 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9715         else
9716                 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9717         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9718         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9719
9720         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9721         pmlmeext->mgnt_seq++;
9722         SetFrameSubType(pframe, WIFI_ACTION);
9723
9724         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9725         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9726
9727         pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9728         pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9729
9730         switch (action)
9731         {
9732                 case 0: //SA Query req
9733                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9734                         pmlmeext->sa_query_seq++;
9735                         /* send sa query request to AP, AP should reply sa query response in 1 second */
9736                         if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9737                                 psta = rtw_get_stainfo(pstapriv, raddr);
9738                                 if (psta != NULL) {
9739                                         /* DBG_871X("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9740                                         _set_timer(&psta->dot11w_expire_timer, 1000);
9741                                 }
9742                         }
9743                         break;
9744
9745                 case 1: //SA Query rsp
9746                         tid = cpu_to_le16(tid);
9747                         /* DBG_871X("rtw_set_fixed_ie, %04x\n", tid); */
9748                         pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9749                         break;
9750                 default:
9751                         break;
9752         }
9753
9754         pattrib->last_txcmdsz = pattrib->pktlen;
9755
9756         dump_mgntframe(padapter, pmgntframe);
9757 }
9758 #endif //CONFIG_IEEE80211W
9759
9760 /**
9761  * issue_action_ba - internal function to TX Block Ack action frame
9762  * @padapter: the adapter to TX
9763  * @raddr: receiver address
9764  * @action: Block Ack Action
9765  * @tid: tid
9766  * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9767  * @status: status/reason code. used by ADDBA_RESP, DELBA
9768  * @initiator: if we are the initiator of AMPDU association. used by DELBA
9769  * @wait_ack: used xmit ack
9770  *
9771  * Returns:
9772  * _SUCCESS: No xmit ack is used or acked
9773  * _FAIL: not acked when using xmit ack
9774  */
9775 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9776         , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9777 {
9778         int ret = _FAIL;
9779         u8      category = RTW_WLAN_CATEGORY_BACK;
9780         u16     start_seq;
9781         u16     BA_para_set;
9782         u16     BA_timeout_value;
9783         u16     BA_starting_seqctrl;
9784         struct xmit_frame               *pmgntframe;
9785         struct pkt_attrib               *pattrib;
9786         u8                                      *pframe;
9787         struct rtw_ieee80211_hdr        *pwlanhdr;
9788         u16                                     *fctrl;
9789         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
9790         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
9791         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
9792         struct sta_info         *psta;
9793         struct sta_priv         *pstapriv = &padapter->stapriv;
9794         struct registry_priv            *pregpriv = &padapter->registrypriv;
9795
9796 #ifdef CONFIG_80211N_HT
9797
9798         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9799                 goto exit;
9800
9801         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9802                 goto exit;
9803
9804         //update attribute
9805         pattrib = &pmgntframe->attrib;
9806         update_mgntframe_attrib(padapter, pattrib);
9807
9808         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9809
9810         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9811         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9812
9813         fctrl = &(pwlanhdr->frame_ctl);
9814         *(fctrl) = 0;
9815
9816         //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9817         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9818         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9819         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9820
9821         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9822         pmlmeext->mgnt_seq++;
9823         SetFrameSubType(pframe, WIFI_ACTION);
9824
9825         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9826         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9827
9828         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9829         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9830
9831         if (category == 3)
9832         {
9833                 switch (action)
9834                 {
9835                         case RTW_WLAN_ACTION_ADDBA_REQ:
9836                                 do {
9837                                         pmlmeinfo->dialogToken++;
9838                                 } while (pmlmeinfo->dialogToken == 0);
9839                                 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9840
9841                                 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9842                                 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9843                                 #else
9844                                 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9845                                 #endif
9846
9847                                 BA_para_set = cpu_to_le16(BA_para_set);
9848                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9849
9850                                 //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
9851                                 BA_timeout_value = 5000;//~ 5ms
9852                                 BA_timeout_value = cpu_to_le16(BA_timeout_value);
9853                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9854
9855                                 //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
9856                                 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
9857                                 {
9858                                         start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1;
9859
9860                                         DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9861                                         
9862                                         psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9863                                         
9864                                         BA_starting_seqctrl = start_seq << 4;
9865                                 }
9866                                 
9867                                 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9868                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9869                                 break;
9870
9871                         case RTW_WLAN_ACTION_ADDBA_RESP:
9872                                 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9873                                 status = cpu_to_le16(status);
9874                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9875
9876                                 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9877
9878                                 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9879                                 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9880
9881                                 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9882                                 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9883
9884                                 if (!padapter->registrypriv.wifi_spec) {
9885                                         if(pregpriv->ampdu_amsdu==0)//disabled
9886                                                 BA_para_set &= ~BIT(0);
9887                                         else if(pregpriv->ampdu_amsdu==1)//enabled
9888                                                 BA_para_set |= BIT(0);
9889                                 }
9890
9891                                 BA_para_set = cpu_to_le16(BA_para_set);
9892
9893                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9894                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9895                                 break;
9896
9897                         case RTW_WLAN_ACTION_DELBA:
9898                                 BA_para_set = 0;
9899                                 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9900                                 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9901
9902                                 BA_para_set = cpu_to_le16(BA_para_set);                         
9903                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9904                                 status = cpu_to_le16(status);
9905                                 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9906                                 break;
9907                         default:
9908                                 break;
9909                 }
9910         }
9911
9912         pattrib->last_txcmdsz = pattrib->pktlen;
9913
9914         if (wait_ack) {
9915                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9916         } else {
9917                 dump_mgntframe(padapter, pmgntframe);
9918                 ret = _SUCCESS;
9919         }
9920
9921 exit:
9922 #endif //CONFIG_80211N_HT
9923         return ret;
9924 }
9925
9926 /**
9927  * issue_addba_req - TX ADDBA_REQ
9928  * @adapter: the adapter to TX
9929  * @ra: receiver address
9930  * @tid: tid
9931  */
9932 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
9933 {
9934         issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
9935                 , tid
9936                 , 0 /* unused */
9937                 , 0 /* unused */
9938                 , 0 /* unused */
9939                 , _FALSE
9940         );
9941         DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
9942                 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
9943
9944 }
9945
9946 /**
9947  * issue_addba_rsp - TX ADDBA_RESP
9948  * @adapter: the adapter to TX
9949  * @ra: receiver address
9950  * @tid: tid
9951  * @status: status code
9952  * @size: the announced AMPDU buffer size
9953  */
9954 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
9955 {
9956         issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9957                 , tid
9958                 , size
9959                 , status
9960                 , 0 /* unused */
9961                 , _FALSE
9962         );
9963         DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
9964                 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
9965 }
9966
9967 /**
9968  * issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
9969  * @adapter: the adapter to TX
9970  * @ra: receiver address
9971  * @tid: tid
9972  * @status: status code
9973  * @size: the announced AMPDU buffer size
9974  * @try_cnt: the maximal TX count to try
9975  * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9976  *           > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9977  */
9978 inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
9979 {
9980         int ret = _FAIL;
9981         int i = 0;
9982         u32 start = rtw_get_current_time();
9983
9984         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
9985                 goto exit;
9986
9987         do {
9988                 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9989                         , tid
9990                         , size
9991                         , status
9992                         , 0 /* unused */
9993                         , _TRUE
9994                 );
9995
9996                 i++;
9997
9998                 if (RTW_CANNOT_RUN(adapter))
9999                         break;
10000
10001                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10002                         rtw_msleep_os(wait_ms);
10003
10004         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10005
10006         if (ret != _FAIL) {
10007                 ret = _SUCCESS;
10008         #ifndef DBG_XMIT_ACK
10009                 /* goto exit; */
10010         #endif
10011         }
10012
10013         if (try_cnt && wait_ms) {
10014                 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u%s, %d/%d in %u ms\n"
10015                         , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid
10016                         , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10017         }
10018
10019 exit:
10020         return ret;
10021 }
10022
10023 /**
10024  * issue_del_ba - TX DELBA
10025  * @adapter: the adapter to TX
10026  * @ra: receiver address
10027  * @tid: tid
10028  * @reason: reason code
10029  * @initiator: if we are the initiator of AMPDU association. used by DELBA
10030  */
10031 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10032 {
10033         issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10034                 , tid
10035                 , 0 /* unused */
10036                 , reason
10037                 , initiator
10038                 , _FALSE
10039         );
10040         DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10041                 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10042 }
10043
10044 /**
10045  * issue_del_ba_ex - TX DELBA with xmit ack options
10046  * @adapter: the adapter to TX
10047  * @ra: receiver address
10048  * @tid: tid
10049  * @reason: reason code
10050  * @initiator: if we are the initiator of AMPDU association. used by DELBA
10051  * @try_cnt: the maximal TX count to try
10052  * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10053  *           > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10054  */
10055 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10056         , int try_cnt, int wait_ms)
10057 {
10058         int ret = _FAIL;
10059         int i = 0;
10060         u32 start = rtw_get_current_time();
10061
10062         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
10063                 goto exit;
10064
10065         do {
10066                 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10067                         , tid
10068                         , 0 /* unused */
10069                         , reason
10070                         , initiator
10071                         , wait_ms > 0?_TRUE:_FALSE
10072                 );
10073
10074                 i++;
10075
10076                 if (RTW_CANNOT_RUN(adapter))
10077                         break;
10078
10079                 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10080                         rtw_msleep_os(wait_ms);
10081
10082         } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10083
10084         if (ret != _FAIL) {
10085                 ret = _SUCCESS;
10086         #ifndef DBG_XMIT_ACK
10087                 /* goto exit; */
10088         #endif
10089         }
10090
10091         if (try_cnt && wait_ms) {
10092                 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
10093                         , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
10094                         , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10095         }
10096 exit:
10097         return ret;
10098 }
10099
10100 static void issue_action_BSSCoexistPacket(_adapter *padapter)
10101 {       
10102         _irqL   irqL;
10103         _list           *plist, *phead;
10104         unsigned char category, action;
10105         struct xmit_frame                       *pmgntframe;
10106         struct pkt_attrib                       *pattrib;
10107         unsigned char                           *pframe;
10108         struct rtw_ieee80211_hdr        *pwlanhdr;
10109         unsigned short                  *fctrl;
10110         struct  wlan_network    *pnetwork = NULL;
10111         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
10112         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10113         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
10114         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10115         _queue          *queue  = &(pmlmepriv->scanned_queue);
10116         u8 InfoContent[16] = {0};
10117         u8 ICS[8][15];
10118 #ifdef CONFIG_80211N_HT 
10119         if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
10120                 return;
10121
10122         if(_TRUE == pmlmeinfo->bwmode_updated)
10123                 return;
10124
10125         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10126                 return; 
10127
10128         DBG_871X("%s\n", __FUNCTION__);
10129
10130
10131         category = RTW_WLAN_CATEGORY_PUBLIC;
10132         action = ACT_PUBLIC_BSSCOEXIST;
10133
10134         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10135         {
10136                 return;
10137         }
10138
10139         //update attribute
10140         pattrib = &pmgntframe->attrib;
10141         update_mgntframe_attrib(padapter, pattrib);
10142
10143         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10144
10145         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10146         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10147
10148         fctrl = &(pwlanhdr->frame_ctl);
10149         *(fctrl) = 0;
10150
10151         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10152         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10153         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10154
10155         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10156         pmlmeext->mgnt_seq++;
10157         SetFrameSubType(pframe, WIFI_ACTION);
10158
10159         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10160         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10161
10162         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10163         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10164
10165
10166         //
10167         if(pmlmepriv->num_FortyMHzIntolerant>0)
10168         {
10169                 u8 iedata=0;
10170                 
10171                 iedata |= BIT(2);//20 MHz BSS Width Request
10172
10173                 pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &(pattrib->pktlen));
10174                 
10175         }
10176         
10177
10178         //
10179         _rtw_memset(ICS, 0, sizeof(ICS));
10180         if(pmlmepriv->num_sta_no_ht>0)
10181         {       
10182                 int i;
10183         
10184                 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10185
10186                 phead = get_list_head(queue);
10187                 plist = get_next(phead);
10188        
10189                 while(1)
10190                 {
10191                         int len;
10192                         u8 *p;
10193                         WLAN_BSSID_EX *pbss_network;
10194         
10195                         if (rtw_end_of_queue_search(phead,plist)== _TRUE)
10196                                 break;          
10197
10198                         pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);      
10199                 
10200                         plist = get_next(plist);
10201
10202                         pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10203
10204                         p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10205                         if((p==NULL) || (len==0))//non-HT
10206                         {
10207                                 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
10208                                         continue;
10209                                 
10210                                 ICS[0][pbss_network->Configuration.DSConfig]=1;
10211                                 
10212                                 if(ICS[0][0] == 0)
10213                                         ICS[0][0] = 1;          
10214                         }               
10215         
10216                 }        
10217
10218                 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10219
10220
10221                 for(i= 0;i<8;i++)
10222                 {
10223                         if(ICS[i][0] == 1)
10224                         {
10225                                 int j, k = 0;
10226                                 
10227                                 InfoContent[k] = i;                             
10228                                 //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
10229                                 k++;
10230                                 
10231                                 for(j=1;j<=14;j++)
10232                                 {
10233                                         if(ICS[i][j]==1)
10234                                         {
10235                                                 if(k<16)
10236                                                 {
10237                                                         InfoContent[k] = j; //channel number
10238                                                         //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
10239                                                         k++;
10240                                                 }       
10241                                         }       
10242                                 }       
10243
10244                                 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10245                                 
10246                         }
10247                         
10248                 }
10249                 
10250
10251         }
10252                 
10253
10254         pattrib->last_txcmdsz = pattrib->pktlen;
10255
10256         dump_mgntframe(padapter, pmgntframe);
10257 #endif //CONFIG_80211N_HT
10258 }
10259
10260 // Spatial Multiplexing Powersave (SMPS) action frame
10261 int _issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode ,  u8 wait_ack)
10262 {
10263
10264         int ret = _FAIL;
10265         unsigned char category = RTW_WLAN_CATEGORY_HT;
10266         u8 action = RTW_WLAN_ACTION_HT_SM_PS;   
10267         u8 sm_power_control=0;
10268         struct xmit_frame                       *pmgntframe;
10269         struct pkt_attrib                       *pattrib;
10270         unsigned char                                   *pframe;
10271         struct rtw_ieee80211_hdr        *pwlanhdr;
10272         unsigned short                          *fctrl;
10273         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
10274         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
10275         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10276
10277
10278         if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED)
10279         {
10280                 sm_power_control = sm_power_control  & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable 
10281         }
10282         else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC)
10283         {
10284                 sm_power_control = sm_power_control | BIT(0);    // SM Power Save Enable = 1 SM Power Save Enable  
10285                 sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode
10286         }
10287         else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC)
10288         {
10289                 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable  
10290                 sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode
10291         }
10292         else 
10293                 return ret;
10294
10295         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10296                 return ret;
10297
10298         DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode );
10299     
10300         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10301                 return ret;
10302
10303         //update attribute
10304         pattrib = &pmgntframe->attrib;
10305         update_mgntframe_attrib(padapter, pattrib);
10306
10307         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10308
10309         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10310         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10311
10312         fctrl = &(pwlanhdr->frame_ctl);
10313         *(fctrl) = 0;
10314
10315         _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10316         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10317         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10318
10319         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10320         pmlmeext->mgnt_seq++;
10321         SetFrameSubType(pframe, WIFI_ACTION);
10322
10323         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10324         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10325
10326         /* category, action */
10327         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10328         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10329
10330         pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10331
10332         pattrib->last_txcmdsz = pattrib->pktlen;
10333
10334         if(wait_ack)
10335         {
10336                 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10337         }
10338         else
10339         {
10340                 dump_mgntframe(padapter, pmgntframe);
10341                 ret = _SUCCESS;
10342         }
10343
10344         if (ret != _SUCCESS)
10345             DBG_8192C("%s, ack to\n", __func__);
10346
10347         return ret;
10348 }
10349
10350 /*
10351  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10352  * 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
10353  * try_cnt means the maximal TX count to try
10354  */
10355 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10356 {
10357         int ret = _FAIL;
10358         int i = 0;
10359         u32 start = rtw_get_current_time();
10360
10361         if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10362                 goto exit;
10363
10364         do {
10365                 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE );
10366
10367                 i++;
10368
10369                 if (RTW_CANNOT_RUN(padapter))
10370                         break;
10371
10372                 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
10373                         rtw_msleep_os(wait_ms);
10374
10375         }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
10376
10377         if (ret != _FAIL) {
10378                 ret = _SUCCESS;
10379                 #ifndef DBG_XMIT_ACK
10380                 goto exit;
10381                 #endif
10382         }
10383
10384         if (try_cnt && wait_ms) {
10385                 if (raddr)
10386                         DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10387                                 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10388                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10389                 else
10390                         DBG_871X(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10391                                 FUNC_ADPT_ARG(padapter),
10392                                 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10393         }
10394 exit:
10395
10396         return ret;
10397 }
10398
10399 int issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode )
10400 {
10401         DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10402         return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE );
10403 }
10404
10405 /**
10406  * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10407  * @adapter: the adapter to which @sta belongs
10408  * @initiator: if we are the initiator of AMPDU association
10409  * @sta: the sta to be checked
10410  * @tid: the tid to be checked
10411  * @force: cancel and send DELBA even when no AMPDU association is setup
10412  * @wait_ack: send delba with xmit ack (valid when initiator == 0)
10413  *
10414  * Returns:
10415  * _FAIL if sta is NULL
10416  * when initiator is 1, always _SUCCESS
10417  * when initiator is 0, _SUCCESS if DELBA is acked
10418  */
10419 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10420         , u8 force, int wait_ack)
10421 {
10422         int ret = _SUCCESS;
10423
10424         if (sta == NULL) {
10425                 ret = _FAIL;
10426                 goto exit;
10427         }
10428
10429         if (initiator == 0) {
10430                 /* recipient */
10431                 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10432                         u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10433
10434                         sta->recvreorder_ctrl[tid].enable = _FALSE;
10435                         sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10436
10437                         if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10438                                 ret = _FAIL;
10439                         else if (wait_ack)
10440                                 ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
10441                         else
10442                                 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10443
10444                         if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10445                                 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10446                 }
10447         } else if (initiator == 1) {
10448                 /* originator */
10449 #ifdef CONFIG_80211N_HT
10450                 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10451                         sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10452                         sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10453                         issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10454                 }
10455 #endif
10456         }
10457
10458 exit:
10459         return ret;
10460 }
10461
10462 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10463         , u8 force)
10464 {
10465         return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10466 }
10467
10468 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10469         , u8 force)
10470 {
10471         return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10472 }
10473
10474 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10475 {
10476         struct sta_priv *pstapriv = &padapter->stapriv;
10477         struct sta_info *psta = NULL;
10478         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10479         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10480         u16 tid;
10481
10482         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
10483                 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10484                         return _SUCCESS;
10485
10486         psta = rtw_get_stainfo(pstapriv, addr);
10487         if(psta==NULL)
10488                 return _SUCCESS;
10489
10490         #if 0
10491         DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR");
10492         if (initiator == 1) /* originator */
10493                 DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10494         #endif
10495
10496         for (tid = 0; tid < TID_NUM; tid++)
10497                 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10498
10499         return _SUCCESS;
10500 }
10501
10502 unsigned int send_beacon(_adapter *padapter)
10503 {
10504         u8      bxmitok = _FALSE;
10505         int     issue=0;
10506         int poll = 0;
10507 #if defined(CONFIG_PCI_HCI) && defined(RTL8814AE_SW_BCN)
10508         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
10509 #endif
10510 //#ifdef CONFIG_CONCURRENT_MODE
10511         //struct mlme_ext_priv  *pmlmeext = &(padapter->mlmeextpriv);
10512         //struct mlme_ext_info  *pmlmeinfo = &(pmlmeext->mlmext_info);
10513         //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
10514         //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
10515 //#endif                
10516
10517 #ifdef CONFIG_PCI_HCI
10518         //DBG_871X("%s\n", __FUNCTION__);
10519
10520         rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10521
10522         /* 8192EE Port select for Beacon DL */
10523         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10524
10525         issue_beacon(padapter, 0);
10526
10527 #ifdef RTL8814AE_SW_BCN
10528         if (pHalData->bCorrectBCN != 0)
10529                 DBG_871X("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
10530         pHalData->bCorrectBCN = 1;
10531 #endif
10532
10533         return _SUCCESS;
10534 #endif
10535
10536 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10537         u32 start = rtw_get_current_time();
10538
10539         rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10540         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10541         do{
10542                 issue_beacon(padapter, 100);
10543                 issue++;
10544                 do {
10545                         rtw_yield_os();
10546                         rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10547                         poll++;
10548                 } while ((poll%10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10549
10550         } while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter));
10551
10552         if (RTW_CANNOT_RUN(padapter))
10553                 return _FAIL;
10554
10555         
10556         if(_FALSE == bxmitok)
10557         {
10558                 DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10559                 return _FAIL;
10560         }
10561         else
10562         {
10563                 u32 passing_time = rtw_get_passing_time_ms(start);
10564
10565                 if(passing_time > 100 || issue > 3)
10566                         DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10567                 //else
10568                 //      DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10569                 
10570                 rtw_hal_fw_correct_bcn(padapter);
10571
10572                 return _SUCCESS;
10573         }
10574
10575 #endif
10576
10577 }
10578
10579 /****************************************************************************
10580
10581 Following are some utitity fuctions for WiFi MLME
10582
10583 *****************************************************************************/
10584
10585 BOOLEAN IsLegal5GChannel(
10586         IN PADAPTER                     Adapter,
10587         IN u8                   channel)
10588 {
10589         
10590         int i=0;
10591         u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
10592                 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
10593                 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
10594                 161,163,165};
10595         for(i=0;i<sizeof(Channel_5G);i++)
10596                 if(channel == Channel_5G[i])
10597                         return _TRUE;
10598         return _FALSE;
10599 }
10600
10601 //collect bss info from Beacon and Probe request/response frames.
10602 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10603 {
10604         int     i;
10605         u32     len;
10606         u8      *p;
10607         u16     val16, subtype;
10608         u8      *pframe = precv_frame->u.hdr.rx_data;
10609         u32     packet_len = precv_frame->u.hdr.len;
10610         u8 ie_offset;
10611         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
10612         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10613         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10614
10615         len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10616
10617         if (len > MAX_IE_SZ)
10618         {
10619                 //DBG_871X("IE too long for survey event\n");
10620                 return _FAIL;
10621         }
10622
10623         _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10624
10625         subtype = GetFrameSubType(pframe);
10626
10627         if(subtype==WIFI_BEACON) {
10628                 bssid->Reserved[0] = 1;
10629                 ie_offset = _BEACON_IE_OFFSET_;
10630         } else {
10631                 // FIXME : more type
10632                 if (subtype == WIFI_PROBERSP) {
10633                         ie_offset = _PROBERSP_IE_OFFSET_;
10634                         bssid->Reserved[0] = 3;
10635                 }
10636                 else if (subtype == WIFI_PROBEREQ) {
10637                         ie_offset = _PROBEREQ_IE_OFFSET_;
10638                         bssid->Reserved[0] = 2;
10639                 }
10640                 else {
10641                         bssid->Reserved[0] = 0;
10642                         ie_offset = _FIXED_IE_LENGTH_;
10643                 }
10644         }
10645                 
10646         bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10647
10648         //below is to copy the information element
10649         bssid->IELength = len;
10650         _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10651
10652         //get the signal strength
10653         //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
10654         bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data    
10655         bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage 
10656         bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
10657 #ifdef CONFIG_ANTENNA_DIVERSITY
10658         rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
10659 #endif
10660
10661         // checking SSID
10662         if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
10663         {
10664                 DBG_871X("marc: cannot find SSID for survey event\n");
10665                 return _FAIL;
10666         }
10667
10668         if (*(p + 1))
10669         {
10670                 if (len > NDIS_802_11_LENGTH_SSID)
10671                 {
10672                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10673                         return _FAIL;
10674                 }
10675                 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10676                 bssid->Ssid.SsidLength = *(p + 1);
10677         }
10678         else
10679         {
10680                 bssid->Ssid.SsidLength = 0;
10681         }
10682
10683         _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10684
10685         //checking rate info...
10686         i = 0;
10687         p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10688         if (p != NULL)
10689         {
10690                 if (len > NDIS_802_11_LENGTH_RATES_EX)
10691                 {
10692                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10693                         return _FAIL;
10694                 }
10695                 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10696                 i = len;
10697         }
10698
10699         p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10700         if (p != NULL)
10701         {
10702                 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
10703                 {
10704                         DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10705                         return _FAIL;
10706                 }
10707                 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10708         }
10709
10710         //todo:
10711 #if 0
10712         if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10713         {
10714                 bssid->NetworkTypeInUse = Ndis802_11DS;
10715         }
10716         else
10717 #endif
10718         {
10719                 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10720         }
10721
10722 #ifdef CONFIG_P2P
10723         if (subtype == WIFI_PROBEREQ)
10724         {
10725                 u8 *p2p_ie;
10726                 u32     p2p_ielen;
10727                 // Set Listion Channel
10728                 if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen)))
10729                 {
10730                         u32     attr_contentlen = 0;
10731                         u8 listen_ch[5] = { 0x00 };
10732
10733                         rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10734                         bssid->Configuration.DSConfig = listen_ch[4];
10735                 } else
10736                 { // use current channel
10737                         bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10738                         DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10739                 }
10740
10741                 // FIXME
10742                 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10743                 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10744                 bssid->Privacy = 1;
10745                 return _SUCCESS;
10746         }
10747 #endif //CONFIG_P2P
10748
10749         if (bssid->IELength < 12)
10750                 return _FAIL;
10751
10752         // Checking for DSConfig
10753         p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10754
10755         bssid->Configuration.DSConfig = 0;
10756         bssid->Configuration.Length = 0;
10757
10758         if (p)
10759         {
10760                 bssid->Configuration.DSConfig = *(p + 2);
10761         }
10762         else
10763         {// In 5G, some ap do not have DSSET IE
10764                 // checking HT info for channel
10765                 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10766                 if(p)
10767                 {
10768                         struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10769                         bssid->Configuration.DSConfig = HT_info->primary_channel;
10770                 }
10771                 else
10772                 { // use current channel
10773                         bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
10774                 }
10775         }
10776
10777         _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
10778         bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
10779
10780         val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
10781
10782         if (val16 & BIT(0))
10783         {
10784                 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10785                 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10786         }
10787         else
10788         {
10789                 bssid->InfrastructureMode = Ndis802_11IBSS;
10790                 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10791         }
10792
10793         if (val16 & BIT(4))
10794                 bssid->Privacy = 1;
10795         else
10796                 bssid->Privacy = 0;
10797
10798         bssid->Configuration.ATIMWindow = 0;
10799
10800         //20/40 BSS Coexistence check
10801         if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
10802         {       
10803                 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10804 #ifdef CONFIG_80211N_HT
10805                 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10806                 if(p && len>0)
10807                 {
10808                         struct HT_caps_element  *pHT_caps;
10809                         pHT_caps = (struct HT_caps_element      *)(p + 2);
10810                         
10811                         if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
10812                         {                               
10813                                 pmlmepriv->num_FortyMHzIntolerant++;
10814                         }
10815                 }
10816                 else
10817                 {
10818                         pmlmepriv->num_sta_no_ht++;
10819                 }
10820 #endif //CONFIG_80211N_HT
10821                 
10822         }
10823
10824 #ifdef CONFIG_INTEL_WIDI
10825         //process_intel_widi_query_or_tigger(padapter, bssid);
10826         if(process_intel_widi_query_or_tigger(padapter, bssid))
10827         {
10828                 return _FAIL;
10829         }
10830 #endif // CONFIG_INTEL_WIDI
10831
10832         #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10833         if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10834                 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10835                         , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10836                         , rtw_get_oper_ch(padapter)
10837                         , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10838                 );
10839         }
10840         #endif
10841
10842         // mark bss info receving from nearby channel as SignalQuality 101
10843         if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10844         {
10845                 bssid->PhyInfo.SignalQuality= 101;
10846         }
10847
10848         return _SUCCESS;
10849 }
10850
10851 void start_create_ibss(_adapter* padapter)
10852 {
10853         unsigned short  caps;
10854         u8      val8;
10855         u8      join_type;
10856         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10857         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10858         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10859         u8 doiqk = _FALSE;
10860         pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10861         pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10862
10863         //update wireless mode
10864         update_wireless_mode(padapter);
10865
10866         //udpate capability
10867         caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10868         update_capinfo(padapter, caps);
10869         if(caps&cap_IBSS)//adhoc master
10870         {
10871                 //set_opmode_cmd(padapter, adhoc);//removed
10872
10873                 val8 = 0xcf;
10874                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10875
10876                 doiqk = _TRUE;
10877                 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10878
10879                 //switch channel
10880                 //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
10881                 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10882
10883                 doiqk = _FALSE;
10884                 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10885
10886                 beacon_timing_control(padapter);
10887
10888                 //set msr to WIFI_FW_ADHOC_STATE
10889                 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10890                 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10891
10892                 //issue beacon
10893                 if(send_beacon(padapter)==_FAIL)
10894                 {
10895                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
10896
10897                         report_join_res(padapter, -1);
10898                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
10899                 }
10900                 else
10901                 {
10902                         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10903                         join_type = 0;
10904                         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10905
10906                         report_join_res(padapter, 1);
10907                         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10908                         rtw_indicate_connect(padapter);
10909                 }
10910         }
10911         else
10912         {
10913                 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
10914                 return;
10915         }
10916         //update bc/mc sta_info
10917         update_bmc_sta(padapter);
10918
10919 }
10920
10921 void start_clnt_join(_adapter* padapter)
10922 {
10923         unsigned short  caps;
10924         u8      val8;
10925         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
10926         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
10927         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10928         int beacon_timeout;
10929         u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
10930
10931         //update wireless mode
10932         update_wireless_mode(padapter);
10933
10934         //udpate capability
10935         caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10936         update_capinfo(padapter, caps);
10937         
10938         //check if sta is ASIX peer and fix IOT issue if it is.
10939         if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
10940                 u8 iot_flag = _TRUE;
10941                 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10942         }
10943         
10944         if (caps&cap_ESS)
10945         {
10946                 Set_MSR(padapter, WIFI_FW_STATION_STATE);
10947
10948                 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
10949
10950 #ifdef CONFIG_WAPI_SUPPORT
10951                 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
10952                 {
10953                         //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
10954                         val8 = 0x4c;
10955                 }
10956 #endif
10957                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10958
10959                 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10960                 // Because of AP's not receiving deauth before
10961                 // AP may: 1)not response auth or 2)deauth us after link is complete
10962                 // issue deauth before issuing auth to deal with the situation
10963
10964                 //      Commented by Albert 2012/07/21
10965                 //      For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
10966                 {
10967                         #ifdef CONFIG_P2P
10968                         _queue *queue = &(padapter->mlmepriv.scanned_queue);
10969                         _list   *head = get_list_head(queue);
10970                         _list *pos = get_next(head);
10971                         struct wlan_network *scanned = NULL;
10972                         u8 ie_offset = 0;
10973                         _irqL irqL;
10974                         bool has_p2p_ie = _FALSE;
10975
10976                         _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10977
10978                         for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
10979                                 
10980                                 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
10981
10982                                 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
10983                                         && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
10984                                 ) {
10985                                         ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
10986                                         if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
10987                                                 has_p2p_ie = _TRUE;
10988                                         break;
10989                                 }
10990                         }
10991         
10992                         _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10993
10994                         if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
10995                         #endif /* CONFIG_P2P */
10996                                 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
10997                                 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
10998                 }
10999                 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11000
11001                 //here wait for receiving the beacon to start auth
11002                 //and enable a timer
11003                 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11004                 set_link_timer(pmlmeext, beacon_timeout);       
11005                 _set_timer( &padapter->mlmepriv.assoc_timer, 
11006                         (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
11007                 
11008                 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11009         }
11010         else if (caps&cap_IBSS) //adhoc client
11011         {
11012                 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11013
11014                 val8 = 0xcf;
11015                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11016
11017                 beacon_timing_control(padapter);
11018
11019                 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11020
11021                 report_join_res(padapter, 1);
11022         }
11023         else
11024         {
11025                 //DBG_871X("marc: invalid cap:%x\n", caps);
11026                 return;
11027         }
11028
11029 }
11030
11031 void start_clnt_auth(_adapter* padapter)
11032 {
11033         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11034         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11035
11036         _cancel_timer_ex(&pmlmeext->link_timer);
11037
11038         pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
11039         pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
11040
11041         pmlmeinfo->auth_seq = 1;
11042         pmlmeinfo->reauth_count = 0;
11043         pmlmeinfo->reassoc_count = 0;
11044         pmlmeinfo->link_count = 0;
11045         pmlmeext->retry = 0;
11046
11047
11048         DBG_871X_LEVEL(_drv_always_, "start auth\n");
11049         issue_auth(padapter, NULL, 0);
11050
11051         set_link_timer(pmlmeext, REAUTH_TO);
11052
11053 }
11054
11055
11056 void start_clnt_assoc(_adapter* padapter)
11057 {
11058         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11059         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11060
11061         _cancel_timer_ex(&pmlmeext->link_timer);
11062
11063         pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
11064         pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
11065
11066         issue_assocreq(padapter);
11067
11068         set_link_timer(pmlmeext, REASSOC_TO);
11069 }
11070
11071 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, u8 locally_generated)
11072 {
11073         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11074         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11075
11076         if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
11077                 return _SUCCESS;
11078
11079         DBG_871X("%s\n", __FUNCTION__);
11080
11081         if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11082         {
11083                 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11084                 {
11085                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
11086                         report_del_sta_event(padapter, MacAddr, reason, _TRUE, locally_generated);
11087
11088                 }
11089                 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
11090                 {
11091                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
11092                         report_join_res(padapter, -2);
11093                 } else
11094                         DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
11095         }
11096
11097         return _SUCCESS;
11098 }
11099
11100 #ifdef CONFIG_80211D
11101 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
11102 {
11103         struct registry_priv *pregistrypriv;
11104         struct mlme_ext_priv *pmlmeext;
11105         RT_CHANNEL_INFO *chplan_new;
11106         u8 channel;
11107         u8 i;
11108
11109
11110         pregistrypriv = &padapter->registrypriv;
11111         pmlmeext = &padapter->mlmeextpriv;
11112
11113         // Adjust channel plan by AP Country IE
11114         if (pregistrypriv->enable80211d &&
11115                 (!pmlmeext->update_channel_plan_by_ap_done))
11116         {
11117                 u8 *ie, *p;
11118                 u32 len;
11119                 RT_CHANNEL_PLAN chplan_ap;
11120                 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
11121                 u8 country[4];
11122                 u8 fcn; // first channel number
11123                 u8 noc; // number of channel
11124                 u8 j, k;
11125
11126                 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11127                 if (!ie) return;
11128                 if (len < 6) return;
11129
11130                 ie += 2;
11131                 p = ie;
11132                 ie += len;
11133
11134                 _rtw_memset(country, 0, 4);
11135                 _rtw_memcpy(country, p, 3);
11136                 p += 3;
11137                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11138                                 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
11139
11140                 i = 0;
11141                 while ((ie - p) >= 3)
11142                 {
11143                         fcn = *(p++);
11144                         noc = *(p++);
11145                         p++;
11146
11147                         for (j = 0; j < noc; j++)
11148                         {
11149                                 if (fcn <= 14) channel = fcn + j; // 2.4 GHz
11150                                 else channel = fcn + j*4; // 5 GHz
11151
11152                                 chplan_ap.Channel[i++] = channel;
11153                         }
11154                 }
11155                 chplan_ap.Len = i;
11156
11157 #ifdef CONFIG_DEBUG_RTL871X
11158                 i = 0;
11159                 DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11160                 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
11161                 {
11162                         DBG_8192C("%02d,", chplan_ap.Channel[i]);
11163                         i++;
11164                 }
11165                 DBG_871X("}\n");
11166 #endif
11167
11168                 _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
11169 #ifdef CONFIG_DEBUG_RTL871X
11170                 i = 0;
11171                 DBG_871X("%s: STA channel plan {", __FUNCTION__);
11172                 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11173                 {
11174                         DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
11175                         i++;
11176                 }
11177                 DBG_871X("}\n");
11178 #endif
11179
11180                 _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
11181                 chplan_new = pmlmeext->channel_set;
11182
11183                 i = j = k = 0;
11184                 if (pregistrypriv->wireless_mode & WIRELESS_11G)
11185                 {
11186                         do {
11187                                 if ((i == MAX_CHANNEL_NUM) ||
11188                                         (chplan_sta[i].ChannelNum == 0) ||
11189                                         (chplan_sta[i].ChannelNum > 14))
11190                                         break;
11191
11192                                 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11193                                         break;
11194
11195                                 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11196                                 {
11197                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11198                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11199                                         i++;
11200                                         j++;
11201                                         k++;
11202                                 }
11203                                 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11204                                 {
11205                                         chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11206 //                                      chplan_new[k].ScanType = chplan_sta[i].ScanType;
11207                                         chplan_new[k].ScanType = SCAN_PASSIVE;
11208                                         i++;
11209                                         k++;
11210                                 }
11211                                 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11212                                 {
11213                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11214                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11215                                         j++;
11216                                         k++;
11217                                 }
11218                         } while (1);
11219
11220                         // change AP not support channel to Passive scan
11221                         while ((i < MAX_CHANNEL_NUM) &&
11222                                 (chplan_sta[i].ChannelNum != 0) &&
11223                                 (chplan_sta[i].ChannelNum <= 14))
11224                         {
11225                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11226 //                              chplan_new[k].ScanType = chplan_sta[i].ScanType;
11227                                 chplan_new[k].ScanType = SCAN_PASSIVE;
11228                                 i++;
11229                                 k++;
11230                         }
11231
11232                         // add channel AP supported
11233                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11234                         {
11235                                 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11236                                 chplan_new[k].ScanType = SCAN_ACTIVE;
11237                                 j++;
11238                                 k++;
11239                         }
11240                 }
11241                 else
11242                 {
11243                         // keep original STA 2.4G channel plan
11244                         while ((i < MAX_CHANNEL_NUM) &&
11245                                 (chplan_sta[i].ChannelNum != 0) &&
11246                                 (chplan_sta[i].ChannelNum <= 14))
11247                         {
11248                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11249                                 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11250                                 i++;
11251                                 k++;
11252                         }
11253
11254                         // skip AP 2.4G channel plan
11255                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11256                         {
11257                                 j++;
11258                         }
11259                 }
11260
11261                 if (pregistrypriv->wireless_mode & WIRELESS_11A)
11262                 {
11263                         do {
11264                                 if ((i >= MAX_CHANNEL_NUM) ||
11265                                         (chplan_sta[i].ChannelNum == 0))
11266                                         break;
11267
11268                                 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11269                                         break;
11270
11271                                 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11272                                 {
11273                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11274                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11275                                         i++;
11276                                         j++;
11277                                         k++;
11278                                 }
11279                                 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11280                                 {
11281                                         chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11282 //                                      chplan_new[k].ScanType = chplan_sta[i].ScanType;
11283                                         chplan_new[k].ScanType = SCAN_PASSIVE;
11284                                         i++;
11285                                         k++;
11286                                 }
11287                                 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11288                                 {
11289                                         chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11290                                         chplan_new[k].ScanType = SCAN_ACTIVE;
11291                                         j++;
11292                                         k++;
11293                                 }
11294                         } while (1);
11295
11296                         // change AP not support channel to Passive scan
11297                         while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11298                         {
11299                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11300 //                              chplan_new[k].ScanType = chplan_sta[i].ScanType;
11301                                 chplan_new[k].ScanType = SCAN_PASSIVE;
11302                                 i++;
11303                                 k++;
11304                         }
11305
11306                         // add channel AP supported
11307                         while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
11308                         {
11309                                 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11310                                 chplan_new[k].ScanType = SCAN_ACTIVE;
11311                                 j++;
11312                                 k++;
11313                         }
11314                 }
11315                 else
11316                 {
11317                         // keep original STA 5G channel plan
11318                         while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11319                         {
11320                                 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11321                                 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11322                                 i++;
11323                                 k++;
11324                         }
11325                 }
11326
11327                 pmlmeext->update_channel_plan_by_ap_done = 1;
11328
11329 #ifdef CONFIG_DEBUG_RTL871X
11330                 k = 0;
11331                 DBG_871X("%s: new STA channel plan {", __FUNCTION__);
11332                 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11333                 {
11334                         DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
11335                         k++;
11336                 }
11337                 DBG_871X("}\n");
11338 #endif
11339
11340 #if 0
11341                 // recover the right channel index
11342                 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11343                 k = 0;
11344                 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11345                 {
11346                         if (chplan_new[k].ChannelNum == channel) {
11347                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11348                                                  ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11349                                                   __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
11350                                 pmlmeext->sitesurvey_res.channel_idx = k;
11351                                 break;
11352                         }
11353                         k++;
11354                 }
11355 #endif
11356         }
11357
11358         // If channel is used by AP, set channel scan type to active
11359         channel = bssid->Configuration.DSConfig;
11360         chplan_new = pmlmeext->channel_set;
11361         i = 0;
11362         while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
11363         {
11364                 if (chplan_new[i].ChannelNum == channel)
11365                 {
11366                         if (chplan_new[i].ScanType == SCAN_PASSIVE)
11367                         {
11368                                 //5G Bnad 2, 3 (DFS) doesn't change to active scan
11369                                 if(channel >= 52 && channel <= 144)
11370                                         break;
11371                                 
11372                                 chplan_new[i].ScanType = SCAN_ACTIVE;
11373                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11374                                                  ("%s: change channel %d scan type from passive to active\n",
11375                                                   __FUNCTION__, channel));
11376                         }
11377                         break;
11378                 }
11379                 i++;
11380         }
11381 }
11382 #endif
11383
11384 /****************************************************************************
11385
11386 Following are the functions to report events
11387
11388 *****************************************************************************/
11389
11390 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11391 {
11392         struct cmd_obj *pcmd_obj;
11393         u8      *pevtcmd;
11394         u32 cmdsz;
11395         struct survey_event     *psurvey_evt;
11396         struct C2HEvent_Header *pc2h_evt_hdr;
11397         struct mlme_ext_priv *pmlmeext;
11398         struct cmd_priv *pcmdpriv;
11399         //u8 *pframe = precv_frame->u.hdr.rx_data;
11400         //uint len = precv_frame->u.hdr.len;
11401
11402         if(!padapter)
11403                 return;
11404
11405         pmlmeext = &padapter->mlmeextpriv;
11406         pcmdpriv = &padapter->cmdpriv;
11407         
11408
11409         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11410         {
11411                 return;
11412         }
11413
11414         cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11415         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11416         {
11417                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11418                 return;
11419         }
11420
11421         _rtw_init_listhead(&pcmd_obj->list);
11422
11423         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11424         pcmd_obj->cmdsz = cmdsz;
11425         pcmd_obj->parmbuf = pevtcmd;
11426
11427         pcmd_obj->rsp = NULL;
11428         pcmd_obj->rspsz  = 0;
11429
11430         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11431         pc2h_evt_hdr->len = sizeof(struct survey_event);
11432         pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11433         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11434
11435         psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11436
11437         if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
11438         {
11439                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11440                 rtw_mfree((u8 *)pevtcmd, cmdsz);
11441                 return;
11442         }
11443
11444 #ifdef CONFIG_80211D
11445         process_80211d(padapter, &psurvey_evt->bss);
11446 #endif
11447
11448         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11449
11450         pmlmeext->sitesurvey_res.bss_cnt++;
11451
11452         return;
11453
11454 }
11455
11456 void report_surveydone_event(_adapter *padapter)
11457 {
11458         struct cmd_obj *pcmd_obj;
11459         u8      *pevtcmd;
11460         u32 cmdsz;
11461         struct surveydone_event *psurveydone_evt;
11462         struct C2HEvent_Header  *pc2h_evt_hdr;
11463         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11464         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11465
11466         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11467         {
11468                 return;
11469         }
11470
11471         cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11472         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11473         {
11474                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11475                 return;
11476         }
11477
11478         _rtw_init_listhead(&pcmd_obj->list);
11479
11480         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11481         pcmd_obj->cmdsz = cmdsz;
11482         pcmd_obj->parmbuf = pevtcmd;
11483
11484         pcmd_obj->rsp = NULL;
11485         pcmd_obj->rspsz  = 0;
11486
11487         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11488         pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11489         pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11490         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11491
11492         psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11493         psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11494
11495         DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11496
11497         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11498
11499         return;
11500
11501 }
11502
11503 void report_join_res(_adapter *padapter, int res)
11504 {
11505         struct cmd_obj *pcmd_obj;
11506         u8      *pevtcmd;
11507         u32 cmdsz;
11508         struct joinbss_event            *pjoinbss_evt;
11509         struct C2HEvent_Header  *pc2h_evt_hdr;
11510         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11511         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11512         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11513
11514         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11515         {
11516                 return;
11517         }
11518
11519         cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11520         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11521         {
11522                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11523                 return;
11524         }
11525
11526         _rtw_init_listhead(&pcmd_obj->list);
11527
11528         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11529         pcmd_obj->cmdsz = cmdsz;
11530         pcmd_obj->parmbuf = pevtcmd;
11531
11532         pcmd_obj->rsp = NULL;
11533         pcmd_obj->rspsz  = 0;
11534
11535         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11536         pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11537         pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11538         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11539
11540         pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11541         _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11542         pjoinbss_evt->network.join_res  = pjoinbss_evt->network.aid = res;
11543
11544         DBG_871X("report_join_res(%d)\n", res);
11545         
11546         
11547         rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11548         
11549         
11550         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11551
11552         return;
11553
11554 }
11555
11556 void report_wmm_edca_update(_adapter *padapter)
11557 {
11558         struct cmd_obj *pcmd_obj;
11559         u8      *pevtcmd;
11560         u32 cmdsz;
11561         struct wmm_event                *pwmm_event;
11562         struct C2HEvent_Header  *pc2h_evt_hdr;
11563         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11564         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11565         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11566
11567         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11568         {
11569                 return;
11570         }
11571
11572         cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11573         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11574         {
11575                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11576                 return;
11577         }
11578
11579         _rtw_init_listhead(&pcmd_obj->list);
11580
11581         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11582         pcmd_obj->cmdsz = cmdsz;
11583         pcmd_obj->parmbuf = pevtcmd;
11584
11585         pcmd_obj->rsp = NULL;
11586         pcmd_obj->rspsz  = 0;
11587
11588         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11589         pc2h_evt_hdr->len = sizeof(struct wmm_event);
11590         pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11591         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11592
11593         pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11594         pwmm_event->wmm =0;
11595         
11596         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11597
11598         return;
11599
11600 }
11601
11602 void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue, u8 locally_generated)
11603 {
11604         struct cmd_obj *pcmd_obj;
11605         u8      *pevtcmd;
11606         u32 cmdsz;
11607         struct sta_info *psta;
11608         int     mac_id = -1;
11609         struct stadel_event                     *pdel_sta_evt;
11610         struct C2HEvent_Header  *pc2h_evt_hdr;
11611         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11612         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11613         u8 res = _SUCCESS;
11614
11615         /* prepare cmd parameter */
11616         cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11617         pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11618         if (pevtcmd == NULL) {
11619                 res = _FAIL;
11620                 goto exit;
11621         }
11622
11623         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11624         pc2h_evt_hdr->len = sizeof(struct stadel_event);
11625         pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11626         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11627
11628         pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11629         _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11630         _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
11631         psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11632         if(psta)
11633                 mac_id = (int)psta->mac_id;     
11634         else
11635                 mac_id = (-1);
11636         pdel_sta_evt->mac_id = mac_id;
11637          pdel_sta_evt->locally_generated = locally_generated;
11638
11639         if (!enqueue) {
11640                 /* do directly */
11641                 rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11642                 rtw_mfree(pevtcmd, cmdsz);
11643         } else {
11644                 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11645                 if (pcmd_obj == NULL) {
11646                         rtw_mfree(pevtcmd, cmdsz);
11647                         res = _FAIL;
11648                         goto exit;
11649                 }
11650
11651                 _rtw_init_listhead(&pcmd_obj->list);
11652                 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11653                 pcmd_obj->cmdsz = cmdsz;
11654                 pcmd_obj->parmbuf = pevtcmd;
11655
11656                 pcmd_obj->rsp = NULL;
11657                 pcmd_obj->rspsz  = 0;
11658
11659                 res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11660         }
11661
11662 exit:
11663
11664         DBG_871X(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11665                 , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11666
11667         return;
11668 }
11669
11670 void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
11671 {
11672         struct cmd_obj *pcmd_obj;
11673         u8      *pevtcmd;
11674         u32 cmdsz;
11675         struct stassoc_event            *padd_sta_evt;
11676         struct C2HEvent_Header  *pc2h_evt_hdr;
11677         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
11678         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11679
11680         if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11681         {
11682                 return;
11683         }
11684
11685         cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11686         if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11687         {
11688                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11689                 return;
11690         }
11691
11692         _rtw_init_listhead(&pcmd_obj->list);
11693
11694         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11695         pcmd_obj->cmdsz = cmdsz;
11696         pcmd_obj->parmbuf = pevtcmd;
11697
11698         pcmd_obj->rsp = NULL;
11699         pcmd_obj->rspsz  = 0;
11700
11701         pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11702         pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11703         pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11704         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11705
11706         padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11707         _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11708
11709         DBG_871X("report_add_sta_event: add STA\n");
11710
11711         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11712
11713         return;
11714 }
11715
11716
11717 bool rtw_port_switch_chk(_adapter *adapter)
11718 {
11719         bool switch_needed = _FALSE;
11720 #ifdef CONFIG_CONCURRENT_MODE
11721 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11722         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11723         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11724         _adapter *if_port0 = NULL;
11725         _adapter *if_port1 = NULL;
11726         struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11727         struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11728         int i;
11729
11730         for (i = 0; i < dvobj->iface_nums; i++) {
11731                 if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) {
11732                         if_port0 = dvobj->padapters[i];
11733                         if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11734                 }
11735                 else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) {
11736                         if_port1 = dvobj->padapters[i];
11737                         if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11738                 }
11739         }
11740
11741         if (if_port0 == NULL) {
11742                 rtw_warn_on(1);
11743                 goto exit;
11744         }
11745
11746         if (if_port1 == NULL) {
11747                 rtw_warn_on(1);
11748                 goto exit;
11749         }
11750
11751 #ifdef DBG_RUNTIME_PORT_SWITCH
11752         DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11753                 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11754                 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11755                 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11756                 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11757                 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11758 #endif /* DBG_RUNTIME_PORT_SWITCH */
11759
11760 #ifdef CONFIG_WOWLAN
11761         /* WOWLAN interface(primary, for now) should be port0 */
11762         if (pwrctl->wowlan_mode == _TRUE) {
11763                 if(!is_primary_adapter(if_port0)) {
11764                         DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11765                         switch_needed = _TRUE;
11766                 }
11767                 goto exit;
11768         }
11769 #endif /* CONFIG_WOWLAN */
11770
11771         /* AP should use port0 for ctl frame's ack */
11772         if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11773                 DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11774                 switch_needed = _TRUE;
11775                 goto exit;
11776         }
11777
11778         /* GC should use port0 for p2p ps */    
11779         if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11780                 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11781                 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11782                 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11783         ) {
11784                 DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11785                 switch_needed = _TRUE;
11786                 goto exit;
11787         }
11788
11789         /* port1 linked, but port0 not linked */
11790         if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11791                 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11792                 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11793         ) {
11794                 DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11795                 switch_needed = _TRUE;
11796                 goto exit;
11797         }
11798
11799 exit:
11800 #ifdef DBG_RUNTIME_PORT_SWITCH
11801         DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11802 #endif /* DBG_RUNTIME_PORT_SWITCH */
11803 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11804 #endif /* CONFIG_CONCURRENT_MODE */
11805         return switch_needed;
11806 }
11807
11808 /****************************************************************************
11809
11810 Following are the event callback functions
11811
11812 *****************************************************************************/
11813
11814 //for sta/adhoc mode
11815 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11816 {
11817         _irqL   irqL;
11818         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11819         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11820         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11821
11822         //ERP
11823         VCS_update(padapter, psta);
11824
11825 #ifdef CONFIG_80211N_HT
11826         //HT
11827         if(pmlmepriv->htpriv.ht_option)
11828         {
11829                 psta->htpriv.ht_option = _TRUE;
11830
11831                 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11832
11833                 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
11834
11835                 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11836                         psta->htpriv.sgi_20m = _TRUE;
11837
11838                 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11839                         psta->htpriv.sgi_40m = _TRUE;
11840
11841                 psta->qos_option = _TRUE;
11842
11843                 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11844                 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11845                 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11846
11847                 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11848         }
11849         else
11850 #endif //CONFIG_80211N_HT
11851         {
11852 #ifdef CONFIG_80211N_HT
11853                 psta->htpriv.ht_option = _FALSE;
11854
11855                 psta->htpriv.ampdu_enable = _FALSE;
11856                 
11857                 psta->htpriv.sgi_20m = _FALSE;
11858                 psta->htpriv.sgi_40m = _FALSE;
11859 #endif //CONFIG_80211N_HT
11860                 psta->qos_option = _FALSE;
11861
11862         }
11863
11864 #ifdef CONFIG_80211N_HT
11865         psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11866         
11867         psta->htpriv.agg_enable_bitmap = 0x0;//reset
11868         psta->htpriv.candidate_tid_bitmap = 0x0;//reset
11869 #endif //CONFIG_80211N_HT
11870
11871         psta->bw_mode = pmlmeext->cur_bwmode;
11872
11873         //QoS
11874         if(pmlmepriv->qospriv.qos_option)
11875                 psta->qos_option = _TRUE;
11876
11877 #ifdef CONFIG_80211AC_VHT
11878         _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11879 #endif //CONFIG_80211AC_VHT
11880
11881         update_ldpc_stbc_cap(psta);
11882
11883         _enter_critical_bh(&psta->lock, &irqL);
11884         psta->state = _FW_LINKED;
11885         _exit_critical_bh(&psta->lock, &irqL);
11886
11887 }
11888
11889 static void rtw_mlmeext_disconnect(_adapter *padapter)
11890 {
11891         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
11892         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11893         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11894         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11895         u8 state_backup = (pmlmeinfo->state&0x03);
11896         u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
11897
11898         //set_opmode_cmd(padapter, infra_client_with_mlme);
11899
11900         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11901         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11902
11903         //set MSR to no link state -> infra. mode
11904         Set_MSR(padapter, _HW_STATE_STATION_);
11905
11906         //check if sta is ASIX peer and fix IOT issue if it is.
11907         if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
11908                 u8 iot_flag = _FALSE;
11909                 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11910         }
11911         pmlmeinfo->state = WIFI_FW_NULL_STATE;
11912
11913         if(state_backup == WIFI_FW_STATION_STATE)
11914         {
11915                 if (rtw_port_switch_chk(padapter) == _TRUE) {
11916                         rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11917                         #ifdef CONFIG_LPS
11918                         {
11919                                 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11920                                 if (port0_iface)
11921                                         rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11922                         }
11923                         #endif
11924                 }
11925         }
11926
11927         /* switch to the 20M Hz mode after disconnect */
11928         pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11929         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11930
11931 #ifdef CONFIG_FCS_MODE
11932         if (EN_FCS(padapter))
11933                 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11934 #endif
11935
11936 #ifdef CONFIG_DFS_MASTER
11937         if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
11938                 rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);
11939         else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
11940                 rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED);
11941 #endif
11942
11943         {
11944                 u8 ch, bw, offset;
11945
11946                 if (rtw_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
11947                         set_channel_bwmode(padapter, ch, offset, bw);
11948         }
11949
11950         flush_all_cam_entry(padapter);
11951
11952         _cancel_timer_ex(&pmlmeext->link_timer);
11953
11954         //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE;
11955         pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11956         pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11957
11958 #ifdef CONFIG_TDLS
11959         padapter->tdlsinfo.ap_prohibited = _FALSE;
11960
11961         /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11962         if (padapter->registrypriv.wifi_spec == 1)
11963         {
11964                 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
11965         }
11966 #endif /* CONFIG_TDLS */
11967
11968 }
11969
11970 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
11971 {
11972         struct sta_info         *psta, *psta_bmc;
11973         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
11974         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
11975         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
11976         struct sta_priv         *pstapriv = &padapter->stapriv;
11977         u8      join_type;
11978 #ifdef CONFIG_ARP_KEEP_ALIVE
11979         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
11980 #endif
11981         struct security_priv *psecuritypriv = &padapter->securitypriv;
11982
11983         if(join_res < 0)
11984         {
11985                 join_type = 1;
11986                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11987                 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11988
11989                 goto exit_mlmeext_joinbss_event_callback;
11990         }
11991 #ifdef CONFIG_ARP_KEEP_ALIVE
11992         pmlmepriv->bGetGateway = 1;
11993 #endif
11994
11995         if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11996         {
11997                 //update bc/mc sta_info
11998                 update_bmc_sta(padapter);
11999         }
12000
12001
12002         //turn on dynamic functions
12003         /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12004
12005         // update IOT-releated issue
12006         update_IOT_info(padapter);
12007
12008         rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12009
12010         //BCN interval
12011         rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12012
12013         //udpate capability
12014         update_capinfo(padapter, pmlmeinfo->capability);
12015
12016         //WMM, Update EDCA param
12017         WMMOnAssocRsp(padapter);
12018
12019         //HT
12020         HTOnAssocRsp(padapter);
12021
12022 #ifdef CONFIG_80211AC_VHT
12023         //VHT
12024         VHTOnAssocRsp(padapter);
12025 #endif
12026
12027         psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12028         if (psta) //only for infra. mode
12029         {
12030                 //DBG_871X("set_sta_rate\n");
12031
12032                 psta->wireless_mode = pmlmeext->cur_wireless_mode;
12033         
12034                 //set per sta rate after updating HT cap.
12035                 set_sta_rate(padapter, psta);
12036                 
12037                 rtw_sta_media_status_rpt(padapter, psta, 1);
12038
12039                 /* wakeup macid after join bss successfully to ensure 
12040                         the subsequent data frames can be sent out normally */
12041                 rtw_hal_macid_wakeup(padapter, psta->mac_id);
12042         }
12043
12044 #ifndef CONFIG_IOCTL_CFG80211
12045         if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12046                 rtw_sec_restore_wep_key(padapter);
12047 #endif /* CONFIG_IOCTL_CFG80211 */
12048
12049         if (rtw_port_switch_chk(padapter) == _TRUE)
12050                 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12051
12052         join_type = 2;
12053         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12054
12055         if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12056         {
12057                 // correcting TSF
12058                 correct_TSF(padapter, pmlmeext);
12059         
12060                 //set_link_timer(pmlmeext, DISCONNECT_TO);
12061         }
12062
12063 #ifdef CONFIG_LPS
12064         if(get_iface_type(padapter) == IFACE_PORT0)
12065                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
12066 #endif
12067
12068 #ifdef CONFIG_BEAMFORMING
12069         if (psta)
12070                 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12071 #endif/*CONFIG_BEAMFORMING*/
12072
12073 exit_mlmeext_joinbss_event_callback:
12074
12075         rtw_join_done_chk_ch(padapter, join_res);
12076
12077         DBG_871X("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12078 }
12079
12080 //currently only adhoc mode will go here
12081 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12082 {
12083         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
12084         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12085         u8      join_type;
12086
12087         DBG_871X("%s\n", __FUNCTION__);
12088
12089         if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
12090         {
12091                 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
12092                 {
12093                         //nothing to do
12094                 }
12095                 else//adhoc client
12096                 {
12097                         //update TSF Value
12098                         //update_TSF(pmlmeext, pframe, len);                    
12099
12100                         // correcting TSF
12101                         correct_TSF(padapter, pmlmeext);
12102
12103                         //start beacon
12104                         if (send_beacon(padapter) == _FAIL)
12105                                 rtw_warn_on(1);
12106
12107                         pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12108                 }
12109
12110                 join_type = 2;
12111                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12112         }
12113
12114         //update adhoc sta_info
12115         update_sta_info(padapter, psta);
12116
12117         rtw_hal_update_sta_rate_mask(padapter, psta);
12118
12119         // ToDo: HT for Ad-hoc 
12120         psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12121         psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
12122
12123         //rate radaptive
12124         Update_RA_Entry(padapter, psta);
12125 }
12126
12127 void mlmeext_sta_del_event_callback(_adapter *padapter)
12128 {
12129         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12130         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12131
12132         if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12133         {
12134                 rtw_mlmeext_disconnect(padapter);
12135         }
12136
12137 }
12138
12139 /****************************************************************************
12140
12141 Following are the functions for the timer handlers
12142
12143 *****************************************************************************/
12144 void _linked_info_dump(_adapter *padapter)
12145 {
12146         int i;
12147         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12148         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12149         HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
12150         int UndecoratedSmoothedPWDB = 0;
12151         
12152         if(padapter->bLinkInfoDump){
12153
12154                 DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter));    
12155
12156                 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12157                 {
12158                         rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);      
12159                 
12160                         DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
12161                                 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB);
12162                 }
12163                 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
12164                 {
12165                         _irqL irqL;
12166                         _list   *phead, *plist;
12167         
12168                         struct sta_info *psta=NULL;     
12169                         struct sta_priv *pstapriv = &padapter->stapriv;
12170                         
12171                         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);   
12172                         phead = &pstapriv->asoc_list;
12173                         plist = get_next(phead);
12174                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12175                         {
12176                                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
12177                                 plist = get_next(plist);                        
12178                                 
12179                                 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n", 
12180                                         MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB);
12181                         }
12182                         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);            
12183                         
12184                 }
12185                 
12186                 /*============  tx info ============    */
12187                 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
12188
12189                 rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
12190                 
12191         }
12192               
12193
12194 }
12195 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12196 {
12197         int     i = 0;
12198         int ret = _SUCCESS;
12199         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12200         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12201
12202         /*
12203                 IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12204                 AP is originator.AP does not transmit unicast packets when STA response its BAR.
12205                 This case probably occur ap issue BAR after AP builds BA. 
12206                                 
12207                 Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12208                 The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12209         */
12210         if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12211                 for (i = 0; i < TID_NUM ; i++) {                                
12212                         if (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) {                      
12213                                 if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12214                                         if (psta->recvreorder_ctrl[i].enable) {                                         
12215                                                 /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */              
12216                                                 if (!from_timer)
12217                                                         ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1);
12218                                                 else
12219                                                         issue_del_ba(padapter,  psta->hwaddr, i, 39, 0);                                                        
12220                                                         psta->recvreorder_ctrl[i].enable = _FALSE;
12221                                                 if (ret != _FAIL)
12222                                                         psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12223                                                         rtw_reset_continual_no_rx_packet(psta, i);
12224                                                 }                               
12225                                         }
12226                                 }
12227                         else{   
12228                                 /* The inactivity timer is reset when MPDUs to the TID is received. */
12229                                 rtw_reset_continual_no_rx_packet(psta, i);      
12230                         }
12231                 }
12232         }
12233 }
12234
12235 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12236 {
12237         u8 ret = _FALSE;
12238         int i = 0;
12239         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12240         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12241
12242         #ifdef DBG_EXPIRATION_CHK
12243         DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12244                                 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12245                                 ", retry:%u\n"
12246                 , FUNC_ADPT_ARG(padapter)
12247                 , STA_RX_PKTS_DIFF_ARG(psta)
12248                 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12249                 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12250                 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12251                 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12252                 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12253                 , pmlmeinfo->bcn_interval*/
12254                 , pmlmeext->retry
12255         );
12256
12257         DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12258                 , padapter->xmitpriv.tx_pkts
12259                 , pmlmeinfo->link_count
12260         );
12261         #endif
12262
12263         if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12264                 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12265                 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12266         )
12267         {
12268                 ret = _FALSE;
12269         }
12270         else
12271         {
12272                 ret = _TRUE;
12273         }
12274
12275         sta_update_last_rx_pkts(psta);
12276
12277         /*
12278                 record last rx data packets for every tid.
12279         */
12280         for (i = 0; i < TID_NUM; i++)   
12281                 psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i];
12282
12283         return ret;
12284 }
12285
12286 u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
12287 {
12288         u8 ret = _TRUE;
12289
12290         #ifdef DBG_EXPIRATION_CHK
12291         DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12292                 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12293                 ", expire_to:%u\n"
12294                 , MAC_ARG(psta->hwaddr)
12295                 , psta->rssi_stat.UndecoratedSmoothedPWDB
12296                 , STA_RX_PKTS_DIFF_ARG(psta)
12297                 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12298                 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12299                 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12300                 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12301                 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12302                 , pmlmeinfo->bcn_interval*/
12303                 , psta->expire_to
12304         );
12305         #endif
12306
12307         if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
12308                 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12309                 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
12310                 ret = _FALSE;
12311
12312         sta_update_last_rx_pkts(psta);
12313
12314         return ret;
12315 }
12316
12317 #ifdef CONFIG_TDLS
12318 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12319 {
12320         if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12321                 && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12322                 return _FALSE;
12323
12324         return _TRUE;
12325 }
12326
12327 void linked_status_chk_tdls(_adapter *padapter)
12328 {
12329         struct candidate_pool {
12330                 struct sta_info *psta;
12331                 u8 addr[ETH_ALEN];
12332         };
12333         struct sta_priv *pstapriv = &padapter->stapriv;
12334         _irqL irqL;
12335         u8 ack_chk;
12336         struct sta_info *psta;
12337         int i, num_teardown=0, num_checkalive=0;
12338         _list   *plist, *phead;
12339         struct tdls_txmgmt txmgmt;
12340         struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
12341         struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
12342         u8 tdls_sta_max = _FALSE;
12343
12344 #define ALIVE_MIN 2
12345 #define ALIVE_MAX 5
12346
12347         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12348         _rtw_memset(checkalive, 0x00, sizeof(checkalive));
12349         _rtw_memset(teardown, 0x00, sizeof(teardown));
12350
12351         if((padapter->tdlsinfo.link_established == _TRUE)){
12352                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12353                 for(i=0; i< NUM_STA; i++)
12354                 {
12355                         phead = &(pstapriv->sta_hash[i]);
12356                         plist = get_next(phead);
12357                         
12358                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12359                         {
12360                                 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12361                                 plist = get_next(plist);
12362
12363                                 if(psta->tdls_sta_state & TDLS_LINKED_STATE)
12364                                 {
12365                                         psta->alive_count++;
12366                                         if(psta->alive_count >= ALIVE_MIN)
12367                                         {
12368                                                 if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12369                                                         if (psta->alive_count < ALIVE_MAX) {
12370                                                                 _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12371                                                                 checkalive[num_checkalive].psta = psta;
12372                                                                 num_checkalive++;
12373                                                         }
12374                                                         else
12375                                                         {
12376                                                                 _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12377                                                                 teardown[num_teardown].psta = psta;
12378                                                                 num_teardown++;
12379                                                         }
12380                                                 }
12381                                                 else
12382                                                 {
12383                                                         psta->alive_count = 0;
12384                                                 }
12385                                         }
12386                                         psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12387                                         psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12388
12389                                         if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
12390                                                 tdls_sta_max = _TRUE;
12391                                                 break;
12392                                         }
12393                                 }
12394                         }
12395
12396                         if (tdls_sta_max == _TRUE)
12397                                 break;
12398                 }
12399                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12400
12401                 if (num_checkalive > 0) {
12402                         for (i = 0; i < num_checkalive; i++) {
12403                                 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12404                                 issue_tdls_dis_req(padapter, &txmgmt);
12405                                 issue_tdls_dis_req(padapter, &txmgmt);
12406                                 issue_tdls_dis_req(padapter, &txmgmt);
12407                         }
12408                 }
12409
12410                 if(num_teardown > 0)
12411                 {
12412                         for(i=0; i< num_teardown; i++)
12413                         {
12414                                 DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12415                                 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12416                                 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12417                                 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12418                         }
12419                 }
12420         }
12421
12422 }
12423 #endif //CONFIG_TDLS
12424
12425 //from_timer == 1 means driver is in LPS
12426 void linked_status_chk(_adapter *padapter, u8 from_timer)
12427 {
12428         u32     i;
12429         struct sta_info         *psta;
12430         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
12431         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12432         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12433         struct sta_priv         *pstapriv = &padapter->stapriv;
12434 #ifdef CONFIG_ARP_KEEP_ALIVE
12435         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
12436 #endif
12437         
12438
12439         if (is_client_associated_to_ap(padapter))
12440         {
12441                 //linked infrastructure client mode
12442
12443                 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12444                 int rx_chk_limit;
12445                 int link_count_limit;
12446
12447                 #if defined(DBG_ROAMING_TEST)
12448                 rx_chk_limit = 1;
12449                 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12450                 rx_chk_limit = 4;
12451                 #else
12452                 rx_chk_limit = 8;
12453                 #endif
12454 #ifdef CONFIG_ARP_KEEP_ALIVE
12455                 if (!from_timer && pmlmepriv->bGetGateway == 1) {
12456                         DBG_871X("do rtw_gw_addr_query()");
12457                         if (rtw_gw_addr_query(padapter) == 0) {
12458                                 pmlmepriv->bGetGateway = 0;
12459                         } else {
12460                                 _rtw_memset(pmlmepriv->gw_ip, 0, 4);
12461                                 _rtw_memset(pmlmepriv->gw_mac_addr, 0, 6);
12462                         }
12463                 }
12464 #endif
12465 #ifdef CONFIG_P2P
12466                 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12467                 {
12468                         if(!from_timer)
12469                                 link_count_limit = 3; // 8 sec
12470                         else
12471                                 link_count_limit = 15; // 32 sec
12472                 }
12473                 else
12474 #endif // CONFIG_P2P
12475                 {
12476                         if(!from_timer)
12477                                 link_count_limit = 7; // 16 sec
12478                         else
12479                                 link_count_limit = 29; // 60 sec
12480                 }               
12481
12482 #ifdef CONFIG_TDLS
12483 #ifdef CONFIG_TDLS_CH_SW
12484                 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12485                         return;
12486 #endif /* CONFIG_TDLS_CH_SW */
12487
12488 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12489                 linked_status_chk_tdls(padapter);
12490 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12491 #endif /* CONFIG_TDLS */
12492
12493                 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12494                 {
12495                         bool is_p2p_enable = _FALSE;
12496                         #ifdef CONFIG_P2P
12497                         is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12498                         #endif
12499
12500                         /*issue delba when ap does not tx data packet that is Broadcom ap */
12501                         rtw_delba_check(padapter, psta, from_timer);
12502
12503                         if (chk_ap_is_alive(padapter, psta) == _FALSE)
12504                                 rx_chk = _FAIL;
12505
12506                         if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12507                                 tx_chk = _FAIL;
12508
12509                         #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12510                         if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
12511                                 u8 backup_oper_channel=0;
12512
12513                                 /* switch to correct channel of current network  before issue keep-alive frames */
12514                                 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12515                                         backup_oper_channel = rtw_get_oper_ch(padapter);
12516                                         SelectChannel(padapter, pmlmeext->cur_channel);
12517                                 }
12518
12519                                 if (rx_chk != _SUCCESS)
12520                                         issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12521
12522                                 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12523                                         tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12524                                         /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12525                                         if (tx_chk == _SUCCESS && !is_p2p_enable)
12526                                                 rx_chk = _SUCCESS;
12527                                 }
12528
12529                                 /* back to the original operation channel */
12530                                 if(backup_oper_channel>0)
12531                                         SelectChannel(padapter, backup_oper_channel);
12532
12533                         }
12534                         else
12535                         #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12536                         {
12537                                 if (rx_chk != _SUCCESS) {
12538                                         if (pmlmeext->retry == 0) {
12539                                                 #ifdef DBG_EXPIRATION_CHK
12540                                                 DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12541                                                 #endif
12542                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12543                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12544                                                 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12545                                         }
12546                                 }
12547
12548                                 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
12549                                         #ifdef DBG_EXPIRATION_CHK
12550                                         DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0);
12551                                         #endif
12552                                         tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0);
12553                                 }
12554                         }
12555
12556                         if (rx_chk == _FAIL) {
12557                                 pmlmeext->retry++;
12558                                 if (pmlmeext->retry > rx_chk_limit) {
12559                                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
12560                                                 FUNC_ADPT_ARG(padapter));
12561                                         receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12562                                                 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
12563                                         return;
12564                                 }
12565                         } else {
12566                                 pmlmeext->retry = 0;
12567                         }
12568
12569                         if (tx_chk == _FAIL) {
12570                                 pmlmeinfo->link_count %= (link_count_limit+1);
12571                         } else {
12572                                 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12573                                 pmlmeinfo->link_count = 0;
12574                         }
12575
12576                 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12577
12578         } else if (is_client_associated_to_ibss(padapter)) {
12579                 _irqL irqL;
12580                 _list *phead, *plist, dlist;
12581
12582                 _rtw_init_listhead(&dlist);
12583
12584                 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12585
12586                 for (i = 0; i < NUM_STA; i++) {
12587
12588                         phead = &(pstapriv->sta_hash[i]);
12589                         plist = get_next(phead);
12590                         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12591                                 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12592                                 plist = get_next(plist);
12593
12594                                 if (is_broadcast_mac_addr(psta->hwaddr))
12595                                         continue;
12596
12597                                 if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
12598                                         psta->expire_to = pstapriv->adhoc_expire_to;
12599                                 else
12600                                         psta->expire_to--;
12601
12602                                 if (psta->expire_to <= 0) {
12603                                         rtw_list_delete(&psta->list);
12604                                         rtw_list_insert_tail(&psta->list, &dlist);
12605                                 }
12606                         }
12607                 }
12608
12609                 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12610
12611                 plist = get_next(&dlist);
12612                 while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
12613                         psta = LIST_CONTAINOR(plist, struct sta_info, list);
12614                         plist = get_next(plist);
12615                         rtw_list_delete(&psta->list);
12616                         DBG_871X(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
12617                                 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->hwaddr));
12618                         report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE, _FALSE);
12619                 }
12620         }
12621
12622 }
12623
12624 void survey_timer_hdl(_adapter *padapter)
12625 {
12626         struct cmd_obj *cmd;
12627         struct sitesurvey_parm *psurveyPara;
12628         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12629         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12630 #ifdef CONFIG_P2P
12631         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12632 #endif
12633
12634         if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12635                 cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12636                 if (cmd == NULL) {
12637                         rtw_warn_on(1);
12638                         goto exit;
12639                 }
12640
12641                 psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12642                 if (psurveyPara == NULL) {
12643                         rtw_warn_on(1);
12644                         rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12645                         goto exit;
12646                 }
12647
12648                 init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12649                 rtw_enqueue_cmd(pcmdpriv, cmd);
12650         }
12651
12652 exit:
12653         return;
12654 }
12655
12656 void link_timer_hdl(_adapter *padapter)
12657 {
12658         //static unsigned int           rx_pkt = 0;
12659         //static u64                            tx_cnt = 0;
12660         //struct xmit_priv              *pxmitpriv = &(padapter->xmitpriv);
12661         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12662         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12663         //struct sta_priv               *pstapriv = &padapter->stapriv;
12664
12665
12666         if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
12667         {
12668                 DBG_871X("link_timer_hdl:no beacon while connecting\n");
12669                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12670                 report_join_res(padapter, -3);
12671         }
12672         else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
12673         {
12674                 //re-auth timer
12675                 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
12676                 {
12677                         //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
12678                         //{
12679                                 pmlmeinfo->state = 0;
12680                                 report_join_res(padapter, -1);
12681                                 return;
12682                         //}
12683                         //else
12684                         //{
12685                         //      pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
12686                         //      pmlmeinfo->reauth_count = 0;
12687                         //}
12688                 }
12689                 
12690                 DBG_871X("link_timer_hdl: auth timeout and try again\n");
12691                 pmlmeinfo->auth_seq = 1;
12692                 issue_auth(padapter, NULL, 0);
12693                 set_link_timer(pmlmeext, REAUTH_TO);
12694         }
12695         else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
12696         {
12697                 //re-assoc timer
12698                 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
12699                 {
12700                         pmlmeinfo->state = WIFI_FW_NULL_STATE;
12701                         report_join_res(padapter, -2);
12702                         return;
12703                 }
12704
12705                 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
12706                 issue_assocreq(padapter);
12707                 set_link_timer(pmlmeext, REASSOC_TO);
12708         }
12709
12710         return;
12711 }
12712
12713 void addba_timer_hdl(struct sta_info *psta)
12714 {
12715 #ifdef CONFIG_80211N_HT
12716         struct ht_priv  *phtpriv;
12717
12718         if(!psta)
12719                 return;
12720         
12721         phtpriv = &psta->htpriv;
12722
12723         if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) 
12724         {
12725                 if(phtpriv->candidate_tid_bitmap)
12726                         phtpriv->candidate_tid_bitmap=0x0;
12727                 
12728         }
12729 #endif //CONFIG_80211N_HT
12730 }
12731
12732 #ifdef CONFIG_IEEE80211W
12733 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
12734 {
12735         struct cmd_obj *pcmd_obj;
12736         u8      *pevtcmd;
12737         u32 cmdsz;
12738         struct sta_info *psta;
12739         int     mac_id;
12740         struct stadel_event                     *pdel_sta_evt;
12741         struct C2HEvent_Header  *pc2h_evt_hdr;
12742         struct mlme_ext_priv            *pmlmeext = &padapter->mlmeextpriv;
12743         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12744         
12745         pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12746         if (pcmd_obj == NULL)
12747                 return;
12748
12749         cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
12750         pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12751         if (pevtcmd == NULL) {
12752                 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12753                 return;
12754         }
12755
12756         _rtw_init_listhead(&pcmd_obj->list);
12757
12758         pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
12759         pcmd_obj->cmdsz = cmdsz;
12760         pcmd_obj->parmbuf = pevtcmd;
12761
12762         pcmd_obj->rsp = NULL;
12763         pcmd_obj->rspsz  = 0;
12764
12765         pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
12766         pc2h_evt_hdr->len = sizeof(struct stadel_event);
12767         pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
12768         pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12769
12770         pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
12771         _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12772         _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12773
12774
12775         psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12776         if (psta)
12777                 mac_id = (int)psta->mac_id;     
12778         else
12779                 mac_id = (-1);
12780
12781         pdel_sta_evt->mac_id = mac_id;
12782
12783         DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
12784
12785         rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12786
12787         return;
12788 }
12789
12790 void clnt_sa_query_timeout(_adapter *padapter)
12791 {
12792
12793         rtw_disassoc_cmd(padapter, 0, _TRUE);
12794         rtw_indicate_disconnect(padapter, 0,  _FALSE);
12795         rtw_free_assoc_resources(padapter, 1);  
12796
12797         DBG_871X("SA query timeout client disconnect\n");
12798 }
12799
12800 void sa_query_timer_hdl(struct sta_info *psta)
12801 {
12802         _adapter *padapter = psta->padapter;
12803         _irqL irqL;
12804         struct sta_priv *pstapriv = &padapter->stapriv;
12805         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12806
12807         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
12808                                         check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12809                 clnt_sa_query_timeout(padapter);
12810         else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
12811                 report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID);
12812 }
12813
12814 #endif //CONFIG_IEEE80211W
12815
12816 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
12817 {
12818         return H2C_SUCCESS;
12819 }
12820
12821 #ifdef CONFIG_AUTO_AP_MODE
12822 void rtw_start_auto_ap(_adapter *adapter)
12823 {
12824         DBG_871X("%s\n", __FUNCTION__);
12825
12826         rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
12827
12828         rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE);
12829 }
12830
12831 static int rtw_auto_ap_start_beacon(_adapter *adapter)
12832 {
12833         int ret=0;
12834         u8 *pbuf = NULL;
12835         uint len;
12836         u8      supportRate[16];
12837         int     sz = 0, rateLen;
12838         u8 *    ie;
12839         u8      wireless_mode, oper_channel;
12840         u8 ssid[3] = {0}; //hidden ssid
12841         u32 ssid_len = sizeof(ssid);
12842         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
12843
12844
12845         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
12846                 return -EINVAL;
12847
12848
12849         len = 128;
12850         pbuf = rtw_zmalloc(len);
12851         if(!pbuf)
12852                 return -ENOMEM;
12853
12854
12855         //generate beacon
12856         ie = pbuf;
12857
12858         //timestamp will be inserted by hardware
12859         sz += 8;
12860         ie += sz;
12861
12862         //beacon interval : 2bytes
12863         *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
12864         sz += 2;
12865         ie += 2;
12866
12867         //capability info
12868         *(u16*)ie = 0;
12869         *(u16*)ie |= cpu_to_le16(cap_ESS);
12870         *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
12871         //*(u16*)ie |= cpu_to_le16(cap_Privacy);
12872         sz += 2;
12873         ie += 2;
12874
12875         //SSID
12876         ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
12877
12878         //supported rates
12879         wireless_mode = WIRELESS_11BG_24N;
12880         rtw_set_supported_rate(supportRate, wireless_mode) ;
12881         rateLen = rtw_get_rateset_len(supportRate);
12882         if (rateLen > 8)
12883         {
12884                 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
12885         }
12886         else
12887         {
12888                 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
12889         }
12890
12891
12892         //DS parameter set
12893         if(check_buddy_fwstate(adapter, _FW_LINKED) &&
12894                 check_buddy_fwstate(adapter, WIFI_STATION_STATE))
12895         {
12896                 PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
12897                 struct mlme_ext_priv *pbuddy_mlmeext  = &pbuddy_adapter->mlmeextpriv;
12898
12899                 oper_channel = pbuddy_mlmeext->cur_channel;
12900         }
12901         else
12902         {
12903                 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
12904         }
12905         ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
12906
12907         //ext supported rates
12908         if (rateLen > 8)
12909         {
12910                 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
12911         }
12912
12913         DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
12914
12915         //lunch ap mode & start to issue beacon
12916         if(rtw_check_beacon_data(adapter, pbuf,  sz) == _SUCCESS)
12917         {
12918
12919         }
12920         else
12921         {
12922                 ret = -EINVAL;
12923         }
12924
12925
12926         rtw_mfree(pbuf, len);
12927
12928         return ret;
12929
12930 }
12931 #endif//CONFIG_AUTO_AP_MODE
12932
12933 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
12934 {
12935         u8      type;
12936         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12937         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12938         struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
12939
12940         if(psetop->mode == Ndis802_11APMode)
12941         {
12942                 pmlmeinfo->state = WIFI_FW_AP_STATE;
12943                 type = _HW_STATE_AP_;
12944 #ifdef CONFIG_NATIVEAP_MLME
12945                 //start_ap_mode(padapter);
12946 #endif
12947         }
12948         else if(psetop->mode == Ndis802_11Infrastructure)
12949         {
12950                 pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
12951                 pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to      STATION_STATE
12952                 type = _HW_STATE_STATION_;
12953         }
12954         else if(psetop->mode == Ndis802_11IBSS)
12955         {
12956                 type = _HW_STATE_ADHOC_;
12957         } else if (psetop->mode == Ndis802_11Monitor) {
12958                 type = _HW_STATE_MONITOR_;
12959         }
12960         else
12961         {
12962                 type = _HW_STATE_NOLINK_;
12963         }
12964
12965         rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
12966         //Set_NETYPE0_MSR(padapter, type);
12967
12968
12969 #ifdef CONFIG_AUTO_AP_MODE
12970         if(psetop->mode == Ndis802_11APMode)
12971                 rtw_auto_ap_start_beacon(padapter);
12972 #endif
12973
12974         if (rtw_port_switch_chk(padapter) == _TRUE)
12975         {
12976                 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12977
12978                 if(psetop->mode == Ndis802_11APMode)
12979                         adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages
12980                 else if (psetop->mode == Ndis802_11Infrastructure) {
12981                         #ifdef CONFIG_LPS
12982                         _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12983                         if (port0_iface)
12984                                 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
12985                         #endif  
12986                 }
12987         }       
12988
12989 #ifdef CONFIG_BT_COEXIST
12990         if (psetop->mode == Ndis802_11APMode)
12991         {
12992                 // Do this after port switch to
12993                 // prevent from downloading rsvd page to wrong port
12994                 rtw_btcoex_MediaStatusNotify(padapter, 1); //connect 
12995         }
12996 #endif // CONFIG_BT_COEXIST
12997
12998         return H2C_SUCCESS;
12999         
13000 }
13001
13002 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
13003 {
13004         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13005         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
13006         WLAN_BSSID_EX   *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13007         WLAN_BSSID_EX   *pdev_network = &padapter->registrypriv.dev_network;
13008         struct createbss_parm *parm = (struct createbss_parm *)pbuf;
13009         u8 ret = H2C_SUCCESS;
13010         //u8    initialgain;
13011         
13012 #ifdef CONFIG_AP_MODE
13013         if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
13014                 start_bss_network(padapter, parm);
13015                 goto exit;
13016         }
13017 #endif
13018
13019         /* below is for ad-hoc master */
13020         if (parm->adhoc) {
13021                 rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
13022                 rtw_joinbss_reset(padapter);
13023         
13024                 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13025                 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;       
13026                 pmlmeinfo->ERP_enable = 0;
13027                 pmlmeinfo->WMM_enable = 0;
13028                 pmlmeinfo->HT_enable = 0;
13029                 pmlmeinfo->HT_caps_enable = 0;
13030                 pmlmeinfo->HT_info_enable = 0;
13031                 pmlmeinfo->agg_enable_bitmap = 0;
13032                 pmlmeinfo->candidate_tid_bitmap = 0;
13033
13034                 //config the initial gain under linking, need to write the BB registers
13035                 //initialgain = 0x1E;
13036                 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13037
13038                 //disable dynamic functions, such as high power, DIG
13039                 rtw_phydm_ability_backup(padapter);
13040                 rtw_phydm_func_disable_all(padapter);
13041                 
13042                 //cancel link timer 
13043                 _cancel_timer_ex(&pmlmeext->link_timer);
13044
13045                 //clear CAM
13046                 flush_all_cam_entry(padapter);  
13047
13048                 pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
13049                 _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13050                 pnetwork->IELength = pdev_network->IELength;
13051
13052                 if (pnetwork->IELength > MAX_IE_SZ) {
13053                         ret = H2C_PARAMETERS_ERROR;
13054                         goto ibss_post_hdl;
13055                 }
13056
13057                 _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
13058                 start_create_ibss(padapter);
13059         } else {
13060                 rtw_warn_on(1);
13061                 ret = H2C_PARAMETERS_ERROR;
13062         }
13063
13064 ibss_post_hdl:
13065         rtw_create_ibss_post_hdl(padapter, ret);
13066
13067 exit:
13068         return ret;
13069 }
13070
13071 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13072 {
13073         u8      join_type;
13074         PNDIS_802_11_VARIABLE_IEs       pIE;
13075         struct registry_priv    *pregpriv = &padapter->registrypriv;
13076         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13077         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
13078         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13079 #ifdef CONFIG_ANTENNA_DIVERSITY
13080         struct joinbss_parm     *pparm = (struct joinbss_parm *)pbuf;
13081 #endif //CONFIG_ANTENNA_DIVERSITY
13082         u32 i;
13083         //u8    initialgain;
13084         //u32   acparm;
13085         u8 u_ch, u_bw, u_offset;
13086         u8 doiqk = _FALSE;
13087
13088         //check already connecting to AP or not
13089         if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
13090         {
13091                 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13092                 {
13093                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13094                 }
13095                 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13096                 
13097                 //clear CAM
13098                 flush_all_cam_entry(padapter);          
13099                 
13100                 _cancel_timer_ex(&pmlmeext->link_timer);
13101                 
13102                 //set MSR to nolink -> infra. mode              
13103                 //Set_MSR(padapter, _HW_STATE_NOLINK_);
13104                 Set_MSR(padapter, _HW_STATE_STATION_);  
13105                 
13106
13107                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13108         }
13109
13110 #ifdef CONFIG_ANTENNA_DIVERSITY
13111         rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13112 #endif
13113
13114 #ifdef CONFIG_WAPI_SUPPORT
13115         rtw_wapi_clear_all_cam_entry(padapter);
13116 #endif
13117
13118         rtw_joinbss_reset(padapter);
13119
13120         pmlmeinfo->ERP_enable = 0;
13121         pmlmeinfo->WMM_enable = 0;
13122         pmlmeinfo->HT_enable = 0;
13123         pmlmeinfo->HT_caps_enable = 0;
13124         pmlmeinfo->HT_info_enable = 0;
13125         pmlmeinfo->agg_enable_bitmap = 0;
13126         pmlmeinfo->candidate_tid_bitmap = 0;
13127         pmlmeinfo->bwmode_updated = _FALSE;
13128         //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
13129         pmlmeinfo->VHT_enable = 0;
13130
13131         _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength)); 
13132         pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13133         
13134         if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
13135                 return H2C_PARAMETERS_ERROR;    
13136         
13137         if (pnetwork->IELength < 2) {
13138                 report_join_res(padapter, (-4));
13139                 return H2C_SUCCESS;
13140         }
13141         _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength); 
13142
13143         pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13144
13145         //Check AP vendor to move rtw_joinbss_cmd()
13146         //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
13147
13148         //sizeof(NDIS_802_11_FIXED_IEs) 
13149         for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13150                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13151
13152                 switch (pIE->ElementID)
13153                 {
13154                         case _VENDOR_SPECIFIC_IE_://Get WMM IE.
13155                                 if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
13156                                 {
13157                                         WMM_param_handler(padapter, pIE);
13158                                 }
13159                                 break;
13160
13161 #ifdef CONFIG_80211N_HT
13162                         case _HT_CAPABILITY_IE_:        //Get HT Cap IE.
13163                                 pmlmeinfo->HT_caps_enable = 1;
13164                                 break;
13165
13166                         case _HT_EXTRA_INFO_IE_:        //Get HT Info IE.
13167                                 pmlmeinfo->HT_info_enable = 1;
13168                                 break;
13169 #endif /* CONFIG_80211N_HT */
13170
13171 #ifdef CONFIG_80211AC_VHT
13172                         case EID_VHTCapability://Get VHT Cap IE.
13173                                 pmlmeinfo->VHT_enable = 1;
13174                                 break;
13175
13176                         case EID_VHTOperation://Get VHT Operation IE.
13177                                 break;
13178 #endif /* CONFIG_80211AC_VHT */
13179                         default:
13180                                 break;
13181                 }
13182
13183                 i += (pIE->Length + 2);
13184         }
13185
13186         rtw_bss_get_chbw(pnetwork
13187                 , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13188
13189         rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13190
13191 #if 0
13192         if (padapter->registrypriv.wifi_spec) {
13193                 // for WiFi test, follow WMM test plan spec
13194                 acparm = 0x002F431C; // VO
13195                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13196                 acparm = 0x005E541C; // VI
13197                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13198                 acparm = 0x0000A525; // BE
13199                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13200                 acparm = 0x0000A549; // BK
13201                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13202         
13203                 // for WiFi test, mixed mode with intel STA under bg mode throughput issue
13204                 if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
13205                         acparm = 0x00004320;
13206                         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13207                 }
13208         }
13209         else {
13210                 acparm = 0x002F3217; // VO
13211                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13212                 acparm = 0x005E4317; // VI
13213                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13214                 acparm = 0x00105320; // BE
13215                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13216                 acparm = 0x0000A444; // BK
13217                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13218         }
13219 #endif
13220
13221         /* check channel, bandwidth, offset and switch */
13222         if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
13223                 report_join_res(padapter, (-4));
13224                 return H2C_SUCCESS;
13225         }
13226
13227         //disable dynamic functions, such as high power, DIG
13228         /*rtw_phydm_func_disable_all(padapter);*/
13229
13230         //config the initial gain under linking, need to write the BB registers
13231         //initialgain = 0x1E;
13232         /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13233
13234         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
13235         join_type = 0;
13236         rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13237         doiqk = _TRUE;
13238         rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13239
13240         set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
13241
13242         doiqk = _FALSE;
13243         rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13244
13245         //cancel link timer 
13246         _cancel_timer_ex(&pmlmeext->link_timer);
13247         
13248         start_clnt_join(padapter);
13249         
13250         return H2C_SUCCESS;
13251         
13252 }
13253
13254 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
13255 {
13256         struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
13257         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13258         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
13259         WLAN_BSSID_EX           *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13260         u8 val8;
13261
13262         if (is_client_associated_to_ap(padapter))
13263         {
13264 #ifdef CONFIG_DFS
13265                 if(padapter->mlmepriv.handle_dfs == _FALSE)
13266 #endif //CONFIG_DFS
13267 #ifdef CONFIG_PLATFORM_ROCKCHIPS
13268                         //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
13269                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13270 #else
13271                         issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
13272 #endif //CONFIG_PLATFORM_ROCKCHIPS
13273         }
13274
13275 #ifdef CONFIG_DFS
13276         if( padapter->mlmepriv.handle_dfs == _TRUE )
13277                 padapter->mlmepriv.handle_dfs = _FALSE;
13278 #endif //CONFIG_DFS
13279
13280         if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13281         {
13282                 //Stop BCN
13283                 val8 = 0;
13284                 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13285         }
13286
13287         rtw_mlmeext_disconnect(padapter);
13288
13289         rtw_free_uc_swdec_pending_queue(padapter);
13290
13291         return  H2C_SUCCESS;
13292 }
13293
13294 static const char * const _scan_state_str[] = {
13295         "SCAN_DISABLE",
13296         "SCAN_START",
13297         "SCAN_PS_ANNC_WAIT",
13298         "SCAN_ENTER",
13299         "SCAN_PROCESS",
13300         "SCAN_BACKING_OP",
13301         "SCAN_BACK_OP",
13302         "SCAN_LEAVING_OP",
13303         "SCAN_LEAVE_OP",
13304         "SCAN_SW_ANTDIV_BL",
13305         "SCAN_TO_P2P_LISTEN",
13306         "SCAN_P2P_LISTEN",
13307         "SCAN_COMPLETE",
13308         "SCAN_STATE_MAX",
13309 };
13310
13311 const char *scan_state_str(u8 state)
13312 {
13313         state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
13314         return _scan_state_str[state];
13315 }
13316
13317 static bool scan_abort_hdl(_adapter *adapter)
13318 {
13319         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13320         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13321         struct ss_res *ss = &pmlmeext->sitesurvey_res;
13322 #ifdef CONFIG_P2P
13323         struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13324 #endif
13325         bool ret = _FALSE;
13326
13327         if (pmlmeext->scan_abort == _TRUE) {
13328                 #ifdef CONFIG_P2P
13329                 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
13330                         rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
13331                         ss->channel_idx = 3;
13332                         DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
13333                                 , ss->channel_idx
13334                                 , pwdinfo->find_phase_state_exchange_cnt
13335                         );
13336                 } else
13337                 #endif
13338                 {
13339                         ss->channel_idx = ss->ch_num;
13340                         DBG_871X("%s idx:%d\n", __FUNCTION__
13341                                 , ss->channel_idx
13342                         );
13343                 }
13344                 pmlmeext->scan_abort = _FALSE;
13345                 ret = _TRUE;
13346         }
13347
13348         return ret;
13349 }
13350
13351 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13352 {
13353 /* interval larger than this is treated as backgroud scan */
13354 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13355 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13356 #endif
13357
13358 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13359 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13360 #endif
13361 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13362 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13363 #endif
13364
13365 #define SCAN_SPARSE_CH_NUM_INVALID 255
13366
13367         static u8 token = 255;
13368         u32 interval;
13369         bool busy_traffic = _FALSE;
13370         bool miracast_enabled = _FALSE;
13371         bool bg_scan = _FALSE;
13372         u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13373         u8 scan_division_num;
13374         u8 ret_num = ch_num;
13375         struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13376         struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13377
13378         if (regsty->wifi_spec)
13379                 goto exit;
13380
13381         /* assume ch_num > 6 is normal scan */
13382         if (ch_num <= 6)
13383                 goto exit;
13384
13385         if (mlmeext->last_scan_time == 0)
13386                 mlmeext->last_scan_time = rtw_get_current_time();
13387
13388         interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13389
13390         if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE
13391                 #ifdef CONFIG_CONCURRENT_MODE
13392                 || (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
13393                 #endif
13394         )
13395                         busy_traffic = _TRUE;
13396
13397         if (is_miracast_enabled(adapter)
13398                 #ifdef CONFIG_CONCURRENT_MODE
13399                 || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter))
13400                 #endif
13401         )
13402                 miracast_enabled = _TRUE;
13403
13404         if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13405                 bg_scan = _TRUE;
13406
13407         /* max_allow_ch by conditions*/
13408
13409         #if RTW_SCAN_SPARSE_MIRACAST
13410         if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13411                 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13412         #endif
13413
13414         #if RTW_SCAN_SPARSE_BG
13415         if (bg_scan == _TRUE)
13416                 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13417         #endif
13418
13419
13420         if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13421                 int i;
13422                 int k = 0;
13423
13424                 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0);
13425                 token = (token + 1) % scan_division_num;
13426                 
13427                 if (0)
13428                         DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token);
13429                 
13430                 for (i = 0; i < ch_num; i++) {
13431                         if (ch[i].hw_value && (i % scan_division_num) == token
13432                         ) {
13433                                 if (i != k)
13434                                         _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13435                                 k++;
13436                         }
13437                 }
13438
13439                 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13440
13441                 ret_num = k;
13442                 mlmeext->last_scan_time = rtw_get_current_time();
13443         }
13444
13445 exit:
13446         return ret_num;
13447 }
13448
13449 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13450         u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13451 {
13452         int i, j;
13453         int scan_ch_num = 0;
13454         int set_idx;
13455         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
13456
13457         /* clear first */
13458         _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
13459
13460         /* acquire channels from in */
13461         j = 0;
13462         for (i=0;i<in_num;i++) {
13463
13464                 if (0)
13465                         DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13466
13467                 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
13468                         && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
13469                         && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE
13470                 )
13471                 {
13472                         if (j >= out_num) {
13473                                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13474                                         FUNC_ADPT_ARG(padapter), out_num);
13475                                 break;
13476                         }
13477
13478                         _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13479                         
13480                         if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13481                                 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13482                                 
13483                         j++;
13484                 }
13485                 if(j>=out_num)
13486                         break;
13487         }
13488         
13489         /* if out is empty, use channel_set as default */
13490         if(j == 0) {
13491                 for (i=0;i<pmlmeext->max_chan_nums;i++) {
13492
13493                         if (0)
13494                                 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
13495
13496                         if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) {
13497
13498                                 if (j >= out_num) {
13499                                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13500                                                 FUNC_ADPT_ARG(padapter), out_num);
13501                                         break;
13502                                 }
13503
13504                                 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
13505                         
13506                                 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
13507                                         out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13508
13509                                 j++;
13510                         }
13511                 }
13512         }
13513
13514         /* scan_sparse */
13515         j = rtw_scan_sparse(padapter, out, j);
13516
13517         return j;
13518 }
13519
13520 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
13521 {
13522         struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
13523         int i;
13524
13525         ss->bss_cnt = 0;
13526         ss->channel_idx = 0;
13527 #ifdef CONFIG_SCAN_BACKOP
13528         ss->scan_cnt = 0;
13529 #endif
13530 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
13531         ss->is_sw_antdiv_bl_scan = 0;
13532 #endif
13533         
13534         for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13535                 if (parm->ssid[i].SsidLength) {
13536                         _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
13537                         ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
13538                 } else {
13539                         ss->ssid[i].SsidLength = 0;
13540                 }
13541         }
13542
13543         ss->ch_num = rtw_scan_ch_decision(adapter
13544                 , ss->ch, RTW_CHANNEL_SCAN_AMOUNT
13545                 , parm->ch, parm->ch_num
13546         );
13547
13548         ss->scan_mode = parm->scan_mode;
13549 }
13550
13551 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
13552 {
13553         u8 next_state;
13554         u8 scan_ch = 0;
13555         RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
13556         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13557         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
13558         struct ss_res *ss = &pmlmeext->sitesurvey_res;
13559
13560 #ifdef CONFIG_P2P
13561         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13562 #endif
13563
13564         /* handle scan abort request */
13565         scan_abort_hdl(padapter);
13566
13567 #ifdef CONFIG_P2P
13568         if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
13569                 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
13570                         scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
13571                 else
13572                         scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
13573                 scan_type = SCAN_ACTIVE;
13574         } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
13575                 /*
13576                 * Commented by Albert 2011/06/03
13577                 * The driver is in the find phase, it should go through the social channel.
13578                 */
13579                 int ch_set_idx;
13580
13581                 scan_ch = pwdinfo->social_chan[ss->channel_idx];
13582                 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch);
13583                 if (ch_set_idx >= 0)
13584                         scan_type = pmlmeext->channel_set[ch_set_idx].ScanType;
13585                 else
13586                         scan_type = SCAN_ACTIVE;
13587         } else
13588 #endif /* CONFIG_P2P */
13589         {
13590                 struct rtw_ieee80211_channel *ch;
13591
13592                 if (ss->channel_idx < ss->ch_num) {
13593                         ch = &ss->ch[ss->channel_idx];
13594                         scan_ch = ch->hw_value;
13595                         scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
13596                 }
13597         }
13598
13599         if (scan_ch != 0) {
13600                 next_state = SCAN_PROCESS;
13601                 #ifdef CONFIG_SCAN_BACKOP
13602                 {
13603                         u8 sta_num;
13604                         u8 ld_sta_num;
13605                         u8 ap_num;
13606                         u8 ld_ap_num;
13607                         u8 backop_flags = 0;
13608
13609                         rtw_dev_iface_status(padapter, &sta_num, &ld_sta_num, NULL, &ap_num, &ld_ap_num);
13610
13611                         if ((ld_sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN))
13612                                         || (sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL))
13613                         ) {
13614                                 backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext);
13615                         }
13616
13617                         if ((ld_ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN))
13618                                         || (ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL))
13619                         ) {
13620                                 backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext);
13621                         }
13622
13623                         if (backop_flags) {
13624                                 if (ss->scan_cnt < ss->scan_cnt_max) {
13625                                         ss->scan_cnt++;
13626                                 } else {
13627                                         mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
13628                                         next_state = SCAN_BACKING_OP;
13629                                 }
13630                         }
13631                 }
13632                 #endif /* CONFIG_SCAN_BACKOP */
13633         } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
13634                 /* go p2p listen */
13635                 next_state = SCAN_TO_P2P_LISTEN;
13636
13637         #ifdef CONFIG_ANTENNA_DIVERSITY
13638         } else if (rtw_hal_antdiv_before_linked(padapter)) {
13639                 /* go sw antdiv before link */
13640                 next_state = SCAN_SW_ANTDIV_BL;
13641         #endif
13642         } else {
13643                 next_state = SCAN_COMPLETE;
13644
13645                 #if defined(DBG_SCAN_SW_ANTDIV_BL)
13646                 {
13647                         /* for SCAN_SW_ANTDIV_BL state testing */
13648                         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13649                         int i;
13650                         bool is_linked = _FALSE;
13651
13652                         for (i = 0; i < dvobj->iface_nums; i++) {
13653                                 if (rtw_linked_check(dvobj->padapters[i]))
13654                                         is_linked = _TRUE;
13655                         }
13656
13657                         if (!is_linked) {
13658                                 static bool fake_sw_antdiv_bl_state = 0;
13659
13660                                 if (fake_sw_antdiv_bl_state == 0) {
13661                                         next_state = SCAN_SW_ANTDIV_BL;
13662                                         fake_sw_antdiv_bl_state = 1;
13663                                 } else {
13664                                         fake_sw_antdiv_bl_state = 0;
13665                                 }
13666                         }
13667                 }
13668                 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
13669         }
13670
13671         #ifdef CONFIG_SCAN_BACKOP
13672         if (next_state != SCAN_PROCESS)
13673                 ss->scan_cnt = 0;
13674         #endif
13675
13676
13677 #ifdef DBG_FIXED_CHAN
13678         if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
13679                 scan_ch = pmlmeext->fixed_chan;
13680 #endif
13681
13682         if (ch)
13683                 *ch = scan_ch;
13684         if (type)
13685                 *type = scan_type;
13686
13687         return next_state;
13688 }
13689
13690 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
13691 {
13692         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13693         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13694
13695 #ifdef CONFIG_P2P
13696         struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
13697 #endif
13698
13699         if (survey_channel != 0) {
13700                 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
13701
13702                 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13703                 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
13704                         ACS_OP acs_op = ACS_RESET;
13705
13706                         rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
13707                         rtw_set_acs_channel(padapter, survey_channel);
13708                         #ifdef DBG_AUTO_CHNL_SEL_NHM
13709                         DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n",
13710                                 ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
13711                         #endif
13712                 }
13713                 #endif
13714
13715                 if (ScanType == SCAN_ACTIVE) {
13716                         #ifdef CONFIG_P2P
13717                         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || 
13718                                 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
13719                         ) {
13720                                 issue_probereq_p2p(padapter, NULL);
13721                                 issue_probereq_p2p(padapter, NULL);
13722                                 issue_probereq_p2p(padapter, NULL);
13723                         } else
13724                         #endif /* CONFIG_P2P */
13725                         {
13726                                 int i;
13727
13728                                 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13729                                         if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
13730                                                 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13731                                                 if (padapter->registrypriv.wifi_spec)
13732                                                         issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13733                                                 else
13734                                                         issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
13735                                                 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13736                                         }
13737                                 }
13738
13739                                 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
13740                                         /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13741                                         if (padapter->registrypriv.wifi_spec)
13742                                                 issue_probereq(padapter, NULL, NULL);
13743                                         else
13744                                                 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
13745                                         issue_probereq(padapter, NULL, NULL);
13746                                 }
13747                         }
13748                 }
13749         } else {
13750                 /* channel number is 0 or this channel is not valid. */
13751                 rtw_warn_on(1);
13752         }
13753
13754         return;
13755 }
13756
13757 void survey_done_set_ch_bw(_adapter *padapter)
13758 {
13759         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13760         u8 cur_channel = 0;
13761         u8 cur_bwmode;
13762         u8 cur_ch_offset;
13763         
13764         if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
13765                 if (0)
13766                         DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
13767                                 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13768         } else {
13769                 #ifdef CONFIG_P2P
13770                 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13771                 _adapter *iface;
13772                 int i;
13773
13774                 for (i = 0; i < dvobj->iface_nums; i++) {
13775                         iface = dvobj->padapters[i];
13776                         if (!iface)
13777                                 continue;
13778
13779                         #ifdef CONFIG_IOCTL_CFG80211
13780                         if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
13781                                 continue;
13782                         #endif
13783
13784                         if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
13785                                 cur_channel = iface->wdinfo.listen_channel;
13786                                 cur_bwmode = CHANNEL_WIDTH_20;
13787                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13788                                 if (0)
13789                                         DBG_871X(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
13790                                                 FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
13791                                 break;
13792                         }
13793                 }
13794                 #endif /* CONFIG_P2P */
13795
13796                 if (cur_channel == 0) {
13797                         cur_channel = pmlmeext->cur_channel;
13798                         cur_bwmode = pmlmeext->cur_bwmode;
13799                         cur_ch_offset = pmlmeext->cur_ch_offset;
13800                         if (0)
13801                                 DBG_871X(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
13802                                         FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13803                 }
13804         }
13805
13806         set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
13807 }
13808
13809 /**
13810  * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
13811  * @dvobj: the dvobj to check
13812  * @ps: power saving or not
13813  *
13814  * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
13815  */
13816 u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps)
13817 {
13818         _adapter *adapter;
13819         int i;
13820         u8 ps_anc = 0;
13821
13822         for (i = 0; i < dvobj->iface_nums; i++) {
13823                 adapter = dvobj->padapters[i];
13824                 if (!adapter)
13825                         continue;
13826
13827                 if (ps) {
13828                         if (is_client_associated_to_ap(adapter) == _TRUE) {
13829                                 /* TODO: TDLS peers */
13830                                 issue_nulldata(adapter, NULL, 1, 3, 500);
13831                                 ps_anc = 1;
13832                         }
13833                 } else {
13834                         if (is_client_associated_to_ap(adapter) == _TRUE) {
13835                                 /* TODO: TDLS peers */
13836                                 issue_nulldata(adapter, NULL, 0, 3, 500);
13837                                 ps_anc = 1;
13838                         }
13839                 }
13840         }
13841
13842         return ps_anc;
13843 }
13844
13845 void sitesurvey_set_igi(_adapter *adapter, bool enter)
13846 {
13847         u8 igi;
13848 #ifdef CONFIG_P2P
13849         struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13850 #endif
13851
13852         if (enter) {
13853 #ifdef CONFIG_P2P
13854 #ifdef CONFIG_IOCTL_CFG80211
13855                 if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211)
13856                         igi = 0x30;
13857                 else
13858 #endif /* CONFIG_IOCTL_CFG80211 */
13859                 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
13860                         igi = 0x28;
13861                 else
13862 #endif /* CONFIG_P2P */
13863                         igi = 0x1e;
13864         } else {
13865                         igi = 0xff; /* restore RX GAIN */
13866         }
13867
13868         rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
13869 }
13870
13871 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
13872 {
13873         struct sitesurvey_parm  *pparm = (struct sitesurvey_parm *)pbuf;
13874         struct dvobj_priv *dvobj = padapter->dvobj;
13875         struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
13876         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13877         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13878         struct ss_res *ss = &pmlmeext->sitesurvey_res;
13879         u8 val8;
13880
13881 #ifdef CONFIG_P2P
13882         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13883 #endif
13884
13885 #ifdef DBG_CHECK_FW_PS_STATE
13886         if (rtw_fw_ps_state(padapter) == _FAIL) {
13887                 DBG_871X("scan without leave 32k\n");
13888                 pdbgpriv->dbg_scan_pwr_state_cnt++;
13889         }
13890 #endif /* DBG_CHECK_FW_PS_STATE */
13891
13892         /* increase channel idx */
13893         if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
13894                 ss->channel_idx++;
13895
13896         /* update scan state to next state (assigned by previous cmd hdl) */
13897         if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
13898                 mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
13899
13900 operation_by_state:
13901         switch (mlmeext_scan_state(pmlmeext)) {
13902
13903         case SCAN_DISABLE:
13904                 /* 
13905                 * SW parameter initialization
13906                 */
13907
13908                 sitesurvey_res_reset(padapter, pparm);
13909                 mlmeext_set_scan_state(pmlmeext, SCAN_START);
13910                 goto operation_by_state;
13911
13912         case SCAN_START:
13913                 /*
13914                 * prepare to leave operating channel
13915                 */
13916
13917                 /* apply rx ampdu setting */
13918                 if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
13919                         || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID
13920                 ) {
13921                         rtw_rx_ampdu_apply(padapter);
13922                 }
13923
13924                 /* clear HW TX queue before scan */
13925                 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
13926
13927                 /* power save state announcement */
13928                 if (sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)) {
13929                         mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
13930                         mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
13931                         set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
13932                 } else {
13933                         mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
13934                         goto operation_by_state;
13935                 }
13936
13937                 break;
13938
13939         case SCAN_ENTER:
13940                 /*
13941                 * HW register and DM setting for enter scan
13942                 */
13943
13944                 /* config the initial gain under scanning */
13945                 sitesurvey_set_igi(padapter, 1);
13946                 
13947                 /* disable dynamic functions, such as high power, DIG */
13948                 rtw_phydm_ability_backup(padapter);
13949                 rtw_phydm_func_for_offchannel(padapter);
13950                 /* set MSR to no link state */
13951                 Set_MSR(padapter, _HW_STATE_NOLINK_);
13952                 val8 = 1; /* under site survey */
13953                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
13954
13955                 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
13956                 goto operation_by_state;
13957
13958         case SCAN_PROCESS:
13959         {
13960                 u8 scan_ch;
13961                 RT_SCAN_TYPE scan_type;
13962                 u8 next_state;
13963                 u32 scan_ms;
13964
13965                 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13966                 if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) {
13967                         ACS_OP acs_op = ACS_SELECT;
13968
13969                         rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
13970                 }
13971                 #endif
13972
13973                 next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
13974                 if (next_state != SCAN_PROCESS) {
13975                         #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13976                         if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
13977                                 rtw_set_acs_channel(padapter, 0);
13978                                 #ifdef DBG_AUTO_CHNL_SEL_NHM
13979                                 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
13980                                 #endif
13981                         }
13982                         #endif
13983
13984                         mlmeext_set_scan_state(pmlmeext, next_state);
13985                         goto operation_by_state;
13986                 }
13987
13988                 /* still SCAN_PROCESS state */
13989                 if (0)
13990                         #ifdef CONFIG_P2P
13991                         DBG_871X(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
13992                                 , FUNC_ADPT_ARG(padapter)
13993                                 , mlmeext_scan_state_str(pmlmeext)
13994                                 , scan_ch
13995                                 , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
13996                                 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
13997                                 , scan_type?'A':'P', ss->scan_mode?'A':'P'
13998                                 , ss->ssid[0].SsidLength?'S':' ' 
13999                         );
14000                         #else
14001                         DBG_871X(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n"
14002                                 , FUNC_ADPT_ARG(padapter)
14003                                 , mlmeext_scan_state_str(pmlmeext)
14004                                 , scan_ch
14005                                 , ss->channel_idx
14006                                 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14007                                 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14008                                 , ss->ssid[0].SsidLength?'S':' '
14009                         );
14010                         #endif /* CONFIG_P2P */
14011
14012                 #ifdef DBG_FIXED_CHAN
14013                 if (pmlmeext->fixed_chan != 0xff)
14014                         DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
14015                 #endif
14016
14017                 site_survey(padapter, scan_ch, scan_type);
14018
14019                 #if defined(CONFIG_ATMEL_RC_PATCH)
14020                 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
14021                         scan_ms = 20;
14022                 else
14023                         scan_ms = 40;
14024                 #else
14025                 scan_ms = ss->scan_ch_ms;
14026                 #endif
14027
14028                 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14029                 if (ss->is_sw_antdiv_bl_scan)
14030                         scan_ms = scan_ms/2;
14031                 #endif
14032
14033                 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14034                 {
14035                         struct noise_info info;
14036
14037                         info.bPauseDIG = _FALSE;
14038                         info.IGIValue = 0;
14039                         info.max_time = scan_ms/2;
14040                         info.chan = scan_ch;
14041                         rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE); 
14042                 }
14043                 #endif
14044
14045                 set_survey_timer(pmlmeext, scan_ms);
14046                 break;
14047         }
14048
14049         #ifdef CONFIG_SCAN_BACKOP
14050         case SCAN_BACKING_OP:
14051         {
14052                 u8 back_ch, back_bw, back_ch_offset;
14053
14054                 if (rtw_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
14055                         rtw_warn_on(1);
14056
14057                 if (0)
14058                         DBG_871X(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
14059                                 , FUNC_ADPT_ARG(padapter)
14060                                 , mlmeext_scan_state_str(pmlmeext)
14061                                 , back_ch, back_bw, back_ch_offset
14062                                 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14063                         );
14064
14065                 set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
14066
14067                 Set_MSR(padapter, (pmlmeinfo->state & 0x3));            
14068                 val8 = 0; /* survey done */
14069                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14070
14071                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14072                         sitesurvey_set_igi(padapter, 0);
14073                         sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14074                 }
14075
14076                 mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
14077                 ss->backop_time = rtw_get_current_time();
14078
14079                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME)) {
14080                         int     i;
14081
14082                         /* resume TX */
14083                         for (i = 0; i < dvobj->iface_nums; i++) {
14084                                 if (!dvobj->padapters[i])
14085                                         continue;
14086
14087                                 rtw_os_xmit_schedule(dvobj->padapters[i]);
14088                         }
14089                 }
14090
14091                 goto operation_by_state;
14092         }
14093         
14094         case SCAN_BACK_OP:
14095                 if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
14096                         || pmlmeext->scan_abort
14097                 ) {
14098                         mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
14099                         goto operation_by_state;
14100                 }
14101                 set_survey_timer(pmlmeext, 50);
14102                 break;
14103
14104         case SCAN_LEAVING_OP:
14105                 /*
14106                 * prepare to leave operating channel
14107                 */
14108
14109                 /* clear HW TX queue before scan */
14110                 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14111
14112                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
14113                         && sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)
14114                 ) {
14115                         mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14116                         mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
14117                         set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14118                 } else {
14119                         mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
14120                         goto operation_by_state;
14121                 }
14122
14123                 break;
14124
14125         case SCAN_LEAVE_OP:
14126                 /*
14127                 * HW register and DM setting for enter scan
14128                 */
14129
14130                 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14131                         /* config the initial gain under scanning */
14132                         sitesurvey_set_igi(padapter, 1);
14133                 }
14134
14135                 /* set MSR to no link state */
14136                 Set_MSR(padapter, _HW_STATE_NOLINK_);
14137                 val8 = 1; //under site survey
14138                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14139
14140                 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14141                 goto operation_by_state;
14142
14143         #endif /* CONFIG_SCAN_BACKOP */
14144
14145         #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14146         case SCAN_SW_ANTDIV_BL:
14147                 /*
14148                 * 20100721
14149                 * For SW antenna diversity before link, it needs to switch to another antenna and scan again.
14150                 * It compares the scan result and select better one to do connection.
14151                 */
14152                 ss->bss_cnt = 0;
14153                 ss->channel_idx = 0;
14154                 ss->is_sw_antdiv_bl_scan = 1;
14155
14156                 mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
14157                 set_survey_timer(pmlmeext, ss->scan_ch_ms);
14158                 break;
14159         #endif
14160
14161         #ifdef CONFIG_P2P
14162         case SCAN_TO_P2P_LISTEN:
14163                 /*
14164                 * Set the P2P State to the listen state of find phase
14165                 * and set the current channel to the listen channel
14166                 */
14167                 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14168                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
14169         
14170                 /* turn on phy-dynamic functions */
14171                 rtw_phydm_ability_restore(padapter);
14172
14173                 sitesurvey_set_igi(padapter, 0);
14174
14175                 mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
14176                 _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
14177                 break;
14178
14179         case SCAN_P2P_LISTEN:
14180                 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14181                 ss->channel_idx = 0;
14182                 goto operation_by_state;
14183         #endif /* CONFIG_P2P */
14184
14185         case SCAN_COMPLETE:             
14186                 #ifdef CONFIG_P2P
14187                 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14188                         || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14189                 ) {
14190                         #ifdef CONFIG_CONCURRENT_MODE
14191                         if (pwdinfo->driver_interface == DRIVER_WEXT) {
14192                                 if (check_buddy_fwstate(padapter, _FW_LINKED))
14193                                         _set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
14194                         }
14195                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14196                         #else
14197                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14198                         #endif
14199                 }
14200                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
14201                 #endif /* CONFIG_P2P */
14202
14203                 /* switch channel */
14204                 survey_done_set_ch_bw(padapter);
14205
14206                 /* config MSR */
14207                 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14208                 val8 = 0; /* survey done */
14209                 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14210
14211                 /* turn on phy-dynamic functions */
14212                 rtw_phydm_ability_restore(padapter);
14213
14214                 sitesurvey_set_igi(padapter, 0);
14215
14216                 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14217
14218                 /* apply rx ampdu setting */
14219                 rtw_rx_ampdu_apply(padapter);
14220
14221                 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
14222
14223                 report_surveydone_event(padapter);
14224
14225                 issue_action_BSSCoexistPacket(padapter);
14226                 issue_action_BSSCoexistPacket(padapter);
14227                 issue_action_BSSCoexistPacket(padapter);
14228         }
14229
14230         return H2C_SUCCESS;
14231 }
14232
14233 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
14234 {
14235         struct setauth_parm             *pparm = (struct setauth_parm *)pbuf;
14236         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14237         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14238         
14239         if (pparm->mode < 4)
14240         {
14241                 pmlmeinfo->auth_algo = pparm->mode;
14242         }
14243
14244         return  H2C_SUCCESS;
14245 }
14246
14247 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
14248 {
14249         u16     ctrl = 0;
14250         s16 cam_id = 0;
14251         struct setkey_parm              *pparm = (struct setkey_parm *)pbuf;
14252         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14253         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14254         unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14255         struct set_stakey_parm  sta_pparm;
14256         struct security_priv *psecuritypriv = &padapter->securitypriv;
14257         u8 *addr;
14258         bool used;
14259
14260         //main tx key for wep.
14261         if(pparm->set_tx)
14262                 pmlmeinfo->key_index = pparm->keyid;
14263
14264         cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used);
14265
14266         if (cam_id < 0)
14267                 goto enable_mc;
14268
14269         if (cam_id > 3) /* not default key, searched by A2 */
14270                 addr = get_bssid(&padapter->mlmepriv);
14271         else
14272                 addr = null_addr;
14273
14274         #ifdef DYNAMIC_CAMID_ALLOC
14275         /* cam entry searched is pairwise key */
14276         if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
14277                 s16 camid_clr;
14278
14279                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
14280                         , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
14281
14282                 /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
14283                 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14284                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14285
14286                 /* clear group key */
14287                 while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
14288                         DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
14289                         clear_cam_entry(padapter, camid_clr);
14290                         rtw_camid_free(padapter, camid_clr);
14291                 }
14292
14293                 goto enable_mc;
14294         }
14295         #endif
14296
14297         ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
14298         DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
14299                 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
14300         write_cam(padapter, cam_id, ctrl, addr, pparm->key);
14301
14302         #ifdef DYNAMIC_CAMID_ALLOC
14303         if (cam_id >=0 && cam_id <=3)
14304                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE);
14305         #endif
14306         /* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
14307         if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC) && is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm)) {
14308                 struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
14309
14310                 sta_pparm.algorithm = pparm->algorithm;
14311                 sta_pparm.keyid = pparm->keyid;
14312                 _rtw_memcpy(sta_pparm.key, pparm->key, 16);
14313                 _rtw_memcpy(sta_pparm.addr, get_bssid(pmlmepriv), ETH_ALEN);
14314                 set_stakey_hdl(padapter, (u8 *) &sta_pparm);
14315         }
14316
14317 enable_mc:
14318         //allow multicast packets to driver
14319         rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
14320
14321         return H2C_SUCCESS;
14322 }
14323
14324 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
14325 {
14326         u16 ctrl = 0;
14327         s16 cam_id = 0;
14328         bool used;
14329         u8 ret = H2C_SUCCESS;
14330         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14331         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14332         struct set_stakey_parm  *pparm = (struct set_stakey_parm *)pbuf;
14333         struct sta_priv *pstapriv = &padapter->stapriv;
14334         struct sta_info *psta;
14335
14336         if(pparm->algorithm == _NO_PRIVACY_)
14337                 goto write_to_cam;
14338
14339         psta = rtw_get_stainfo(pstapriv, pparm->addr);
14340         if (!psta) {
14341                 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
14342                 ret = H2C_REJECTED;
14343                 goto exit;
14344         }
14345
14346         pmlmeinfo->enc_algo = pparm->algorithm;
14347         cam_id = rtw_camid_alloc(padapter, psta, 0, &used);
14348         if (cam_id < 0)
14349                 goto exit;
14350
14351         #ifdef DYNAMIC_CAMID_ALLOC
14352         /* cam entry searched is group key */
14353         if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
14354                 s16 camid_clr;
14355
14356                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
14357                         , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
14358
14359                 /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
14360                 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14361                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14362
14363                 /* clear group key */
14364                 while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
14365                         DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
14366                         clear_cam_entry(padapter, camid_clr);
14367                         rtw_camid_free(padapter, camid_clr);
14368                 }
14369         }
14370         #endif
14371
14372 write_to_cam:
14373         if(pparm->algorithm == _NO_PRIVACY_) {
14374                 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
14375                         DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
14376                         clear_cam_entry(padapter, cam_id);
14377                         rtw_camid_free(padapter,cam_id);
14378                 }
14379         } else {
14380                 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
14381                         cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
14382                 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
14383                 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
14384         }
14385         ret = H2C_SUCCESS_RSP;
14386
14387 exit:
14388         return ret;
14389 }
14390
14391 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
14392 {
14393         struct addBaReq_parm    *pparm = (struct addBaReq_parm *)pbuf;
14394         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14395         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14396
14397         struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
14398         
14399         if(!psta)
14400                 return  H2C_SUCCESS;
14401                 
14402 #ifdef CONFIG_80211N_HT
14403         if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
14404                 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
14405         {
14406                 //pmlmeinfo->ADDBA_retry_count = 0;
14407                 //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);               
14408                 //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
14409                 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14410                 //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
14411                 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14412         }
14413 #ifdef CONFIG_TDLS
14414         else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&& 
14415                 (psta->htpriv.ht_option==_TRUE) && 
14416                 (psta->htpriv.ampdu_enable==_TRUE) )
14417         {
14418                 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14419                 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14420         }
14421 #endif //CONFIG
14422         else
14423         {               
14424                 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);          
14425         }
14426 #endif //CONFIG_80211N_HT
14427         return  H2C_SUCCESS;
14428 }
14429
14430
14431 u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
14432 {
14433         struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
14434         u8 ret = _TRUE, i = 0, try_cnt = 3, wait_ms = 50;
14435         struct recv_reorder_ctrl *preorder_ctrl;
14436         struct sta_priv *pstapriv = &padapter->stapriv;
14437         struct sta_info *psta;
14438
14439         psta = rtw_get_stainfo(pstapriv, pparm->addr);
14440         if (!psta)
14441                 goto exit;
14442
14443         preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
14444         ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
14445
14446         #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
14447         /* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
14448         if (pparm->status == 0) {
14449                 preorder_ctrl->indicate_seq = pparm->start_seq;
14450                 #ifdef DBG_RX_SEQ
14451                 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __func__, __LINE__,
14452                         preorder_ctrl->indicate_seq, pparm->start_seq);
14453                 #endif
14454         }
14455         #else
14456         preorder_ctrl->indicate_seq = 0xffff;
14457         #endif
14458
14459         /*
14460           * status = 0 means accept this addba req
14461           * status = 37 means reject this addba req
14462           */
14463         if (pparm->status == 0) {
14464                 preorder_ctrl->enable = _TRUE;
14465                 preorder_ctrl->ampdu_size = pparm->size;
14466         } else if (pparm->status == 37)
14467                 preorder_ctrl->enable = _FALSE;
14468
14469 exit:
14470         return H2C_SUCCESS;
14471 }
14472
14473 u8 chk_bmc_sleepq_cmd(_adapter* padapter)
14474 {
14475         struct cmd_obj *ph2c;
14476         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14477         u8 res = _SUCCESS;
14478
14479 _func_enter_;
14480
14481         if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14482         {
14483                 res= _FAIL;
14484                 goto exit;
14485         }
14486
14487         init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
14488
14489         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14490
14491 exit:
14492
14493 _func_exit_;
14494
14495         return res;
14496 }
14497
14498 u8 set_tx_beacon_cmd(_adapter* padapter)
14499 {
14500         struct cmd_obj  *ph2c;
14501         struct Tx_Beacon_param  *ptxBeacon_parm;        
14502         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14503         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
14504         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
14505         u8      res = _SUCCESS;
14506         int len_diff = 0;
14507         
14508 _func_enter_;   
14509
14510         if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14511         {
14512                 res= _FAIL;
14513                 goto exit;
14514         }
14515
14516         if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
14517         {
14518                 rtw_mfree((unsigned char *)ph2c, sizeof(struct  cmd_obj));
14519                 res= _FAIL;
14520                 goto exit;
14521         }
14522
14523         _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
14524
14525         len_diff = update_hidden_ssid(
14526                 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
14527                 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
14528                 , pmlmeinfo->hidden_ssid_mode
14529         );
14530         ptxBeacon_parm->network.IELength += len_diff;
14531
14532         init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
14533
14534         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14535
14536         
14537 exit:
14538         
14539 _func_exit_;
14540
14541         return res;
14542 }
14543
14544
14545 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
14546 {
14547         u8 evt_code, evt_seq;
14548         u16 evt_sz;
14549         uint    *peventbuf;
14550         void (*event_callback)(_adapter *dev, u8 *pbuf);
14551         struct evt_priv *pevt_priv = &(padapter->evtpriv);
14552
14553         if (pbuf == NULL)
14554                 goto _abort_event_;
14555
14556         peventbuf = (uint*)pbuf;
14557         evt_sz = (u16)(*peventbuf&0xffff);
14558         evt_seq = (u8)((*peventbuf>>24)&0x7f);
14559         evt_code = (u8)((*peventbuf>>16)&0xff);
14560         
14561                 
14562         #ifdef CHECK_EVENT_SEQ
14563         // checking event sequence...           
14564         if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
14565         {
14566                 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)));
14567         
14568                 pevt_priv->event_seq = (evt_seq+1)&0x7f;
14569
14570                 goto _abort_event_;
14571         }
14572         #endif
14573
14574         // checking if event code is valid
14575         if (evt_code >= MAX_C2HEVT)
14576         {
14577                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
14578                 goto _abort_event_;
14579         }
14580
14581         // checking if event size match the event parm size     
14582         if ((wlanevents[evt_code].parmsize != 0) && 
14583                         (wlanevents[evt_code].parmsize != evt_sz))
14584         {
14585                         
14586                 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n", 
14587                         evt_code, wlanevents[evt_code].parmsize, evt_sz));
14588                 goto _abort_event_;     
14589                         
14590         }
14591
14592         ATOMIC_INC(&pevt_priv->event_seq);
14593
14594         peventbuf += 2;
14595                                 
14596         if(peventbuf)
14597         {
14598                 event_callback = wlanevents[evt_code].event_callback;
14599                 event_callback(padapter, (u8*)peventbuf);
14600
14601                 pevt_priv->evt_done_cnt++;
14602         }
14603
14604
14605 _abort_event_:
14606
14607
14608         return H2C_SUCCESS;
14609                 
14610 }
14611
14612 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
14613 {
14614         if(!pbuf)
14615                 return H2C_PARAMETERS_ERROR;
14616
14617         return H2C_SUCCESS;
14618 }
14619
14620 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
14621 {
14622 #ifdef CONFIG_AP_MODE
14623         _irqL irqL;
14624         struct sta_info *psta_bmc;
14625         _list   *xmitframe_plist, *xmitframe_phead;
14626         struct xmit_frame *pxmitframe=NULL;
14627         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
14628         struct sta_priv  *pstapriv = &padapter->stapriv;
14629
14630         //for BC/MC Frames
14631         psta_bmc = rtw_get_bcmc_stainfo(padapter);
14632         if(!psta_bmc)
14633                 return H2C_SUCCESS;
14634
14635         if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
14636         {
14637 #ifndef CONFIG_PCI_HCI
14638                 rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
14639 #endif
14640                 //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14641                 _enter_critical_bh(&pxmitpriv->lock, &irqL);
14642
14643                 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
14644                 xmitframe_plist = get_next(xmitframe_phead);
14645
14646                 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
14647                 {
14648                         pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
14649
14650                         xmitframe_plist = get_next(xmitframe_plist);
14651
14652                         rtw_list_delete(&pxmitframe->list);
14653
14654                         psta_bmc->sleepq_len--;
14655                         if(psta_bmc->sleepq_len>0)
14656                                 pxmitframe->attrib.mdata = 1;
14657                         else
14658                                 pxmitframe->attrib.mdata = 0;
14659
14660                         pxmitframe->attrib.triggered=1;
14661
14662                         if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
14663                                 pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ
14664
14665                         #if 0
14666                         _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14667                         if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
14668                         {
14669                                 rtw_os_xmit_complete(padapter, pxmitframe);
14670                         }
14671                         _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14672                         #endif
14673                         rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
14674                 }
14675
14676                 //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14677                 _exit_critical_bh(&pxmitpriv->lock, &irqL);
14678
14679                 if (rtw_get_intf_type(padapter) != RTW_PCIE) {
14680                         /* check hi queue and bmc_sleepq */
14681                         rtw_chk_hi_queue_cmd(padapter);
14682                 }
14683         }
14684 #endif
14685
14686         return H2C_SUCCESS;
14687 }
14688
14689 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
14690 {
14691         if(send_beacon(padapter)==_FAIL)
14692         {
14693                 DBG_871X("issue_beacon, fail!\n");
14694                 return H2C_PARAMETERS_ERROR;
14695         }
14696
14697
14698         if (padapter->registrypriv.wifi_spec == 1)
14699                 return H2C_SUCCESS;
14700         
14701         /* tx bc/mc frames after update TIM */
14702         chk_bmc_sleepq_hdl(padapter, NULL);
14703
14704         return H2C_SUCCESS;
14705 }
14706
14707 /*
14708 * according to channel
14709 * add/remove WLAN_BSSID_EX.IEs's ERP ie
14710 * set WLAN_BSSID_EX.SupportedRates
14711 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
14712 */
14713 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
14714 {
14715         u8      network_type,rate_len, total_rate_len,remainder_rate_len;
14716         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
14717         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14718         u8      erpinfo=0x4;
14719
14720         if (ch >= 36) {
14721                 network_type = WIRELESS_11A;
14722                 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
14723                 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
14724         } else {
14725                 network_type = WIRELESS_11BG;
14726                 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
14727                 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
14728         }
14729
14730         rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
14731
14732         UpdateBrateTbl(padapter, pnetwork->SupportedRates);
14733
14734         if(total_rate_len > 8)
14735         {
14736                 rate_len = 8;
14737                 remainder_rate_len = total_rate_len - 8;
14738         }
14739         else
14740         {
14741                 rate_len = total_rate_len;
14742                 remainder_rate_len = 0;
14743         }
14744
14745         rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
14746
14747         if(remainder_rate_len)
14748         {
14749                 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
14750         }
14751         else
14752         {
14753                 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
14754         }
14755
14756         pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
14757 }
14758
14759 #ifdef CONFIG_CONCURRENT_MODE
14760 sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
14761 {
14762         PADAPTER pbuddy_adapter;
14763         struct mlme_ext_priv *pbuddy_mlmeext;
14764         struct mlme_ext_info *pbuddy_mlmeinfo;
14765
14766         if(padapter == NULL)
14767                 return _FALSE;  
14768         
14769         pbuddy_adapter = padapter->pbuddy_adapter;
14770
14771         if(pbuddy_adapter == NULL)
14772                 return _FALSE;  
14773
14774
14775         pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
14776         pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
14777                 
14778         if((pbuddy_mlmeinfo->state&0x03) == state)
14779                 return _TRUE;           
14780
14781         return _FALSE;
14782         
14783 }
14784 #endif /* CONFIG_CONCURRENT_MODE */
14785
14786 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
14787 {
14788 #define DUMP_ADAPTERS_STATUS 0
14789
14790         struct dvobj_priv *dvobj;
14791         _adapter *iface;
14792         struct mlme_priv *mlme;
14793         struct mlme_ext_priv *mlmeext;
14794         u8 u_ch, u_offset, u_bw;
14795         int i;
14796
14797         dvobj = adapter_to_dvobj(adapter);
14798
14799         if (DUMP_ADAPTERS_STATUS) {
14800                 DBG_871X(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
14801                 dump_adapters_status(RTW_DBGDUMP , dvobj);
14802         }
14803
14804         if (join_res >= 0) {
14805                 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14806                         dump_adapters_status(RTW_DBGDUMP , dvobj);
14807                         rtw_warn_on(1);
14808                 }
14809
14810                 for (i = 0; i < dvobj->iface_nums; i++) {
14811                         iface = dvobj->padapters[i];
14812                         mlme = &iface->mlmepriv;
14813                         mlmeext = &iface->mlmeextpriv;
14814
14815                         if (!iface || iface == adapter)
14816                                 continue;
14817
14818                         if (check_fwstate(mlme, WIFI_AP_STATE)
14819                                 && check_fwstate(mlme, WIFI_ASOC_STATE)
14820                         ) {
14821                                 bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
14822                                         , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14823
14824                                 if (is_grouped == _FALSE) {
14825                                         /* handle AP which need to switch ch setting */
14826
14827                                         /* restore original bw, adjust bw by registry setting on target ch */
14828                                         mlmeext->cur_bwmode = mlme->ori_bw;
14829                                         mlmeext->cur_channel = u_ch;
14830                                         rtw_adjust_chbw(iface
14831                                                 , mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
14832                                         
14833                                         rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
14834                                                 , &u_ch, &u_bw, &u_offset);
14835
14836                                         rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
14837                                                 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14838
14839                                         _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
14840
14841                                         rtw_start_bss_hdl_after_chbw_decided(iface);
14842                                 }
14843
14844                                 update_beacon(iface, 0, NULL, _TRUE);
14845                         }
14846
14847                         clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14848                 }
14849
14850                 #ifdef CONFIG_DFS_MASTER
14851                 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED);
14852                 #endif
14853         } else {
14854                 for (i = 0; i < dvobj->iface_nums; i++) {
14855                         iface = dvobj->padapters[i];
14856                         mlme = &iface->mlmepriv;
14857                         mlmeext = &iface->mlmeextpriv;
14858
14859                         if (!iface || iface == adapter)
14860                                 continue;
14861
14862                         if (check_fwstate(mlme, WIFI_AP_STATE)
14863                                 && check_fwstate(mlme, WIFI_ASOC_STATE))
14864                                 update_beacon(iface, 0, NULL, _TRUE);
14865
14866                         clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14867                 }
14868                 #ifdef CONFIG_DFS_MASTER
14869                 rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED);
14870                 #endif
14871         }
14872
14873         if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
14874                 set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
14875
14876         if (DUMP_ADAPTERS_STATUS) {
14877                 DBG_871X(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
14878                 dump_adapters_status(RTW_DBGDUMP , dvobj);
14879         }
14880 }
14881
14882 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
14883 {
14884         bool chbw_allow = _TRUE;
14885         bool connect_allow = _TRUE;
14886         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
14887         u8 cur_ch, cur_bw, cur_ch_offset;
14888         u8 u_ch, u_offset, u_bw;
14889
14890         u_ch = cur_ch = pmlmeext->cur_channel;
14891         u_bw = cur_bw = pmlmeext->cur_bwmode;
14892         u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
14893
14894         if (!ch || !bw || !offset) {
14895                 connect_allow = _FALSE;
14896                 rtw_warn_on(1);
14897                 goto exit;
14898         }
14899
14900         if (cur_ch == 0) {
14901                 connect_allow = _FALSE;
14902                 DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n"
14903                         , FUNC_ADPT_ARG(adapter), cur_ch);
14904                 rtw_warn_on(1);
14905                 goto exit;
14906         }
14907         DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14908
14909 #ifdef CONFIG_CONCURRENT_MODE
14910 {
14911         struct dvobj_priv *dvobj;
14912         _adapter *iface;
14913         struct mlme_priv *mlme;
14914         struct mlme_ext_priv *mlmeext;
14915         u8 sta_num;
14916         u8 ld_sta_num;
14917         u8 lg_sta_num;
14918         u8 ap_num;
14919         u8 ld_ap_num;
14920         int i;
14921
14922         dvobj = adapter_to_dvobj(adapter);
14923
14924         rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num);
14925         DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n"
14926                 , FUNC_ADPT_ARG(adapter), ld_sta_num, ap_num);
14927
14928         if (!ld_sta_num && !ap_num) {
14929                 /* consider linking STA? */
14930                 goto connect_allow_hdl;
14931         }
14932
14933         if (rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14934                 dump_adapters_status(RTW_DBGDUMP , dvobj);
14935                 rtw_warn_on(1);
14936         }
14937         DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
14938                 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14939
14940         /* chbw_allow? */
14941         chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
14942                 , u_ch, u_bw, u_offset);
14943
14944         DBG_871X(FUNC_ADPT_FMT" chbw_allow:%d\n"
14945                 , FUNC_ADPT_ARG(adapter), chbw_allow);
14946
14947         if (chbw_allow == _TRUE) {
14948                 rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
14949                 rtw_warn_on(cur_ch != pmlmeext->cur_channel);
14950                 rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
14951                 rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
14952                 goto connect_allow_hdl;
14953         }
14954
14955         /* chbw_allow is _FALSE, connect allow? */
14956         for (i = 0; i < dvobj->iface_nums; i++) {
14957                 iface = dvobj->padapters[i];
14958                 mlme = &iface->mlmepriv;
14959                 mlmeext = &iface->mlmeextpriv;
14960
14961                 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
14962                 if (check_fwstate(mlme, WIFI_STATION_STATE)
14963                         && check_fwstate(mlme, WIFI_ASOC_STATE)
14964                         #if defined(CONFIG_P2P)
14965                         && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
14966                         #endif
14967                 ) {
14968                         connect_allow = _FALSE;
14969                         break;
14970                 }
14971                 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
14972         }
14973         DBG_871X(FUNC_ADPT_FMT" connect_allow:%d\n"
14974                 , FUNC_ADPT_ARG(adapter), connect_allow);
14975
14976         if (connect_allow == _FALSE)
14977                 goto exit;
14978
14979 connect_allow_hdl:
14980         /* connect_allow == _TRUE */
14981
14982         #ifdef CONFIG_DFS_MASTER
14983         rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING);
14984         #endif
14985
14986         if (chbw_allow == _FALSE) {
14987                 u_ch = cur_ch;
14988                 u_bw = cur_bw;
14989                 u_offset = cur_ch_offset;
14990
14991                 for (i = 0; i < dvobj->iface_nums; i++) {
14992                         iface = dvobj->padapters[i];
14993                         mlme = &iface->mlmepriv;
14994                         mlmeext = &iface->mlmeextpriv;
14995
14996                         if (!iface || iface == adapter)
14997                                 continue;
14998
14999                         if (check_fwstate(mlme, WIFI_AP_STATE)
15000                                 && check_fwstate(mlme, WIFI_ASOC_STATE)
15001                         ) {
15002                                 #ifdef CONFIG_SPCT_CH_SWITCH
15003                                 if (1)
15004                                         rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
15005                                 else
15006                                 #endif
15007                                         rtw_sta_flush(iface, _FALSE);
15008
15009                                 rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
15010                                 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15011                         } else if (check_fwstate(mlme, WIFI_STATION_STATE)
15012                                 && check_fwstate(mlme, WIFI_ASOC_STATE)
15013                         ) {
15014                                 rtw_disassoc_cmd(iface, 500, _FALSE);
15015                                 rtw_indicate_disconnect(iface, 0, _FALSE);
15016                                 rtw_free_assoc_resources(iface, 1);
15017                         }
15018                 }
15019         }
15020 }
15021 #endif /* CONFIG_CONCURRENT_MODE */
15022
15023 exit:
15024
15025         if (connect_allow == _TRUE) {
15026                 DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15027                 *ch = u_ch;
15028                 *bw = u_bw;
15029                 *offset = u_offset;
15030         }
15031
15032         return connect_allow == _TRUE ? _SUCCESS : _FAIL;
15033 }
15034
15035 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
15036 int _rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
15037 {
15038         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15039         _adapter *iface;
15040         struct mlme_ext_priv *mlmeext;
15041         int i;
15042         u8 ch_ret = 0;
15043         u8 bw_ret = CHANNEL_WIDTH_20;
15044         u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15045         int num = 0;
15046
15047         if (ch) *ch = 0;
15048         if (bw) *bw = CHANNEL_WIDTH_20;
15049         if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15050
15051         for (i = 0; i<dvobj->iface_nums; i++) {
15052                 iface = dvobj->padapters[i];
15053                 mlmeext = &iface->mlmeextpriv;
15054
15055                 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
15056                         continue;
15057
15058                 if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
15059                         continue;
15060
15061                 if (include_self == _FALSE && adapter == iface)
15062                         continue;
15063
15064                 if (num == 0) {
15065                         ch_ret = mlmeext->cur_channel;
15066                         bw_ret = mlmeext->cur_bwmode;
15067                         offset_ret = mlmeext->cur_ch_offset;
15068                         num++;
15069                         continue;
15070                 }
15071
15072                 if (ch_ret != mlmeext->cur_channel) {
15073                         num = 0;
15074                         break;
15075                 }
15076
15077                 if (bw_ret < mlmeext->cur_bwmode) {
15078                         bw_ret = mlmeext->cur_bwmode;
15079                         offset_ret = mlmeext->cur_ch_offset;
15080                 } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
15081                         num = 0;
15082                         break;
15083                 }
15084
15085                 num++;
15086         }
15087
15088         if (num) {
15089                 if (ch) *ch = ch_ret;
15090                 if (bw) *bw = bw_ret;
15091                 if (offset) *offset = offset_ret;
15092         }
15093
15094         return num;
15095 }
15096
15097 inline int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15098 {
15099         return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 1);
15100 }
15101
15102 inline int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15103 {
15104         return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 0);
15105 }
15106
15107 void _rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15108         , u8 *ap_num, u8 *ld_ap_num, bool include_self)
15109 {
15110         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15111         _adapter *iface;
15112         struct mlme_ext_priv *mlmeext;
15113         struct mlme_ext_info *mlmeextinfo;
15114         int i;
15115         u8 sta_num_ret = 0;
15116         u8 ld_sta_num_ret = 0;
15117         u8 lg_sta_num_ret = 0;
15118         u8 ap_num_ret = 0;
15119         u8 ld_ap_num_ret = 0;
15120
15121         if (sta_num)
15122                 *sta_num = 0;
15123         if (ld_sta_num)
15124                 *ld_sta_num = 0;
15125         if (lg_sta_num)
15126                 *lg_sta_num = 0;
15127         if (ap_num)
15128                 *ap_num = 0;
15129         if (ld_ap_num)
15130                 *ld_ap_num = 0;
15131
15132         for (i = 0; i < dvobj->iface_nums; i++) {
15133                 iface = dvobj->padapters[i];
15134
15135                 if (include_self == _FALSE && iface == adapter)
15136                         continue;
15137
15138                 mlmeext = &iface->mlmeextpriv;
15139
15140                 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
15141                         sta_num_ret++;
15142                         if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
15143                                 ld_sta_num_ret++;
15144                         if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
15145                                 lg_sta_num_ret++;
15146                 }
15147
15148                 if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
15149                         && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
15150                 ) {
15151                         ap_num_ret++;
15152                         if (iface->stapriv.asoc_sta_count > 2)
15153                                 ld_ap_num_ret++;
15154                 }
15155         }
15156
15157         if (sta_num)
15158                 *sta_num = sta_num_ret;
15159         if (ld_sta_num)
15160                 *ld_sta_num = ld_sta_num_ret;
15161         if (lg_sta_num)
15162                 *lg_sta_num = lg_sta_num_ret;
15163         if (ap_num)
15164                 *ap_num = ap_num_ret;
15165         if (ld_ap_num)
15166                 *ld_ap_num = ld_ap_num_ret;
15167 }
15168
15169 inline void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15170         , u8 *ap_num, u8 *ld_ap_num)
15171 {
15172         return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 1);
15173 }
15174
15175 inline void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15176         , u8 *ap_num, u8 *ld_ap_num)
15177 {
15178         return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 0);
15179 }
15180
15181 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
15182 {
15183         struct set_ch_parm *set_ch_parm;
15184         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
15185         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
15186
15187         if(!pbuf)
15188                 return H2C_PARAMETERS_ERROR;
15189
15190         set_ch_parm = (struct set_ch_parm *)pbuf;
15191
15192         DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
15193                 FUNC_NDEV_ARG(padapter->pnetdev),
15194                 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
15195
15196         pmlmeext->cur_channel = set_ch_parm->ch;
15197         pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
15198         pmlmeext->cur_bwmode = set_ch_parm->bw;
15199
15200         set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
15201
15202         return  H2C_SUCCESS;
15203 }
15204
15205 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
15206 {
15207         struct SetChannelPlan_param *setChannelPlan_param;
15208         struct mlme_priv *mlme = &padapter->mlmepriv;
15209         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15210
15211         if(!pbuf)
15212                 return H2C_PARAMETERS_ERROR;
15213
15214         setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
15215
15216         if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) {
15217                 return H2C_PARAMETERS_ERROR;
15218         }
15219
15220         mlme->country_ent = setChannelPlan_param->country_ent;
15221         mlme->ChannelPlan = setChannelPlan_param->channel_plan;
15222
15223         pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
15224         init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);   
15225
15226         rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE);
15227         
15228 #ifdef CONFIG_IOCTL_CFG80211
15229         rtw_reg_notify_by_driver(padapter);
15230 #endif //CONFIG_IOCTL_CFG80211
15231
15232         return  H2C_SUCCESS;
15233 }
15234
15235 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
15236 {
15237         struct LedBlink_param *ledBlink_param;
15238
15239         if(!pbuf)
15240                 return H2C_PARAMETERS_ERROR;
15241
15242         ledBlink_param = (struct LedBlink_param *)pbuf;
15243
15244         #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
15245         BlinkHandler((PLED_DATA)ledBlink_param->pLed);
15246         #endif
15247
15248         return  H2C_SUCCESS;
15249 }
15250
15251 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
15252 {
15253 #ifdef CONFIG_DFS
15254         struct SetChannelSwitch_param *setChannelSwitch_param;
15255         u8 new_ch_no;
15256         u8 gval8 = 0x00, sval8 = 0xff;
15257
15258         if(!pbuf)
15259                 return H2C_PARAMETERS_ERROR;
15260
15261         setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
15262         new_ch_no = setChannelSwitch_param->new_ch_no;
15263
15264         rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15265
15266         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
15267
15268         DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
15269         SelectChannel(padapter, new_ch_no);
15270
15271         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15272
15273         rtw_disassoc_cmd(padapter, 0, _FALSE);
15274         rtw_indicate_disconnect(padapter, 0, _FALSE);
15275         rtw_free_assoc_resources(padapter, 1);
15276         rtw_free_network_queue(padapter, _TRUE);
15277
15278         if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
15279                 DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
15280         }
15281
15282         return  H2C_SUCCESS;
15283 #else
15284         return  H2C_REJECTED;
15285 #endif //CONFIG_DFS
15286
15287 }
15288
15289 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
15290 {
15291 #ifdef CONFIG_TDLS
15292         _irqL irqL;
15293         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
15294         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
15295 #ifdef CONFIG_TDLS_CH_SW        
15296         struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
15297 #endif
15298         struct TDLSoption_param *TDLSoption;
15299         struct sta_info *ptdls_sta = NULL;
15300         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15301         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
15302         u8 survey_channel, i, min, option;
15303         struct tdls_txmgmt txmgmt;
15304         u32 setchtime, resp_sleep = 0, wait_time;
15305         u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15306         u8 ret;
15307         u8 doiqk;
15308
15309         if (!pbuf)
15310                 return H2C_PARAMETERS_ERROR;
15311
15312         TDLSoption = (struct TDLSoption_param *)pbuf;
15313         option = TDLSoption->option;
15314
15315         if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
15316                 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
15317                 if (ptdls_sta == NULL) {
15318                         return H2C_REJECTED;
15319                 }
15320         } else {
15321                 if (!(option == TDLS_RS_RCR))
15322                         return H2C_REJECTED;
15323         }
15324
15325         //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15326         //DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
15327                 
15328         switch (option) {
15329         case TDLS_ESTABLISHED:
15330         {
15331                 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
15332                 /* So we can receive all kinds of data frames. */
15333                 u8 sta_band = 0;
15334
15335                 //leave ALL PS when TDLS is established
15336                         rtw_pwr_wakeup(padapter);
15337
15338                 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
15339                 DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
15340
15341                 /* Set TDLS sta rate. */
15342                 /* Update station supportRate */
15343                 rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
15344                 if (pmlmeext->cur_channel > 14) {
15345                         if (ptdls_sta->ra_mask & 0xffff000)
15346                                 sta_band |= WIRELESS_11_5N ;
15347
15348                         if (ptdls_sta->ra_mask & 0xff0)
15349                                 sta_band |= WIRELESS_11A;
15350
15351                         /* 5G band */
15352                         #ifdef CONFIG_80211AC_VHT
15353                         if (ptdls_sta->vhtpriv.vht_option)
15354                                 sta_band = WIRELESS_11_5AC;
15355                         #endif
15356                         
15357                 } else {
15358                         if (ptdls_sta->ra_mask & 0xffff000)
15359                                 sta_band |= WIRELESS_11_24N;
15360
15361                         if (ptdls_sta->ra_mask & 0xff0)
15362                                 sta_band |= WIRELESS_11G;
15363
15364                         if (ptdls_sta->ra_mask & 0x0f)
15365                                 sta_band |= WIRELESS_11B;
15366                 }
15367                 ptdls_sta->wireless_mode = sta_band;
15368                 ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta);
15369                 set_sta_rate(padapter, ptdls_sta);
15370                 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
15371                 /* Sta mode */
15372                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE);
15373                 break;
15374         }
15375         case TDLS_ISSUE_PTI:
15376                 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
15377                 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
15378                 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
15379                 break;
15380 #ifdef CONFIG_TDLS_CH_SW                
15381         case TDLS_CH_SW_RESP:
15382                 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15383                 txmgmt.status_code = 0;
15384                 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15385
15386                 issue_nulldata(padapter, NULL, 1, 3, 3);
15387
15388                 DBG_871X("[TDLS ] issue tdls channel switch response\n");
15389                 ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
15390
15391                 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
15392                 /* then we just SelectChannel to AP's channel*/
15393                 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
15394                         rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
15395                         break;
15396                 }
15397
15398                 if (ret == _SUCCESS)
15399                         rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_OFF_CHNL);
15400                 else
15401                         DBG_871X("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
15402
15403                 break;
15404         case TDLS_CH_SW_PREPARE:
15405                 pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
15406
15407                 /* to collect IQK info of off-chnl */
15408                 doiqk = _TRUE;
15409                 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15410                 set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
15411                 doiqk = _FALSE;
15412                 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15413
15414                 /* switch back to base-chnl */
15415                 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
15416
15417                 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
15418
15419                 pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
15420
15421                 break;
15422         case TDLS_CH_SW_START:
15423                 rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
15424                 break;
15425         case TDLS_CH_SW_TO_OFF_CHNL:
15426                 issue_nulldata(padapter, NULL, 1, 3, 3);
15427
15428                 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15429                         _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) / 1000);
15430
15431                 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num,
15432                         pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
15433                                 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15434                                 if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
15435                                         if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 1, 3) == _FAIL)
15436                                                 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15437                                 }
15438                 } else {
15439                         u8 bcancelled;
15440
15441                         if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15442                                 _cancel_timer(&ptdls_sta->ch_sw_timer, &bcancelled);
15443                 }
15444
15445
15446                 break;
15447         case TDLS_CH_SW_END:
15448         case TDLS_CH_SW_END_TO_BASE_CHNL:
15449                 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15450                 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
15451                 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
15452                 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
15453 #if 0
15454                 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
15455                 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
15456 #endif
15457
15458                 if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
15459                         rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15460
15461                 break;
15462         case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
15463         case TDLS_CH_SW_TO_BASE_CHNL:
15464                 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
15465
15466                 if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
15467                         if (ptdls_sta != NULL) {
15468                                 /* Send unsolicited channel switch rsp. to peer */
15469                                 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15470                                 txmgmt.status_code = 0;
15471                                 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15472                                 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
15473                         }
15474                 }
15475
15476                 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel,
15477                         pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
15478                         issue_nulldata(padapter, NULL, 0, 3, 3);
15479                         /* set ch sw monitor timer for responder */
15480                         if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15481                                 _set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
15482                 }
15483
15484                 break;
15485 #endif          
15486         case TDLS_RS_RCR:
15487                 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
15488                 DBG_871X("[TDLS] write REG_RCR, set bit6 on\n");
15489                 break;
15490         case TDLS_TEARDOWN_STA:
15491                 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15492                 txmgmt.status_code = 0;
15493                 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15494
15495                 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
15496                 break;
15497         case TDLS_TEARDOWN_STA_LOCALLY:
15498 #ifdef CONFIG_TDLS_CH_SW        
15499                 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
15500                         pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
15501                                                                                 TDLS_CH_SWITCH_ON_STATE |
15502                                                                                 TDLS_PEER_AT_OFF_STATE);
15503                         rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15504                         _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
15505                 }
15506 #endif          
15507                 rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
15508                 free_tdls_sta(padapter, ptdls_sta);
15509                 break;                  
15510         }
15511
15512         //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15513
15514         return H2C_SUCCESS;
15515 #else
15516         return H2C_REJECTED;
15517 #endif /* CONFIG_TDLS */
15518
15519 }
15520
15521 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
15522 {
15523         struct RunInThread_param *p;
15524
15525
15526         if (NULL == pbuf)
15527                 return H2C_PARAMETERS_ERROR;
15528         p = (struct RunInThread_param*)pbuf;
15529
15530         if (p->func)
15531                 p->func(p->context);
15532
15533         return H2C_SUCCESS;
15534 }
15535
15536 u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf)
15537 {
15538
15539         struct readMAC_parm *preadmacparm = NULL;
15540         u8 sz = 0;
15541         u32     addr = 0;
15542         u32     value = 0;
15543
15544         if (!pbuf)
15545                 return H2C_PARAMETERS_ERROR;
15546
15547         preadmacparm = (struct readMAC_parm *) pbuf;
15548         sz = preadmacparm->len;
15549         addr = preadmacparm->addr;
15550         value = 0;
15551
15552         switch (sz) {
15553         case 1:
15554                 value = rtw_read8(padapter, addr);
15555                 break;
15556         case 2:
15557                 value = rtw_read16(padapter, addr);
15558                 break;
15559         case 4:
15560                 value = rtw_read32(padapter, addr);
15561                 break;
15562         default:
15563                 DBG_871X("%s: Unknown size\n", __func__);
15564                 break;
15565         }
15566         DBG_871X("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value);
15567
15568         return H2C_SUCCESS;
15569 }
15570