xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8189es/core/rtw_mlme_ext.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
118 /********************************************************
119 ChannelPlan definitions
120 *********************************************************/
121 /*static RT_CHANNEL_PLAN	DefaultChannelPlan[RT_CHANNEL_DOMAIN_MAX] = {
122 	{{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},					// 0x00, RT_CHANNEL_DOMAIN_FCC
123 	{{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},						// 0x01, RT_CHANNEL_DOMAIN_IC
124 	{{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},						// 0x02, RT_CHANNEL_DOMAIN_ETSI
125 	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x03, RT_CHANNEL_DOMAIN_SPAIN
126 	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x04, RT_CHANNEL_DOMAIN_FRANCE
127 	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x05, RT_CHANNEL_DOMAIN_MKK
128 	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x06, RT_CHANNEL_DOMAIN_MKK1
129 	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},																// 0x07, RT_CHANNEL_DOMAIN_ISRAEL
130 	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},															// 0x08, RT_CHANNEL_DOMAIN_TELEC
131 	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14},																				// 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
132 	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
133 	{{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},									// 0x0B, RT_CHANNEL_DOMAIN_TAIWAN
134 	{{1,2,3,4,5,6,7,8,9,10,11,12,13,149,153,157,161,165},18},																// 0x0C, RT_CHANNEL_DOMAIN_CHINA
135 	{{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},												// 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
136 	{{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},						// 0x0E, RT_CHANNEL_DOMAIN_KOREA
137 	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19},																	// 0x0F, RT_CHANNEL_DOMAIN_TURKEY
138 	{{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},						// 0x10, RT_CHANNEL_DOMAIN_JAPAN
139 	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,149,153,157,161,165},20},															// 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
140 	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48},17},																		// 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
141 	{{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},	// 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
142 	{{1,2,3,4,5,6,7,8,9,10,11,56,60,64,149,153,157,161,165},19},																// 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
143 };*/
144 
145 static RT_CHANNEL_PLAN_2G	RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
146 	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},		// 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13
147 	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},		// 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1
148 	{{1,2,3,4,5,6,7,8,9,10,11},11},			// 0x02, RT_CHANNEL_DOMAIN_2G_FCC1
149 	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14},	// 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1
150 	{{10,11,12,13},4},						// 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2
151 	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14},	// 0x05, RT_CHANNEL_DOMAIN_2G_GLOBAL , Passive scan CH 12, 13, 14
152 	{{},0},								// 0x06, RT_CHANNEL_DOMAIN_2G_NULL
153 };
154 
155 static RT_CHANNEL_PLAN_5G	RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
156 	{{},0},																					// 0x00, RT_CHANNEL_DOMAIN_5G_NULL
157 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19},						// 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1
158 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24},	// 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2
159 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165},22},			// 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3
160 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24},	// 0x04, RT_CHANNEL_DOMAIN_5G_FCC1
161 	{{36,40,44,48,149,153,157,161,165},9},														// 0x05, RT_CHANNEL_DOMAIN_5G_FCC2
162 	{{36,40,44,48,52,56,60,64,149,153,157,161,165},13},											// 0x06, RT_CHANNEL_DOMAIN_5G_FCC3
163 	{{36,40,44,48,52,56,60,64,149,153,157,161},12},												// 0x07, RT_CHANNEL_DOMAIN_5G_FCC4
164 	{{149,153,157,161,165},5},																	// 0x08, RT_CHANNEL_DOMAIN_5G_FCC5
165 	{{36,40,44,48,52,56,60,64},8},																// 0x09, RT_CHANNEL_DOMAIN_5G_FCC6
166 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},20},					// 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1
167 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},20},					// 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1
168 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19},						// 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1
169 	{{36,40,44,48,52,56,60,64},8},																// 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2
170 	{{100,104,108,112,116,120,124,128,132,136,140},11},											// 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3
171 	{{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15},								// 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1
172 	{{56,60,64,149,153,157,161,165},8},															// 0x10, RT_CHANNEL_DOMAIN_5G_NCC2
173 	{{149,153,157,161,165},5},																	// 0x11, RT_CHANNEL_DOMAIN_5G_NCC3
174 	{{36,40,44,48},4},																			// 0x12, RT_CHANNEL_DOMAIN_5G_ETSI4
175 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21},			// 0x13, RT_CHANNEL_DOMAIN_5G_ETSI5
176 	{{149,153,157,161},4},																		// 0x14, RT_CHANNEL_DOMAIN_5G_FCC8
177 	{{36,40,44,48,52,56,60,64},8},																// 0x15, RT_CHANNEL_DOMAIN_5G_ETSI6
178 	{{36,40,44,48,52,56,60,64,149,153,157,161,165},13},											// 0x16, RT_CHANNEL_DOMAIN_5G_ETSI7
179 	{{36,40,44,48,149,153,157,161,165},9},														// 0x17, RT_CHANNEL_DOMAIN_5G_ETSI8
180 	{{100,104,108,112,116,120,124,128,132,136,140},11},											// 0x18, RT_CHANNEL_DOMAIN_5G_ETSI9
181 	{{149,153,157,161,165},5},																	// 0x19, RT_CHANNEL_DOMAIN_5G_ETSI10
182 	{{36,40,44,48,52,56,60,64,132,136,140,149,153,157,161,165},16},									// 0x1A, RT_CHANNEL_DOMAIN_5G_ETSI11
183 	{{52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},17},							// 0x1B, RT_CHANNEL_DOMAIN_5G_NCC4
184 	{{149,153,157,161},4},																		// 0x1C, RT_CHANNEL_DOMAIN_5G_ETSI12
185 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21},			// 0x1D, RT_CHANNEL_DOMAIN_5G_FCC9
186 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140},16},								// 0x1E, RT_CHANNEL_DOMAIN_5G_ETSI13
187 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161},20},				// 0x1F, RT_CHANNEL_DOMAIN_5G_FCC10
188 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161},19},					// 0x20, RT_CHANNEL_DOMAIN_5G_KCC2
189 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21},			// 0x21, RT_CHANNEL_DOMAIN_5G_FCC11
190 	{{56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},16},						// 0x22, RT_CHANNEL_DOMAIN_5G_NCC5
191 	{{36,40,44,48},4},																			// 0x23, RT_CHANNEL_DOMAIN_5G_MKK4
192 	//===== Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition =====
193 	{{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21},			// 0x30, RT_CHANNEL_DOMAIN_5G_FCC
194 	{{36,40,44,48},4},																			// 0x31, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS
195 	{{36,40,44,48,149,153,157,161},8},															// 0x32, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS
196 };
197 
198 static RT_CHANNEL_PLAN_MAP	RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
199 	//===== 0x00 ~ 0x1F , Old Define =====
200 	{0x02,0x20},	//0x00, RT_CHANNEL_DOMAIN_FCC
201 	{0x02,0x0A},	//0x01, RT_CHANNEL_DOMAIN_IC
202 	{0x01,0x01},	//0x02, RT_CHANNEL_DOMAIN_ETSI
203 	{0x01,0x00},	//0x03, RT_CHANNEL_DOMAIN_SPAIN
204 	{0x01,0x00},	//0x04, RT_CHANNEL_DOMAIN_FRANCE
205 	{0x03,0x00},	//0x05, RT_CHANNEL_DOMAIN_MKK
206 	{0x03,0x00},	//0x06, RT_CHANNEL_DOMAIN_MKK1
207 	{0x01,0x09},	//0x07, RT_CHANNEL_DOMAIN_ISRAEL
208 	{0x03,0x09},	//0x08, RT_CHANNEL_DOMAIN_TELEC
209 	{0x03,0x00},	//0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
210 	{0x00,0x00},	//0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
211 	{0x02,0x0F},	//0x0B, RT_CHANNEL_DOMAIN_TAIWAN
212 	{0x01,0x08},	//0x0C, RT_CHANNEL_DOMAIN_CHINA
213 	{0x02,0x06},	//0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
214 	{0x02,0x0B},	//0x0E, RT_CHANNEL_DOMAIN_KOREA
215 	{0x02,0x09},	//0x0F, RT_CHANNEL_DOMAIN_TURKEY
216 	{0x01,0x01},	//0x10, RT_CHANNEL_DOMAIN_JAPAN
217 	{0x02,0x05},	//0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
218 	{0x01,0x21},	//0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
219 	{0x00,0x04},	//0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
220 	{0x02,0x10},	//0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
221 	{0x00,0x21},	//0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS
222 	{0x00,0x22},	//0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS
223 	{0x03,0x21},	//0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
224 	{0x06,0x08},	//0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS
225 	{0x02,0x08},	//0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS
226 	{0x00,0x00},	//0x1A,
227 	{0x00,0x00},	//0x1B,
228 	{0x00,0x00},	//0x1C,
229 	{0x00,0x00},	//0x1D,
230 	{0x00,0x00},	//0x1E,
231 	{0x06,0x04},	//0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G
232 	//===== 0x20 ~ 0x7F ,New Define =====
233 	{0x00,0x00},	//0x20, RT_CHANNEL_DOMAIN_WORLD_NULL
234 	{0x01,0x00},	//0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL
235 	{0x02,0x00},	//0x22, RT_CHANNEL_DOMAIN_FCC1_NULL
236 	{0x03,0x00},	//0x23, RT_CHANNEL_DOMAIN_MKK1_NULL
237 	{0x04,0x00},	//0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL
238 	{0x02,0x04},	//0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1
239 	{0x00,0x01},	//0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1
240 	{0x03,0x0C},	//0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1
241 	{0x00,0x20},	//0x28, RT_CHANNEL_DOMAIN_5G_KCC2
242 	{0x00,0x05},	//0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2
243 	{0x00,0x00},	//0x2A,
244 	{0x00,0x00},	//0x2B,
245 	{0x00,0x00},	//0x2C,
246 	{0x00,0x00},	//0x2D,
247 	{0x00,0x00},	//0x2E,
248 	{0x00,0x00},	//0x2F,
249 	{0x00,0x06},	//0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3
250 	{0x00,0x07},	//0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4
251 	{0x00,0x08},	//0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5
252 	{0x00,0x09},	//0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6
253 	{0x02,0x21},	//0x34, RT_CHANNEL_DOMAIN_5G_FCC11
254 	{0x00,0x02},	//0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2
255 	{0x00,0x03},	//0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3
256 	{0x03,0x0D},	//0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2
257 	{0x03,0x0E},	//0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3
258 	{0x02,0x22},	//0x39, RT_CHANNEL_DOMAIN_5G_NCC5
259 	{0x00,0x00},	//0x3A,
260 	{0x00,0x00},	//0x3B,
261 	{0x00,0x00},	//0x3C,
262 	{0x00,0x00},	//0x3D,
263 	{0x00,0x00},	//0x3E,
264 	{0x00,0x00},	//0x3F,
265 	{0x02,0x10},	//0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2
266 	{0x05,0x00},	//0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL
267 	{0x01,0x12},	//0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4
268 	{0x02,0x05},	//0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2
269 	{0x02,0x11},	//0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3
270 	{0x00,0x13},	//0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5
271 	{0x02,0x14},	//0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8
272 	{0x00,0x15},	//0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6
273 	{0x00,0x16},	//0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7
274 	{0x00,0x17},	//0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8
275 	{0x00,0x00},	//0x4A,
276 	{0x00,0x00},	//0x4B,
277 	{0x00,0x00},	//0x4C,
278 	{0x00,0x00},	//0x4D,
279 	{0x00,0x00},	//0x4E,
280 	{0x00,0x00},	//0x4F,
281 	{0x00,0x18},	//0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9
282 	{0x00,0x19},	//0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10
283 	{0x00,0x1A},	//0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11
284 	{0x02,0x1B},	//0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4
285 	{0x00,0x1C},	//0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12
286 	{0x02,0x1D},	//0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9
287 	{0x00,0x1E},	//0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13
288 	{0x02,0x1F},	//0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10
289 	{0x01,0x23},	//0x58, RT_CHANNEL_DOMAIN_WORLD_MKK4
290 };
291 
292 static RT_CHANNEL_PLAN_MAP	RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x00,0x02}; //use the conbination for max channel numbers
293 
294 
295 #ifdef CONFIG_DFS_MASTER
rtw_rfctl_reset_cac(struct rf_ctl_t * rfctl)296 void rtw_rfctl_reset_cac(struct rf_ctl_t *rfctl)
297 {
298 	if (rtw_is_long_cac_ch(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset))
299 		rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_CE_MS);
300 	else
301 		rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_MS);
302 }
303 
304 /*
305 * check if channel coverage includes new range and the new range is in DFS range
306 * called after radar_detect_ch,bw,offset is updated
307 */
rtw_is_cac_reset_needed(_adapter * adapter)308 bool rtw_is_cac_reset_needed(_adapter *adapter)
309 {
310 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
311 	bool needed = _FALSE;
312 	u32 pre_hi, pre_lo, hi, lo;
313 
314 	if (0)
315 		DBG_871X("pre_radar_detect_ch:%d, pre_radar_detect_by_sta_link:%d\n"
316 			, rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_by_sta_link);
317 
318 	if (rfctl->pre_radar_detect_by_sta_link == _TRUE)
319 		goto exit;
320 
321 	if (rfctl->pre_radar_detect_ch == 0) {
322 		needed = _TRUE;
323 		goto exit;
324 	}
325 
326 	if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &hi, &lo) == _FALSE)
327 		rtw_warn_on(1);
328 	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)
329 		rtw_warn_on(1);
330 
331 	if (!rtw_is_range_a_in_b(hi, lo, pre_hi, pre_lo)) {
332 		if (rtw_is_range_a_in_b(pre_hi, pre_lo, hi, lo)) {
333 			/* currrent is supper set of previous */
334 			if (rtw_is_dfs_range(hi, lo))
335 				needed = _TRUE;
336 		} else if (rtw_is_range_overlap(hi, lo, pre_hi, pre_lo)) {
337 			/* currrent is not supper set of previous, but has overlap */
338 			u32 new_hi, new_lo;
339 
340 			if (lo < pre_lo) {
341 				new_hi = pre_lo;
342 				new_lo = lo;
343 				if (hi <= pre_lo || hi >= pre_hi) {
344 					DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
345 						, hi, lo, pre_hi, pre_lo);
346 					rtw_warn_on(1);
347 					goto exit;
348 				}
349 			} else if (hi > pre_hi) {
350 				new_hi = hi;
351 				new_lo = pre_hi;
352 				if (lo >= pre_hi && lo <= pre_lo) {
353 					DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
354 						, hi, lo, pre_hi, pre_lo);
355 					rtw_warn_on(1);
356 					goto exit;
357 				}
358 			} else {
359 				DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
360 					, hi, lo, pre_hi, pre_lo);
361 				rtw_warn_on(1);
362 				goto exit;
363 			}
364 
365 			if (rtw_is_dfs_range(new_hi, new_lo))
366 				needed = _TRUE;
367 
368 		} else {
369 			/* no overlap */
370 			if (rtw_is_dfs_range(hi, lo))
371 				needed = _TRUE;
372 		}
373 	}
374 
375 exit:
376 	return needed;
377 }
378 
_rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)379 bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
380 {
381 	bool ret = _FALSE;
382 	u32 hi = 0, lo = 0;
383 	u32 r_hi = 0, r_lo = 0;
384 	int i;
385 
386 	if (rfctl->radar_detect_ch == 0)
387 		goto exit;
388 
389 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
390 		rtw_warn_on(1);
391 		goto exit;
392 	}
393 
394 	if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
395 			, rfctl->radar_detect_bw, rfctl->radar_detect_offset
396 			, &r_hi, &r_lo) == _FALSE) {
397 		rtw_warn_on(1);
398 		goto exit;
399 	}
400 
401 	if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
402 		ret = _TRUE;
403 
404 exit:
405 	return ret;
406 }
407 
rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl)408 bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
409 {
410 	return _rtw_rfctl_overlap_radar_detect_ch(rfctl
411 				, rfctl_to_dvobj(rfctl)->oper_channel
412 				, rfctl_to_dvobj(rfctl)->oper_bwmode
413 				, rfctl_to_dvobj(rfctl)->oper_ch_offset);
414 }
415 
rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t * rfctl)416 bool rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t *rfctl)
417 {
418 	return (rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_UNDER_CAC(rfctl));
419 }
420 
rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)421 bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
422 {
423 	bool ret = _FALSE;
424 	u32 hi = 0, lo = 0;
425 	int i;
426 
427 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
428 		goto exit;
429 
430 	for (i = 0; ch_set[i].ChannelNum != 0; i++) {
431 		if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
432 			rtw_warn_on(1);
433 			continue;
434 		}
435 
436 		if (!CH_IS_NON_OCP(&ch_set[i]))
437 			continue;
438 
439 		if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
440 			&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
441 		) {
442 			ret = _TRUE;
443 			break;
444 		}
445 	}
446 
447 exit:
448 	return ret;
449 }
450 
451 /**
452  * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
453  * @ch_set: the given channel set
454  * @ch: channel number on which radar is detected
455  * @bw: bandwidth on which radar is detected
456  * @offset: bandwidth offset on which radar is detected
457  * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
458  */
_rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)459 static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
460 {
461 	u32 hi = 0, lo = 0;
462 	int i;
463 
464 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
465 		goto exit;
466 
467 	for (i = 0; ch_set[i].ChannelNum != 0; i++) {
468 		if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
469 			rtw_warn_on(1);
470 			continue;
471 		}
472 
473 		if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
474 			&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
475 		) {
476 			if (ms >= 0)
477 				ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
478 			else
479 				ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
480 		}
481 	}
482 
483 exit:
484 	return;
485 }
486 
rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)487 inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
488 {
489 	_rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
490 }
491 
rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)492 inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
493 {
494 	_rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
495 }
496 #endif /* CONFIG_DFS_MASTER */
497 
rtw_choose_available_chbw(_adapter * adapter,u8 req_bw,u8 * dec_ch,u8 * dec_bw,u8 * dec_offset,u8 d_flags)498 bool rtw_choose_available_chbw(_adapter *adapter, u8 req_bw, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset, u8 d_flags)
499 {
500 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
501 	int i;
502 
503 	if (!dec_ch || !dec_bw || !dec_offset) {
504 		rtw_warn_on(1);
505 		return _FAIL;
506 	}
507 
508 	for (i = 0; i < mlmeext->max_chan_nums; i++) {
509 
510 		*dec_ch = mlmeext->channel_set[i].ChannelNum;
511 		*dec_bw = req_bw;
512 		if (*dec_bw == CHANNEL_WIDTH_20)
513 			*dec_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
514 		else
515 			*dec_offset = rtw_get_offset_by_ch(*dec_ch);
516 
517 		if ((d_flags & RTW_CHF_2G) && *dec_ch <= 14)
518 			continue;
519 
520 		if ((d_flags & RTW_CHF_5G)  && *dec_ch > 14)
521 			continue;
522 
523 		rtw_regsty_adjust_chbw(&adapter->registrypriv, *dec_ch, dec_bw, dec_offset);
524 
525 		if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
526 			continue;
527 
528 		if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
529 			continue;
530 
531 		if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
532 			continue;
533 
534 		if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
535 			continue;
536 
537 		if (!rtw_chset_is_ch_non_ocp(mlmeext->channel_set, *dec_ch, *dec_bw, *dec_offset))
538 			break;
539 	}
540 
541 	return (i < mlmeext->max_chan_nums)?_TRUE:_FALSE;
542 }
543 
dump_chset(void * sel,RT_CHANNEL_INFO * ch_set)544 void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set)
545 {
546 	u8	i;
547 
548 	for (i = 0; ch_set[i].ChannelNum != 0; i++) {
549 		DBG_871X_SEL_NL(sel, "ch:%3u, freq:%u, scan_type:%d"
550 			, ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType);
551 
552 		#ifdef CONFIG_FIND_BEST_CHANNEL
553 		DBG_871X_SEL(sel, ", rx_count:%u", ch_set[i].rx_count);
554 		#endif
555 
556 		#ifdef CONFIG_DFS_MASTER
557 		if (rtw_is_dfs_ch(ch_set[i].ChannelNum, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
558 			if (CH_IS_NON_OCP(&ch_set[i]))
559 				DBG_871X_SEL(sel, ", non_ocp:%d"
560 					, rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()));
561 			else
562 				DBG_871X_SEL(sel, ", non_ocp:N/A");
563 		}
564 		#endif
565 
566 		DBG_871X_SEL(sel, "\n");
567 	}
568 
569 	DBG_871X_SEL_NL(sel, "total ch number:%d\n", i);
570 }
571 
dump_ch_plan_test(void * sel)572 void dump_ch_plan_test(void *sel)
573 {
574 	int i, j;
575 
576 	for (i = 0; i < RT_CHANNEL_DOMAIN_2G_MAX; i++) {
577 		for (j = 0; j < RTW_ChannelPlan2G[i].Len; j++) {
578 			if (rtw_ch2freq(RTW_ChannelPlan2G[i].Channel[j]) == 0)
579 				DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan2G[i].Channel[j], i, j);
580 		}
581 	}
582 
583 	for (i = 0; i < RT_CHANNEL_DOMAIN_5G_MAX; i++) {
584 		for (j = 0; j < RTW_ChannelPlan5G[i].Len; j++) {
585 			if (rtw_ch2freq(RTW_ChannelPlan5G[i].Channel[j]) == 0)
586 				DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan5G[i].Channel[j], i, j);
587 		}
588 	}
589 }
590 
591 /*
592  * Search the @param ch in given @param ch_set
593  * @ch_set: the given channel set
594  * @ch: the given channel number
595  *
596  * return the index of channel_num in channel_set, -1 if not found
597  */
rtw_ch_set_search_ch(RT_CHANNEL_INFO * ch_set,const u32 ch)598 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
599 {
600 	int i;
601 	for(i=0;ch_set[i].ChannelNum!=0;i++){
602 		if(ch == ch_set[i].ChannelNum)
603 			break;
604 	}
605 
606 	if(i >= ch_set[i].ChannelNum)
607 		return -1;
608 	return i;
609 }
610 
611 /*
612  * Check the @param ch is fit with setband setting of @param adapter
613  * @adapter: the given adapter
614  * @ch: the given channel number
615  *
616  * return _TRUE when check valid, _FALSE not valid
617  */
rtw_mlme_band_check(_adapter * adapter,const u32 ch)618 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
619 {
620 	if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
621 		|| (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
622 		|| (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
623 	) {
624 		return _TRUE;
625 	}
626 	return _FALSE;
627 }
628 
629 /****************************************************************************
630 
631 Following are the initialization functions for WiFi MLME
632 
633 *****************************************************************************/
634 
init_hw_mlme_ext(_adapter * padapter)635 int init_hw_mlme_ext(_adapter *padapter)
636 {
637 	struct	mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
638 
639 	//set_opmode_cmd(padapter, infra_client_with_mlme);//removed
640 
641 	set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
642 
643 	return _SUCCESS;
644 }
645 
init_mlme_default_rate_set(_adapter * padapter)646 void init_mlme_default_rate_set(_adapter* padapter)
647 {
648 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
649 
650 	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};
651 	unsigned char	mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
652 	unsigned char	supported_mcs_set[16] = {0xff, 0xff, 0xff, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
653 
654 	_rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
655 	_rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
656 
657 	_rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
658 }
659 
init_mlme_ext_priv_value(_adapter * padapter)660 static void init_mlme_ext_priv_value(_adapter* padapter)
661 {
662 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
663 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
664 
665 	ATOMIC_SET(&pmlmeext->event_seq, 0);
666 	pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
667 #ifdef CONFIG_IEEE80211W
668 	pmlmeext->sa_query_seq = 0;
669 	pmlmeext->mgnt_80211w_IPN=0;
670 	pmlmeext->mgnt_80211w_IPN_rx=0;
671 #endif //CONFIG_IEEE80211W
672 	pmlmeext->cur_channel = padapter->registrypriv.channel;
673 	pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
674 	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
675 
676 	pmlmeext->retry = 0;
677 
678 	pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
679 
680 	init_mlme_default_rate_set(padapter);
681 
682 	if(pmlmeext->cur_channel > 14)
683 		pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
684 	else
685 		pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
686 
687 	mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
688 	pmlmeext->sitesurvey_res.channel_idx = 0;
689 	pmlmeext->sitesurvey_res.bss_cnt = 0;
690 	pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
691 	pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
692 	pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
693 	#ifdef CONFIG_SCAN_BACKOP
694 	mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
695 	mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN|SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
696 	pmlmeext->sitesurvey_res.scan_cnt = 0;
697 	pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
698 	pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
699 	#endif
700 	#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
701 	pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
702 	#endif
703 	pmlmeext->scan_abort = _FALSE;
704 
705 	pmlmeinfo->state = WIFI_FW_NULL_STATE;
706 	pmlmeinfo->reauth_count = 0;
707 	pmlmeinfo->reassoc_count = 0;
708 	pmlmeinfo->link_count = 0;
709 	pmlmeinfo->auth_seq = 0;
710 	pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
711 	pmlmeinfo->key_index = 0;
712 	pmlmeinfo->iv = 0;
713 
714 	pmlmeinfo->enc_algo = _NO_PRIVACY_;
715 	pmlmeinfo->authModeToggle = 0;
716 
717 	_rtw_memset(pmlmeinfo->chg_txt, 0, 128);
718 
719 	pmlmeinfo->slotTime = SHORT_SLOT_TIME;
720 	pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
721 
722 	pmlmeinfo->dialogToken = 0;
723 
724 	pmlmeext->action_public_rxseq = 0xffff;
725 	pmlmeext->action_public_dialog_token = 0xff;
726 }
727 
has_channel(RT_CHANNEL_INFO * channel_set,u8 chanset_size,u8 chan)728 static int has_channel(RT_CHANNEL_INFO *channel_set,
729 					   u8 chanset_size,
730 					   u8 chan) {
731 	int i;
732 
733 	for (i = 0; i < chanset_size; i++) {
734 		if (channel_set[i].ChannelNum == chan) {
735 			return 1;
736 		}
737 	}
738 
739 	return 0;
740 }
741 
init_channel_list(_adapter * padapter,RT_CHANNEL_INFO * channel_set,u8 chanset_size,struct p2p_channels * channel_list)742 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
743 							  u8 chanset_size,
744 							  struct p2p_channels *channel_list) {
745 
746 	struct p2p_oper_class_map op_class[] = {
747 		{ IEEE80211G,  81,   1,  13,  1, BW20 },
748 		{ IEEE80211G,  82,  14,  14,  1, BW20 },
749 #if 0 /* Do not enable HT40 on 2 GHz */
750 		{ IEEE80211G,  83,   1,   9,  1, BW40PLUS },
751 		{ IEEE80211G,  84,   5,  13,  1, BW40MINUS },
752 #endif
753 		{ IEEE80211A, 115,  36,  48,  4, BW20 },
754 		{ IEEE80211A, 116,  36,  44,  8, BW40PLUS },
755 		{ IEEE80211A, 117,  40,  48,  8, BW40MINUS },
756 		{ IEEE80211A, 124, 149, 161,  4, BW20 },
757 		{ IEEE80211A, 125, 149, 169,  4, BW20 },
758 		{ IEEE80211A, 126, 149, 157,  8, BW40PLUS },
759 		{ IEEE80211A, 127, 153, 161,  8, BW40MINUS },
760 		{ -1, 0, 0, 0, 0, BW20 }
761 	};
762 
763 	int cla, op;
764 
765 	cla = 0;
766 
767 	for (op = 0; op_class[op].op_class; op++) {
768 		u8 ch;
769 		struct p2p_oper_class_map *o = &op_class[op];
770 		struct p2p_reg_class *reg = NULL;
771 
772 		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
773 			if (!has_channel(channel_set, chanset_size, ch)) {
774 				continue;
775 			}
776 
777 			if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
778 				continue;
779 
780 			if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) &&
781 				((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
782 				continue;
783 
784 			if (reg == NULL) {
785 				reg = &channel_list->reg_class[cla];
786 				cla++;
787 				reg->reg_class = o->op_class;
788 				reg->channels = 0;
789 			}
790 			reg->channel[reg->channels] = ch;
791 			reg->channels++;
792 		}
793 	}
794 	channel_list->reg_classes = cla;
795 
796 }
797 
init_channel_set(_adapter * padapter,u8 ChannelPlan,RT_CHANNEL_INFO * channel_set)798 static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
799 {
800 	u8	index,chanset_size = 0;
801 	u8	b5GBand = _FALSE, b2_4GBand = _FALSE;
802 	u8	Index2G = 0, Index5G=0;
803 
804 	if (!rtw_is_channel_plan_valid(ChannelPlan)) {
805 		DBG_871X("ChannelPlan ID %x error !!!!!\n",ChannelPlan);
806 		return chanset_size;
807 	}
808 
809 	_rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
810 
811 	if(IsSupported24G(padapter->registrypriv.wireless_mode))
812 	{
813 		b2_4GBand = _TRUE;
814 		if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
815 			Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
816 		else
817 			Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
818 	}
819 
820 	if(IsSupported5G(padapter->registrypriv.wireless_mode))
821 	{
822 		b5GBand = _TRUE;
823 		if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
824 			Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
825 		else
826 			Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
827 	}
828 
829 	if(b2_4GBand)
830 	{
831 		for(index=0;index<RTW_ChannelPlan2G[Index2G].Len;index++)
832 		{
833 			channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
834 
835 			if(	(RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||//Channel 1~11 is active, and 12~14 is passive
836 				(RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan)	)
837 			{
838 				if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
839 					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
840 				else if((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
841 					channel_set[chanset_size].ScanType  = SCAN_PASSIVE;
842 			}
843 			else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
844 				RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
845 				RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)// channel 12~13, passive scan
846 			{
847 				if(channel_set[chanset_size].ChannelNum <= 11)
848 					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
849 				else
850 					channel_set[chanset_size].ScanType = SCAN_PASSIVE;
851 			}
852 			else
853 			{
854 				channel_set[chanset_size].ScanType = SCAN_ACTIVE;
855 			}
856 
857 			chanset_size++;
858 		}
859 	}
860 
861 	if(b5GBand)
862 	{
863 		for(index=0;index<RTW_ChannelPlan5G[Index5G].Len;index++)
864 		{
865 #ifdef CONFIG_DFS
866 			channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
867 			if ( channel_set[chanset_size].ChannelNum <= 48
868 				|| channel_set[chanset_size].ChannelNum >= 149 )
869 			{
870 				if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
871 					channel_set[chanset_size].ScanType = SCAN_PASSIVE;
872 				else
873 					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
874 			}
875 			else
876 			{
877 				channel_set[chanset_size].ScanType = SCAN_PASSIVE;
878 			}
879 			chanset_size++;
880 #else /* CONFIG_DFS */
881 			if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
882 				|| RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) {
883 				channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
884 				if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
885 					channel_set[chanset_size].ScanType = SCAN_PASSIVE;
886 				else
887 					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
888 				DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
889 				chanset_size++;
890 			}
891 #endif /* CONFIG_DFS */
892 		}
893 	}
894 
895 	Hal_ChannelPlanToRegulation(padapter, ChannelPlan);
896 
897 	DBG_871X("%s ChannelPlan ID %x Chan num:%d  \n",__FUNCTION__,ChannelPlan,chanset_size);
898 	return chanset_size;
899 }
900 
init_mlme_ext_priv(_adapter * padapter)901 int	init_mlme_ext_priv(_adapter* padapter)
902 {
903 	int	res = _SUCCESS;
904 	struct registry_priv* pregistrypriv = &padapter->registrypriv;
905 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
906 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
907 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
908 
909 	// We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
910 	//_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
911 
912 	pmlmeext->padapter = padapter;
913 
914 	//fill_fwpriv(padapter, &(pmlmeext->fwpriv));
915 
916 	init_mlme_ext_priv_value(padapter);
917 	pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
918 
919 	init_mlme_ext_timer(padapter);
920 
921 #ifdef CONFIG_AP_MODE
922 	init_mlme_ap_info(padapter);
923 #endif
924 
925 	pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
926 	init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
927 	pmlmeext->last_scan_time = 0;
928 	pmlmeext->mlmeext_init = _TRUE;
929 
930 
931 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
932 	pmlmeext->active_keep_alive_check = _TRUE;
933 #else
934 	pmlmeext->active_keep_alive_check = _FALSE;
935 #endif
936 
937 #ifdef DBG_FIXED_CHAN
938 	pmlmeext->fixed_chan = 0xFF;
939 #endif
940 
941 	return res;
942 
943 }
944 
free_mlme_ext_priv(struct mlme_ext_priv * pmlmeext)945 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
946 {
947 	_adapter *padapter = pmlmeext->padapter;
948 
949 	if (!padapter)
950 		return;
951 
952 	if (rtw_is_drv_stopped(padapter)) {
953 		_cancel_timer_ex(&pmlmeext->survey_timer);
954 		_cancel_timer_ex(&pmlmeext->link_timer);
955 		//_cancel_timer_ex(&pmlmeext->ADDBA_timer);
956 	}
957 }
958 
cmp_pkt_chnl_diff(_adapter * padapter,u8 * pframe,uint packet_len)959 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
960 {	// if the channel is same, return 0. else return channel differential
961 	uint len;
962 	u8 channel;
963 	u8 *p;
964 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
965 	if (p)
966 	{
967 		channel = *(p + 2);
968 		if(padapter->mlmeextpriv.cur_channel >= channel)
969 		{
970 			return (padapter->mlmeextpriv.cur_channel - channel);
971 		}
972 		else
973 		{
974 			return (channel-padapter->mlmeextpriv.cur_channel);
975 		}
976 	}
977 	else
978 	{
979 		return 0;
980 	}
981 }
982 
_mgt_dispatcher(_adapter * padapter,struct mlme_handler * ptable,union recv_frame * precv_frame)983 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
984 {
985 	u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
986 	u8 *pframe = precv_frame->u.hdr.rx_data;
987 
988 	  if(ptable->func)
989         {
990        	 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
991 		if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
992 			!_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
993 		{
994 			return;
995 		}
996 
997 		ptable->func(padapter, precv_frame);
998         }
999 
1000 }
1001 
mgt_dispatcher(_adapter * padapter,union recv_frame * precv_frame)1002 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1003 {
1004 	int index;
1005 	struct mlme_handler *ptable;
1006 #ifdef CONFIG_AP_MODE
1007 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1008 #endif //CONFIG_AP_MODE
1009 	u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1010 	u8 *pframe = precv_frame->u.hdr.rx_data;
1011 	struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
1012 	struct dvobj_priv *psdpriv = padapter->dvobj;
1013 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1014 
1015 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1016 		 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
1017 		  GetFrameType(pframe), GetFrameSubType(pframe)));
1018 
1019 #if 0
1020 	{
1021 		u8 *pbuf;
1022 		pbuf = GetAddr1Ptr(pframe);
1023 		DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1024 		pbuf = GetAddr2Ptr(pframe);
1025 		DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1026 		pbuf = GetAddr3Ptr(pframe);
1027 		DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1028 	}
1029 #endif
1030 
1031 	if (GetFrameType(pframe) != WIFI_MGT_TYPE)
1032 	{
1033 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
1034 		return;
1035 	}
1036 
1037 	//receive the frames that ra(a1) is my address or ra(a1) is bc address.
1038 	if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1039 		!_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1040 	{
1041 		return;
1042 	}
1043 
1044 	ptable = mlme_sta_tbl;
1045 
1046 	index = GetFrameSubType(pframe) >> 4;
1047 
1048 #ifdef CONFIG_TDLS
1049 	if((index << 4)==WIFI_ACTION){
1050 		/* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1051 		if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) {
1052 			DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe)));
1053 			On_TDLS_Dis_Rsp(padapter, precv_frame);
1054 		}
1055 	}
1056 #endif //CONFIG_TDLS
1057 
1058 	if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler)))
1059 	{
1060 		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
1061 		return;
1062 	}
1063 	ptable += index;
1064 
1065 #if 1
1066 	if (psta != NULL)
1067 	{
1068 		if (GetRetry(pframe))
1069 		{
1070 			if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
1071 			{
1072 				/* drop the duplicate management frame */
1073 				pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
1074 				DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1075 				return;
1076 			}
1077 		}
1078 		psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1079 	}
1080 #else
1081 
1082 	if(GetRetry(pframe))
1083 	{
1084 		//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
1085 		//return;
1086 	}
1087 #endif
1088 
1089 #ifdef CONFIG_AP_MODE
1090 	switch (GetFrameSubType(pframe))
1091 	{
1092 		case WIFI_AUTH:
1093 			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1094 				ptable->func = &OnAuth;
1095 			else
1096 				ptable->func = &OnAuthClient;
1097 			//pass through
1098 		case WIFI_ASSOCREQ:
1099 		case WIFI_REASSOCREQ:
1100 			_mgt_dispatcher(padapter, ptable, precv_frame);
1101 #ifdef CONFIG_HOSTAPD_MLME
1102 			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1103 				rtw_hostapd_mlme_rx(padapter, precv_frame);
1104 #endif
1105 			break;
1106 		case WIFI_PROBEREQ:
1107 			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1108 			{
1109 #ifdef CONFIG_HOSTAPD_MLME
1110 				rtw_hostapd_mlme_rx(padapter, precv_frame);
1111 #else
1112 				_mgt_dispatcher(padapter, ptable, precv_frame);
1113 #endif
1114 			}
1115 			else
1116 				_mgt_dispatcher(padapter, ptable, precv_frame);
1117 			break;
1118 		case WIFI_BEACON:
1119 			_mgt_dispatcher(padapter, ptable, precv_frame);
1120 			break;
1121 		case WIFI_ACTION:
1122 			//if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1123 			_mgt_dispatcher(padapter, ptable, precv_frame);
1124 			break;
1125 		default:
1126 			_mgt_dispatcher(padapter, ptable, precv_frame);
1127 			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1128 				rtw_hostapd_mlme_rx(padapter, precv_frame);
1129 			break;
1130 	}
1131 #else
1132 
1133 	_mgt_dispatcher(padapter, ptable, precv_frame);
1134 
1135 #endif
1136 
1137 }
1138 
1139 #ifdef CONFIG_P2P
p2p_listen_state_process(_adapter * padapter,unsigned char * da)1140 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1141 {
1142 	bool response = _TRUE;
1143 
1144 #ifdef CONFIG_IOCTL_CFG80211
1145 	if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
1146 	{
1147 		if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE
1148 			|| rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1149 			|| adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1150 			|| padapter->mlmepriv.wps_probe_resp_ie == NULL
1151 			|| padapter->mlmepriv.p2p_probe_resp_ie == NULL
1152 		)
1153 		{
1154 #ifdef CONFIG_DEBUG_CFG80211
1155 			DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ",
1156 				adapter_wdev_data(padapter)->p2p_enabled,
1157 				padapter->mlmepriv.wps_probe_resp_ie,
1158 				padapter->mlmepriv.p2p_probe_resp_ie);
1159 			DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n",
1160 				padapter->cfg80211_wdinfo.is_ro_ch,
1161 				rtw_get_oper_ch(padapter),
1162 				padapter->wdinfo.listen_channel);
1163 #endif
1164 			response = _FALSE;
1165 		}
1166 	}
1167 	else
1168 #endif //CONFIG_IOCTL_CFG80211
1169 	if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1170 	{
1171 		//	do nothing if the device name is empty
1172 		if ( !padapter->wdinfo.device_name_len )
1173 		{
1174 			response	= _FALSE;
1175 		}
1176 	}
1177 
1178 	if (response == _TRUE)
1179 		issue_probersp_p2p( padapter, da);
1180 
1181 	return _SUCCESS;
1182 }
1183 #endif //CONFIG_P2P
1184 
1185 
1186 /****************************************************************************
1187 
1188 Following are the callback functions for each subtype of the management frames
1189 
1190 *****************************************************************************/
1191 
OnProbeReq(_adapter * padapter,union recv_frame * precv_frame)1192 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1193 {
1194 	unsigned int	ielen;
1195 	unsigned char	*p;
1196 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1197 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1198 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1199 	WLAN_BSSID_EX 	*cur = &(pmlmeinfo->network);
1200 	u8 *pframe = precv_frame->u.hdr.rx_data;
1201 	uint len = precv_frame->u.hdr.len;
1202 	u8 is_valid_p2p_probereq = _FALSE;
1203 
1204 #ifdef CONFIG_ATMEL_RC_PATCH
1205 	u8 *target_ie=NULL, *wps_ie=NULL;
1206 	u8 *start;
1207 	uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1208 	struct sta_info	*psta;
1209 	struct sta_priv *pstapriv = &padapter->stapriv;
1210 #endif
1211 
1212 
1213 #ifdef CONFIG_P2P
1214 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
1215 	struct rx_pkt_attrib	*pattrib = &precv_frame->u.hdr.attrib;
1216 	u8 wifi_test_chk_rate = 1;
1217 
1218 #ifdef CONFIG_IOCTL_CFG80211
1219 	if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1220 		&& !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1221 		&& (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1222 		 ) {
1223 		rtw_cfg80211_rx_probe_request(padapter, pframe, len);
1224 		return _SUCCESS;
1225 	}
1226 #endif /* CONFIG_IOCTL_CFG80211 */
1227 
1228 	if (	!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1229 		!rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
1230 		!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1231 		!rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1232 		!rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1233 	   )
1234 	{
1235 		//	Commented by Albert 2011/03/17
1236 		//	mcs_rate = 0 -> CCK 1M rate
1237 		//	mcs_rate = 1 -> CCK 2M rate
1238 		//	mcs_rate = 2 -> CCK 5.5M rate
1239 		//	mcs_rate = 3 -> CCK 11M rate
1240 		//	In the P2P mode, the driver should not support the CCK rate
1241 
1242 		//	Commented by Kurt 2012/10/16
1243 		//	IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
1244         if (padapter->registrypriv.wifi_spec == 1)
1245         {
1246             if ( pattrib->data_rate <= 3 )
1247             {
1248                 wifi_test_chk_rate = 0;
1249             }
1250         }
1251 
1252 		if( wifi_test_chk_rate == 1 )
1253 		{
1254 			if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
1255 			{
1256 				if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
1257 				{
1258 					// FIXME
1259 					if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1260 						report_survey_event(padapter, precv_frame);
1261 
1262 					p2p_listen_state_process( padapter,  get_sa(pframe));
1263 
1264 					return _SUCCESS;
1265 				}
1266 
1267 				if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1268 				{
1269 					goto _continue;
1270 				}
1271 			}
1272 		}
1273 	}
1274 
1275 _continue:
1276 #endif //CONFIG_P2P
1277 
1278 	if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1279 	{
1280 		return _SUCCESS;
1281 	}
1282 
1283 	if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
1284 		check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
1285 	{
1286 		return _SUCCESS;
1287 	}
1288 
1289 
1290 	//DBG_871X("+OnProbeReq\n");
1291 
1292 
1293 #ifdef CONFIG_ATMEL_RC_PATCH
1294 		if ((wps_ie = rtw_get_wps_ie(
1295 			pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1296 			len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1297 			 NULL, &wps_ielen))) {
1298 
1299 			target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1300 		}
1301 		if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) {
1302 			//psta->flag_atmel_rc = 1;
1303 			unsigned char *sa_addr = get_sa(pframe);
1304 			printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x  \n\n",
1305 				__func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5));
1306 			_rtw_memcpy(  pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1307 		}
1308 #endif
1309 
1310 
1311 #ifdef CONFIG_AUTO_AP_MODE
1312 	if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1313 			pmlmepriv->cur_network.join_res == _TRUE)
1314 	{
1315 		_irqL	irqL;
1316 		struct sta_info	*psta;
1317 		u8 *mac_addr, *peer_addr;
1318 		struct sta_priv *pstapriv = &padapter->stapriv;
1319 		u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
1320 		//EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
1321 
1322 		p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1323 			len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1324 
1325 		if(!p || ielen !=14)
1326 			goto _non_rc_device;
1327 
1328 		if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
1329 			goto _non_rc_device;
1330 
1331 		if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
1332 		{
1333 			DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1334 				MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
1335 
1336 			goto _non_rc_device;
1337 		}
1338 
1339 		DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__,  MAC_ARG(get_sa(pframe)));
1340 
1341 		//new a station
1342 		psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1343 		if (psta == NULL)
1344 		{
1345 			// allocate a new one
1346 			DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n",  MAC_ARG(get_sa(pframe)));
1347 			psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1348 			if (psta == NULL)
1349 			{
1350 				//TODO:
1351 				DBG_871X(" Exceed the upper limit of supported clients...\n");
1352 				return _SUCCESS;
1353 			}
1354 
1355 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1356 			if (rtw_is_list_empty(&psta->asoc_list))
1357 			{
1358 				psta->expire_to = pstapriv->expire_to;
1359 				rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1360 				pstapriv->asoc_list_cnt++;
1361 			}
1362 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1363 
1364 			//generate pairing ID
1365 			mac_addr = adapter_mac_addr(padapter);
1366 			peer_addr = psta->hwaddr;
1367 			psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
1368 
1369 			//update peer stainfo
1370 			psta->isrc = _TRUE;
1371 			//psta->aid = 0;
1372 			//psta->mac_id = 2;
1373 
1374 			/* get a unique AID */
1375 			if (psta->aid > 0) {
1376 				DBG_871X("old AID %d\n", psta->aid);
1377 			} else {
1378 				for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1379 					if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1380 						break;
1381 
1382 				if (psta->aid > pstapriv->max_num_sta) {
1383 					psta->aid = 0;
1384 					DBG_871X("no room for more AIDs\n");
1385 					return _SUCCESS;
1386 				} else {
1387 					pstapriv->sta_aid[psta->aid - 1] = psta;
1388 					DBG_871X("allocate new AID = (%d)\n", psta->aid);
1389 				}
1390 			}
1391 
1392 			psta->qos_option = 1;
1393 			psta->bw_mode = CHANNEL_WIDTH_20;
1394 			psta->ieee8021x_blocked = _FALSE;
1395 #ifdef CONFIG_80211N_HT
1396 			psta->htpriv.ht_option = _TRUE;
1397 			psta->htpriv.ampdu_enable = _FALSE;
1398 			psta->htpriv.sgi_20m = _FALSE;
1399 			psta->htpriv.sgi_40m = _FALSE;
1400 			psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1401 			psta->htpriv.agg_enable_bitmap = 0x0;//reset
1402 			psta->htpriv.candidate_tid_bitmap = 0x0;//reset
1403 #endif
1404 
1405 			rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1406 
1407 			_rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1408 
1409 			_enter_critical_bh(&psta->lock, &irqL);
1410 			psta->state |= _FW_LINKED;
1411 			_exit_critical_bh(&psta->lock, &irqL);
1412 
1413 			report_add_sta_event(padapter, psta->hwaddr, psta->aid);
1414 
1415 		}
1416 
1417 		issue_probersp(padapter, get_sa(pframe), _FALSE);
1418 
1419 		return _SUCCESS;
1420 
1421 	}
1422 
1423 _non_rc_device:
1424 
1425 	return _SUCCESS;
1426 
1427 #endif //CONFIG_AUTO_AP_MODE
1428 
1429 
1430 #ifdef CONFIG_CONCURRENT_MODE
1431 	if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1432 		check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1433 	{
1434 		//don't process probe req
1435 		return _SUCCESS;
1436 	}
1437 #endif
1438 
1439 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1440 			len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1441 
1442 
1443 	//check (wildcard) SSID
1444 	if (p != NULL)
1445 	{
1446 		if(is_valid_p2p_probereq == _TRUE)
1447 		{
1448 			goto _issue_probersp;
1449 		}
1450 
1451 		if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1452 			|| (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1453 		)
1454 		{
1455 			return _SUCCESS;
1456 		}
1457 
1458 _issue_probersp:
1459 		if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1460 			pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1461 		{
1462 			//DBG_871X("+issue_probersp during ap mode\n");
1463 			issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
1464 		}
1465 
1466 	}
1467 
1468 	return _SUCCESS;
1469 
1470 }
1471 
OnProbeRsp(_adapter * padapter,union recv_frame * precv_frame)1472 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1473 {
1474 	struct sta_info		*psta;
1475 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1476 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1477 	struct sta_priv		*pstapriv = &padapter->stapriv;
1478 	u8	*pframe = precv_frame->u.hdr.rx_data;
1479 #ifdef CONFIG_P2P
1480 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
1481 #endif
1482 
1483 
1484 #ifdef CONFIG_P2P
1485 	if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
1486 	{
1487 		if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
1488 		{
1489 			if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1490 			{
1491 				if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
1492 				{
1493 					pwdinfo->tx_prov_disc_info.benable = _FALSE;
1494 					issue_p2p_provision_request( padapter,
1495 												pwdinfo->tx_prov_disc_info.ssid.Ssid,
1496 												pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1497 												pwdinfo->tx_prov_disc_info.peerDevAddr );
1498 				}
1499 				else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
1500 				{
1501 					pwdinfo->tx_prov_disc_info.benable = _FALSE;
1502 					issue_p2p_provision_request( padapter,
1503 												NULL,
1504 												0,
1505 												pwdinfo->tx_prov_disc_info.peerDevAddr );
1506 				}
1507 			}
1508 		}
1509 		return _SUCCESS;
1510 	}
1511 	else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
1512 	{
1513 		if ( _TRUE == pwdinfo->nego_req_info.benable )
1514 		{
1515 			DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
1516 			if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1517 			{
1518 				pwdinfo->nego_req_info.benable = _FALSE;
1519 				issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
1520 			}
1521 		}
1522 	}
1523 	else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
1524 	{
1525 		if ( _TRUE == pwdinfo->invitereq_info.benable )
1526 		{
1527 			DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
1528 			if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1529 			{
1530 				pwdinfo->invitereq_info.benable = _FALSE;
1531 				issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
1532 			}
1533 		}
1534 	}
1535 #endif
1536 
1537 
1538 	if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1539 		report_survey_event(padapter, precv_frame);
1540 #ifdef CONFIG_CONCURRENT_MODE
1541 		report_survey_event(padapter->pbuddy_adapter, precv_frame);
1542 #endif
1543 		return _SUCCESS;
1544 	}
1545 
1546 	#if 0 //move to validate_recv_mgnt_frame
1547 	if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1548 	{
1549 		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1550 		{
1551 			if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1552 			{
1553 				psta->sta_stats.rx_mgnt_pkts++;
1554 			}
1555 		}
1556 	}
1557 	#endif
1558 
1559 	return _SUCCESS;
1560 
1561 }
1562 
OnBeacon(_adapter * padapter,union recv_frame * precv_frame)1563 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1564 {
1565 	int cam_idx;
1566 	struct sta_info	*psta;
1567 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1568 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1569 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1570 	struct sta_priv	*pstapriv = &padapter->stapriv;
1571 	u8 *pframe = precv_frame->u.hdr.rx_data;
1572 	uint len = precv_frame->u.hdr.len;
1573 	WLAN_BSSID_EX *pbss;
1574 	int ret = _SUCCESS;
1575 	u8 *p = NULL;
1576 	u32 ielen = 0;
1577 #ifdef CONFIG_TDLS
1578 	struct sta_info *ptdls_sta;
1579 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1580 #endif /* CONFIG_TDLS */
1581 
1582 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1583 	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_);
1584 	if ((p != NULL) && (ielen > 0))
1585 	{
1586 		if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
1587 		{
1588 			/* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
1589 		       	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)));
1590 		       	*(p + 1) = ielen - 1;
1591 		}
1592 	}
1593 #endif
1594 
1595 	if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1596 		report_survey_event(padapter, precv_frame);
1597 #ifdef CONFIG_CONCURRENT_MODE
1598 		report_survey_event(padapter->pbuddy_adapter, precv_frame);
1599 #endif
1600 		return _SUCCESS;
1601 	}
1602 
1603 	if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1604 	{
1605 		if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1606 		{
1607 			//we should update current network before auth, or some IE is wrong
1608 			pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1609 			if (pbss) {
1610 				if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1611 					struct beacon_keys recv_beacon;
1612 
1613 					update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1614 					rtw_get_bcn_info(&(pmlmepriv->cur_network));
1615 
1616 					// update bcn keys
1617 					if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1618 						DBG_871X("%s: beacon keys ready\n", __func__);
1619 						_rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1620 							&recv_beacon, sizeof(recv_beacon));
1621 						pmlmepriv->new_beacon_cnts = 0;
1622 					}
1623 					else {
1624 						DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__);
1625 						_rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1626 						pmlmepriv->new_beacon_cnts = 0;
1627 					}
1628 				}
1629 				rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1630 			}
1631 
1632 			//check the vendor of the assoc AP
1633 			pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
1634 
1635 			//update TSF Value
1636 			update_TSF(pmlmeext, pframe, len);
1637 
1638 			//reset for adaptive_early_32k
1639 			pmlmeext->adaptive_tsf_done = _FALSE;
1640 			pmlmeext->DrvBcnEarly = 0xff;
1641 			pmlmeext->DrvBcnTimeOut = 0xff;
1642 			pmlmeext->bcn_cnt = 0;
1643 			_rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1644 			_rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1645 
1646 #ifdef CONFIG_P2P_PS
1647 			process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1648 #endif //CONFIG_P2P_PS
1649 
1650 #if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE)
1651 			if (padapter->registrypriv.wifi_spec) {
1652 				if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1653 					if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
1654 						DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n ");
1655 						return _SUCCESS;
1656 					}
1657 				}
1658 			}
1659 #endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE
1660 
1661 			//start auth
1662 			start_clnt_auth(padapter);
1663 
1664 			return _SUCCESS;
1665 		}
1666 
1667 		if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1668 		{
1669 			if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1670 			{
1671 				#ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1672 				//Merge from 8712 FW code
1673 				if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
1674 				{            // join wrong channel, deauth and reconnect
1675 					issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1676 
1677 					report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE);
1678 					pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1679 					return _SUCCESS;
1680 				}
1681 				#endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
1682 
1683 				ret = rtw_check_bcn_info(padapter, pframe, len);
1684 				if (!ret) {
1685 						DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1686 						receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0);
1687 						return _SUCCESS;
1688 				}
1689 				//update WMM, ERP in the beacon
1690 				//todo: the timer is used instead of the number of the beacon received
1691 				if ((sta_rx_pkts(psta) & 0xf) == 0)
1692 				{
1693 					//DBG_871X("update_bcn_info\n");
1694 					update_beacon_info(padapter, pframe, len, psta);
1695 				}
1696 
1697 				adaptive_early_32k(pmlmeext, pframe, len);
1698 
1699 #ifdef CONFIG_TDLS
1700 #ifdef CONFIG_TDLS_CH_SW
1701 				if (padapter->tdlsinfo.ch_switch_prohibited == _FALSE)
1702 				{
1703 					/* Send TDLS Channel Switch Request when receiving Beacon */
1704 					if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1705 						ptdlsinfo->chsw_info.ch_sw_state |= TDLS_WAIT_CH_RSP_STATE;
1706 						/* DBG_871X("[%s] issue_tdls_ch_switch_req to "MAC_FMT"\n", __FUNCTION__, MAC_ARG(padapter->tdlsinfo.chsw_info.addr)); */
1707 						ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1708 						if (ptdls_sta != NULL) {
1709 							if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
1710 								issue_tdls_ch_switch_req(padapter, ptdls_sta);
1711 						}
1712 					}
1713 				}
1714 #endif
1715 #endif /* CONFIG_TDLS */
1716 
1717 #ifdef CONFIG_DFS
1718 				process_csa_ie(padapter, pframe, len);	//channel switch announcement
1719 #endif //CONFIG_DFS
1720 
1721 #ifdef CONFIG_P2P_PS
1722 				process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1723 #endif //CONFIG_P2P_PS
1724 
1725 				#if 0 //move to validate_recv_mgnt_frame
1726 				psta->sta_stats.rx_mgnt_pkts++;
1727 				#endif
1728 			}
1729 		}
1730 		else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
1731 		{
1732 			if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1733 			{
1734 				//update WMM, ERP in the beacon
1735 				//todo: the timer is used instead of the number of the beacon received
1736 				if ((sta_rx_pkts(psta) & 0xf) == 0)
1737 				{
1738 					//DBG_871X("update_bcn_info\n");
1739 					update_beacon_info(padapter, pframe, len, psta);
1740 				}
1741 
1742 				#if 0 //move to validate_recv_mgnt_frame
1743 				psta->sta_stats.rx_mgnt_pkts++;
1744 				#endif
1745 			}
1746 			else
1747 			{
1748 				//allocate a new CAM entry for IBSS station
1749 				if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
1750 				{
1751 					goto _END_ONBEACON_;
1752 				}
1753 
1754 				//get supported rate
1755 				if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL)
1756 				{
1757 					pmlmeinfo->FW_sta_info[cam_idx].status = 0;
1758 					goto _END_ONBEACON_;
1759 				}
1760 
1761 				//update TSF Value
1762 				update_TSF(pmlmeext, pframe, len);
1763 
1764 				//report sta add event
1765 				report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
1766 			}
1767 		}
1768 	}
1769 
1770 _END_ONBEACON_:
1771 
1772 	return _SUCCESS;
1773 
1774 }
1775 
OnAuth(_adapter * padapter,union recv_frame * precv_frame)1776 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1777 {
1778 #ifdef CONFIG_AP_MODE
1779 	_irqL irqL;
1780 	unsigned int	auth_mode, seq, ie_len;
1781 	unsigned char	*sa, *p;
1782 	u16	algorithm;
1783 	int	status;
1784 	static struct sta_info stat;
1785 	struct	sta_info	*pstat=NULL;
1786 	struct	sta_priv *pstapriv = &padapter->stapriv;
1787 	struct security_priv *psecuritypriv = &padapter->securitypriv;
1788 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1789 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1790 	u8 *pframe = precv_frame->u.hdr.rx_data;
1791 	uint len = precv_frame->u.hdr.len;
1792 	u8	offset = 0;
1793 
1794 
1795 #ifdef CONFIG_CONCURRENT_MODE
1796 	if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1797 		check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1798 	{
1799 		//don't process auth request;
1800 		return _SUCCESS;
1801 	}
1802 #endif //CONFIG_CONCURRENT_MODE
1803 
1804 	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1805 		return _FAIL;
1806 
1807 	DBG_871X("+OnAuth\n");
1808 
1809 	sa = GetAddr2Ptr(pframe);
1810 
1811 	auth_mode = psecuritypriv->dot11AuthAlgrthm;
1812 
1813 	if (GetPrivacy(pframe))
1814 	{
1815 		u8	*iv;
1816 		struct rx_pkt_attrib	 *prxattrib = &(precv_frame->u.hdr.attrib);
1817 
1818 		prxattrib->hdrlen = WLAN_HDR_A3_LEN;
1819 		prxattrib->encrypt = _WEP40_;
1820 
1821 		iv = pframe+prxattrib->hdrlen;
1822 		prxattrib->key_index = ((iv[3]>>6)&0x3);
1823 
1824 		prxattrib->iv_len = 4;
1825 		prxattrib->icv_len = 4;
1826 
1827 		rtw_wep_decrypt(padapter, (u8 *)precv_frame);
1828 
1829 		offset = 4;
1830 	}
1831 
1832 	algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1833 	seq 	= le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1834 
1835 	DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
1836 
1837 	if (auth_mode == 2 &&
1838 			psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1839 			psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1840 		auth_mode = 0;
1841 
1842 	if ((algorithm > 0 && auth_mode == 0) ||	// rx a shared-key auth but shared not enabled
1843 		(algorithm == 0 && auth_mode == 1) )	// rx a open-system auth but shared-key is enabled
1844 	{
1845 		DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1846 			algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1847 
1848 		status = _STATS_NO_SUPP_ALG_;
1849 
1850 		goto auth_fail;
1851 	}
1852 
1853 #if 0 //ACL control
1854 	phead = &priv->wlan_acl_list;
1855 	plist = phead->next;
1856 	//check sa
1857 	if (acl_mode == 1)		// 1: positive check, only those on acl_list can be connected.
1858 		res = FAIL;
1859 	else
1860 		res = SUCCESS;
1861 
1862 	while(plist != phead)
1863 	{
1864 		paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
1865 		plist = plist->next;
1866 		if (!memcmp((void *)sa, paclnode->addr, 6)) {
1867 			if (paclnode->mode & 2) { // deny
1868 				res = FAIL;
1869 				break;
1870 			}
1871 			else {
1872 				res = SUCCESS;
1873 				break;
1874 			}
1875 		}
1876 	}
1877 
1878 	if (res != SUCCESS) {
1879 		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
1880 		return FAIL;
1881 	}
1882 #else
1883 	if(rtw_access_ctrl(padapter, sa) == _FALSE)
1884 	{
1885 		status = _STATS_UNABLE_HANDLE_STA_;
1886 		goto auth_fail;
1887 	}
1888 #endif
1889 
1890 	pstat = rtw_get_stainfo(pstapriv, sa);
1891 	if (pstat == NULL)
1892 	{
1893 
1894 		// allocate a new one
1895 		DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n",  MAC_ARG(sa));
1896 		pstat = rtw_alloc_stainfo(pstapriv, sa);
1897 		if (pstat == NULL)
1898 		{
1899 			DBG_871X(" Exceed the upper limit of supported clients...\n");
1900 			status = _STATS_UNABLE_HANDLE_STA_;
1901 			goto auth_fail;
1902 		}
1903 
1904 		pstat->state = WIFI_FW_AUTH_NULL;
1905 		pstat->auth_seq = 0;
1906 
1907 		//pstat->flags = 0;
1908 		//pstat->capability = 0;
1909 	} else {
1910 #ifdef CONFIG_IEEE80211W
1911 		if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1912 #endif /* CONFIG_IEEE80211W */
1913 		{
1914 
1915 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1916 			if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
1917 				rtw_list_delete(&pstat->asoc_list);
1918 				pstapriv->asoc_list_cnt--;
1919 				if (pstat->expire_to > 0)
1920 					;/* TODO: STA re_auth within expire_to */
1921 			}
1922 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1923 
1924 			if (seq == 1)
1925 				; /* TODO: STA re_auth and auth timeout */
1926 
1927 		}
1928 	}
1929 
1930 #ifdef CONFIG_IEEE80211W
1931 	if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1932 #endif /* CONFIG_IEEE80211W */
1933 	{
1934 		_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
1935 		if (rtw_is_list_empty(&pstat->auth_list)) {
1936 
1937 			rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
1938 			pstapriv->auth_list_cnt++;
1939 		}
1940 		_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
1941 	}
1942 
1943 	if (pstat->auth_seq == 0)
1944 		pstat->expire_to = pstapriv->auth_to;
1945 
1946 
1947 	if ((pstat->auth_seq + 1) != seq)
1948 	{
1949 		DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1950 			seq, pstat->auth_seq+1);
1951 		status = _STATS_OUT_OF_AUTH_SEQ_;
1952 		goto auth_fail;
1953 	}
1954 
1955 	if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
1956 	{
1957 		if (seq == 1)
1958 		{
1959 #ifdef CONFIG_IEEE80211W
1960 			if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1961 #endif /* CONFIG_IEEE80211W */
1962 			{
1963 				pstat->state &= ~WIFI_FW_AUTH_NULL;
1964 				pstat->state |= WIFI_FW_AUTH_SUCCESS;
1965 				pstat->expire_to = pstapriv->assoc_to;
1966 			}
1967 			pstat->authalg = algorithm;
1968 		}
1969 		else
1970 		{
1971 			DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1972 				seq, pstat->auth_seq+1);
1973 			status = _STATS_OUT_OF_AUTH_SEQ_;
1974 			goto auth_fail;
1975 		}
1976 	}
1977 	else // shared system or auto authentication
1978 	{
1979 		if (seq == 1)
1980 		{
1981 			//prepare for the challenging txt...
1982 
1983 			//get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
1984 			_rtw_memset((void *)pstat->chg_txt, 78, 128);
1985 #ifdef CONFIG_IEEE80211W
1986 			if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1987 #endif /* CONFIG_IEEE80211W */
1988 			{
1989 				pstat->state &= ~WIFI_FW_AUTH_NULL;
1990 				pstat->state |= WIFI_FW_AUTH_STATE;
1991 			}
1992 			pstat->authalg = algorithm;
1993 			pstat->auth_seq = 2;
1994 		}
1995 		else if (seq == 3)
1996 		{
1997 			//checking for challenging txt...
1998 			DBG_871X("checking for challenging txt...\n");
1999 
2000 			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2001 					len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2002 
2003 			if((p==NULL) || (ie_len<=0))
2004 			{
2005 				DBG_871X("auth rejected because challenge failure!(1)\n");
2006 				status = _STATS_CHALLENGE_FAIL_;
2007 				goto auth_fail;
2008 			}
2009 
2010 			if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
2011 			{
2012 #ifdef CONFIG_IEEE80211W
2013 				if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2014 #endif /* CONFIG_IEEE80211W */
2015 				{
2016 					pstat->state &= (~WIFI_FW_AUTH_STATE);
2017 					pstat->state |= WIFI_FW_AUTH_SUCCESS;
2018 					/* challenging txt is correct... */
2019 					pstat->expire_to =  pstapriv->assoc_to;
2020 				}
2021 			}
2022 			else
2023 			{
2024 				DBG_871X("auth rejected because challenge failure!\n");
2025 				status = _STATS_CHALLENGE_FAIL_;
2026 				goto auth_fail;
2027 			}
2028 		}
2029 		else
2030 		{
2031 			DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2032 				seq, pstat->auth_seq+1);
2033 			status = _STATS_OUT_OF_AUTH_SEQ_;
2034 			goto auth_fail;
2035 		}
2036 	}
2037 
2038 
2039 	// Now, we are going to issue_auth...
2040 	pstat->auth_seq = seq + 1;
2041 
2042 #ifdef CONFIG_NATIVEAP_MLME
2043 	issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2044 #endif
2045 
2046 	if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2047 		pstat->auth_seq = 0;
2048 
2049 
2050 	return _SUCCESS;
2051 
2052 auth_fail:
2053 
2054 	if(pstat)
2055 		rtw_free_stainfo(padapter , pstat);
2056 
2057 	pstat = &stat;
2058 	_rtw_memset((char *)pstat, '\0', sizeof(stat));
2059 	pstat->auth_seq = 2;
2060 	_rtw_memcpy(pstat->hwaddr, sa, 6);
2061 
2062 #ifdef CONFIG_NATIVEAP_MLME
2063 	issue_auth(padapter, pstat, (unsigned short)status);
2064 #endif
2065 
2066 #endif
2067 	return _FAIL;
2068 
2069 }
2070 
OnAuthClient(_adapter * padapter,union recv_frame * precv_frame)2071 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2072 {
2073 	unsigned int	seq, len, status, algthm, offset;
2074 	unsigned char	*p;
2075 	unsigned int	go2asoc = 0;
2076 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2077 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2078 	u8 *pframe = precv_frame->u.hdr.rx_data;
2079 	uint pkt_len = precv_frame->u.hdr.len;
2080 
2081 	DBG_871X("%s\n", __FUNCTION__);
2082 
2083 	//check A1 matches or not
2084 	if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2085 		return _SUCCESS;
2086 
2087 	if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2088 		return _SUCCESS;
2089 
2090 	offset = (GetPrivacy(pframe))? 4: 0;
2091 
2092 	algthm 	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2093 	seq 	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2094 	status 	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2095 
2096 	if (status != 0)
2097 	{
2098 		DBG_871X("clnt auth fail, status: %d\n", status);
2099 		if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
2100 		{
2101 			if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2102 				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2103 			else
2104 				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2105 			//pmlmeinfo->reauth_count = 0;
2106 		}
2107 
2108 		set_link_timer(pmlmeext, 1);
2109 		goto authclnt_fail;
2110 	}
2111 
2112 	if (seq == 2)
2113 	{
2114 		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2115 		{
2116 			 // legendary shared system
2117 			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2118 				pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2119 
2120 			if (p == NULL)
2121 			{
2122 				//DBG_871X("marc: no challenge text?\n");
2123 				goto authclnt_fail;
2124 			}
2125 
2126 			_rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2127 			pmlmeinfo->auth_seq = 3;
2128 			issue_auth(padapter, NULL, 0);
2129 			set_link_timer(pmlmeext, REAUTH_TO);
2130 
2131 			return _SUCCESS;
2132 		}
2133 		else
2134 		{
2135 			// open system
2136 			go2asoc = 1;
2137 		}
2138 	}
2139 	else if (seq == 4)
2140 	{
2141 		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2142 		{
2143 			go2asoc = 1;
2144 		}
2145 		else
2146 		{
2147 			goto authclnt_fail;
2148 		}
2149 	}
2150 	else
2151 	{
2152 		// this is also illegal
2153 		//DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
2154 		goto authclnt_fail;
2155 	}
2156 
2157 	if (go2asoc)
2158 	{
2159 		DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
2160 		start_clnt_assoc(padapter);
2161 		return _SUCCESS;
2162 	}
2163 
2164 authclnt_fail:
2165 
2166 	//pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
2167 
2168 	return _FAIL;
2169 
2170 }
2171 
OnAssocReq(_adapter * padapter,union recv_frame * precv_frame)2172 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2173 {
2174 #ifdef CONFIG_AP_MODE
2175 	_irqL irqL;
2176 	u16 capab_info, listen_interval;
2177 	struct rtw_ieee802_11_elems elems;
2178 	struct sta_info	*pstat;
2179 	unsigned char		reassoc, *p, *pos, *wpa_ie;
2180 	unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2181 	int		i, ie_len, wpa_ie_len, left;
2182 	unsigned char		supportRate[16];
2183 	int					supportRateNum;
2184 	unsigned short		status = _STATS_SUCCESSFUL_;
2185 	unsigned short		frame_type, ie_offset=0;
2186 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2187 	struct security_priv *psecuritypriv = &padapter->securitypriv;
2188 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2189 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2190 	WLAN_BSSID_EX 	*cur = &(pmlmeinfo->network);
2191 	struct sta_priv *pstapriv = &padapter->stapriv;
2192 	u8 *pframe = precv_frame->u.hdr.rx_data;
2193 	uint pkt_len = precv_frame->u.hdr.len;
2194 #ifdef CONFIG_P2P
2195 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
2196 	u8 p2p_status_code = P2P_STATUS_SUCCESS;
2197 	u8 *p2pie;
2198 	u32 p2pielen = 0;
2199 #ifdef CONFIG_WFD
2200 	u8	wfd_ie[ 128 ] = { 0x00 };
2201 	u32	wfd_ielen = 0;
2202 #endif // CONFIG_WFD
2203 #endif //CONFIG_P2P
2204 
2205 #ifdef CONFIG_CONCURRENT_MODE
2206 	if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
2207 		check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
2208 	{
2209 		//don't process assoc request;
2210 		return _SUCCESS;
2211 	}
2212 #endif //CONFIG_CONCURRENT_MODE
2213 
2214 	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2215 		return _FAIL;
2216 
2217 	frame_type = GetFrameSubType(pframe);
2218 	if (frame_type == WIFI_ASSOCREQ)
2219 	{
2220 		reassoc = 0;
2221 		ie_offset = _ASOCREQ_IE_OFFSET_;
2222 	}
2223 	else // WIFI_REASSOCREQ
2224 	{
2225 		reassoc = 1;
2226 		ie_offset = _REASOCREQ_IE_OFFSET_;
2227 	}
2228 
2229 
2230 	if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2231 		DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2232 		       "\n", reassoc, (unsigned long)pkt_len);
2233 		return _FAIL;
2234 	}
2235 
2236 	pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2237 	if (pstat == (struct sta_info *)NULL)
2238 	{
2239 		status = _RSON_CLS2_;
2240 		goto asoc_class2_error;
2241 	}
2242 
2243 	capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
2244 	//capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2245 	//listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
2246 	listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
2247 
2248 	left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2249 	pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2250 
2251 
2252 	DBG_871X("%s\n", __FUNCTION__);
2253 
2254 	// check if this stat has been successfully authenticated/assocated
2255 	if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
2256 	{
2257 		if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
2258 		{
2259 			status = _RSON_CLS2_;
2260 			goto asoc_class2_error;
2261 		}
2262 		else
2263 		{
2264 			pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2265 			pstat->state |= WIFI_FW_ASSOC_STATE;
2266 		}
2267 	}
2268 	else
2269 	{
2270 		pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2271 		pstat->state |= WIFI_FW_ASSOC_STATE;
2272 	}
2273 
2274 
2275 #if 0// todo:tkip_countermeasures
2276 	if (hapd->tkip_countermeasures) {
2277 		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2278 		goto fail;
2279 	}
2280 #endif
2281 
2282 	pstat->capability = capab_info;
2283 
2284 #if 0//todo:
2285 	//check listen_interval
2286 	if (listen_interval > hapd->conf->max_listen_interval) {
2287 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2288 			       HOSTAPD_LEVEL_DEBUG,
2289 			       "Too large Listen Interval (%d)",
2290 			       listen_interval);
2291 		resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2292 		goto fail;
2293 	}
2294 
2295 	pstat->listen_interval = listen_interval;
2296 #endif
2297 
2298 	//now parse all ieee802_11 ie to point to elems
2299 	if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2300 	    !elems.ssid) {
2301 		DBG_871X("STA " MAC_FMT " sent invalid association request\n",
2302 		       MAC_ARG(pstat->hwaddr));
2303 		status = _STATS_FAILURE_;
2304 		goto OnAssocReqFail;
2305 	}
2306 
2307 
2308 	// now we should check all the fields...
2309 	// checking SSID
2310 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2311 		pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2312 	if (p == NULL)
2313 	{
2314 		status = _STATS_FAILURE_;
2315 	}
2316 
2317 	if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
2318 		status = _STATS_FAILURE_;
2319 	else
2320 	{
2321 		// check if ssid match
2322 		if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2323 			status = _STATS_FAILURE_;
2324 
2325 		if (ie_len != cur->Ssid.SsidLength)
2326 			status = _STATS_FAILURE_;
2327 	}
2328 
2329 	if(_STATS_SUCCESSFUL_ != status)
2330 		goto OnAssocReqFail;
2331 
2332 	// check if the supported rate is ok
2333 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2334 	if (p == NULL) {
2335 		DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
2336 		// use our own rate set as statoin used
2337 		//_rtw_memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN);
2338 		//supportRateNum = AP_BSSRATE_LEN;
2339 
2340 		status = _STATS_FAILURE_;
2341 		goto OnAssocReqFail;
2342 	}
2343 	else {
2344 		_rtw_memcpy(supportRate, p+2, ie_len);
2345 		supportRateNum = ie_len;
2346 
2347 		p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
2348 				pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2349 		if (p !=  NULL) {
2350 
2351 			if(supportRateNum<=sizeof(supportRate))
2352 			{
2353 				_rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
2354 				supportRateNum += ie_len;
2355 			}
2356 		}
2357 	}
2358 
2359 	//todo: mask supportRate between AP & STA -> move to update raid
2360 	//get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0);
2361 
2362 	//update station supportRate
2363 	pstat->bssratelen = supportRateNum;
2364 	_rtw_memcpy(pstat->bssrateset, supportRate, supportRateNum);
2365 	UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2366 
2367 	//check RSN/WPA/WPS
2368 	pstat->dot8021xalg = 0;
2369       	pstat->wpa_psk = 0;
2370 	pstat->wpa_group_cipher = 0;
2371 	pstat->wpa2_group_cipher = 0;
2372 	pstat->wpa_pairwise_cipher = 0;
2373 	pstat->wpa2_pairwise_cipher = 0;
2374 	_rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2375 	if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2376 
2377 		int group_cipher=0, pairwise_cipher=0;
2378 
2379 		wpa_ie = elems.rsn_ie;
2380 		wpa_ie_len = elems.rsn_ie_len;
2381 
2382 		if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2383 		{
2384 			pstat->dot8021xalg = 1;//psk,  todo:802.1x
2385 			pstat->wpa_psk |= BIT(1);
2386 
2387 			pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
2388 			pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
2389 
2390 			if(!pstat->wpa2_group_cipher)
2391 				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2392 
2393 			if(!pstat->wpa2_pairwise_cipher)
2394 				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2395 		}
2396 		else
2397 		{
2398 			status = WLAN_STATUS_INVALID_IE;
2399 		}
2400 
2401 	} else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2402 
2403 		int group_cipher=0, pairwise_cipher=0;
2404 
2405 		wpa_ie = elems.wpa_ie;
2406 		wpa_ie_len = elems.wpa_ie_len;
2407 
2408 		if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2409 		{
2410 			pstat->dot8021xalg = 1;//psk,  todo:802.1x
2411 			pstat->wpa_psk |= BIT(0);
2412 
2413 			pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
2414 			pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
2415 
2416 			if(!pstat->wpa_group_cipher)
2417 				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2418 
2419 			if(!pstat->wpa_pairwise_cipher)
2420 				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2421 
2422 		}
2423 		else
2424 		{
2425 			status = WLAN_STATUS_INVALID_IE;
2426 		}
2427 
2428 	} else {
2429 		wpa_ie = NULL;
2430 		wpa_ie_len = 0;
2431 	}
2432 
2433 	if(_STATS_SUCCESSFUL_ != status)
2434 		goto OnAssocReqFail;
2435 
2436 	pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2437 	//if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
2438 	if(wpa_ie == NULL) {
2439 		if (elems.wps_ie) {
2440 			DBG_871X("STA included WPS IE in "
2441 				   "(Re)Association Request - assume WPS is "
2442 				   "used\n");
2443 			pstat->flags |= WLAN_STA_WPS;
2444 			//wpabuf_free(sta->wps_ie);
2445 			//sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
2446 			//				elems.wps_ie_len - 4);
2447 		} else {
2448 			DBG_871X("STA did not include WPA/RSN IE "
2449 				   "in (Re)Association Request - possible WPS "
2450 				   "use\n");
2451 			pstat->flags |= WLAN_STA_MAYBE_WPS;
2452 		}
2453 
2454 
2455 		// AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
2456 		// that the selected registrar of AP is _FLASE
2457 		if((psecuritypriv->wpa_psk >0)
2458 			&& (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
2459 		{
2460 			if(pmlmepriv->wps_beacon_ie)
2461 			{
2462 				u8 selected_registrar = 0;
2463 
2464 				rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2465 
2466 				if(!selected_registrar)
2467 				{
2468 					DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2469 
2470 					status = _STATS_UNABLE_HANDLE_STA_;
2471 
2472 					goto OnAssocReqFail;
2473 				}
2474 			}
2475 		}
2476 
2477 	}
2478 	else
2479 	{
2480 		int copy_len;
2481 
2482 		if(psecuritypriv->wpa_psk == 0)
2483 		{
2484 			DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
2485 		       	"request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2486 
2487 			status = WLAN_STATUS_INVALID_IE;
2488 
2489 			goto OnAssocReqFail;
2490 
2491 		}
2492 
2493 		if (elems.wps_ie) {
2494 			DBG_871X("STA included WPS IE in "
2495 				   "(Re)Association Request - WPS is "
2496 				   "used\n");
2497 			pstat->flags |= WLAN_STA_WPS;
2498 			copy_len=0;
2499 		}
2500 		else
2501 		{
2502 			copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
2503 		}
2504 
2505 
2506 		if(copy_len>0)
2507 			_rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
2508 
2509 	}
2510 
2511 
2512 	// check if there is WMM IE & support WWM-PS
2513 	pstat->flags &= ~WLAN_STA_WME;
2514 	pstat->qos_option = 0;
2515 	pstat->qos_info = 0;
2516 	pstat->has_legacy_ac = _TRUE;
2517 	pstat->uapsd_vo = 0;
2518 	pstat->uapsd_vi = 0;
2519 	pstat->uapsd_be = 0;
2520 	pstat->uapsd_bk = 0;
2521 	if (pmlmepriv->qospriv.qos_option)
2522 	{
2523 		p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
2524 		for (;;)
2525 		{
2526 			p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2527 			if (p != NULL) {
2528 				if (_rtw_memcmp(p+2, WMM_IE, 6)) {
2529 
2530 					pstat->flags |= WLAN_STA_WME;
2531 
2532 					pstat->qos_option = 1;
2533 					pstat->qos_info = *(p+8);
2534 
2535 					pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
2536 
2537 					if((pstat->qos_info&0xf) !=0xf)
2538 						pstat->has_legacy_ac = _TRUE;
2539 					else
2540 						pstat->has_legacy_ac = _FALSE;
2541 
2542 					if(pstat->qos_info&0xf)
2543 					{
2544 						if(pstat->qos_info&BIT(0))
2545 							pstat->uapsd_vo = BIT(0)|BIT(1);
2546 						else
2547 							pstat->uapsd_vo = 0;
2548 
2549 						if(pstat->qos_info&BIT(1))
2550 							pstat->uapsd_vi = BIT(0)|BIT(1);
2551 						else
2552 							pstat->uapsd_vi = 0;
2553 
2554 						if(pstat->qos_info&BIT(2))
2555 							pstat->uapsd_bk = BIT(0)|BIT(1);
2556 						else
2557 							pstat->uapsd_bk = 0;
2558 
2559 						if(pstat->qos_info&BIT(3))
2560 							pstat->uapsd_be = BIT(0)|BIT(1);
2561 						else
2562 							pstat->uapsd_be = 0;
2563 
2564 					}
2565 
2566 					break;
2567 				}
2568 			}
2569 			else {
2570 				break;
2571 			}
2572 			p = p + ie_len + 2;
2573 		}
2574 	}
2575 
2576 
2577 #ifdef CONFIG_80211N_HT
2578 	/* save HT capabilities in the sta object */
2579 	_rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2580 	if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
2581 	{
2582 		pstat->flags |= WLAN_STA_HT;
2583 
2584 		pstat->flags |= WLAN_STA_WME;
2585 
2586 		_rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
2587 
2588 	} else
2589 		pstat->flags &= ~WLAN_STA_HT;
2590 
2591 
2592 	if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
2593 	{
2594 		status = _STATS_FAILURE_;
2595 		goto OnAssocReqFail;
2596 	}
2597 
2598 #endif /* CONFIG_80211N_HT */
2599 
2600 #ifdef CONFIG_80211AC_VHT
2601 	_rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
2602 	if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
2603 		pstat->flags |= WLAN_STA_VHT;
2604 
2605 		_rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
2606 
2607 		if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) {
2608 			_rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1);
2609 		}
2610 		else // for Frame without Operating Mode notify ie; default: 80M
2611 		{
2612 			pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
2613 		}
2614 	}
2615 	else {
2616 		pstat->flags &= ~WLAN_STA_VHT;
2617 	}
2618 
2619 	if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT))
2620 	{
2621 		status = _STATS_FAILURE_;
2622 		goto OnAssocReqFail;
2623 	}
2624 #endif /* CONFIG_80211AC_VHT */
2625 
2626 	if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
2627 		((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
2628 		(pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2629 
2630 		DBG_871X("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr));
2631 
2632 		pstat->flags &= ~WLAN_STA_HT;
2633 		pstat->flags &= ~WLAN_STA_VHT;
2634 		/*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2635 		  * goto OnAssocReqFail;
2636 		*/
2637 	}
2638 
2639 
2640        //
2641        //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
2642 	pstat->flags |= WLAN_STA_NONERP;
2643 	for (i = 0; i < pstat->bssratelen; i++) {
2644 		if ((pstat->bssrateset[i] & 0x7f) > 22) {
2645 			pstat->flags &= ~WLAN_STA_NONERP;
2646 			break;
2647 		}
2648 	}
2649 
2650 	if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2651 		pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2652 	else
2653 		pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2654 
2655 
2656 
2657 	if (status != _STATS_SUCCESSFUL_)
2658 		goto OnAssocReqFail;
2659 
2660 #ifdef CONFIG_P2P
2661 	pstat->is_p2p_device = _FALSE;
2662 	if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2663 	{
2664 		if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
2665 		{
2666 			pstat->is_p2p_device = _TRUE;
2667 			if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
2668 			{
2669 				pstat->p2p_status_code = p2p_status_code;
2670 				status = _STATS_CAP_FAIL_;
2671 				goto OnAssocReqFail;
2672 			}
2673 		}
2674 #ifdef CONFIG_WFD
2675 		if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
2676 		{
2677 			u8	attr_content[ 10 ] = { 0x00 };
2678 			u32	attr_contentlen = 0;
2679 
2680 			DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ );
2681 			rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
2682 			if ( attr_contentlen )
2683 			{
2684 				pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
2685 				DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
2686 			}
2687 		}
2688 #endif
2689 	}
2690 	pstat->p2p_status_code = p2p_status_code;
2691 #endif //CONFIG_P2P
2692 
2693 	//TODO: identify_proprietary_vendor_ie();
2694 	// Realtek proprietary IE
2695 	// identify if this is Broadcom sta
2696 	// identify if this is ralink sta
2697 	// Customer proprietary IE
2698 
2699 
2700 
2701 	/* get a unique AID */
2702 	if (pstat->aid > 0) {
2703 		DBG_871X("  old AID %d\n", pstat->aid);
2704 	} else {
2705 		for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2706 			if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2707 				if (pstat->aid > pstapriv->max_num_sta) {
2708 					pstat->aid = 0;
2709 
2710 					DBG_871X("  no room for more AIDs\n");
2711 
2712 					status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2713 
2714 					goto OnAssocReqFail;
2715 
2716 
2717 				} else {
2718 					pstapriv->sta_aid[pstat->aid - 1] = pstat;
2719 					DBG_871X("allocate new AID = (%d)\n", pstat->aid);
2720 					break;
2721 				}
2722 			}
2723 		}
2724 	}
2725 
2726 
2727 	pstat->state &= (~WIFI_FW_ASSOC_STATE);
2728 	pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2729 	/* DBG_871X("==================%s, %d,  (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2730 	, __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */
2731 #ifdef CONFIG_IEEE80211W
2732 	if (pstat->bpairwise_key_installed != _TRUE)
2733 #endif /* CONFIG_IEEE80211W */
2734 	{
2735 		_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2736 		if (!rtw_is_list_empty(&pstat->auth_list)) {
2737 			rtw_list_delete(&pstat->auth_list);
2738 			pstapriv->auth_list_cnt--;
2739 		}
2740 		_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2741 
2742 		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2743 		if (rtw_is_list_empty(&pstat->asoc_list)) {
2744 			pstat->expire_to = pstapriv->expire_to;
2745 			rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2746 			pstapriv->asoc_list_cnt++;
2747 		}
2748 		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2749 	}
2750 
2751 	// now the station is qualified to join our BSS...
2752 	if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
2753 	{
2754 #ifdef CONFIG_NATIVEAP_MLME
2755 #ifdef CONFIG_IEEE80211W
2756 		if (pstat->bpairwise_key_installed != _TRUE)
2757 #endif /* CONFIG_IEEE80211W */
2758 		{
2759 			/* .1 bss_cap_update & sta_info_update */
2760 			bss_cap_update_on_sta_join(padapter, pstat);
2761 			sta_info_update(padapter, pstat);
2762 		}
2763 #ifdef CONFIG_IEEE80211W
2764 		if (pstat->bpairwise_key_installed == _TRUE)
2765 			status = _STATS_REFUSED_TEMPORARILY_;
2766 #endif /* CONFIG_IEEE80211W */
2767 		//.2 issue assoc rsp before notify station join event.
2768 		if (frame_type == WIFI_ASSOCREQ)
2769 			issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2770 		else
2771 			issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2772 
2773 #ifdef CONFIG_IOCTL_CFG80211
2774 		_enter_critical_bh(&pstat->lock, &irqL);
2775 		if(pstat->passoc_req)
2776 		{
2777 			rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2778 			pstat->passoc_req = NULL;
2779 			pstat->assoc_req_len = 0;
2780 		}
2781 
2782 		pstat->passoc_req =  rtw_zmalloc(pkt_len);
2783 		if(pstat->passoc_req)
2784 		{
2785 			_rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2786 			pstat->assoc_req_len = pkt_len;
2787 		}
2788 		_exit_critical_bh(&pstat->lock, &irqL);
2789 #endif //CONFIG_IOCTL_CFG80211
2790 #ifdef CONFIG_IEEE80211W
2791 		if (pstat->bpairwise_key_installed != _TRUE)
2792 #endif /* CONFIG_IEEE80211W */
2793 		{
2794 			/* .3-(1) report sta add event */
2795 			report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
2796 		}
2797 #ifdef CONFIG_IEEE80211W
2798 		if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) {
2799 			DBG_871X(MAC_FMT"\n", MAC_ARG(pstat->hwaddr));
2800 			issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY);
2801 		}
2802 #endif /* CONFIG_IEEE80211W */
2803 #endif //CONFIG_NATIVEAP_MLME
2804 	}
2805 
2806 	return _SUCCESS;
2807 
2808 asoc_class2_error:
2809 
2810 #ifdef CONFIG_NATIVEAP_MLME
2811 	issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
2812 #endif
2813 
2814 	return _FAIL;
2815 
2816 OnAssocReqFail:
2817 
2818 
2819 #ifdef CONFIG_NATIVEAP_MLME
2820 	pstat->aid = 0;
2821 	if (frame_type == WIFI_ASSOCREQ)
2822 		issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2823 	else
2824 		issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2825 #endif
2826 
2827 
2828 #endif /* CONFIG_AP_MODE */
2829 
2830 	return _FAIL;
2831 
2832 }
2833 
OnAssocRsp(_adapter * padapter,union recv_frame * precv_frame)2834 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2835 {
2836 	uint i;
2837 	int res;
2838 	unsigned short	status;
2839 	PNDIS_802_11_VARIABLE_IEs	pIE = NULL;
2840 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2841 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2842 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2843 	//WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
2844 	u8 *pframe = precv_frame->u.hdr.rx_data;
2845 	uint pkt_len = precv_frame->u.hdr.len;
2846 	PNDIS_802_11_VARIABLE_IEs	pWapiIE = NULL;
2847 
2848 	DBG_871X("%s\n", __FUNCTION__);
2849 
2850 	//check A1 matches or not
2851 	if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2852 		return _SUCCESS;
2853 
2854 	if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2855 		return _SUCCESS;
2856 
2857 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2858 		return _SUCCESS;
2859 
2860 	_cancel_timer_ex(&pmlmeext->link_timer);
2861 
2862 	//status
2863 	if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2864 	{
2865 		DBG_871X("assoc reject, status code: %d\n", status);
2866 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
2867 		res = -4;
2868 		goto report_assoc_result;
2869 	}
2870 
2871 	//get capabilities
2872 	pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2873 
2874 	//set slot time
2875 	pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2876 
2877 	//AID
2878 	res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2879 
2880 	//following are moved to join event callback function
2881 	//to handle HT, WMM, rate adaptive, update MAC reg
2882 	//for not to handle the synchronous IO in the tasklet
2883 	for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2884 	{
2885 		pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2886 
2887 		switch (pIE->ElementID)
2888 		{
2889 			case _VENDOR_SPECIFIC_IE_:
2890 				if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6))	//WMM
2891 				{
2892 					WMM_param_handler(padapter, pIE);
2893 				}
2894 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2895 				else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4))		//WFD
2896 				{
2897 					DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ );
2898 					WFD_info_handler( padapter, pIE );
2899 				}
2900 #endif
2901 				break;
2902 
2903 #ifdef CONFIG_WAPI_SUPPORT
2904 			case _WAPI_IE_:
2905 				pWapiIE = pIE;
2906 				break;
2907 #endif
2908 
2909 			case _HT_CAPABILITY_IE_:	//HT caps
2910 				HT_caps_handler(padapter, pIE);
2911 				break;
2912 
2913 			case _HT_EXTRA_INFO_IE_:	//HT info
2914 				HT_info_handler(padapter, pIE);
2915 				break;
2916 
2917 #ifdef CONFIG_80211AC_VHT
2918 			case EID_VHTCapability:
2919 				VHT_caps_handler(padapter, pIE);
2920 				break;
2921 
2922 			case EID_VHTOperation:
2923 				VHT_operation_handler(padapter, pIE);
2924 				break;
2925 #endif
2926 
2927 			case _ERPINFO_IE_:
2928 				ERP_IE_handler(padapter, pIE);
2929 				break;
2930 #ifdef CONFIG_TDLS
2931 			case _EXT_CAP_IE_:
2932 				if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2933 					padapter->tdlsinfo.ap_prohibited = _TRUE;
2934 				if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
2935 					padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
2936 				break;
2937 #endif /* CONFIG_TDLS */
2938 			default:
2939 				break;
2940 		}
2941 
2942 		i += (pIE->Length + 2);
2943 	}
2944 
2945 #ifdef CONFIG_WAPI_SUPPORT
2946 	if (pIE != NULL)
2947 		rtw_wapi_on_assoc_ok(padapter, pIE);
2948 #endif
2949 
2950 	pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
2951 	pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
2952 
2953 	//Update Basic Rate Table for spec, 2010-12-28 , by thomas
2954 	UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
2955 
2956 report_assoc_result:
2957 	if (res > 0) {
2958 		rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
2959 	} else {
2960 		rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
2961 	}
2962 
2963 	report_join_res(padapter, res);
2964 
2965 	return _SUCCESS;
2966 }
2967 
OnDeAuth(_adapter * padapter,union recv_frame * precv_frame)2968 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
2969 {
2970 	unsigned short	reason;
2971 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2972 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2973 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2974 	u8 *pframe = precv_frame->u.hdr.rx_data;
2975 #ifdef CONFIG_P2P
2976 	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2977 #endif //CONFIG_P2P
2978 
2979 	//check A3
2980 	if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
2981 		return _SUCCESS;
2982 
2983 	DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
2984 
2985 #ifdef CONFIG_P2P
2986 	if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2987 	{
2988 		_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2989 		_set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2990 	}
2991 #endif //CONFIG_P2P
2992 
2993 	reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2994 
2995 	rtw_lock_rx_suspend_timeout(8000);
2996 
2997 #ifdef CONFIG_AP_MODE
2998 	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2999 	{
3000 		_irqL irqL;
3001 		struct sta_info *psta;
3002 		struct sta_priv *pstapriv = &padapter->stapriv;
3003 
3004 		//_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3005 		//rtw_free_stainfo(padapter, psta);
3006 		//_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3007 
3008 		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3009 			, FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3010 
3011 		psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3012 		if(psta)
3013 		{
3014 			u8 updated = _FALSE;
3015 
3016 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3017 			if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3018 			{
3019 				rtw_list_delete(&psta->asoc_list);
3020 				pstapriv->asoc_list_cnt--;
3021 				updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3022 
3023 			}
3024 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3025 
3026 			associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3027 		}
3028 
3029 
3030 		return _SUCCESS;
3031 	}
3032 	else
3033 #endif
3034 	{
3035 		int	ignore_received_deauth = 0;
3036 
3037 		//	Commented by Albert 20130604
3038 		//	Before sending the auth frame to start the STA/GC mode connection with AP/GO,
3039 		//	we will send the deauth first.
3040 		//	However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
3041 		//	Added the following code to avoid this case.
3042 		if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
3043 			( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
3044 		{
3045 			if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
3046 			{
3047 				ignore_received_deauth = 1;
3048 			} else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3049 				// TODO: 802.11r
3050 				ignore_received_deauth = 1;
3051 			}
3052 		}
3053 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
3054 		if(padapter->mlmepriv.not_indic_disco == _TRUE)
3055 			ignore_received_deauth = 1;
3056 #endif
3057 
3058 		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3059 			, FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth);
3060 
3061 		if ( 0 == ignore_received_deauth )
3062 		{
3063 			receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3064 		}
3065 	}
3066 	pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3067 	return _SUCCESS;
3068 
3069 }
3070 
OnDisassoc(_adapter * padapter,union recv_frame * precv_frame)3071 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3072 {
3073 	unsigned short	reason;
3074 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3075 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3076 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3077 	u8 *pframe = precv_frame->u.hdr.rx_data;
3078 #ifdef CONFIG_P2P
3079 	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3080 #endif //CONFIG_P2P
3081 
3082 	//check A3
3083 	if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3084 		return _SUCCESS;
3085 
3086 	DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3087 
3088 #ifdef CONFIG_P2P
3089 	if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3090 	{
3091 		_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3092 		_set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3093 	}
3094 #endif //CONFIG_P2P
3095 
3096 	reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3097 
3098 	rtw_lock_rx_suspend_timeout(8000);
3099 
3100 #ifdef CONFIG_AP_MODE
3101 	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3102 	{
3103 		_irqL irqL;
3104 		struct sta_info *psta;
3105 		struct sta_priv *pstapriv = &padapter->stapriv;
3106 
3107 		//_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3108 		//rtw_free_stainfo(padapter, psta);
3109 		//_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3110 
3111 		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3112 			, FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3113 
3114 		psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3115 		if(psta)
3116 		{
3117 			u8 updated = _FALSE;
3118 
3119 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3120 			if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3121 			{
3122 				rtw_list_delete(&psta->asoc_list);
3123 				pstapriv->asoc_list_cnt--;
3124 				updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3125 
3126 			}
3127 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3128 
3129 			associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3130 		}
3131 
3132 		return _SUCCESS;
3133 	}
3134 	else
3135 #endif
3136 	{
3137 		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3138 			, FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3139 
3140 		receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3141 	}
3142 	pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3143 	return _SUCCESS;
3144 
3145 }
3146 
OnAtim(_adapter * padapter,union recv_frame * precv_frame)3147 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3148 {
3149 	DBG_871X("%s\n", __FUNCTION__);
3150 	return _SUCCESS;
3151 }
3152 
on_action_spct_ch_switch(_adapter * padapter,struct sta_info * psta,u8 * ies,uint ies_len)3153 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3154 {
3155 	unsigned int ret = _FAIL;
3156 	struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3157 	struct mlme_ext_info	*pmlmeinfo = &(mlmeext->mlmext_info);
3158 
3159 	if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3160 		ret = _SUCCESS;
3161 		goto exit;
3162 	}
3163 
3164 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3165 
3166 		int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3167 		int ch_offset = -1;
3168 		u8 bwmode;
3169 		struct ieee80211_info_element *ie;
3170 
3171 		DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3172 			FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
3173 
3174 		for_each_ie(ie, ies, ies_len) {
3175 			if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3176 				ch_switch_mode = ie->data[0];
3177 				ch = ie->data[1];
3178 				ch_switch_cnt = ie->data[2];
3179 				DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3180 					ch_switch_mode, ch, ch_switch_cnt);
3181 			}
3182 			else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3183 				ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3184 				DBG_871X("ch_offset:%d\n", ch_offset);
3185 			}
3186 		}
3187 
3188 		if (ch == -1)
3189 			return _SUCCESS;
3190 
3191 		if (ch_offset == -1)
3192 			bwmode = mlmeext->cur_bwmode;
3193 		else
3194 			bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3195 				CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3196 
3197 		ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3198 
3199 		/* todo:
3200 		 * 1. the decision of channel switching
3201 		 * 2. things after channel switching
3202 		 */
3203 
3204 		ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
3205 	}
3206 
3207 exit:
3208 	return ret;
3209 }
3210 
on_action_spct(_adapter * padapter,union recv_frame * precv_frame)3211 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3212 {
3213 	unsigned int ret = _FAIL;
3214 	struct sta_info *psta = NULL;
3215 	struct sta_priv *pstapriv = &padapter->stapriv;
3216 	u8 *pframe = precv_frame->u.hdr.rx_data;
3217 	uint frame_len = precv_frame->u.hdr.len;
3218 	u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3219 	u8 category;
3220 	u8 action;
3221 
3222 	DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3223 
3224 	psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3225 
3226 	if (!psta)
3227 		goto exit;
3228 
3229 	category = frame_body[0];
3230 	if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3231 		goto exit;
3232 
3233 	action = frame_body[1];
3234 	switch (action) {
3235 	case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3236 	case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3237 	case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3238 	case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3239 		break;
3240 	case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3241 		#ifdef CONFIG_SPCT_CH_SWITCH
3242 		ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
3243 			frame_len-(frame_body-pframe)-2);
3244 		#endif
3245 		break;
3246 	default:
3247 		break;
3248 	}
3249 
3250 exit:
3251 	return ret;
3252 }
3253 
OnAction_qos(_adapter * padapter,union recv_frame * precv_frame)3254 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3255 {
3256 	return _SUCCESS;
3257 }
3258 
OnAction_dls(_adapter * padapter,union recv_frame * precv_frame)3259 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3260 {
3261 	return _SUCCESS;
3262 }
3263 
3264 /**
3265  * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3266  * @adapter: the adapter to get target RX AMPDU buffer size
3267  *
3268  * Returns: the target RX AMPDU buffer size
3269  */
rtw_rx_ampdu_size(_adapter * adapter)3270 u8 rtw_rx_ampdu_size(_adapter *adapter)
3271 {
3272 	u8 size;
3273 	HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3274 
3275 	if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) {
3276 		size = adapter->fix_rx_ampdu_size;
3277 		goto exit;
3278 	}
3279 
3280 #ifdef CONFIG_BT_COEXIST
3281 	if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3282 		size = rtw_btcoex_GetAMPDUSize(adapter);
3283 		goto exit;
3284 	}
3285 #endif
3286 
3287 	/* for scan */
3288 	if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3289 		&& !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3290 		&& adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3291 	) {
3292 		size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3293 		goto exit;
3294 	}
3295 
3296 	/* default value based on max_rx_ampdu_factor */
3297 	if (adapter->driver_rx_ampdu_factor != 0xFF)
3298 		max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3299 	else
3300 		rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3301 
3302 	if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3303 		size = 64;
3304 	else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3305 		size = 32;
3306 	else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3307 		size = 16;
3308 	else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3309 		size = 8;
3310 	else
3311 		size = 64;
3312 
3313 exit:
3314 
3315 	if (size > 127)
3316 		size = 127;
3317 
3318 	return size;
3319 }
3320 
3321 /**
3322  * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3323  * @adapter: the adapter to get the permission if RX AMPDU should be set up
3324  *
3325  * Returns: accept or not
3326  */
rtw_rx_ampdu_is_accept(_adapter * adapter)3327 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3328 {
3329 	bool accept;
3330 
3331 	if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3332 		accept = adapter->fix_rx_ampdu_accept;
3333 		goto exit;
3334 	}
3335 
3336 #ifdef CONFIG_BT_COEXIST
3337 	if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3338 		accept = _FALSE;
3339 		goto exit;
3340 	}
3341 #endif
3342 
3343 	/* for scan */
3344 	if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3345 		&& !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3346 		&& adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3347 	) {
3348 		accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3349 		goto exit;
3350 	}
3351 
3352 	/* default value for other cases */
3353 	accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3354 
3355 exit:
3356 	return accept;
3357 }
3358 
3359 /**
3360  * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3361  * @adapter: the adapter to set target RX AMPDU buffer size
3362  * @size: the target RX AMPDU buffer size to set
3363  * @reason: reason for the target RX AMPDU buffer size setting
3364  *
3365  * Returns: whether the target RX AMPDU buffer size is changed
3366  */
rtw_rx_ampdu_set_size(_adapter * adapter,u8 size,u8 reason)3367 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3368 {
3369 	bool is_adj = _FALSE;
3370 	struct mlme_ext_priv *mlmeext;
3371 	struct mlme_ext_info *mlmeinfo;
3372 
3373 	mlmeext = &adapter->mlmeextpriv;
3374 	mlmeinfo = &mlmeext->mlmext_info;
3375 
3376 	if (reason == RX_AMPDU_DRV_FIXED) {
3377 		if (adapter->fix_rx_ampdu_size != size) {
3378 			adapter->fix_rx_ampdu_size = size;
3379 			is_adj = _TRUE;
3380 			DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3381 		}
3382 	} else if (reason == RX_AMPDU_DRV_SCAN) {
3383 		struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3384 
3385 		if (ss->rx_ampdu_size != size) {
3386 			ss->rx_ampdu_size = size;
3387 			is_adj = _TRUE;
3388 			DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3389 		}
3390 	}
3391 
3392 	return is_adj;
3393 }
3394 
3395 /**
3396  * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3397  * @adapter: the adapter to set if RX AMPDU should be set up
3398  * @accept: if RX AMPDU should be set up
3399  * @reason: reason for the permission if RX AMPDU should be set up
3400  *
3401  * Returns: whether the permission if RX AMPDU should be set up is changed
3402  */
rtw_rx_ampdu_set_accept(_adapter * adapter,u8 accept,u8 reason)3403 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3404 {
3405 	bool is_adj = _FALSE;
3406 	struct mlme_ext_priv *mlmeext;
3407 	struct mlme_ext_info *mlmeinfo;
3408 
3409 	mlmeext = &adapter->mlmeextpriv;
3410 	mlmeinfo = &mlmeext->mlmext_info;
3411 
3412 	if (reason == RX_AMPDU_DRV_FIXED) {
3413 		if (adapter->fix_rx_ampdu_accept != accept) {
3414 			adapter->fix_rx_ampdu_accept = accept;
3415 			is_adj = _TRUE;
3416 			DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3417 		}
3418 	} else if (reason == RX_AMPDU_DRV_SCAN) {
3419 		if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3420 			adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3421 			is_adj = _TRUE;
3422 			DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3423 		}
3424 	}
3425 
3426 	return is_adj;
3427 }
3428 
3429 /**
3430  * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3431  * @adapter: the adapter to which @sta belongs
3432  * @sta: the sta to be checked
3433  * @tid: the tid to be checked
3434  * @accept: the target permission if RX AMPDU should be set up
3435  * @size: the target RX AMPDU buffer size
3436  *
3437  * Returns:
3438  * 0: no canceled
3439  * 1: canceled by no permission
3440  * 2: canceled by different buffer size
3441  * 3: canceled by potential mismatched status
3442  *
3443  * Blocking function, may sleep
3444  */
rx_ampdu_apply_sta_tid(_adapter * adapter,struct sta_info * sta,u8 tid,u8 accept,u8 size)3445 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3446 {
3447 	u8 ret = 0;
3448 	struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3449 
3450 	if (reorder_ctl->enable == _FALSE) {
3451 		if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3452 			send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3453 			ret = 3;
3454 		}
3455 		goto exit;
3456 	}
3457 
3458 	if (accept == _FALSE) {
3459 		send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3460 		ret = 1;
3461 	} else if (reorder_ctl->ampdu_size != size) {
3462 		send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3463 		ret = 2;
3464 	}
3465 
3466 exit:
3467 	return ret;
3468 }
3469 
3470 /**
3471  * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3472  * @adapter: the adapter to which @sta belongs
3473  * @sta: the sta to be checked
3474  * @accept: the target permission if RX AMPDU should be set up
3475  * @size: the target RX AMPDU buffer size
3476  *
3477  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3478  *
3479  * Blocking function, may sleep
3480  */
rx_ampdu_apply_sta(_adapter * adapter,struct sta_info * sta,u8 accept,u8 size)3481 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3482 {
3483 	u8 change_cnt = 0;
3484 	int i;
3485 
3486 	for (i = 0; i < TID_NUM; i++) {
3487 		if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3488 			change_cnt++;
3489 	}
3490 
3491 	return change_cnt;
3492 }
3493 
3494 /**
3495  * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3496  * @adapter: the adapter to be applied
3497  *
3498  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3499  */
rtw_rx_ampdu_apply(_adapter * adapter)3500 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3501 {
3502 	u16 adj_cnt = 0;
3503 	struct mlme_ext_priv *mlmeext;
3504 	struct sta_info *sta;
3505 	u8 accept = rtw_rx_ampdu_is_accept(adapter);
3506 	u8 size = rtw_rx_ampdu_size(adapter);
3507 
3508 	mlmeext = &adapter->mlmeextpriv;
3509 
3510 	if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3511 		sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3512 		if (sta)
3513 			adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3514 	}
3515 #ifdef CONFIG_AP_MODE
3516 	else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3517 		_irqL irqL;
3518 		_list *phead, *plist;
3519 		u8 peer_num = 0;
3520 		char peers[NUM_STA];
3521 		struct sta_priv *pstapriv = &adapter->stapriv;
3522 		int i;
3523 
3524 		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3525 
3526 		phead = &pstapriv->asoc_list;
3527 		plist = get_next(phead);
3528 
3529 		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3530 			int stainfo_offset;
3531 
3532 			sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3533 			plist = get_next(plist);
3534 
3535 			stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3536 			if (stainfo_offset_valid(stainfo_offset))
3537 				peers[peer_num++] = stainfo_offset;
3538 		}
3539 
3540 		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3541 
3542 		for (i = 0; i < peer_num; i++) {
3543 			sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3544 			if (sta)
3545 				adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3546 		}
3547 	}
3548 #endif /*CONFIG_AP_MODE*/
3549 	return adj_cnt;
3550 }
3551 
OnAction_back(_adapter * padapter,union recv_frame * precv_frame)3552 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3553 {
3554 	u8 *addr;
3555 	struct sta_info *psta=NULL;
3556 	struct recv_reorder_ctrl *preorder_ctrl;
3557 	unsigned char		*frame_body;
3558 	unsigned char		category, action;
3559 	unsigned short	tid, status, reason_code = 0;
3560 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3561 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3562 	u8 *pframe = precv_frame->u.hdr.rx_data;
3563 	struct sta_priv *pstapriv = &padapter->stapriv;
3564 #ifdef CONFIG_80211N_HT
3565 
3566 	DBG_871X("%s\n", __FUNCTION__);
3567 
3568 	//check RA matches or not
3569 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3570 		return _SUCCESS;
3571 
3572 /*
3573 	//check A1 matches or not
3574 	if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3575 		return _SUCCESS;
3576 */
3577 
3578 	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3579 		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3580 			return _SUCCESS;
3581 
3582 	addr = GetAddr2Ptr(pframe);
3583 	psta = rtw_get_stainfo(pstapriv, addr);
3584 
3585 	if(psta==NULL)
3586 		return _SUCCESS;
3587 
3588 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3589 
3590 	category = frame_body[0];
3591 	if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
3592 	{
3593 #ifdef CONFIG_TDLS
3594 		if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3595 			(psta->htpriv.ht_option==_TRUE) &&
3596 			(psta->htpriv.ampdu_enable==_TRUE))
3597 		{
3598 			DBG_871X("Recv [%s] from direc link\n", __FUNCTION__);
3599 		}
3600 		else
3601 #endif //CONFIG_TDLS
3602 		if (!pmlmeinfo->HT_enable)
3603 		{
3604 			return _SUCCESS;
3605 		}
3606 
3607 		action = frame_body[1];
3608 		DBG_871X("%s, action=%d\n", __FUNCTION__, action);
3609 		switch (action)
3610 		{
3611 			case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
3612 
3613 				_rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3614 				//process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
3615 				process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
3616 
3617 				break;
3618 
3619 			case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
3620 
3621 				//status = frame_body[3] | (frame_body[4] << 8); //endian issue
3622 				status = RTW_GET_LE16(&frame_body[3]);
3623 				tid = ((frame_body[5] >> 2) & 0x7);
3624 
3625 				if (status == 0)
3626 				{	//successful
3627 					DBG_871X("agg_enable for TID=%d\n", tid);
3628 					psta->htpriv.agg_enable_bitmap |= 1 << tid;
3629 					psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3630 				}
3631 				else
3632 				{
3633 					psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3634 				}
3635 #ifdef CONFIG_AP_MODE
3636 				if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3637 				{
3638 					DBG_871X("%s alive check - rx ADDBA response\n", __func__);
3639 					psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3640 					psta->expire_to = pstapriv->expire_to;
3641 					psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3642 				}
3643 #endif
3644 				//DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
3645 				break;
3646 
3647 			case RTW_WLAN_ACTION_DELBA: //DELBA
3648 				if ((frame_body[3] & BIT(3)) == 0)
3649 				{
3650 					psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3651 					psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3652 
3653 					//reason_code = frame_body[4] | (frame_body[5] << 8);
3654 					reason_code = RTW_GET_LE16(&frame_body[4]);
3655 				}
3656 				else if((frame_body[3] & BIT(3)) == BIT(3))
3657 				{
3658 					tid = (frame_body[3] >> 4) & 0x0F;
3659 
3660 					preorder_ctrl = &psta->recvreorder_ctrl[tid];
3661 					preorder_ctrl->enable = _FALSE;
3662 					preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3663 				}
3664 
3665 				DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
3666 				//todo: how to notify the host while receiving DELETE BA
3667 				break;
3668 
3669 			default:
3670 				break;
3671 		}
3672 	}
3673 #endif //CONFIG_80211N_HT
3674 	return _SUCCESS;
3675 }
3676 
3677 #ifdef CONFIG_P2P
3678 
get_reg_classes_full_count(struct p2p_channels channel_list)3679 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
3680 	int cnt = 0;
3681 	int i;
3682 
3683 	for (i = 0; i < channel_list.reg_classes; i++) {
3684 		cnt += channel_list.reg_class[i].channels;
3685 	}
3686 
3687 	return cnt;
3688 }
3689 
get_channel_cnt_24g_5gl_5gh(struct mlme_ext_priv * pmlmeext,u8 * p24g_cnt,u8 * p5gl_cnt,u8 * p5gh_cnt)3690 static void get_channel_cnt_24g_5gl_5gh(  struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
3691 {
3692 	int	i = 0;
3693 
3694 	*p24g_cnt = 0;
3695 	*p5gl_cnt = 0;
3696 	*p5gh_cnt = 0;
3697 
3698 	for( i = 0; i < pmlmeext->max_chan_nums; i++ )
3699 	{
3700 		if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
3701 		{
3702 			(*p24g_cnt)++;
3703 		}
3704 		else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
3705 		{
3706 			//	Just include the channel 36, 40, 44, 48 channels for 5G low
3707 			(*p5gl_cnt)++;
3708 		}
3709 		else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
3710 		{
3711 			//	Just include the channel 149, 153, 157, 161 channels for 5G high
3712 			(*p5gh_cnt)++;
3713 		}
3714 	}
3715 }
3716 
issue_p2p_GO_request(_adapter * padapter,u8 * raddr)3717 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
3718 {
3719 
3720 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3721 	u8			action = P2P_PUB_ACTION_ACTION;
3722 	u32			p2poui = cpu_to_be32(P2POUI);
3723 	u8			oui_subtype = P2P_GO_NEGO_REQ;
3724 	u8			wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3725 	u8			wpsielen = 0, p2pielen = 0, i;
3726 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3727 	u16			len_channellist_attr = 0;
3728 #ifdef CONFIG_WFD
3729 	u32					wfdielen = 0;
3730 #endif //CONFIG_WFD
3731 
3732 	struct xmit_frame			*pmgntframe;
3733 	struct pkt_attrib			*pattrib;
3734 	unsigned char					*pframe;
3735 	struct rtw_ieee80211_hdr	*pwlanhdr;
3736 	unsigned short				*fctrl;
3737 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
3738 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
3739 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3740 	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
3741 
3742 
3743 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3744 	{
3745 		return;
3746 	}
3747 
3748 	DBG_871X( "[%s] In\n", __FUNCTION__ );
3749 	//update attribute
3750 	pattrib = &pmgntframe->attrib;
3751 	update_mgntframe_attrib(padapter, pattrib);
3752 
3753 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3754 
3755 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3756 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3757 
3758 	fctrl = &(pwlanhdr->frame_ctl);
3759 	*(fctrl) = 0;
3760 
3761 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3762 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3763 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3764 
3765 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3766 	pmlmeext->mgnt_seq++;
3767 	SetFrameSubType(pframe, WIFI_ACTION);
3768 
3769 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3770 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3771 
3772 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3773 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3774 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3775 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3776 	pwdinfo->negotiation_dialog_token = 1;	//	Initialize the dialog value
3777 	pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3778 
3779 
3780 
3781 	//	WPS Section
3782 	wpsielen = 0;
3783 	//	WPS OUI
3784 	*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3785 	wpsielen += 4;
3786 
3787 	//	WPS version
3788 	//	Type:
3789 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3790 	wpsielen += 2;
3791 
3792 	//	Length:
3793 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3794 	wpsielen += 2;
3795 
3796 	//	Value:
3797 	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
3798 
3799 	//	Device Password ID
3800 	//	Type:
3801 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3802 	wpsielen += 2;
3803 
3804 	//	Length:
3805 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3806 	wpsielen += 2;
3807 
3808 	//	Value:
3809 
3810 	if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
3811 	{
3812 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3813 	}
3814 	else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
3815 	{
3816 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3817 	}
3818 	else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
3819 	{
3820 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3821 	}
3822 
3823 	wpsielen += 2;
3824 
3825 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3826 
3827 
3828 	//	P2P IE Section.
3829 
3830 	//	P2P OUI
3831 	p2pielen = 0;
3832 	p2pie[ p2pielen++ ] = 0x50;
3833 	p2pie[ p2pielen++ ] = 0x6F;
3834 	p2pie[ p2pielen++ ] = 0x9A;
3835 	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
3836 
3837 	//	Commented by Albert 20110306
3838 	//	According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
3839 	//	1. P2P Capability
3840 	//	2. Group Owner Intent
3841 	//	3. Configuration Timeout
3842 	//	4. Listen Channel
3843 	//	5. Extended Listen Timing
3844 	//	6. Intended P2P Interface Address
3845 	//	7. Channel List
3846 	//	8. P2P Device Info
3847 	//	9. Operating Channel
3848 
3849 
3850 	//	P2P Capability
3851 	//	Type:
3852 	p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3853 
3854 	//	Length:
3855 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3856 	p2pielen += 2;
3857 
3858 	//	Value:
3859 	//	Device Capability Bitmap, 1 byte
3860 	p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3861 
3862 	//	Group Capability Bitmap, 1 byte
3863 	if ( pwdinfo->persistent_supported )
3864 	{
3865 		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3866 	}
3867 	else
3868 	{
3869 		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3870 	}
3871 
3872 
3873 	//	Group Owner Intent
3874 	//	Type:
3875 	p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3876 
3877 	//	Length:
3878 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3879 	p2pielen += 2;
3880 
3881 	//	Value:
3882 	//	Todo the tie breaker bit.
3883 	p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) &  0xFE );
3884 
3885 	//	Configuration Timeout
3886 	//	Type:
3887 	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3888 
3889 	//	Length:
3890 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3891 	p2pielen += 2;
3892 
3893 	//	Value:
3894 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
3895 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
3896 
3897 
3898 	//	Listen Channel
3899 	//	Type:
3900 	p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
3901 
3902 	//	Length:
3903 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3904 	p2pielen += 2;
3905 
3906 	//	Value:
3907 	//	Country String
3908 	p2pie[ p2pielen++ ] = 'X';
3909 	p2pie[ p2pielen++ ] = 'X';
3910 
3911 	//	The third byte should be set to 0x04.
3912 	//	Described in the "Operating Channel Attribute" section.
3913 	p2pie[ p2pielen++ ] = 0x04;
3914 
3915 	//	Operating Class
3916 	p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
3917 
3918 	//	Channel Number
3919 	p2pie[ p2pielen++ ] = pwdinfo->listen_channel;	//	listening channel number
3920 
3921 
3922 	//	Extended Listen Timing ATTR
3923 	//	Type:
3924 	p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
3925 
3926 	//	Length:
3927 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
3928 	p2pielen += 2;
3929 
3930 	//	Value:
3931 	//	Availability Period
3932 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3933 	p2pielen += 2;
3934 
3935 	//	Availability Interval
3936 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3937 	p2pielen += 2;
3938 
3939 
3940 	//	Intended P2P Interface Address
3941 	//	Type:
3942 	p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
3943 
3944 	//	Length:
3945 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3946 	p2pielen += 2;
3947 
3948 	//	Value:
3949 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
3950 	p2pielen += ETH_ALEN;
3951 
3952 
3953 	//	Channel List
3954 	//	Type:
3955 	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3956 
3957 	// Length:
3958 	// Country String(3)
3959 	// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
3960 	// + number of channels in all classes
3961 	len_channellist_attr = 3
3962 	   + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
3963 	   + get_reg_classes_full_count(pmlmeext->channel_list);
3964 
3965 #ifdef CONFIG_CONCURRENT_MODE
3966 	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3967 	{
3968 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3969 	}
3970 	else
3971 	{
3972 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3973 	}
3974 #else
3975 
3976 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3977 
3978 #endif
3979 	p2pielen += 2;
3980 
3981 	//	Value:
3982 	//	Country String
3983 	p2pie[ p2pielen++ ] = 'X';
3984 	p2pie[ p2pielen++ ] = 'X';
3985 
3986 	//	The third byte should be set to 0x04.
3987 	//	Described in the "Operating Channel Attribute" section.
3988 	p2pie[ p2pielen++ ] = 0x04;
3989 
3990 	//	Channel Entry List
3991 
3992 #ifdef CONFIG_CONCURRENT_MODE
3993 	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3994 	{
3995 		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3996 		struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3997 
3998 		//	Operating Class
3999 		if ( pbuddy_mlmeext->cur_channel > 14 )
4000 		{
4001 			if ( pbuddy_mlmeext->cur_channel >= 149 )
4002 			{
4003 				p2pie[ p2pielen++ ] = 0x7c;
4004 			}
4005 			else
4006 			{
4007 				p2pie[ p2pielen++ ] = 0x73;
4008 			}
4009 		}
4010 		else
4011 		{
4012 			p2pie[ p2pielen++ ] = 0x51;
4013 		}
4014 
4015 		//	Number of Channels
4016 		//	Just support 1 channel and this channel is AP's channel
4017 		p2pie[ p2pielen++ ] = 1;
4018 
4019 		//	Channel List
4020 		p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4021 	}
4022 	else
4023 	{
4024 		int i,j;
4025 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4026 			//	Operating Class
4027 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4028 
4029 			//	Number of Channels
4030 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4031 
4032 			//	Channel List
4033 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4034 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4035 			}
4036 		}
4037 	}
4038 #else // CONFIG_CONCURRENT_MODE
4039 	{
4040 		int i,j;
4041 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4042 			//	Operating Class
4043 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4044 
4045 			//	Number of Channels
4046 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4047 
4048 			//	Channel List
4049 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4050 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4051 			}
4052 		}
4053 	}
4054 #endif // CONFIG_CONCURRENT_MODE
4055 
4056 	//	Device Info
4057 	//	Type:
4058 	p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4059 
4060 	//	Length:
4061 	//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4062 	//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4063 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4064 	p2pielen += 2;
4065 
4066 	//	Value:
4067 	//	P2P Device Address
4068 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4069 	p2pielen += ETH_ALEN;
4070 
4071 	//	Config Method
4072 	//	This field should be big endian. Noted by P2P specification.
4073 
4074 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4075 
4076 	p2pielen += 2;
4077 
4078 	//	Primary Device Type
4079 	//	Category ID
4080 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4081 	p2pielen += 2;
4082 
4083 	//	OUI
4084 	*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4085 	p2pielen += 4;
4086 
4087 	//	Sub Category ID
4088 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4089 	p2pielen += 2;
4090 
4091 	//	Number of Secondary Device Types
4092 	p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
4093 
4094 	//	Device Name
4095 	//	Type:
4096 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4097 	p2pielen += 2;
4098 
4099 	//	Length:
4100 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4101 	p2pielen += 2;
4102 
4103 	//	Value:
4104 	_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4105 	p2pielen += pwdinfo->device_name_len;
4106 
4107 
4108 	//	Operating Channel
4109 	//	Type:
4110 	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4111 
4112 	//	Length:
4113 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4114 	p2pielen += 2;
4115 
4116 	//	Value:
4117 	//	Country String
4118 	p2pie[ p2pielen++ ] = 'X';
4119 	p2pie[ p2pielen++ ] = 'X';
4120 
4121 	//	The third byte should be set to 0x04.
4122 	//	Described in the "Operating Channel Attribute" section.
4123 	p2pie[ p2pielen++ ] = 0x04;
4124 
4125 	//	Operating Class
4126 	if ( pwdinfo->operating_channel <= 14 )
4127 	{
4128 		//	Operating Class
4129 		p2pie[ p2pielen++ ] = 0x51;
4130 	}
4131 	else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4132 	{
4133 		//	Operating Class
4134 		p2pie[ p2pielen++ ] = 0x73;
4135 	}
4136 	else
4137 	{
4138 		//	Operating Class
4139 		p2pie[ p2pielen++ ] = 0x7c;
4140 	}
4141 
4142 	//	Channel Number
4143 	p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
4144 
4145 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4146 
4147 #ifdef CONFIG_WFD
4148 	wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4149 	pframe += wfdielen;
4150 	pattrib->pktlen += wfdielen;
4151 #endif //CONFIG_WFD
4152 
4153 	pattrib->last_txcmdsz = pattrib->pktlen;
4154 
4155 	dump_mgntframe(padapter, pmgntframe);
4156 
4157 	return;
4158 
4159 }
4160 
4161 
issue_p2p_GO_response(_adapter * padapter,u8 * raddr,u8 * frame_body,uint len,u8 result)4162 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
4163 {
4164 
4165 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4166 	u8			action = P2P_PUB_ACTION_ACTION;
4167 	u32			p2poui = cpu_to_be32(P2POUI);
4168 	u8			oui_subtype = P2P_GO_NEGO_RESP;
4169 	u8			wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4170 	u8			p2pielen = 0, i;
4171 	uint			wpsielen = 0;
4172 	u16			wps_devicepassword_id = 0x0000;
4173 	uint			wps_devicepassword_id_len = 0;
4174 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4175 	u16			len_channellist_attr = 0;
4176 
4177 	struct xmit_frame			*pmgntframe;
4178 	struct pkt_attrib			*pattrib;
4179 	unsigned char					*pframe;
4180 	struct rtw_ieee80211_hdr	*pwlanhdr;
4181 	unsigned short				*fctrl;
4182 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
4183 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4184 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4185 	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
4186 
4187 #ifdef CONFIG_WFD
4188 	u32					wfdielen = 0;
4189 #endif //CONFIG_WFD
4190 
4191 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4192 	{
4193 		return;
4194 	}
4195 
4196 	DBG_871X( "[%s] In, result = %d\n", __FUNCTION__,  result );
4197 	//update attribute
4198 	pattrib = &pmgntframe->attrib;
4199 	update_mgntframe_attrib(padapter, pattrib);
4200 
4201 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4202 
4203 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4204 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4205 
4206 	fctrl = &(pwlanhdr->frame_ctl);
4207 	*(fctrl) = 0;
4208 
4209 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4210 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4211 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4212 
4213 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4214 	pmlmeext->mgnt_seq++;
4215 	SetFrameSubType(pframe, WIFI_ACTION);
4216 
4217 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4218 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4219 
4220 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4221 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4222 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4223 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4224 	pwdinfo->negotiation_dialog_token = frame_body[7];	//	The Dialog Token of provisioning discovery request frame.
4225 	pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4226 
4227 	//	Commented by Albert 20110328
4228 	//	Try to get the device password ID from the WPS IE of group negotiation request frame
4229 	//	WiFi Direct test plan 5.1.15
4230 	rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4231 	rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4232 	wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4233 
4234 	_rtw_memset( wpsie, 0x00, 255 );
4235 	wpsielen = 0;
4236 
4237 	//	WPS Section
4238 	wpsielen = 0;
4239 	//	WPS OUI
4240 	*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4241 	wpsielen += 4;
4242 
4243 	//	WPS version
4244 	//	Type:
4245 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4246 	wpsielen += 2;
4247 
4248 	//	Length:
4249 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4250 	wpsielen += 2;
4251 
4252 	//	Value:
4253 	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
4254 
4255 	//	Device Password ID
4256 	//	Type:
4257 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4258 	wpsielen += 2;
4259 
4260 	//	Length:
4261 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4262 	wpsielen += 2;
4263 
4264 	//	Value:
4265 	if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4266 	{
4267 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
4268 	}
4269 	else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4270 	{
4271 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
4272 	}
4273 	else
4274 	{
4275 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
4276 	}
4277 	wpsielen += 2;
4278 
4279 	//	Commented by Kurt 20120113
4280 	//	If some device wants to do p2p handshake without sending prov_disc_req
4281 	//	We have to get peer_req_cm from here.
4282 	if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
4283 	{
4284 		if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4285 		{
4286 			_rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
4287 		}
4288 		else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4289 		{
4290 			_rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
4291 		}
4292 		else
4293 		{
4294 			_rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
4295 		}
4296 	}
4297 
4298 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4299 
4300 
4301 	//	P2P IE Section.
4302 
4303 	//	P2P OUI
4304 	p2pielen = 0;
4305 	p2pie[ p2pielen++ ] = 0x50;
4306 	p2pie[ p2pielen++ ] = 0x6F;
4307 	p2pie[ p2pielen++ ] = 0x9A;
4308 	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
4309 
4310 	//	Commented by Albert 20100908
4311 	//	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
4312 	//	1. Status
4313 	//	2. P2P Capability
4314 	//	3. Group Owner Intent
4315 	//	4. Configuration Timeout
4316 	//	5. Operating Channel
4317 	//	6. Intended P2P Interface Address
4318 	//	7. Channel List
4319 	//	8. Device Info
4320 	//	9. Group ID	( Only GO )
4321 
4322 
4323 	//	ToDo:
4324 
4325 	//	P2P Status
4326 	//	Type:
4327 	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4328 
4329 	//	Length:
4330 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4331 	p2pielen += 2;
4332 
4333 	//	Value:
4334 	p2pie[ p2pielen++ ] = result;
4335 
4336 	//	P2P Capability
4337 	//	Type:
4338 	p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4339 
4340 	//	Length:
4341 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4342 	p2pielen += 2;
4343 
4344 	//	Value:
4345 	//	Device Capability Bitmap, 1 byte
4346 
4347 	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4348 	{
4349 		//	Commented by Albert 2011/03/08
4350 		//	According to the P2P specification
4351 		//	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
4352 		p2pie[ p2pielen++ ] = 0;
4353 	}
4354 	else
4355 	{
4356 		//	Be group owner or meet the error case
4357 		p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4358 	}
4359 
4360 	//	Group Capability Bitmap, 1 byte
4361 	if ( pwdinfo->persistent_supported )
4362 	{
4363 		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4364 	}
4365 	else
4366 	{
4367 		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4368 	}
4369 
4370 	//	Group Owner Intent
4371 	//	Type:
4372 	p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
4373 
4374 	//	Length:
4375 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4376 	p2pielen += 2;
4377 
4378 	//	Value:
4379 	if ( pwdinfo->peer_intent & 0x01 )
4380 	{
4381 		//	Peer's tie breaker bit is 1, our tie breaker bit should be 0
4382 		p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
4383 	}
4384 	else
4385 	{
4386 		//	Peer's tie breaker bit is 0, our tie breaker bit should be 1
4387 		p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
4388 	}
4389 
4390 
4391 	//	Configuration Timeout
4392 	//	Type:
4393 	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4394 
4395 	//	Length:
4396 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4397 	p2pielen += 2;
4398 
4399 	//	Value:
4400 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
4401 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
4402 
4403 	//	Operating Channel
4404 	//	Type:
4405 	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4406 
4407 	//	Length:
4408 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4409 	p2pielen += 2;
4410 
4411 	//	Value:
4412 	//	Country String
4413 	p2pie[ p2pielen++ ] = 'X';
4414 	p2pie[ p2pielen++ ] = 'X';
4415 
4416 	//	The third byte should be set to 0x04.
4417 	//	Described in the "Operating Channel Attribute" section.
4418 	p2pie[ p2pielen++ ] = 0x04;
4419 
4420 	//	Operating Class
4421 	if ( pwdinfo->operating_channel <= 14 )
4422 	{
4423 		//	Operating Class
4424 		p2pie[ p2pielen++ ] = 0x51;
4425 	}
4426 	else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4427 	{
4428 		//	Operating Class
4429 		p2pie[ p2pielen++ ] = 0x73;
4430 	}
4431 	else
4432 	{
4433 		//	Operating Class
4434 		p2pie[ p2pielen++ ] = 0x7c;
4435 	}
4436 
4437 	//	Channel Number
4438 	p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
4439 
4440 	//	Intended P2P Interface Address
4441 	//	Type:
4442 	p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4443 
4444 	//	Length:
4445 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4446 	p2pielen += 2;
4447 
4448 	//	Value:
4449 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4450 	p2pielen += ETH_ALEN;
4451 
4452 	//	Channel List
4453 	//	Type:
4454 	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4455 
4456 	// Country String(3)
4457 	// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4458 	// + number of channels in all classes
4459 	len_channellist_attr = 3
4460 	   + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4461 	   + get_reg_classes_full_count(pmlmeext->channel_list);
4462 
4463 #ifdef CONFIG_CONCURRENT_MODE
4464 	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4465 	{
4466 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4467 	}
4468 	else
4469 	{
4470 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4471 	}
4472 #else
4473 
4474 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4475 
4476  #endif
4477 	p2pielen += 2;
4478 
4479 	//	Value:
4480 	//	Country String
4481 	p2pie[ p2pielen++ ] = 'X';
4482 	p2pie[ p2pielen++ ] = 'X';
4483 
4484 	//	The third byte should be set to 0x04.
4485 	//	Described in the "Operating Channel Attribute" section.
4486 	p2pie[ p2pielen++ ] = 0x04;
4487 
4488 	//	Channel Entry List
4489 
4490 #ifdef CONFIG_CONCURRENT_MODE
4491 	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4492 	{
4493 		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4494 		struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4495 
4496 		//	Operating Class
4497 		if ( pbuddy_mlmeext->cur_channel > 14 )
4498 		{
4499 			if ( pbuddy_mlmeext->cur_channel >= 149 )
4500 			{
4501 				p2pie[ p2pielen++ ] = 0x7c;
4502 			}
4503 			else
4504 			{
4505 				p2pie[ p2pielen++ ] = 0x73;
4506 			}
4507 		}
4508 		else
4509 		{
4510 			p2pie[ p2pielen++ ] = 0x51;
4511 		}
4512 
4513 		//	Number of Channels
4514 		//	Just support 1 channel and this channel is AP's channel
4515 		p2pie[ p2pielen++ ] = 1;
4516 
4517 		//	Channel List
4518 		p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4519 	}
4520 	else
4521 	{
4522 		int i, j;
4523 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4524 			//	Operating Class
4525 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4526 
4527 			//	Number of Channels
4528 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4529 
4530 			//	Channel List
4531 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4532 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4533 			}
4534 		}
4535 	}
4536 #else // CONFIG_CONCURRENT_MODE
4537 	{
4538 		int i, j;
4539 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4540 			//	Operating Class
4541 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4542 
4543 			//	Number of Channels
4544 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4545 
4546 			//	Channel List
4547 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4548 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4549 			}
4550 		}
4551 	}
4552 #endif // CONFIG_CONCURRENT_MODE
4553 
4554 
4555 	//	Device Info
4556 	//	Type:
4557 	p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4558 
4559 	//	Length:
4560 	//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4561 	//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4562 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4563 	p2pielen += 2;
4564 
4565 	//	Value:
4566 	//	P2P Device Address
4567 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4568 	p2pielen += ETH_ALEN;
4569 
4570 	//	Config Method
4571 	//	This field should be big endian. Noted by P2P specification.
4572 
4573 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4574 
4575 	p2pielen += 2;
4576 
4577 	//	Primary Device Type
4578 	//	Category ID
4579 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4580 	p2pielen += 2;
4581 
4582 	//	OUI
4583 	*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4584 	p2pielen += 4;
4585 
4586 	//	Sub Category ID
4587 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4588 	p2pielen += 2;
4589 
4590 	//	Number of Secondary Device Types
4591 	p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
4592 
4593 	//	Device Name
4594 	//	Type:
4595 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4596 	p2pielen += 2;
4597 
4598 	//	Length:
4599 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4600 	p2pielen += 2;
4601 
4602 	//	Value:
4603 	_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4604 	p2pielen += pwdinfo->device_name_len;
4605 
4606 	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4607 	{
4608 		//	Group ID Attribute
4609 		//	Type:
4610 		p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4611 
4612 		//	Length:
4613 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4614 		p2pielen += 2;
4615 
4616 		//	Value:
4617 		//	p2P Device Address
4618 		_rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4619 		p2pielen += ETH_ALEN;
4620 
4621 		//	SSID
4622 		_rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4623 		p2pielen += pwdinfo->nego_ssidlen;
4624 
4625 	}
4626 
4627 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4628 
4629 #ifdef CONFIG_WFD
4630 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4631 	pframe += wfdielen;
4632 	pattrib->pktlen += wfdielen;
4633 #endif //CONFIG_WFD
4634 
4635 	pattrib->last_txcmdsz = pattrib->pktlen;
4636 
4637 	dump_mgntframe(padapter, pmgntframe);
4638 
4639 	return;
4640 
4641 }
4642 
issue_p2p_GO_confirm(_adapter * padapter,u8 * raddr,u8 result)4643 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
4644 {
4645 
4646 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4647 	u8			action = P2P_PUB_ACTION_ACTION;
4648 	u32			p2poui = cpu_to_be32(P2POUI);
4649 	u8			oui_subtype = P2P_GO_NEGO_CONF;
4650 	u8			wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4651 	u8			wpsielen = 0, p2pielen = 0;
4652 
4653 	struct xmit_frame			*pmgntframe;
4654 	struct pkt_attrib			*pattrib;
4655 	unsigned char					*pframe;
4656 	struct rtw_ieee80211_hdr	*pwlanhdr;
4657 	unsigned short				*fctrl;
4658 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
4659 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4660 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4661 	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
4662 #ifdef CONFIG_WFD
4663 	u32					wfdielen = 0;
4664 #endif //CONFIG_WFD
4665 
4666 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4667 	{
4668 		return;
4669 	}
4670 
4671 	DBG_871X( "[%s] In\n", __FUNCTION__ );
4672 	//update attribute
4673 	pattrib = &pmgntframe->attrib;
4674 	update_mgntframe_attrib(padapter, pattrib);
4675 
4676 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4677 
4678 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4679 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4680 
4681 	fctrl = &(pwlanhdr->frame_ctl);
4682 	*(fctrl) = 0;
4683 
4684 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4685 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4686 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4687 
4688 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4689 	pmlmeext->mgnt_seq++;
4690 	SetFrameSubType(pframe, WIFI_ACTION);
4691 
4692 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4693 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4694 
4695 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4696 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4697 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4698 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4699 	pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4700 
4701 
4702 
4703 	//	P2P IE Section.
4704 
4705 	//	P2P OUI
4706 	p2pielen = 0;
4707 	p2pie[ p2pielen++ ] = 0x50;
4708 	p2pie[ p2pielen++ ] = 0x6F;
4709 	p2pie[ p2pielen++ ] = 0x9A;
4710 	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
4711 
4712 	//	Commented by Albert 20110306
4713 	//	According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
4714 	//	1. Status
4715 	//	2. P2P Capability
4716 	//	3. Operating Channel
4717 	//	4. Channel List
4718 	//	5. Group ID	( if this WiFi is GO )
4719 
4720 	//	P2P Status
4721 	//	Type:
4722 	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4723 
4724 	//	Length:
4725 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4726 	p2pielen += 2;
4727 
4728 	//	Value:
4729 	p2pie[ p2pielen++ ] = result;
4730 
4731 	//	P2P Capability
4732 	//	Type:
4733 	p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4734 
4735 	//	Length:
4736 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4737 	p2pielen += 2;
4738 
4739 	//	Value:
4740 	//	Device Capability Bitmap, 1 byte
4741 	p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4742 
4743 	//	Group Capability Bitmap, 1 byte
4744 	if ( pwdinfo->persistent_supported )
4745 	{
4746 		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4747 	}
4748 	else
4749 	{
4750 		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4751 	}
4752 
4753 
4754 	//	Operating Channel
4755 	//	Type:
4756 	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4757 
4758 	//	Length:
4759 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4760 	p2pielen += 2;
4761 
4762 	//	Value:
4763 	//	Country String
4764 	p2pie[ p2pielen++ ] = 'X';
4765 	p2pie[ p2pielen++ ] = 'X';
4766 
4767 	//	The third byte should be set to 0x04.
4768 	//	Described in the "Operating Channel Attribute" section.
4769 	p2pie[ p2pielen++ ] = 0x04;
4770 
4771 
4772 	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4773 	{
4774 		if ( pwdinfo->peer_operating_ch <= 14 )
4775 		{
4776 			//	Operating Class
4777 			p2pie[ p2pielen++ ] = 0x51;
4778 		}
4779 		else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4780 		{
4781 			//	Operating Class
4782 			p2pie[ p2pielen++ ] = 0x73;
4783 		}
4784 		else
4785 		{
4786 			//	Operating Class
4787 			p2pie[ p2pielen++ ] = 0x7c;
4788 		}
4789 
4790 		p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4791 	}
4792 	else
4793 	{
4794 		if ( pwdinfo->operating_channel <= 14 )
4795 		{
4796 			//	Operating Class
4797 			p2pie[ p2pielen++ ] = 0x51;
4798 		}
4799 		else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4800 		{
4801 			//	Operating Class
4802 			p2pie[ p2pielen++ ] = 0x73;
4803 		}
4804 		else
4805 		{
4806 			//	Operating Class
4807 			p2pie[ p2pielen++ ] = 0x7c;
4808 		}
4809 
4810 		//	Channel Number
4811 		p2pie[ p2pielen++ ] = pwdinfo->operating_channel;		//	Use the listen channel as the operating channel
4812 	}
4813 
4814 
4815 	//	Channel List
4816 	//	Type:
4817 	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4818 
4819 	*(u16*) ( p2pie + p2pielen ) = 6;
4820 	p2pielen += 2;
4821 
4822 	//	Country String
4823 	p2pie[ p2pielen++ ] = 'X';
4824 	p2pie[ p2pielen++ ] = 'X';
4825 
4826 	//	The third byte should be set to 0x04.
4827 	//	Described in the "Operating Channel Attribute" section.
4828 	p2pie[ p2pielen++ ] = 0x04;
4829 
4830 	//	Value:
4831 	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4832 	{
4833 		if ( pwdinfo->peer_operating_ch <= 14 )
4834 		{
4835 			//	Operating Class
4836 			p2pie[ p2pielen++ ] = 0x51;
4837 		}
4838 		else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4839 		{
4840 			//	Operating Class
4841 			p2pie[ p2pielen++ ] = 0x73;
4842 		}
4843 		else
4844 		{
4845 			//	Operating Class
4846 			p2pie[ p2pielen++ ] = 0x7c;
4847 		}
4848 		p2pie[ p2pielen++ ] = 1;
4849 		p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4850 	}
4851 	else
4852 	{
4853 		if ( pwdinfo->operating_channel <= 14 )
4854 		{
4855 			//	Operating Class
4856 			p2pie[ p2pielen++ ] = 0x51;
4857 		}
4858 		else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4859 		{
4860 			//	Operating Class
4861 			p2pie[ p2pielen++ ] = 0x73;
4862 		}
4863 		else
4864 		{
4865 			//	Operating Class
4866 			p2pie[ p2pielen++ ] = 0x7c;
4867 		}
4868 
4869 		//	Channel Number
4870 		p2pie[ p2pielen++ ] = 1;
4871 		p2pie[ p2pielen++ ] = pwdinfo->operating_channel;		//	Use the listen channel as the operating channel
4872 	}
4873 
4874 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4875 	{
4876 		//	Group ID Attribute
4877 		//	Type:
4878 		p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4879 
4880 		//	Length:
4881 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4882 		p2pielen += 2;
4883 
4884 		//	Value:
4885 		//	p2P Device Address
4886 		_rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4887 		p2pielen += ETH_ALEN;
4888 
4889 		//	SSID
4890 		_rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4891 		p2pielen += pwdinfo->nego_ssidlen;
4892 	}
4893 
4894 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4895 
4896 #ifdef CONFIG_WFD
4897 	wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4898 	pframe += wfdielen;
4899 	pattrib->pktlen += wfdielen;
4900 #endif //CONFIG_WFD
4901 
4902 	pattrib->last_txcmdsz = pattrib->pktlen;
4903 
4904 	dump_mgntframe(padapter, pmgntframe);
4905 
4906 	return;
4907 
4908 }
4909 
issue_p2p_invitation_request(_adapter * padapter,u8 * raddr)4910 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
4911 {
4912 
4913 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4914 	u8			action = P2P_PUB_ACTION_ACTION;
4915 	u32			p2poui = cpu_to_be32(P2POUI);
4916 	u8			oui_subtype = P2P_INVIT_REQ;
4917 	u8			p2pie[ 255 ] = { 0x00 };
4918 	u8			p2pielen = 0, i;
4919 	u8			dialogToken = 3;
4920 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4921 	u16			len_channellist_attr = 0;
4922 #ifdef CONFIG_WFD
4923 	u32					wfdielen = 0;
4924 #endif //CONFIG_WFD
4925 #ifdef CONFIG_CONCURRENT_MODE
4926 	_adapter				*pbuddy_adapter = padapter->pbuddy_adapter;
4927 	struct wifidirect_info	*pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4928 	struct mlme_priv		*pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4929 	struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4930 #endif
4931 
4932 	struct xmit_frame			*pmgntframe;
4933 	struct pkt_attrib			*pattrib;
4934 	unsigned char					*pframe;
4935 	struct rtw_ieee80211_hdr	*pwlanhdr;
4936 	unsigned short				*fctrl;
4937 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
4938 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4939 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4940 	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
4941 
4942 
4943 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4944 	{
4945 		return;
4946 	}
4947 
4948 	//update attribute
4949 	pattrib = &pmgntframe->attrib;
4950 	update_mgntframe_attrib(padapter, pattrib);
4951 
4952 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4953 
4954 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4955 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4956 
4957 	fctrl = &(pwlanhdr->frame_ctl);
4958 	*(fctrl) = 0;
4959 
4960 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4961 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4962 	_rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
4963 
4964 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4965 	pmlmeext->mgnt_seq++;
4966 	SetFrameSubType(pframe, WIFI_ACTION);
4967 
4968 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4969 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4970 
4971 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4972 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4973 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4974 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4975 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4976 
4977 	//	P2P IE Section.
4978 
4979 	//	P2P OUI
4980 	p2pielen = 0;
4981 	p2pie[ p2pielen++ ] = 0x50;
4982 	p2pie[ p2pielen++ ] = 0x6F;
4983 	p2pie[ p2pielen++ ] = 0x9A;
4984 	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
4985 
4986 	//	Commented by Albert 20101011
4987 	//	According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
4988 	//	1. Configuration Timeout
4989 	//	2. Invitation Flags
4990 	//	3. Operating Channel	( Only GO )
4991 	//	4. P2P Group BSSID	( Should be included if I am the GO )
4992 	//	5. Channel List
4993 	//	6. P2P Group ID
4994 	//	7. P2P Device Info
4995 
4996 	//	Configuration Timeout
4997 	//	Type:
4998 	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4999 
5000 	//	Length:
5001 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5002 	p2pielen += 2;
5003 
5004 	//	Value:
5005 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
5006 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
5007 
5008 	//	Invitation Flags
5009 	//	Type:
5010 	p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
5011 
5012 	//	Length:
5013 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5014 	p2pielen += 2;
5015 
5016 	//	Value:
5017 	p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
5018 
5019 
5020 	//	Operating Channel
5021 	//	Type:
5022 	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5023 
5024 	//	Length:
5025 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5026 	p2pielen += 2;
5027 
5028 	//	Value:
5029 	//	Country String
5030 	p2pie[ p2pielen++ ] = 'X';
5031 	p2pie[ p2pielen++ ] = 'X';
5032 
5033 	//	The third byte should be set to 0x04.
5034 	//	Described in the "Operating Channel Attribute" section.
5035 	p2pie[ p2pielen++ ] = 0x04;
5036 
5037 	//	Operating Class
5038 	if ( pwdinfo->invitereq_info.operating_ch <= 14 )
5039 		p2pie[ p2pielen++ ] = 0x51;
5040 	else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
5041 		p2pie[ p2pielen++ ] = 0x73;
5042 	else
5043 		p2pie[ p2pielen++ ] = 0x7c;
5044 
5045 	//	Channel Number
5046 	p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch;	//	operating channel number
5047 
5048 	if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
5049 	{
5050 		//	P2P Group BSSID
5051 		//	Type:
5052 		p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5053 
5054 		//	Length:
5055 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5056 		p2pielen += 2;
5057 
5058 		//	Value:
5059 		//	P2P Device Address for GO
5060 		_rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5061 		p2pielen += ETH_ALEN;
5062 	}
5063 
5064 	//	Channel List
5065 	//	Type:
5066 	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5067 
5068 
5069 	//	Length:
5070 	// Country String(3)
5071 	// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5072 	// + number of channels in all classes
5073 	len_channellist_attr = 3
5074 	   + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5075 	   + get_reg_classes_full_count(pmlmeext->channel_list);
5076 
5077 #ifdef CONFIG_CONCURRENT_MODE
5078 	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5079 	{
5080 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5081 	}
5082 	else
5083 	{
5084 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5085 	}
5086 #else
5087 
5088 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5089 
5090  #endif
5091 	p2pielen += 2;
5092 
5093 	//	Value:
5094 	//	Country String
5095 	p2pie[ p2pielen++ ] = 'X';
5096 	p2pie[ p2pielen++ ] = 'X';
5097 
5098 	//	The third byte should be set to 0x04.
5099 	//	Described in the "Operating Channel Attribute" section.
5100 	p2pie[ p2pielen++ ] = 0x04;
5101 
5102 	//	Channel Entry List
5103 #ifdef CONFIG_CONCURRENT_MODE
5104 	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5105 	{
5106 		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5107 		struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5108 
5109 		//	Operating Class
5110 		if ( pbuddy_mlmeext->cur_channel > 14 )
5111 		{
5112 			if ( pbuddy_mlmeext->cur_channel >= 149 )
5113 			{
5114 				p2pie[ p2pielen++ ] = 0x7c;
5115 			}
5116 			else
5117 			{
5118 				p2pie[ p2pielen++ ] = 0x73;
5119 			}
5120 		}
5121 		else
5122 		{
5123 			p2pie[ p2pielen++ ] = 0x51;
5124 		}
5125 
5126 		//	Number of Channels
5127 		//	Just support 1 channel and this channel is AP's channel
5128 		p2pie[ p2pielen++ ] = 1;
5129 
5130 		//	Channel List
5131 		p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5132 	}
5133 	else
5134 	{
5135 		int i, j;
5136 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5137 			//	Operating Class
5138 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5139 
5140 			//	Number of Channels
5141 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5142 
5143 			//	Channel List
5144 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5145 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5146 			}
5147 		}
5148 	}
5149 #else // CONFIG_CONCURRENT_MODE
5150 	{
5151 		int i, j;
5152 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5153 			//	Operating Class
5154 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5155 
5156 			//	Number of Channels
5157 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5158 
5159 			//	Channel List
5160 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5161 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5162 			}
5163 		}
5164 	}
5165 #endif // CONFIG_CONCURRENT_MODE
5166 
5167 
5168 	//	P2P Group ID
5169 	//	Type:
5170 	p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
5171 
5172 	//	Length:
5173 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
5174 	p2pielen += 2;
5175 
5176 	//	Value:
5177 	//	P2P Device Address for GO
5178 	_rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5179 	p2pielen += ETH_ALEN;
5180 
5181 	//	SSID
5182 	_rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
5183 	p2pielen += pwdinfo->invitereq_info.ssidlen;
5184 
5185 
5186 	//	Device Info
5187 	//	Type:
5188 	p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
5189 
5190 	//	Length:
5191 	//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
5192 	//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
5193 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
5194 	p2pielen += 2;
5195 
5196 	//	Value:
5197 	//	P2P Device Address
5198 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5199 	p2pielen += ETH_ALEN;
5200 
5201 	//	Config Method
5202 	//	This field should be big endian. Noted by P2P specification.
5203 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
5204 	p2pielen += 2;
5205 
5206 	//	Primary Device Type
5207 	//	Category ID
5208 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5209 	p2pielen += 2;
5210 
5211 	//	OUI
5212 	*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
5213 	p2pielen += 4;
5214 
5215 	//	Sub Category ID
5216 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5217 	p2pielen += 2;
5218 
5219 	//	Number of Secondary Device Types
5220 	p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
5221 
5222 	//	Device Name
5223 	//	Type:
5224 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5225 	p2pielen += 2;
5226 
5227 	//	Length:
5228 	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
5229 	p2pielen += 2;
5230 
5231 	//	Value:
5232 	_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
5233 	p2pielen += pwdinfo->device_name_len;
5234 
5235 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5236 
5237 #ifdef CONFIG_WFD
5238 	wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5239 	pframe += wfdielen;
5240 	pattrib->pktlen += wfdielen;
5241 #endif //CONFIG_WFD
5242 
5243 	pattrib->last_txcmdsz = pattrib->pktlen;
5244 
5245 	dump_mgntframe(padapter, pmgntframe);
5246 
5247 	return;
5248 
5249 }
5250 
issue_p2p_invitation_response(_adapter * padapter,u8 * raddr,u8 dialogToken,u8 status_code)5251 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
5252 {
5253 
5254 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5255 	u8			action = P2P_PUB_ACTION_ACTION;
5256 	u32			p2poui = cpu_to_be32(P2POUI);
5257 	u8			oui_subtype = P2P_INVIT_RESP;
5258 	u8			p2pie[ 255 ] = { 0x00 };
5259 	u8			p2pielen = 0, i;
5260 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5261 	u16			len_channellist_attr = 0;
5262 #ifdef CONFIG_CONCURRENT_MODE
5263 	_adapter				*pbuddy_adapter = padapter->pbuddy_adapter;
5264 	struct wifidirect_info	*pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5265 	struct mlme_priv		*pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5266 	struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5267 #endif
5268 #ifdef CONFIG_WFD
5269 	u32					wfdielen = 0;
5270 #endif //CONFIG_WFD
5271 
5272 	struct xmit_frame			*pmgntframe;
5273 	struct pkt_attrib			*pattrib;
5274 	unsigned char					*pframe;
5275 	struct rtw_ieee80211_hdr	*pwlanhdr;
5276 	unsigned short				*fctrl;
5277 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5278 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5279 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5280 	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
5281 
5282 
5283 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5284 	{
5285 		return;
5286 	}
5287 
5288 	//update attribute
5289 	pattrib = &pmgntframe->attrib;
5290 	update_mgntframe_attrib(padapter, pattrib);
5291 
5292 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5293 
5294 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5295 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5296 
5297 	fctrl = &(pwlanhdr->frame_ctl);
5298 	*(fctrl) = 0;
5299 
5300 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5301 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5302 	_rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
5303 
5304 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5305 	pmlmeext->mgnt_seq++;
5306 	SetFrameSubType(pframe, WIFI_ACTION);
5307 
5308 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5309 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5310 
5311 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5312 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5313 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5314 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5315 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5316 
5317 	//	P2P IE Section.
5318 
5319 	//	P2P OUI
5320 	p2pielen = 0;
5321 	p2pie[ p2pielen++ ] = 0x50;
5322 	p2pie[ p2pielen++ ] = 0x6F;
5323 	p2pie[ p2pielen++ ] = 0x9A;
5324 	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
5325 
5326 	//	Commented by Albert 20101005
5327 	//	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
5328 	//	1. Status
5329 	//	2. Configuration Timeout
5330 	//	3. Operating Channel	( Only GO )
5331 	//	4. P2P Group BSSID	( Only GO )
5332 	//	5. Channel List
5333 
5334 	//	P2P Status
5335 	//	Type:
5336 	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
5337 
5338 	//	Length:
5339 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5340 	p2pielen += 2;
5341 
5342 	//	Value:
5343 	//	When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
5344 	//	Sent the event receiving the P2P Invitation Req frame to DMP UI.
5345 	//	DMP had to compare the MAC address to find out the profile.
5346 	//	So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
5347 	//	If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
5348 	//	to NB to rebuild the persistent group.
5349 	p2pie[ p2pielen++ ] = status_code;
5350 
5351 	//	Configuration Timeout
5352 	//	Type:
5353 	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5354 
5355 	//	Length:
5356 	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5357 	p2pielen += 2;
5358 
5359 	//	Value:
5360 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
5361 	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
5362 
5363 	if( status_code == P2P_STATUS_SUCCESS )
5364 	{
5365 		if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
5366 		{
5367 			//	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
5368 			//	In this case, the P2P Invitation response frame should carry the two more P2P attributes.
5369 			//	First one is operating channel attribute.
5370 			//	Second one is P2P Group BSSID attribute.
5371 
5372 			//	Operating Channel
5373 			//	Type:
5374 			p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5375 
5376 			//	Length:
5377 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5378 			p2pielen += 2;
5379 
5380 			//	Value:
5381 			//	Country String
5382 			p2pie[ p2pielen++ ] = 'X';
5383 			p2pie[ p2pielen++ ] = 'X';
5384 
5385 			//	The third byte should be set to 0x04.
5386 			//	Described in the "Operating Channel Attribute" section.
5387 			p2pie[ p2pielen++ ] = 0x04;
5388 
5389 			//	Operating Class
5390 			p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
5391 
5392 			//	Channel Number
5393 			p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
5394 
5395 
5396 			//	P2P Group BSSID
5397 			//	Type:
5398 			p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5399 
5400 			//	Length:
5401 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5402 			p2pielen += 2;
5403 
5404 			//	Value:
5405 			//	P2P Device Address for GO
5406 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5407 			p2pielen += ETH_ALEN;
5408 
5409 		}
5410 
5411 		//	Channel List
5412 		//	Type:
5413 		p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5414 
5415 		//	Length:
5416 		// Country String(3)
5417 		// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5418 		// + number of channels in all classes
5419 		len_channellist_attr = 3
5420 			+ (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5421 			+ get_reg_classes_full_count(pmlmeext->channel_list);
5422 
5423 #ifdef CONFIG_CONCURRENT_MODE
5424 		if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5425 		{
5426 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5427 		}
5428 		else
5429 		{
5430 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5431 		}
5432 #else
5433 
5434 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5435 
5436 #endif
5437 		p2pielen += 2;
5438 
5439 		//	Value:
5440 		//	Country String
5441 		p2pie[ p2pielen++ ] = 'X';
5442 		p2pie[ p2pielen++ ] = 'X';
5443 
5444 		//	The third byte should be set to 0x04.
5445 		//	Described in the "Operating Channel Attribute" section.
5446 		p2pie[ p2pielen++ ] = 0x04;
5447 
5448 		//	Channel Entry List
5449 #ifdef CONFIG_CONCURRENT_MODE
5450 		if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5451 		{
5452 			_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5453 			struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5454 
5455 			//	Operating Class
5456 			if ( pbuddy_mlmeext->cur_channel > 14 )
5457 			{
5458 				if ( pbuddy_mlmeext->cur_channel >= 149 )
5459 				{
5460 					p2pie[ p2pielen++ ] = 0x7c;
5461 				}
5462 				else
5463 				{
5464 					p2pie[ p2pielen++ ] = 0x73;
5465 				}
5466 			}
5467 			else
5468 			{
5469 				p2pie[ p2pielen++ ] = 0x51;
5470 			}
5471 
5472 			//	Number of Channels
5473 			//	Just support 1 channel and this channel is AP's channel
5474 			p2pie[ p2pielen++ ] = 1;
5475 
5476 			//	Channel List
5477 			p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5478 		}
5479 		else
5480 		{
5481 			int i, j;
5482 			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5483 				//	Operating Class
5484 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5485 
5486 				//	Number of Channels
5487 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5488 
5489 				//	Channel List
5490 				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5491 					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5492 				}
5493 			}
5494 		}
5495 #else // CONFIG_CONCURRENT_MODE
5496 		{
5497 			int i, j;
5498 			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5499 				//	Operating Class
5500 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5501 
5502 				//	Number of Channels
5503 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5504 
5505 				//	Channel List
5506 				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5507 					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5508 				}
5509 			}
5510 		}
5511 #endif // CONFIG_CONCURRENT_MODE
5512 	}
5513 
5514 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5515 
5516 #ifdef CONFIG_WFD
5517 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5518 	pframe += wfdielen;
5519 	pattrib->pktlen += wfdielen;
5520 #endif //CONFIG_WFD
5521 
5522 	pattrib->last_txcmdsz = pattrib->pktlen;
5523 
5524 	dump_mgntframe(padapter, pmgntframe);
5525 
5526 	return;
5527 
5528 }
5529 
issue_p2p_provision_request(_adapter * padapter,u8 * pssid,u8 ussidlen,u8 * pdev_raddr)5530 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
5531 {
5532 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5533 	u8			action = P2P_PUB_ACTION_ACTION;
5534 	u8			dialogToken = 1;
5535 	u32			p2poui = cpu_to_be32(P2POUI);
5536 	u8			oui_subtype = P2P_PROVISION_DISC_REQ;
5537 	u8			wpsie[ 100 ] = { 0x00 };
5538 	u8			wpsielen = 0;
5539 	u32			p2pielen = 0;
5540 #ifdef CONFIG_WFD
5541 	u32					wfdielen = 0;
5542 #endif //CONFIG_WFD
5543 
5544 	struct xmit_frame			*pmgntframe;
5545 	struct pkt_attrib			*pattrib;
5546 	unsigned char					*pframe;
5547 	struct rtw_ieee80211_hdr	*pwlanhdr;
5548 	unsigned short				*fctrl;
5549 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5550 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5551 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5552 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5553 
5554 
5555 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5556 	{
5557 		return;
5558 	}
5559 
5560 	DBG_871X( "[%s] In\n", __FUNCTION__ );
5561 	//update attribute
5562 	pattrib = &pmgntframe->attrib;
5563 	update_mgntframe_attrib(padapter, pattrib);
5564 
5565 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5566 
5567 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5568 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5569 
5570 	fctrl = &(pwlanhdr->frame_ctl);
5571 	*(fctrl) = 0;
5572 
5573 	_rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5574 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5575 	_rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5576 
5577 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5578 	pmlmeext->mgnt_seq++;
5579 	SetFrameSubType(pframe, WIFI_ACTION);
5580 
5581 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5582 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5583 
5584 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5585 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5586 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5587 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5588 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5589 
5590 	p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
5591 
5592 	pframe += p2pielen;
5593 	pattrib->pktlen += p2pielen;
5594 
5595 	wpsielen = 0;
5596 	//	WPS OUI
5597 	*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5598 	wpsielen += 4;
5599 
5600 	//	WPS version
5601 	//	Type:
5602 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5603 	wpsielen += 2;
5604 
5605 	//	Length:
5606 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5607 	wpsielen += 2;
5608 
5609 	//	Value:
5610 	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
5611 
5612 	//	Config Method
5613 	//	Type:
5614 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5615 	wpsielen += 2;
5616 
5617 	//	Length:
5618 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5619 	wpsielen += 2;
5620 
5621 	//	Value:
5622 	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
5623 	wpsielen += 2;
5624 
5625 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5626 
5627 
5628 #ifdef CONFIG_WFD
5629 	wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5630 	pframe += wfdielen;
5631 	pattrib->pktlen += wfdielen;
5632 #endif //CONFIG_WFD
5633 
5634 	pattrib->last_txcmdsz = pattrib->pktlen;
5635 
5636 	dump_mgntframe(padapter, pmgntframe);
5637 
5638 	return;
5639 
5640 }
5641 
5642 
is_matched_in_profilelist(u8 * peermacaddr,struct profile_info * profileinfo)5643 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
5644 {
5645 	u8 i, match_result = 0;
5646 
5647 	DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5648 	  	    peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
5649 
5650 	for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
5651 	{
5652 	       DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5653 		   	    profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
5654 		if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
5655 		{
5656 			match_result = 1;
5657 			DBG_871X( "[%s] Match!\n", __FUNCTION__ );
5658 			break;
5659 		}
5660 	}
5661 
5662 	return (match_result );
5663 }
5664 
issue_probersp_p2p(_adapter * padapter,unsigned char * da)5665 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5666 {
5667 	struct xmit_frame			*pmgntframe;
5668 	struct pkt_attrib			*pattrib;
5669 	unsigned char					*pframe;
5670 	struct rtw_ieee80211_hdr	*pwlanhdr;
5671 	unsigned short				*fctrl;
5672 	unsigned char					*mac;
5673 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
5674 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5675 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5676 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5677 	//WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
5678 	u16					beacon_interval = 100;
5679 	u16					capInfo = 0;
5680 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5681 	u8					wpsie[255] = { 0x00 };
5682 	u32					wpsielen = 0, p2pielen = 0;
5683 #ifdef CONFIG_WFD
5684 	u32					wfdielen = 0;
5685 #endif //CONFIG_WFD
5686 #ifdef CONFIG_INTEL_WIDI
5687 	u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5688 #endif //CONFIG_INTEL_WIDI
5689 
5690 	//DBG_871X("%s\n", __FUNCTION__);
5691 
5692 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5693 	{
5694 		return;
5695 	}
5696 
5697 	//update attribute
5698 	pattrib = &pmgntframe->attrib;
5699 	update_mgntframe_attrib(padapter, pattrib);
5700 
5701 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5702 
5703 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5704 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5705 
5706 	mac = adapter_mac_addr(padapter);
5707 
5708 	fctrl = &(pwlanhdr->frame_ctl);
5709 	*(fctrl) = 0;
5710 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5711 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5712 
5713 	//	Use the device address for BSSID field.
5714 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5715 
5716 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5717 	pmlmeext->mgnt_seq++;
5718 	SetFrameSubType(fctrl, WIFI_PROBERSP);
5719 
5720 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5721 	pattrib->pktlen = pattrib->hdrlen;
5722 	pframe += pattrib->hdrlen;
5723 
5724 	//timestamp will be inserted by hardware
5725 	pframe += 8;
5726 	pattrib->pktlen += 8;
5727 
5728 	// beacon interval: 2 bytes
5729 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5730 	pframe += 2;
5731 	pattrib->pktlen += 2;
5732 
5733 	//	capability info: 2 bytes
5734 	//	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
5735 	capInfo |= cap_ShortPremble;
5736 	capInfo |= cap_ShortSlot;
5737 
5738 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5739 	pframe += 2;
5740 	pattrib->pktlen += 2;
5741 
5742 
5743 	// SSID
5744 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5745 
5746 	// supported rates...
5747 	//	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5748 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5749 
5750 	// DS parameter set
5751 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5752 
5753 #ifdef CONFIG_IOCTL_CFG80211
5754 	if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5755 	{
5756 		if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
5757 		{
5758 			//WPS IE
5759 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5760 			pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5761 			pframe += pmlmepriv->wps_probe_resp_ie_len;
5762 
5763 			//P2P IE
5764 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5765 			pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5766 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
5767 		}
5768 	}
5769 	else
5770 #endif //CONFIG_IOCTL_CFG80211
5771 	{
5772 
5773 		//	Todo: WPS IE
5774 		//	Noted by Albert 20100907
5775 		//	According to the WPS specification, all the WPS attribute is presented by Big Endian.
5776 
5777 		wpsielen = 0;
5778 		//	WPS OUI
5779 		*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5780 		wpsielen += 4;
5781 
5782 		//	WPS version
5783 		//	Type:
5784 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5785 		wpsielen += 2;
5786 
5787 		//	Length:
5788 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5789 		wpsielen += 2;
5790 
5791 		//	Value:
5792 		wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
5793 
5794 #ifdef CONFIG_INTEL_WIDI
5795 		//	Commented by Kurt
5796 		//	Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
5797 		if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5798 			|| pmlmepriv->num_p2p_sdt != 0 )
5799 		{
5800 			//Sec dev type
5801 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
5802 			wpsielen += 2;
5803 
5804 			//	Length:
5805 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5806 			wpsielen += 2;
5807 
5808 			//	Value:
5809 			//	Category ID
5810 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
5811 			wpsielen += 2;
5812 
5813 			//	OUI
5814 			*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
5815 			wpsielen += 4;
5816 
5817 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
5818 			wpsielen += 2;
5819 
5820 			if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
5821 			{
5822 				//	Vendor Extension
5823 				_rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
5824 				wpsielen += L2SDTA_SERVICE_VE_LEN;
5825 			}
5826 		}
5827 #endif //CONFIG_INTEL_WIDI
5828 
5829 		//	WiFi Simple Config State
5830 		//	Type:
5831 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
5832 		wpsielen += 2;
5833 
5834 		//	Length:
5835 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5836 		wpsielen += 2;
5837 
5838 		//	Value:
5839 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	//	Not Configured.
5840 
5841 		//	Response Type
5842 		//	Type:
5843 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
5844 		wpsielen += 2;
5845 
5846 		//	Length:
5847 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5848 		wpsielen += 2;
5849 
5850 		//	Value:
5851 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5852 
5853 		//	UUID-E
5854 		//	Type:
5855 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5856 		wpsielen += 2;
5857 
5858 		//	Length:
5859 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5860 		wpsielen += 2;
5861 
5862 		//	Value:
5863 		if (pwdinfo->external_uuid == 0) {
5864 			_rtw_memset( wpsie + wpsielen, 0x0, 16 );
5865 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5866 		} else {
5867 			_rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5868 		}
5869 		wpsielen += 0x10;
5870 
5871 		//	Manufacturer
5872 		//	Type:
5873 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
5874 		wpsielen += 2;
5875 
5876 		//	Length:
5877 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
5878 		wpsielen += 2;
5879 
5880 		//	Value:
5881 		_rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
5882 		wpsielen += 7;
5883 
5884 		//	Model Name
5885 		//	Type:
5886 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
5887 		wpsielen += 2;
5888 
5889 		//	Length:
5890 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
5891 		wpsielen += 2;
5892 
5893 		//	Value:
5894 		_rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
5895 		wpsielen += 6;
5896 
5897 		//	Model Number
5898 		//	Type:
5899 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
5900 		wpsielen += 2;
5901 
5902 		//	Length:
5903 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5904 		wpsielen += 2;
5905 
5906 		//	Value:
5907 		wpsie[ wpsielen++ ] = 0x31;		//	character 1
5908 
5909 		//	Serial Number
5910 		//	Type:
5911 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
5912 		wpsielen += 2;
5913 
5914 		//	Length:
5915 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
5916 		wpsielen += 2;
5917 
5918 		//	Value:
5919 		_rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
5920 		wpsielen += ETH_ALEN;
5921 
5922 		//	Primary Device Type
5923 		//	Type:
5924 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5925 		wpsielen += 2;
5926 
5927 		//	Length:
5928 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5929 		wpsielen += 2;
5930 
5931 		//	Value:
5932 		//	Category ID
5933 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5934 		wpsielen += 2;
5935 
5936 		//	OUI
5937 		*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
5938 		wpsielen += 4;
5939 
5940 		//	Sub Category ID
5941 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5942 		wpsielen += 2;
5943 
5944 		//	Device Name
5945 		//	Type:
5946 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5947 		wpsielen += 2;
5948 
5949 		//	Length:
5950 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
5951 		wpsielen += 2;
5952 
5953 		//	Value:
5954 		_rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
5955 		wpsielen += pwdinfo->device_name_len;
5956 
5957 		//	Config Method
5958 		//	Type:
5959 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5960 		wpsielen += 2;
5961 
5962 		//	Length:
5963 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5964 		wpsielen += 2;
5965 
5966 		//	Value:
5967 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
5968 		wpsielen += 2;
5969 
5970 
5971 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5972 
5973 
5974 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
5975 		pframe += p2pielen;
5976 		pattrib->pktlen += p2pielen;
5977 	}
5978 
5979 #ifdef CONFIG_WFD
5980 #ifdef CONFIG_IOCTL_CFG80211
5981 	if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
5982 #endif //CONFIG_IOCTL_CFG80211
5983 	{
5984 		wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
5985 		pframe += wfdielen;
5986 		pattrib->pktlen += wfdielen;
5987 	}
5988 #ifdef CONFIG_IOCTL_CFG80211
5989 	else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
5990 	{
5991 		//WFD IE
5992 		_rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
5993 		pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
5994 		pframe += pmlmepriv->wfd_probe_resp_ie_len;
5995 	}
5996 #endif //CONFIG_IOCTL_CFG80211
5997 #endif //CONFIG_WFD
5998 
5999 	pattrib->last_txcmdsz = pattrib->pktlen;
6000 
6001 
6002 	dump_mgntframe(padapter, pmgntframe);
6003 
6004 	return;
6005 
6006 }
6007 
_issue_probereq_p2p(_adapter * padapter,u8 * da,int wait_ack)6008 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6009 {
6010 	int ret = _FAIL;
6011 	struct xmit_frame		*pmgntframe;
6012 	struct pkt_attrib		*pattrib;
6013 	unsigned char			*pframe;
6014 	struct rtw_ieee80211_hdr	*pwlanhdr;
6015 	unsigned short		*fctrl;
6016 	unsigned char			*mac;
6017 	unsigned char			bssrate[NumRates];
6018 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
6019 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6020 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6021 	int	bssrate_len = 0;
6022 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6023 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6024 	u8					wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
6025 	u16					wpsielen = 0, p2pielen = 0;
6026 #ifdef CONFIG_WFD
6027 	u32					wfdielen = 0;
6028 #endif //CONFIG_WFD
6029 
6030 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6031 
6032 
6033 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6034 	{
6035 		goto exit;
6036 	}
6037 
6038 	//update attribute
6039 	pattrib = &pmgntframe->attrib;
6040 	update_mgntframe_attrib(padapter, pattrib);
6041 
6042 
6043 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6044 
6045 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6046 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6047 
6048 	mac = adapter_mac_addr(padapter);
6049 
6050 	fctrl = &(pwlanhdr->frame_ctl);
6051 	*(fctrl) = 0;
6052 
6053 	if (da) {
6054 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6055 		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6056 	} else {
6057 		if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
6058 		{
6059 			//	This two flags will be set when this is only the P2P client mode.
6060 			_rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6061 			_rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6062 		}
6063 		else
6064 		{
6065 			//	broadcast probe request frame
6066 			_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6067 			_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6068 		}
6069 	}
6070 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6071 
6072 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6073 	pmlmeext->mgnt_seq++;
6074 	SetFrameSubType(pframe, WIFI_PROBEREQ);
6075 
6076 	pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6077 	pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6078 
6079 	if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6080 	{
6081 		pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6082 	}
6083 	else
6084 	{
6085 		pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6086 	}
6087 	//	Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
6088 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6089 
6090 #ifdef CONFIG_IOCTL_CFG80211
6091 	if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
6092 	{
6093 		if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
6094 		{
6095 			//WPS IE
6096 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6097 			pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6098 			pframe += pmlmepriv->wps_probe_req_ie_len;
6099 
6100 			//P2P IE
6101 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6102 			pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6103 			pframe += pmlmepriv->p2p_probe_req_ie_len;
6104 		}
6105 	}
6106 	else
6107 #endif //CONFIG_IOCTL_CFG80211
6108 	{
6109 
6110 		//	WPS IE
6111 		//	Noted by Albert 20110221
6112 		//	According to the WPS specification, all the WPS attribute is presented by Big Endian.
6113 
6114 		wpsielen = 0;
6115 		//	WPS OUI
6116 		*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
6117 		wpsielen += 4;
6118 
6119 		//	WPS version
6120 		//	Type:
6121 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
6122 		wpsielen += 2;
6123 
6124 		//	Length:
6125 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
6126 		wpsielen += 2;
6127 
6128 		//	Value:
6129 		wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
6130 
6131 		if( pmlmepriv->wps_probe_req_ie == NULL )
6132 		{
6133 			//	UUID-E
6134 			//	Type:
6135 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
6136 			wpsielen += 2;
6137 
6138 			//	Length:
6139 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
6140 			wpsielen += 2;
6141 
6142 			//	Value:
6143 			if (pwdinfo->external_uuid == 0) {
6144 				_rtw_memset( wpsie + wpsielen, 0x0, 16 );
6145 				_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6146 			} else {
6147 				_rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
6148 			}
6149 			wpsielen += 0x10;
6150 
6151 			//	Config Method
6152 			//	Type:
6153 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6154 			wpsielen += 2;
6155 
6156 			//	Length:
6157 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6158 			wpsielen += 2;
6159 
6160 			//	Value:
6161 			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6162 			wpsielen += 2;
6163 		}
6164 
6165 		//	Device Name
6166 		//	Type:
6167 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6168 		wpsielen += 2;
6169 
6170 		//	Length:
6171 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6172 		wpsielen += 2;
6173 
6174 		//	Value:
6175 		_rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6176 		wpsielen += pwdinfo->device_name_len;
6177 
6178 		//	Primary Device Type
6179 		//	Type:
6180 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6181 		wpsielen += 2;
6182 
6183 		//	Length:
6184 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6185 		wpsielen += 2;
6186 
6187 		//	Value:
6188 		//	Category ID
6189 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
6190 		wpsielen += 2;
6191 
6192 		//	OUI
6193 		*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6194 		wpsielen += 4;
6195 
6196 		//	Sub Category ID
6197 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
6198 		wpsielen += 2;
6199 
6200 		//	Device Password ID
6201 		//	Type:
6202 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
6203 		wpsielen += 2;
6204 
6205 		//	Length:
6206 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6207 		wpsielen += 2;
6208 
6209 		//	Value:
6210 		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );	//	Registrar-specified
6211 		wpsielen += 2;
6212 
6213 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6214 
6215 		//	P2P OUI
6216 		p2pielen = 0;
6217 		p2pie[ p2pielen++ ] = 0x50;
6218 		p2pie[ p2pielen++ ] = 0x6F;
6219 		p2pie[ p2pielen++ ] = 0x9A;
6220 		p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
6221 
6222 		//	Commented by Albert 20110221
6223 		//	According to the P2P Specification, the probe request frame should contain 5 P2P attributes
6224 		//	1. P2P Capability
6225 		//	2. P2P Device ID if this probe request wants to find the specific P2P device
6226 		//	3. Listen Channel
6227 		//	4. Extended Listen Timing
6228 		//	5. Operating Channel if this WiFi is working as the group owner now
6229 
6230 		//	P2P Capability
6231 		//	Type:
6232 		p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
6233 
6234 		//	Length:
6235 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
6236 		p2pielen += 2;
6237 
6238 		//	Value:
6239 		//	Device Capability Bitmap, 1 byte
6240 		p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
6241 
6242 		//	Group Capability Bitmap, 1 byte
6243 		if ( pwdinfo->persistent_supported )
6244 			p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6245 		else
6246 			p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
6247 
6248 		//	Listen Channel
6249 		//	Type:
6250 		p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
6251 
6252 		//	Length:
6253 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6254 		p2pielen += 2;
6255 
6256 		//	Value:
6257 		//	Country String
6258 		p2pie[ p2pielen++ ] = 'X';
6259 		p2pie[ p2pielen++ ] = 'X';
6260 
6261 		//	The third byte should be set to 0x04.
6262 		//	Described in the "Operating Channel Attribute" section.
6263 		p2pie[ p2pielen++ ] = 0x04;
6264 
6265 		//	Operating Class
6266 		p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
6267 
6268 		//	Channel Number
6269 		p2pie[ p2pielen++ ] = pwdinfo->listen_channel;	//	listen channel
6270 
6271 
6272 		//	Extended Listen Timing
6273 		//	Type:
6274 		p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
6275 
6276 		//	Length:
6277 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
6278 		p2pielen += 2;
6279 
6280 		//	Value:
6281 		//	Availability Period
6282 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6283 		p2pielen += 2;
6284 
6285 		//	Availability Interval
6286 		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6287 		p2pielen += 2;
6288 
6289 		if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
6290 		{
6291 			//	Operating Channel (if this WiFi is working as the group owner now)
6292 			//	Type:
6293 			p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
6294 
6295 			//	Length:
6296 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6297 			p2pielen += 2;
6298 
6299 			//	Value:
6300 			//	Country String
6301 			p2pie[ p2pielen++ ] = 'X';
6302 			p2pie[ p2pielen++ ] = 'X';
6303 
6304 			//	The third byte should be set to 0x04.
6305 			//	Described in the "Operating Channel Attribute" section.
6306 			p2pie[ p2pielen++ ] = 0x04;
6307 
6308 			//	Operating Class
6309 			p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
6310 
6311 			//	Channel Number
6312 			p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
6313 
6314 		}
6315 
6316 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
6317 
6318 	}
6319 
6320 #ifdef CONFIG_WFD
6321 #ifdef CONFIG_IOCTL_CFG80211
6322 	if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
6323 #endif
6324 	{
6325 		wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
6326 		pframe += wfdielen;
6327 		pattrib->pktlen += wfdielen;
6328 	}
6329 #ifdef CONFIG_IOCTL_CFG80211
6330 	else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
6331 	{
6332 		//WFD IE
6333 		_rtw_memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
6334 		pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
6335 		pframe += pmlmepriv->wfd_probe_req_ie_len;
6336 	}
6337 #endif //CONFIG_IOCTL_CFG80211
6338 #endif //CONFIG_WFD
6339 
6340 	pattrib->last_txcmdsz = pattrib->pktlen;
6341 
6342 	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6343 
6344 	if (wait_ack) {
6345 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6346 	} else {
6347 		dump_mgntframe(padapter, pmgntframe);
6348 		ret = _SUCCESS;
6349 	}
6350 
6351 exit:
6352 	return ret;
6353 }
6354 
issue_probereq_p2p(_adapter * adapter,u8 * da)6355 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6356 {
6357 	_issue_probereq_p2p(adapter, da, _FALSE);
6358 }
6359 
6360 /*
6361  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6362  * 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
6363  * try_cnt means the maximal TX count to try
6364  */
issue_probereq_p2p_ex(_adapter * adapter,u8 * da,int try_cnt,int wait_ms)6365 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6366 {
6367 	int ret;
6368 	int i = 0;
6369 	u32 start = rtw_get_current_time();
6370 
6371 	do
6372 	{
6373 		ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
6374 
6375 		i++;
6376 
6377 		if (RTW_CANNOT_RUN(adapter))
6378 			break;
6379 
6380 		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6381 			rtw_msleep_os(wait_ms);
6382 
6383 	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6384 
6385 	if (ret != _FAIL) {
6386 		ret = _SUCCESS;
6387 		#ifndef DBG_XMIT_ACK
6388 		goto exit;
6389 		#endif
6390 	}
6391 
6392 	if (try_cnt && wait_ms) {
6393 		if (da)
6394 			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6395 				FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6396 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6397 		else
6398 			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6399 				FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6400 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6401 	}
6402 exit:
6403 	return ret;
6404 }
6405 
6406 #endif //CONFIG_P2P
6407 
rtw_action_public_decache(union recv_frame * recv_frame,s32 token)6408 s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
6409 {
6410 	_adapter *adapter = recv_frame->u.hdr.adapter;
6411 	struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6412 	u8 *frame = recv_frame->u.hdr.rx_data;
6413 	u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
6414 		(recv_frame->u.hdr.attrib.frag_num & 0xf);
6415 
6416 	if (GetRetry(frame)) {
6417 		if (token >= 0) {
6418 			if ((seq_ctrl == mlmeext->action_public_rxseq)
6419 				&& (token == mlmeext->action_public_dialog_token))
6420 			{
6421 				DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6422 					FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6423 				return _FAIL;
6424 			}
6425 		} else {
6426 			if (seq_ctrl == mlmeext->action_public_rxseq) {
6427 				DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
6428 					FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
6429 				return _FAIL;
6430 			}
6431 		}
6432 	}
6433 
6434 	mlmeext->action_public_rxseq = seq_ctrl;
6435 
6436 	if (token >= 0)
6437 		mlmeext->action_public_dialog_token = token;
6438 
6439 	return _SUCCESS;
6440 }
6441 
on_action_public_p2p(union recv_frame * precv_frame)6442 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6443 {
6444 	_adapter *padapter = precv_frame->u.hdr.adapter;
6445 	u8 *pframe = precv_frame->u.hdr.rx_data;
6446 	uint len = precv_frame->u.hdr.len;
6447 	u8 *frame_body;
6448 	u8 dialogToken=0;
6449 #ifdef CONFIG_P2P
6450 	u8 *p2p_ie;
6451 	u32	p2p_ielen, wps_ielen;
6452 	struct	wifidirect_info	*pwdinfo = &( padapter->wdinfo );
6453 	u8	result = P2P_STATUS_SUCCESS;
6454 	u8	empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6455 	u8 *merged_p2pie = NULL;
6456 	u32 merged_p2p_ielen= 0;
6457 #endif //CONFIG_P2P
6458 
6459 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6460 
6461 	dialogToken = frame_body[7];
6462 
6463 	if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
6464 		return _FAIL;
6465 
6466 #ifdef CONFIG_P2P
6467 	_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
6468 #ifdef CONFIG_IOCTL_CFG80211
6469 	if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6470 	{
6471 		rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
6472 	}
6473 	else
6474 #endif //CONFIG_IOCTL_CFG80211
6475 	{
6476 		//	Do nothing if the driver doesn't enable the P2P function.
6477 		if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6478 			return _SUCCESS;
6479 
6480 		len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6481 
6482 		switch( frame_body[ 6 ] )//OUI Subtype
6483 		{
6484 			case P2P_GO_NEGO_REQ:
6485 			{
6486 				DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6487 				_rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
6488 
6489 				if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6490 				{
6491 					rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6492 				}
6493 
6494 				if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6495 				{
6496 					//	Commented by Albert 20110526
6497 					//	In this case, this means the previous nego fail doesn't be reset yet.
6498 					_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6499 					//	Restore the previous p2p state
6500 					rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6501 					DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
6502 				}
6503 #ifdef CONFIG_CONCURRENT_MODE
6504 				if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
6505 				{
6506 					_cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6507 				}
6508 #endif // CONFIG_CONCURRENT_MODE
6509 
6510 				//	Commented by Kurt 20110902
6511 				//Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6512 				if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6513 					rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6514 
6515 				//	Commented by Kurt 20120113
6516 				//	Get peer_dev_addr here if peer doesn't issue prov_disc frame.
6517 				if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
6518 					_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6519 
6520 				result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
6521 				issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
6522 #ifdef CONFIG_INTEL_WIDI
6523 				if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6524 					padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6525 					_cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6526 					intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6527 				}
6528 #endif //CONFIG_INTEL_WIDI
6529 
6530 				//	Commented by Albert 20110718
6531 				//	No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
6532 #ifdef CONFIG_CONCURRENT_MODE
6533 				//	Commented by Albert 20120107
6534 				_set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6535 #else // CONFIG_CONCURRENT_MODE
6536 				_set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6537 #endif // CONFIG_CONCURRENT_MODE
6538 				break;
6539 			}
6540 			case P2P_GO_NEGO_RESP:
6541 			{
6542 				DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6543 
6544 				if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6545 				{
6546 					//	Commented by Albert 20110425
6547 					//	The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
6548 					_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6549 					pwdinfo->nego_req_info.benable = _FALSE;
6550 					result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
6551 					issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
6552 					if ( P2P_STATUS_SUCCESS == result )
6553 					{
6554 						if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6555 						{
6556 							pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6557 							#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6558 							pwdinfo->p2p_info.operation_ch[ 1 ] = 1;	//Check whether GO is operating in channel 1;
6559 							pwdinfo->p2p_info.operation_ch[ 2 ] = 6;	//Check whether GO is operating in channel 6;
6560 							pwdinfo->p2p_info.operation_ch[ 3 ] = 11;	//Check whether GO is operating in channel 11;
6561 							#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6562 							pwdinfo->p2p_info.scan_op_ch_only = 1;
6563 							_set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6564 						}
6565 					}
6566 
6567 					//	Reset the dialog token for group negotiation frames.
6568 					pwdinfo->negotiation_dialog_token = 1;
6569 
6570 					if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6571 					{
6572 						_set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6573 					}
6574 				}
6575 				else
6576 				{
6577 					DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6578 				}
6579 
6580 				break;
6581 			}
6582 			case P2P_GO_NEGO_CONF:
6583 			{
6584 				DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6585 				result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
6586 				if ( P2P_STATUS_SUCCESS == result )
6587 				{
6588 					if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6589 					{
6590 						pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6591 						#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6592 						pwdinfo->p2p_info.operation_ch[ 1 ] = 1;	//Check whether GO is operating in channel 1;
6593 						pwdinfo->p2p_info.operation_ch[ 2 ] = 6;	//Check whether GO is operating in channel 6;
6594 						pwdinfo->p2p_info.operation_ch[ 3 ] = 11;	//Check whether GO is operating in channel 11;
6595 						#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6596 						pwdinfo->p2p_info.scan_op_ch_only = 1;
6597 						_set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6598 					}
6599 				}
6600 				break;
6601 			}
6602 			case P2P_INVIT_REQ:
6603 			{
6604 				//	Added by Albert 2010/10/05
6605 				//	Received the P2P Invite Request frame.
6606 
6607 				DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
6608 				if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6609 				{
6610 					//	Parse the necessary information from the P2P Invitation Request frame.
6611 					//	For example: The MAC address of sending this P2P Invitation Request frame.
6612 					u32	attr_contentlen = 0;
6613 					u8	status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6614 					struct group_id_info group_id;
6615 					u8	invitation_flag = 0;
6616 					int j=0;
6617 
6618 					merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6619 
6620 					merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2);	// 2 is for EID and Length
6621 					if (merged_p2pie == NULL)
6622 					{
6623 						DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
6624 						goto exit;
6625 					}
6626 					_rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
6627 
6628 					merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6629 
6630 					rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6631 					if ( attr_contentlen )
6632 					{
6633 
6634 						rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6635 						//	Commented by Albert 20120510
6636 						//	Copy to the pwdinfo->p2p_peer_interface_addr.
6637 						//	So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
6638 						//	#> iwpriv wlan0 p2p_get peer_ifa
6639 						//	After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
6640 
6641 						if ( attr_contentlen )
6642 						{
6643 							DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6644 									pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6645 									pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6646 									pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
6647 						}
6648 
6649 						if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
6650 						{
6651 							//	Re-invoke the persistent group.
6652 
6653 							_rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6654 							rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6655 							if ( attr_contentlen )
6656 							{
6657 								if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6658 								{
6659 									//	The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
6660 									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
6661 									rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
6662 									status_code = P2P_STATUS_SUCCESS;
6663 								}
6664 								else
6665 								{
6666 									//	The p2p device sending this p2p invitation request wants to be the persistent GO.
6667 									if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
6668 									{
6669 										u8 operatingch_info[5] = { 0x00 };
6670 										if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
6671 										{
6672 											if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
6673 											{
6674 												//	The operating channel is acceptable for this device.
6675 												pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
6676 												#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6677 												pwdinfo->rx_invitereq_info.operation_ch[1]= 1;		//Check whether GO is operating in channel 1;
6678 												pwdinfo->rx_invitereq_info.operation_ch[2]= 6;		//Check whether GO is operating in channel 6;
6679 												pwdinfo->rx_invitereq_info.operation_ch[3]= 11;		//Check whether GO is operating in channel 11;
6680 												#endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6681 												pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6682 												_set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
6683 												rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6684 												rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6685 												status_code = P2P_STATUS_SUCCESS;
6686 											}
6687 											else
6688 											{
6689 												//	The operating channel isn't supported by this device.
6690 												rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6691 												rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
6692 												status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6693 												_set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6694 											}
6695 										}
6696 										else
6697 										{
6698 											//	Commented by Albert 20121130
6699 											//	Intel will use the different P2P IE to store the operating channel information
6700 											//	Workaround for Intel WiDi 3.5
6701 											rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6702 											rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6703 											status_code = P2P_STATUS_SUCCESS;
6704 										}
6705 									}
6706 									else
6707 									{
6708 										rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6709 										#ifdef CONFIG_INTEL_WIDI
6710 										_rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6711 										rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6712 										#endif //CONFIG_INTEL_WIDI
6713 
6714 										status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6715 									}
6716 								}
6717 							}
6718 							else
6719 							{
6720 								DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6721 								status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6722 							}
6723 						}
6724 						else
6725 						{
6726 							//	Received the invitation to join a P2P group.
6727 
6728 							_rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6729 							rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6730 							if ( attr_contentlen )
6731 							{
6732 								if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6733 								{
6734 									//	In this case, the GO can't be myself.
6735 									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6736 									status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6737 								}
6738 								else
6739 								{
6740 									//	The p2p device sending this p2p invitation request wants to join an existing P2P group
6741 									//	Commented by Albert 2012/06/28
6742 									//	In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
6743 									//	The peer device address should be the destination address for the provisioning discovery request.
6744 									//	Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
6745 									//	The peer interface address should be the address for WPS mac address
6746 									_rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6747 									rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6748 									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
6749 									status_code = P2P_STATUS_SUCCESS;
6750 								}
6751 							}
6752 							else
6753 							{
6754 								DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6755 								status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6756 							}
6757 						}
6758 					}
6759 					else
6760 					{
6761 						DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
6762 						status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6763 					}
6764 
6765 					DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
6766 
6767 					pwdinfo->inviteresp_info.token = frame_body[ 7 ];
6768 					issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
6769 					_set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6770 				}
6771 #ifdef CONFIG_INTEL_WIDI
6772 				if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6773 					padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6774 					_cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6775 					intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6776 				}
6777 #endif //CONFIG_INTEL_WIDI
6778 				break;
6779 			}
6780 			case P2P_INVIT_RESP:
6781 			{
6782 				u8	attr_content = 0x00;
6783 				u32	attr_contentlen = 0;
6784 
6785 				DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
6786 				_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6787 				if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6788 				{
6789 					rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6790 
6791 					if ( attr_contentlen == 1 )
6792 					{
6793 						DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
6794 						pwdinfo->invitereq_info.benable = _FALSE;
6795 
6796 						if ( attr_content == P2P_STATUS_SUCCESS )
6797 						{
6798 							if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6799 								rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
6800 							else
6801 								rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6802 
6803 							rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
6804 						}
6805 						else
6806 						{
6807 							rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6808 							rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6809 						}
6810 					}
6811 					else
6812 					{
6813 						rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6814 						rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6815 					}
6816 				}
6817 				else
6818 				{
6819 					rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6820 					rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6821 				}
6822 
6823 				if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
6824 				{
6825 					_set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6826 				}
6827 				break;
6828 			}
6829 			case P2P_DEVDISC_REQ:
6830 
6831 				process_p2p_devdisc_req(pwdinfo, pframe, len);
6832 
6833 				break;
6834 
6835 			case P2P_DEVDISC_RESP:
6836 
6837 				process_p2p_devdisc_resp(pwdinfo, pframe, len);
6838 
6839 				break;
6840 
6841 			case P2P_PROVISION_DISC_REQ:
6842 				DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
6843 				process_p2p_provdisc_req(pwdinfo, pframe, len);
6844 				_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6845 
6846 				//20110902 Kurt
6847 				//Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6848 				if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6849 					rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6850 
6851 				rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6852 				_set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6853 #ifdef CONFIG_INTEL_WIDI
6854 				if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6855 					padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6856 					_cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6857 					intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6858 				}
6859 #endif //CONFIG_INTEL_WIDI
6860 				break;
6861 
6862 			case P2P_PROVISION_DISC_RESP:
6863 				//	Commented by Albert 20110707
6864 				//	Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
6865 				DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
6866 				//	Commented by Albert 20110426
6867 				//	The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
6868 				_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6869 				rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6870 				process_p2p_provdisc_resp(pwdinfo, pframe);
6871 				_set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6872 				break;
6873 
6874 		}
6875 	}
6876 
6877 
6878 exit:
6879 
6880 	if(merged_p2pie)
6881 	{
6882 		rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6883 	}
6884 #endif //CONFIG_P2P
6885 	return _SUCCESS;
6886 }
6887 
on_action_public_vendor(union recv_frame * precv_frame)6888 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6889 {
6890 	unsigned int ret = _FAIL;
6891 	u8 *pframe = precv_frame->u.hdr.rx_data;
6892 	uint frame_len = precv_frame->u.hdr.len;
6893 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6894 
6895 	if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6896 		ret = on_action_public_p2p(precv_frame);
6897 	}
6898 
6899 	return ret;
6900 }
6901 
on_action_public_default(union recv_frame * precv_frame,u8 action)6902 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6903 {
6904 	unsigned int ret = _FAIL;
6905 	u8 *pframe = precv_frame->u.hdr.rx_data;
6906 	uint frame_len = precv_frame->u.hdr.len;
6907 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6908 	u8 token;
6909 	_adapter *adapter = precv_frame->u.hdr.adapter;
6910 	int cnt = 0;
6911 	char msg[64];
6912 
6913 	token = frame_body[2];
6914 
6915 	if (rtw_action_public_decache(precv_frame, token) == _FAIL)
6916 		goto exit;
6917 
6918 	#ifdef CONFIG_IOCTL_CFG80211
6919 	cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
6920 	rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
6921 	#endif
6922 
6923 	ret = _SUCCESS;
6924 
6925 exit:
6926 	return ret;
6927 }
6928 
on_action_public(_adapter * padapter,union recv_frame * precv_frame)6929 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6930 {
6931 	unsigned int ret = _FAIL;
6932 	u8 *pframe = precv_frame->u.hdr.rx_data;
6933 	uint frame_len = precv_frame->u.hdr.len;
6934 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6935 	u8 category, action;
6936 
6937 	/* check RA matches or not */
6938 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6939 		goto exit;
6940 
6941 	category = frame_body[0];
6942 	if (category != RTW_WLAN_CATEGORY_PUBLIC)
6943 		goto exit;
6944 
6945 	action = frame_body[1];
6946 	switch (action) {
6947 	case ACT_PUBLIC_BSSCOEXIST:
6948 #ifdef CONFIG_80211N_HT
6949 #ifdef CONFIG_AP_MODE
6950 		/*20/40 BSS Coexistence Management frame is a Public Action frame*/
6951 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6952 			rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6953 #endif /*CONFIG_AP_MODE*/
6954 #endif /*CONFIG_80211N_HT*/
6955 		break;
6956 	case ACT_PUBLIC_VENDOR:
6957 		ret = on_action_public_vendor(precv_frame);
6958 		break;
6959 	default:
6960 		ret = on_action_public_default(precv_frame, action);
6961 		break;
6962 	}
6963 
6964 exit:
6965 	return ret;
6966 }
6967 
OnAction_ht(_adapter * padapter,union recv_frame * precv_frame)6968 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
6969 {
6970 	u8 *pframe = precv_frame->u.hdr.rx_data;
6971 	uint frame_len = precv_frame->u.hdr.len;
6972 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6973 	u8 category, action;
6974 
6975 	/* check RA matches or not */
6976 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6977 		goto exit;
6978 
6979 	category = frame_body[0];
6980 	if (category != RTW_WLAN_CATEGORY_HT)
6981 		goto exit;
6982 
6983 	action = frame_body[1];
6984 	switch (action) {
6985 	case RTW_WLAN_ACTION_HT_SM_PS:
6986 #ifdef CONFIG_80211N_HT
6987 #ifdef CONFIG_AP_MODE
6988 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6989 			rtw_process_ht_action_smps(padapter, GetAddr2Ptr(pframe), frame_body[2]);
6990 #endif /*CONFIG_AP_MODE*/
6991 #endif /*CONFIG_80211N_HT*/
6992 			break;
6993 	case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
6994 #ifdef CONFIG_BEAMFORMING
6995 		//DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");
6996 		beamforming_get_report_frame(padapter, precv_frame);
6997 #endif //CONFIG_BEAMFORMING
6998 		break;
6999 	default:
7000 		break;
7001 	}
7002 
7003 exit:
7004 
7005 	return _SUCCESS;
7006 }
7007 
7008 #ifdef CONFIG_IEEE80211W
OnAction_sa_query(_adapter * padapter,union recv_frame * precv_frame)7009 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7010 {
7011 	u8 *pframe = precv_frame->u.hdr.rx_data;
7012 	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7013 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7014 	struct sta_info		*psta;
7015 	struct sta_priv		*pstapriv = &padapter->stapriv;
7016 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7017 	u16 tid;
7018 	//Baron
7019 
7020 	DBG_871X("OnAction_sa_query\n");
7021 
7022 	switch (pframe[WLAN_HDR_A3_LEN+1])
7023 	{
7024 		case 0: //SA Query req
7025 			_rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7026 			DBG_871X("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7027 			, pframe[WLAN_HDR_A3_LEN+1], tid, pframe[WLAN_HDR_A3_LEN+2], pframe[WLAN_HDR_A3_LEN+3]);
7028 			issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7029 			break;
7030 
7031 		case 1: //SA Query rsp
7032 			psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
7033 			if (psta != NULL)
7034 				_cancel_timer_ex(&psta->dot11w_expire_timer);
7035 
7036 			_rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7037 			DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], tid);
7038 			break;
7039 		default:
7040 			break;
7041 	}
7042 	if(0)
7043 	{
7044 		int pp;
7045 		printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7046 		for(pp=0;pp< pattrib->pkt_len; pp++)
7047 			printk(" %02x ", pframe[pp]);
7048 		printk("\n");
7049 	}
7050 
7051 	return _SUCCESS;
7052 }
7053 #endif //CONFIG_IEEE80211W
7054 
OnAction_wmm(_adapter * padapter,union recv_frame * precv_frame)7055 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7056 {
7057 	return _SUCCESS;
7058 }
7059 
OnAction_vht(_adapter * padapter,union recv_frame * precv_frame)7060 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7061 {
7062 #ifdef CONFIG_80211AC_VHT
7063 	struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
7064 	u8 *pframe = precv_frame->u.hdr.rx_data;
7065 	uint frame_len = precv_frame->u.hdr.len;
7066 	struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7067 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7068 	u8 category, action;
7069 	struct sta_info *psta = NULL;
7070 
7071 	/* check RA matches or not */
7072 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7073 		goto exit;
7074 
7075 	category = frame_body[0];
7076 	if(category != RTW_WLAN_CATEGORY_VHT)
7077 		goto exit;
7078 
7079 	action = frame_body[1];
7080 	switch (action) {
7081 	case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7082 #ifdef CONFIG_BEAMFORMING
7083 		//DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");
7084 		beamforming_get_report_frame(padapter, precv_frame);
7085 #endif //CONFIG_BEAMFORMING
7086 		break;
7087 	case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7088 		// CategoryCode(1) + ActionCode(1) + OpModeNotification(1)
7089 		//DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n");
7090 		psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7091 		if (psta)
7092 			rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7093 		break;
7094 	default:
7095 		break;
7096 	}
7097 
7098 exit:
7099 #endif //CONFIG_80211AC_VHT
7100 
7101 	return _SUCCESS;
7102 }
7103 
OnAction_p2p(_adapter * padapter,union recv_frame * precv_frame)7104 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7105 {
7106 #ifdef CONFIG_P2P
7107 	u8 *frame_body;
7108 	u8 category, OUI_Subtype, dialogToken=0;
7109 	u8 *pframe = precv_frame->u.hdr.rx_data;
7110 	uint len = precv_frame->u.hdr.len;
7111 	struct	wifidirect_info	*pwdinfo = &( padapter->wdinfo );
7112 
7113 	//check RA matches or not
7114 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7115 		return _SUCCESS;
7116 
7117 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7118 
7119 	category = frame_body[0];
7120 	if(category != RTW_WLAN_CATEGORY_P2P)
7121 		return _SUCCESS;
7122 
7123 	if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
7124 		return _SUCCESS;
7125 
7126 #ifdef CONFIG_IOCTL_CFG80211
7127 	if (adapter_wdev_data(padapter)->p2p_enabled
7128 		&& pwdinfo->driver_interface == DRIVER_CFG80211
7129 		) {
7130 		rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
7131 		return _SUCCESS;
7132 	}
7133 	else
7134 #endif //CONFIG_IOCTL_CFG80211
7135 	{
7136 		len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7137 		OUI_Subtype = frame_body[5];
7138 		dialogToken = frame_body[6];
7139 
7140 		switch(OUI_Subtype)
7141 		{
7142 			case P2P_NOTICE_OF_ABSENCE:
7143 
7144 				break;
7145 
7146 			case P2P_PRESENCE_REQUEST:
7147 
7148 				process_p2p_presence_req(pwdinfo, pframe, len);
7149 
7150 				break;
7151 
7152 			case P2P_PRESENCE_RESPONSE:
7153 
7154 				break;
7155 
7156 			case P2P_GO_DISC_REQUEST:
7157 
7158 				break;
7159 
7160 			default:
7161 				break;
7162 
7163 		}
7164 	}
7165 #endif //CONFIG_P2P
7166 
7167 	return _SUCCESS;
7168 
7169 }
7170 
OnAction(_adapter * padapter,union recv_frame * precv_frame)7171 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7172 {
7173 	int i;
7174 	unsigned char	category;
7175 	struct action_handler *ptable;
7176 	unsigned char	*frame_body;
7177 	u8 *pframe = precv_frame->u.hdr.rx_data;
7178 
7179 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7180 
7181 	category = frame_body[0];
7182 
7183 	for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
7184 	{
7185 		ptable = &OnAction_tbl[i];
7186 
7187 		if(category == ptable->num)
7188 			ptable->func(padapter, precv_frame);
7189 
7190 	}
7191 
7192 	return _SUCCESS;
7193 
7194 }
7195 
DoReserved(_adapter * padapter,union recv_frame * precv_frame)7196 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7197 {
7198 
7199 	//DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
7200 	return _SUCCESS;
7201 }
7202 
_alloc_mgtxmitframe(struct xmit_priv * pxmitpriv,bool once)7203 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7204 {
7205 	struct xmit_frame *pmgntframe;
7206 	struct xmit_buf *pxmitbuf;
7207 
7208 	if (once)
7209 		pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7210 	else
7211 		pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7212 
7213 	if (pmgntframe == NULL) {
7214 		DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7215 		goto exit;
7216 	}
7217 
7218 	if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
7219 		DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7220 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
7221 		pmgntframe = NULL;
7222 		goto exit;
7223 	}
7224 
7225 	pmgntframe->frame_tag = MGNT_FRAMETAG;
7226 	pmgntframe->pxmitbuf = pxmitbuf;
7227 	pmgntframe->buf_addr = pxmitbuf->pbuf;
7228 	pxmitbuf->priv_data = pmgntframe;
7229 
7230 exit:
7231 	return pmgntframe;
7232 
7233 }
7234 
alloc_mgtxmitframe(struct xmit_priv * pxmitpriv)7235 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7236 {
7237 	return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7238 }
7239 
alloc_mgtxmitframe_once(struct xmit_priv * pxmitpriv)7240 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7241 {
7242 	return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7243 }
7244 
7245 
7246 /****************************************************************************
7247 
7248 Following are some TX fuctions for WiFi MLME
7249 
7250 *****************************************************************************/
7251 
update_mgnt_tx_rate(_adapter * padapter,u8 rate)7252 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7253 {
7254 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7255 
7256 	pmlmeext->tx_rate = rate;
7257 	//DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
7258 }
7259 
update_mgntframe_attrib(_adapter * padapter,struct pkt_attrib * pattrib)7260 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7261 {
7262 	u8	wireless_mode;
7263 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7264 	struct xmit_priv 		*pxmitpriv = &padapter->xmitpriv;
7265 	struct sta_info *pbcmc_sta = NULL;
7266 	//_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
7267 
7268 	pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7269 
7270 	pattrib->hdrlen = 24;
7271 	pattrib->nr_frags = 1;
7272 	pattrib->priority = 7;
7273 
7274 	if (pbcmc_sta)
7275 		pattrib->mac_id = pbcmc_sta->mac_id;
7276 	else {
7277 		pattrib->mac_id = 0;
7278 		DBG_871X("mgmt use mac_id 0 will affect RA\n");
7279 	}
7280 	pattrib->qsel = QSLT_MGNT;
7281 
7282 	pattrib->pktlen = 0;
7283 
7284 	if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7285 		wireless_mode = WIRELESS_11B;
7286 	else
7287 		wireless_mode = WIRELESS_11G;
7288 	pattrib->raid =  rtw_get_mgntframe_raid(padapter, wireless_mode);
7289 	pattrib->rate = pmlmeext->tx_rate;
7290 
7291 	pattrib->encrypt = _NO_PRIVACY_;
7292 	pattrib->bswenc = _FALSE;
7293 
7294 	pattrib->qos_en = _FALSE;
7295 	pattrib->ht_en = _FALSE;
7296 	pattrib->bwmode = CHANNEL_WIDTH_20;
7297 	pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7298 	pattrib->sgi = _FALSE;
7299 
7300 	pattrib->seqnum = pmlmeext->mgnt_seq;
7301 
7302 	pattrib->retry_ctrl = _TRUE;
7303 
7304 	pattrib->mbssid = 0;
7305 	pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7306 
7307 }
7308 
update_mgntframe_attrib_addr(_adapter * padapter,struct xmit_frame * pmgntframe)7309 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7310 {
7311 	u8	*pframe;
7312 	struct pkt_attrib	*pattrib = &pmgntframe->attrib;
7313 
7314 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7315 
7316 	_rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7317 	_rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
7318 }
7319 
dump_mgntframe(_adapter * padapter,struct xmit_frame * pmgntframe)7320 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7321 {
7322 	if (RTW_CANNOT_RUN(padapter)) {
7323 		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7324 		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7325 		return;
7326 	}
7327 
7328 	rtw_hal_mgnt_xmit(padapter, pmgntframe);
7329 }
7330 
dump_mgntframe_and_wait(_adapter * padapter,struct xmit_frame * pmgntframe,int timeout_ms)7331 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7332 {
7333 	s32 ret = _FAIL;
7334 	_irqL irqL;
7335 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7336 	struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7337 	struct submit_ctx sctx;
7338 
7339 	if (RTW_CANNOT_RUN(padapter)) {
7340 		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7341 		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7342 		return ret;
7343 	}
7344 
7345 	rtw_sctx_init(&sctx, timeout_ms);
7346 	pxmitbuf->sctx = &sctx;
7347 
7348 	ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7349 
7350 	if (ret == _SUCCESS)
7351 		ret = rtw_sctx_wait(&sctx, __func__);
7352 
7353 	_enter_critical(&pxmitpriv->lock_sctx, &irqL);
7354 	pxmitbuf->sctx = NULL;
7355 	_exit_critical(&pxmitpriv->lock_sctx, &irqL);
7356 
7357 	 return ret;
7358 }
7359 
dump_mgntframe_and_wait_ack(_adapter * padapter,struct xmit_frame * pmgntframe)7360 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7361 {
7362 #ifdef CONFIG_XMIT_ACK
7363 	static u8 seq_no = 0;
7364 	s32 ret = _FAIL;
7365 	u32 timeout_ms = 500;//  500ms
7366 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
7367 	#ifdef CONFIG_CONCURRENT_MODE
7368 	if (padapter->pbuddy_adapter && !padapter->isprimary)
7369 		pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7370 	#endif
7371 
7372 	if (RTW_CANNOT_RUN(padapter)) {
7373 		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7374 		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7375 		return -1;
7376 	}
7377 
7378 	_enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7379 	pxmitpriv->ack_tx = _TRUE;
7380 	pxmitpriv->seq_no = seq_no++;
7381 	pmgntframe->ack_report = 1;
7382 	rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7383 	if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7384 #ifdef CONFIG_XMIT_ACK_POLLING
7385 		ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7386 #else
7387 		ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7388 #endif
7389 	}
7390 
7391 	pxmitpriv->ack_tx = _FALSE;
7392 	_exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7393 
7394 	 return ret;
7395 #else //!CONFIG_XMIT_ACK
7396 	dump_mgntframe(padapter, pmgntframe);
7397 	rtw_msleep_os(50);
7398 	return _SUCCESS;
7399 #endif //!CONFIG_XMIT_ACK
7400 }
7401 
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)7402 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7403 {
7404 	u8 *ssid_ie;
7405 	sint ssid_len_ori;
7406 	int len_diff = 0;
7407 
7408 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
7409 
7410 	//DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
7411 
7412 	if(ssid_ie && ssid_len_ori>0)
7413 	{
7414 		switch(hidden_ssid_mode)
7415 		{
7416 			case 1:
7417 			{
7418 				u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7419 				u32 remain_len = 0;
7420 
7421 				remain_len = ies_len -(next_ie-ies);
7422 
7423 				ssid_ie[1] = 0;
7424 				_rtw_memcpy(ssid_ie+2, next_ie, remain_len);
7425 				len_diff -= ssid_len_ori;
7426 
7427 				break;
7428 			}
7429 			case 2:
7430 				_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7431 				break;
7432 			default:
7433 				break;
7434 		}
7435 	}
7436 
7437 	return len_diff;
7438 }
7439 
7440 #ifdef CONFIG_AP_MODE
issue_beacon(_adapter * padapter,int timeout_ms)7441 void issue_beacon(_adapter *padapter, int timeout_ms)
7442 {
7443 	struct xmit_frame	*pmgntframe;
7444 	struct pkt_attrib	*pattrib;
7445 	unsigned char	*pframe;
7446 	struct rtw_ieee80211_hdr *pwlanhdr;
7447 	unsigned short *fctrl;
7448 	unsigned int	rate_len;
7449 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
7450 #if defined (CONFIG_NATIVEAP_MLME)
7451 	_irqL irqL;
7452 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7453 #endif //#if defined (CONFIG_NATIVEAP_MLME)
7454 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7455 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7456 	WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
7457 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7458 #ifdef CONFIG_P2P
7459 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7460 #endif //CONFIG_P2P
7461 
7462 
7463 	//DBG_871X("%s\n", __FUNCTION__);
7464 
7465 #ifdef CONFIG_BCN_ICF
7466 	if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL)
7467 #else
7468 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7469 #endif
7470 	{
7471 		DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7472 		return;
7473 	}
7474 #if defined (CONFIG_NATIVEAP_MLME)
7475 	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7476 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7477 
7478 	//update attribute
7479 	pattrib = &pmgntframe->attrib;
7480 	update_mgntframe_attrib(padapter, pattrib);
7481 	pattrib->qsel = QSLT_BEACON;
7482 	#ifdef CONFIG_CONCURRENT_MODE
7483 	if(padapter->iface_type == IFACE_PORT1)
7484 		pattrib->mbssid = 1;
7485 	#endif
7486 
7487 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7488 
7489 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7490 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7491 
7492 
7493 	fctrl = &(pwlanhdr->frame_ctl);
7494 	*(fctrl) = 0;
7495 
7496 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7497 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7498 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7499 
7500 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7501 	//pmlmeext->mgnt_seq++;
7502 	SetFrameSubType(pframe, WIFI_BEACON);
7503 
7504 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7505 	pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7506 
7507 	if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7508 	{
7509 		//DBG_871X("ie len=%d\n", cur_network->IELength);
7510 #ifdef CONFIG_P2P
7511 		// for P2P : Primary Device Type & Device Name
7512 		u32 wpsielen=0, insert_len=0;
7513 		u8 *wpsie=NULL;
7514 		wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
7515 
7516 		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
7517 		{
7518 			uint wps_offset, remainder_ielen;
7519 			u8 *premainder_ie, *pframe_wscie;
7520 
7521 			wps_offset = (uint)(wpsie - cur_network->IEs);
7522 
7523 			premainder_ie = wpsie + wpsielen;
7524 
7525 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7526 
7527 #ifdef CONFIG_IOCTL_CFG80211
7528 			if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7529 			{
7530 				if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
7531 				{
7532 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7533 					pframe += wps_offset;
7534 					pattrib->pktlen += wps_offset;
7535 
7536 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7537 					pframe += pmlmepriv->wps_beacon_ie_len;
7538 					pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7539 
7540 					//copy remainder_ie to pframe
7541 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7542 					pframe += remainder_ielen;
7543 					pattrib->pktlen += remainder_ielen;
7544 				}
7545 				else
7546 				{
7547 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7548 					pframe += cur_network->IELength;
7549 					pattrib->pktlen += cur_network->IELength;
7550 				}
7551 			}
7552 			else
7553 #endif //CONFIG_IOCTL_CFG80211
7554 			{
7555 				pframe_wscie = pframe + wps_offset;
7556 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
7557 				pframe += (wps_offset + wpsielen);
7558 				pattrib->pktlen += (wps_offset + wpsielen);
7559 
7560 				//now pframe is end of wsc ie, insert Primary Device Type & Device Name
7561 				//	Primary Device Type
7562 				//	Type:
7563 				*(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
7564 				insert_len += 2;
7565 
7566 				//	Length:
7567 				*(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
7568 				insert_len += 2;
7569 
7570 				//	Value:
7571 				//	Category ID
7572 				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7573 				insert_len += 2;
7574 
7575 				//	OUI
7576 				*(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
7577 				insert_len += 4;
7578 
7579 				//	Sub Category ID
7580 				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7581 				insert_len += 2;
7582 
7583 
7584 				//	Device Name
7585 				//	Type:
7586 				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7587 				insert_len += 2;
7588 
7589 				//	Length:
7590 				*(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
7591 				insert_len += 2;
7592 
7593 				//	Value:
7594 				_rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
7595 				insert_len += pwdinfo->device_name_len;
7596 
7597 
7598 				//update wsc ie length
7599 				*(pframe_wscie+1) = (wpsielen -2) + insert_len;
7600 
7601 				//pframe move to end
7602 				pframe+=insert_len;
7603 				pattrib->pktlen += insert_len;
7604 
7605 				//copy remainder_ie to pframe
7606 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7607 				pframe += remainder_ielen;
7608 				pattrib->pktlen += remainder_ielen;
7609 			}
7610 		}
7611 		else
7612 #endif //CONFIG_P2P
7613 		{
7614 			int len_diff;
7615 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7616 			len_diff = update_hidden_ssid(
7617 				pframe+_BEACON_IE_OFFSET_
7618 				, cur_network->IELength-_BEACON_IE_OFFSET_
7619 				, pmlmeinfo->hidden_ssid_mode
7620 			);
7621 			pframe += (cur_network->IELength+len_diff);
7622 			pattrib->pktlen += (cur_network->IELength+len_diff);
7623 		}
7624 
7625 		{
7626 			u8 *wps_ie;
7627 			uint wps_ielen;
7628 			u8 sr = 0;
7629 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
7630 				pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
7631 			if (wps_ie && wps_ielen>0) {
7632 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
7633 			}
7634 			if (sr != 0)
7635 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7636 			else
7637 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7638 		}
7639 
7640 #ifdef CONFIG_P2P
7641 		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
7642 		{
7643 			u32 len;
7644 #ifdef CONFIG_IOCTL_CFG80211
7645 			if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7646 			{
7647 				len = pmlmepriv->p2p_beacon_ie_len;
7648 				if(pmlmepriv->p2p_beacon_ie && len>0)
7649 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7650 			}
7651 			else
7652 #endif //CONFIG_IOCTL_CFG80211
7653 			{
7654 				len = build_beacon_p2p_ie(pwdinfo, pframe);
7655 			}
7656 
7657 			pframe += len;
7658 			pattrib->pktlen += len;
7659 #ifdef CONFIG_WFD
7660 #ifdef CONFIG_IOCTL_CFG80211
7661 			if(_TRUE == pwdinfo->wfd_info->wfd_enable)
7662 #endif //CONFIG_IOCTL_CFG80211
7663 			{
7664 			len = build_beacon_wfd_ie( pwdinfo, pframe );
7665 			}
7666 #ifdef CONFIG_IOCTL_CFG80211
7667 			else
7668 			{
7669 				len = 0;
7670 				if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
7671 				{
7672 					len = pmlmepriv->wfd_beacon_ie_len;
7673 					_rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
7674 				}
7675 			}
7676 #endif //CONFIG_IOCTL_CFG80211
7677 			pframe += len;
7678 			pattrib->pktlen += len;
7679 #endif //CONFIG_WFD
7680 		}
7681 #endif //CONFIG_P2P
7682 
7683 		goto _issue_bcn;
7684 
7685 	}
7686 
7687 	//below for ad-hoc mode
7688 
7689 	//timestamp will be inserted by hardware
7690 	pframe += 8;
7691 	pattrib->pktlen += 8;
7692 
7693 	// beacon interval: 2 bytes
7694 
7695 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7696 
7697 	pframe += 2;
7698 	pattrib->pktlen += 2;
7699 
7700 	// capability info: 2 bytes
7701 
7702 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7703 
7704 	pframe += 2;
7705 	pattrib->pktlen += 2;
7706 
7707 	// SSID
7708 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7709 
7710 	// supported rates...
7711 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7712 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7713 
7714 	// DS parameter set
7715 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7716 
7717 	//if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7718 	{
7719 		u8 erpinfo=0;
7720 		u32 ATIMWindow;
7721 		// IBSS Parameter Set...
7722 		//ATIMWindow = cur->Configuration.ATIMWindow;
7723 		ATIMWindow = 0;
7724 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7725 
7726 		//ERP IE
7727 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7728 	}
7729 
7730 
7731 	// EXTERNDED SUPPORTED RATE
7732 	if (rate_len > 8)
7733 	{
7734 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7735 	}
7736 
7737 
7738 	//todo:HT for adhoc
7739 
7740 _issue_bcn:
7741 
7742 #if defined (CONFIG_NATIVEAP_MLME)
7743 	pmlmepriv->update_bcn = _FALSE;
7744 
7745 	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7746 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7747 
7748 	if ((pattrib->pktlen + TXDESC_SIZE) > 512)
7749 	{
7750 		DBG_871X("beacon frame too large\n");
7751 		return;
7752 	}
7753 
7754 	pattrib->last_txcmdsz = pattrib->pktlen;
7755 
7756 	//DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
7757 	if(timeout_ms > 0)
7758 		dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7759 	else
7760 		dump_mgntframe(padapter, pmgntframe);
7761 
7762 }
7763 #endif /*CONFIG_AP_MODE*/
7764 
issue_probersp(_adapter * padapter,unsigned char * da,u8 is_valid_p2p_probereq)7765 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7766 {
7767 	struct xmit_frame			*pmgntframe;
7768 	struct pkt_attrib			*pattrib;
7769 	unsigned char					*pframe;
7770 	struct rtw_ieee80211_hdr	*pwlanhdr;
7771 	unsigned short				*fctrl;
7772 	unsigned char					*mac, *bssid;
7773 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
7774 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7775 	u8 *pwps_ie;
7776 	uint wps_ielen;
7777 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7778 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7779 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7780 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7781 	WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
7782 	unsigned int	rate_len;
7783 #ifdef CONFIG_P2P
7784 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7785 #ifdef CONFIG_WFD
7786 	u32					wfdielen = 0;
7787 #endif //CONFIG_WFD
7788 #endif //CONFIG_P2P
7789 
7790 	//DBG_871X("%s\n", __FUNCTION__);
7791 
7792 	if(da == NULL)
7793 		return;
7794 
7795 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
7796 		return;
7797 
7798 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7799 	{
7800 		DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7801 		return;
7802 	}
7803 
7804 
7805 	//update attribute
7806 	pattrib = &pmgntframe->attrib;
7807 	update_mgntframe_attrib(padapter, pattrib);
7808 
7809 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7810 
7811 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7812 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7813 
7814 	mac = adapter_mac_addr(padapter);
7815 	bssid = cur_network->MacAddress;
7816 
7817 	fctrl = &(pwlanhdr->frame_ctl);
7818 	*(fctrl) = 0;
7819 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7820 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7821 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7822 
7823 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7824 	pmlmeext->mgnt_seq++;
7825 	SetFrameSubType(fctrl, WIFI_PROBERSP);
7826 
7827 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7828 	pattrib->pktlen = pattrib->hdrlen;
7829 	pframe += pattrib->hdrlen;
7830 
7831 
7832 	if(cur_network->IELength>MAX_IE_SZ)
7833 		return;
7834 
7835 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7836 	if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7837 	{
7838 		pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
7839 
7840 		//inerset & update wps_probe_resp_ie
7841 		if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
7842 		{
7843 			uint wps_offset, remainder_ielen;
7844 			u8 *premainder_ie;
7845 
7846 			wps_offset = (uint)(pwps_ie - cur_network->IEs);
7847 
7848 			premainder_ie = pwps_ie + wps_ielen;
7849 
7850 			remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
7851 
7852 			_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7853 			pframe += wps_offset;
7854 			pattrib->pktlen += wps_offset;
7855 
7856 			wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
7857 			if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
7858 			{
7859 				_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
7860 				pframe += wps_ielen+2;
7861 				pattrib->pktlen += wps_ielen+2;
7862 			}
7863 
7864 			if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
7865 			{
7866 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7867 				pframe += remainder_ielen;
7868 				pattrib->pktlen += remainder_ielen;
7869 			}
7870 		}
7871 		else
7872 		{
7873 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7874 			pframe += cur_network->IELength;
7875 			pattrib->pktlen += cur_network->IELength;
7876 		}
7877 
7878 		/* retrieve SSID IE from cur_network->Ssid */
7879 		{
7880 			u8 *ssid_ie;
7881 			sint ssid_ielen;
7882 			sint ssid_ielen_diff;
7883 			u8 buf[MAX_IE_SZ];
7884 			u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
7885 
7886 			ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
7887 				(pframe-ies)-_FIXED_IE_LENGTH_);
7888 
7889 			ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
7890 
7891 			if (ssid_ie &&  cur_network->Ssid.SsidLength) {
7892 				uint remainder_ielen;
7893 				u8 *remainder_ie;
7894 				remainder_ie = ssid_ie+2;
7895 				remainder_ielen = (pframe-remainder_ie);
7896 
7897 				if (remainder_ielen > MAX_IE_SZ) {
7898 					DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
7899 					remainder_ielen = MAX_IE_SZ;
7900 				}
7901 
7902 				_rtw_memcpy(buf, remainder_ie, remainder_ielen);
7903 				_rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
7904 				*(ssid_ie+1) = cur_network->Ssid.SsidLength;
7905 				_rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
7906 
7907 				pframe += ssid_ielen_diff;
7908 				pattrib->pktlen += ssid_ielen_diff;
7909 			}
7910 		}
7911 	}
7912 	else
7913 #endif
7914 	{
7915 
7916 		//timestamp will be inserted by hardware
7917 		pframe += 8;
7918 		pattrib->pktlen += 8;
7919 
7920 		// beacon interval: 2 bytes
7921 
7922 		_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7923 
7924 		pframe += 2;
7925 		pattrib->pktlen += 2;
7926 
7927 		// capability info: 2 bytes
7928 
7929 		_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7930 
7931 		pframe += 2;
7932 		pattrib->pktlen += 2;
7933 
7934 		//below for ad-hoc mode
7935 
7936 		// SSID
7937 		pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7938 
7939 		// supported rates...
7940 		rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7941 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7942 
7943 		// DS parameter set
7944 		pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7945 
7946 		if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7947 		{
7948 			u8 erpinfo=0;
7949 			u32 ATIMWindow;
7950 			// IBSS Parameter Set...
7951 			//ATIMWindow = cur->Configuration.ATIMWindow;
7952 			ATIMWindow = 0;
7953 			pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7954 
7955 			//ERP IE
7956 			pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7957 		}
7958 
7959 
7960 		// EXTERNDED SUPPORTED RATE
7961 		if (rate_len > 8)
7962 		{
7963 			pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7964 		}
7965 
7966 
7967 		//todo:HT for adhoc
7968 
7969 	}
7970 
7971 #ifdef CONFIG_P2P
7972 	if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
7973 		/* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
7974 		&& (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec))
7975 	{
7976 		u32 len;
7977 #ifdef CONFIG_IOCTL_CFG80211
7978 		if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7979 		{
7980 			//if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
7981 			len = pmlmepriv->p2p_go_probe_resp_ie_len;
7982 			if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
7983 				_rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
7984 		}
7985 		else
7986 #endif //CONFIG_IOCTL_CFG80211
7987 		{
7988 			len = build_probe_resp_p2p_ie(pwdinfo, pframe);
7989 		}
7990 
7991 		pframe += len;
7992 		pattrib->pktlen += len;
7993 
7994 #ifdef CONFIG_WFD
7995 #ifdef CONFIG_IOCTL_CFG80211
7996 		if(_TRUE == pwdinfo->wfd_info->wfd_enable)
7997 #endif //CONFIG_IOCTL_CFG80211
7998 		{
7999 			len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
8000 		}
8001 #ifdef CONFIG_IOCTL_CFG80211
8002 		else
8003 		{
8004 			len = 0;
8005 			if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
8006 			{
8007 				len = pmlmepriv->wfd_probe_resp_ie_len;
8008 				_rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
8009 			}
8010 		}
8011 #endif //CONFIG_IOCTL_CFG80211
8012 		pframe += len;
8013 		pattrib->pktlen += len;
8014 #endif //CONFIG_WFD
8015 
8016 	}
8017 #endif //CONFIG_P2P
8018 
8019 
8020 #ifdef CONFIG_AUTO_AP_MODE
8021 {
8022 	struct sta_info	*psta;
8023 	struct sta_priv *pstapriv = &padapter->stapriv;
8024 
8025 	DBG_871X("(%s)\n", __FUNCTION__);
8026 
8027 	//check rc station
8028 	psta = rtw_get_stainfo(pstapriv, da);
8029 	if (psta && psta->isrc && psta->pid>0)
8030 	{
8031 		u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
8032 		u8 RC_INFO[14] = {0};
8033 		//EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
8034 		u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8035 
8036 		DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8037 			psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
8038 
8039 		//append vendor specific ie
8040 		_rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8041 		_rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8042 		_rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
8043 		_rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
8044 
8045 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8046 	}
8047 }
8048 #endif //CONFIG_AUTO_AP_MODE
8049 
8050 
8051 	pattrib->last_txcmdsz = pattrib->pktlen;
8052 
8053 
8054 	dump_mgntframe(padapter, pmgntframe);
8055 
8056 	return;
8057 
8058 }
8059 
_issue_probereq(_adapter * padapter,NDIS_802_11_SSID * pssid,u8 * da,u8 ch,bool append_wps,int wait_ack)8060 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
8061 {
8062 	int ret = _FAIL;
8063 	struct xmit_frame		*pmgntframe;
8064 	struct pkt_attrib		*pattrib;
8065 	unsigned char			*pframe;
8066 	struct rtw_ieee80211_hdr	*pwlanhdr;
8067 	unsigned short		*fctrl;
8068 	unsigned char			*mac;
8069 	unsigned char			bssrate[NumRates];
8070 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8071 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8072 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8073 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8074 	int	bssrate_len = 0;
8075 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8076 
8077 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8078 		goto exit;
8079 
8080 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8081 	{
8082 		goto exit;
8083 	}
8084 
8085 	//update attribute
8086 	pattrib = &pmgntframe->attrib;
8087 	update_mgntframe_attrib(padapter, pattrib);
8088 
8089 
8090 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8091 
8092 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8093 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8094 
8095 	mac = adapter_mac_addr(padapter);
8096 
8097 	fctrl = &(pwlanhdr->frame_ctl);
8098 	*(fctrl) = 0;
8099 
8100 	if (da)
8101 	{
8102 		//	unicast probe request frame
8103 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8104 		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8105 	}
8106 	else
8107 	{
8108 		//	broadcast probe request frame
8109 		_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8110 		_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8111 	}
8112 
8113 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8114 
8115 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8116 	pmlmeext->mgnt_seq++;
8117 	SetFrameSubType(pframe, WIFI_PROBEREQ);
8118 
8119 	pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
8120 	pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
8121 
8122 	if(pssid)
8123 		pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8124 	else
8125 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8126 
8127 	get_rate_set(padapter, bssrate, &bssrate_len);
8128 
8129 	if (bssrate_len > 8)
8130 	{
8131 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8132 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8133 	}
8134 	else
8135 	{
8136 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8137 	}
8138 
8139 	if (ch)
8140 		pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8141 
8142 	if (append_wps) {
8143 		//add wps_ie for wps2.0
8144 		if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
8145 		{
8146 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8147 			pframe += pmlmepriv->wps_probe_req_ie_len;
8148 			pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8149 			//pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
8150 		}
8151 	}
8152 
8153 	pattrib->last_txcmdsz = pattrib->pktlen;
8154 
8155 	RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
8156 
8157 	if (wait_ack) {
8158 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8159 	} else {
8160 		dump_mgntframe(padapter, pmgntframe);
8161 		ret = _SUCCESS;
8162 	}
8163 
8164 exit:
8165 	return ret;
8166 }
8167 
issue_probereq(_adapter * padapter,NDIS_802_11_SSID * pssid,u8 * da)8168 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
8169 {
8170 	_issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8171 }
8172 
8173 /*
8174  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8175  * 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
8176  * try_cnt means the maximal TX count to try
8177  */
issue_probereq_ex(_adapter * padapter,NDIS_802_11_SSID * pssid,u8 * da,u8 ch,bool append_wps,int try_cnt,int wait_ms)8178 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
8179 	int try_cnt, int wait_ms)
8180 {
8181 	int ret = _FAIL;
8182 	int i = 0;
8183 	u32 start = rtw_get_current_time();
8184 
8185 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8186 		goto exit;
8187 
8188 	do
8189 	{
8190 		ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE);
8191 
8192 		i++;
8193 
8194 		if (RTW_CANNOT_RUN(padapter))
8195 			break;
8196 
8197 		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8198 			rtw_msleep_os(wait_ms);
8199 
8200 	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8201 
8202 	if (ret != _FAIL) {
8203 		ret = _SUCCESS;
8204 		#ifndef DBG_XMIT_ACK
8205 		goto exit;
8206 		#endif
8207 	}
8208 
8209 	if (try_cnt && wait_ms) {
8210 		if (da)
8211 			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8212 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8213 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8214 		else
8215 			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8216 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8217 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8218 	}
8219 exit:
8220 	return ret;
8221 }
8222 
8223 // if psta == NULL, indiate we are station(client) now...
issue_auth(_adapter * padapter,struct sta_info * psta,unsigned short status)8224 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8225 {
8226 	struct xmit_frame			*pmgntframe;
8227 	struct pkt_attrib			*pattrib;
8228 	unsigned char					*pframe;
8229 	struct rtw_ieee80211_hdr	*pwlanhdr;
8230 	unsigned short				*fctrl;
8231 	unsigned int					val32;
8232 	unsigned short				val16;
8233 	int use_shared_key = 0;
8234 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
8235 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8236 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8237 
8238 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8239 		return;
8240 
8241 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8242 	{
8243 		return;
8244 	}
8245 
8246 	//update attribute
8247 	pattrib = &pmgntframe->attrib;
8248 	update_mgntframe_attrib(padapter, pattrib);
8249 
8250 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8251 
8252 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8253 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8254 
8255 	fctrl = &(pwlanhdr->frame_ctl);
8256 	*(fctrl) = 0;
8257 
8258 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8259 	pmlmeext->mgnt_seq++;
8260 	SetFrameSubType(pframe, WIFI_AUTH);
8261 
8262 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8263 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8264 
8265 
8266 	if(psta)// for AP mode
8267 	{
8268 #ifdef CONFIG_NATIVEAP_MLME
8269 
8270 		_rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
8271 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8272 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8273 
8274 
8275 		// setting auth algo number
8276 		val16 = (u16)psta->authalg;
8277 
8278 		if(status != _STATS_SUCCESSFUL_)
8279 			val16 = 0;
8280 
8281 		if (val16)	{
8282 			val16 = cpu_to_le16(val16);
8283 			use_shared_key = 1;
8284 		}
8285 
8286 		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8287 
8288 		// setting auth seq number
8289 		val16 =(u16)psta->auth_seq;
8290 		val16 = cpu_to_le16(val16);
8291 		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8292 
8293 		// setting status code...
8294 		val16 = status;
8295 		val16 = cpu_to_le16(val16);
8296 		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8297 
8298 		// added challenging text...
8299 		if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8300 		{
8301 			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8302 		}
8303 #endif
8304 	}
8305 	else
8306 	{
8307 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8308 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8309 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8310 
8311 		// setting auth algo number
8312 		val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
8313 		if (val16)	{
8314 			val16 = cpu_to_le16(val16);
8315 			use_shared_key = 1;
8316 		}
8317 		//DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
8318 
8319 		//setting IV for auth seq #3
8320 		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8321 		{
8322 			//DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
8323 			val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8324 			val32 = cpu_to_le32(val32);
8325 			pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8326 
8327 			pattrib->iv_len = 4;
8328 		}
8329 
8330 		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8331 
8332 		// setting auth seq number
8333 		val16 = pmlmeinfo->auth_seq;
8334 		val16 = cpu_to_le16(val16);
8335 		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8336 
8337 
8338 		// setting status code...
8339 		val16 = status;
8340 		val16 = cpu_to_le16(val16);
8341 		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8342 
8343 		// then checking to see if sending challenging text...
8344 		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8345 		{
8346 			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8347 
8348 			SetPrivacy(fctrl);
8349 
8350 			pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8351 
8352 			pattrib->encrypt = _WEP40_;
8353 
8354 			pattrib->icv_len = 4;
8355 
8356 			pattrib->pktlen += pattrib->icv_len;
8357 
8358 		}
8359 
8360 	}
8361 
8362 	pattrib->last_txcmdsz = pattrib->pktlen;
8363 
8364 	rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8365 	DBG_871X("%s\n", __FUNCTION__);
8366 	dump_mgntframe(padapter, pmgntframe);
8367 
8368 	return;
8369 }
8370 
8371 
issue_asocrsp(_adapter * padapter,unsigned short status,struct sta_info * pstat,int pkt_type)8372 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8373 {
8374 #ifdef CONFIG_AP_MODE
8375 	struct xmit_frame	*pmgntframe;
8376 	struct rtw_ieee80211_hdr	*pwlanhdr;
8377 	struct pkt_attrib *pattrib;
8378 	unsigned char	*pbuf, *pframe;
8379 	unsigned short val, ie_status;
8380 	unsigned short *fctrl;
8381 	struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8382 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8383 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8384 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8385 	WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8386 	u8 *ie = pnetwork->IEs;
8387 #ifdef CONFIG_P2P
8388 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
8389 #ifdef CONFIG_WFD
8390 	u32					wfdielen = 0;
8391 #endif //CONFIG_WFD
8392 
8393 #endif //CONFIG_P2P
8394 
8395 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8396 		return;
8397 
8398 	DBG_871X("%s\n", __FUNCTION__);
8399 
8400 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8401 	{
8402 		return;
8403 	}
8404 
8405 	//update attribute
8406 	pattrib = &pmgntframe->attrib;
8407 	update_mgntframe_attrib(padapter, pattrib);
8408 
8409 
8410 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8411 
8412 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8413 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8414 
8415 	fctrl = &(pwlanhdr->frame_ctl);
8416 	*(fctrl) = 0;
8417 
8418 	_rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
8419 	_rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8420 	_rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8421 
8422 
8423 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8424 	pmlmeext->mgnt_seq++;
8425 	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8426 		SetFrameSubType(pwlanhdr, pkt_type);
8427 	else
8428 		return;
8429 
8430 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8431 	pattrib->pktlen += pattrib->hdrlen;
8432 	pframe += pattrib->hdrlen;
8433 
8434 	//capability
8435 	val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8436 
8437 	pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8438 
8439 	ie_status = cpu_to_le16(status);
8440 	pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8441 
8442 	val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
8443 	pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8444 
8445 	if (pstat->bssratelen <= 8)
8446 	{
8447 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8448 	}
8449 	else
8450 	{
8451 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8452 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
8453 	}
8454 
8455 #ifdef CONFIG_IEEE80211W
8456 	if (status == _STATS_REFUSED_TEMPORARILY_) {
8457 		u8 timeout_itvl[5];
8458 		u32 timeout_interval = 3000;
8459 		/* Association Comeback time */
8460 		timeout_itvl[0] = 0x03;
8461 		timeout_interval = cpu_to_le32(timeout_interval);
8462 		_rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
8463 		pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8464 	}
8465 #endif /* CONFIG_IEEE80211W */
8466 
8467 #ifdef CONFIG_80211N_HT
8468 	if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
8469 	{
8470 		uint ie_len=0;
8471 
8472 		//FILL HT CAP INFO IE
8473 		//p = hostapd_eid_ht_capabilities_info(hapd, p);
8474 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8475 		if(pbuf && ie_len>0)
8476 		{
8477 			_rtw_memcpy(pframe, pbuf, ie_len+2);
8478 			pframe += (ie_len+2);
8479 			pattrib->pktlen +=(ie_len+2);
8480 		}
8481 
8482 		//FILL HT ADD INFO IE
8483 		//p = hostapd_eid_ht_operation(hapd, p);
8484 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8485 		if(pbuf && ie_len>0)
8486 		{
8487 			_rtw_memcpy(pframe, pbuf, ie_len+2);
8488 			pframe += (ie_len+2);
8489 			pattrib->pktlen +=(ie_len+2);
8490 		}
8491 
8492 	}
8493 #endif
8494 
8495 	/*adding EXT_CAPAB_IE */
8496 	if (pmlmepriv->ext_capab_ie_len > 0) {
8497 		uint ie_len = 0;
8498 
8499 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8500 		if (pbuf && ie_len > 0) {
8501 			_rtw_memcpy(pframe, pbuf, ie_len+2);
8502 			pframe += (ie_len+2);
8503 			pattrib->pktlen += (ie_len+2);
8504 		}
8505 	}
8506 
8507 #ifdef CONFIG_80211AC_VHT
8508 	if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8509 		&& (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8510 		&& (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP))
8511 	{
8512 		u32 ie_len=0;
8513 
8514 		//FILL VHT CAP IE
8515 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8516 		if(pbuf && ie_len>0)
8517 		{
8518 			_rtw_memcpy(pframe, pbuf, ie_len+2);
8519 			pframe += (ie_len+2);
8520 			pattrib->pktlen +=(ie_len+2);
8521 		}
8522 
8523 		//FILL VHT OPERATION IE
8524 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8525 		if(pbuf && ie_len>0)
8526 		{
8527 			_rtw_memcpy(pframe, pbuf, ie_len+2);
8528 			pframe += (ie_len+2);
8529 			pattrib->pktlen +=(ie_len+2);
8530 		}
8531 	}
8532 #endif //CONFIG_80211AC_VHT
8533 
8534 	//FILL WMM IE
8535 	if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
8536 	{
8537 		uint ie_len=0;
8538 		unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
8539 
8540 		for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
8541 		{
8542 			pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
8543 			if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
8544 			{
8545 				_rtw_memcpy(pframe, pbuf, ie_len+2);
8546 				pframe += (ie_len+2);
8547 				pattrib->pktlen +=(ie_len+2);
8548 
8549 				break;
8550 			}
8551 
8552 			if ((pbuf == NULL) || (ie_len == 0))
8553 			{
8554 				break;
8555 			}
8556 		}
8557 
8558 	}
8559 
8560 
8561 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8562 	{
8563 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8564 	}
8565 
8566 	//add WPS IE ie for wps 2.0
8567 	if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
8568 	{
8569 		_rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8570 
8571 		pframe += pmlmepriv->wps_assoc_resp_ie_len;
8572 		pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8573 	}
8574 
8575 #ifdef CONFIG_P2P
8576 	if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
8577 	{
8578 		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
8579 		{
8580 			u32 len;
8581 
8582 			len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8583 
8584 			pframe += len;
8585 			pattrib->pktlen += len;
8586 		}
8587 	}
8588 #ifdef CONFIG_WFD
8589 	if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8590 #ifdef CONFIG_IOCTL_CFG80211
8591 		&& (_TRUE == pwdinfo->wfd_info->wfd_enable)
8592 #endif //CONFIG_IOCTL_CFG80211
8593 	)
8594 	{
8595 		wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
8596 		pframe += wfdielen;
8597 		pattrib->pktlen += wfdielen;
8598 	}
8599 #endif //CONFIG_WFD
8600 #endif //CONFIG_P2P
8601 
8602 	pattrib->last_txcmdsz = pattrib->pktlen;
8603 
8604 	dump_mgntframe(padapter, pmgntframe);
8605 
8606 #endif
8607 }
8608 
issue_assocreq(_adapter * padapter)8609 void issue_assocreq(_adapter *padapter)
8610 {
8611 	int ret = _FAIL;
8612 	struct xmit_frame				*pmgntframe;
8613 	struct pkt_attrib				*pattrib;
8614 	unsigned char					*pframe, *p;
8615 	struct rtw_ieee80211_hdr			*pwlanhdr;
8616 	unsigned short				*fctrl;
8617 	unsigned short				val16;
8618 	unsigned int					i, j, ie_len, index=0;
8619 	unsigned char					rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8620 	PNDIS_802_11_VARIABLE_IEs	pIE;
8621 	struct registry_priv	*pregpriv = &padapter->registrypriv;
8622 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8623 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8624 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8625 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8626 	int	bssrate_len = 0, sta_bssrate_len = 0;
8627 	u8	vs_ie_length = 0;
8628 #ifdef CONFIG_P2P
8629 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
8630 	u8					p2pie[ 255 ] = { 0x00 };
8631 	u16					p2pielen = 0;
8632 #ifdef CONFIG_WFD
8633 	u32					wfdielen = 0;
8634 #endif //CONFIG_WFD
8635 #endif //CONFIG_P2P
8636 
8637 #ifdef CONFIG_DFS
8638 	u16	cap;
8639 
8640 	/* Dot H */
8641 	u8 pow_cap_ele[2] = { 0x00 };
8642 	u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2;	//For supported channel
8643 #endif //CONFIG_DFS
8644 
8645 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8646 		goto exit;
8647 
8648 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8649 		goto exit;
8650 
8651 	//update attribute
8652 	pattrib = &pmgntframe->attrib;
8653 	update_mgntframe_attrib(padapter, pattrib);
8654 
8655 
8656 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8657 
8658 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8659 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8660 
8661 	fctrl = &(pwlanhdr->frame_ctl);
8662 	*(fctrl) = 0;
8663 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8664 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8665 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8666 
8667 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8668 	pmlmeext->mgnt_seq++;
8669 	SetFrameSubType(pframe, WIFI_ASSOCREQ);
8670 
8671 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8672 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8673 
8674 	//caps
8675 
8676 #ifdef CONFIG_DFS
8677 	_rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8678 	cap |= cap_SpecMgmt;
8679 	_rtw_memcpy(pframe, &cap, 2);
8680 #else
8681 	_rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8682 #endif //CONFIG_DFS
8683 
8684 	pframe += 2;
8685 	pattrib->pktlen += 2;
8686 
8687 	//listen interval
8688 	//todo: listen interval for power saving
8689 	val16 = cpu_to_le16(3);
8690 	_rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
8691 	pframe += 2;
8692 	pattrib->pktlen += 2;
8693 
8694 	//SSID
8695 	pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8696 
8697 #ifdef CONFIG_DFS
8698 	/* Dot H */
8699 	if(pmlmeext->cur_channel > 14)
8700 	{
8701 		pow_cap_ele[0] = 13;	// Minimum transmit power capability
8702 		pow_cap_ele[1] = 21;	// Maximum transmit power capability
8703 		pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8704 
8705 		//supported channels
8706 		do{
8707 			if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
8708 			{
8709 				sup_ch[0] = 1;	//First channel number
8710 				sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;	//Number of channel
8711 			}
8712 			else
8713 			{
8714 				sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8715 				sup_ch[idx_5g++] = 1;
8716 			}
8717 			sup_ch_idx++;
8718 		}
8719 		while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
8720 		pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8721 	}
8722 #endif //CONFIG_DFS
8723 
8724 	//supported rate & extended supported rate
8725 
8726 #if 1	// Check if the AP's supported rates are also supported by STA.
8727 	get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8728 	//DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
8729 
8730 	if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
8731 	{
8732 		sta_bssrate_len = 4;
8733 	}
8734 
8735 
8736 	//for (i = 0; i < sta_bssrate_len; i++) {
8737 	//	DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
8738 	//}
8739 
8740 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8741 		if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8742 		DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8743 	}
8744 
8745 
8746 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8747 		if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8748 
8749 
8750 		// Check if the AP's supported rates are also supported by STA.
8751 		for (j=0; j < sta_bssrate_len; j++) {
8752 			 // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8753 			if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
8754 					== (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
8755 				//DBG_871X("match i = %d, j=%d\n", i, j);
8756 				break;
8757 			} else {
8758 				//DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
8759 			}
8760 		}
8761 
8762 		if (j == sta_bssrate_len) {
8763 			// the rate is not supported by STA
8764 			DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8765 		} else {
8766 			// the rate is supported by STA
8767 			bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8768 		}
8769 	}
8770 
8771 	bssrate_len = index;
8772 	DBG_871X("bssrate_len = %d\n", bssrate_len);
8773 
8774 #else	// Check if the AP's supported rates are also supported by STA.
8775 #if 0
8776 	get_rate_set(padapter, bssrate, &bssrate_len);
8777 #else
8778 	for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8779 		if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
8780 
8781 		if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8782 			break;
8783 
8784 		bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8785 	}
8786 #endif
8787 #endif	// Check if the AP's supported rates are also supported by STA.
8788 
8789 	if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8790 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8791 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
8792 		goto exit; //don't connect to AP if no joint supported rate
8793 	}
8794 
8795 
8796 	if (bssrate_len > 8)
8797 	{
8798 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8799 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8800 	}
8801 	else if (bssrate_len > 0)
8802 	{
8803 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8804 	} else {
8805 		DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n",__FUNCTION__);
8806 	}
8807 
8808 	//vendor specific IE, such as WPA, WMM, WPS
8809 	for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
8810 	{
8811 		pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8812 
8813 		switch (pIE->ElementID)
8814 		{
8815 			case _VENDOR_SPECIFIC_IE_:
8816 				if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8817 						(_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8818 						(_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8819 				{
8820 					vs_ie_length = pIE->Length;
8821 					if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8822 					{
8823 						//Commented by Kurt 20110629
8824 						//In some older APs, WPS handshake
8825 						//would be fail if we append vender extensions informations to AP
8826 
8827 						vs_ie_length = 14;
8828 					}
8829 
8830 					pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8831 				}
8832 				break;
8833 
8834 			case EID_WPA2:
8835 				pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8836 				break;
8837 #ifdef CONFIG_80211N_HT
8838 			case EID_HTCapability:
8839 				if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8840 					if (!(is_ap_in_tkip(padapter)))
8841 					{
8842 						_rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8843 
8844 						pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8845 
8846 						pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8847 					}
8848 				}
8849 				break;
8850 
8851 			case EID_EXTCapability:
8852 				if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8853 					pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8854 				}
8855 				break;
8856 #endif //CONFIG_80211N_HT
8857 #ifdef CONFIG_80211AC_VHT
8858 			case EID_VHTCapability:
8859 				if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8860 					pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8861 				}
8862 				break;
8863 
8864 			case EID_OpModeNotification:
8865 				if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8866 					pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
8867 				}
8868 				break;
8869 #endif // CONFIG_80211AC_VHT
8870 			default:
8871 				break;
8872 		}
8873 
8874 		i += (pIE->Length + 2);
8875 	}
8876 
8877 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8878 	{
8879 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8880 	}
8881 
8882 
8883 #ifdef CONFIG_WAPI_SUPPORT
8884 	rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
8885 #endif
8886 
8887 
8888 #ifdef CONFIG_P2P
8889 
8890 #ifdef CONFIG_IOCTL_CFG80211
8891 	if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8892 	{
8893 		if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
8894 		{
8895 			_rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
8896 			pframe += pmlmepriv->p2p_assoc_req_ie_len;
8897 			pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
8898 		}
8899 	}
8900 	else
8901 #endif //CONFIG_IOCTL_CFG80211
8902 	{
8903 		if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
8904 		{
8905 			//	Should add the P2P IE in the association request frame.
8906 			//	P2P OUI
8907 
8908 			p2pielen = 0;
8909 			p2pie[ p2pielen++ ] = 0x50;
8910 			p2pie[ p2pielen++ ] = 0x6F;
8911 			p2pie[ p2pielen++ ] = 0x9A;
8912 			p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
8913 
8914 			//	Commented by Albert 20101109
8915 			//	According to the P2P Specification, the association request frame should contain 3 P2P attributes
8916 			//	1. P2P Capability
8917 			//	2. Extended Listen Timing
8918 			//	3. Device Info
8919 			//	Commented by Albert 20110516
8920 			//	4. P2P Interface
8921 
8922 			//	P2P Capability
8923 			//	Type:
8924 			p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
8925 
8926 			//	Length:
8927 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
8928 			p2pielen += 2;
8929 
8930 			//	Value:
8931 			//	Device Capability Bitmap, 1 byte
8932 			p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
8933 
8934 			//	Group Capability Bitmap, 1 byte
8935 			if ( pwdinfo->persistent_supported )
8936 				p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
8937 			else
8938 				p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
8939 
8940 			//	Extended Listen Timing
8941 			//	Type:
8942 			p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
8943 
8944 			//	Length:
8945 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
8946 			p2pielen += 2;
8947 
8948 			//	Value:
8949 			//	Availability Period
8950 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
8951 			p2pielen += 2;
8952 
8953 			//	Availability Interval
8954 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
8955 			p2pielen += 2;
8956 
8957 			//	Device Info
8958 			//	Type:
8959 			p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
8960 
8961 			//	Length:
8962 			//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
8963 			//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
8964 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
8965 			p2pielen += 2;
8966 
8967 			//	Value:
8968 			//	P2P Device Address
8969 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
8970 			p2pielen += ETH_ALEN;
8971 
8972 			//	Config Method
8973 			//	This field should be big endian. Noted by P2P specification.
8974 			if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
8975 				( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
8976 			{
8977 				*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
8978 			}
8979 			else
8980 			{
8981 				*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
8982 			}
8983 
8984 			p2pielen += 2;
8985 
8986 			//	Primary Device Type
8987 			//	Category ID
8988 			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
8989 			p2pielen += 2;
8990 
8991 			//	OUI
8992 			*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
8993 			p2pielen += 4;
8994 
8995 			//	Sub Category ID
8996 			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
8997 			p2pielen += 2;
8998 
8999 			//	Number of Secondary Device Types
9000 			p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
9001 
9002 			//	Device Name
9003 			//	Type:
9004 			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
9005 			p2pielen += 2;
9006 
9007 			//	Length:
9008 			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
9009 			p2pielen += 2;
9010 
9011 			//	Value:
9012 			_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
9013 			p2pielen += pwdinfo->device_name_len;
9014 
9015 			//	P2P Interface
9016 			//	Type:
9017 			p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
9018 
9019 			//	Length:
9020 			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
9021 			p2pielen += 2;
9022 
9023 			//	Value:
9024 			_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );	//	P2P Device Address
9025 			p2pielen += ETH_ALEN;
9026 
9027 			p2pie[ p2pielen++ ] = 1;	//	P2P Interface Address Count
9028 
9029 			_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );	//	P2P Interface Address List
9030 			p2pielen += ETH_ALEN;
9031 
9032 			pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
9033 
9034 #ifdef CONFIG_WFD
9035 			//wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
9036 			//pframe += wfdielen;
9037 			//pattrib->pktlen += wfdielen;
9038 #endif //CONFIG_WFD
9039 		}
9040 	}
9041 
9042 #endif //CONFIG_P2P
9043 
9044 #ifdef CONFIG_WFD
9045 #ifdef CONFIG_IOCTL_CFG80211
9046 	if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
9047 #endif //CONFIG_IOCTL_CFG80211
9048 	{
9049 		wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
9050 		pframe += wfdielen;
9051 		pattrib->pktlen += wfdielen;
9052 	}
9053 #ifdef CONFIG_IOCTL_CFG80211
9054 	else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
9055 	{
9056 		//WFD IE
9057 		_rtw_memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
9058 		pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
9059 		pframe += pmlmepriv->wfd_assoc_req_ie_len;
9060 	}
9061 #endif //CONFIG_IOCTL_CFG80211
9062 #endif //CONFIG_WFD
9063 
9064 	pattrib->last_txcmdsz = pattrib->pktlen;
9065 	dump_mgntframe(padapter, pmgntframe);
9066 
9067 	ret = _SUCCESS;
9068 
9069 exit:
9070 	if (ret == _SUCCESS)
9071 		rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9072 	else
9073 		rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9074 
9075 	return;
9076 }
9077 
9078 //when wait_ack is ture, this function shoule be called at process context
_issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int wait_ack)9079 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9080 {
9081 	int ret = _FAIL;
9082 	struct xmit_frame			*pmgntframe;
9083 	struct pkt_attrib			*pattrib;
9084 	unsigned char					*pframe;
9085 	struct rtw_ieee80211_hdr	*pwlanhdr;
9086 	unsigned short				*fctrl;
9087 	struct xmit_priv	*pxmitpriv;
9088 	struct mlme_ext_priv	*pmlmeext;
9089 	struct mlme_ext_info	*pmlmeinfo;
9090 
9091 	//DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
9092 
9093 	if(!padapter)
9094 		goto exit;
9095 
9096 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9097 		goto exit;
9098 
9099 	pxmitpriv = &(padapter->xmitpriv);
9100 	pmlmeext = &(padapter->mlmeextpriv);
9101 	pmlmeinfo = &(pmlmeext->mlmext_info);
9102 
9103 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9104 	{
9105 		goto exit;
9106 	}
9107 
9108 	//update attribute
9109 	pattrib = &pmgntframe->attrib;
9110 	update_mgntframe_attrib(padapter, pattrib);
9111 	pattrib->retry_ctrl = _FALSE;
9112 
9113 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9114 
9115 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9116 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9117 
9118 	fctrl = &(pwlanhdr->frame_ctl);
9119 	*(fctrl) = 0;
9120 
9121 	if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9122 	{
9123 		SetFrDs(fctrl);
9124 	}
9125 	else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9126 	{
9127 		SetToDs(fctrl);
9128 	}
9129 
9130 	if (power_mode)
9131 	{
9132 		SetPwrMgt(fctrl);
9133 	}
9134 
9135 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9136 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9137 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9138 
9139 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9140 	pmlmeext->mgnt_seq++;
9141 	SetFrameSubType(pframe, WIFI_DATA_NULL);
9142 
9143 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9144 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9145 
9146 	pattrib->last_txcmdsz = pattrib->pktlen;
9147 
9148 	if(wait_ack)
9149 	{
9150 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9151 	}
9152 	else
9153 	{
9154 		dump_mgntframe(padapter, pmgntframe);
9155 		ret = _SUCCESS;
9156 	}
9157 
9158 exit:
9159 	return ret;
9160 }
9161 
9162 /*
9163  * [IMPORTANT] Don't call this function in interrupt context
9164  *
9165  * When wait_ms > 0, this function should be called at process context
9166  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9167  * 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
9168  * try_cnt means the maximal TX count to try
9169  * da == NULL for station mode
9170  */
issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int try_cnt,int wait_ms)9171 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9172 {
9173 	int ret = _FAIL;
9174 	int i = 0;
9175 	u32 start = rtw_get_current_time();
9176 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9177 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9178 	struct sta_info *psta;
9179 
9180 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9181 		goto exit;
9182 
9183 	/* da == NULL, assum it's null data for sta to ap*/
9184 	if (da == NULL)
9185 		da = get_my_bssid(&(pmlmeinfo->network));
9186 
9187 	psta = rtw_get_stainfo(&padapter->stapriv, da);
9188 	if (psta) {
9189 		if (power_mode)
9190 			rtw_hal_macid_sleep(padapter, psta->mac_id);
9191 		else
9192 			rtw_hal_macid_wakeup(padapter, psta->mac_id);
9193 	} else {
9194 		DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
9195 			FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
9196 		rtw_warn_on(1);
9197 	}
9198 
9199 	do {
9200 		ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
9201 
9202 		i++;
9203 
9204 		if (RTW_CANNOT_RUN(padapter))
9205 			break;
9206 
9207 		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9208 			rtw_msleep_os(wait_ms);
9209 
9210 	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9211 
9212 	if (ret != _FAIL) {
9213 		ret = _SUCCESS;
9214 		#ifndef DBG_XMIT_ACK
9215 		goto exit;
9216 		#endif
9217 	}
9218 
9219 	if (try_cnt && wait_ms) {
9220 		if (da)
9221 			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9222 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9223 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9224 		else
9225 			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9226 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9227 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9228 	}
9229 exit:
9230 	return ret;
9231 }
9232 
9233 /*
9234  * [IMPORTANT] This function run in interrupt context
9235  *
9236  * The null data packet would be sent without power bit,
9237  * and not guarantee success.
9238  */
issue_nulldata_in_interrupt(PADAPTER padapter,u8 * da,unsigned int power_mode)9239 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
9240 {
9241 	int ret;
9242 	struct mlme_ext_priv *pmlmeext;
9243 	struct mlme_ext_info *pmlmeinfo;
9244 
9245 
9246 	pmlmeext = &padapter->mlmeextpriv;
9247 	pmlmeinfo = &pmlmeext->mlmext_info;
9248 
9249 	/* da == NULL, assum it's null data for sta to ap*/
9250 	if (da == NULL)
9251 		da = get_my_bssid(&(pmlmeinfo->network));
9252 
9253 	ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
9254 
9255 	return ret;
9256 }
9257 
9258 //when wait_ack is ture, this function shoule be called at process context
_issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,int wait_ack)9259 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
9260 {
9261 	int ret = _FAIL;
9262 	struct xmit_frame			*pmgntframe;
9263 	struct pkt_attrib			*pattrib;
9264 	unsigned char					*pframe;
9265 	struct rtw_ieee80211_hdr	*pwlanhdr;
9266 	unsigned short				*fctrl, *qc;
9267 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
9268 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9269 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9270 
9271 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9272 		goto exit;
9273 
9274 	DBG_871X("%s\n", __FUNCTION__);
9275 
9276 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9277 	{
9278 		goto exit;
9279 	}
9280 
9281 	//update attribute
9282 	pattrib = &pmgntframe->attrib;
9283 	update_mgntframe_attrib(padapter, pattrib);
9284 
9285 	pattrib->hdrlen +=2;
9286 	pattrib->qos_en = _TRUE;
9287 	pattrib->eosp = 1;
9288 	pattrib->ack_policy = 0;
9289 	pattrib->mdata = 0;
9290 
9291 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9292 
9293 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9294 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9295 
9296 	fctrl = &(pwlanhdr->frame_ctl);
9297 	*(fctrl) = 0;
9298 
9299 	if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9300 	{
9301 		SetFrDs(fctrl);
9302 	}
9303 	else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9304 	{
9305 		SetToDs(fctrl);
9306 	}
9307 
9308 	if(pattrib->mdata)
9309 		SetMData(fctrl);
9310 
9311 	qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9312 
9313 	SetPriority(qc, tid);
9314 
9315 	SetEOSP(qc, pattrib->eosp);
9316 
9317 	SetAckpolicy(qc, pattrib->ack_policy);
9318 
9319 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9320 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9321 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9322 
9323 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9324 	pmlmeext->mgnt_seq++;
9325 	SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
9326 
9327 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9328 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9329 
9330 	pattrib->last_txcmdsz = pattrib->pktlen;
9331 
9332 	if(wait_ack)
9333 	{
9334 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9335 	}
9336 	else
9337 	{
9338 		dump_mgntframe(padapter, pmgntframe);
9339 		ret = _SUCCESS;
9340 	}
9341 
9342 exit:
9343 	return ret;
9344 }
9345 
9346 /*
9347  * when wait_ms >0 , this function should be called at process context
9348  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9349  * 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
9350  * try_cnt means the maximal TX count to try
9351  * da == NULL for station mode
9352  */
issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,int try_cnt,int wait_ms)9353 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
9354 {
9355 	int ret = _FAIL;
9356 	int i = 0;
9357 	u32 start = rtw_get_current_time();
9358 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9359 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9360 
9361 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9362 		goto exit;
9363 
9364 	/* da == NULL, assum it's null data for sta to ap*/
9365 	if (da == NULL)
9366 		da = get_my_bssid(&(pmlmeinfo->network));
9367 
9368 	do
9369 	{
9370 		ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
9371 
9372 		i++;
9373 
9374 		if (RTW_CANNOT_RUN(padapter))
9375 			break;
9376 
9377 		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9378 			rtw_msleep_os(wait_ms);
9379 
9380 	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9381 
9382 	if (ret != _FAIL) {
9383 		ret = _SUCCESS;
9384 		#ifndef DBG_XMIT_ACK
9385 		goto exit;
9386 		#endif
9387 	}
9388 
9389 	if (try_cnt && wait_ms) {
9390 		if (da)
9391 			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9392 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9393 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9394 		else
9395 			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9396 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9397 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9398 	}
9399 exit:
9400 	return ret;
9401 }
9402 
_issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason,u8 wait_ack,u8 key_type)9403 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9404 {
9405 	struct xmit_frame			*pmgntframe;
9406 	struct pkt_attrib			*pattrib;
9407 	unsigned char					*pframe;
9408 	struct rtw_ieee80211_hdr	*pwlanhdr;
9409 	unsigned short				*fctrl;
9410 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
9411 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9412 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9413 	int ret = _FAIL;
9414 #ifdef CONFIG_P2P
9415 	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
9416 #endif //CONFIG_P2P
9417 
9418 	//DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9419 
9420 #ifdef CONFIG_P2P
9421 	if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
9422 	{
9423 		_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
9424 		_set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
9425 	}
9426 #endif //CONFIG_P2P
9427 
9428 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9429 		goto exit;
9430 
9431 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9432 	{
9433 		goto exit;
9434 	}
9435 
9436 	//update attribute
9437 	pattrib = &pmgntframe->attrib;
9438 	update_mgntframe_attrib(padapter, pattrib);
9439 	pattrib->retry_ctrl = _FALSE;
9440 	pattrib->key_type = key_type;
9441 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9442 
9443 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9444 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9445 
9446 	fctrl = &(pwlanhdr->frame_ctl);
9447 	*(fctrl) = 0;
9448 
9449 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9450 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9451 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9452 
9453 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9454 	pmlmeext->mgnt_seq++;
9455 	SetFrameSubType(pframe, WIFI_DEAUTH);
9456 
9457 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9458 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9459 
9460 	reason = cpu_to_le16(reason);
9461 	pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9462 
9463 	pattrib->last_txcmdsz = pattrib->pktlen;
9464 
9465 
9466 	if(wait_ack)
9467 	{
9468 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9469 	}
9470 	else
9471 	{
9472 		dump_mgntframe(padapter, pmgntframe);
9473 		ret = _SUCCESS;
9474 	}
9475 
9476 exit:
9477 	return ret;
9478 }
9479 
issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason)9480 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9481 {
9482 	DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9483 	return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9484 }
9485 
9486 #ifdef CONFIG_IEEE80211W
issue_deauth_11w(_adapter * padapter,unsigned char * da,unsigned short reason,u8 key_type)9487 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9488 {
9489 	DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9490 	return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9491 }
9492 #endif /* CONFIG_IEEE80211W */
9493 
9494 /*
9495  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9496  * 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
9497  * try_cnt means the maximal TX count to try
9498  */
issue_deauth_ex(_adapter * padapter,u8 * da,unsigned short reason,int try_cnt,int wait_ms)9499 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9500 	int wait_ms)
9501 {
9502 	int ret = _FAIL;
9503 	int i = 0;
9504 	u32 start = rtw_get_current_time();
9505 
9506 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9507 		goto exit;
9508 
9509 	do
9510 	{
9511 		ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE:_FALSE, IEEE80211W_RIGHT_KEY);
9512 
9513 		i++;
9514 
9515 		if (RTW_CANNOT_RUN(padapter))
9516 			break;
9517 
9518 		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9519 			rtw_msleep_os(wait_ms);
9520 
9521 	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9522 
9523 	if (ret != _FAIL) {
9524 		ret = _SUCCESS;
9525 		#ifndef DBG_XMIT_ACK
9526 		goto exit;
9527 		#endif
9528 	}
9529 
9530 	if (try_cnt && wait_ms) {
9531 		if (da)
9532 			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9533 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9534 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9535 		else
9536 			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9537 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9538 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9539 	}
9540 exit:
9541 	return ret;
9542 }
9543 
issue_action_spct_ch_switch(_adapter * padapter,u8 * ra,u8 new_ch,u8 ch_offset)9544 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9545 {
9546 	_irqL	irqL;
9547 	_list		*plist, *phead;
9548 	struct xmit_frame			*pmgntframe;
9549 	struct pkt_attrib			*pattrib;
9550 	unsigned char				*pframe;
9551 	struct rtw_ieee80211_hdr	*pwlanhdr;
9552 	unsigned short			*fctrl;
9553 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
9554 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9555 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9556 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9557 
9558 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9559 		return;
9560 
9561 	DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9562 		FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9563 
9564 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9565 		return;
9566 
9567 	//update attribute
9568 	pattrib = &pmgntframe->attrib;
9569 	update_mgntframe_attrib(padapter, pattrib);
9570 
9571 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9572 
9573 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9574 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9575 
9576 	fctrl = &(pwlanhdr->frame_ctl);
9577 	*(fctrl) = 0;
9578 
9579 	_rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9580 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9581 	_rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9582 
9583 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9584 	pmlmeext->mgnt_seq++;
9585 	SetFrameSubType(pframe, WIFI_ACTION);
9586 
9587 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9588 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9589 
9590 	/* category, action */
9591 	{
9592 		u8 category, action;
9593 		category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9594 		action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9595 
9596 		pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9597 		pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9598 	}
9599 
9600 	pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9601 	pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9602 		hal_ch_offset_to_secondary_ch_offset(ch_offset));
9603 
9604 	pattrib->last_txcmdsz = pattrib->pktlen;
9605 
9606 	dump_mgntframe(padapter, pmgntframe);
9607 
9608 }
9609 
9610 #ifdef CONFIG_IEEE80211W
issue_action_SA_Query(_adapter * padapter,unsigned char * raddr,unsigned char action,unsigned short tid,u8 key_type)9611 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9612 {
9613 	u8	category = RTW_WLAN_CATEGORY_SA_QUERY;
9614 	u16	reason_code;
9615 	struct xmit_frame		*pmgntframe;
9616 	struct pkt_attrib		*pattrib;
9617 	u8					*pframe;
9618 	struct rtw_ieee80211_hdr	*pwlanhdr;
9619 	u16					*fctrl;
9620 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
9621 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9622 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9623 	struct sta_info		*psta;
9624 	struct sta_priv		*pstapriv = &padapter->stapriv;
9625 	struct registry_priv	 	*pregpriv = &padapter->registrypriv;
9626 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9627 
9628 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9629 		return;
9630 
9631 	DBG_871X("%s, %04x\n", __FUNCTION__, tid);
9632 
9633 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9634 	{
9635 		DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9636 		return;
9637 	}
9638 
9639 	//update attribute
9640 	pattrib = &pmgntframe->attrib;
9641 	update_mgntframe_attrib(padapter, pattrib);
9642 	pattrib->key_type = key_type;
9643 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9644 
9645 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9646 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9647 
9648 	fctrl = &(pwlanhdr->frame_ctl);
9649 	*(fctrl) = 0;
9650 
9651 	if(raddr)
9652 		_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9653 	else
9654 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9655 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9656 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9657 
9658 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9659 	pmlmeext->mgnt_seq++;
9660 	SetFrameSubType(pframe, WIFI_ACTION);
9661 
9662 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9663 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9664 
9665 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9666 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9667 
9668 	switch (action)
9669 	{
9670 		case 0: //SA Query req
9671 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9672 			pmlmeext->sa_query_seq++;
9673 			/* send sa query request to AP, AP should reply sa query response in 1 second */
9674 			if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9675 				psta = rtw_get_stainfo(pstapriv, raddr);
9676 				if (psta != NULL) {
9677 					/* DBG_871X("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9678 					_set_timer(&psta->dot11w_expire_timer, 1000);
9679 				}
9680 			}
9681 			break;
9682 
9683 		case 1: //SA Query rsp
9684 			tid = cpu_to_le16(tid);
9685 			/* DBG_871X("rtw_set_fixed_ie, %04x\n", tid); */
9686 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9687 			break;
9688 		default:
9689 			break;
9690 	}
9691 
9692 	pattrib->last_txcmdsz = pattrib->pktlen;
9693 
9694 	dump_mgntframe(padapter, pmgntframe);
9695 }
9696 #endif //CONFIG_IEEE80211W
9697 
9698 /**
9699  * issue_action_ba - internal function to TX Block Ack action frame
9700  * @padapter: the adapter to TX
9701  * @raddr: receiver address
9702  * @action: Block Ack Action
9703  * @tid: tid
9704  * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9705  * @status: status/reason code. used by ADDBA_RESP, DELBA
9706  * @initiator: if we are the initiator of AMPDU association. used by DELBA
9707  * @wait_ack: used xmit ack
9708  *
9709  * Returns:
9710  * _SUCCESS: No xmit ack is used or acked
9711  * _FAIL: not acked when using xmit ack
9712  */
issue_action_ba(_adapter * padapter,unsigned char * raddr,unsigned char action,u8 tid,u8 size,u16 status,u8 initiator,int wait_ack)9713 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9714 	, u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9715 {
9716 	int ret = _FAIL;
9717 	u8	category = RTW_WLAN_CATEGORY_BACK;
9718 	u16	start_seq;
9719 	u16	BA_para_set;
9720 	u16	BA_timeout_value;
9721 	u16	BA_starting_seqctrl;
9722 	struct xmit_frame		*pmgntframe;
9723 	struct pkt_attrib		*pattrib;
9724 	u8					*pframe;
9725 	struct rtw_ieee80211_hdr	*pwlanhdr;
9726 	u16					*fctrl;
9727 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
9728 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9729 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9730 	struct sta_info		*psta;
9731 	struct sta_priv		*pstapriv = &padapter->stapriv;
9732 	struct registry_priv	 	*pregpriv = &padapter->registrypriv;
9733 
9734 #ifdef CONFIG_80211N_HT
9735 
9736 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9737 		goto exit;
9738 
9739 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9740 		goto exit;
9741 
9742 	//update attribute
9743 	pattrib = &pmgntframe->attrib;
9744 	update_mgntframe_attrib(padapter, pattrib);
9745 
9746 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9747 
9748 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9749 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9750 
9751 	fctrl = &(pwlanhdr->frame_ctl);
9752 	*(fctrl) = 0;
9753 
9754 	//_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9755 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9756 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9757 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9758 
9759 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9760 	pmlmeext->mgnt_seq++;
9761 	SetFrameSubType(pframe, WIFI_ACTION);
9762 
9763 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9764 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9765 
9766 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9767 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9768 
9769 	if (category == 3)
9770 	{
9771 		switch (action)
9772 		{
9773 			case RTW_WLAN_ACTION_ADDBA_REQ:
9774 				do {
9775 					pmlmeinfo->dialogToken++;
9776 				} while (pmlmeinfo->dialogToken == 0);
9777 				pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9778 
9779 				#if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9780 				BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9781 				#else
9782 				BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9783 				#endif
9784 
9785 				BA_para_set = cpu_to_le16(BA_para_set);
9786 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9787 
9788 				//BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
9789 				BA_timeout_value = 5000;//~ 5ms
9790 				BA_timeout_value = cpu_to_le16(BA_timeout_value);
9791 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9792 
9793 				//if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
9794 				if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
9795 				{
9796 					start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1;
9797 
9798 					DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9799 
9800 					psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9801 
9802 					BA_starting_seqctrl = start_seq << 4;
9803 				}
9804 
9805 				BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9806 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9807 				break;
9808 
9809 			case RTW_WLAN_ACTION_ADDBA_RESP:
9810 				pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9811 				status = cpu_to_le16(status);
9812 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9813 
9814 				BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9815 
9816 				BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9817 				BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9818 
9819 				BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9820 				BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9821 
9822 				if (!padapter->registrypriv.wifi_spec) {
9823 					if(pregpriv->ampdu_amsdu==0)//disabled
9824 						BA_para_set &= ~BIT(0);
9825 					else if(pregpriv->ampdu_amsdu==1)//enabled
9826 						BA_para_set |= BIT(0);
9827 				}
9828 
9829 				BA_para_set = cpu_to_le16(BA_para_set);
9830 
9831 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9832 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9833 				break;
9834 
9835 			case RTW_WLAN_ACTION_DELBA:
9836 				BA_para_set = 0;
9837 				BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9838 				BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9839 
9840 				BA_para_set = cpu_to_le16(BA_para_set);
9841 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9842 				status = cpu_to_le16(status);
9843 				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9844 				break;
9845 			default:
9846 				break;
9847 		}
9848 	}
9849 
9850 	pattrib->last_txcmdsz = pattrib->pktlen;
9851 
9852 	if (wait_ack) {
9853 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9854 	} else {
9855 		dump_mgntframe(padapter, pmgntframe);
9856 		ret = _SUCCESS;
9857 	}
9858 
9859 exit:
9860 #endif //CONFIG_80211N_HT
9861 	return ret;
9862 }
9863 
9864 /**
9865  * issue_addba_req - TX ADDBA_REQ
9866  * @adapter: the adapter to TX
9867  * @ra: receiver address
9868  * @tid: tid
9869  */
issue_addba_req(_adapter * adapter,unsigned char * ra,u8 tid)9870 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
9871 {
9872 	issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
9873 		, tid
9874 		, 0 /* unused */
9875 		, 0 /* unused */
9876 		, 0 /* unused */
9877 		, _FALSE
9878 	);
9879 	DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
9880 		, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
9881 
9882 }
9883 
9884 /**
9885  * issue_addba_rsp - TX ADDBA_RESP
9886  * @adapter: the adapter to TX
9887  * @ra: receiver address
9888  * @tid: tid
9889  * @status: status code
9890  * @size: the announced AMPDU buffer size
9891  */
issue_addba_rsp(_adapter * adapter,unsigned char * ra,u8 tid,u16 status,u8 size)9892 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
9893 {
9894 	issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9895 		, tid
9896 		, size
9897 		, status
9898 		, 0 /* unused */
9899 		, _FALSE
9900 	);
9901 	DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
9902 		, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
9903 }
9904 
9905 /**
9906  * issue_del_ba - TX DELBA
9907  * @adapter: the adapter to TX
9908  * @ra: receiver address
9909  * @tid: tid
9910  * @reason: reason code
9911  * @initiator: if we are the initiator of AMPDU association. used by DELBA
9912  */
issue_del_ba(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator)9913 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
9914 {
9915 	issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
9916 		, tid
9917 		, 0 /* unused */
9918 		, reason
9919 		, initiator
9920 		, _FALSE
9921 	);
9922 	DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
9923 		, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
9924 }
9925 
9926 /**
9927  * issue_del_ba_ex - TX DELBA with xmit ack options
9928  * @adapter: the adapter to TX
9929  * @ra: receiver address
9930  * @tid: tid
9931  * @reason: reason code
9932  * @initiator: if we are the initiator of AMPDU association. used by DELBA
9933  * @try_cnt: the maximal TX count to try
9934  * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9935  *           > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9936  */
issue_del_ba_ex(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator,int try_cnt,int wait_ms)9937 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
9938 	, int try_cnt, int wait_ms)
9939 {
9940 	int ret = _FAIL;
9941 	int i = 0;
9942 	u32 start = rtw_get_current_time();
9943 
9944 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
9945 		goto exit;
9946 
9947 	do {
9948 		ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
9949 			, tid
9950 			, 0 /* unused */
9951 			, reason
9952 			, initiator
9953 			, wait_ms > 0?_TRUE:_FALSE
9954 		);
9955 
9956 		i++;
9957 
9958 		if (RTW_CANNOT_RUN(adapter))
9959 			break;
9960 
9961 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9962 			rtw_msleep_os(wait_ms);
9963 
9964 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9965 
9966 	if (ret != _FAIL) {
9967 		ret = _SUCCESS;
9968 	#ifndef DBG_XMIT_ACK
9969 		/* goto exit; */
9970 	#endif
9971 	}
9972 
9973 	if (try_cnt && wait_ms) {
9974 		DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
9975 			, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
9976 			, ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9977 	}
9978 exit:
9979 	return ret;
9980 }
9981 
issue_action_BSSCoexistPacket(_adapter * padapter)9982 static void issue_action_BSSCoexistPacket(_adapter *padapter)
9983 {
9984 	_irqL	irqL;
9985 	_list		*plist, *phead;
9986 	unsigned char category, action;
9987 	struct xmit_frame			*pmgntframe;
9988 	struct pkt_attrib			*pattrib;
9989 	unsigned char				*pframe;
9990 	struct rtw_ieee80211_hdr	*pwlanhdr;
9991 	unsigned short			*fctrl;
9992 	struct	wlan_network	*pnetwork = NULL;
9993 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
9994 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9995 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9996 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9997 	_queue		*queue	= &(pmlmepriv->scanned_queue);
9998 	u8 InfoContent[16] = {0};
9999 	u8 ICS[8][15];
10000 #ifdef CONFIG_80211N_HT
10001 	if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
10002 		return;
10003 
10004 	if(_TRUE == pmlmeinfo->bwmode_updated)
10005 		return;
10006 
10007 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10008 		return;
10009 
10010 	DBG_871X("%s\n", __FUNCTION__);
10011 
10012 
10013 	category = RTW_WLAN_CATEGORY_PUBLIC;
10014 	action = ACT_PUBLIC_BSSCOEXIST;
10015 
10016 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10017 	{
10018 		return;
10019 	}
10020 
10021 	//update attribute
10022 	pattrib = &pmgntframe->attrib;
10023 	update_mgntframe_attrib(padapter, pattrib);
10024 
10025 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10026 
10027 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10028 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10029 
10030 	fctrl = &(pwlanhdr->frame_ctl);
10031 	*(fctrl) = 0;
10032 
10033 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10034 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10035 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10036 
10037 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10038 	pmlmeext->mgnt_seq++;
10039 	SetFrameSubType(pframe, WIFI_ACTION);
10040 
10041 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10042 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10043 
10044 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10045 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10046 
10047 
10048 	//
10049 	if(pmlmepriv->num_FortyMHzIntolerant>0)
10050 	{
10051 		u8 iedata=0;
10052 
10053 		iedata |= BIT(2);//20 MHz BSS Width Request
10054 
10055 		pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &(pattrib->pktlen));
10056 
10057 	}
10058 
10059 
10060 	//
10061 	_rtw_memset(ICS, 0, sizeof(ICS));
10062 	if(pmlmepriv->num_sta_no_ht>0)
10063 	{
10064 		int i;
10065 
10066 		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10067 
10068 		phead = get_list_head(queue);
10069 		plist = get_next(phead);
10070 
10071 		while(1)
10072 		{
10073 			int len;
10074 			u8 *p;
10075 			WLAN_BSSID_EX *pbss_network;
10076 
10077 			if (rtw_end_of_queue_search(phead,plist)== _TRUE)
10078 				break;
10079 
10080 			pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
10081 
10082 			plist = get_next(plist);
10083 
10084 			pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10085 
10086 			p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10087 			if((p==NULL) || (len==0))//non-HT
10088 			{
10089 				if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
10090 					continue;
10091 
10092 				ICS[0][pbss_network->Configuration.DSConfig]=1;
10093 
10094 				if(ICS[0][0] == 0)
10095 					ICS[0][0] = 1;
10096 			}
10097 
10098 		}
10099 
10100 		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10101 
10102 
10103 		for(i= 0;i<8;i++)
10104 		{
10105 			if(ICS[i][0] == 1)
10106 			{
10107 				int j, k = 0;
10108 
10109 				InfoContent[k] = i;
10110 				//SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
10111 				k++;
10112 
10113 				for(j=1;j<=14;j++)
10114 				{
10115 					if(ICS[i][j]==1)
10116 					{
10117 						if(k<16)
10118 						{
10119 							InfoContent[k] = j; //channel number
10120 							//SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
10121 							k++;
10122 						}
10123 					}
10124 				}
10125 
10126 				pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10127 
10128 			}
10129 
10130 		}
10131 
10132 
10133 	}
10134 
10135 
10136 	pattrib->last_txcmdsz = pattrib->pktlen;
10137 
10138 	dump_mgntframe(padapter, pmgntframe);
10139 #endif //CONFIG_80211N_HT
10140 }
10141 
10142 // Spatial Multiplexing Powersave (SMPS) action frame
_issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,u8 wait_ack)10143 int _issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode ,  u8 wait_ack)
10144 {
10145 
10146 	int ret = _FAIL;
10147 	unsigned char category = RTW_WLAN_CATEGORY_HT;
10148 	u8 action = RTW_WLAN_ACTION_HT_SM_PS;
10149 	u8 sm_power_control=0;
10150 	struct xmit_frame			*pmgntframe;
10151 	struct pkt_attrib			*pattrib;
10152 	unsigned char					*pframe;
10153 	struct rtw_ieee80211_hdr	*pwlanhdr;
10154 	unsigned short				*fctrl;
10155 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
10156 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10157 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10158 
10159 
10160 	if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED)
10161 	{
10162 		sm_power_control = sm_power_control  & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable
10163 	}
10164         else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC)
10165         {
10166                 sm_power_control = sm_power_control | BIT(0);    // SM Power Save Enable = 1 SM Power Save Enable
10167                 sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode
10168         }
10169         else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC)
10170         {
10171                 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
10172                 sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode
10173         }
10174         else
10175 		return ret;
10176 
10177 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10178 		return ret;
10179 
10180         DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode );
10181 
10182 	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10183 		return ret;
10184 
10185 	//update attribute
10186 	pattrib = &pmgntframe->attrib;
10187 	update_mgntframe_attrib(padapter, pattrib);
10188 
10189 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10190 
10191 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10192 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10193 
10194 	fctrl = &(pwlanhdr->frame_ctl);
10195 	*(fctrl) = 0;
10196 
10197 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10198 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10199 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10200 
10201 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10202 	pmlmeext->mgnt_seq++;
10203 	SetFrameSubType(pframe, WIFI_ACTION);
10204 
10205 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10206 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10207 
10208 	/* category, action */
10209 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10210 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10211 
10212 	pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10213 
10214 	pattrib->last_txcmdsz = pattrib->pktlen;
10215 
10216 	if(wait_ack)
10217 	{
10218 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10219 	}
10220 	else
10221 	{
10222 		dump_mgntframe(padapter, pmgntframe);
10223 		ret = _SUCCESS;
10224 	}
10225 
10226         if (ret != _SUCCESS)
10227             DBG_8192C("%s, ack to\n", __func__);
10228 
10229 	return ret;
10230 }
10231 
10232 /*
10233  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10234  * 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
10235  * try_cnt means the maximal TX count to try
10236  */
issue_action_SM_PS_wait_ack(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,int try_cnt,int wait_ms)10237 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10238 {
10239 	int ret = _FAIL;
10240 	int i = 0;
10241 	u32 start = rtw_get_current_time();
10242 
10243 	if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10244 		goto exit;
10245 
10246 	do {
10247 		ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE );
10248 
10249 		i++;
10250 
10251 		if (RTW_CANNOT_RUN(padapter))
10252 			break;
10253 
10254 		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
10255 			rtw_msleep_os(wait_ms);
10256 
10257 	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
10258 
10259 	if (ret != _FAIL) {
10260 		ret = _SUCCESS;
10261 		#ifndef DBG_XMIT_ACK
10262 		goto exit;
10263 		#endif
10264 	}
10265 
10266 	if (try_cnt && wait_ms) {
10267 		if (raddr)
10268 			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10269 				FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10270 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10271 		else
10272 			DBG_871X(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10273 				FUNC_ADPT_ARG(padapter),
10274 				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10275 	}
10276 exit:
10277 
10278 	return ret;
10279 }
10280 
issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode)10281 int issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode )
10282 {
10283 	DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10284 	return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE );
10285 }
10286 
10287 /**
10288  * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10289  * @adapter: the adapter to which @sta belongs
10290  * @initiator: if we are the initiator of AMPDU association
10291  * @sta: the sta to be checked
10292  * @tid: the tid to be checked
10293  * @force: cancel and send DELBA even when no AMPDU association is setup
10294  * @wait_ack: send delba with xmit ack (valid when initiator == 0)
10295  *
10296  * Returns:
10297  * _FAIL if sta is NULL
10298  * when initiator is 1, always _SUCCESS
10299  * when initiator is 0, _SUCCESS if DELBA is acked
10300  */
_send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force,int wait_ack)10301 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10302 	, u8 force, int wait_ack)
10303 {
10304 	int ret = _SUCCESS;
10305 
10306 	if (sta == NULL) {
10307 		ret = _FAIL;
10308 		goto exit;
10309 	}
10310 
10311 	if (initiator == 0) {
10312 		/* recipient */
10313 		if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10314 			u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10315 
10316 			sta->recvreorder_ctrl[tid].enable = _FALSE;
10317 			sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10318 
10319 			if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10320 				ret = _FAIL;
10321 			else if (wait_ack)
10322 				ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
10323 			else
10324 				issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10325 
10326 			if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10327 				sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10328 		}
10329 	} else if (initiator == 1) {
10330 		/* originator */
10331 #ifdef CONFIG_80211N_HT
10332 		if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10333 			sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10334 			sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10335 			issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10336 		}
10337 #endif
10338 	}
10339 
10340 exit:
10341 	return ret;
10342 }
10343 
send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)10344 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10345 	, u8 force)
10346 {
10347 	return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10348 }
10349 
send_delba_sta_tid_wait_ack(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)10350 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10351 	, u8 force)
10352 {
10353 	return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10354 }
10355 
send_delba(_adapter * padapter,u8 initiator,u8 * addr)10356 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10357 {
10358 	struct sta_priv *pstapriv = &padapter->stapriv;
10359 	struct sta_info *psta = NULL;
10360 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
10361 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10362 	u16 tid;
10363 
10364 	if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
10365 		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10366 			return _SUCCESS;
10367 
10368 	psta = rtw_get_stainfo(pstapriv, addr);
10369 	if(psta==NULL)
10370 		return _SUCCESS;
10371 
10372 	#if 0
10373 	DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR");
10374 	if (initiator == 1) /* originator */
10375 		DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10376 	#endif
10377 
10378 	for (tid = 0; tid < TID_NUM; tid++)
10379 		send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10380 
10381 	return _SUCCESS;
10382 }
10383 #ifdef CONFIG_AP_MODE
send_beacon(_adapter * padapter)10384 unsigned int send_beacon(_adapter *padapter)
10385 {
10386 	u8	bxmitok = _FALSE;
10387 	int	issue=0;
10388 	int poll = 0;
10389 //#ifdef CONFIG_CONCURRENT_MODE
10390 	//struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10391 	//struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10392 	//_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
10393 	//struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
10394 //#endif
10395 
10396 #ifdef CONFIG_PCI_HCI
10397 	//DBG_871X("%s\n", __FUNCTION__);
10398 
10399 	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10400 
10401 	/* 8192EE Port select for Beacon DL */
10402 	rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10403 
10404 	issue_beacon(padapter, 0);
10405 
10406 	return _SUCCESS;
10407 #endif
10408 
10409 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10410 	u32 start = rtw_get_current_time();
10411 
10412 	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10413 	rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10414 	do{
10415 		issue_beacon(padapter, 100);
10416 		issue++;
10417 		do {
10418 			rtw_yield_os();
10419 			rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10420 			poll++;
10421 		} while ((poll%10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10422 
10423 	} while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter));
10424 
10425 	if (RTW_CANNOT_RUN(padapter))
10426 		return _FAIL;
10427 
10428 
10429 	if(_FALSE == bxmitok)
10430 	{
10431 		DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10432 		return _FAIL;
10433 	}
10434 	else
10435 	{
10436 		u32 passing_time = rtw_get_passing_time_ms(start);
10437 
10438 		if(passing_time > 100 || issue > 3)
10439 			DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10440 		//else
10441 		//	DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10442 
10443 		return _SUCCESS;
10444 	}
10445 
10446 #endif
10447 
10448 }
10449 #endif
10450 
10451 /****************************************************************************
10452 
10453 Following are some utitity fuctions for WiFi MLME
10454 
10455 *****************************************************************************/
10456 
IsLegal5GChannel(IN PADAPTER Adapter,IN u8 channel)10457 BOOLEAN IsLegal5GChannel(
10458 	IN PADAPTER			Adapter,
10459 	IN u8			channel)
10460 {
10461 
10462 	int i=0;
10463 	u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
10464 		60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
10465 		124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
10466 		161,163,165};
10467 	for(i=0;i<sizeof(Channel_5G);i++)
10468 		if(channel == Channel_5G[i])
10469 			return _TRUE;
10470 	return _FALSE;
10471 }
10472 
10473 //collect bss info from Beacon and Probe request/response frames.
collect_bss_info(_adapter * padapter,union recv_frame * precv_frame,WLAN_BSSID_EX * bssid)10474 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10475 {
10476 	int	i;
10477 	u32	len;
10478 	u8	*p;
10479 	u16	val16, subtype;
10480 	u8	*pframe = precv_frame->u.hdr.rx_data;
10481 	u32	packet_len = precv_frame->u.hdr.len;
10482 	u8 ie_offset;
10483 	struct registry_priv 	*pregistrypriv = &padapter->registrypriv;
10484 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
10485 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10486 
10487 	len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10488 
10489 	if (len > MAX_IE_SZ)
10490 	{
10491 		//DBG_871X("IE too long for survey event\n");
10492 		return _FAIL;
10493 	}
10494 
10495 	_rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10496 
10497 	subtype = GetFrameSubType(pframe);
10498 
10499 	if(subtype==WIFI_BEACON) {
10500 		bssid->Reserved[0] = 1;
10501 		ie_offset = _BEACON_IE_OFFSET_;
10502 	} else {
10503 		// FIXME : more type
10504 		if (subtype == WIFI_PROBERSP) {
10505 			ie_offset = _PROBERSP_IE_OFFSET_;
10506 			bssid->Reserved[0] = 3;
10507 		}
10508 		else if (subtype == WIFI_PROBEREQ) {
10509 			ie_offset = _PROBEREQ_IE_OFFSET_;
10510 			bssid->Reserved[0] = 2;
10511 		}
10512 		else {
10513 			bssid->Reserved[0] = 0;
10514 			ie_offset = _FIXED_IE_LENGTH_;
10515 		}
10516 	}
10517 
10518 	bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10519 
10520 	//below is to copy the information element
10521 	bssid->IELength = len;
10522 	_rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10523 
10524 	//get the signal strength
10525 	//bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
10526 	bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
10527 	bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
10528 	bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
10529 #ifdef CONFIG_ANTENNA_DIVERSITY
10530 	//rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna));
10531 	rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA,  &bssid->PhyInfo.Optimum_antenna);
10532 #endif
10533 
10534 	// checking SSID
10535 	if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
10536 	{
10537 		DBG_871X("marc: cannot find SSID for survey event\n");
10538 		return _FAIL;
10539 	}
10540 
10541 	if (*(p + 1))
10542 	{
10543 		if (len > NDIS_802_11_LENGTH_SSID)
10544 		{
10545 			DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10546 			return _FAIL;
10547 		}
10548 		_rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10549 		bssid->Ssid.SsidLength = *(p + 1);
10550 	}
10551 	else
10552 	{
10553 		bssid->Ssid.SsidLength = 0;
10554 	}
10555 
10556 	_rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10557 
10558 	//checking rate info...
10559 	i = 0;
10560 	p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10561 	if (p != NULL)
10562 	{
10563 		if (len > NDIS_802_11_LENGTH_RATES_EX)
10564 		{
10565 			DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10566 			return _FAIL;
10567 		}
10568 		_rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10569 		i = len;
10570 	}
10571 
10572 	p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10573 	if (p != NULL)
10574 	{
10575 		if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
10576 		{
10577 			DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10578 			return _FAIL;
10579 		}
10580 		_rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10581 	}
10582 
10583 	//todo:
10584 #if 0
10585 	if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10586 	{
10587 		bssid->NetworkTypeInUse = Ndis802_11DS;
10588 	}
10589 	else
10590 #endif
10591 	{
10592 		bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10593 	}
10594 
10595 #ifdef CONFIG_P2P
10596 	if (subtype == WIFI_PROBEREQ)
10597 	{
10598 		u8 *p2p_ie;
10599 		u32	p2p_ielen;
10600 		// Set Listion Channel
10601 		if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen)))
10602 		{
10603 			u32	attr_contentlen = 0;
10604 			u8 listen_ch[5] = { 0x00 };
10605 
10606 			rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10607 			bssid->Configuration.DSConfig = listen_ch[4];
10608 		} else
10609 		{ // use current channel
10610 			bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10611 			DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10612 		}
10613 
10614 		// FIXME
10615 		bssid->InfrastructureMode = Ndis802_11Infrastructure;
10616 		_rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10617 		bssid->Privacy = 1;
10618 		return _SUCCESS;
10619 	}
10620 #endif //CONFIG_P2P
10621 
10622 	if (bssid->IELength < 12)
10623 		return _FAIL;
10624 
10625 	// Checking for DSConfig
10626 	p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10627 
10628 	bssid->Configuration.DSConfig = 0;
10629 	bssid->Configuration.Length = 0;
10630 
10631 	if (p)
10632 	{
10633 		bssid->Configuration.DSConfig = *(p + 2);
10634 	}
10635 	else
10636 	{// In 5G, some ap do not have DSSET IE
10637 		// checking HT info for channel
10638 		p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10639 		if(p)
10640 		{
10641 			struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10642 			bssid->Configuration.DSConfig = HT_info->primary_channel;
10643 		}
10644 		else
10645 		{ // use current channel
10646 			bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
10647 		}
10648 	}
10649 
10650 	_rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
10651 	bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
10652 
10653 	val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
10654 
10655 	if (val16 & BIT(0))
10656 	{
10657 		bssid->InfrastructureMode = Ndis802_11Infrastructure;
10658 		_rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10659 	}
10660 	else
10661 	{
10662 		bssid->InfrastructureMode = Ndis802_11IBSS;
10663 		_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10664 	}
10665 
10666 	if (val16 & BIT(4))
10667 		bssid->Privacy = 1;
10668 	else
10669 		bssid->Privacy = 0;
10670 
10671 	bssid->Configuration.ATIMWindow = 0;
10672 
10673 	//20/40 BSS Coexistence check
10674 	if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
10675 	{
10676 		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10677 #ifdef CONFIG_80211N_HT
10678 		p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10679 		if(p && len>0)
10680 		{
10681 			struct HT_caps_element	*pHT_caps;
10682 			pHT_caps = (struct HT_caps_element	*)(p + 2);
10683 
10684 			if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
10685 			{
10686 				pmlmepriv->num_FortyMHzIntolerant++;
10687 			}
10688 		}
10689 		else
10690 		{
10691 			pmlmepriv->num_sta_no_ht++;
10692 		}
10693 #endif //CONFIG_80211N_HT
10694 
10695 	}
10696 
10697 #ifdef CONFIG_INTEL_WIDI
10698 	//process_intel_widi_query_or_tigger(padapter, bssid);
10699 	if(process_intel_widi_query_or_tigger(padapter, bssid))
10700 	{
10701 		return _FAIL;
10702 	}
10703 #endif // CONFIG_INTEL_WIDI
10704 
10705 	#if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10706 	if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10707 		DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10708 			, bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10709 			, rtw_get_oper_ch(padapter)
10710 			, bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10711 		);
10712 	}
10713 	#endif
10714 
10715 	// mark bss info receving from nearby channel as SignalQuality 101
10716 	if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10717 	{
10718 		bssid->PhyInfo.SignalQuality= 101;
10719 	}
10720 
10721 	return _SUCCESS;
10722 }
10723 #ifdef CONFIG_ADHOC_MODE
start_create_ibss(_adapter * padapter)10724 void start_create_ibss(_adapter* padapter)
10725 {
10726 	unsigned short	caps;
10727 	u8	val8;
10728 	u8	join_type;
10729 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
10730 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10731 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10732 	pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10733 	pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10734 
10735 	//update wireless mode
10736 	update_wireless_mode(padapter);
10737 
10738 	//udpate capability
10739 	caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10740 	update_capinfo(padapter, caps);
10741 	if(caps&cap_IBSS)//adhoc master
10742 	{
10743 		//set_opmode_cmd(padapter, adhoc);//removed
10744 
10745 		val8 = 0xcf;
10746 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10747 
10748 		rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
10749 
10750 		//switch channel
10751 		//SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
10752 		set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10753 
10754 		beacon_timing_control(padapter);
10755 
10756 		//set msr to WIFI_FW_ADHOC_STATE
10757 		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10758 		Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10759 
10760 		//issue beacon
10761 		if(send_beacon(padapter)==_FAIL)
10762 		{
10763 			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
10764 
10765 			report_join_res(padapter, -1);
10766 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
10767 		}
10768 		else
10769 		{
10770 			rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10771 			join_type = 0;
10772 			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10773 
10774 			report_join_res(padapter, 1);
10775 			pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10776 			rtw_indicate_connect(padapter);
10777 		}
10778 	}
10779 	else
10780 	{
10781 		DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
10782 		return;
10783 	}
10784 	//update bc/mc sta_info
10785 	update_bmc_sta(padapter);
10786 
10787 }
10788 #endif /*CONFIG_ADHOC_MODE*/
10789 
start_clnt_join(_adapter * padapter)10790 void start_clnt_join(_adapter* padapter)
10791 {
10792 	unsigned short	caps;
10793 	u8	val8;
10794 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
10795 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10796 	WLAN_BSSID_EX	*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10797 	int beacon_timeout;
10798 	u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
10799 	u8 E2500_ID[]= {0x20, 0xAA, 0x4B};
10800 	u8 iot_flag = _FALSE;
10801 
10802 	//update wireless mode
10803 	update_wireless_mode(padapter);
10804 
10805 	//udpate capability
10806 	caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10807 	update_capinfo(padapter, caps);
10808 
10809 	//check if sta is ASIX peer and fix IOT issue if it is.
10810 	if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
10811 		iot_flag = _TRUE;
10812 		rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10813 	} else if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network),
10814 			       E2500_ID, 3)) {
10815 		iot_flag = _TRUE;
10816 		rtw_hal_set_hwreg(padapter, HW_VAR_E2500_IOT,
10817 				  (u8 *)(&iot_flag));
10818 		DBG_871X("%s: Join with Linksys E2500\n", __func__);
10819 	}
10820 
10821 	if (caps&cap_ESS)
10822 	{
10823 		Set_MSR(padapter, WIFI_FW_STATION_STATE);
10824 
10825 		val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
10826 
10827 #ifdef CONFIG_WAPI_SUPPORT
10828 		if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
10829 		{
10830 			//Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
10831 			val8 = 0x4c;
10832 		}
10833 #endif
10834 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10835 
10836 		#ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10837 		// Because of AP's not receiving deauth before
10838 		// AP may: 1)not response auth or 2)deauth us after link is complete
10839 		// issue deauth before issuing auth to deal with the situation
10840 
10841 		//	Commented by Albert 2012/07/21
10842 		//	For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
10843 		{
10844 			#ifdef CONFIG_P2P
10845 			_queue *queue = &(padapter->mlmepriv.scanned_queue);
10846 			_list	*head = get_list_head(queue);
10847 			_list *pos = get_next(head);
10848 			struct wlan_network *scanned = NULL;
10849 			u8 ie_offset = 0;
10850 			_irqL irqL;
10851 			bool has_p2p_ie = _FALSE;
10852 
10853 			_enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10854 
10855 			for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
10856 
10857 				scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
10858 
10859 				if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
10860 					&& _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
10861 				) {
10862 					ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
10863 					if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
10864 						has_p2p_ie = _TRUE;
10865 					break;
10866 				}
10867 			}
10868 
10869 			_exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10870 
10871 			if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
10872 			#endif /* CONFIG_P2P */
10873 				//To avoid connecting to AP fail during resume process, change retry count from 5 to 1
10874 				issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
10875 		}
10876 		#endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
10877 
10878 		//here wait for receiving the beacon to start auth
10879 		//and enable a timer
10880 		beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
10881 		set_link_timer(pmlmeext, beacon_timeout);
10882 		_set_timer( &padapter->mlmepriv.assoc_timer,
10883 			(REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
10884 
10885 		pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
10886 	}
10887 	else if (caps&cap_IBSS) //adhoc client
10888 	{
10889 		Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
10890 
10891 		val8 = 0xcf;
10892 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10893 
10894 		beacon_timing_control(padapter);
10895 
10896 		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10897 
10898 		report_join_res(padapter, 1);
10899 	}
10900 	else
10901 	{
10902 		//DBG_871X("marc: invalid cap:%x\n", caps);
10903 		return;
10904 	}
10905 
10906 }
10907 
start_clnt_auth(_adapter * padapter)10908 void start_clnt_auth(_adapter* padapter)
10909 {
10910 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
10911 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10912 
10913 	_cancel_timer_ex(&pmlmeext->link_timer);
10914 
10915 	pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
10916 	pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
10917 
10918 	pmlmeinfo->auth_seq = 1;
10919 	pmlmeinfo->reauth_count = 0;
10920 	pmlmeinfo->reassoc_count = 0;
10921 	pmlmeinfo->link_count = 0;
10922 	pmlmeext->retry = 0;
10923 
10924 
10925 	DBG_871X_LEVEL(_drv_always_, "start auth\n");
10926 	issue_auth(padapter, NULL, 0);
10927 
10928 	set_link_timer(pmlmeext, REAUTH_TO);
10929 
10930 }
10931 
10932 
start_clnt_assoc(_adapter * padapter)10933 void start_clnt_assoc(_adapter* padapter)
10934 {
10935 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
10936 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10937 
10938 	_cancel_timer_ex(&pmlmeext->link_timer);
10939 
10940 	pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
10941 	pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
10942 
10943 	issue_assocreq(padapter);
10944 
10945 	set_link_timer(pmlmeext, REASSOC_TO);
10946 }
10947 
receive_disconnect(_adapter * padapter,unsigned char * MacAddr,unsigned short reason)10948 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
10949 {
10950 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
10951 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10952 
10953 	if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
10954 		return _SUCCESS;
10955 
10956 	DBG_871X("%s\n", __FUNCTION__);
10957 
10958 	if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
10959 	{
10960 		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
10961 		{
10962 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
10963 			report_del_sta_event(padapter, MacAddr, reason, _TRUE);
10964 
10965 		}
10966 		else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
10967 		{
10968 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
10969 			report_join_res(padapter, -2);
10970 		} else
10971 			DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
10972 	}
10973 
10974 	return _SUCCESS;
10975 }
10976 
10977 #ifdef CONFIG_80211D
process_80211d(PADAPTER padapter,WLAN_BSSID_EX * bssid)10978 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
10979 {
10980 	struct registry_priv *pregistrypriv;
10981 	struct mlme_ext_priv *pmlmeext;
10982 	RT_CHANNEL_INFO *chplan_new;
10983 	u8 channel;
10984 	u8 i;
10985 
10986 
10987 	pregistrypriv = &padapter->registrypriv;
10988 	pmlmeext = &padapter->mlmeextpriv;
10989 
10990 	// Adjust channel plan by AP Country IE
10991 	if (pregistrypriv->enable80211d &&
10992 		(!pmlmeext->update_channel_plan_by_ap_done))
10993 	{
10994 		u8 *ie, *p;
10995 		u32 len;
10996 		RT_CHANNEL_PLAN chplan_ap;
10997 		RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
10998 		u8 country[4];
10999 		u8 fcn; // first channel number
11000 		u8 noc; // number of channel
11001 		u8 j, k;
11002 
11003 		ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11004 		if (!ie) return;
11005 		if (len < 6) return;
11006 
11007 		ie += 2;
11008 		p = ie;
11009 		ie += len;
11010 
11011 		_rtw_memset(country, 0, 4);
11012 		_rtw_memcpy(country, p, 3);
11013 		p += 3;
11014 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11015 				("%s: 802.11d country=%s\n", __FUNCTION__, country));
11016 
11017 		i = 0;
11018 		while ((ie - p) >= 3)
11019 		{
11020 			fcn = *(p++);
11021 			noc = *(p++);
11022 			p++;
11023 
11024 			for (j = 0; j < noc; j++)
11025 			{
11026 				if (fcn <= 14) channel = fcn + j; // 2.4 GHz
11027 				else channel = fcn + j*4; // 5 GHz
11028 
11029 				chplan_ap.Channel[i++] = channel;
11030 			}
11031 		}
11032 		chplan_ap.Len = i;
11033 
11034 #ifdef CONFIG_DEBUG_RTL871X
11035 		i = 0;
11036 		DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11037 		while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
11038 		{
11039 			DBG_8192C("%02d,", chplan_ap.Channel[i]);
11040 			i++;
11041 		}
11042 		DBG_871X("}\n");
11043 #endif
11044 
11045 		_rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
11046 #ifdef CONFIG_DEBUG_RTL871X
11047 		i = 0;
11048 		DBG_871X("%s: STA channel plan {", __FUNCTION__);
11049 		while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11050 		{
11051 			DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
11052 			i++;
11053 		}
11054 		DBG_871X("}\n");
11055 #endif
11056 
11057 		_rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
11058 		chplan_new = pmlmeext->channel_set;
11059 
11060 		i = j = k = 0;
11061 		if (pregistrypriv->wireless_mode & WIRELESS_11G)
11062 		{
11063 			do {
11064 				if ((i == MAX_CHANNEL_NUM) ||
11065 					(chplan_sta[i].ChannelNum == 0) ||
11066 					(chplan_sta[i].ChannelNum > 14))
11067 					break;
11068 
11069 				if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11070 					break;
11071 
11072 				if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11073 				{
11074 					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11075 					chplan_new[k].ScanType = SCAN_ACTIVE;
11076 					i++;
11077 					j++;
11078 					k++;
11079 				}
11080 				else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11081 				{
11082 					chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11083 //					chplan_new[k].ScanType = chplan_sta[i].ScanType;
11084 					chplan_new[k].ScanType = SCAN_PASSIVE;
11085 					i++;
11086 					k++;
11087 				}
11088 				else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11089 				{
11090 					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11091 					chplan_new[k].ScanType = SCAN_ACTIVE;
11092 					j++;
11093 					k++;
11094 				}
11095 			} while (1);
11096 
11097 			// change AP not support channel to Passive scan
11098 			while ((i < MAX_CHANNEL_NUM) &&
11099 				(chplan_sta[i].ChannelNum != 0) &&
11100 				(chplan_sta[i].ChannelNum <= 14))
11101 			{
11102 				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11103 //				chplan_new[k].ScanType = chplan_sta[i].ScanType;
11104 				chplan_new[k].ScanType = SCAN_PASSIVE;
11105 				i++;
11106 				k++;
11107 			}
11108 
11109 			// add channel AP supported
11110 			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11111 			{
11112 				chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11113 				chplan_new[k].ScanType = SCAN_ACTIVE;
11114 				j++;
11115 				k++;
11116 			}
11117 		}
11118 		else
11119 		{
11120 			// keep original STA 2.4G channel plan
11121 			while ((i < MAX_CHANNEL_NUM) &&
11122 				(chplan_sta[i].ChannelNum != 0) &&
11123 				(chplan_sta[i].ChannelNum <= 14))
11124 			{
11125 				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11126 				chplan_new[k].ScanType = chplan_sta[i].ScanType;
11127 				i++;
11128 				k++;
11129 			}
11130 
11131 			// skip AP 2.4G channel plan
11132 			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11133 			{
11134 				j++;
11135 			}
11136 		}
11137 
11138 		if (pregistrypriv->wireless_mode & WIRELESS_11A)
11139 		{
11140 			do {
11141 				if ((i >= MAX_CHANNEL_NUM) ||
11142 					(chplan_sta[i].ChannelNum == 0))
11143 					break;
11144 
11145 				if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11146 					break;
11147 
11148 				if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11149 				{
11150 					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11151 					chplan_new[k].ScanType = SCAN_ACTIVE;
11152 					i++;
11153 					j++;
11154 					k++;
11155 				}
11156 				else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11157 				{
11158 					chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11159 //					chplan_new[k].ScanType = chplan_sta[i].ScanType;
11160 					chplan_new[k].ScanType = SCAN_PASSIVE;
11161 					i++;
11162 					k++;
11163 				}
11164 				else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11165 				{
11166 					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11167 					chplan_new[k].ScanType = SCAN_ACTIVE;
11168 					j++;
11169 					k++;
11170 				}
11171 			} while (1);
11172 
11173 			// change AP not support channel to Passive scan
11174 			while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11175 			{
11176 				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11177 //				chplan_new[k].ScanType = chplan_sta[i].ScanType;
11178 				chplan_new[k].ScanType = SCAN_PASSIVE;
11179 				i++;
11180 				k++;
11181 			}
11182 
11183 			// add channel AP supported
11184 			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
11185 			{
11186 				chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11187 				chplan_new[k].ScanType = SCAN_ACTIVE;
11188 				j++;
11189 				k++;
11190 			}
11191 		}
11192 		else
11193 		{
11194 			// keep original STA 5G channel plan
11195 			while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11196 			{
11197 				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11198 				chplan_new[k].ScanType = chplan_sta[i].ScanType;
11199 				i++;
11200 				k++;
11201 			}
11202 		}
11203 
11204 		pmlmeext->update_channel_plan_by_ap_done = 1;
11205 
11206 #ifdef CONFIG_DEBUG_RTL871X
11207 		k = 0;
11208 		DBG_871X("%s: new STA channel plan {", __FUNCTION__);
11209 		while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11210 		{
11211 			DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
11212 			k++;
11213 		}
11214 		DBG_871X("}\n");
11215 #endif
11216 
11217 #if 0
11218 		// recover the right channel index
11219 		channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11220 		k = 0;
11221 		while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11222 		{
11223 			if (chplan_new[k].ChannelNum == channel) {
11224 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11225 						 ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11226 						  __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
11227 				pmlmeext->sitesurvey_res.channel_idx = k;
11228 				break;
11229 			}
11230 			k++;
11231 		}
11232 #endif
11233 	}
11234 
11235 	// If channel is used by AP, set channel scan type to active
11236 	channel = bssid->Configuration.DSConfig;
11237 	chplan_new = pmlmeext->channel_set;
11238 	i = 0;
11239 	while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
11240 	{
11241 		if (chplan_new[i].ChannelNum == channel)
11242 		{
11243 			if (chplan_new[i].ScanType == SCAN_PASSIVE)
11244 			{
11245 				//5G Bnad 2, 3 (DFS) doesn't change to active scan
11246 				if(channel >= 52 && channel <= 144)
11247 					break;
11248 
11249 				chplan_new[i].ScanType = SCAN_ACTIVE;
11250 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11251 						 ("%s: change channel %d scan type from passive to active\n",
11252 						  __FUNCTION__, channel));
11253 			}
11254 			break;
11255 		}
11256 		i++;
11257 	}
11258 }
11259 #endif
11260 
11261 /****************************************************************************
11262 
11263 Following are the functions to report events
11264 
11265 *****************************************************************************/
11266 
report_survey_event(_adapter * padapter,union recv_frame * precv_frame)11267 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11268 {
11269 	struct cmd_obj *pcmd_obj;
11270 	u8	*pevtcmd;
11271 	u32 cmdsz;
11272 	struct survey_event	*psurvey_evt;
11273 	struct C2HEvent_Header *pc2h_evt_hdr;
11274 	struct mlme_ext_priv *pmlmeext;
11275 	struct cmd_priv *pcmdpriv;
11276 	//u8 *pframe = precv_frame->u.hdr.rx_data;
11277 	//uint len = precv_frame->u.hdr.len;
11278 
11279 	if(!padapter)
11280 		return;
11281 
11282 	pmlmeext = &padapter->mlmeextpriv;
11283 	pcmdpriv = &padapter->cmdpriv;
11284 
11285 
11286 	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11287 	{
11288 		return;
11289 	}
11290 
11291 	cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11292 	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11293 	{
11294 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11295 		return;
11296 	}
11297 
11298 	_rtw_init_listhead(&pcmd_obj->list);
11299 
11300 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11301 	pcmd_obj->cmdsz = cmdsz;
11302 	pcmd_obj->parmbuf = pevtcmd;
11303 
11304 	pcmd_obj->rsp = NULL;
11305 	pcmd_obj->rspsz  = 0;
11306 
11307 	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11308 	pc2h_evt_hdr->len = sizeof(struct survey_event);
11309 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11310 	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11311 
11312 	psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11313 
11314 	if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
11315 	{
11316 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11317 		rtw_mfree((u8 *)pevtcmd, cmdsz);
11318 		return;
11319 	}
11320 
11321 #ifdef CONFIG_80211D
11322 	process_80211d(padapter, &psurvey_evt->bss);
11323 #endif
11324 
11325 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11326 
11327 	pmlmeext->sitesurvey_res.bss_cnt++;
11328 
11329 	return;
11330 
11331 }
11332 
report_surveydone_event(_adapter * padapter)11333 void report_surveydone_event(_adapter *padapter)
11334 {
11335 	struct cmd_obj *pcmd_obj;
11336 	u8	*pevtcmd;
11337 	u32 cmdsz;
11338 	struct surveydone_event *psurveydone_evt;
11339 	struct C2HEvent_Header	*pc2h_evt_hdr;
11340 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
11341 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11342 
11343 	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11344 	{
11345 		return;
11346 	}
11347 
11348 	cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11349 	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11350 	{
11351 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11352 		return;
11353 	}
11354 
11355 	_rtw_init_listhead(&pcmd_obj->list);
11356 
11357 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11358 	pcmd_obj->cmdsz = cmdsz;
11359 	pcmd_obj->parmbuf = pevtcmd;
11360 
11361 	pcmd_obj->rsp = NULL;
11362 	pcmd_obj->rspsz  = 0;
11363 
11364 	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11365 	pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11366 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11367 	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11368 
11369 	psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11370 	psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11371 
11372 	DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11373 
11374 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11375 
11376 	return;
11377 
11378 }
11379 
report_join_res(_adapter * padapter,int res)11380 void report_join_res(_adapter *padapter, int res)
11381 {
11382 	struct cmd_obj *pcmd_obj;
11383 	u8	*pevtcmd;
11384 	u32 cmdsz;
11385 	struct joinbss_event		*pjoinbss_evt;
11386 	struct C2HEvent_Header	*pc2h_evt_hdr;
11387 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
11388 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11389 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11390 
11391 	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11392 	{
11393 		return;
11394 	}
11395 
11396 	cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11397 	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11398 	{
11399 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11400 		return;
11401 	}
11402 
11403 	_rtw_init_listhead(&pcmd_obj->list);
11404 
11405 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11406 	pcmd_obj->cmdsz = cmdsz;
11407 	pcmd_obj->parmbuf = pevtcmd;
11408 
11409 	pcmd_obj->rsp = NULL;
11410 	pcmd_obj->rspsz  = 0;
11411 
11412 	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11413 	pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11414 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11415 	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11416 
11417 	pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11418 	_rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11419 	pjoinbss_evt->network.join_res 	= pjoinbss_evt->network.aid = res;
11420 
11421 	DBG_871X("report_join_res(%d)\n", res);
11422 
11423 
11424 	rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11425 
11426 
11427 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11428 
11429 	return;
11430 
11431 }
11432 
report_wmm_edca_update(_adapter * padapter)11433 void report_wmm_edca_update(_adapter *padapter)
11434 {
11435 	struct cmd_obj *pcmd_obj;
11436 	u8	*pevtcmd;
11437 	u32 cmdsz;
11438 	struct wmm_event		*pwmm_event;
11439 	struct C2HEvent_Header	*pc2h_evt_hdr;
11440 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
11441 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11442 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11443 
11444 	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11445 	{
11446 		return;
11447 	}
11448 
11449 	cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11450 	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11451 	{
11452 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11453 		return;
11454 	}
11455 
11456 	_rtw_init_listhead(&pcmd_obj->list);
11457 
11458 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11459 	pcmd_obj->cmdsz = cmdsz;
11460 	pcmd_obj->parmbuf = pevtcmd;
11461 
11462 	pcmd_obj->rsp = NULL;
11463 	pcmd_obj->rspsz  = 0;
11464 
11465 	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11466 	pc2h_evt_hdr->len = sizeof(struct wmm_event);
11467 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11468 	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11469 
11470 	pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11471 	pwmm_event->wmm =0;
11472 
11473 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11474 
11475 	return;
11476 
11477 }
11478 
report_del_sta_event(_adapter * padapter,unsigned char * MacAddr,unsigned short reason,bool enqueue)11479 void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue)
11480 {
11481 	struct cmd_obj *pcmd_obj;
11482 	u8	*pevtcmd;
11483 	u32 cmdsz;
11484 	struct sta_info *psta;
11485 	int	mac_id = -1;
11486 	struct stadel_event			*pdel_sta_evt;
11487 	struct C2HEvent_Header	*pc2h_evt_hdr;
11488 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
11489 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11490 	u8 res = _SUCCESS;
11491 
11492 	/* prepare cmd parameter */
11493 	cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11494 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11495 	if (pevtcmd == NULL) {
11496 		res = _FAIL;
11497 		goto exit;
11498 	}
11499 
11500 	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11501 	pc2h_evt_hdr->len = sizeof(struct stadel_event);
11502 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11503 	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11504 
11505 	pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11506 	_rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11507 	_rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
11508 	psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11509 	if(psta)
11510 		mac_id = (int)psta->mac_id;
11511 	else
11512 		mac_id = (-1);
11513 	pdel_sta_evt->mac_id = mac_id;
11514 
11515 	if (!enqueue) {
11516 		/* do directly */
11517 		rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11518 		rtw_mfree(pevtcmd, cmdsz);
11519 	} else {
11520 		pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11521 		if (pcmd_obj == NULL) {
11522 			rtw_mfree(pevtcmd, cmdsz);
11523 			res = _FAIL;
11524 			goto exit;
11525 		}
11526 
11527 		_rtw_init_listhead(&pcmd_obj->list);
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 		res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11536 	}
11537 
11538 exit:
11539 
11540 	DBG_871X(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11541 		, FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11542 
11543 	return;
11544 }
11545 
report_add_sta_event(_adapter * padapter,unsigned char * MacAddr,int cam_idx)11546 void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
11547 {
11548 	struct cmd_obj *pcmd_obj;
11549 	u8	*pevtcmd;
11550 	u32 cmdsz;
11551 	struct stassoc_event		*padd_sta_evt;
11552 	struct C2HEvent_Header	*pc2h_evt_hdr;
11553 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
11554 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11555 
11556 	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11557 	{
11558 		return;
11559 	}
11560 
11561 	cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11562 	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11563 	{
11564 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11565 		return;
11566 	}
11567 
11568 	_rtw_init_listhead(&pcmd_obj->list);
11569 
11570 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11571 	pcmd_obj->cmdsz = cmdsz;
11572 	pcmd_obj->parmbuf = pevtcmd;
11573 
11574 	pcmd_obj->rsp = NULL;
11575 	pcmd_obj->rspsz  = 0;
11576 
11577 	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11578 	pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11579 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11580 	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11581 
11582 	padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11583 	_rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11584 	padd_sta_evt->cam_id = cam_idx;
11585 
11586 	DBG_871X("report_add_sta_event: add STA\n");
11587 
11588 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11589 
11590 	return;
11591 }
11592 
11593 
rtw_port_switch_chk(_adapter * adapter)11594 bool rtw_port_switch_chk(_adapter *adapter)
11595 {
11596 	bool switch_needed = _FALSE;
11597 #ifdef CONFIG_CONCURRENT_MODE
11598 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11599 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11600 	struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11601 	_adapter *if_port0 = NULL;
11602 	_adapter *if_port1 = NULL;
11603 	struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11604 	struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11605 	int i;
11606 
11607 	for (i = 0; i < dvobj->iface_nums; i++) {
11608 		if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) {
11609 			if_port0 = dvobj->padapters[i];
11610 			if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11611 		}
11612 		else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) {
11613 			if_port1 = dvobj->padapters[i];
11614 			if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11615 		}
11616 	}
11617 
11618 	if (if_port0 == NULL) {
11619 		rtw_warn_on(1);
11620 		goto exit;
11621 	}
11622 
11623 	if (if_port1 == NULL) {
11624 		rtw_warn_on(1);
11625 		goto exit;
11626 	}
11627 
11628 #ifdef DBG_RUNTIME_PORT_SWITCH
11629 	DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11630 		ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11631 		ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11632 		FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11633 		ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11634 		ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11635 #endif /* DBG_RUNTIME_PORT_SWITCH */
11636 
11637 #ifdef CONFIG_WOWLAN
11638 	/* WOWLAN interface(primary, for now) should be port0 */
11639 	if (pwrctl->wowlan_mode == _TRUE) {
11640 		if(!is_primary_adapter(if_port0)) {
11641 			DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11642 			switch_needed = _TRUE;
11643 		}
11644 		goto exit;
11645 	}
11646 #endif /* CONFIG_WOWLAN */
11647 
11648 	/* AP should use port0 for ctl frame's ack */
11649 	if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11650 		DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11651 		switch_needed = _TRUE;
11652 		goto exit;
11653 	}
11654 
11655 	/* GC should use port0 for p2p ps */
11656 	if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11657 		&& (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11658 		&& !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11659 		&& !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11660 	) {
11661 		DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11662 		switch_needed = _TRUE;
11663 		goto exit;
11664 	}
11665 
11666 	/* port1 linked, but port0 not linked */
11667 	if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11668 		&& !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11669 		&& ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11670 	) {
11671 		DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11672 		switch_needed = _TRUE;
11673 		goto exit;
11674 	}
11675 
11676 exit:
11677 #ifdef DBG_RUNTIME_PORT_SWITCH
11678 	DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11679 #endif /* DBG_RUNTIME_PORT_SWITCH */
11680 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11681 #endif /* CONFIG_CONCURRENT_MODE */
11682 	return switch_needed;
11683 }
11684 
11685 /****************************************************************************
11686 
11687 Following are the event callback functions
11688 
11689 *****************************************************************************/
11690 
11691 //for sta/adhoc mode
update_sta_info(_adapter * padapter,struct sta_info * psta)11692 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11693 {
11694 	_irqL	irqL;
11695 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11696 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11697 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11698 
11699 	//ERP
11700 	VCS_update(padapter, psta);
11701 
11702 #ifdef CONFIG_80211N_HT
11703 	//HT
11704 	if(pmlmepriv->htpriv.ht_option)
11705 	{
11706 		psta->htpriv.ht_option = _TRUE;
11707 
11708 		psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11709 
11710 		psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
11711 
11712 		if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11713 			psta->htpriv.sgi_20m = _TRUE;
11714 
11715 		if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11716 			psta->htpriv.sgi_40m = _TRUE;
11717 
11718 		psta->qos_option = _TRUE;
11719 
11720 		psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11721 		psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11722 		psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11723 
11724 		_rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11725 	}
11726 	else
11727 #endif //CONFIG_80211N_HT
11728 	{
11729 #ifdef CONFIG_80211N_HT
11730 		psta->htpriv.ht_option = _FALSE;
11731 
11732 		psta->htpriv.ampdu_enable = _FALSE;
11733 
11734 		psta->htpriv.sgi_20m = _FALSE;
11735 		psta->htpriv.sgi_40m = _FALSE;
11736 #endif //CONFIG_80211N_HT
11737 		psta->qos_option = _FALSE;
11738 
11739 	}
11740 
11741 #ifdef CONFIG_80211N_HT
11742 	psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11743 
11744 	psta->htpriv.agg_enable_bitmap = 0x0;//reset
11745 	psta->htpriv.candidate_tid_bitmap = 0x0;//reset
11746 #endif //CONFIG_80211N_HT
11747 
11748 	psta->bw_mode = pmlmeext->cur_bwmode;
11749 
11750 	//QoS
11751 	if(pmlmepriv->qospriv.qos_option)
11752 		psta->qos_option = _TRUE;
11753 
11754 #ifdef CONFIG_80211AC_VHT
11755 	_rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11756 #endif //CONFIG_80211AC_VHT
11757 
11758 	update_ldpc_stbc_cap(psta);
11759 
11760 	_enter_critical_bh(&psta->lock, &irqL);
11761 	psta->state = _FW_LINKED;
11762 	_exit_critical_bh(&psta->lock, &irqL);
11763 
11764 }
11765 
rtw_mlmeext_disconnect(_adapter * padapter)11766 static void rtw_mlmeext_disconnect(_adapter *padapter)
11767 {
11768 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
11769 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11770 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11771 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11772 	u8 state_backup = (pmlmeinfo->state&0x03);
11773 	u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
11774 	u8 E2500_ID[]= {0x20, 0xAA, 0x4B};
11775 	u8 iot_flag = _FALSE;
11776 
11777 	//set_opmode_cmd(padapter, infra_client_with_mlme);
11778 
11779 #if 1
11780 	/*
11781 	 * For safety, prevent from keeping macid sleep.
11782 	 * If we can sure all power mode enter/leave are paired,
11783 	 * this check can be removed.
11784 	 * Lucas@20131113
11785 	 */
11786 	/* wakeup macid after disconnect. */
11787 	{
11788 		struct sta_info *psta;
11789 		psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork));
11790 		if (psta)
11791 			rtw_hal_macid_wakeup(padapter, psta->mac_id);
11792 	}
11793 #endif
11794 
11795 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11796 	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11797 
11798 	//set MSR to no link state -> infra. mode
11799 	Set_MSR(padapter, _HW_STATE_STATION_);
11800 
11801 	//check if sta is ASIX peer and fix IOT issue if it is.
11802 	if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3))
11803 		rtw_hal_set_hwreg(padapter,
11804 				  HW_VAR_ASIX_IOT,
11805 				  (u8 *)(&iot_flag));
11806 	else if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,E2500_ID ,3))
11807 		rtw_hal_set_hwreg(padapter,
11808 				  HW_VAR_E2500_IOT,
11809 				  (u8 *)(&iot_flag));
11810 
11811 	pmlmeinfo->state = WIFI_FW_NULL_STATE;
11812 
11813 	if(state_backup == WIFI_FW_STATION_STATE)
11814 	{
11815 		if (rtw_port_switch_chk(padapter) == _TRUE) {
11816 			rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11817 			#ifdef CONFIG_LPS
11818 			{
11819 				_adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11820 				if (port0_iface)
11821 					rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11822 			}
11823 			#endif
11824 		}
11825 	}
11826 
11827 	/* switch to the 20M Hz mode after disconnect */
11828 	pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11829 	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11830 
11831 #ifdef CONFIG_FCS_MODE
11832 	if (EN_FCS(padapter))
11833 		rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11834 #endif
11835 
11836 #ifdef CONFIG_DFS_MASTER
11837 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
11838 		rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);
11839 	else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
11840 		rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED);
11841 #endif
11842 
11843 	{
11844 		u8 ch, bw, offset;
11845 
11846 		if (rtw_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
11847 			set_channel_bwmode(padapter, ch, offset, bw);
11848 	}
11849 
11850 	flush_all_cam_entry(padapter);
11851 
11852 	_cancel_timer_ex(&pmlmeext->link_timer);
11853 
11854 	//pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE;
11855 	pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11856 	pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11857 
11858 #ifdef CONFIG_TDLS
11859 	padapter->tdlsinfo.ap_prohibited = _FALSE;
11860 
11861 	/* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11862 	if (padapter->registrypriv.wifi_spec == 1)
11863 	{
11864 		padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
11865 	}
11866 #endif /* CONFIG_TDLS */
11867 
11868 }
11869 
mlmeext_joinbss_event_callback(_adapter * padapter,int join_res)11870 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
11871 {
11872 	struct sta_info		*psta, *psta_bmc;
11873 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11874 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11875 	WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
11876 	struct sta_priv		*pstapriv = &padapter->stapriv;
11877 	u8	join_type;
11878 #ifdef CONFIG_ARP_KEEP_ALIVE
11879 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
11880 #endif
11881 
11882 	if(join_res < 0)
11883 	{
11884 		join_type = 1;
11885 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11886 		rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11887 
11888 		goto exit_mlmeext_joinbss_event_callback;
11889 	}
11890 #ifdef CONFIG_ARP_KEEP_ALIVE
11891 	pmlmepriv->bGetGateway = 1;
11892 #endif
11893 
11894 #ifdef CONFIG_ADHOC_MODE
11895 	if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11896 	{
11897 		//update bc/mc sta_info
11898 		update_bmc_sta(padapter);
11899 	}
11900 #endif
11901 
11902 
11903 	//turn on dynamic functions
11904 	/* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
11905 
11906 	// update IOT-releated issue
11907 	update_IOT_info(padapter);
11908 
11909 	rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
11910 
11911 	//BCN interval
11912 	rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
11913 
11914 	//udpate capability
11915 	update_capinfo(padapter, pmlmeinfo->capability);
11916 
11917 	//WMM, Update EDCA param
11918 	WMMOnAssocRsp(padapter);
11919 
11920 	//HT
11921 	HTOnAssocRsp(padapter);
11922 
11923 #ifdef CONFIG_80211AC_VHT
11924 	//VHT
11925 	VHTOnAssocRsp(padapter);
11926 #endif
11927 
11928 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
11929 	if (psta) //only for infra. mode
11930 	{
11931 		pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
11932 
11933 		//DBG_871X("set_sta_rate\n");
11934 
11935 		psta->wireless_mode = pmlmeext->cur_wireless_mode;
11936 
11937 		//set per sta rate after updating HT cap.
11938 		set_sta_rate(padapter, psta);
11939 
11940 		rtw_sta_media_status_rpt(padapter, psta, 1);
11941 
11942 		/* wakeup macid after join bss successfully to ensure
11943 			the subsequent data frames can be sent out normally */
11944 		rtw_hal_macid_wakeup(padapter, psta->mac_id);
11945 	}
11946 
11947 	if (rtw_port_switch_chk(padapter) == _TRUE)
11948 		rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11949 
11950 	join_type = 2;
11951 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11952 
11953 	if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11954 	{
11955 		// correcting TSF
11956 		correct_TSF(padapter, pmlmeext);
11957 
11958 		//set_link_timer(pmlmeext, DISCONNECT_TO);
11959 	}
11960 
11961 #ifdef CONFIG_LPS
11962 	if(get_iface_type(padapter) == IFACE_PORT0)
11963 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
11964 #endif
11965 
11966 #ifdef CONFIG_BEAMFORMING
11967 	if (psta)
11968 		beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
11969 #endif
11970 
11971 exit_mlmeext_joinbss_event_callback:
11972 
11973 	rtw_join_done_chk_ch(padapter, join_res);
11974 
11975 	DBG_871X("=>%s - End to Connection without 4-way\n", __FUNCTION__);
11976 }
11977 
11978 
11979 //currently only adhoc mode will go here
mlmeext_sta_add_event_callback(_adapter * padapter,struct sta_info * psta)11980 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
11981 {
11982 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
11983 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11984 	u8	join_type;
11985 
11986 	DBG_871X("%s\n", __FUNCTION__);
11987 
11988 #ifdef CONFIG_ADHOC_MODE
11989 	if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11990 	{
11991 		if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
11992 		{
11993 			//nothing to do
11994 		}
11995 		else//adhoc client
11996 		{
11997 			//update TSF Value
11998 			//update_TSF(pmlmeext, pframe, len);
11999 
12000 			// correcting TSF
12001 			correct_TSF(padapter, pmlmeext);
12002 
12003 			//start beacon
12004 			if(send_beacon(padapter)==_FAIL)
12005 			{
12006 				pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
12007 
12008 				pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
12009 
12010 				return;
12011 			}
12012 
12013 			pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12014 
12015 		}
12016 
12017 		join_type = 2;
12018 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12019 	}
12020 
12021 	pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
12022 
12023 	psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates);
12024 	_rtw_memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen);
12025 
12026 	//update adhoc sta_info
12027 	update_sta_info(padapter, psta);
12028 
12029 	rtw_hal_update_sta_rate_mask(padapter, psta);
12030 
12031 	// ToDo: HT for Ad-hoc
12032 	psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12033 	psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
12034 
12035 	//rate radaptive
12036 	Update_RA_Entry(padapter, psta);
12037 #endif
12038 }
12039 
mlmeext_sta_del_event_callback(_adapter * padapter)12040 void mlmeext_sta_del_event_callback(_adapter *padapter)
12041 {
12042 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12043 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12044 
12045 	if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12046 	{
12047 		rtw_mlmeext_disconnect(padapter);
12048 	}
12049 
12050 }
12051 
12052 /****************************************************************************
12053 
12054 Following are the functions for the timer handlers
12055 
12056 *****************************************************************************/
_linked_info_dump(_adapter * padapter)12057 void _linked_info_dump(_adapter *padapter)
12058 {
12059 	int i;
12060 	struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
12061 	struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
12062 	int UndecoratedSmoothedPWDB = 0;
12063 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
12064 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
12065 
12066 	if(padapter->bLinkInfoDump){
12067 
12068 		DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter));
12069 
12070 		if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12071 		{
12072 			rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
12073 
12074 			DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
12075 				MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB);
12076 		}
12077 #ifdef CONFIG_AP_MODE
12078 		else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
12079 		{
12080 			_irqL irqL;
12081 			_list	*phead, *plist;
12082 
12083 			struct sta_info *psta=NULL;
12084 			struct sta_priv *pstapriv = &padapter->stapriv;
12085 
12086 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12087 			phead = &pstapriv->asoc_list;
12088 			plist = get_next(phead);
12089 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12090 			{
12091 				psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
12092 				plist = get_next(plist);
12093 
12094 				DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n",
12095 					MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB);
12096 			}
12097 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12098 
12099 		}
12100 #endif /*CONFIG_AP_MODE*/
12101 		for(i=0; i<macid_ctl->num; i++)
12102 		{
12103 			if(rtw_macid_is_used(macid_ctl, i)
12104 				&& !rtw_macid_is_bmc(macid_ctl, i) /* skip bc/mc sta */
12105 			) {
12106 				//============  tx info ============
12107 				rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i);
12108 			}
12109 		}
12110 		rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, NULL, _FALSE);
12111 
12112 	}
12113 }
rtw_delba_check(_adapter * padapter,struct sta_info * psta,u8 from_timer)12114 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12115 {
12116 	int	i = 0;
12117 	int ret = _SUCCESS;
12118 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12119 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12120 
12121 	/*
12122 		IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12123 		AP is originator.AP does not transmit unicast packets when STA response its BAR.
12124 		This case probably occur ap issue BAR after AP builds BA.
12125 
12126 		Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12127 		The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12128 	*/
12129 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12130 		for (i = 0; i < TID_NUM ; i++) {
12131 			if (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) {
12132 				if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12133 					if (psta->recvreorder_ctrl[i].enable) {
12134 						/* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
12135 						if (!from_timer)
12136 							ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1);
12137 						else
12138 							issue_del_ba(padapter,  psta->hwaddr, i, 39, 0);
12139 						psta->recvreorder_ctrl[i].enable = _FALSE;
12140 						if (ret != _FAIL)
12141 							psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12142 						rtw_reset_continual_no_rx_packet(psta, i);
12143 						}
12144 					}
12145 				}
12146 			else{
12147 				/* The inactivity timer is reset when MPDUs to the TID is received. */
12148 				rtw_reset_continual_no_rx_packet(psta, i);
12149 			}
12150 		}
12151 	}
12152 }
12153 
chk_ap_is_alive(_adapter * padapter,struct sta_info * psta)12154 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12155 {
12156 	u8 ret = _FALSE;
12157 	int i = 0;
12158 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12159 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12160 
12161 	#ifdef DBG_EXPIRATION_CHK
12162 	DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12163 				/*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12164 				", retry:%u\n"
12165 		, FUNC_ADPT_ARG(padapter)
12166 		, STA_RX_PKTS_DIFF_ARG(psta)
12167 		, psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12168 		, psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12169 		/*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12170 		, psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12171 		, psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12172 		, pmlmeinfo->bcn_interval*/
12173 		, pmlmeext->retry
12174 	);
12175 
12176 	DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12177 		, padapter->xmitpriv.tx_pkts
12178 		, pmlmeinfo->link_count
12179 	);
12180 	#endif
12181 
12182 	if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12183 		&& sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12184 		&& sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12185 	)
12186 	{
12187 		ret = _FALSE;
12188 	}
12189 	else
12190 	{
12191 		ret = _TRUE;
12192 	}
12193 
12194 	sta_update_last_rx_pkts(psta);
12195 
12196 	/*
12197 		record last rx data packets for every tid.
12198 	*/
12199 	for (i = 0; i < TID_NUM; i++)
12200 		psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i];
12201 
12202 	return ret;
12203 }
12204 
12205 #ifdef CONFIG_TDLS
chk_tdls_peer_sta_is_alive(_adapter * padapter,struct sta_info * psta)12206 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12207 {
12208 	if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12209 		&& (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12210 		return _FALSE;
12211 
12212 	return _TRUE;
12213 }
12214 
linked_status_chk_tdls(_adapter * padapter)12215 void linked_status_chk_tdls(_adapter *padapter)
12216 {
12217 struct candidate_pool{
12218 	struct sta_info *psta;
12219 	u8 addr[ETH_ALEN];
12220 };
12221 	struct sta_priv *pstapriv = &padapter->stapriv;
12222 	_irqL irqL;
12223 	u8 ack_chk;
12224 	struct sta_info *psta;
12225 	int i, num_teardown=0, num_checkalive=0;
12226 	_list	*plist, *phead;
12227 	struct tdls_txmgmt txmgmt;
12228 	struct candidate_pool checkalive[NUM_STA];
12229 	struct candidate_pool teardown[NUM_STA];
12230 #define ALIVE_MIN 2
12231 #define ALIVE_MAX 5
12232 
12233 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12234 	_rtw_memset(checkalive, 0x00, sizeof(checkalive));
12235 	_rtw_memset(teardown, 0x00, sizeof(teardown));
12236 
12237 	if((padapter->tdlsinfo.link_established == _TRUE)){
12238 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12239 		for(i=0; i< NUM_STA; i++)
12240 		{
12241 			phead = &(pstapriv->sta_hash[i]);
12242 			plist = get_next(phead);
12243 
12244 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12245 			{
12246 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12247 				plist = get_next(plist);
12248 
12249 				if(psta->tdls_sta_state & TDLS_LINKED_STATE)
12250 				{
12251 					psta->alive_count++;
12252 					if(psta->alive_count >= ALIVE_MIN)
12253 					{
12254 						if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12255 							if (psta->alive_count < ALIVE_MAX) {
12256 								_rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12257 								checkalive[num_checkalive].psta = psta;
12258 								num_checkalive++;
12259 							}
12260 							else
12261 							{
12262 								_rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12263 								teardown[num_teardown].psta = psta;
12264 								num_teardown++;
12265 							}
12266 						}
12267 						else
12268 						{
12269 							psta->alive_count = 0;
12270 						}
12271 					}
12272 					psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12273 					psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12274 				}
12275 			}
12276 		}
12277 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12278 
12279 		if (num_checkalive > 0) {
12280 			for (i = 0; i < num_checkalive; i++) {
12281 				_rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12282 				issue_tdls_dis_req(padapter, &txmgmt);
12283 				issue_tdls_dis_req(padapter, &txmgmt);
12284 				issue_tdls_dis_req(padapter, &txmgmt);
12285 			}
12286 		}
12287 
12288 		if(num_teardown > 0)
12289 		{
12290 			for(i=0; i< num_teardown; i++)
12291 			{
12292 				DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12293 				txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12294 				_rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12295 				issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12296 			}
12297 		}
12298 	}
12299 
12300 }
12301 #endif //CONFIG_TDLS
12302 
12303 //from_timer == 1 means driver is in LPS
linked_status_chk(_adapter * padapter,u8 from_timer)12304 void linked_status_chk(_adapter *padapter, u8 from_timer)
12305 {
12306 	u32	i;
12307 	struct sta_info		*psta;
12308 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
12309 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12310 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12311 	struct sta_priv		*pstapriv = &padapter->stapriv;
12312 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
12313 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
12314 
12315 	if (is_client_associated_to_ap(padapter))
12316 	{
12317 		//linked infrastructure client mode
12318 
12319 		int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12320 		int rx_chk_limit;
12321 		int link_count_limit;
12322 
12323 		#if defined(DBG_ROAMING_TEST)
12324 		rx_chk_limit = 1;
12325 		#elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12326 		rx_chk_limit = 4;
12327 		#else
12328 		rx_chk_limit = 8;
12329 		#endif
12330 
12331 #ifdef CONFIG_ARP_KEEP_ALIVE
12332 		if (!from_timer && pmlmepriv->bGetGateway == 1) {
12333 			DBG_871X("do rtw_gw_addr_query()");
12334 			if (rtw_gw_addr_query(padapter) == 0) {
12335 				pmlmepriv->bGetGateway = 0;
12336 			} else {
12337 				_rtw_memset(pmlmepriv->gw_ip, 0, 4);
12338 				_rtw_memset(pmlmepriv->gw_mac_addr, 0, 6);
12339 			}
12340 		}
12341 #endif
12342 #ifdef CONFIG_P2P
12343 		if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12344 		{
12345 			if(!from_timer)
12346 				link_count_limit = 3; // 8 sec
12347 			else
12348 				link_count_limit = 15; // 32 sec
12349 		}
12350 		else
12351 #endif // CONFIG_P2P
12352 		{
12353 			if(!from_timer)
12354 				link_count_limit = 7; // 16 sec
12355 			else
12356 				link_count_limit = 29; // 60 sec
12357 		}
12358 
12359 		if (pwrpriv->disable_smart_ps)
12360 			link_count_limit = 3; // 8 sec
12361 #ifdef CONFIG_TDLS
12362 #ifdef CONFIG_TDLS_CH_SW
12363 		if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12364 			return;
12365 #endif /* CONFIG_TDLS_CH_SW */
12366 
12367 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12368 		linked_status_chk_tdls(padapter);
12369 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12370 #endif /* CONFIG_TDLS */
12371 
12372 		if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12373 		{
12374 			bool is_p2p_enable = _FALSE;
12375 			#ifdef CONFIG_P2P
12376 			is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12377 			#endif
12378 
12379 			/*issue delba when ap does not tx data packet that is Broadcom ap */
12380 			rtw_delba_check(padapter, psta, from_timer);
12381 
12382 			if (chk_ap_is_alive(padapter, psta) == _FALSE)
12383 				rx_chk = _FAIL;
12384 
12385 			if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12386 				tx_chk = _FAIL;
12387 
12388 			#if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12389 			if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
12390 				u8 backup_oper_channel=0;
12391 
12392 				/* switch to correct channel of current network  before issue keep-alive frames */
12393 				if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12394 					backup_oper_channel = rtw_get_oper_ch(padapter);
12395 					SelectChannel(padapter, pmlmeext->cur_channel);
12396 				}
12397 
12398 				if (rx_chk != _SUCCESS)
12399 					issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12400 
12401 				if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12402 					tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12403 					/* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12404 					if (tx_chk == _SUCCESS && !is_p2p_enable)
12405 						rx_chk = _SUCCESS;
12406 				}
12407 
12408 				/* back to the original operation channel */
12409 				if(backup_oper_channel>0)
12410 					SelectChannel(padapter, backup_oper_channel);
12411 
12412 			}
12413 			else
12414 			#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12415 			{
12416 				if (rx_chk != _SUCCESS) {
12417 					if (pmlmeext->retry == 0) {
12418 						#ifdef DBG_EXPIRATION_CHK
12419 						DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12420 						#endif
12421 						issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12422 						issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12423 						issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12424 					}
12425 				}
12426 
12427 				if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
12428 					#ifdef DBG_EXPIRATION_CHK
12429 					DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0);
12430 					#endif
12431 					tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0);
12432 				}
12433 			}
12434 
12435 			if (rx_chk == _FAIL) {
12436 				pmlmeext->retry++;
12437 				if (pmlmeext->retry > rx_chk_limit) {
12438 					DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
12439 						FUNC_ADPT_ARG(padapter));
12440 
12441 					DBG_871X_LEVEL(_drv_always_, "%s: rx_chk_limit: %d\n",
12442 						__func__, rx_chk_limit);
12443 					receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12444 						, WLAN_REASON_EXPIRATION_CHK);
12445 					return;
12446 				}
12447 			} else {
12448 				pmlmeext->retry = 0;
12449 			}
12450 
12451 			if (tx_chk == _FAIL) {
12452 				pmlmeinfo->link_count %= (link_count_limit+1);
12453 			} else {
12454 				pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12455 				pmlmeinfo->link_count = 0;
12456 			}
12457 
12458 		} //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12459 
12460 	}
12461 	else if (is_client_associated_to_ibss(padapter))
12462 	{
12463 		//linked IBSS mode
12464 		//for each assoc list entry to check the rx pkt counter
12465 		for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
12466 		{
12467 			if (pmlmeinfo->FW_sta_info[i].status == 1)
12468 			{
12469 				psta = pmlmeinfo->FW_sta_info[i].psta;
12470 
12471 				if(NULL==psta) continue;
12472 
12473 				if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
12474 				{
12475 
12476 					if(pmlmeinfo->FW_sta_info[i].retry<3)
12477 					{
12478 						pmlmeinfo->FW_sta_info[i].retry++;
12479 					}
12480 					else
12481 					{
12482 						pmlmeinfo->FW_sta_info[i].retry = 0;
12483 						pmlmeinfo->FW_sta_info[i].status = 0;
12484 						report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, _TRUE);
12485 					}
12486 				}
12487 				else
12488 				{
12489 					pmlmeinfo->FW_sta_info[i].retry = 0;
12490 					pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
12491 				}
12492 			}
12493 		}
12494 
12495 		//set_link_timer(pmlmeext, DISCONNECT_TO);
12496 
12497 	}
12498 
12499 }
12500 
survey_timer_hdl(_adapter * padapter)12501 void survey_timer_hdl(_adapter *padapter)
12502 {
12503 	struct cmd_obj *cmd;
12504 	struct sitesurvey_parm *psurveyPara;
12505 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12506 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12507 #ifdef CONFIG_P2P
12508 	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12509 #endif
12510 
12511 	if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12512 		cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12513 		if (cmd == NULL) {
12514 			rtw_warn_on(1);
12515 			goto exit;
12516 		}
12517 
12518 		psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12519 		if (psurveyPara == NULL) {
12520 			rtw_warn_on(1);
12521 			rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12522 			goto exit;
12523 		}
12524 
12525 		init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12526 		rtw_enqueue_cmd(pcmdpriv, cmd);
12527 	}
12528 
12529 exit:
12530 	return;
12531 }
12532 
link_timer_hdl(_adapter * padapter)12533 void link_timer_hdl(_adapter *padapter)
12534 {
12535 	//static unsigned int		rx_pkt = 0;
12536 	//static u64				tx_cnt = 0;
12537 	//struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
12538 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12539 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12540 	//struct sta_priv		*pstapriv = &padapter->stapriv;
12541 
12542 
12543 	if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
12544 	{
12545 		DBG_871X("link_timer_hdl:no beacon while connecting\n");
12546 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
12547 		report_join_res(padapter, -3);
12548 	}
12549 	else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
12550 	{
12551 		//re-auth timer
12552 		if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
12553 		{
12554 			//if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
12555 			//{
12556 				pmlmeinfo->state = 0;
12557 				report_join_res(padapter, -1);
12558 				return;
12559 			//}
12560 			//else
12561 			//{
12562 			//	pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
12563 			//	pmlmeinfo->reauth_count = 0;
12564 			//}
12565 		}
12566 
12567 		DBG_871X("link_timer_hdl: auth timeout and try again\n");
12568 		pmlmeinfo->auth_seq = 1;
12569 		issue_auth(padapter, NULL, 0);
12570 		set_link_timer(pmlmeext, REAUTH_TO);
12571 	}
12572 	else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
12573 	{
12574 		//re-assoc timer
12575 		if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
12576 		{
12577 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
12578 			report_join_res(padapter, -2);
12579 			return;
12580 		}
12581 
12582 		DBG_871X("link_timer_hdl: assoc timeout and try again\n");
12583 		issue_assocreq(padapter);
12584 		set_link_timer(pmlmeext, REASSOC_TO);
12585 	}
12586 #if 0
12587 	else if (is_client_associated_to_ap(padapter))
12588 	{
12589 		//linked infrastructure client mode
12590 		if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12591 		{
12592 			/*to monitor whether the AP is alive or not*/
12593 			if (rx_pkt == psta->sta_stats.rx_pkts)
12594 			{
12595 				receive_disconnect(padapter, pmlmeinfo->network.MacAddress);
12596 				return;
12597 			}
12598 			else
12599 			{
12600 				rx_pkt = psta->sta_stats.rx_pkts;
12601 				set_link_timer(pmlmeext, DISCONNECT_TO);
12602 			}
12603 
12604 			//update the EDCA paramter according to the Tx/RX mode
12605 			update_EDCA_param(padapter);
12606 
12607 			/*to send the AP a nulldata if no frame is xmitted in order to keep alive*/
12608 			if (pmlmeinfo->link_count++ == 0)
12609 			{
12610 				tx_cnt = pxmitpriv->tx_pkts;
12611 			}
12612 			else if ((pmlmeinfo->link_count & 0xf) == 0)
12613 			{
12614 				if (tx_cnt == pxmitpriv->tx_pkts)
12615 				{
12616 					issue_nulldata_in_interrupt(padapter, NULL, 0);
12617 				}
12618 
12619 				tx_cnt = pxmitpriv->tx_pkts;
12620 			}
12621 		} //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12622 	}
12623 	else if (is_client_associated_to_ibss(padapter))
12624 	{
12625 		//linked IBSS mode
12626 		//for each assoc list entry to check the rx pkt counter
12627 		for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
12628 		{
12629 			if (pmlmeinfo->FW_sta_info[i].status == 1)
12630 			{
12631 				psta = pmlmeinfo->FW_sta_info[i].psta;
12632 
12633 				if (pmlmeinfo->FW_sta_info[i].rx_pkt == psta->sta_stats.rx_pkts)
12634 				{
12635 					pmlmeinfo->FW_sta_info[i].status = 0;
12636 					report_del_sta_event(padapter, psta->hwaddr);
12637 				}
12638 				else
12639 				{
12640 					pmlmeinfo->FW_sta_info[i].rx_pkt = psta->sta_stats.rx_pkts;
12641 				}
12642 			}
12643 		}
12644 
12645 		set_link_timer(pmlmeext, DISCONNECT_TO);
12646 	}
12647 #endif
12648 
12649 	return;
12650 }
12651 
addba_timer_hdl(struct sta_info * psta)12652 void addba_timer_hdl(struct sta_info *psta)
12653 {
12654 #ifdef CONFIG_80211N_HT
12655 	struct ht_priv	*phtpriv;
12656 
12657 	if(!psta)
12658 		return;
12659 
12660 	phtpriv = &psta->htpriv;
12661 
12662 	if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
12663 	{
12664 		if(phtpriv->candidate_tid_bitmap)
12665 			phtpriv->candidate_tid_bitmap=0x0;
12666 
12667 	}
12668 #endif //CONFIG_80211N_HT
12669 }
12670 
12671 #ifdef CONFIG_IEEE80211W
report_sta_timeout_event(_adapter * padapter,u8 * MacAddr,unsigned short reason)12672 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
12673 {
12674 	struct cmd_obj *pcmd_obj;
12675 	u8	*pevtcmd;
12676 	u32 cmdsz;
12677 	struct sta_info *psta;
12678 	int	mac_id;
12679 	struct stadel_event			*pdel_sta_evt;
12680 	struct C2HEvent_Header	*pc2h_evt_hdr;
12681 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
12682 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12683 
12684 	pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12685 	if (pcmd_obj == NULL)
12686 		return;
12687 
12688 	cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
12689 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12690 	if (pevtcmd == NULL) {
12691 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12692 		return;
12693 	}
12694 
12695 	_rtw_init_listhead(&pcmd_obj->list);
12696 
12697 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
12698 	pcmd_obj->cmdsz = cmdsz;
12699 	pcmd_obj->parmbuf = pevtcmd;
12700 
12701 	pcmd_obj->rsp = NULL;
12702 	pcmd_obj->rspsz  = 0;
12703 
12704 	pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
12705 	pc2h_evt_hdr->len = sizeof(struct stadel_event);
12706 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
12707 	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12708 
12709 	pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
12710 	_rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12711 	_rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12712 
12713 
12714 	psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12715 	if (psta)
12716 		mac_id = (int)psta->mac_id;
12717 	else
12718 		mac_id = (-1);
12719 
12720 	pdel_sta_evt->mac_id = mac_id;
12721 
12722 	DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
12723 
12724 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12725 
12726 	return;
12727 }
12728 
clnt_sa_query_timeout(_adapter * padapter)12729 void clnt_sa_query_timeout(_adapter *padapter)
12730 {
12731 
12732 	rtw_disassoc_cmd(padapter, 0, _TRUE);
12733 	rtw_indicate_disconnect(padapter);
12734 	rtw_free_assoc_resources(padapter, 1);
12735 
12736 	DBG_871X("SA query timeout client disconnect\n");
12737 }
12738 
sa_query_timer_hdl(struct sta_info * psta)12739 void sa_query_timer_hdl(struct sta_info *psta)
12740 {
12741 	_adapter *padapter = psta->padapter;
12742 	_irqL irqL;
12743 	struct sta_priv *pstapriv = &padapter->stapriv;
12744 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12745 
12746 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
12747 					check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12748 		clnt_sa_query_timeout(padapter);
12749 	else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
12750 		report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID);
12751 }
12752 
12753 #endif //CONFIG_IEEE80211W
12754 
NULL_hdl(_adapter * padapter,u8 * pbuf)12755 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
12756 {
12757 	return H2C_SUCCESS;
12758 }
12759 
12760 #ifdef CONFIG_AUTO_AP_MODE
rtw_start_auto_ap(_adapter * adapter)12761 void rtw_start_auto_ap(_adapter *adapter)
12762 {
12763 	DBG_871X("%s\n", __FUNCTION__);
12764 
12765 	rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
12766 
12767 	rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE);
12768 }
12769 
rtw_auto_ap_start_beacon(_adapter * adapter)12770 static int rtw_auto_ap_start_beacon(_adapter *adapter)
12771 {
12772 	int ret=0;
12773 	u8 *pbuf = NULL;
12774 	uint len;
12775 	u8	supportRate[16];
12776 	int 	sz = 0, rateLen;
12777 	u8 *	ie;
12778 	u8	wireless_mode, oper_channel;
12779 	u8 ssid[3] = {0}; //hidden ssid
12780 	u32 ssid_len = sizeof(ssid);
12781 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
12782 
12783 
12784 	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
12785 		return -EINVAL;
12786 
12787 
12788 	len = 128;
12789 	pbuf = rtw_zmalloc(len);
12790 	if(!pbuf)
12791 		return -ENOMEM;
12792 
12793 
12794 	//generate beacon
12795 	ie = pbuf;
12796 
12797 	//timestamp will be inserted by hardware
12798 	sz += 8;
12799 	ie += sz;
12800 
12801 	//beacon interval : 2bytes
12802 	*(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
12803 	sz += 2;
12804 	ie += 2;
12805 
12806 	//capability info
12807 	*(u16*)ie = 0;
12808 	*(u16*)ie |= cpu_to_le16(cap_ESS);
12809 	*(u16*)ie |= cpu_to_le16(cap_ShortPremble);
12810 	//*(u16*)ie |= cpu_to_le16(cap_Privacy);
12811 	sz += 2;
12812 	ie += 2;
12813 
12814 	//SSID
12815 	ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
12816 
12817 	//supported rates
12818 	wireless_mode = WIRELESS_11BG_24N;
12819 	rtw_set_supported_rate(supportRate, wireless_mode) ;
12820 	rateLen = rtw_get_rateset_len(supportRate);
12821 	if (rateLen > 8)
12822 	{
12823 		ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
12824 	}
12825 	else
12826 	{
12827 		ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
12828 	}
12829 
12830 
12831 	//DS parameter set
12832 	if(check_buddy_fwstate(adapter, _FW_LINKED) &&
12833 		check_buddy_fwstate(adapter, WIFI_STATION_STATE))
12834 	{
12835 		PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
12836 		struct mlme_ext_priv *pbuddy_mlmeext  = &pbuddy_adapter->mlmeextpriv;
12837 
12838 		oper_channel = pbuddy_mlmeext->cur_channel;
12839 	}
12840 	else
12841 	{
12842 		oper_channel = adapter_to_dvobj(adapter)->oper_channel;
12843 	}
12844 	ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
12845 
12846 	//ext supported rates
12847 	if (rateLen > 8)
12848 	{
12849 		ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
12850 	}
12851 
12852 	DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
12853 
12854 	//lunch ap mode & start to issue beacon
12855 	if(rtw_check_beacon_data(adapter, pbuf,  sz) == _SUCCESS)
12856 	{
12857 
12858 	}
12859 	else
12860 	{
12861 		ret = -EINVAL;
12862 	}
12863 
12864 
12865 	rtw_mfree(pbuf, len);
12866 
12867 	return ret;
12868 
12869 }
12870 #endif//CONFIG_AUTO_AP_MODE
12871 
setopmode_hdl(_adapter * padapter,u8 * pbuf)12872 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
12873 {
12874 	u8	type;
12875 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12876 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12877 	struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
12878 
12879 	if(psetop->mode == Ndis802_11APMode)
12880 	{
12881 		pmlmeinfo->state = WIFI_FW_AP_STATE;
12882 		type = _HW_STATE_AP_;
12883 #ifdef CONFIG_NATIVEAP_MLME
12884 		//start_ap_mode(padapter);
12885 #endif
12886 	}
12887 	else if(psetop->mode == Ndis802_11Infrastructure)
12888 	{
12889 		pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
12890 		pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to 	STATION_STATE
12891 		type = _HW_STATE_STATION_;
12892 	}
12893 	else if(psetop->mode == Ndis802_11IBSS)
12894 	{
12895 		type = _HW_STATE_ADHOC_;
12896 	} else if (psetop->mode == Ndis802_11Monitor) {
12897 		type = _HW_STATE_MONITOR_;
12898 	}
12899 	else
12900 	{
12901 		type = _HW_STATE_NOLINK_;
12902 	}
12903 
12904 	rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
12905 	//Set_NETYPE0_MSR(padapter, type);
12906 
12907 
12908 #ifdef CONFIG_AUTO_AP_MODE
12909 	if(psetop->mode == Ndis802_11APMode)
12910 		rtw_auto_ap_start_beacon(padapter);
12911 #endif
12912 
12913 	if (rtw_port_switch_chk(padapter) == _TRUE)
12914 	{
12915 		rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12916 
12917 		if(psetop->mode == Ndis802_11APMode)
12918 			adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages
12919 		else if (psetop->mode == Ndis802_11Infrastructure) {
12920 			#ifdef CONFIG_LPS
12921 			_adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12922 			if (port0_iface)
12923 				rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
12924 			#endif
12925 		}
12926 	}
12927 
12928 #ifdef CONFIG_BT_COEXIST
12929 	if (psetop->mode == Ndis802_11APMode)
12930 	{
12931 		// Do this after port switch to
12932 		// prevent from downloading rsvd page to wrong port
12933 		rtw_btcoex_MediaStatusNotify(padapter, 1); //connect
12934 	}
12935 #endif // CONFIG_BT_COEXIST
12936 
12937 	return H2C_SUCCESS;
12938 
12939 }
12940 
createbss_hdl(_adapter * padapter,u8 * pbuf)12941 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
12942 {
12943 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12944 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12945 	WLAN_BSSID_EX	*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
12946 	WLAN_BSSID_EX	*pdev_network = &padapter->registrypriv.dev_network;
12947 	struct createbss_parm *parm = (struct createbss_parm *)pbuf;
12948 	u8 ret = H2C_SUCCESS;
12949 	//u8	initialgain;
12950 
12951 #ifdef CONFIG_AP_MODE
12952 	if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
12953 		start_bss_network(padapter, parm);
12954 		goto exit;
12955 	}
12956 #endif
12957 
12958 #ifdef CONFIG_ADHOC_MODE
12959 	/* below is for ad-hoc master */
12960 	if (parm->adhoc) {
12961 		rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
12962 		rtw_joinbss_reset(padapter);
12963 
12964 		pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12965 		pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12966 		pmlmeinfo->ERP_enable = 0;
12967 		pmlmeinfo->WMM_enable = 0;
12968 		pmlmeinfo->HT_enable = 0;
12969 		pmlmeinfo->HT_caps_enable = 0;
12970 		pmlmeinfo->HT_info_enable = 0;
12971 		pmlmeinfo->agg_enable_bitmap = 0;
12972 		pmlmeinfo->candidate_tid_bitmap = 0;
12973 
12974 		//config the initial gain under linking, need to write the BB registers
12975 		//initialgain = 0x1E;
12976 		/*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
12977 
12978 		//disable dynamic functions, such as high power, DIG
12979 		rtw_phydm_ability_backup(padapter);
12980 		rtw_phydm_func_disable_all(padapter);
12981 
12982 		//cancel link timer
12983 		_cancel_timer_ex(&pmlmeext->link_timer);
12984 
12985 		//clear CAM
12986 		flush_all_cam_entry(padapter);
12987 
12988 		pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
12989 		_rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
12990 		pnetwork->IELength = pdev_network->IELength;
12991 
12992 		if (pnetwork->IELength > MAX_IE_SZ) {
12993 			ret = H2C_PARAMETERS_ERROR;
12994 			goto ibss_post_hdl;
12995 		}
12996 
12997 		_rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
12998 		start_create_ibss(padapter);
12999 	} else
13000 #endif /*CONFIG_ADHOC_MODE*/
13001 	{
13002 		rtw_warn_on(1);
13003 		ret = H2C_PARAMETERS_ERROR;
13004 	}
13005 
13006 ibss_post_hdl:
13007 	rtw_create_ibss_post_hdl(padapter, ret);
13008 
13009 exit:
13010 	return ret;
13011 }
13012 
13013 #ifdef CONFIG_IOCTL_CFG80211
rtw_set_wpa_version(struct security_priv * psecuritypriv,u32 wpa_version)13014 static int rtw_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
13015 {
13016 	DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
13017 
13018 	if (!wpa_version) {
13019 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
13020 		return 0;
13021 	}
13022 
13023 
13024 	if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
13025 	{
13026 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
13027 	}
13028 
13029 /*
13030 	if (wpa_version & NL80211_WPA_VERSION_2)
13031 	{
13032 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
13033 	}
13034 */
13035 
13036 	#ifdef CONFIG_WAPI_SUPPORT
13037 	if (wpa_version & NL80211_WAPI_VERSION_1)
13038 	{
13039 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
13040 	}
13041 	#endif
13042 
13043 	return 0;
13044 
13045 }
13046 
rtw_set_auth_type(struct security_priv * psecuritypriv,enum nl80211_auth_type sme_auth_type)13047 static int rtw_set_auth_type(struct security_priv *psecuritypriv,
13048 			     enum nl80211_auth_type sme_auth_type)
13049 {
13050 	DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
13051 
13052 
13053 	switch (sme_auth_type) {
13054 	case NL80211_AUTHTYPE_AUTOMATIC:
13055 
13056 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
13057 
13058 		break;
13059 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
13060 
13061 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
13062 
13063 		if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
13064 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
13065 
13066 #ifdef CONFIG_WAPI_SUPPORT
13067 		if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
13068 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
13069 #endif
13070 
13071 		break;
13072 	case NL80211_AUTHTYPE_SHARED_KEY:
13073 
13074 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
13075 
13076 		psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
13077 
13078 
13079 		break;
13080 	default:
13081 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
13082 		//return -ENOTSUPP;
13083 	}
13084 
13085 	return 0;
13086 
13087 }
13088 
rtw_set_cipher(struct security_priv * psecuritypriv,u32 cipher,bool ucast)13089 static int rtw_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
13090 {
13091 	u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
13092 
13093 	u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
13094 		&psecuritypriv->dot118021XGrpPrivacy;
13095 
13096 	DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
13097 
13098 
13099 	if (!cipher) {
13100 		*profile_cipher = _NO_PRIVACY_;
13101 		psecuritypriv->ndisencryptstatus = ndisencryptstatus;
13102 		return 0;
13103 	}
13104 
13105 	switch (cipher) {
13106 	case IW_AUTH_CIPHER_NONE:
13107 		*profile_cipher = _NO_PRIVACY_;
13108 		ndisencryptstatus = Ndis802_11EncryptionDisabled;
13109 #ifdef CONFIG_WAPI_SUPPORT
13110 		if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
13111 		{
13112 			*profile_cipher = _SMS4_;
13113 		}
13114 #endif
13115 		break;
13116 	case WLAN_CIPHER_SUITE_WEP40:
13117 		*profile_cipher = _WEP40_;
13118 		ndisencryptstatus = Ndis802_11Encryption1Enabled;
13119 		break;
13120 	case WLAN_CIPHER_SUITE_WEP104:
13121 		*profile_cipher = _WEP104_;
13122 		ndisencryptstatus = Ndis802_11Encryption1Enabled;
13123 		break;
13124 	case WLAN_CIPHER_SUITE_TKIP:
13125 		*profile_cipher = _TKIP_;
13126 		ndisencryptstatus = Ndis802_11Encryption2Enabled;
13127 		break;
13128 	case WLAN_CIPHER_SUITE_CCMP:
13129 		*profile_cipher = _AES_;
13130 		ndisencryptstatus = Ndis802_11Encryption3Enabled;
13131 		break;
13132 #ifdef CONFIG_WAPI_SUPPORT
13133 	case WLAN_CIPHER_SUITE_SMS4:
13134 		*profile_cipher = _SMS4_;
13135 		ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
13136 		break;
13137 #endif
13138 	default:
13139 		DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
13140 		return -ENOTSUPP;
13141 	}
13142 
13143 	if(ucast)
13144 	{
13145 		psecuritypriv->ndisencryptstatus = ndisencryptstatus;
13146 
13147 		//if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
13148 		//	psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
13149 	}
13150 
13151 	return 0;
13152 }
13153 
rtw_set_key_mgt(struct security_priv * psecuritypriv,u32 key_mgt)13154 static int rtw_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
13155 {
13156 	DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
13157 
13158 	if (key_mgt == WLAN_AKM_SUITE_8021X)
13159 		//*auth_type = UMAC_AUTH_TYPE_8021X;
13160 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
13161 	else if (key_mgt == WLAN_AKM_SUITE_PSK) {
13162 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
13163 	}
13164 #ifdef CONFIG_WAPI_SUPPORT
13165 	else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
13166 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
13167 	}
13168 	else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
13169 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
13170 	}
13171 #endif
13172 	else {
13173 		DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
13174 		//return -EINVAL;
13175 	}
13176 
13177 	return 0;
13178 }
13179 
rtw_set_wpa_ie(_adapter * padapter,u8 * pie,size_t ielen)13180 static int rtw_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
13181 {
13182 	u8 *buf=NULL, *pos=NULL;
13183 	u32 left;
13184 	int group_cipher = 0, pairwise_cipher = 0;
13185 	int ret = 0;
13186 	int wpa_ielen=0;
13187 	int wpa2_ielen=0;
13188 	u8 *pwpa, *pwpa2;
13189 	u8 null_addr[]= {0,0,0,0,0,0};
13190 
13191 	if (pie == NULL || !ielen) {
13192 		/* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
13193 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
13194 		goto exit;
13195 	}
13196 
13197 	if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
13198 		ret = -EINVAL;
13199 		goto exit;
13200 	}
13201 
13202 	buf = rtw_zmalloc(ielen);
13203 	if (buf == NULL){
13204 		ret =  -ENOMEM;
13205 		goto exit;
13206 	}
13207 
13208 	_rtw_memcpy(buf, pie , ielen);
13209 
13210 	//dump
13211 	{
13212 		int i;
13213 		DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
13214 		for(i=0;i<ielen;i=i+8)
13215 			DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7]);
13216 	}
13217 
13218 	pos = buf;
13219 	if(ielen < RSN_HEADER_LEN){
13220 		RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
13221 		ret  = -1;
13222 		goto exit;
13223 	}
13224 
13225 	pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
13226 	if(pwpa && wpa_ielen>0)
13227 	{
13228 		if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
13229 		{
13230 			padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
13231 			padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
13232 			_rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
13233 
13234 			DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
13235 		}
13236 	}
13237 
13238 	pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
13239 	if(pwpa2 && wpa2_ielen>0)
13240 	{
13241 		if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
13242 		{
13243 			padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
13244 			padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
13245 			_rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
13246 
13247 			DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
13248 		}
13249 	}
13250 
13251 	if (group_cipher == 0)
13252 	{
13253 		group_cipher = WPA_CIPHER_NONE;
13254 	}
13255 	if (pairwise_cipher == 0)
13256 	{
13257 		pairwise_cipher = WPA_CIPHER_NONE;
13258 	}
13259 
13260 	switch(group_cipher)
13261 	{
13262 		case WPA_CIPHER_NONE:
13263 			padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
13264 			padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
13265 			break;
13266 		case WPA_CIPHER_WEP40:
13267 			padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
13268 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13269 			break;
13270 		case WPA_CIPHER_TKIP:
13271 			padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
13272 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
13273 			break;
13274 		case WPA_CIPHER_CCMP:
13275 			padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
13276 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
13277 			break;
13278 		case WPA_CIPHER_WEP104:
13279 			padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
13280 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13281 			break;
13282 	}
13283 
13284 	switch(pairwise_cipher)
13285 	{
13286 		case WPA_CIPHER_NONE:
13287 			padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
13288 			padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
13289 			break;
13290 		case WPA_CIPHER_WEP40:
13291 			padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
13292 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13293 			break;
13294 		case WPA_CIPHER_TKIP:
13295 			padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
13296 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
13297 			break;
13298 		case WPA_CIPHER_CCMP:
13299 			padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
13300 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
13301 			break;
13302 		case WPA_CIPHER_WEP104:
13303 			padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
13304 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13305 			break;
13306 	}
13307 
13308 	{/* handle wps_ie */
13309 		uint wps_ielen;
13310 		u8 *wps_ie;
13311 
13312 		wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
13313 		if (wps_ie && wps_ielen > 0) {
13314 			DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
13315 			padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
13316 			_rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
13317 			set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
13318 		} else {
13319 			_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
13320 		}
13321 	}
13322 
13323 	#ifdef CONFIG_P2P
13324 	{//check p2p_ie for assoc req;
13325 		uint p2p_ielen=0;
13326 		u8 *p2p_ie;
13327 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13328 
13329 		if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
13330 		{
13331 			#ifdef CONFIG_DEBUG_CFG80211
13332 			DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
13333 			#endif
13334 
13335 			if(pmlmepriv->p2p_assoc_req_ie)
13336 			{
13337 				u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
13338 				pmlmepriv->p2p_assoc_req_ie_len = 0;
13339 				rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
13340 				pmlmepriv->p2p_assoc_req_ie = NULL;
13341 			}
13342 
13343 			pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
13344 			if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
13345 				DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
13346 				goto exit;
13347 			}
13348 			_rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
13349 			pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
13350 		}
13351 	}
13352 	#endif //CONFIG_P2P
13353 
13354 	#ifdef CONFIG_WFD
13355 	{//check wfd_ie for assoc req;
13356 		uint wfd_ielen=0;
13357 		u8 *wfd_ie;
13358 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13359 
13360 		if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
13361 		{
13362 			#ifdef CONFIG_DEBUG_CFG80211
13363 			DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
13364 			#endif
13365 
13366 			if(pmlmepriv->wfd_assoc_req_ie)
13367 			{
13368 				u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
13369 				pmlmepriv->wfd_assoc_req_ie_len = 0;
13370 				rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
13371 				pmlmepriv->wfd_assoc_req_ie = NULL;
13372 			}
13373 
13374 			pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
13375 			if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
13376 				DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
13377 				goto exit;
13378 			}
13379 			rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
13380 		}
13381 	}
13382 	#endif //CONFIG_WFD
13383 
13384 	//TKIP and AES disallow multicast packets until installing group key
13385 	if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
13386 		|| padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
13387 		|| padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
13388 		//WPS open need to enable multicast
13389 		//|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
13390 		rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
13391 
13392 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
13393 		("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
13394 		pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
13395 
13396 exit:
13397 	if (buf)
13398 		rtw_mfree(buf, ielen);
13399 	if (ret)
13400 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
13401 	return ret;
13402 }
13403 
start_connect_cmd_hdl(_adapter * padapter,u8 * pbuf)13404 u8 start_connect_cmd_hdl(_adapter *padapter, u8 *pbuf)
13405 {
13406 	NDIS_802_11_SSID ndis_ssid;
13407 	NDIS_802_11_AUTHENTICATION_MODE authmode;
13408 	struct cfg80211_connect_params *params = NULL;
13409 	struct security_priv *psecuritypriv = &padapter->securitypriv;
13410 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13411 	int ret = 0;
13412 
13413 	params = (struct cfg80211_connect_params *)pbuf;
13414 
13415 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
13416 		rtw_scan_abort(padapter);
13417 	}
13418 #ifdef CONFIG_CONCURRENT_MODE
13419 	if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
13420 		rtw_scan_abort(padapter->pbuddy_adapter);
13421 	}
13422 #endif
13423 
13424 	DBG_871X("%s ====>\n", __func__);
13425 	DBG_871X("wpa_version: %d cipher group:%d\n",
13426 		 params->crypto.wpa_versions, params->crypto.cipher_group);
13427 
13428 	_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
13429 	ndis_ssid.SsidLength = params->ssid_len;
13430 	_rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
13431 
13432 	DBG_871X("ssid=%s, len=%d\n",
13433 		  ndis_ssid.Ssid, ndis_ssid.SsidLength);
13434 
13435 	if (params->bssid)
13436 		DBG_871X("bssid="MAC_FMT"\n", MAC_ARG(params->bssid));
13437 
13438 	psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
13439 	psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
13440 	psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
13441 	psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
13442 	psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
13443 
13444 #ifdef CONFIG_WAPI_SUPPORT
13445 	padapter->wapiInfo.bWapiEnable = false;
13446 #endif
13447 
13448 	rtw_set_wpa_version(psecuritypriv, params->crypto.wpa_versions);
13449 
13450 	rtw_set_auth_type(psecuritypriv, params->auth_type);
13451 
13452 #ifdef CONFIG_WAPI_SUPPORT
13453 	if(params->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
13454 		padapter->wapiInfo.bWapiEnable = true;
13455 		padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
13456 		padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
13457 	}
13458 
13459 	if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI) {
13460 		padapter->mlmeextpriv.mlmext_info.auth_algo =
13461 			psecuritypriv->dot11AuthAlgrthm;
13462 	}
13463 #endif
13464 
13465 	DBG_871X("%s, ie_len=%zu\n", __func__, params->ie_len);
13466 
13467 	ret = rtw_set_wpa_ie(padapter, (u8 *)params->ie, params->ie_len);
13468 	if (ret < 0) {
13469 		DBG_871X("%s: set wpa ie fail\n", __func__);
13470 		return H2C_PARAMETERS_ERROR;
13471 	}
13472 
13473 	if (params->crypto.n_ciphers_pairwise) {
13474 		ret = rtw_set_cipher(psecuritypriv,
13475 					params->crypto.ciphers_pairwise[0],
13476 					_TRUE);
13477 		if (ret < 0) {
13478 			DBG_871X("%s: set wpa cipher fail\n", __func__);
13479 			return H2C_PARAMETERS_ERROR;
13480 		}
13481 	}
13482 
13483 	//For WEP Shared auth
13484 	if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared ||
13485 	    psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) &&
13486 	   params->key) {
13487 		u32 wep_key_idx, wep_key_len,wep_total_len;
13488 		NDIS_802_11_WEP	 *pwep = NULL;
13489 		DBG_871X("%s(): Shared/Auto WEP\n", __func__);
13490 
13491 		wep_key_idx = params->key_idx;
13492 		wep_key_len = params->key_len;
13493 
13494 		if (params->key_idx > WEP_KEYS) {
13495 			DBG_871X("%s: incorrect WEP key id.\n", __func__);
13496 			return H2C_PARAMETERS_ERROR;
13497 		}
13498 
13499 		if (wep_key_len > 0) {
13500 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
13501 			wep_total_len = wep_key_len +
13502 				FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
13503 			pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
13504 			if (pwep == NULL) {
13505 				DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
13506 				return H2C_PARAMETERS_ERROR;
13507 			}
13508 
13509 			_rtw_memset(pwep, 0, wep_total_len);
13510 
13511 			pwep->KeyLength = wep_key_len;
13512 			pwep->Length = wep_total_len;
13513 
13514 			if (wep_key_len==13) {
13515 				padapter->securitypriv.dot11PrivacyAlgrthm =
13516 					_WEP104_;
13517 				padapter->securitypriv.dot118021XGrpPrivacy =
13518 					_WEP104_;
13519 			}
13520 		}
13521 		else {
13522 			DBG_871X("%s: incorrect key length\n", __func__);
13523 			return H2C_PARAMETERS_ERROR;
13524 		}
13525 
13526 		pwep->KeyIndex = wep_key_idx;
13527 		pwep->KeyIndex |= 0x80000000;
13528 
13529 		_rtw_memcpy(pwep->KeyMaterial, (void *)params->key,
13530 			    pwep->KeyLength);
13531 
13532 		if(rtw_set_802_11_add_wep(padapter, pwep) == _FAIL) {
13533 			DBG_871X("%s: add wep fail\n", __func__);
13534 			return H2C_PARAMETERS_ERROR;
13535 		}
13536 
13537 		if (pwep)
13538 			rtw_mfree((u8 *)pwep, wep_total_len);
13539 	}
13540 
13541 	rtw_set_cipher(psecuritypriv,
13542 				params->crypto.cipher_group, _FALSE);
13543 
13544 	if (params->crypto.n_akm_suites) {
13545 		ret = rtw_set_key_mgt(psecuritypriv,
13546 					       params->crypto.akm_suites[0]);
13547 		if (ret < 0) {
13548 			DBG_871X("%s: set key mgt fail\n", __func__);
13549 			return H2C_PARAMETERS_ERROR;
13550 		}
13551 	}
13552 
13553 #ifdef CONFIG_WAPI_SUPPORT
13554 	if(params->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK) {
13555 		padapter->wapiInfo.bWapiPSK = true;
13556 	} else if (params->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT) {
13557 	      padapter->wapiInfo.bWapiPSK = false;
13558 	}
13559 #endif
13560 
13561 	authmode = psecuritypriv->ndisauthtype;
13562 	rtw_set_802_11_authentication_mode(padapter, authmode);
13563 
13564 	ret = rtw_set_802_11_connect(padapter, (u8 *)params->bssid, &ndis_ssid);
13565 	if (ret == _FALSE) {
13566 		DBG_871X("%s: set connect fail\n", __func__);
13567 		return H2C_PARAMETERS_ERROR;
13568 	}
13569 
13570 	DBG_871X("%s: set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n",
13571 		 __func__,psecuritypriv->dot11AuthAlgrthm,
13572 		 psecuritypriv->dot11PrivacyAlgrthm,
13573 		 psecuritypriv->dot118021XGrpPrivacy);
13574 
13575 	return H2C_SUCCESS;
13576 }
13577 #endif
13578 
join_cmd_hdl(_adapter * padapter,u8 * pbuf)13579 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13580 {
13581 	u8	join_type;
13582 	PNDIS_802_11_VARIABLE_IEs	pIE;
13583 	struct registry_priv	*pregpriv = &padapter->registrypriv;
13584 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13585 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13586 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13587 #ifdef CONFIG_ANTENNA_DIVERSITY
13588 	struct joinbss_parm	*pparm = (struct joinbss_parm *)pbuf;
13589 #endif //CONFIG_ANTENNA_DIVERSITY
13590 	u32 i;
13591 	//u8	initialgain;
13592 	//u32	acparm;
13593 	u8 u_ch, u_bw, u_offset;
13594 
13595 	//check already connecting to AP or not
13596 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
13597 	{
13598 		if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13599 		{
13600 			issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13601 		}
13602 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
13603 
13604 		//clear CAM
13605 		flush_all_cam_entry(padapter);
13606 
13607 		_cancel_timer_ex(&pmlmeext->link_timer);
13608 
13609 		//set MSR to nolink -> infra. mode
13610 		//Set_MSR(padapter, _HW_STATE_NOLINK_);
13611 		Set_MSR(padapter, _HW_STATE_STATION_);
13612 
13613 
13614 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13615 	}
13616 
13617 #ifdef CONFIG_ANTENNA_DIVERSITY
13618 	rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13619 #endif
13620 
13621 #ifdef CONFIG_WAPI_SUPPORT
13622 	rtw_wapi_clear_all_cam_entry(padapter);
13623 #endif
13624 
13625 	rtw_joinbss_reset(padapter);
13626 
13627 	pmlmeinfo->ERP_enable = 0;
13628 	pmlmeinfo->WMM_enable = 0;
13629 	pmlmeinfo->HT_enable = 0;
13630 	pmlmeinfo->HT_caps_enable = 0;
13631 	pmlmeinfo->HT_info_enable = 0;
13632 	pmlmeinfo->agg_enable_bitmap = 0;
13633 	pmlmeinfo->candidate_tid_bitmap = 0;
13634 	pmlmeinfo->bwmode_updated = _FALSE;
13635 	//pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
13636 	pmlmeinfo->VHT_enable = 0;
13637 
13638 	_rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13639 	pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13640 
13641 	if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
13642 		return H2C_PARAMETERS_ERROR;
13643 
13644 	if (pnetwork->IELength < 2) {
13645 		report_join_res(padapter, (-4));
13646 		return H2C_SUCCESS;
13647 	}
13648 	_rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
13649 
13650 	pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13651 
13652 	//Check AP vendor to move rtw_joinbss_cmd()
13653 	//pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
13654 
13655 	//sizeof(NDIS_802_11_FIXED_IEs)
13656 	for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13657 		pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13658 
13659 		switch (pIE->ElementID)
13660 		{
13661 			case _VENDOR_SPECIFIC_IE_://Get WMM IE.
13662 				if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
13663 				{
13664 					WMM_param_handler(padapter, pIE);
13665 				}
13666 				break;
13667 
13668 #ifdef CONFIG_80211N_HT
13669 			case _HT_CAPABILITY_IE_:	//Get HT Cap IE.
13670 				pmlmeinfo->HT_caps_enable = 1;
13671 				break;
13672 
13673 			case _HT_EXTRA_INFO_IE_:	//Get HT Info IE.
13674 				pmlmeinfo->HT_info_enable = 1;
13675 				break;
13676 #endif /* CONFIG_80211N_HT */
13677 
13678 #ifdef CONFIG_80211AC_VHT
13679 			case EID_VHTCapability://Get VHT Cap IE.
13680 				pmlmeinfo->VHT_enable = 1;
13681 				break;
13682 
13683 			case EID_VHTOperation://Get VHT Operation IE.
13684 				break;
13685 #endif /* CONFIG_80211AC_VHT */
13686 			default:
13687 				break;
13688 		}
13689 
13690 		i += (pIE->Length + 2);
13691 	}
13692 
13693 	rtw_bss_get_chbw(pnetwork
13694 		, &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13695 
13696 	rtw_regsty_adjust_chbw(pregpriv, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13697 
13698 #if 0
13699 	if (padapter->registrypriv.wifi_spec) {
13700 		// for WiFi test, follow WMM test plan spec
13701 		acparm = 0x002F431C; // VO
13702 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13703 		acparm = 0x005E541C; // VI
13704 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13705 		acparm = 0x0000A525; // BE
13706 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13707 		acparm = 0x0000A549; // BK
13708 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13709 
13710 		// for WiFi test, mixed mode with intel STA under bg mode throughput issue
13711 		if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
13712 			acparm = 0x00004320;
13713 			rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13714 		}
13715 	}
13716 	else {
13717 		acparm = 0x002F3217; // VO
13718 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13719 		acparm = 0x005E4317; // VI
13720 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13721 		acparm = 0x00105320; // BE
13722 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13723 		acparm = 0x0000A444; // BK
13724 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13725 	}
13726 #endif
13727 
13728 	/* check channel, bandwidth, offset and switch */
13729 	if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
13730 		report_join_res(padapter, (-4));
13731 		return H2C_SUCCESS;
13732 	}
13733 
13734 	//disable dynamic functions, such as high power, DIG
13735 	/*rtw_phydm_func_disable_all(padapter);*/
13736 
13737 	//config the initial gain under linking, need to write the BB registers
13738 	//initialgain = 0x1E;
13739 	/*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13740 
13741 	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
13742 	join_type = 0;
13743 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13744 	rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
13745 
13746 	set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
13747 
13748 	//cancel link timer
13749 	_cancel_timer_ex(&pmlmeext->link_timer);
13750 
13751 	start_clnt_join(padapter);
13752 
13753 	return H2C_SUCCESS;
13754 
13755 }
13756 
disconnect_hdl(_adapter * padapter,unsigned char * pbuf)13757 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
13758 {
13759 	struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
13760 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13761 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13762 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13763 	u8 val8;
13764 
13765 	if (is_client_associated_to_ap(padapter))
13766 	{
13767 #ifdef CONFIG_DFS
13768 		if(padapter->mlmepriv.handle_dfs == _FALSE)
13769 #endif //CONFIG_DFS
13770 #ifdef CONFIG_PLATFORM_ROCKCHIPS
13771 			//To avoid connecting to AP fail during resume process, change retry count from 5 to 1
13772 			issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13773 #else
13774 			issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
13775 #endif //CONFIG_PLATFORM_ROCKCHIPS
13776 	}
13777 
13778 #ifdef CONFIG_DFS
13779 	if( padapter->mlmepriv.handle_dfs == _TRUE )
13780 		padapter->mlmepriv.handle_dfs = _FALSE;
13781 #endif //CONFIG_DFS
13782 
13783 	if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13784 	{
13785 		//Stop BCN
13786 		val8 = 0;
13787 		rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13788 	}
13789 
13790 	rtw_mlmeext_disconnect(padapter);
13791 
13792 	rtw_free_uc_swdec_pending_queue(padapter);
13793 
13794 	return 	H2C_SUCCESS;
13795 }
13796 
13797 static const char * const _scan_state_str[] = {
13798 	"SCAN_DISABLE",
13799 	"SCAN_START",
13800 	"SCAN_PS_ANNC_WAIT",
13801 	"SCAN_ENTER",
13802 	"SCAN_PROCESS",
13803 	"SCAN_BACKING_OP",
13804 	"SCAN_BACK_OP",
13805 	"SCAN_LEAVING_OP",
13806 	"SCAN_LEAVE_OP",
13807 	"SCAN_SW_ANTDIV_BL",
13808 	"SCAN_TO_P2P_LISTEN",
13809 	"SCAN_P2P_LISTEN",
13810 	"SCAN_COMPLETE",
13811 	"SCAN_STATE_MAX",
13812 };
13813 
scan_state_str(u8 state)13814 const char *scan_state_str(u8 state)
13815 {
13816 	state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
13817 	return _scan_state_str[state];
13818 }
13819 
scan_abort_hdl(_adapter * adapter)13820 static bool scan_abort_hdl(_adapter *adapter)
13821 {
13822 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13823 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13824 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
13825 #ifdef CONFIG_P2P
13826 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13827 #endif
13828 	bool ret = _FALSE;
13829 
13830 	if (pmlmeext->scan_abort == _TRUE) {
13831 		#ifdef CONFIG_P2P
13832 		if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
13833 			rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
13834 			ss->channel_idx = 3;
13835 			DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
13836 				, ss->channel_idx
13837 				, pwdinfo->find_phase_state_exchange_cnt
13838 			);
13839 		} else
13840 		#endif
13841 		{
13842 			ss->channel_idx = ss->ch_num;
13843 			DBG_871X("%s idx:%d\n", __FUNCTION__
13844 				, ss->channel_idx
13845 			);
13846 		}
13847 		pmlmeext->scan_abort = _FALSE;
13848 		ret = _TRUE;
13849 	}
13850 
13851 	return ret;
13852 }
13853 
rtw_scan_sparse(_adapter * adapter,struct rtw_ieee80211_channel * ch,u8 ch_num)13854 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13855 {
13856 /* interval larger than this is treated as backgroud scan */
13857 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13858 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13859 #endif
13860 
13861 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13862 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13863 #endif
13864 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13865 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13866 #endif
13867 
13868 #define SCAN_SPARSE_CH_NUM_INVALID 255
13869 
13870 	static u8 token = 255;
13871 	u32 interval;
13872 	bool busy_traffic = _FALSE;
13873 	bool miracast_enabled = _FALSE;
13874 	bool bg_scan = _FALSE;
13875 	u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13876 	u8 scan_division_num;
13877 	u8 ret_num = ch_num;
13878 	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13879 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13880 
13881 	if (regsty->wifi_spec)
13882 		goto exit;
13883 
13884 	/* assume ch_num > 6 is normal scan */
13885 	if (ch_num <= 6)
13886 		goto exit;
13887 
13888 	if (mlmeext->last_scan_time == 0)
13889 		mlmeext->last_scan_time = rtw_get_current_time();
13890 
13891 	interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13892 
13893 	if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE
13894 		#ifdef CONFIG_CONCURRENT_MODE
13895 		|| (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
13896 		#endif
13897 	)
13898 			busy_traffic = _TRUE;
13899 
13900 	#ifdef CONFIG_WFD
13901 	if (is_miracast_enabled(adapter->wfd_info.stack_wfd_mode)
13902 		#ifdef CONFIG_CONCURRENT_MODE
13903 		|| (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter->wfd_info.stack_wfd_mode))
13904 		#endif
13905 	)
13906 		miracast_enabled = _TRUE;
13907 	#endif
13908 
13909 	if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13910 		bg_scan = _TRUE;
13911 
13912 	/* max_allow_ch by conditions*/
13913 
13914 	#if RTW_SCAN_SPARSE_MIRACAST
13915 	if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13916 		max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13917 	#endif
13918 
13919 	#if RTW_SCAN_SPARSE_BG
13920 	if (bg_scan == _TRUE)
13921 		max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13922 	#endif
13923 
13924 
13925 	if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13926 		int i;
13927 		int k = 0;
13928 
13929 		scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0);
13930 		token = (token + 1) % scan_division_num;
13931 
13932 		if (0)
13933 			DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token);
13934 
13935 		for (i = 0; i < ch_num; i++) {
13936 			if (ch[i].hw_value && (i % scan_division_num) == token
13937 			) {
13938 				if (i != k)
13939 					_rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13940 				k++;
13941 			}
13942 		}
13943 
13944 		_rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13945 
13946 		ret_num = k;
13947 		mlmeext->last_scan_time = rtw_get_current_time();
13948 	}
13949 
13950 exit:
13951 	return ret_num;
13952 }
13953 
rtw_scan_ch_decision(_adapter * padapter,struct rtw_ieee80211_channel * out,u32 out_num,struct rtw_ieee80211_channel * in,u32 in_num)13954 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13955 	u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13956 {
13957 	int i, j;
13958 	int scan_ch_num = 0;
13959 	int set_idx;
13960 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13961 
13962 	/* clear first */
13963 	_rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
13964 
13965 	/* acquire channels from in */
13966 	j = 0;
13967 	for (i=0;i<in_num;i++) {
13968 
13969 		if (0)
13970 			DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13971 
13972 		if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
13973 			&& (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
13974 			&& rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE
13975 		)
13976 		{
13977 			if (j >= out_num) {
13978 				DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13979 					FUNC_ADPT_ARG(padapter), out_num);
13980 				break;
13981 			}
13982 
13983 			_rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13984 
13985 			if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13986 				out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13987 
13988 			j++;
13989 		}
13990 		if(j>=out_num)
13991 			break;
13992 	}
13993 
13994 	/* if out is empty, use channel_set as default */
13995 	if(j == 0) {
13996 		for (i=0;i<pmlmeext->max_chan_nums;i++) {
13997 
13998 			if (0)
13999 				DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
14000 
14001 			if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) {
14002 
14003 				if (j >= out_num) {
14004 					DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
14005 						FUNC_ADPT_ARG(padapter), out_num);
14006 					break;
14007 				}
14008 
14009 				out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
14010 
14011 				if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
14012 					out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14013 
14014 				j++;
14015 			}
14016 		}
14017 	}
14018 
14019 	/* scan_sparse */
14020 	j = rtw_scan_sparse(padapter, out, j);
14021 
14022 	return j;
14023 }
14024 
sitesurvey_res_reset(_adapter * adapter,struct sitesurvey_parm * parm)14025 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
14026 {
14027 	struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
14028 	int i;
14029 
14030 	ss->bss_cnt = 0;
14031 	ss->channel_idx = 0;
14032 #ifdef CONFIG_SCAN_BACKOP
14033 	ss->scan_cnt = 0;
14034 #endif
14035 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14036 	ss->is_sw_antdiv_bl_scan = 0;
14037 #endif
14038 
14039 	for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14040 		if (parm->ssid[i].SsidLength) {
14041 			_rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
14042 			ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
14043 		} else {
14044 			ss->ssid[i].SsidLength = 0;
14045 		}
14046 	}
14047 
14048 	ss->ch_num = rtw_scan_ch_decision(adapter
14049 		, ss->ch, RTW_CHANNEL_SCAN_AMOUNT
14050 		, parm->ch, parm->ch_num
14051 	);
14052 
14053 	ss->scan_mode = parm->scan_mode;
14054 }
14055 
sitesurvey_pick_ch_behavior(_adapter * padapter,u8 * ch,RT_SCAN_TYPE * type)14056 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
14057 {
14058 	u8 next_state;
14059 	u8 scan_ch = 0;
14060 	RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
14061 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14062 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
14063 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
14064 
14065 #ifdef CONFIG_P2P
14066 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14067 #endif
14068 
14069 	/* handle scan abort request */
14070 	scan_abort_hdl(padapter);
14071 
14072 #ifdef CONFIG_P2P
14073 	if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
14074 		if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
14075 			scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
14076 		else
14077 			scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
14078 		scan_type = SCAN_ACTIVE;
14079 	} else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
14080 		/*
14081 		* Commented by Albert 2011/06/03
14082 		* The driver is in the find phase, it should go through the social channel.
14083 		*/
14084 		int ch_set_idx;
14085 
14086 		scan_ch = pwdinfo->social_chan[ss->channel_idx];
14087 		ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch);
14088 		if (ch_set_idx >= 0)
14089 			scan_type = pmlmeext->channel_set[ch_set_idx].ScanType;
14090 		else
14091 			scan_type = SCAN_ACTIVE;
14092 	} else
14093 #endif /* CONFIG_P2P */
14094 	{
14095 		struct rtw_ieee80211_channel *ch;
14096 
14097 		if (ss->channel_idx < ss->ch_num) {
14098 			ch = &ss->ch[ss->channel_idx];
14099 			scan_ch = ch->hw_value;
14100 			scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
14101 		}
14102 	}
14103 
14104 	if (scan_ch != 0) {
14105 		next_state = SCAN_PROCESS;
14106 		#ifdef CONFIG_SCAN_BACKOP
14107 		{
14108 			u8 sta_num;
14109 			u8 ld_sta_num;
14110 			u8 ap_num;
14111 			u8 ld_ap_num;
14112 			u8 backop_flags = 0;
14113 
14114 			rtw_dev_iface_status(padapter, &sta_num, &ld_sta_num, NULL, &ap_num, &ld_ap_num);
14115 
14116 			if ((ld_sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN))
14117 					|| (sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL))
14118 			) {
14119 				backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext);
14120 			}
14121 
14122 			if ((ld_ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN))
14123 					|| (ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL))
14124 			) {
14125 				backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext);
14126 			}
14127 
14128 			if (backop_flags) {
14129 				if (ss->scan_cnt < ss->scan_cnt_max) {
14130 					ss->scan_cnt++;
14131 				} else {
14132 					mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
14133 					next_state = SCAN_BACKING_OP;
14134 				}
14135 			}
14136 		}
14137 		#endif /* CONFIG_SCAN_BACKOP */
14138 	#ifdef CONFIG_P2P
14139 	} else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
14140 		/* go p2p listen */
14141 		next_state = SCAN_TO_P2P_LISTEN;
14142 	#endif
14143 	#ifdef CONFIG_ANTENNA_DIVERSITY
14144 	} else if (rtw_hal_antdiv_before_linked(padapter)) {
14145 		/* go sw antdiv before link */
14146 		next_state = SCAN_SW_ANTDIV_BL;
14147 	#endif
14148 	} else {
14149 		next_state = SCAN_COMPLETE;
14150 
14151 		#if defined(DBG_SCAN_SW_ANTDIV_BL)
14152 		{
14153 			/* for SCAN_SW_ANTDIV_BL state testing */
14154 			struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14155 			int i;
14156 			bool is_linked = _FALSE;
14157 
14158 			for (i = 0; i < dvobj->iface_nums; i++) {
14159 				if (rtw_linked_check(dvobj->padapters[i]))
14160 					is_linked = _TRUE;
14161 			}
14162 
14163 			if (!is_linked) {
14164 				static bool fake_sw_antdiv_bl_state = 0;
14165 
14166 				if (fake_sw_antdiv_bl_state == 0) {
14167 					next_state = SCAN_SW_ANTDIV_BL;
14168 					fake_sw_antdiv_bl_state = 1;
14169 				} else {
14170 					fake_sw_antdiv_bl_state = 0;
14171 				}
14172 			}
14173 		}
14174 		#endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
14175 	}
14176 
14177 	#ifdef CONFIG_SCAN_BACKOP
14178 	if (next_state != SCAN_PROCESS)
14179 		ss->scan_cnt = 0;
14180 	#endif
14181 
14182 
14183 #ifdef DBG_FIXED_CHAN
14184 	if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
14185 		scan_ch = pmlmeext->fixed_chan;
14186 #endif
14187 
14188 	if (ch)
14189 		*ch = scan_ch;
14190 	if (type)
14191 		*type = scan_type;
14192 
14193 	return next_state;
14194 }
14195 
site_survey(_adapter * padapter,u8 survey_channel,RT_SCAN_TYPE ScanType)14196 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
14197 {
14198 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14199 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14200 
14201 #ifdef CONFIG_P2P
14202 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
14203 #endif
14204 
14205 	if (survey_channel != 0) {
14206 		set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14207 
14208 		#ifdef CONFIG_AUTO_CHNL_SEL_NHM
14209 		if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
14210 			ACS_OP acs_op = ACS_RESET;
14211 
14212 			rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
14213 			rtw_set_acs_channel(padapter, survey_channel);
14214 			#ifdef DBG_AUTO_CHNL_SEL_NHM
14215 			DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n",
14216 				ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
14217 			#endif
14218 		}
14219 		#endif
14220 
14221 		if (ScanType == SCAN_ACTIVE) {
14222 			#ifdef CONFIG_P2P
14223 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
14224 				rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14225 			) {
14226 				issue_probereq_p2p(padapter, NULL);
14227 				issue_probereq_p2p(padapter, NULL);
14228 				issue_probereq_p2p(padapter, NULL);
14229 			} else
14230 			#endif /* CONFIG_P2P */
14231 			{
14232 				int i;
14233 
14234 				for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14235 					if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
14236 						/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14237 						if (padapter->registrypriv.wifi_spec)
14238 							issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
14239 						else
14240 							issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
14241 						issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
14242 					}
14243 				}
14244 
14245 				if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
14246 					/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14247 					if (padapter->registrypriv.wifi_spec)
14248 						issue_probereq(padapter, NULL, NULL);
14249 					else
14250 						issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
14251 					issue_probereq(padapter, NULL, NULL);
14252 				}
14253 			}
14254 		}
14255 	} else {
14256 		/* channel number is 0 or this channel is not valid. */
14257 		rtw_warn_on(1);
14258 	}
14259 
14260 	return;
14261 }
14262 
survey_done_set_ch_bw(_adapter * padapter)14263 void survey_done_set_ch_bw(_adapter *padapter)
14264 {
14265 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14266 	u8 cur_channel = 0;
14267 	u8 cur_bwmode;
14268 	u8 cur_ch_offset;
14269 
14270 	if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
14271 		if (0)
14272 			DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
14273 				FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14274 	} else {
14275 		#ifdef CONFIG_P2P
14276 		struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14277 		_adapter *iface;
14278 		int i;
14279 
14280 		for (i = 0; i < dvobj->iface_nums; i++) {
14281 			iface = dvobj->padapters[i];
14282 			if (!iface)
14283 				continue;
14284 
14285 			#ifdef CONFIG_IOCTL_CFG80211
14286 			if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
14287 				continue;
14288 			#endif
14289 
14290 			if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
14291 				cur_channel = iface->wdinfo.listen_channel;
14292 				cur_bwmode = CHANNEL_WIDTH_20;
14293 				cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14294 				if (0)
14295 					DBG_871X(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
14296 						FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
14297 				break;
14298 			}
14299 		}
14300 		#endif /* CONFIG_P2P */
14301 
14302 		if (cur_channel == 0) {
14303 			cur_channel = pmlmeext->cur_channel;
14304 			cur_bwmode = pmlmeext->cur_bwmode;
14305 			cur_ch_offset = pmlmeext->cur_ch_offset;
14306 			if (0)
14307 				DBG_871X(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
14308 					FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14309 		}
14310 	}
14311 
14312 	set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
14313 }
14314 
14315 /**
14316  * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
14317  * @dvobj: the dvobj to check
14318  * @ps: power saving or not
14319  *
14320  * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
14321  */
sitesurvey_ps_annc(struct dvobj_priv * dvobj,bool ps)14322 u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps)
14323 {
14324 	_adapter *adapter;
14325 	int i;
14326 	u8 ps_anc = 0;
14327 
14328 	for (i = 0; i < dvobj->iface_nums; i++) {
14329 		adapter = dvobj->padapters[i];
14330 		if (!adapter)
14331 			continue;
14332 
14333 		if (ps) {
14334 			if (is_client_associated_to_ap(adapter) == _TRUE) {
14335 				/* TODO: TDLS peers */
14336 				issue_nulldata(adapter, NULL, 1, 3, 500);
14337 				ps_anc = 1;
14338 			}
14339 		} else {
14340 			if (is_client_associated_to_ap(adapter) == _TRUE) {
14341 				/* TODO: TDLS peers */
14342 				issue_nulldata(adapter, NULL, 0, 3, 500);
14343 				ps_anc = 1;
14344 			}
14345 		}
14346 	}
14347 
14348 	return ps_anc;
14349 }
14350 
sitesurvey_set_igi(_adapter * adapter,bool enter)14351 void sitesurvey_set_igi(_adapter *adapter, bool enter)
14352 {
14353 	u8 igi;
14354 #ifdef CONFIG_P2P
14355 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
14356 #endif
14357 
14358 	if (enter) {
14359 #ifdef CONFIG_P2P
14360 #ifdef CONFIG_IOCTL_CFG80211
14361 		if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211)
14362 			igi = 0x30;
14363 		else
14364 #endif /* CONFIG_IOCTL_CFG80211 */
14365 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
14366 			igi = 0x28;
14367 		else
14368 #endif /* CONFIG_P2P */
14369 			igi = 0x1e;
14370 	} else {
14371 			igi = 0xff; /* restore RX GAIN */
14372 	}
14373 
14374 	rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
14375 }
14376 
sitesurvey_cmd_hdl(_adapter * padapter,u8 * pbuf)14377 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
14378 {
14379 	struct sitesurvey_parm	*pparm = (struct sitesurvey_parm *)pbuf;
14380 	struct dvobj_priv *dvobj = padapter->dvobj;
14381 	struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
14382 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14383 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14384 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
14385 	u8 val8;
14386 
14387 #ifdef CONFIG_P2P
14388 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14389 #endif
14390 
14391 #ifdef DBG_CHECK_FW_PS_STATE
14392 	if (rtw_fw_ps_state(padapter) == _FAIL) {
14393 		DBG_871X("scan without leave 32k\n");
14394 		pdbgpriv->dbg_scan_pwr_state_cnt++;
14395 	}
14396 #endif /* DBG_CHECK_FW_PS_STATE */
14397 
14398 	/* increase channel idx */
14399 	if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
14400 		ss->channel_idx++;
14401 
14402 	/* update scan state to next state (assigned by previous cmd hdl) */
14403 	if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
14404 		mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
14405 
14406 operation_by_state:
14407 	switch (mlmeext_scan_state(pmlmeext)) {
14408 
14409 	case SCAN_DISABLE:
14410 		/*
14411 		* SW parameter initialization
14412 		*/
14413 
14414 		sitesurvey_res_reset(padapter, pparm);
14415 		mlmeext_set_scan_state(pmlmeext, SCAN_START);
14416 		goto operation_by_state;
14417 
14418 	case SCAN_START:
14419 		/*
14420 		* prepare to leave operating channel
14421 		*/
14422 
14423 		/* apply rx ampdu setting */
14424 		if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
14425 			|| ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID
14426 		) {
14427 			rtw_rx_ampdu_apply(padapter);
14428 		}
14429 
14430 		/* clear HW TX queue before scan */
14431 		rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14432 
14433 		/* power save state announcement */
14434 		if (sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)) {
14435 			mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14436 			mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
14437 			set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14438 		} else {
14439 			mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
14440 			goto operation_by_state;
14441 		}
14442 
14443 		break;
14444 
14445 	case SCAN_ENTER:
14446 		/*
14447 		* HW register and DM setting for enter scan
14448 		*/
14449 
14450 		/* config the initial gain under scanning */
14451 		sitesurvey_set_igi(padapter, 1);
14452 
14453 		/* disable dynamic functions, such as high power, DIG */
14454 		rtw_phydm_ability_backup(padapter);
14455 		rtw_phydm_func_for_offchannel(padapter);
14456 
14457 		/* set MSR to no link state */
14458 		Set_MSR(padapter, _HW_STATE_NOLINK_);
14459 		val8 = 1; /* under site survey */
14460 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14461 
14462 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14463 		goto operation_by_state;
14464 
14465 	case SCAN_PROCESS:
14466 	{
14467 		u8 scan_ch;
14468 		RT_SCAN_TYPE scan_type;
14469 		u8 next_state;
14470 		u32 scan_ms;
14471 
14472 		#ifdef CONFIG_AUTO_CHNL_SEL_NHM
14473 		if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) {
14474 			ACS_OP acs_op = ACS_SELECT;
14475 
14476 			rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
14477 		}
14478 		#endif
14479 
14480 		next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
14481 		if (next_state != SCAN_PROCESS) {
14482 			#ifdef CONFIG_AUTO_CHNL_SEL_NHM
14483 			if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
14484 				rtw_set_acs_channel(padapter, 0);
14485 				#ifdef DBG_AUTO_CHNL_SEL_NHM
14486 				DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
14487 				#endif
14488 			}
14489 			#endif
14490 
14491 			mlmeext_set_scan_state(pmlmeext, next_state);
14492 			goto operation_by_state;
14493 		}
14494 
14495 		/* still SCAN_PROCESS state */
14496 		if (0)
14497 			#ifdef CONFIG_P2P
14498 			DBG_871X(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
14499 				, FUNC_ADPT_ARG(padapter)
14500 				, mlmeext_scan_state_str(pmlmeext)
14501 				, scan_ch
14502 				, pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
14503 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14504 				, scan_type?'A':'P', ss->scan_mode?'A':'P'
14505 				, ss->ssid[0].SsidLength?'S':' '
14506 			);
14507 			#else
14508 			DBG_871X(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n"
14509 				, FUNC_ADPT_ARG(padapter)
14510 				, mlmeext_scan_state_str(pmlmeext)
14511 				, scan_ch
14512 				, ss->channel_idx
14513 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14514 				, scan_type?'A':'P', ss->scan_mode?'A':'P'
14515 				, ss->ssid[0].SsidLength?'S':' '
14516 			);
14517 			#endif /* CONFIG_P2P */
14518 
14519 		#ifdef DBG_FIXED_CHAN
14520 		if (pmlmeext->fixed_chan != 0xff)
14521 			DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
14522 		#endif
14523 
14524 		site_survey(padapter, scan_ch, scan_type);
14525 
14526 		#if defined(CONFIG_ATMEL_RC_PATCH)
14527 		if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
14528 			scan_ms = 20;
14529 		else
14530 			scan_ms = 40;
14531 		#else
14532 		scan_ms = ss->scan_ch_ms;
14533 		#endif
14534 
14535 		#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14536 		if (ss->is_sw_antdiv_bl_scan)
14537 			scan_ms = scan_ms/2;
14538 		#endif
14539 
14540 		#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14541 		{
14542 			struct noise_info info;
14543 
14544 			info.bPauseDIG = _FALSE;
14545 			info.IGIValue = 0;
14546 			info.max_time = scan_ms/2;
14547 			info.chan = scan_ch;
14548 			rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
14549 		}
14550 		#endif
14551 
14552 		set_survey_timer(pmlmeext, scan_ms);
14553 		break;
14554 	}
14555 
14556 	#ifdef CONFIG_SCAN_BACKOP
14557 	case SCAN_BACKING_OP:
14558 	{
14559 		u8 back_ch, back_bw, back_ch_offset;
14560 
14561 		if (rtw_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
14562 			rtw_warn_on(1);
14563 
14564 		if (0)
14565 			DBG_871X(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
14566 				, FUNC_ADPT_ARG(padapter)
14567 				, mlmeext_scan_state_str(pmlmeext)
14568 				, back_ch, back_bw, back_ch_offset
14569 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14570 			);
14571 
14572 		set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
14573 
14574 		Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14575 		val8 = 0; /* survey done */
14576 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14577 
14578 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14579 			sitesurvey_set_igi(padapter, 0);
14580 			sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14581 		}
14582 
14583 		mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
14584 		ss->backop_time = rtw_get_current_time();
14585 
14586 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME)) {
14587 			int	i;
14588 
14589 			/* resume TX */
14590 			for (i = 0; i < dvobj->iface_nums; i++) {
14591 				if (!dvobj->padapters[i])
14592 					continue;
14593 
14594 				rtw_os_xmit_schedule(dvobj->padapters[i]);
14595 			}
14596 		}
14597 
14598 		goto operation_by_state;
14599 	}
14600 
14601 	case SCAN_BACK_OP:
14602 		if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
14603 			|| pmlmeext->scan_abort
14604 		) {
14605 			mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
14606 			goto operation_by_state;
14607 		}
14608 		set_survey_timer(pmlmeext, 50);
14609 		break;
14610 
14611 	case SCAN_LEAVING_OP:
14612 		/*
14613 		* prepare to leave operating channel
14614 		*/
14615 
14616 		/* clear HW TX queue before scan */
14617 		rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14618 
14619 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
14620 			&& sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)
14621 		) {
14622 			mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14623 			mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
14624 			set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14625 		} else {
14626 			mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
14627 			goto operation_by_state;
14628 		}
14629 
14630 		break;
14631 
14632 	case SCAN_LEAVE_OP:
14633 		/*
14634 		* HW register and DM setting for enter scan
14635 		*/
14636 
14637 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14638 			/* config the initial gain under scanning */
14639 			sitesurvey_set_igi(padapter, 1);
14640 		}
14641 
14642 		/* set MSR to no link state */
14643 		Set_MSR(padapter, _HW_STATE_NOLINK_);
14644 		val8 = 1; //under site survey
14645 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14646 
14647 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14648 		goto operation_by_state;
14649 
14650 	#endif /* CONFIG_SCAN_BACKOP */
14651 
14652 	#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14653 	case SCAN_SW_ANTDIV_BL:
14654 		/*
14655 		* 20100721
14656 		* For SW antenna diversity before link, it needs to switch to another antenna and scan again.
14657 		* It compares the scan result and select better one to do connection.
14658 		*/
14659 		ss->bss_cnt = 0;
14660 		ss->channel_idx = 0;
14661 		ss->is_sw_antdiv_bl_scan = 1;
14662 
14663 		mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
14664 		set_survey_timer(pmlmeext, ss->scan_ch_ms);
14665 		break;
14666 	#endif
14667 
14668 	#ifdef CONFIG_P2P
14669 	case SCAN_TO_P2P_LISTEN:
14670 		/*
14671 		* Set the P2P State to the listen state of find phase
14672 		* and set the current channel to the listen channel
14673 		*/
14674 		set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14675 		rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
14676 
14677 		/* turn on phy-dynamic functions */
14678 		rtw_phydm_ability_restore(padapter);
14679 
14680 		sitesurvey_set_igi(padapter, 0);
14681 
14682 		mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
14683 		_set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
14684 		break;
14685 
14686 	case SCAN_P2P_LISTEN:
14687 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14688 		ss->channel_idx = 0;
14689 		goto operation_by_state;
14690 	#endif /* CONFIG_P2P */
14691 
14692 	case SCAN_COMPLETE:
14693 		#ifdef CONFIG_P2P
14694 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14695 			|| rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14696 		) {
14697 			#ifdef CONFIG_CONCURRENT_MODE
14698 			if (pwdinfo->driver_interface == DRIVER_WEXT) {
14699 				if (check_buddy_fwstate(padapter, _FW_LINKED))
14700 					_set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
14701 			}
14702 			rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14703 			#else
14704 			rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14705 			#endif
14706 		}
14707 		rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
14708 		#endif /* CONFIG_P2P */
14709 
14710 		/* switch channel */
14711 		survey_done_set_ch_bw(padapter);
14712 
14713 		/* config MSR */
14714 		Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14715 		val8 = 0; /* survey done */
14716 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14717 
14718 		/* turn on phy-dynamic functions */
14719 		rtw_phydm_ability_restore(padapter);
14720 
14721 		sitesurvey_set_igi(padapter, 0);
14722 
14723 		sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14724 
14725 		/* apply rx ampdu setting */
14726 		rtw_rx_ampdu_apply(padapter);
14727 
14728 		mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
14729 
14730 		report_surveydone_event(padapter);
14731 
14732 		issue_action_BSSCoexistPacket(padapter);
14733 		issue_action_BSSCoexistPacket(padapter);
14734 		issue_action_BSSCoexistPacket(padapter);
14735 	}
14736 
14737 	return H2C_SUCCESS;
14738 }
14739 
setauth_hdl(_adapter * padapter,unsigned char * pbuf)14740 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
14741 {
14742 	struct setauth_parm		*pparm = (struct setauth_parm *)pbuf;
14743 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14744 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14745 
14746 	if (pparm->mode < 4)
14747 	{
14748 		pmlmeinfo->auth_algo = pparm->mode;
14749 	}
14750 
14751 	return 	H2C_SUCCESS;
14752 }
14753 
setkey_hdl(_adapter * padapter,u8 * pbuf)14754 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
14755 {
14756 	u16	ctrl = 0;
14757 	s16 cam_id = 0;
14758 	struct setkey_parm		*pparm = (struct setkey_parm *)pbuf;
14759 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14760 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14761 	unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14762 	u8 *addr;
14763 	bool used;
14764 
14765 	//main tx key for wep.
14766 	if(pparm->set_tx)
14767 		pmlmeinfo->key_index = pparm->keyid;
14768 
14769 	cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used);
14770 
14771 	if (cam_id < 0)
14772 		goto enable_mc;
14773 
14774 	if (cam_id > 3) /* not default key, searched by A2 */
14775 		addr = get_bssid(&padapter->mlmepriv);
14776 	else
14777 		addr = null_addr;
14778 
14779 	#ifdef DYNAMIC_CAMID_ALLOC
14780 	/* cam entry searched is pairwise key */
14781 	if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
14782 		s16 camid_clr;
14783 
14784 		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
14785 			, FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
14786 
14787 		/* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
14788 		rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14789 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14790 
14791 		/* clear group key */
14792 		while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
14793 			DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
14794 			clear_cam_entry(padapter, camid_clr);
14795 			rtw_camid_free(padapter, camid_clr);
14796 		}
14797 
14798 		goto enable_mc;
14799 	}
14800 	#endif
14801 
14802 	ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
14803 	write_cam(padapter, cam_id, ctrl, addr, pparm->key);
14804 	DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
14805 		, cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
14806 
14807 	#ifdef DYNAMIC_CAMID_ALLOC
14808 	if (cam_id >=0 && cam_id <=3)
14809 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE);
14810 	#endif
14811 
14812 enable_mc:
14813 	//allow multicast packets to driver
14814 	rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
14815 
14816 	return H2C_SUCCESS;
14817 }
14818 
set_stakey_hdl(_adapter * padapter,u8 * pbuf)14819 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
14820 {
14821 	u16 ctrl = 0;
14822 	s16 cam_id = 0;
14823 	bool used;
14824 	u8 ret = H2C_SUCCESS;
14825 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14826 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14827 	struct set_stakey_parm	*pparm = (struct set_stakey_parm *)pbuf;
14828 	struct sta_priv *pstapriv = &padapter->stapriv;
14829 	struct sta_info *psta;
14830 
14831 	if(pparm->algorithm == _NO_PRIVACY_)
14832 		goto write_to_cam;
14833 
14834 	psta = rtw_get_stainfo(pstapriv, pparm->addr);
14835 	if (!psta) {
14836 		DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
14837 		ret = H2C_REJECTED;
14838 		goto exit;
14839 	}
14840 
14841 	pmlmeinfo->enc_algo = pparm->algorithm;
14842 	cam_id = rtw_camid_alloc(padapter, psta, 0, &used);
14843 	if (cam_id < 0)
14844 		goto exit;
14845 
14846 	#ifdef DYNAMIC_CAMID_ALLOC
14847 	/* cam entry searched is group key */
14848 	if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
14849 		s16 camid_clr;
14850 
14851 		DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
14852 			, FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
14853 
14854 		/* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
14855 		rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14856 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14857 
14858 		/* clear group key */
14859 		while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
14860 			DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
14861 			clear_cam_entry(padapter, camid_clr);
14862 			rtw_camid_free(padapter, camid_clr);
14863 		}
14864 	}
14865 	#endif
14866 
14867 write_to_cam:
14868 	if(pparm->algorithm == _NO_PRIVACY_) {
14869 		while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
14870 			DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
14871 			clear_cam_entry(padapter, cam_id);
14872 			rtw_camid_free(padapter,cam_id);
14873 		}
14874 	} else {
14875 		DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
14876 			cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
14877 		ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
14878 		write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
14879 	}
14880 	ret = H2C_SUCCESS_RSP;
14881 
14882 exit:
14883 	return ret;
14884 }
14885 
add_ba_hdl(_adapter * padapter,unsigned char * pbuf)14886 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
14887 {
14888 	struct addBaReq_parm 	*pparm = (struct addBaReq_parm *)pbuf;
14889 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14890 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14891 
14892 	struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
14893 
14894 	if(!psta)
14895 		return 	H2C_SUCCESS;
14896 
14897 #ifdef CONFIG_80211N_HT
14898 	if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
14899 		((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
14900 	{
14901 		//pmlmeinfo->ADDBA_retry_count = 0;
14902 		//pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
14903 		//psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
14904 		issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14905 		//_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
14906 		_set_timer(&psta->addba_retry_timer, ADDBA_TO);
14907 	}
14908 #ifdef CONFIG_TDLS
14909 	else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
14910 		(psta->htpriv.ht_option==_TRUE) &&
14911 		(psta->htpriv.ampdu_enable==_TRUE) )
14912 	{
14913 		issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14914 		_set_timer(&psta->addba_retry_timer, ADDBA_TO);
14915 	}
14916 #endif //CONFIG
14917 	else
14918 	{
14919 		psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
14920 	}
14921 #endif //CONFIG_80211N_HT
14922 	return 	H2C_SUCCESS;
14923 }
14924 
14925 
chk_bmc_sleepq_cmd(_adapter * padapter)14926 u8 chk_bmc_sleepq_cmd(_adapter* padapter)
14927 {
14928 	struct cmd_obj *ph2c;
14929 	struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14930 	u8 res = _SUCCESS;
14931 
14932 _func_enter_;
14933 
14934 	if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14935 	{
14936 		res= _FAIL;
14937 		goto exit;
14938 	}
14939 
14940 	init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
14941 
14942 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14943 
14944 exit:
14945 
14946 _func_exit_;
14947 
14948 	return res;
14949 }
14950 
set_tx_beacon_cmd(_adapter * padapter)14951 u8 set_tx_beacon_cmd(_adapter* padapter)
14952 {
14953 	struct cmd_obj	*ph2c;
14954 	struct Tx_Beacon_param 	*ptxBeacon_parm;
14955 	struct cmd_priv	*pcmdpriv = &(padapter->cmdpriv);
14956 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14957 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14958 	u8	res = _SUCCESS;
14959 	int len_diff = 0;
14960 
14961 _func_enter_;
14962 
14963 	if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14964 	{
14965 		res= _FAIL;
14966 		goto exit;
14967 	}
14968 
14969 	if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
14970 	{
14971 		rtw_mfree((unsigned char *)ph2c, sizeof(struct	cmd_obj));
14972 		res= _FAIL;
14973 		goto exit;
14974 	}
14975 
14976 	_rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
14977 
14978 	len_diff = update_hidden_ssid(
14979 		ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
14980 		, ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
14981 		, pmlmeinfo->hidden_ssid_mode
14982 	);
14983 	ptxBeacon_parm->network.IELength += len_diff;
14984 
14985 	init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
14986 
14987 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14988 
14989 
14990 exit:
14991 
14992 _func_exit_;
14993 
14994 	return res;
14995 }
14996 
14997 
mlme_evt_hdl(_adapter * padapter,unsigned char * pbuf)14998 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
14999 {
15000 	u8 evt_code, evt_seq;
15001 	u16 evt_sz;
15002 	uint 	*peventbuf;
15003 	void (*event_callback)(_adapter *dev, u8 *pbuf);
15004 	struct evt_priv *pevt_priv = &(padapter->evtpriv);
15005 
15006 	if (pbuf == NULL)
15007 		goto _abort_event_;
15008 
15009 	peventbuf = (uint*)pbuf;
15010 	evt_sz = (u16)(*peventbuf&0xffff);
15011 	evt_seq = (u8)((*peventbuf>>24)&0x7f);
15012 	evt_code = (u8)((*peventbuf>>16)&0xff);
15013 
15014 
15015 	#ifdef CHECK_EVENT_SEQ
15016 	// checking event sequence...
15017 	if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
15018 	{
15019 		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)));
15020 
15021 		pevt_priv->event_seq = (evt_seq+1)&0x7f;
15022 
15023 		goto _abort_event_;
15024 	}
15025 	#endif
15026 
15027 	// checking if event code is valid
15028 	if (evt_code >= MAX_C2HEVT)
15029 	{
15030 		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
15031 		goto _abort_event_;
15032 	}
15033 
15034 	// checking if event size match the event parm size
15035 	if ((wlanevents[evt_code].parmsize != 0) &&
15036 			(wlanevents[evt_code].parmsize != evt_sz))
15037 	{
15038 
15039 		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
15040 			evt_code, wlanevents[evt_code].parmsize, evt_sz));
15041 		goto _abort_event_;
15042 
15043 	}
15044 
15045 	ATOMIC_INC(&pevt_priv->event_seq);
15046 
15047 	peventbuf += 2;
15048 
15049 	if(peventbuf)
15050 	{
15051 		event_callback = wlanevents[evt_code].event_callback;
15052 		event_callback(padapter, (u8*)peventbuf);
15053 
15054 		pevt_priv->evt_done_cnt++;
15055 	}
15056 
15057 
15058 _abort_event_:
15059 
15060 
15061 	return H2C_SUCCESS;
15062 
15063 }
15064 
h2c_msg_hdl(_adapter * padapter,unsigned char * pbuf)15065 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
15066 {
15067 	if(!pbuf)
15068 		return H2C_PARAMETERS_ERROR;
15069 
15070 	return H2C_SUCCESS;
15071 }
15072 
chk_bmc_sleepq_hdl(_adapter * padapter,unsigned char * pbuf)15073 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
15074 {
15075 #ifdef CONFIG_AP_MODE
15076 	_irqL irqL;
15077 	struct sta_info *psta_bmc;
15078 	_list	*xmitframe_plist, *xmitframe_phead;
15079 	struct xmit_frame *pxmitframe=NULL;
15080 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
15081 	struct sta_priv  *pstapriv = &padapter->stapriv;
15082 
15083 	//for BC/MC Frames
15084 	psta_bmc = rtw_get_bcmc_stainfo(padapter);
15085 	if(!psta_bmc)
15086 		return H2C_SUCCESS;
15087 
15088 	if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
15089 	{
15090 #ifndef CONFIG_PCI_HCI
15091 		rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
15092 #endif
15093 		//_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15094 		_enter_critical_bh(&pxmitpriv->lock, &irqL);
15095 
15096 		xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
15097 		xmitframe_plist = get_next(xmitframe_phead);
15098 
15099 		while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
15100 		{
15101 			pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
15102 
15103 			xmitframe_plist = get_next(xmitframe_plist);
15104 
15105 			rtw_list_delete(&pxmitframe->list);
15106 
15107 			psta_bmc->sleepq_len--;
15108 			if(psta_bmc->sleepq_len>0)
15109 				pxmitframe->attrib.mdata = 1;
15110 			else
15111 				pxmitframe->attrib.mdata = 0;
15112 
15113 			pxmitframe->attrib.triggered=1;
15114 
15115 			if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
15116 				pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ
15117 
15118 			#if 0
15119 			_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15120 			if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
15121 			{
15122 				rtw_os_xmit_complete(padapter, pxmitframe);
15123 			}
15124 			_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15125 			#endif
15126 			rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
15127 		}
15128 
15129 		//_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15130 		_exit_critical_bh(&pxmitpriv->lock, &irqL);
15131 
15132 		if (rtw_get_intf_type(padapter) != RTW_PCIE) {
15133 			/* check hi queue and bmc_sleepq */
15134 			rtw_chk_hi_queue_cmd(padapter);
15135 		}
15136 	}
15137 #endif
15138 
15139 	return H2C_SUCCESS;
15140 }
15141 
tx_beacon_hdl(_adapter * padapter,unsigned char * pbuf)15142 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
15143 {
15144 #ifdef CONFIG_AP_MODE
15145 	if(send_beacon(padapter)==_FAIL)
15146 	{
15147 		DBG_871X("issue_beacon, fail!\n");
15148 		return H2C_PARAMETERS_ERROR;
15149 	}
15150 
15151 
15152 	if (padapter->registrypriv.wifi_spec == 1)
15153 		return H2C_SUCCESS;
15154 
15155 	/* tx bc/mc frames after update TIM */
15156 	chk_bmc_sleepq_hdl(padapter, NULL);
15157 #endif /* CONFIG_AP_MODE */
15158 	return H2C_SUCCESS;
15159 }
15160 
15161 #ifdef CONFIG_AP_MODE
15162 /*
15163 * according to channel
15164 * add/remove WLAN_BSSID_EX.IEs's ERP ie
15165 * set WLAN_BSSID_EX.SupportedRates
15166 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
15167 */
change_band_update_ie(_adapter * padapter,WLAN_BSSID_EX * pnetwork,u8 ch)15168 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
15169 {
15170 	u8	network_type,rate_len, total_rate_len,remainder_rate_len;
15171 	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
15172 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15173 	u8	erpinfo=0x4;
15174 
15175 	if (ch >= 36) {
15176 		network_type = WIRELESS_11A;
15177 		total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
15178 		rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
15179 	} else {
15180 		network_type = WIRELESS_11BG;
15181 		total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
15182 		rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
15183 	}
15184 
15185 	rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
15186 
15187 	UpdateBrateTbl(padapter, pnetwork->SupportedRates);
15188 
15189 	if(total_rate_len > 8)
15190 	{
15191 		rate_len = 8;
15192 		remainder_rate_len = total_rate_len - 8;
15193 	}
15194 	else
15195 	{
15196 		rate_len = total_rate_len;
15197 		remainder_rate_len = 0;
15198 	}
15199 
15200 	rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
15201 
15202 	if(remainder_rate_len)
15203 	{
15204 		rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
15205 	}
15206 	else
15207 	{
15208 		rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
15209 	}
15210 
15211 	pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
15212 }
15213 #endif /* CONFIG_AP_MODE */
15214 
15215 #ifdef CONFIG_CONCURRENT_MODE
check_buddy_mlmeinfo_state(_adapter * padapter,u32 state)15216 sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
15217 {
15218 	PADAPTER pbuddy_adapter;
15219 	struct mlme_ext_priv *pbuddy_mlmeext;
15220 	struct mlme_ext_info *pbuddy_mlmeinfo;
15221 
15222 	if(padapter == NULL)
15223 		return _FALSE;
15224 
15225 	pbuddy_adapter = padapter->pbuddy_adapter;
15226 
15227 	if(pbuddy_adapter == NULL)
15228 		return _FALSE;
15229 
15230 
15231 	pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
15232 	pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
15233 
15234 	if((pbuddy_mlmeinfo->state&0x03) == state)
15235 		return _TRUE;
15236 
15237 	return _FALSE;
15238 
15239 }
15240 #endif /* CONFIG_CONCURRENT_MODE */
15241 
rtw_join_done_chk_ch(_adapter * adapter,int join_res)15242 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
15243 {
15244 #define DUMP_ADAPTERS_STATUS 0
15245 
15246 	struct dvobj_priv *dvobj;
15247 	_adapter *iface;
15248 	struct mlme_priv *mlme;
15249 	struct mlme_ext_priv *mlmeext;
15250 	u8 u_ch, u_offset, u_bw;
15251 	int i;
15252 
15253 	dvobj = adapter_to_dvobj(adapter);
15254 
15255 	if (DUMP_ADAPTERS_STATUS) {
15256 		DBG_871X(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
15257 		dump_adapters_status(RTW_DBGDUMP , dvobj);
15258 	}
15259 
15260 	if (join_res >= 0) {
15261 		if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
15262 			dump_adapters_status(RTW_DBGDUMP , dvobj);
15263 			rtw_warn_on(1);
15264 		}
15265 
15266 		for (i = 0; i < dvobj->iface_nums; i++) {
15267 			iface = dvobj->padapters[i];
15268 			mlme = &iface->mlmepriv;
15269 			mlmeext = &iface->mlmeextpriv;
15270 
15271 			if (!iface || iface == adapter)
15272 				continue;
15273 #ifdef CONFIG_AP_MODE
15274 			if (check_fwstate(mlme, WIFI_AP_STATE)
15275 				&& check_fwstate(mlme, WIFI_ASOC_STATE)
15276 			) {
15277 				bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
15278 					, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
15279 
15280 				if (is_grouped == _FALSE) {
15281 					/* handle AP which need to switch ch setting */
15282 
15283 					/* restore original bw, adjust bw by registry setting on target ch */
15284 					mlmeext->cur_bwmode = mlme->ori_bw;
15285 					mlmeext->cur_channel = u_ch;
15286 					rtw_regsty_adjust_chbw(&iface->registrypriv
15287 						, mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
15288 
15289 					rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
15290 						, &u_ch, &u_bw, &u_offset);
15291 
15292 					rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
15293 						, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
15294 
15295 					_rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
15296 
15297 					rtw_start_bss_hdl_after_chbw_decided(iface);
15298 				}
15299 
15300 				update_beacon(iface, 0, NULL, _TRUE);
15301 			}
15302 #endif /* CONFIG_AP_MODE */
15303 			clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15304 		}
15305 
15306 		#ifdef CONFIG_DFS_MASTER
15307 		rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED);
15308 		#endif
15309 	} else {
15310 		for (i = 0; i < dvobj->iface_nums; i++) {
15311 			iface = dvobj->padapters[i];
15312 			mlme = &iface->mlmepriv;
15313 			mlmeext = &iface->mlmeextpriv;
15314 
15315 			if (!iface || iface == adapter)
15316 				continue;
15317 #ifdef CONFIG_AP_MODE
15318 			if (check_fwstate(mlme, WIFI_AP_STATE)
15319 				&& check_fwstate(mlme, WIFI_ASOC_STATE))
15320 				update_beacon(iface, 0, NULL, _TRUE);
15321 #endif /* CONFIG_AP_MODE */
15322 			clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15323 		}
15324 		#ifdef CONFIG_DFS_MASTER
15325 		rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED);
15326 		#endif
15327 	}
15328 
15329 	if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
15330 		set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
15331 
15332 	if (DUMP_ADAPTERS_STATUS) {
15333 		DBG_871X(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
15334 		dump_adapters_status(RTW_DBGDUMP , dvobj);
15335 	}
15336 }
15337 
rtw_chk_start_clnt_join(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)15338 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15339 {
15340 	bool chbw_allow = _TRUE;
15341 	bool connect_allow = _TRUE;
15342 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
15343 	u8 cur_ch, cur_bw, cur_ch_offset;
15344 	u8 u_ch, u_offset, u_bw;
15345 
15346 	u_ch = cur_ch = pmlmeext->cur_channel;
15347 	u_bw = cur_bw = pmlmeext->cur_bwmode;
15348 	u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
15349 
15350 	if (!ch || !bw || !offset) {
15351 		connect_allow = _FALSE;
15352 		rtw_warn_on(1);
15353 		goto exit;
15354 	}
15355 
15356 	if (cur_ch == 0) {
15357 		connect_allow = _FALSE;
15358 		DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n"
15359 			, FUNC_ADPT_ARG(adapter), cur_ch);
15360 		rtw_warn_on(1);
15361 		goto exit;
15362 	}
15363 	DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15364 
15365 #ifdef CONFIG_CONCURRENT_MODE
15366 {
15367 	struct dvobj_priv *dvobj;
15368 	_adapter *iface;
15369 	struct mlme_priv *mlme;
15370 	struct mlme_ext_priv *mlmeext;
15371 	u8 sta_num;
15372 	u8 ld_sta_num;
15373 	u8 lg_sta_num;
15374 	u8 ap_num;
15375 	u8 ld_ap_num;
15376 	int i;
15377 
15378 	dvobj = adapter_to_dvobj(adapter);
15379 
15380 	rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num);
15381 	DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n"
15382 		, FUNC_ADPT_ARG(adapter), ld_sta_num, ap_num);
15383 
15384 	if (!ld_sta_num && !ap_num) {
15385 		/* consider linking STA? */
15386 		goto connect_allow_hdl;
15387 	}
15388 
15389 	if (rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
15390 		dump_adapters_status(RTW_DBGDUMP , dvobj);
15391 		rtw_warn_on(1);
15392 	}
15393 	DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
15394 		, FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15395 
15396 	/* chbw_allow? */
15397 	chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
15398 		, u_ch, u_bw, u_offset);
15399 
15400 	DBG_871X(FUNC_ADPT_FMT" chbw_allow:%d\n"
15401 		, FUNC_ADPT_ARG(adapter), chbw_allow);
15402 
15403 	if (chbw_allow == _TRUE) {
15404 		rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
15405 		rtw_warn_on(cur_ch != pmlmeext->cur_channel);
15406 		rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
15407 		rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
15408 		goto connect_allow_hdl;
15409 	}
15410 
15411 	/* chbw_allow is _FALSE, connect allow? */
15412 	for (i = 0; i < dvobj->iface_nums; i++) {
15413 		iface = dvobj->padapters[i];
15414 		mlme = &iface->mlmepriv;
15415 		mlmeext = &iface->mlmeextpriv;
15416 
15417 		#ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
15418 		if (check_fwstate(mlme, WIFI_STATION_STATE)
15419 			&& check_fwstate(mlme, WIFI_ASOC_STATE)
15420 			#if defined(CONFIG_P2P)
15421 			&& rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
15422 			#endif
15423 		) {
15424 			connect_allow = _FALSE;
15425 			break;
15426 		}
15427 		#endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
15428 	}
15429 	DBG_871X(FUNC_ADPT_FMT" connect_allow:%d\n"
15430 		, FUNC_ADPT_ARG(adapter), connect_allow);
15431 
15432 	if (connect_allow == _FALSE)
15433 		goto exit;
15434 
15435 connect_allow_hdl:
15436 	/* connect_allow == _TRUE */
15437 
15438 	#ifdef CONFIG_DFS_MASTER
15439 	rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING);
15440 	#endif
15441 
15442 	if (chbw_allow == _FALSE) {
15443 		u_ch = cur_ch;
15444 		u_bw = cur_bw;
15445 		u_offset = cur_ch_offset;
15446 
15447 		for (i = 0; i < dvobj->iface_nums; i++) {
15448 			iface = dvobj->padapters[i];
15449 			mlme = &iface->mlmepriv;
15450 			mlmeext = &iface->mlmeextpriv;
15451 
15452 			if (!iface || iface == adapter)
15453 				continue;
15454 
15455 			if (check_fwstate(mlme, WIFI_AP_STATE)
15456 				&& check_fwstate(mlme, WIFI_ASOC_STATE)
15457 			) {
15458 				#ifdef CONFIG_SPCT_CH_SWITCH
15459 				if (1)
15460 					rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
15461 				else
15462 				#endif
15463 					rtw_sta_flush(iface, _FALSE);
15464 
15465 				rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
15466 				set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15467 			} else if (check_fwstate(mlme, WIFI_STATION_STATE)
15468 				&& check_fwstate(mlme, WIFI_ASOC_STATE)
15469 			) {
15470 				rtw_disassoc_cmd(iface, 500, _FALSE);
15471 				rtw_indicate_disconnect(iface);
15472 				rtw_free_assoc_resources(iface, 1);
15473 			}
15474 		}
15475 	}
15476 }
15477 #endif /* CONFIG_CONCURRENT_MODE */
15478 
15479 exit:
15480 
15481 	if (connect_allow == _TRUE) {
15482 		DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15483 		*ch = u_ch;
15484 		*bw = u_bw;
15485 		*offset = u_offset;
15486 	}
15487 
15488 	return connect_allow == _TRUE ? _SUCCESS : _FAIL;
15489 }
15490 
15491 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
_rtw_get_ch_setting_union(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset,bool include_self)15492 int _rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
15493 {
15494 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15495 	_adapter *iface;
15496 	struct mlme_ext_priv *mlmeext;
15497 	int i;
15498 	u8 ch_ret = 0;
15499 	u8 bw_ret = CHANNEL_WIDTH_20;
15500 	u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15501 	int num = 0;
15502 
15503 	if (ch) *ch = 0;
15504 	if (bw) *bw = CHANNEL_WIDTH_20;
15505 	if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15506 
15507 	for (i = 0; i<dvobj->iface_nums; i++) {
15508 		iface = dvobj->padapters[i];
15509 		mlmeext = &iface->mlmeextpriv;
15510 
15511 		if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
15512 			continue;
15513 
15514 		if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
15515 			continue;
15516 
15517 		if (include_self == _FALSE && adapter == iface)
15518 			continue;
15519 
15520 		if (num == 0) {
15521 			ch_ret = mlmeext->cur_channel;
15522 			bw_ret = mlmeext->cur_bwmode;
15523 			offset_ret = mlmeext->cur_ch_offset;
15524 			num++;
15525 			continue;
15526 		}
15527 
15528 		if (ch_ret != mlmeext->cur_channel) {
15529 			num = 0;
15530 			break;
15531 		}
15532 
15533 		if (bw_ret < mlmeext->cur_bwmode) {
15534 			bw_ret = mlmeext->cur_bwmode;
15535 			offset_ret = mlmeext->cur_ch_offset;
15536 		} else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
15537 			num = 0;
15538 			break;
15539 		}
15540 
15541 		num++;
15542 	}
15543 
15544 	if (num) {
15545 		if (ch) *ch = ch_ret;
15546 		if (bw) *bw = bw_ret;
15547 		if (offset) *offset = offset_ret;
15548 	}
15549 
15550 	return num;
15551 }
15552 
rtw_get_ch_setting_union(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)15553 inline int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15554 {
15555 	return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 1);
15556 }
15557 
rtw_get_ch_setting_union_no_self(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)15558 inline int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15559 {
15560 	return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 0);
15561 }
15562 
_rtw_dev_iface_status(_adapter * adapter,u8 * sta_num,u8 * ld_sta_num,u8 * lg_sta_num,u8 * ap_num,u8 * ld_ap_num,bool include_self)15563 void _rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15564 	, u8 *ap_num, u8 *ld_ap_num, bool include_self)
15565 {
15566 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15567 	_adapter *iface;
15568 	struct mlme_ext_priv *mlmeext;
15569 	struct mlme_ext_info *mlmeextinfo;
15570 	int i;
15571 	u8 sta_num_ret = 0;
15572 	u8 ld_sta_num_ret = 0;
15573 	u8 lg_sta_num_ret = 0;
15574 	u8 ap_num_ret = 0;
15575 	u8 ld_ap_num_ret = 0;
15576 
15577 	if (sta_num)
15578 		*sta_num = 0;
15579 	if (ld_sta_num)
15580 		*ld_sta_num = 0;
15581 	if (lg_sta_num)
15582 		*lg_sta_num = 0;
15583 	if (ap_num)
15584 		*ap_num = 0;
15585 	if (ld_ap_num)
15586 		*ld_ap_num = 0;
15587 
15588 	for (i = 0; i < dvobj->iface_nums; i++) {
15589 		iface = dvobj->padapters[i];
15590 
15591 		if (include_self == _FALSE && iface == adapter)
15592 			continue;
15593 
15594 		mlmeext = &iface->mlmeextpriv;
15595 
15596 		if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
15597 			sta_num_ret++;
15598 			if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
15599 				ld_sta_num_ret++;
15600 			if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
15601 				lg_sta_num_ret++;
15602 		}
15603 
15604 		if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
15605 			&& check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
15606 		) {
15607 			ap_num_ret++;
15608 			if (iface->stapriv.asoc_sta_count > 2)
15609 				ld_ap_num_ret++;
15610 		}
15611 	}
15612 
15613 	if (sta_num)
15614 		*sta_num = sta_num_ret;
15615 	if (ld_sta_num)
15616 		*ld_sta_num = ld_sta_num_ret;
15617 	if (lg_sta_num)
15618 		*lg_sta_num = lg_sta_num_ret;
15619 	if (ap_num)
15620 		*ap_num = ap_num_ret;
15621 	if (ld_ap_num)
15622 		*ld_ap_num = ld_ap_num_ret;
15623 }
15624 
rtw_dev_iface_status(_adapter * adapter,u8 * sta_num,u8 * ld_sta_num,u8 * lg_sta_num,u8 * ap_num,u8 * ld_ap_num)15625 inline void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15626 	, u8 *ap_num, u8 *ld_ap_num)
15627 {
15628 	return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 1);
15629 }
15630 
rtw_dev_iface_status_no_self(_adapter * adapter,u8 * sta_num,u8 * ld_sta_num,u8 * lg_sta_num,u8 * ap_num,u8 * ld_ap_num)15631 inline void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15632 	, u8 *ap_num, u8 *ld_ap_num)
15633 {
15634 	return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 0);
15635 }
15636 
set_ch_hdl(_adapter * padapter,u8 * pbuf)15637 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
15638 {
15639 	struct set_ch_parm *set_ch_parm;
15640 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
15641 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
15642 
15643 	if(!pbuf)
15644 		return H2C_PARAMETERS_ERROR;
15645 
15646 	set_ch_parm = (struct set_ch_parm *)pbuf;
15647 
15648 	DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
15649 		FUNC_NDEV_ARG(padapter->pnetdev),
15650 		set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
15651 
15652 	pmlmeext->cur_channel = set_ch_parm->ch;
15653 	pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
15654 	pmlmeext->cur_bwmode = set_ch_parm->bw;
15655 
15656 	set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
15657 
15658 	return 	H2C_SUCCESS;
15659 }
15660 
set_chplan_hdl(_adapter * padapter,unsigned char * pbuf)15661 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
15662 {
15663 	struct SetChannelPlan_param *setChannelPlan_param;
15664 	struct mlme_priv *mlme = &padapter->mlmepriv;
15665 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15666 
15667 	if(!pbuf)
15668 		return H2C_PARAMETERS_ERROR;
15669 
15670 	setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
15671 
15672 	if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) {
15673 		return H2C_PARAMETERS_ERROR;
15674 	}
15675 
15676 	mlme->ChannelPlan = setChannelPlan_param->channel_plan;
15677 
15678 	pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
15679 	init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
15680 
15681 	rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE);
15682 
15683 #ifdef CONFIG_IOCTL_CFG80211
15684 	rtw_reg_notify_by_driver(padapter);
15685 #endif //CONFIG_IOCTL_CFG80211
15686 
15687 	return 	H2C_SUCCESS;
15688 }
15689 
led_blink_hdl(_adapter * padapter,unsigned char * pbuf)15690 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
15691 {
15692 	struct LedBlink_param *ledBlink_param;
15693 
15694 	if(!pbuf)
15695 		return H2C_PARAMETERS_ERROR;
15696 
15697 	ledBlink_param = (struct LedBlink_param *)pbuf;
15698 
15699 	#ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
15700 	BlinkHandler((PLED_DATA)ledBlink_param->pLed);
15701 	#endif
15702 
15703 	return 	H2C_SUCCESS;
15704 }
15705 
set_csa_hdl(_adapter * padapter,unsigned char * pbuf)15706 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
15707 {
15708 #ifdef CONFIG_DFS
15709 	struct SetChannelSwitch_param *setChannelSwitch_param;
15710 	u8 new_ch_no;
15711 	u8 gval8 = 0x00, sval8 = 0xff;
15712 
15713 	if(!pbuf)
15714 		return H2C_PARAMETERS_ERROR;
15715 
15716 	setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
15717 	new_ch_no = setChannelSwitch_param->new_ch_no;
15718 
15719 	rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15720 
15721 	rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
15722 
15723 	DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
15724 	SelectChannel(padapter, new_ch_no);
15725 
15726 	rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15727 
15728 	rtw_disassoc_cmd(padapter, 0, _FALSE);
15729 	rtw_indicate_disconnect(padapter);
15730 	rtw_free_assoc_resources(padapter, 1);
15731 	rtw_free_network_queue(padapter, _TRUE);
15732 
15733 	if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
15734 		DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
15735 	}
15736 
15737 	return 	H2C_SUCCESS;
15738 #else
15739 	return	H2C_REJECTED;
15740 #endif //CONFIG_DFS
15741 
15742 }
15743 
tdls_hdl(_adapter * padapter,unsigned char * pbuf)15744 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
15745 {
15746 #ifdef CONFIG_TDLS
15747 	_irqL irqL;
15748 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
15749 #ifdef CONFIG_TDLS_CH_SW
15750 	struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
15751 #endif
15752 	struct TDLSoption_param *TDLSoption;
15753 	struct sta_info *ptdls_sta = NULL;
15754 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15755 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
15756 	u8 survey_channel, i, min, option;
15757 	struct tdls_txmgmt txmgmt;
15758 	u32 setchtime, resp_sleep = 0, wait_time;
15759 	u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15760 
15761 	if (!pbuf)
15762 		return H2C_PARAMETERS_ERROR;
15763 
15764 	TDLSoption = (struct TDLSoption_param *)pbuf;
15765 	option = TDLSoption->option;
15766 
15767 	if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
15768 		ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
15769 		if (ptdls_sta == NULL) {
15770 			return H2C_REJECTED;
15771 		}
15772 	} else {
15773 		if (!(option == TDLS_RS_RCR || option == TDLS_CH_SW_BACK))
15774 			return H2C_REJECTED;
15775 	}
15776 
15777 	//_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15778 	//DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
15779 
15780 	switch (option) {
15781 	case TDLS_ESTABLISHED:
15782 	{
15783 		/* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
15784 		/* So we can receive all kinds of data frames. */
15785 		u8 sta_band = 0;
15786 
15787 		//leave ALL PS when TDLS is established
15788 			rtw_pwr_wakeup(padapter);
15789 
15790 		rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
15791 		DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
15792 
15793 		pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta;
15794 		/* Set TDLS sta rate. */
15795 		/* Update station supportRate */
15796 		rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
15797 		if (pmlmeext->cur_channel > 14) {
15798 			if (ptdls_sta->ra_mask & 0xffff000)
15799 				sta_band |= WIRELESS_11_5N ;
15800 
15801 			if (ptdls_sta->ra_mask & 0xff0)
15802 				sta_band |= WIRELESS_11A;
15803 
15804 			/* 5G band */
15805 			#ifdef CONFIG_80211AC_VHT
15806 			if (ptdls_sta->vhtpriv.vht_option)
15807 				sta_band = WIRELESS_11_5AC;
15808 			#endif
15809 
15810 		} else {
15811 			if (ptdls_sta->ra_mask & 0xffff000)
15812 				sta_band |= WIRELESS_11_24N;
15813 
15814 			if (ptdls_sta->ra_mask & 0xff0)
15815 				sta_band |= WIRELESS_11G;
15816 
15817 			if (ptdls_sta->ra_mask & 0x0f)
15818 				sta_band |= WIRELESS_11B;
15819 		}
15820 		ptdls_sta->wireless_mode = sta_band;
15821 		ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta);
15822 		set_sta_rate(padapter, ptdls_sta);
15823 		rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
15824 		/* Sta mode */
15825 		rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE);
15826 		break;
15827 	}
15828 	case TDLS_ISSUE_PTI:
15829 		ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
15830 		issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
15831 		_set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
15832 		break;
15833 #ifdef CONFIG_TDLS_CH_SW
15834 	case TDLS_CH_SW_RESP:
15835 		_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15836 		txmgmt.status_code = 0;
15837 		_rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15838 
15839 		issue_nulldata(padapter, NULL, 1, 0, 0);
15840 
15841 		DBG_871X("issue tdls channel switch response\n");
15842 		issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
15843 		resp_sleep = 5;
15844 		rtw_msleep_os(resp_sleep);
15845 
15846 		/* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
15847 		/* then we just SelectChannel to AP's channel*/
15848 		if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
15849 			SelectChannel(padapter, padapter->mlmeextpriv.cur_channel);
15850 			issue_nulldata(padapter, NULL, 0, 0, 0);
15851 			pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15852 			ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
15853 			break;
15854 		}
15855 
15856 		_set_timer(&ptdls_sta->delay_timer, pmlmeinfo->bcn_interval - 40);
15857 
15858 		/* Continue following actions */
15859 
15860 	case TDLS_CH_SW:
15861 		issue_nulldata(padapter, NULL, 1, 0, 0);
15862 		_set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout)/1000);
15863 
15864 		setchtime = rtw_systime_to_ms(rtw_get_current_time());
15865 		SelectChannel(padapter, pchsw_info->off_ch_num);
15866 		setchtime = rtw_systime_to_ms(rtw_get_current_time()) - setchtime;
15867 		setchtime += resp_sleep;
15868 
15869 		if (pmlmeext->cur_channel != rtw_get_oper_ch(padapter))
15870 			issue_nulldata(padapter, NULL, 0, 0, 0);
15871 		pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15872 
15873 		if ((u32)ptdls_sta->ch_switch_time/1000 > setchtime)
15874 			wait_time = (u32)ptdls_sta->ch_switch_time/1000 - setchtime;
15875 		else
15876 			wait_time = 0;
15877 
15878 		if (wait_time > 0)
15879 			rtw_msleep_os(wait_time);
15880 
15881 		issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
15882 		issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
15883 
15884 		break;
15885 	case TDLS_CH_SW_BACK:
15886 		pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
15887 		ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
15888 		SelectChannel(padapter, padapter->mlmeextpriv.cur_channel);
15889 		issue_nulldata(padapter, NULL, 0, 0, 0);
15890 		break;
15891 #endif
15892 	case TDLS_RS_RCR:
15893 		rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
15894 		DBG_871X("wirte REG_RCR, set bit6 on\n");
15895 		break;
15896 	case TDLS_TEAR_STA:
15897 #ifdef CONFIG_TDLS_CH_SW
15898 		if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
15899 			pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
15900 										TDLS_CH_SWITCH_ON_STATE |
15901 										TDLS_PEER_AT_OFF_STATE);
15902 			ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
15903 			_rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
15904 		}
15905 #endif
15906 		rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
15907 		free_tdls_sta(padapter, ptdls_sta);
15908 		break;
15909 	}
15910 
15911 	//_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15912 
15913 	return H2C_SUCCESS;
15914 #else
15915 	return H2C_REJECTED;
15916 #endif /* CONFIG_TDLS */
15917 
15918 }
15919 
run_in_thread_hdl(_adapter * padapter,u8 * pbuf)15920 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
15921 {
15922 	struct RunInThread_param *p;
15923 
15924 
15925 	if (NULL == pbuf)
15926 		return H2C_PARAMETERS_ERROR;
15927 	p = (struct RunInThread_param*)pbuf;
15928 
15929 	if (p->func)
15930 		p->func(p->context);
15931 
15932 	return H2C_SUCCESS;
15933 }
15934 
15935