1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 #define _RTW_MLME_EXT_C_
22 #include <drv_types.h>
23 #ifdef CONFIG_IOCTL_CFG80211
24 #include <rtw_wifi_regd.h>
25 #endif //CONFIG_IOCTL_CFG80211
28 struct mlme_handler mlme_sta_tbl[]={
29 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
30 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
31 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
32 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
33 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
34 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
36 /*----------------------------------------------------------
38 -----------------------------------------------------------*/
39 {0, "DoReserved", &DoReserved},
40 {0, "DoReserved", &DoReserved},
41 {WIFI_BEACON, "OnBeacon", &OnBeacon},
42 {WIFI_ATIM, "OnATIM", &OnAtim},
43 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
44 {WIFI_AUTH, "OnAuth", &OnAuthClient},
45 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
46 {WIFI_ACTION, "OnAction", &OnAction},
47 {WIFI_ACTION_NOACK,"OnActionNoAck", &OnAction},
50 #ifdef _CONFIG_NATIVEAP_MLME_
51 struct mlme_handler mlme_ap_tbl[]={
52 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
53 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
54 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
55 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
56 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
57 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
59 /*----------------------------------------------------------
61 -----------------------------------------------------------*/
62 {0, "DoReserved", &DoReserved},
63 {0, "DoReserved", &DoReserved},
64 {WIFI_BEACON, "OnBeacon", &OnBeacon},
65 {WIFI_ATIM, "OnATIM", &OnAtim},
66 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
67 {WIFI_AUTH, "OnAuth", &OnAuth},
68 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
69 {WIFI_ACTION, "OnAction", &OnAction},
70 {WIFI_ACTION_NOACK,"OnActionNoAck", &OnAction},
74 struct action_handler OnAction_tbl[]={
75 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
76 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
77 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
78 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
79 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
80 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
81 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
82 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
83 #ifdef CONFIG_IEEE80211W
84 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
86 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
87 #endif //CONFIG_IEEE80211W
88 //add for CONFIG_IEEE80211W
89 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
90 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
91 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
92 {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
93 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
97 u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0};
99 /**************************************************
100 OUI definitions for the vendor specific IE
101 ***************************************************/
102 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
103 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
104 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
105 unsigned char P2P_OUI[] = {0x50,0x6F,0x9A,0x09};
106 unsigned char WFD_OUI[] = {0x50,0x6F,0x9A,0x0A};
108 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
109 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
111 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
112 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
114 extern unsigned char REALTEK_96B_IE[];
117 /********************************************************
118 ChannelPlan definitions
119 *********************************************************/
120 /*static RT_CHANNEL_PLAN DefaultChannelPlan[RT_CHANNEL_DOMAIN_MAX] = {
121 {{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
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,136,140,149,153,157,161,165},31}, // 0x01, RT_CHANNEL_DOMAIN_IC
123 {{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
124 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x03, RT_CHANNEL_DOMAIN_SPAIN
125 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x04, RT_CHANNEL_DOMAIN_FRANCE
126 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x05, RT_CHANNEL_DOMAIN_MKK
127 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x06, RT_CHANNEL_DOMAIN_MKK1
128 {{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
129 {{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
130 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
131 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
132 {{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
133 {{1,2,3,4,5,6,7,8,9,10,11,12,13,149,153,157,161,165},18}, // 0x0C, RT_CHANNEL_DOMAIN_CHINA
134 {{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
135 {{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
136 {{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
137 {{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
138 {{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
139 {{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
140 {{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
141 {{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
144 static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
145 {{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
146 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1
147 {{1,2,3,4,5,6,7,8,9,10,11},11}, // 0x02, RT_CHANNEL_DOMAIN_2G_FCC1
148 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1
149 {{10,11,12,13},4}, // 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2
150 {{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
151 {{},0}, // 0x06, RT_CHANNEL_DOMAIN_2G_NULL
154 static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
155 {{},0}, // 0x00, RT_CHANNEL_DOMAIN_5G_NULL
156 {{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
157 {{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
158 {{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
159 {{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
160 {{36,40,44,48,149,153,157,161,165},9}, // 0x05, RT_CHANNEL_DOMAIN_5G_FCC2
161 {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, // 0x06, RT_CHANNEL_DOMAIN_5G_FCC3
162 {{36,40,44,48,52,56,60,64,149,153,157,161},12}, // 0x07, RT_CHANNEL_DOMAIN_5G_FCC4
163 {{149,153,157,161,165},5}, // 0x08, RT_CHANNEL_DOMAIN_5G_FCC5
164 {{36,40,44,48,52,56,60,64},8}, // 0x09, RT_CHANNEL_DOMAIN_5G_FCC6
165 {{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
166 {{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
167 {{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
168 {{36,40,44,48,52,56,60,64},8}, // 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2
169 {{100,104,108,112,116,120,124,128,132,136,140},11}, // 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3
170 {{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15}, // 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1
171 {{56,60,64,149,153,157,161,165},8}, // 0x10, RT_CHANNEL_DOMAIN_5G_NCC2
172 {{149,153,157,161,165},5}, // 0x11, RT_CHANNEL_DOMAIN_5G_NCC3
173 {{36,40,44,48},4}, // 0x12, RT_CHANNEL_DOMAIN_5G_ETSI4
174 {{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
175 {{149,153,157,161},4}, // 0x14, RT_CHANNEL_DOMAIN_5G_FCC8
176 {{36,40,44,48,52,56,60,64},8}, // 0x15, RT_CHANNEL_DOMAIN_5G_ETSI6
177 {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, // 0x16, RT_CHANNEL_DOMAIN_5G_ETSI7
178 {{36,40,44,48,149,153,157,161,165},9}, // 0x17, RT_CHANNEL_DOMAIN_5G_ETSI8
179 {{100,104,108,112,116,120,124,128,132,136,140},11}, // 0x18, RT_CHANNEL_DOMAIN_5G_ETSI9
180 {{149,153,157,161,165},5}, // 0x19, RT_CHANNEL_DOMAIN_5G_ETSI10
181 {{36,40,44,48,52,56,60,64,132,136,140,149,153,157,161,165},16}, // 0x1A, RT_CHANNEL_DOMAIN_5G_ETSI11
182 {{52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},17}, // 0x1B, RT_CHANNEL_DOMAIN_5G_NCC4
183 {{149,153,157,161},4}, // 0x1C, RT_CHANNEL_DOMAIN_5G_ETSI12
184 {{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
185 {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140},16}, // 0x1E, RT_CHANNEL_DOMAIN_5G_ETSI13
186 {{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
187 {{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
188 {{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
189 {{56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},16}, // 0x22, RT_CHANNEL_DOMAIN_5G_NCC5
190 {{36,40,44,48},4}, // 0x23, RT_CHANNEL_DOMAIN_5G_MKK4
191 //===== Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition =====
192 {{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
193 {{36,40,44,48},4}, // 0x31, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS
194 {{36,40,44,48,149,153,157,161},8}, // 0x32, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS
197 static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
198 //===== 0x00 ~ 0x1F , Old Define =====
199 {0x02,0x20}, //0x00, RT_CHANNEL_DOMAIN_FCC
200 {0x02,0x0A}, //0x01, RT_CHANNEL_DOMAIN_IC
201 {0x01,0x01}, //0x02, RT_CHANNEL_DOMAIN_ETSI
202 {0x01,0x00}, //0x03, RT_CHANNEL_DOMAIN_SPAIN
203 {0x01,0x00}, //0x04, RT_CHANNEL_DOMAIN_FRANCE
204 {0x03,0x00}, //0x05, RT_CHANNEL_DOMAIN_MKK
205 {0x03,0x00}, //0x06, RT_CHANNEL_DOMAIN_MKK1
206 {0x01,0x09}, //0x07, RT_CHANNEL_DOMAIN_ISRAEL
207 {0x03,0x09}, //0x08, RT_CHANNEL_DOMAIN_TELEC
208 {0x03,0x00}, //0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
209 {0x00,0x00}, //0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
210 {0x02,0x0F}, //0x0B, RT_CHANNEL_DOMAIN_TAIWAN
211 {0x01,0x08}, //0x0C, RT_CHANNEL_DOMAIN_CHINA
212 {0x02,0x06}, //0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
213 {0x02,0x0B}, //0x0E, RT_CHANNEL_DOMAIN_KOREA
214 {0x02,0x09}, //0x0F, RT_CHANNEL_DOMAIN_TURKEY
215 {0x01,0x01}, //0x10, RT_CHANNEL_DOMAIN_JAPAN
216 {0x02,0x05}, //0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
217 {0x01,0x21}, //0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
218 {0x00,0x04}, //0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
219 {0x02,0x10}, //0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
220 {0x00,0x21}, //0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS
221 {0x00,0x22}, //0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS
222 {0x03,0x21}, //0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
223 {0x06,0x08}, //0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS
224 {0x02,0x08}, //0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS
230 {0x06,0x04}, //0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G
231 //===== 0x20 ~ 0x7F ,New Define =====
232 {0x00,0x00}, //0x20, RT_CHANNEL_DOMAIN_WORLD_NULL
233 {0x01,0x00}, //0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL
234 {0x02,0x00}, //0x22, RT_CHANNEL_DOMAIN_FCC1_NULL
235 {0x03,0x00}, //0x23, RT_CHANNEL_DOMAIN_MKK1_NULL
236 {0x04,0x00}, //0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL
237 {0x02,0x04}, //0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1
238 {0x00,0x01}, //0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1
239 {0x03,0x0C}, //0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1
240 {0x00,0x20}, //0x28, RT_CHANNEL_DOMAIN_5G_KCC2
241 {0x00,0x05}, //0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2
248 {0x00,0x06}, //0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3
249 {0x00,0x07}, //0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4
250 {0x00,0x08}, //0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5
251 {0x00,0x09}, //0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6
252 {0x02,0x21}, //0x34, RT_CHANNEL_DOMAIN_5G_FCC11
253 {0x00,0x02}, //0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2
254 {0x00,0x03}, //0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3
255 {0x03,0x0D}, //0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2
256 {0x03,0x0E}, //0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3
257 {0x02,0x22}, //0x39, RT_CHANNEL_DOMAIN_5G_NCC5
264 {0x02,0x10}, //0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2
265 {0x05,0x00}, //0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL
266 {0x01,0x12}, //0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4
267 {0x02,0x05}, //0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2
268 {0x02,0x11}, //0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3
269 {0x00,0x13}, //0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5
270 {0x02,0x14}, //0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8
271 {0x00,0x15}, //0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6
272 {0x00,0x16}, //0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7
273 {0x00,0x17}, //0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8
280 {0x00,0x18}, //0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9
281 {0x00,0x19}, //0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10
282 {0x00,0x1A}, //0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11
283 {0x02,0x1B}, //0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4
284 {0x00,0x1C}, //0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12
285 {0x02,0x1D}, //0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9
286 {0x00,0x1E}, //0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13
287 {0x02,0x1F}, //0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10
288 {0x01,0x23}, //0x58, RT_CHANNEL_DOMAIN_WORLD_MKK4
291 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x00,0x02}; //use the conbination for max channel numbers
294 * Search the @param ch in given @param ch_set
295 * @ch_set: the given channel set
296 * @ch: the given channel number
298 * return the index of channel_num in channel_set, -1 if not found
300 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
303 for(i=0;ch_set[i].ChannelNum!=0;i++){
304 if(ch == ch_set[i].ChannelNum)
308 if(i >= ch_set[i].ChannelNum)
314 * Check the @param ch is fit with setband setting of @param adapter
315 * @adapter: the given adapter
316 * @ch: the given channel number
318 * return _TRUE when check valid, _FALSE not valid
320 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
322 if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
323 || (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
324 || (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
331 /****************************************************************************
333 Following are the initialization functions for WiFi MLME
335 *****************************************************************************/
337 int init_hw_mlme_ext(_adapter *padapter)
339 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
341 //set_opmode_cmd(padapter, infra_client_with_mlme);//removed
343 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
348 void init_mlme_default_rate_set(_adapter* padapter)
350 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
352 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};
353 unsigned char mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
354 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0xff, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
356 _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
357 _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
359 _rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
362 static void init_mlme_ext_priv_value(_adapter* padapter)
364 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
365 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
367 ATOMIC_SET(&pmlmeext->event_seq, 0);
368 pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
369 #ifdef CONFIG_IEEE80211W
370 pmlmeext->sa_query_seq = 0;
371 pmlmeext->mgnt_80211w_IPN=0;
372 pmlmeext->mgnt_80211w_IPN_rx=0;
373 #endif //CONFIG_IEEE80211W
374 pmlmeext->cur_channel = padapter->registrypriv.channel;
375 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
376 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
380 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
382 init_mlme_default_rate_set(padapter);
384 if(pmlmeext->cur_channel > 14)
385 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
387 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
389 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
390 pmlmeext->sitesurvey_res.channel_idx = 0;
391 pmlmeext->sitesurvey_res.bss_cnt = 0;
392 pmlmeext->scan_abort = _FALSE;
394 pmlmeinfo->state = WIFI_FW_NULL_STATE;
395 pmlmeinfo->reauth_count = 0;
396 pmlmeinfo->reassoc_count = 0;
397 pmlmeinfo->link_count = 0;
398 pmlmeinfo->auth_seq = 0;
399 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
400 pmlmeinfo->key_index = 0;
403 pmlmeinfo->enc_algo = _NO_PRIVACY_;
404 pmlmeinfo->authModeToggle = 0;
406 _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
408 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
409 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
411 pmlmeinfo->dialogToken = 0;
413 pmlmeext->action_public_rxseq = 0xffff;
414 pmlmeext->action_public_dialog_token = 0xff;
417 static int has_channel(RT_CHANNEL_INFO *channel_set,
422 for (i = 0; i < chanset_size; i++) {
423 if (channel_set[i].ChannelNum == chan) {
431 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
433 struct p2p_channels *channel_list) {
435 struct p2p_oper_class_map op_class[] = {
436 { IEEE80211G, 81, 1, 13, 1, BW20 },
437 { IEEE80211G, 82, 14, 14, 1, BW20 },
438 #if 0 /* Do not enable HT40 on 2 GHz */
439 { IEEE80211G, 83, 1, 9, 1, BW40PLUS },
440 { IEEE80211G, 84, 5, 13, 1, BW40MINUS },
442 { IEEE80211A, 115, 36, 48, 4, BW20 },
443 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
444 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
445 { IEEE80211A, 124, 149, 161, 4, BW20 },
446 { IEEE80211A, 125, 149, 169, 4, BW20 },
447 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
448 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
449 { -1, 0, 0, 0, 0, BW20 }
456 for (op = 0; op_class[op].op_class; op++) {
458 struct p2p_oper_class_map *o = &op_class[op];
459 struct p2p_reg_class *reg = NULL;
461 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
462 if (!has_channel(channel_set, chanset_size, ch)) {
466 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
469 if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) &&
470 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
474 reg = &channel_list->reg_class[cla];
476 reg->reg_class = o->op_class;
479 reg->channel[reg->channels] = ch;
483 channel_list->reg_classes = cla;
487 static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
489 u8 index,chanset_size = 0;
490 u8 b5GBand = _FALSE, b2_4GBand = _FALSE;
491 u8 Index2G = 0, Index5G=0;
493 if (!rtw_is_channel_plan_valid(ChannelPlan)) {
494 DBG_871X("ChannelPlan ID %x error !!!!!\n",ChannelPlan);
498 _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
500 if(IsSupported24G(padapter->registrypriv.wireless_mode))
503 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
504 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
506 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
509 if(IsSupported5G(padapter->registrypriv.wireless_mode))
512 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
513 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
515 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
520 for(index=0;index<RTW_ChannelPlan2G[Index2G].Len;index++)
522 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
524 if( (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||//Channel 1~11 is active, and 12~14 is passive
525 (RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan) )
527 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
528 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
529 else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
530 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
532 else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
533 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
534 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)// channel 12~13, passive scan
536 if(channel_set[chanset_size].ChannelNum <= 11)
537 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
539 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
543 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
552 for(index=0;index<RTW_ChannelPlan5G[Index5G].Len;index++)
555 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
556 if ( channel_set[chanset_size].ChannelNum <= 48
557 || channel_set[chanset_size].ChannelNum >= 149 )
559 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
560 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
562 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
566 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
569 #else /* CONFIG_DFS */
570 if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
571 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) {
572 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
573 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
574 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
576 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
577 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
580 #endif /* CONFIG_DFS */
584 Hal_ChannelPlanToRegulation(padapter, ChannelPlan);
586 DBG_871X("%s ChannelPlan ID %x Chan num:%d \n",__FUNCTION__,ChannelPlan,chanset_size);
590 int init_mlme_ext_priv(_adapter* padapter)
593 struct registry_priv* pregistrypriv = &padapter->registrypriv;
594 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
595 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
596 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
598 // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
599 //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
601 pmlmeext->padapter = padapter;
603 //fill_fwpriv(padapter, &(pmlmeext->fwpriv));
605 init_mlme_ext_priv_value(padapter);
606 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
608 init_mlme_ext_timer(padapter);
610 #ifdef CONFIG_AP_MODE
611 init_mlme_ap_info(padapter);
614 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
615 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
616 pmlmeext->last_scan_time = 0;
617 pmlmeext->chan_scan_time = SURVEY_TO;
618 pmlmeext->mlmeext_init = _TRUE;
621 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
622 pmlmeext->active_keep_alive_check = _TRUE;
624 pmlmeext->active_keep_alive_check = _FALSE;
627 #ifdef DBG_FIXED_CHAN
628 pmlmeext->fixed_chan = 0xFF;
635 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
637 _adapter *padapter = pmlmeext->padapter;
642 if (padapter->bDriverStopped == _TRUE)
644 _cancel_timer_ex(&pmlmeext->survey_timer);
645 _cancel_timer_ex(&pmlmeext->link_timer);
646 //_cancel_timer_ex(&pmlmeext->ADDBA_timer);
650 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
651 { // if the channel is same, return 0. else return channel differential
655 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
659 if(padapter->mlmeextpriv.cur_channel >= channel)
661 return (padapter->mlmeextpriv.cur_channel - channel);
665 return (channel-padapter->mlmeextpriv.cur_channel);
674 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
676 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
677 u8 *pframe = precv_frame->u.hdr.rx_data;
681 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
682 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
683 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
688 ptable->func(padapter, precv_frame);
693 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
696 struct mlme_handler *ptable;
697 #ifdef CONFIG_AP_MODE
698 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
699 #endif //CONFIG_AP_MODE
700 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
701 u8 *pframe = precv_frame->u.hdr.rx_data;
702 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
703 struct dvobj_priv *psdpriv = padapter->dvobj;
704 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
706 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
707 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
708 GetFrameType(pframe), GetFrameSubType(pframe)));
713 pbuf = GetAddr1Ptr(pframe);
714 DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
715 pbuf = GetAddr2Ptr(pframe);
716 DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
717 pbuf = GetAddr3Ptr(pframe);
718 DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
722 if (GetFrameType(pframe) != WIFI_MGT_TYPE)
724 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
728 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
729 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
730 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
735 ptable = mlme_sta_tbl;
737 index = GetFrameSubType(pframe) >> 4;
740 if((index << 4)==WIFI_ACTION){
741 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
742 if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) {
743 DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe)));
744 On_TDLS_Dis_Rsp(padapter, precv_frame);
749 if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler)))
751 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
759 if (GetRetry(pframe))
761 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
763 /* drop the duplicate management frame */
764 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
765 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
769 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
775 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
780 #ifdef CONFIG_AP_MODE
781 switch (GetFrameSubType(pframe))
784 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
785 ptable->func = &OnAuth;
787 ptable->func = &OnAuthClient;
790 case WIFI_REASSOCREQ:
791 _mgt_dispatcher(padapter, ptable, precv_frame);
792 #ifdef CONFIG_HOSTAPD_MLME
793 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
794 rtw_hostapd_mlme_rx(padapter, precv_frame);
798 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
800 #ifdef CONFIG_HOSTAPD_MLME
801 rtw_hostapd_mlme_rx(padapter, precv_frame);
803 _mgt_dispatcher(padapter, ptable, precv_frame);
807 _mgt_dispatcher(padapter, ptable, precv_frame);
810 _mgt_dispatcher(padapter, ptable, precv_frame);
813 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
814 _mgt_dispatcher(padapter, ptable, precv_frame);
817 _mgt_dispatcher(padapter, ptable, precv_frame);
818 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
819 rtw_hostapd_mlme_rx(padapter, precv_frame);
824 _mgt_dispatcher(padapter, ptable, precv_frame);
831 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
833 bool response = _TRUE;
835 #ifdef CONFIG_IOCTL_CFG80211
836 if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
838 if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE
839 || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
840 || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
841 || padapter->mlmepriv.wps_probe_resp_ie == NULL
842 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
845 #ifdef CONFIG_DEBUG_CFG80211
846 DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ",
847 adapter_wdev_data(padapter)->p2p_enabled,
848 padapter->mlmepriv.wps_probe_resp_ie,
849 padapter->mlmepriv.p2p_probe_resp_ie);
850 DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n",
851 padapter->cfg80211_wdinfo.is_ro_ch,
852 rtw_get_oper_ch(padapter),
853 padapter->wdinfo.listen_channel);
859 #endif //CONFIG_IOCTL_CFG80211
860 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
862 // do nothing if the device name is empty
863 if ( !padapter->wdinfo.device_name_len )
869 if (response == _TRUE)
870 issue_probersp_p2p( padapter, da);
877 /****************************************************************************
879 Following are the callback functions for each subtype of the management frames
881 *****************************************************************************/
883 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
887 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
888 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
889 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
890 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
891 u8 *pframe = precv_frame->u.hdr.rx_data;
892 uint len = precv_frame->u.hdr.len;
893 u8 is_valid_p2p_probereq = _FALSE;
895 #ifdef CONFIG_ATMEL_RC_PATCH
896 u8 *target_ie=NULL, *wps_ie=NULL;
898 uint search_len = 0, wps_ielen = 0, target_ielen = 0;
899 struct sta_info *psta;
900 struct sta_priv *pstapriv = &padapter->stapriv;
905 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
906 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
907 u8 wifi_test_chk_rate = 1;
909 if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
910 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
911 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
912 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
913 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
916 // Commented by Albert 2011/03/17
917 // mcs_rate = 0 -> CCK 1M rate
918 // mcs_rate = 1 -> CCK 2M rate
919 // mcs_rate = 2 -> CCK 5.5M rate
920 // mcs_rate = 3 -> CCK 11M rate
921 // In the P2P mode, the driver should not support the CCK rate
923 // Commented by Kurt 2012/10/16
924 // IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
925 if (padapter->registrypriv.wifi_spec == 1)
927 if ( pattrib->data_rate <= 3 )
929 wifi_test_chk_rate = 0;
933 if( wifi_test_chk_rate == 1 )
935 if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
937 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
940 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
941 report_survey_event(padapter, precv_frame);
943 p2p_listen_state_process( padapter, get_sa(pframe));
948 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
959 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
964 if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
965 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
971 //DBG_871X("+OnProbeReq\n");
974 #ifdef CONFIG_ATMEL_RC_PATCH
975 if ((wps_ie = rtw_get_wps_ie(
976 pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
977 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
978 NULL, &wps_ielen))) {
980 target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
982 if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) {
983 //psta->flag_atmel_rc = 1;
984 unsigned char *sa_addr = get_sa(pframe);
985 printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n",
986 __func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5));
987 _rtw_memcpy( pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
992 #ifdef CONFIG_AUTO_AP_MODE
993 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
994 pmlmepriv->cur_network.join_res == _TRUE)
997 struct sta_info *psta;
998 u8 *mac_addr, *peer_addr;
999 struct sta_priv *pstapriv = &padapter->stapriv;
1000 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
1001 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
1003 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1004 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1006 if(!p || ielen !=14)
1007 goto _non_rc_device;
1009 if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
1010 goto _non_rc_device;
1012 if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
1014 DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1015 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
1017 goto _non_rc_device;
1020 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
1023 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1026 // allocate a new one
1027 DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
1028 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1032 DBG_871X(" Exceed the upper limit of supported clients...\n");
1036 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1037 if (rtw_is_list_empty(&psta->asoc_list))
1039 psta->expire_to = pstapriv->expire_to;
1040 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1041 pstapriv->asoc_list_cnt++;
1043 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1045 //generate pairing ID
1046 mac_addr = adapter_mac_addr(padapter);
1047 peer_addr = psta->hwaddr;
1048 psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
1050 //update peer stainfo
1055 /* get a unique AID */
1056 if (psta->aid > 0) {
1057 DBG_871X("old AID %d\n", psta->aid);
1059 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1060 if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1063 if (psta->aid > pstapriv->max_num_sta) {
1065 DBG_871X("no room for more AIDs\n");
1068 pstapriv->sta_aid[psta->aid - 1] = psta;
1069 DBG_871X("allocate new AID = (%d)\n", psta->aid);
1073 psta->qos_option = 1;
1074 psta->bw_mode = CHANNEL_WIDTH_20;
1075 psta->ieee8021x_blocked = _FALSE;
1076 #ifdef CONFIG_80211N_HT
1077 psta->htpriv.ht_option = _TRUE;
1078 psta->htpriv.ampdu_enable = _FALSE;
1079 psta->htpriv.sgi_20m = _FALSE;
1080 psta->htpriv.sgi_40m = _FALSE;
1081 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1082 psta->htpriv.agg_enable_bitmap = 0x0;//reset
1083 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
1086 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1088 _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1090 _enter_critical_bh(&psta->lock, &irqL);
1091 psta->state |= _FW_LINKED;
1092 _exit_critical_bh(&psta->lock, &irqL);
1094 report_add_sta_event(padapter, psta->hwaddr, psta->aid);
1098 issue_probersp(padapter, get_sa(pframe), _FALSE);
1108 #endif //CONFIG_AUTO_AP_MODE
1111 #ifdef CONFIG_CONCURRENT_MODE
1112 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1113 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1115 //don't process probe req
1120 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1121 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1124 //check (wildcard) SSID
1127 if(is_valid_p2p_probereq == _TRUE)
1129 goto _issue_probersp;
1132 if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1133 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1140 if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1141 pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1143 //DBG_871X("+issue_probersp during ap mode\n");
1144 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
1153 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1155 struct sta_info *psta;
1156 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1157 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1158 struct sta_priv *pstapriv = &padapter->stapriv;
1159 u8 *pframe = precv_frame->u.hdr.rx_data;
1161 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1166 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
1168 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
1170 if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1172 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
1174 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1175 issue_p2p_provision_request( padapter,
1176 pwdinfo->tx_prov_disc_info.ssid.Ssid,
1177 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1178 pwdinfo->tx_prov_disc_info.peerDevAddr );
1180 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
1182 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1183 issue_p2p_provision_request( padapter,
1186 pwdinfo->tx_prov_disc_info.peerDevAddr );
1192 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
1194 if ( _TRUE == pwdinfo->nego_req_info.benable )
1196 DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
1197 if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1199 pwdinfo->nego_req_info.benable = _FALSE;
1200 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
1204 else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
1206 if ( _TRUE == pwdinfo->invitereq_info.benable )
1208 DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
1209 if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1211 pwdinfo->invitereq_info.benable = _FALSE;
1212 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
1219 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
1221 report_survey_event(padapter, precv_frame);
1222 #ifdef CONFIG_CONCURRENT_MODE
1223 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1228 #if 0 //move to validate_recv_mgnt_frame
1229 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1231 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1233 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1235 psta->sta_stats.rx_mgnt_pkts++;
1245 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1248 struct sta_info *psta;
1249 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1250 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1251 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1252 struct sta_priv *pstapriv = &padapter->stapriv;
1253 u8 *pframe = precv_frame->u.hdr.rx_data;
1254 uint len = precv_frame->u.hdr.len;
1255 WLAN_BSSID_EX *pbss;
1260 struct sta_info *ptdls_sta;
1261 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1262 #endif /* CONFIG_TDLS */
1264 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1265 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_);
1266 if ((p != NULL) && (ielen > 0))
1268 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
1270 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
1271 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)));
1272 *(p + 1) = ielen - 1;
1277 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
1279 report_survey_event(padapter, precv_frame);
1280 #ifdef CONFIG_CONCURRENT_MODE
1281 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1286 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1288 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1290 //we should update current network before auth, or some IE is wrong
1291 pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1293 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1294 struct beacon_keys recv_beacon;
1296 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1297 rtw_get_bcn_info(&(pmlmepriv->cur_network));
1300 if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1301 DBG_871X("%s: beacon keys ready\n", __func__);
1302 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1303 &recv_beacon, sizeof(recv_beacon));
1304 pmlmepriv->new_beacon_cnts = 0;
1307 DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__);
1308 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1309 pmlmepriv->new_beacon_cnts = 0;
1312 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1315 //check the vendor of the assoc AP
1316 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
1319 update_TSF(pmlmeext, pframe, len);
1321 //reset for adaptive_early_32k
1322 pmlmeext->adaptive_tsf_done = _FALSE;
1323 pmlmeext->DrvBcnEarly = 0xff;
1324 pmlmeext->DrvBcnTimeOut = 0xff;
1325 pmlmeext->bcn_cnt = 0;
1326 _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1327 _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1329 #ifdef CONFIG_P2P_PS
1330 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1331 #endif //CONFIG_P2P_PS
1333 #if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE)
1334 if (padapter->registrypriv.wifi_spec) {
1335 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1336 if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
1337 DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n ");
1342 #endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE
1345 start_clnt_auth(padapter);
1350 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1352 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1354 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1355 //Merge from 8712 FW code
1356 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
1357 { // join wrong channel, deauth and reconnect
1358 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1360 report_del_sta_event(padapter,(&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL);
1361 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1364 #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
1366 ret = rtw_check_bcn_info(padapter, pframe, len);
1368 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1369 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0);
1372 //update WMM, ERP in the beacon
1373 //todo: the timer is used instead of the number of the beacon received
1374 if ((sta_rx_pkts(psta) & 0xf) == 0)
1376 //DBG_871X("update_bcn_info\n");
1377 update_beacon_info(padapter, pframe, len, psta);
1380 adaptive_early_32k(pmlmeext, pframe, len);
1383 #ifdef CONFIG_TDLS_CH_SW
1384 if (padapter->tdlsinfo.ch_switch_prohibited == _FALSE)
1386 /* Send TDLS Channel Switch Request when receiving Beacon */
1387 if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1388 ptdlsinfo->chsw_info.ch_sw_state |= TDLS_WAIT_CH_RSP_STATE;
1389 /* DBG_871X("[%s] issue_tdls_ch_switch_req to "MAC_FMT"\n", __FUNCTION__, MAC_ARG(padapter->tdlsinfo.chsw_info.addr)); */
1390 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1391 if (ptdls_sta != NULL) {
1392 if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
1393 issue_tdls_ch_switch_req(padapter, ptdls_sta);
1398 #endif /* CONFIG_TDLS */
1401 process_csa_ie(padapter, pframe, len); //channel switch announcement
1404 #ifdef CONFIG_P2P_PS
1405 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1406 #endif //CONFIG_P2P_PS
1408 #if 0 //move to validate_recv_mgnt_frame
1409 psta->sta_stats.rx_mgnt_pkts++;
1413 else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
1415 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1417 //update WMM, ERP in the beacon
1418 //todo: the timer is used instead of the number of the beacon received
1419 if ((sta_rx_pkts(psta) & 0xf) == 0)
1421 //DBG_871X("update_bcn_info\n");
1422 update_beacon_info(padapter, pframe, len, psta);
1425 #if 0 //move to validate_recv_mgnt_frame
1426 psta->sta_stats.rx_mgnt_pkts++;
1431 //allocate a new CAM entry for IBSS station
1432 if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
1434 goto _END_ONBEACON_;
1437 //get supported rate
1438 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)
1440 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
1441 goto _END_ONBEACON_;
1445 update_TSF(pmlmeext, pframe, len);
1447 //report sta add event
1448 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
1459 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1461 #ifdef CONFIG_AP_MODE
1463 unsigned int auth_mode, seq, ie_len;
1464 unsigned char *sa, *p;
1467 static struct sta_info stat;
1468 struct sta_info *pstat=NULL;
1469 struct sta_priv *pstapriv = &padapter->stapriv;
1470 struct security_priv *psecuritypriv = &padapter->securitypriv;
1471 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1472 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1473 u8 *pframe = precv_frame->u.hdr.rx_data;
1474 uint len = precv_frame->u.hdr.len;
1478 #ifdef CONFIG_CONCURRENT_MODE
1479 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1480 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1482 //don't process auth request;
1485 #endif //CONFIG_CONCURRENT_MODE
1487 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1490 DBG_871X("+OnAuth\n");
1492 sa = GetAddr2Ptr(pframe);
1494 auth_mode = psecuritypriv->dot11AuthAlgrthm;
1496 if (GetPrivacy(pframe))
1499 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
1501 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
1502 prxattrib->encrypt = _WEP40_;
1504 iv = pframe+prxattrib->hdrlen;
1505 prxattrib->key_index = ((iv[3]>>6)&0x3);
1507 prxattrib->iv_len = 4;
1508 prxattrib->icv_len = 4;
1510 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
1515 algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1516 seq = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1518 DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
1520 if (auth_mode == 2 &&
1521 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1522 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1525 if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled
1526 (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled
1528 DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1529 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1531 status = _STATS_NO_SUPP_ALG_;
1537 phead = &priv->wlan_acl_list;
1538 plist = phead->next;
1540 if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected.
1545 while(plist != phead)
1547 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
1548 plist = plist->next;
1549 if (!memcmp((void *)sa, paclnode->addr, 6)) {
1550 if (paclnode->mode & 2) { // deny
1561 if (res != SUCCESS) {
1562 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
1566 if(rtw_access_ctrl(padapter, sa) == _FALSE)
1568 status = _STATS_UNABLE_HANDLE_STA_;
1573 pstat = rtw_get_stainfo(pstapriv, sa);
1577 // allocate a new one
1578 DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
1579 pstat = rtw_alloc_stainfo(pstapriv, sa);
1582 DBG_871X(" Exceed the upper limit of supported clients...\n");
1583 status = _STATS_UNABLE_HANDLE_STA_;
1587 pstat->state = WIFI_FW_AUTH_NULL;
1588 pstat->auth_seq = 0;
1591 //pstat->capability = 0;
1596 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1597 if(rtw_is_list_empty(&pstat->asoc_list)==_FALSE)
1599 rtw_list_delete(&pstat->asoc_list);
1600 pstapriv->asoc_list_cnt--;
1601 if (pstat->expire_to > 0)
1603 //TODO: STA re_auth within expire_to
1606 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1609 //TODO: STA re_auth and auth timeout
1613 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
1614 if (rtw_is_list_empty(&pstat->auth_list))
1617 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
1618 pstapriv->auth_list_cnt++;
1620 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
1622 if (pstat->auth_seq == 0)
1623 pstat->expire_to = pstapriv->auth_to;
1626 if ((pstat->auth_seq + 1) != seq)
1628 DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1629 seq, pstat->auth_seq+1);
1630 status = _STATS_OUT_OF_AUTH_SEQ_;
1634 if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
1638 pstat->state &= ~WIFI_FW_AUTH_NULL;
1639 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1640 pstat->expire_to = pstapriv->assoc_to;
1641 pstat->authalg = algorithm;
1645 DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1646 seq, pstat->auth_seq+1);
1647 status = _STATS_OUT_OF_AUTH_SEQ_;
1651 else // shared system or auto authentication
1655 //prepare for the challenging txt...
1657 //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
1658 _rtw_memset((void *)pstat->chg_txt, 78, 128);
1660 pstat->state &= ~WIFI_FW_AUTH_NULL;
1661 pstat->state |= WIFI_FW_AUTH_STATE;
1662 pstat->authalg = algorithm;
1663 pstat->auth_seq = 2;
1667 //checking for challenging txt...
1668 DBG_871X("checking for challenging txt...\n");
1670 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
1671 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
1673 if((p==NULL) || (ie_len<=0))
1675 DBG_871X("auth rejected because challenge failure!(1)\n");
1676 status = _STATS_CHALLENGE_FAIL_;
1680 if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
1682 pstat->state &= (~WIFI_FW_AUTH_STATE);
1683 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1684 // challenging txt is correct...
1685 pstat->expire_to = pstapriv->assoc_to;
1689 DBG_871X("auth rejected because challenge failure!\n");
1690 status = _STATS_CHALLENGE_FAIL_;
1696 DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1697 seq, pstat->auth_seq+1);
1698 status = _STATS_OUT_OF_AUTH_SEQ_;
1704 // Now, we are going to issue_auth...
1705 pstat->auth_seq = seq + 1;
1707 #ifdef CONFIG_NATIVEAP_MLME
1708 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
1711 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1712 pstat->auth_seq = 0;
1720 rtw_free_stainfo(padapter , pstat);
1723 _rtw_memset((char *)pstat, '\0', sizeof(stat));
1724 pstat->auth_seq = 2;
1725 _rtw_memcpy(pstat->hwaddr, sa, 6);
1727 #ifdef CONFIG_NATIVEAP_MLME
1728 issue_auth(padapter, pstat, (unsigned short)status);
1736 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
1738 unsigned int seq, len, status, algthm, offset;
1740 unsigned int go2asoc = 0;
1741 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1742 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1743 u8 *pframe = precv_frame->u.hdr.rx_data;
1744 uint pkt_len = precv_frame->u.hdr.len;
1746 DBG_871X("%s\n", __FUNCTION__);
1748 //check A1 matches or not
1749 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
1752 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1755 offset = (GetPrivacy(pframe))? 4: 0;
1757 algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1758 seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1759 status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
1763 DBG_871X("clnt auth fail, status: %d\n", status);
1764 if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
1766 if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1767 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1769 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1770 //pmlmeinfo->reauth_count = 0;
1773 set_link_timer(pmlmeext, 1);
1779 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1781 // legendary shared system
1782 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
1783 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
1787 //DBG_871X("marc: no challenge text?\n");
1791 _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
1792 pmlmeinfo->auth_seq = 3;
1793 issue_auth(padapter, NULL, 0);
1794 set_link_timer(pmlmeext, REAUTH_TO);
1806 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1817 // this is also illegal
1818 //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
1824 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
1825 start_clnt_assoc(padapter);
1831 //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
1837 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
1839 #ifdef CONFIG_AP_MODE
1841 u16 capab_info, listen_interval;
1842 struct rtw_ieee802_11_elems elems;
1843 struct sta_info *pstat;
1844 unsigned char reassoc, *p, *pos, *wpa_ie;
1845 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1846 int i, ie_len, wpa_ie_len, left;
1847 unsigned char supportRate[16];
1849 unsigned short status = _STATS_SUCCESSFUL_;
1850 unsigned short frame_type, ie_offset=0;
1851 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1852 struct security_priv *psecuritypriv = &padapter->securitypriv;
1853 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1854 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1855 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1856 struct sta_priv *pstapriv = &padapter->stapriv;
1857 u8 *pframe = precv_frame->u.hdr.rx_data;
1858 uint pkt_len = precv_frame->u.hdr.len;
1860 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1861 u8 p2p_status_code = P2P_STATUS_SUCCESS;
1865 u8 wfd_ie[ 128 ] = { 0x00 };
1867 #endif // CONFIG_WFD
1870 #ifdef CONFIG_CONCURRENT_MODE
1871 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1872 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1874 //don't process assoc request;
1877 #endif //CONFIG_CONCURRENT_MODE
1879 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1882 frame_type = GetFrameSubType(pframe);
1883 if (frame_type == WIFI_ASSOCREQ)
1886 ie_offset = _ASOCREQ_IE_OFFSET_;
1888 else // WIFI_REASSOCREQ
1891 ie_offset = _REASOCREQ_IE_OFFSET_;
1895 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
1896 DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
1897 "\n", reassoc, (unsigned long)pkt_len);
1901 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1902 if (pstat == (struct sta_info *)NULL)
1904 status = _RSON_CLS2_;
1905 goto asoc_class2_error;
1908 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
1909 //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
1910 //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
1911 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
1913 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
1914 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
1917 DBG_871X("%s\n", __FUNCTION__);
1919 // check if this stat has been successfully authenticated/assocated
1920 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
1922 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
1924 status = _RSON_CLS2_;
1925 goto asoc_class2_error;
1929 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1930 pstat->state |= WIFI_FW_ASSOC_STATE;
1935 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1936 pstat->state |= WIFI_FW_ASSOC_STATE;
1940 #if 0// todo:tkip_countermeasures
1941 if (hapd->tkip_countermeasures) {
1942 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
1947 pstat->capability = capab_info;
1950 //check listen_interval
1951 if (listen_interval > hapd->conf->max_listen_interval) {
1952 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1953 HOSTAPD_LEVEL_DEBUG,
1954 "Too large Listen Interval (%d)",
1956 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
1960 pstat->listen_interval = listen_interval;
1963 //now parse all ieee802_11 ie to point to elems
1964 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
1966 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
1967 MAC_ARG(pstat->hwaddr));
1968 status = _STATS_FAILURE_;
1969 goto OnAssocReqFail;
1973 // now we should check all the fields...
1975 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
1976 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1979 status = _STATS_FAILURE_;
1982 if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
1983 status = _STATS_FAILURE_;
1986 // check if ssid match
1987 if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
1988 status = _STATS_FAILURE_;
1990 if (ie_len != cur->Ssid.SsidLength)
1991 status = _STATS_FAILURE_;
1994 if(_STATS_SUCCESSFUL_ != status)
1995 goto OnAssocReqFail;
1997 // check if the supported rate is ok
1998 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2000 DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
2001 // use our own rate set as statoin used
2002 //_rtw_memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN);
2003 //supportRateNum = AP_BSSRATE_LEN;
2005 status = _STATS_FAILURE_;
2006 goto OnAssocReqFail;
2009 _rtw_memcpy(supportRate, p+2, ie_len);
2010 supportRateNum = ie_len;
2012 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
2013 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2016 if(supportRateNum<=sizeof(supportRate))
2018 _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
2019 supportRateNum += ie_len;
2024 //todo: mask supportRate between AP & STA -> move to update raid
2025 //get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0);
2027 //update station supportRate
2028 pstat->bssratelen = supportRateNum;
2029 _rtw_memcpy(pstat->bssrateset, supportRate, supportRateNum);
2030 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2033 pstat->dot8021xalg = 0;
2035 pstat->wpa_group_cipher = 0;
2036 pstat->wpa2_group_cipher = 0;
2037 pstat->wpa_pairwise_cipher = 0;
2038 pstat->wpa2_pairwise_cipher = 0;
2039 _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2040 if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2042 int group_cipher=0, pairwise_cipher=0;
2044 wpa_ie = elems.rsn_ie;
2045 wpa_ie_len = elems.rsn_ie_len;
2047 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2049 pstat->dot8021xalg = 1;//psk, todo:802.1x
2050 pstat->wpa_psk |= BIT(1);
2052 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
2053 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
2055 if(!pstat->wpa2_group_cipher)
2056 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2058 if(!pstat->wpa2_pairwise_cipher)
2059 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2063 status = WLAN_STATUS_INVALID_IE;
2066 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2068 int group_cipher=0, pairwise_cipher=0;
2070 wpa_ie = elems.wpa_ie;
2071 wpa_ie_len = elems.wpa_ie_len;
2073 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2075 pstat->dot8021xalg = 1;//psk, todo:802.1x
2076 pstat->wpa_psk |= BIT(0);
2078 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
2079 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
2081 if(!pstat->wpa_group_cipher)
2082 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2084 if(!pstat->wpa_pairwise_cipher)
2085 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2090 status = WLAN_STATUS_INVALID_IE;
2098 if(_STATS_SUCCESSFUL_ != status)
2099 goto OnAssocReqFail;
2101 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2102 //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
2103 if(wpa_ie == NULL) {
2105 DBG_871X("STA included WPS IE in "
2106 "(Re)Association Request - assume WPS is "
2108 pstat->flags |= WLAN_STA_WPS;
2109 //wpabuf_free(sta->wps_ie);
2110 //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
2111 // elems.wps_ie_len - 4);
2113 DBG_871X("STA did not include WPA/RSN IE "
2114 "in (Re)Association Request - possible WPS "
2116 pstat->flags |= WLAN_STA_MAYBE_WPS;
2120 // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
2121 // that the selected registrar of AP is _FLASE
2122 if((psecuritypriv->wpa_psk >0)
2123 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
2125 if(pmlmepriv->wps_beacon_ie)
2127 u8 selected_registrar = 0;
2129 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2131 if(!selected_registrar)
2133 DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2135 status = _STATS_UNABLE_HANDLE_STA_;
2137 goto OnAssocReqFail;
2147 if(psecuritypriv->wpa_psk == 0)
2149 DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
2150 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2152 status = WLAN_STATUS_INVALID_IE;
2154 goto OnAssocReqFail;
2159 DBG_871X("STA included WPS IE in "
2160 "(Re)Association Request - WPS is "
2162 pstat->flags |= WLAN_STA_WPS;
2167 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
2172 _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
2177 // check if there is WMM IE & support WWM-PS
2178 pstat->flags &= ~WLAN_STA_WME;
2179 pstat->qos_option = 0;
2180 pstat->qos_info = 0;
2181 pstat->has_legacy_ac = _TRUE;
2182 pstat->uapsd_vo = 0;
2183 pstat->uapsd_vi = 0;
2184 pstat->uapsd_be = 0;
2185 pstat->uapsd_bk = 0;
2186 if (pmlmepriv->qospriv.qos_option)
2188 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
2191 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2193 if (_rtw_memcmp(p+2, WMM_IE, 6)) {
2195 pstat->flags |= WLAN_STA_WME;
2197 pstat->qos_option = 1;
2198 pstat->qos_info = *(p+8);
2200 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
2202 if((pstat->qos_info&0xf) !=0xf)
2203 pstat->has_legacy_ac = _TRUE;
2205 pstat->has_legacy_ac = _FALSE;
2207 if(pstat->qos_info&0xf)
2209 if(pstat->qos_info&BIT(0))
2210 pstat->uapsd_vo = BIT(0)|BIT(1);
2212 pstat->uapsd_vo = 0;
2214 if(pstat->qos_info&BIT(1))
2215 pstat->uapsd_vi = BIT(0)|BIT(1);
2217 pstat->uapsd_vi = 0;
2219 if(pstat->qos_info&BIT(2))
2220 pstat->uapsd_bk = BIT(0)|BIT(1);
2222 pstat->uapsd_bk = 0;
2224 if(pstat->qos_info&BIT(3))
2225 pstat->uapsd_be = BIT(0)|BIT(1);
2227 pstat->uapsd_be = 0;
2242 #ifdef CONFIG_80211N_HT
2243 /* save HT capabilities in the sta object */
2244 _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2245 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
2247 pstat->flags |= WLAN_STA_HT;
2249 pstat->flags |= WLAN_STA_WME;
2251 _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
2254 pstat->flags &= ~WLAN_STA_HT;
2257 if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
2259 status = _STATS_FAILURE_;
2260 goto OnAssocReqFail;
2264 if ((pstat->flags & WLAN_STA_HT) &&
2265 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
2266 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP)))
2268 DBG_871X("HT: " MAC_FMT " tried to "
2269 "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
2271 //status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2272 //goto OnAssocReqFail;
2274 #endif /* CONFIG_80211N_HT */
2276 #ifdef CONFIG_80211AC_VHT
2277 _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
2278 if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
2279 pstat->flags |= WLAN_STA_VHT;
2281 _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
2283 if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) {
2284 _rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1);
2286 else // for Frame without Operating Mode notify ie; default: 80M
2288 pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
2292 pstat->flags &= ~WLAN_STA_VHT;
2295 if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT))
2297 status = _STATS_FAILURE_;
2298 goto OnAssocReqFail;
2300 #endif /* CONFIG_80211AC_VHT */
2303 //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
2304 pstat->flags |= WLAN_STA_NONERP;
2305 for (i = 0; i < pstat->bssratelen; i++) {
2306 if ((pstat->bssrateset[i] & 0x7f) > 22) {
2307 pstat->flags &= ~WLAN_STA_NONERP;
2312 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2313 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2315 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2319 if (status != _STATS_SUCCESSFUL_)
2320 goto OnAssocReqFail;
2323 pstat->is_p2p_device = _FALSE;
2324 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2326 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
2328 pstat->is_p2p_device = _TRUE;
2329 if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
2331 pstat->p2p_status_code = p2p_status_code;
2332 status = _STATS_CAP_FAIL_;
2333 goto OnAssocReqFail;
2337 if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
2339 u8 attr_content[ 10 ] = { 0x00 };
2340 u32 attr_contentlen = 0;
2342 DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ );
2343 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
2344 if ( attr_contentlen )
2346 pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
2347 DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
2352 pstat->p2p_status_code = p2p_status_code;
2355 //TODO: identify_proprietary_vendor_ie();
2356 // Realtek proprietary IE
2357 // identify if this is Broadcom sta
2358 // identify if this is ralink sta
2359 // Customer proprietary IE
2363 /* get a unique AID */
2364 if (pstat->aid > 0) {
2365 DBG_871X(" old AID %d\n", pstat->aid);
2367 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2368 if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2369 if (pstat->aid > pstapriv->max_num_sta) {
2372 DBG_871X(" no room for more AIDs\n");
2374 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2376 goto OnAssocReqFail;
2380 pstapriv->sta_aid[pstat->aid - 1] = pstat;
2381 DBG_871X("allocate new AID = (%d)\n", pstat->aid);
2389 pstat->state &= (~WIFI_FW_ASSOC_STATE);
2390 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2392 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2393 if (!rtw_is_list_empty(&pstat->auth_list))
2395 rtw_list_delete(&pstat->auth_list);
2396 pstapriv->auth_list_cnt--;
2398 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2400 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2401 if (rtw_is_list_empty(&pstat->asoc_list))
2403 pstat->expire_to = pstapriv->expire_to;
2404 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2405 pstapriv->asoc_list_cnt++;
2407 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2409 // now the station is qualified to join our BSS...
2410 if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
2412 #ifdef CONFIG_NATIVEAP_MLME
2413 //.1 bss_cap_update & sta_info_update
2414 bss_cap_update_on_sta_join(padapter, pstat);
2415 sta_info_update(padapter, pstat);
2417 //.2 issue assoc rsp before notify station join event.
2418 if (frame_type == WIFI_ASSOCREQ)
2419 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2421 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2423 #ifdef CONFIG_IOCTL_CFG80211
2424 _enter_critical_bh(&pstat->lock, &irqL);
2425 if(pstat->passoc_req)
2427 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2428 pstat->passoc_req = NULL;
2429 pstat->assoc_req_len = 0;
2432 pstat->passoc_req = rtw_zmalloc(pkt_len);
2433 if(pstat->passoc_req)
2435 _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2436 pstat->assoc_req_len = pkt_len;
2438 _exit_critical_bh(&pstat->lock, &irqL);
2439 #endif //CONFIG_IOCTL_CFG80211
2441 //.3-(1) report sta add event
2442 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
2444 #endif //CONFIG_NATIVEAP_MLME
2451 #ifdef CONFIG_NATIVEAP_MLME
2452 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
2460 #ifdef CONFIG_NATIVEAP_MLME
2462 if (frame_type == WIFI_ASSOCREQ)
2463 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2465 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2469 #endif /* CONFIG_AP_MODE */
2475 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2479 unsigned short status;
2480 PNDIS_802_11_VARIABLE_IEs pIE;
2481 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2482 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2483 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2484 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
2485 u8 *pframe = precv_frame->u.hdr.rx_data;
2486 uint pkt_len = precv_frame->u.hdr.len;
2487 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
2489 DBG_871X("%s\n", __FUNCTION__);
2491 //check A1 matches or not
2492 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2495 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2498 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2501 _cancel_timer_ex(&pmlmeext->link_timer);
2504 if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2506 DBG_871X("assoc reject, status code: %d\n", status);
2507 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2509 goto report_assoc_result;
2513 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2516 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2519 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2521 //following are moved to join event callback function
2522 //to handle HT, WMM, rate adaptive, update MAC reg
2523 //for not to handle the synchronous IO in the tasklet
2524 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2526 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2528 switch (pIE->ElementID)
2530 case _VENDOR_SPECIFIC_IE_:
2531 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM
2533 WMM_param_handler(padapter, pIE);
2535 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2536 else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD
2538 DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ );
2539 WFD_info_handler( padapter, pIE );
2544 #ifdef CONFIG_WAPI_SUPPORT
2550 case _HT_CAPABILITY_IE_: //HT caps
2551 HT_caps_handler(padapter, pIE);
2554 case _HT_EXTRA_INFO_IE_: //HT info
2555 HT_info_handler(padapter, pIE);
2558 #ifdef CONFIG_80211AC_VHT
2559 case EID_VHTCapability:
2560 VHT_caps_handler(padapter, pIE);
2563 case EID_VHTOperation:
2564 VHT_operation_handler(padapter, pIE);
2569 ERP_IE_handler(padapter, pIE);
2573 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2574 padapter->tdlsinfo.ap_prohibited = _TRUE;
2575 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
2576 padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
2578 #endif /* CONFIG_TDLS */
2583 i += (pIE->Length + 2);
2586 #ifdef CONFIG_WAPI_SUPPORT
2587 rtw_wapi_on_assoc_ok(padapter, pIE);
2590 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
2591 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
2593 //Update Basic Rate Table for spec, 2010-12-28 , by thomas
2594 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
2596 report_assoc_result:
2598 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
2600 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
2603 report_join_res(padapter, res);
2608 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
2610 unsigned short reason;
2611 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2612 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2613 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2614 u8 *pframe = precv_frame->u.hdr.rx_data;
2616 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2620 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
2624 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2626 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2627 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2631 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2633 rtw_lock_rx_suspend_timeout(8000);
2635 #ifdef CONFIG_AP_MODE
2636 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2639 struct sta_info *psta;
2640 struct sta_priv *pstapriv = &padapter->stapriv;
2642 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2643 //rtw_free_stainfo(padapter, psta);
2644 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2646 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
2647 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
2649 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2652 u8 updated = _FALSE;
2654 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2655 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
2657 rtw_list_delete(&psta->asoc_list);
2658 pstapriv->asoc_list_cnt--;
2659 updated = ap_free_sta(padapter, psta, _FALSE, reason);
2662 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2664 associated_clients_update(padapter, updated);
2673 int ignore_received_deauth = 0;
2675 // Commented by Albert 20130604
2676 // Before sending the auth frame to start the STA/GC mode connection with AP/GO,
2677 // we will send the deauth first.
2678 // However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
2679 // Added the following code to avoid this case.
2680 if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
2681 ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
2683 if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
2685 ignore_received_deauth = 1;
2686 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
2688 ignore_received_deauth = 1;
2692 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
2693 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth);
2695 if ( 0 == ignore_received_deauth )
2697 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
2700 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
2705 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
2707 unsigned short reason;
2708 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2709 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2710 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2711 u8 *pframe = precv_frame->u.hdr.rx_data;
2713 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2717 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
2721 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2723 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2724 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2728 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2730 rtw_lock_rx_suspend_timeout(8000);
2732 #ifdef CONFIG_AP_MODE
2733 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2736 struct sta_info *psta;
2737 struct sta_priv *pstapriv = &padapter->stapriv;
2739 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2740 //rtw_free_stainfo(padapter, psta);
2741 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
2743 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
2744 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
2746 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2749 u8 updated = _FALSE;
2751 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2752 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
2754 rtw_list_delete(&psta->asoc_list);
2755 pstapriv->asoc_list_cnt--;
2756 updated = ap_free_sta(padapter, psta, _FALSE, reason);
2759 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2761 associated_clients_update(padapter, updated);
2769 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
2770 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
2772 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
2774 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
2779 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
2781 DBG_871X("%s\n", __FUNCTION__);
2785 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
2787 unsigned int ret = _FAIL;
2788 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
2789 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
2791 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
2796 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
2798 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
2801 struct ieee80211_info_element *ie;
2803 DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
2804 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
2806 for_each_ie(ie, ies, ies_len) {
2807 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
2808 ch_switch_mode = ie->data[0];
2810 ch_switch_cnt = ie->data[2];
2811 DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
2812 ch_switch_mode, ch, ch_switch_cnt);
2814 else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
2815 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
2816 DBG_871X("ch_offset:%d\n", ch_offset);
2823 if (ch_offset == -1)
2824 bwmode = mlmeext->cur_bwmode;
2826 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
2827 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
2829 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
2832 * 1. the decision of channel switching
2833 * 2. things after channel switching
2836 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
2843 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
2845 unsigned int ret = _FAIL;
2846 struct sta_info *psta = NULL;
2847 struct sta_priv *pstapriv = &padapter->stapriv;
2848 u8 *pframe = precv_frame->u.hdr.rx_data;
2849 uint frame_len = precv_frame->u.hdr.len;
2850 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
2854 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
2856 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2861 category = frame_body[0];
2862 if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
2865 action = frame_body[1];
2867 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
2868 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
2869 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
2870 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
2872 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
2873 #ifdef CONFIG_SPCT_CH_SWITCH
2874 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
2875 frame_len-(frame_body-pframe)-2);
2886 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
2891 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
2897 * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
2898 * @adapter: the adapter to get target RX AMPDU buffer size
2900 * Returns: the target RX AMPDU buffer size
2902 u8 rtw_rx_ampdu_size(_adapter *adapter)
2905 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
2907 if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) {
2908 size = adapter->fix_rx_ampdu_size;
2912 #ifdef CONFIG_BT_COEXIST
2913 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
2914 size = rtw_btcoex_GetAMPDUSize(adapter);
2919 /* default value based on max_rx_ampdu_factor */
2920 if (adapter->driver_rx_ampdu_factor != 0xFF)
2921 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
2923 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
2925 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
2927 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
2929 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
2931 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
2945 * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
2946 * @adapter: the adapter to get the permission if RX AMPDU should be set up
2948 * Returns: accept or not
2950 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
2954 if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
2955 accept = adapter->fix_rx_ampdu_accept;
2959 #ifdef CONFIG_BT_COEXIST
2960 if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
2966 /* default value for other cases */
2967 accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
2974 * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
2975 * @adapter: the adapter to set target RX AMPDU buffer size
2976 * @size: the target RX AMPDU buffer size to set
2977 * @reason: reason for the target RX AMPDU buffer size setting
2979 * Returns: whether the target RX AMPDU buffer size is changed
2981 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
2983 bool is_adj = _FALSE;
2984 struct mlme_ext_priv *mlmeext;
2985 struct mlme_ext_info *mlmeinfo;
2987 mlmeext = &adapter->mlmeextpriv;
2988 mlmeinfo = &mlmeext->mlmext_info;
2990 if (reason == RX_AMPDU_DRV_FIXED) {
2991 if (adapter->fix_rx_ampdu_size != size) {
2992 adapter->fix_rx_ampdu_size = size;
2994 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3002 * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3003 * @adapter: the adapter to set if RX AMPDU should be set up
3004 * @accept: if RX AMPDU should be set up
3005 * @reason: reason for the permission if RX AMPDU should be set up
3007 * Returns: whether the permission if RX AMPDU should be set up is changed
3009 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3011 bool is_adj = _FALSE;
3012 struct mlme_ext_priv *mlmeext;
3013 struct mlme_ext_info *mlmeinfo;
3015 mlmeext = &adapter->mlmeextpriv;
3016 mlmeinfo = &mlmeext->mlmext_info;
3018 if (reason == RX_AMPDU_DRV_FIXED) {
3019 if (adapter->fix_rx_ampdu_accept != accept) {
3020 adapter->fix_rx_ampdu_accept = accept;
3022 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3030 * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3031 * @adapter: the adapter to which @sta belongs
3032 * @sta: the sta to be checked
3033 * @tid: the tid to be checked
3034 * @accept: the target permission if RX AMPDU should be set up
3035 * @size: the target RX AMPDU buffer size
3039 * 1: canceled by no permission
3040 * 2: canceled by different buffer size
3041 * 3: canceled by potential mismatched status
3043 * Blocking function, may sleep
3045 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3048 struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3050 if (reorder_ctl->enable == _FALSE) {
3051 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3052 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3058 if (accept == _FALSE) {
3059 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3061 } else if (reorder_ctl->ampdu_size != size) {
3062 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3071 * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3072 * @adapter: the adapter to which @sta belongs
3073 * @sta: the sta to be checked
3074 * @accept: the target permission if RX AMPDU should be set up
3075 * @size: the target RX AMPDU buffer size
3077 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3079 * Blocking function, may sleep
3081 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3086 for (i = 0; i < TID_NUM; i++) {
3087 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3095 * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3096 * @adapter: the adapter to be applied
3098 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3100 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3103 struct mlme_ext_priv *mlmeext;
3104 struct sta_info *sta;
3105 u8 accept = rtw_rx_ampdu_is_accept(adapter);
3106 u8 size = rtw_rx_ampdu_size(adapter);
3108 mlmeext = &adapter->mlmeextpriv;
3110 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3111 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3113 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3115 } else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3117 _list *phead, *plist;
3119 char peers[NUM_STA];
3120 struct sta_priv *pstapriv = &adapter->stapriv;
3123 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3125 phead = &pstapriv->asoc_list;
3126 plist = get_next(phead);
3128 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3131 sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3132 plist = get_next(plist);
3134 stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3135 if (stainfo_offset_valid(stainfo_offset))
3136 peers[peer_num++] = stainfo_offset;
3139 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3141 for (i = 0; i < peer_num; i++) {
3142 sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3144 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3151 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3154 struct sta_info *psta=NULL;
3155 struct recv_reorder_ctrl *preorder_ctrl;
3156 unsigned char *frame_body;
3157 unsigned char category, action;
3158 unsigned short tid, status, reason_code = 0;
3159 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3160 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3161 u8 *pframe = precv_frame->u.hdr.rx_data;
3162 struct sta_priv *pstapriv = &padapter->stapriv;
3163 #ifdef CONFIG_80211N_HT
3165 DBG_871X("%s\n", __FUNCTION__);
3167 //check RA matches or not
3168 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3172 //check A1 matches or not
3173 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3177 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3178 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3181 addr = GetAddr2Ptr(pframe);
3182 psta = rtw_get_stainfo(pstapriv, addr);
3187 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3189 category = frame_body[0];
3190 if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
3193 if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3194 (psta->htpriv.ht_option==_TRUE) &&
3195 (psta->htpriv.ampdu_enable==_TRUE))
3197 DBG_871X("Recv [%s] from direc link\n", __FUNCTION__);
3200 #endif //CONFIG_TDLS
3201 if (!pmlmeinfo->HT_enable)
3206 action = frame_body[1];
3207 DBG_871X("%s, action=%d\n", __FUNCTION__, action);
3210 case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
3212 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3213 //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
3214 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
3218 case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
3220 //status = frame_body[3] | (frame_body[4] << 8); //endian issue
3221 status = RTW_GET_LE16(&frame_body[3]);
3222 tid = ((frame_body[5] >> 2) & 0x7);
3226 DBG_871X("agg_enable for TID=%d\n", tid);
3227 psta->htpriv.agg_enable_bitmap |= 1 << tid;
3228 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3232 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3235 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3237 DBG_871X("%s alive check - rx ADDBA response\n", __func__);
3238 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3239 psta->expire_to = pstapriv->expire_to;
3240 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3243 //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
3246 case RTW_WLAN_ACTION_DELBA: //DELBA
3247 if ((frame_body[3] & BIT(3)) == 0)
3249 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3250 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3252 //reason_code = frame_body[4] | (frame_body[5] << 8);
3253 reason_code = RTW_GET_LE16(&frame_body[4]);
3255 else if((frame_body[3] & BIT(3)) == BIT(3))
3257 tid = (frame_body[3] >> 4) & 0x0F;
3259 preorder_ctrl = &psta->recvreorder_ctrl[tid];
3260 preorder_ctrl->enable = _FALSE;
3261 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3264 DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
3265 //todo: how to notify the host while receiving DELETE BA
3272 #endif //CONFIG_80211N_HT
3278 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
3282 for (i = 0; i < channel_list.reg_classes; i++) {
3283 cnt += channel_list.reg_class[i].channels;
3289 static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
3297 for( i = 0; i < pmlmeext->max_chan_nums; i++ )
3299 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
3303 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
3305 // Just include the channel 36, 40, 44, 48 channels for 5G low
3308 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
3310 // Just include the channel 149, 153, 157, 161 channels for 5G high
3316 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
3319 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3320 u8 action = P2P_PUB_ACTION_ACTION;
3321 u32 p2poui = cpu_to_be32(P2POUI);
3322 u8 oui_subtype = P2P_GO_NEGO_REQ;
3323 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3324 u8 wpsielen = 0, p2pielen = 0, i;
3325 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3326 u16 len_channellist_attr = 0;
3331 struct xmit_frame *pmgntframe;
3332 struct pkt_attrib *pattrib;
3333 unsigned char *pframe;
3334 struct rtw_ieee80211_hdr *pwlanhdr;
3335 unsigned short *fctrl;
3336 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3337 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3338 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3339 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3342 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3347 DBG_871X( "[%s] In\n", __FUNCTION__ );
3349 pattrib = &pmgntframe->attrib;
3350 update_mgntframe_attrib(padapter, pattrib);
3352 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3354 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3355 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3357 fctrl = &(pwlanhdr->frame_ctl);
3360 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3361 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3362 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3364 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3365 pmlmeext->mgnt_seq++;
3366 SetFrameSubType(pframe, WIFI_ACTION);
3368 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3369 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3371 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3372 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3373 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3374 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3375 pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value
3376 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3383 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3388 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3392 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3396 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
3398 // Device Password ID
3400 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3404 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3409 if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
3411 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3413 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
3415 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3417 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
3419 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3424 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3431 p2pie[ p2pielen++ ] = 0x50;
3432 p2pie[ p2pielen++ ] = 0x6F;
3433 p2pie[ p2pielen++ ] = 0x9A;
3434 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
3436 // Commented by Albert 20110306
3437 // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
3438 // 1. P2P Capability
3439 // 2. Group Owner Intent
3440 // 3. Configuration Timeout
3441 // 4. Listen Channel
3442 // 5. Extended Listen Timing
3443 // 6. Intended P2P Interface Address
3445 // 8. P2P Device Info
3446 // 9. Operating Channel
3451 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3454 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3458 // Device Capability Bitmap, 1 byte
3459 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3461 // Group Capability Bitmap, 1 byte
3462 if ( pwdinfo->persistent_supported )
3464 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3468 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3472 // Group Owner Intent
3474 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3477 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3481 // Todo the tie breaker bit.
3482 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) & 0xFE );
3484 // Configuration Timeout
3486 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3489 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3493 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
3494 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
3499 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
3502 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3507 p2pie[ p2pielen++ ] = 'X';
3508 p2pie[ p2pielen++ ] = 'X';
3510 // The third byte should be set to 0x04.
3511 // Described in the "Operating Channel Attribute" section.
3512 p2pie[ p2pielen++ ] = 0x04;
3515 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
3518 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listening channel number
3521 // Extended Listen Timing ATTR
3523 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
3526 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
3530 // Availability Period
3531 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3534 // Availability Interval
3535 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3539 // Intended P2P Interface Address
3541 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
3544 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3548 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
3549 p2pielen += ETH_ALEN;
3554 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3557 // Country String(3)
3558 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
3559 // + number of channels in all classes
3560 len_channellist_attr = 3
3561 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
3562 + get_reg_classes_full_count(pmlmeext->channel_list);
3564 #ifdef CONFIG_CONCURRENT_MODE
3565 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3567 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3571 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3575 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3582 p2pie[ p2pielen++ ] = 'X';
3583 p2pie[ p2pielen++ ] = 'X';
3585 // The third byte should be set to 0x04.
3586 // Described in the "Operating Channel Attribute" section.
3587 p2pie[ p2pielen++ ] = 0x04;
3589 // Channel Entry List
3591 #ifdef CONFIG_CONCURRENT_MODE
3592 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3594 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3595 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3598 if ( pbuddy_mlmeext->cur_channel > 14 )
3600 if ( pbuddy_mlmeext->cur_channel >= 149 )
3602 p2pie[ p2pielen++ ] = 0x7c;
3606 p2pie[ p2pielen++ ] = 0x73;
3611 p2pie[ p2pielen++ ] = 0x51;
3614 // Number of Channels
3615 // Just support 1 channel and this channel is AP's channel
3616 p2pie[ p2pielen++ ] = 1;
3619 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
3624 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3626 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3628 // Number of Channels
3629 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3632 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3633 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3637 #else // CONFIG_CONCURRENT_MODE
3640 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3642 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3644 // Number of Channels
3645 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3648 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3649 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3653 #endif // CONFIG_CONCURRENT_MODE
3657 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
3660 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
3661 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
3662 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
3666 // P2P Device Address
3667 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
3668 p2pielen += ETH_ALEN;
3671 // This field should be big endian. Noted by P2P specification.
3673 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
3677 // Primary Device Type
3679 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
3683 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
3687 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
3690 // Number of Secondary Device Types
3691 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
3695 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
3699 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
3703 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
3704 p2pielen += pwdinfo->device_name_len;
3707 // Operating Channel
3709 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3712 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3717 p2pie[ p2pielen++ ] = 'X';
3718 p2pie[ p2pielen++ ] = 'X';
3720 // The third byte should be set to 0x04.
3721 // Described in the "Operating Channel Attribute" section.
3722 p2pie[ p2pielen++ ] = 0x04;
3725 if ( pwdinfo->operating_channel <= 14 )
3728 p2pie[ p2pielen++ ] = 0x51;
3730 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
3733 p2pie[ p2pielen++ ] = 0x73;
3738 p2pie[ p2pielen++ ] = 0x7c;
3742 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
3744 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
3747 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
3749 pattrib->pktlen += wfdielen;
3752 pattrib->last_txcmdsz = pattrib->pktlen;
3754 dump_mgntframe(padapter, pmgntframe);
3761 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
3764 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3765 u8 action = P2P_PUB_ACTION_ACTION;
3766 u32 p2poui = cpu_to_be32(P2POUI);
3767 u8 oui_subtype = P2P_GO_NEGO_RESP;
3768 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3771 u16 wps_devicepassword_id = 0x0000;
3772 uint wps_devicepassword_id_len = 0;
3773 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
3774 u16 len_channellist_attr = 0;
3776 struct xmit_frame *pmgntframe;
3777 struct pkt_attrib *pattrib;
3778 unsigned char *pframe;
3779 struct rtw_ieee80211_hdr *pwlanhdr;
3780 unsigned short *fctrl;
3781 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3782 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3783 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3784 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3790 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3795 DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result );
3797 pattrib = &pmgntframe->attrib;
3798 update_mgntframe_attrib(padapter, pattrib);
3800 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3802 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3803 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3805 fctrl = &(pwlanhdr->frame_ctl);
3808 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3809 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3810 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3812 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3813 pmlmeext->mgnt_seq++;
3814 SetFrameSubType(pframe, WIFI_ACTION);
3816 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3817 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3819 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3820 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3821 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3822 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3823 pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
3824 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
3826 // Commented by Albert 20110328
3827 // Try to get the device password ID from the WPS IE of group negotiation request frame
3828 // WiFi Direct test plan 5.1.15
3829 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
3830 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
3831 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
3833 _rtw_memset( wpsie, 0x00, 255 );
3839 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3844 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3848 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3852 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
3854 // Device Password ID
3856 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3860 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3864 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
3866 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3868 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
3870 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3874 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3878 // Commented by Kurt 20120113
3879 // If some device wants to do p2p handshake without sending prov_disc_req
3880 // We have to get peer_req_cm from here.
3881 if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
3883 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
3885 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
3887 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
3889 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
3893 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
3897 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3904 p2pie[ p2pielen++ ] = 0x50;
3905 p2pie[ p2pielen++ ] = 0x6F;
3906 p2pie[ p2pielen++ ] = 0x9A;
3907 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
3909 // Commented by Albert 20100908
3910 // According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
3912 // 2. P2P Capability
3913 // 3. Group Owner Intent
3914 // 4. Configuration Timeout
3915 // 5. Operating Channel
3916 // 6. Intended P2P Interface Address
3919 // 9. Group ID ( Only GO )
3926 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
3929 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3933 p2pie[ p2pielen++ ] = result;
3937 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3940 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3944 // Device Capability Bitmap, 1 byte
3946 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
3948 // Commented by Albert 2011/03/08
3949 // According to the P2P specification
3950 // if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
3951 p2pie[ p2pielen++ ] = 0;
3955 // Be group owner or meet the error case
3956 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3959 // Group Capability Bitmap, 1 byte
3960 if ( pwdinfo->persistent_supported )
3962 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3966 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3969 // Group Owner Intent
3971 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3974 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3978 if ( pwdinfo->peer_intent & 0x01 )
3980 // Peer's tie breaker bit is 1, our tie breaker bit should be 0
3981 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
3985 // Peer's tie breaker bit is 0, our tie breaker bit should be 1
3986 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
3990 // Configuration Timeout
3992 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3995 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3999 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
4000 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
4002 // Operating Channel
4004 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4007 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4012 p2pie[ p2pielen++ ] = 'X';
4013 p2pie[ p2pielen++ ] = 'X';
4015 // The third byte should be set to 0x04.
4016 // Described in the "Operating Channel Attribute" section.
4017 p2pie[ p2pielen++ ] = 0x04;
4020 if ( pwdinfo->operating_channel <= 14 )
4023 p2pie[ p2pielen++ ] = 0x51;
4025 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4028 p2pie[ p2pielen++ ] = 0x73;
4033 p2pie[ p2pielen++ ] = 0x7c;
4037 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4039 // Intended P2P Interface Address
4041 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4044 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4048 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4049 p2pielen += ETH_ALEN;
4053 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4055 // Country String(3)
4056 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4057 // + number of channels in all classes
4058 len_channellist_attr = 3
4059 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4060 + get_reg_classes_full_count(pmlmeext->channel_list);
4062 #ifdef CONFIG_CONCURRENT_MODE
4063 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4065 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4069 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4073 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4080 p2pie[ p2pielen++ ] = 'X';
4081 p2pie[ p2pielen++ ] = 'X';
4083 // The third byte should be set to 0x04.
4084 // Described in the "Operating Channel Attribute" section.
4085 p2pie[ p2pielen++ ] = 0x04;
4087 // Channel Entry List
4089 #ifdef CONFIG_CONCURRENT_MODE
4090 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4092 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4093 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4096 if ( pbuddy_mlmeext->cur_channel > 14 )
4098 if ( pbuddy_mlmeext->cur_channel >= 149 )
4100 p2pie[ p2pielen++ ] = 0x7c;
4104 p2pie[ p2pielen++ ] = 0x73;
4109 p2pie[ p2pielen++ ] = 0x51;
4112 // Number of Channels
4113 // Just support 1 channel and this channel is AP's channel
4114 p2pie[ p2pielen++ ] = 1;
4117 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4122 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4124 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4126 // Number of Channels
4127 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4130 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4131 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4135 #else // CONFIG_CONCURRENT_MODE
4138 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4140 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4142 // Number of Channels
4143 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4146 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4147 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4151 #endif // CONFIG_CONCURRENT_MODE
4156 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4159 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4160 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4161 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4165 // P2P Device Address
4166 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4167 p2pielen += ETH_ALEN;
4170 // This field should be big endian. Noted by P2P specification.
4172 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4176 // Primary Device Type
4178 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4182 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4186 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4189 // Number of Secondary Device Types
4190 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4194 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4198 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4202 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4203 p2pielen += pwdinfo->device_name_len;
4205 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4207 // Group ID Attribute
4209 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4212 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4216 // p2P Device Address
4217 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4218 p2pielen += ETH_ALEN;
4221 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4222 p2pielen += pwdinfo->nego_ssidlen;
4226 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4229 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4231 pattrib->pktlen += wfdielen;
4234 pattrib->last_txcmdsz = pattrib->pktlen;
4236 dump_mgntframe(padapter, pmgntframe);
4242 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
4245 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4246 u8 action = P2P_PUB_ACTION_ACTION;
4247 u32 p2poui = cpu_to_be32(P2POUI);
4248 u8 oui_subtype = P2P_GO_NEGO_CONF;
4249 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4250 u8 wpsielen = 0, p2pielen = 0;
4252 struct xmit_frame *pmgntframe;
4253 struct pkt_attrib *pattrib;
4254 unsigned char *pframe;
4255 struct rtw_ieee80211_hdr *pwlanhdr;
4256 unsigned short *fctrl;
4257 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4258 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4259 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4260 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4265 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4270 DBG_871X( "[%s] In\n", __FUNCTION__ );
4272 pattrib = &pmgntframe->attrib;
4273 update_mgntframe_attrib(padapter, pattrib);
4275 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4277 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4278 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4280 fctrl = &(pwlanhdr->frame_ctl);
4283 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4284 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4285 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4287 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4288 pmlmeext->mgnt_seq++;
4289 SetFrameSubType(pframe, WIFI_ACTION);
4291 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4292 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4294 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4295 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4296 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4297 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4298 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4306 p2pie[ p2pielen++ ] = 0x50;
4307 p2pie[ p2pielen++ ] = 0x6F;
4308 p2pie[ p2pielen++ ] = 0x9A;
4309 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4311 // Commented by Albert 20110306
4312 // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
4314 // 2. P2P Capability
4315 // 3. Operating Channel
4317 // 5. Group ID ( if this WiFi is GO )
4321 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4324 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4328 p2pie[ p2pielen++ ] = result;
4332 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4335 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4339 // Device Capability Bitmap, 1 byte
4340 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4342 // Group Capability Bitmap, 1 byte
4343 if ( pwdinfo->persistent_supported )
4345 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4349 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4353 // Operating Channel
4355 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4358 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4363 p2pie[ p2pielen++ ] = 'X';
4364 p2pie[ p2pielen++ ] = 'X';
4366 // The third byte should be set to 0x04.
4367 // Described in the "Operating Channel Attribute" section.
4368 p2pie[ p2pielen++ ] = 0x04;
4371 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4373 if ( pwdinfo->peer_operating_ch <= 14 )
4376 p2pie[ p2pielen++ ] = 0x51;
4378 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4381 p2pie[ p2pielen++ ] = 0x73;
4386 p2pie[ p2pielen++ ] = 0x7c;
4389 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4393 if ( pwdinfo->operating_channel <= 14 )
4396 p2pie[ p2pielen++ ] = 0x51;
4398 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4401 p2pie[ p2pielen++ ] = 0x73;
4406 p2pie[ p2pielen++ ] = 0x7c;
4410 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4416 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4418 *(u16*) ( p2pie + p2pielen ) = 6;
4422 p2pie[ p2pielen++ ] = 'X';
4423 p2pie[ p2pielen++ ] = 'X';
4425 // The third byte should be set to 0x04.
4426 // Described in the "Operating Channel Attribute" section.
4427 p2pie[ p2pielen++ ] = 0x04;
4430 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4432 if ( pwdinfo->peer_operating_ch <= 14 )
4435 p2pie[ p2pielen++ ] = 0x51;
4437 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4440 p2pie[ p2pielen++ ] = 0x73;
4445 p2pie[ p2pielen++ ] = 0x7c;
4447 p2pie[ p2pielen++ ] = 1;
4448 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4452 if ( pwdinfo->operating_channel <= 14 )
4455 p2pie[ p2pielen++ ] = 0x51;
4457 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4460 p2pie[ p2pielen++ ] = 0x73;
4465 p2pie[ p2pielen++ ] = 0x7c;
4469 p2pie[ p2pielen++ ] = 1;
4470 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4473 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4475 // Group ID Attribute
4477 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4480 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4484 // p2P Device Address
4485 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4486 p2pielen += ETH_ALEN;
4489 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4490 p2pielen += pwdinfo->nego_ssidlen;
4493 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4496 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4498 pattrib->pktlen += wfdielen;
4501 pattrib->last_txcmdsz = pattrib->pktlen;
4503 dump_mgntframe(padapter, pmgntframe);
4509 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
4512 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4513 u8 action = P2P_PUB_ACTION_ACTION;
4514 u32 p2poui = cpu_to_be32(P2POUI);
4515 u8 oui_subtype = P2P_INVIT_REQ;
4516 u8 p2pie[ 255 ] = { 0x00 };
4519 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4520 u16 len_channellist_attr = 0;
4524 #ifdef CONFIG_CONCURRENT_MODE
4525 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4526 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4527 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4528 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4531 struct xmit_frame *pmgntframe;
4532 struct pkt_attrib *pattrib;
4533 unsigned char *pframe;
4534 struct rtw_ieee80211_hdr *pwlanhdr;
4535 unsigned short *fctrl;
4536 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4537 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4538 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4539 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4542 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4548 pattrib = &pmgntframe->attrib;
4549 update_mgntframe_attrib(padapter, pattrib);
4551 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4553 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4554 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4556 fctrl = &(pwlanhdr->frame_ctl);
4559 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4560 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4561 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
4563 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4564 pmlmeext->mgnt_seq++;
4565 SetFrameSubType(pframe, WIFI_ACTION);
4567 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4568 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4570 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4571 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4572 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4573 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4574 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4580 p2pie[ p2pielen++ ] = 0x50;
4581 p2pie[ p2pielen++ ] = 0x6F;
4582 p2pie[ p2pielen++ ] = 0x9A;
4583 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4585 // Commented by Albert 20101011
4586 // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
4587 // 1. Configuration Timeout
4588 // 2. Invitation Flags
4589 // 3. Operating Channel ( Only GO )
4590 // 4. P2P Group BSSID ( Should be included if I am the GO )
4593 // 7. P2P Device Info
4595 // Configuration Timeout
4597 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4600 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4604 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
4605 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
4609 p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
4612 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4616 p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
4619 // Operating Channel
4621 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4624 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4629 p2pie[ p2pielen++ ] = 'X';
4630 p2pie[ p2pielen++ ] = 'X';
4632 // The third byte should be set to 0x04.
4633 // Described in the "Operating Channel Attribute" section.
4634 p2pie[ p2pielen++ ] = 0x04;
4637 if ( pwdinfo->invitereq_info.operating_ch <= 14 )
4638 p2pie[ p2pielen++ ] = 0x51;
4639 else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
4640 p2pie[ p2pielen++ ] = 0x73;
4642 p2pie[ p2pielen++ ] = 0x7c;
4645 p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number
4647 if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
4651 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
4654 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4658 // P2P Device Address for GO
4659 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
4660 p2pielen += ETH_ALEN;
4665 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4669 // Country String(3)
4670 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4671 // + number of channels in all classes
4672 len_channellist_attr = 3
4673 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4674 + get_reg_classes_full_count(pmlmeext->channel_list);
4676 #ifdef CONFIG_CONCURRENT_MODE
4677 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4679 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4683 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4687 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4694 p2pie[ p2pielen++ ] = 'X';
4695 p2pie[ p2pielen++ ] = 'X';
4697 // The third byte should be set to 0x04.
4698 // Described in the "Operating Channel Attribute" section.
4699 p2pie[ p2pielen++ ] = 0x04;
4701 // Channel Entry List
4702 #ifdef CONFIG_CONCURRENT_MODE
4703 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4705 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4706 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4709 if ( pbuddy_mlmeext->cur_channel > 14 )
4711 if ( pbuddy_mlmeext->cur_channel >= 149 )
4713 p2pie[ p2pielen++ ] = 0x7c;
4717 p2pie[ p2pielen++ ] = 0x73;
4722 p2pie[ p2pielen++ ] = 0x51;
4725 // Number of Channels
4726 // Just support 1 channel and this channel is AP's channel
4727 p2pie[ p2pielen++ ] = 1;
4730 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4735 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4737 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4739 // Number of Channels
4740 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4743 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4744 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4748 #else // CONFIG_CONCURRENT_MODE
4751 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4753 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4755 // Number of Channels
4756 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4759 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4760 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4764 #endif // CONFIG_CONCURRENT_MODE
4769 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4772 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
4776 // P2P Device Address for GO
4777 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
4778 p2pielen += ETH_ALEN;
4781 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
4782 p2pielen += pwdinfo->invitereq_info.ssidlen;
4787 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4790 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4791 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4792 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4796 // P2P Device Address
4797 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4798 p2pielen += ETH_ALEN;
4801 // This field should be big endian. Noted by P2P specification.
4802 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
4805 // Primary Device Type
4807 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4811 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4815 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4818 // Number of Secondary Device Types
4819 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4823 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4827 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4831 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
4832 p2pielen += pwdinfo->device_name_len;
4834 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4837 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
4839 pattrib->pktlen += wfdielen;
4842 pattrib->last_txcmdsz = pattrib->pktlen;
4844 dump_mgntframe(padapter, pmgntframe);
4850 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
4853 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4854 u8 action = P2P_PUB_ACTION_ACTION;
4855 u32 p2poui = cpu_to_be32(P2POUI);
4856 u8 oui_subtype = P2P_INVIT_RESP;
4857 u8 p2pie[ 255 ] = { 0x00 };
4859 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4860 u16 len_channellist_attr = 0;
4861 #ifdef CONFIG_CONCURRENT_MODE
4862 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4863 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4864 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4865 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4871 struct xmit_frame *pmgntframe;
4872 struct pkt_attrib *pattrib;
4873 unsigned char *pframe;
4874 struct rtw_ieee80211_hdr *pwlanhdr;
4875 unsigned short *fctrl;
4876 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4877 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4878 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4879 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4882 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4888 pattrib = &pmgntframe->attrib;
4889 update_mgntframe_attrib(padapter, pattrib);
4891 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4893 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4894 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4896 fctrl = &(pwlanhdr->frame_ctl);
4899 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4900 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4901 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
4903 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4904 pmlmeext->mgnt_seq++;
4905 SetFrameSubType(pframe, WIFI_ACTION);
4907 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4908 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4910 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4911 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4912 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4913 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4914 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4920 p2pie[ p2pielen++ ] = 0x50;
4921 p2pie[ p2pielen++ ] = 0x6F;
4922 p2pie[ p2pielen++ ] = 0x9A;
4923 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4925 // Commented by Albert 20101005
4926 // According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
4928 // 2. Configuration Timeout
4929 // 3. Operating Channel ( Only GO )
4930 // 4. P2P Group BSSID ( Only GO )
4935 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4938 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4942 // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
4943 // Sent the event receiving the P2P Invitation Req frame to DMP UI.
4944 // DMP had to compare the MAC address to find out the profile.
4945 // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
4946 // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
4947 // to NB to rebuild the persistent group.
4948 p2pie[ p2pielen++ ] = status_code;
4950 // Configuration Timeout
4952 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4955 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4959 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
4960 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
4962 if( status_code == P2P_STATUS_SUCCESS )
4964 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
4966 // The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
4967 // In this case, the P2P Invitation response frame should carry the two more P2P attributes.
4968 // First one is operating channel attribute.
4969 // Second one is P2P Group BSSID attribute.
4971 // Operating Channel
4973 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4976 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4981 p2pie[ p2pielen++ ] = 'X';
4982 p2pie[ p2pielen++ ] = 'X';
4984 // The third byte should be set to 0x04.
4985 // Described in the "Operating Channel Attribute" section.
4986 p2pie[ p2pielen++ ] = 0x04;
4989 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
4992 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4997 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5000 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5004 // P2P Device Address for GO
5005 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5006 p2pielen += ETH_ALEN;
5012 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5015 // Country String(3)
5016 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5017 // + number of channels in all classes
5018 len_channellist_attr = 3
5019 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5020 + get_reg_classes_full_count(pmlmeext->channel_list);
5022 #ifdef CONFIG_CONCURRENT_MODE
5023 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5025 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5029 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5033 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5040 p2pie[ p2pielen++ ] = 'X';
5041 p2pie[ p2pielen++ ] = 'X';
5043 // The third byte should be set to 0x04.
5044 // Described in the "Operating Channel Attribute" section.
5045 p2pie[ p2pielen++ ] = 0x04;
5047 // Channel Entry List
5048 #ifdef CONFIG_CONCURRENT_MODE
5049 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5051 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5052 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5055 if ( pbuddy_mlmeext->cur_channel > 14 )
5057 if ( pbuddy_mlmeext->cur_channel >= 149 )
5059 p2pie[ p2pielen++ ] = 0x7c;
5063 p2pie[ p2pielen++ ] = 0x73;
5068 p2pie[ p2pielen++ ] = 0x51;
5071 // Number of Channels
5072 // Just support 1 channel and this channel is AP's channel
5073 p2pie[ p2pielen++ ] = 1;
5076 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5081 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5083 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5085 // Number of Channels
5086 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5089 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5090 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5094 #else // CONFIG_CONCURRENT_MODE
5097 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5099 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5101 // Number of Channels
5102 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5105 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5106 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5110 #endif // CONFIG_CONCURRENT_MODE
5113 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5116 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5118 pattrib->pktlen += wfdielen;
5121 pattrib->last_txcmdsz = pattrib->pktlen;
5123 dump_mgntframe(padapter, pmgntframe);
5129 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
5131 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5132 u8 action = P2P_PUB_ACTION_ACTION;
5134 u32 p2poui = cpu_to_be32(P2POUI);
5135 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
5136 u8 wpsie[ 100 ] = { 0x00 };
5143 struct xmit_frame *pmgntframe;
5144 struct pkt_attrib *pattrib;
5145 unsigned char *pframe;
5146 struct rtw_ieee80211_hdr *pwlanhdr;
5147 unsigned short *fctrl;
5148 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5149 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5150 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5151 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5154 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5159 DBG_871X( "[%s] In\n", __FUNCTION__ );
5161 pattrib = &pmgntframe->attrib;
5162 update_mgntframe_attrib(padapter, pattrib);
5164 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5166 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5167 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5169 fctrl = &(pwlanhdr->frame_ctl);
5172 _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5173 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5174 _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5176 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5177 pmlmeext->mgnt_seq++;
5178 SetFrameSubType(pframe, WIFI_ACTION);
5180 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5181 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5183 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5184 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5185 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5186 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5187 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5189 p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
5192 pattrib->pktlen += p2pielen;
5196 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5201 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5205 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5209 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5213 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5217 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5221 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
5224 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5228 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5230 pattrib->pktlen += wfdielen;
5233 pattrib->last_txcmdsz = pattrib->pktlen;
5235 dump_mgntframe(padapter, pmgntframe);
5242 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
5244 u8 i, match_result = 0;
5246 DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5247 peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
5249 for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
5251 DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5252 profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
5253 if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
5256 DBG_871X( "[%s] Match!\n", __FUNCTION__ );
5261 return (match_result );
5264 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5266 struct xmit_frame *pmgntframe;
5267 struct pkt_attrib *pattrib;
5268 unsigned char *pframe;
5269 struct rtw_ieee80211_hdr *pwlanhdr;
5270 unsigned short *fctrl;
5272 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5273 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5274 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5275 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5276 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5277 u16 beacon_interval = 100;
5279 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5280 u8 wpsie[255] = { 0x00 };
5281 u32 wpsielen = 0, p2pielen = 0;
5285 #ifdef CONFIG_INTEL_WIDI
5286 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5287 #endif //CONFIG_INTEL_WIDI
5289 //DBG_871X("%s\n", __FUNCTION__);
5291 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5297 pattrib = &pmgntframe->attrib;
5298 update_mgntframe_attrib(padapter, pattrib);
5300 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5302 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5303 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5305 mac = adapter_mac_addr(padapter);
5307 fctrl = &(pwlanhdr->frame_ctl);
5309 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5310 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5312 // Use the device address for BSSID field.
5313 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5315 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5316 pmlmeext->mgnt_seq++;
5317 SetFrameSubType(fctrl, WIFI_PROBERSP);
5319 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5320 pattrib->pktlen = pattrib->hdrlen;
5321 pframe += pattrib->hdrlen;
5323 //timestamp will be inserted by hardware
5325 pattrib->pktlen += 8;
5327 // beacon interval: 2 bytes
5328 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5330 pattrib->pktlen += 2;
5332 // capability info: 2 bytes
5333 // ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
5334 capInfo |= cap_ShortPremble;
5335 capInfo |= cap_ShortSlot;
5337 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5339 pattrib->pktlen += 2;
5343 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5345 // supported rates...
5346 // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5347 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5350 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5352 #ifdef CONFIG_IOCTL_CFG80211
5353 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5355 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
5358 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5359 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5360 pframe += pmlmepriv->wps_probe_resp_ie_len;
5363 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5364 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5365 pframe += pmlmepriv->p2p_probe_resp_ie_len;
5369 #endif //CONFIG_IOCTL_CFG80211
5373 // Noted by Albert 20100907
5374 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
5378 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5383 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5387 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5391 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5393 #ifdef CONFIG_INTEL_WIDI
5394 // Commented by Kurt
5395 // Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
5396 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5397 || pmlmepriv->num_p2p_sdt != 0 )
5400 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
5404 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5409 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
5413 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
5416 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
5419 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
5422 _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
5423 wpsielen += L2SDTA_SERVICE_VE_LEN;
5426 #endif //CONFIG_INTEL_WIDI
5428 // WiFi Simple Config State
5430 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
5434 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5438 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; // Not Configured.
5442 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
5446 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5450 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5454 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5458 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5462 if (pwdinfo->external_uuid == 0) {
5463 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
5464 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5466 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5472 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
5476 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
5480 _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
5485 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
5489 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
5493 _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
5498 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
5502 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5506 wpsie[ wpsielen++ ] = 0x31; // character 1
5510 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
5514 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
5518 _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
5519 wpsielen += ETH_ALEN;
5521 // Primary Device Type
5523 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5527 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5532 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5536 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
5540 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5545 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5549 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
5553 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
5554 wpsielen += pwdinfo->device_name_len;
5558 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5562 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5566 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
5570 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5573 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
5575 pattrib->pktlen += p2pielen;
5579 #ifdef CONFIG_IOCTL_CFG80211
5580 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
5581 #endif //CONFIG_IOCTL_CFG80211
5583 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
5585 pattrib->pktlen += wfdielen;
5587 #ifdef CONFIG_IOCTL_CFG80211
5588 else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
5591 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
5592 pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
5593 pframe += pmlmepriv->wfd_probe_resp_ie_len;
5595 #endif //CONFIG_IOCTL_CFG80211
5598 pattrib->last_txcmdsz = pattrib->pktlen;
5601 dump_mgntframe(padapter, pmgntframe);
5607 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
5610 struct xmit_frame *pmgntframe;
5611 struct pkt_attrib *pattrib;
5612 unsigned char *pframe;
5613 struct rtw_ieee80211_hdr *pwlanhdr;
5614 unsigned short *fctrl;
5616 unsigned char bssrate[NumRates];
5617 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5618 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5619 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5620 int bssrate_len = 0;
5621 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5622 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5623 u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
5624 u16 wpsielen = 0, p2pielen = 0;
5629 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5632 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5638 pattrib = &pmgntframe->attrib;
5639 update_mgntframe_attrib(padapter, pattrib);
5642 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5644 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5645 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5647 mac = adapter_mac_addr(padapter);
5649 fctrl = &(pwlanhdr->frame_ctl);
5653 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5654 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
5656 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
5658 // This two flags will be set when this is only the P2P client mode.
5659 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
5660 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
5664 // broadcast probe request frame
5665 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5666 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
5669 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5671 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5672 pmlmeext->mgnt_seq++;
5673 SetFrameSubType(pframe, WIFI_PROBEREQ);
5675 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
5676 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
5678 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
5680 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
5684 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
5686 // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
5687 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5689 #ifdef CONFIG_IOCTL_CFG80211
5690 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5692 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
5695 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
5696 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
5697 pframe += pmlmepriv->wps_probe_req_ie_len;
5700 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
5701 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
5702 pframe += pmlmepriv->p2p_probe_req_ie_len;
5706 #endif //CONFIG_IOCTL_CFG80211
5710 // Noted by Albert 20110221
5711 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
5715 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5720 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5724 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5728 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5730 if( pmlmepriv->wps_probe_req_ie == NULL )
5734 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5738 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5742 if (pwdinfo->external_uuid == 0) {
5743 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
5744 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5746 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5752 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5756 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5760 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
5766 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5770 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
5774 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
5775 wpsielen += pwdinfo->device_name_len;
5777 // Primary Device Type
5779 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5783 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5788 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
5792 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
5796 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
5799 // Device Password ID
5801 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
5805 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5809 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified
5812 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5816 p2pie[ p2pielen++ ] = 0x50;
5817 p2pie[ p2pielen++ ] = 0x6F;
5818 p2pie[ p2pielen++ ] = 0x9A;
5819 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
5821 // Commented by Albert 20110221
5822 // According to the P2P Specification, the probe request frame should contain 5 P2P attributes
5823 // 1. P2P Capability
5824 // 2. P2P Device ID if this probe request wants to find the specific P2P device
5825 // 3. Listen Channel
5826 // 4. Extended Listen Timing
5827 // 5. Operating Channel if this WiFi is working as the group owner now
5831 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
5834 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5838 // Device Capability Bitmap, 1 byte
5839 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
5841 // Group Capability Bitmap, 1 byte
5842 if ( pwdinfo->persistent_supported )
5843 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
5845 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
5849 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
5852 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5857 p2pie[ p2pielen++ ] = 'X';
5858 p2pie[ p2pielen++ ] = 'X';
5860 // The third byte should be set to 0x04.
5861 // Described in the "Operating Channel Attribute" section.
5862 p2pie[ p2pielen++ ] = 0x04;
5865 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
5868 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listen channel
5871 // Extended Listen Timing
5873 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
5876 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
5880 // Availability Period
5881 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
5884 // Availability Interval
5885 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
5888 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
5890 // Operating Channel (if this WiFi is working as the group owner now)
5892 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5895 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5900 p2pie[ p2pielen++ ] = 'X';
5901 p2pie[ p2pielen++ ] = 'X';
5903 // The third byte should be set to 0x04.
5904 // Described in the "Operating Channel Attribute" section.
5905 p2pie[ p2pielen++ ] = 0x04;
5908 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
5911 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
5915 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5920 #ifdef CONFIG_IOCTL_CFG80211
5921 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
5924 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
5926 pattrib->pktlen += wfdielen;
5928 #ifdef CONFIG_IOCTL_CFG80211
5929 else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
5932 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
5933 pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
5934 pframe += pmlmepriv->wfd_probe_req_ie_len;
5936 #endif //CONFIG_IOCTL_CFG80211
5939 pattrib->last_txcmdsz = pattrib->pktlen;
5941 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
5944 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
5946 dump_mgntframe(padapter, pmgntframe);
5954 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
5956 _issue_probereq_p2p(adapter, da, _FALSE);
5959 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
5963 u32 start = rtw_get_current_time();
5967 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
5971 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
5974 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
5975 rtw_msleep_os(wait_ms);
5977 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
5981 #ifndef DBG_XMIT_ACK
5986 if (try_cnt && wait_ms) {
5988 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
5989 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
5990 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
5992 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
5993 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
5994 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6002 s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
6004 _adapter *adapter = recv_frame->u.hdr.adapter;
6005 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6006 u8 *frame = recv_frame->u.hdr.rx_data;
6007 u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
6008 (recv_frame->u.hdr.attrib.frag_num & 0xf);
6010 if (GetRetry(frame)) {
6012 if ((seq_ctrl == mlmeext->action_public_rxseq)
6013 && (token == mlmeext->action_public_dialog_token))
6015 DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6016 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6020 if (seq_ctrl == mlmeext->action_public_rxseq) {
6021 DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
6022 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
6028 mlmeext->action_public_rxseq = seq_ctrl;
6031 mlmeext->action_public_dialog_token = token;
6036 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6038 _adapter *padapter = precv_frame->u.hdr.adapter;
6039 u8 *pframe = precv_frame->u.hdr.rx_data;
6040 uint len = precv_frame->u.hdr.len;
6045 u32 p2p_ielen, wps_ielen;
6046 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6047 u8 result = P2P_STATUS_SUCCESS;
6048 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6049 u8 *merged_p2pie = NULL;
6050 u32 merged_p2p_ielen= 0;
6053 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6055 dialogToken = frame_body[7];
6057 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
6061 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
6062 #ifdef CONFIG_IOCTL_CFG80211
6063 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6065 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
6068 #endif //CONFIG_IOCTL_CFG80211
6070 // Do nothing if the driver doesn't enable the P2P function.
6071 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6074 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6076 switch( frame_body[ 6 ] )//OUI Subtype
6078 case P2P_GO_NEGO_REQ:
6080 DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6081 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
6083 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6085 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6088 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6090 // Commented by Albert 20110526
6091 // In this case, this means the previous nego fail doesn't be reset yet.
6092 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6093 // Restore the previous p2p state
6094 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6095 DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
6097 #ifdef CONFIG_CONCURRENT_MODE
6098 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
6100 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6102 #endif // CONFIG_CONCURRENT_MODE
6104 // Commented by Kurt 20110902
6105 //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6106 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6107 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6109 // Commented by Kurt 20120113
6110 // Get peer_dev_addr here if peer doesn't issue prov_disc frame.
6111 if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
6112 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6114 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
6115 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
6116 #ifdef CONFIG_INTEL_WIDI
6117 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6118 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6119 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6120 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6122 #endif //CONFIG_INTEL_WIDI
6124 // Commented by Albert 20110718
6125 // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
6126 #ifdef CONFIG_CONCURRENT_MODE
6127 // Commented by Albert 20120107
6128 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6129 #else // CONFIG_CONCURRENT_MODE
6130 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6131 #endif // CONFIG_CONCURRENT_MODE
6134 case P2P_GO_NEGO_RESP:
6136 DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6138 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6140 // Commented by Albert 20110425
6141 // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
6142 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6143 pwdinfo->nego_req_info.benable = _FALSE;
6144 result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
6145 issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
6146 if ( P2P_STATUS_SUCCESS == result )
6148 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6150 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6151 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6152 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6153 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6154 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6155 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6156 pwdinfo->p2p_info.scan_op_ch_only = 1;
6157 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6161 // Reset the dialog token for group negotiation frames.
6162 pwdinfo->negotiation_dialog_token = 1;
6164 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6166 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6171 DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6176 case P2P_GO_NEGO_CONF:
6178 DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6179 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
6180 if ( P2P_STATUS_SUCCESS == result )
6182 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6184 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6185 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6186 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6187 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6188 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6189 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6190 pwdinfo->p2p_info.scan_op_ch_only = 1;
6191 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6198 // Added by Albert 2010/10/05
6199 // Received the P2P Invite Request frame.
6201 DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
6202 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6204 // Parse the necessary information from the P2P Invitation Request frame.
6205 // For example: The MAC address of sending this P2P Invitation Request frame.
6206 u32 attr_contentlen = 0;
6207 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6208 struct group_id_info group_id;
6209 u8 invitation_flag = 0;
6212 merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6214 merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); // 2 is for EID and Length
6215 if (merged_p2pie == NULL)
6217 DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
6220 _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
6222 merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6224 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6225 if ( attr_contentlen )
6228 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6229 // Commented by Albert 20120510
6230 // Copy to the pwdinfo->p2p_peer_interface_addr.
6231 // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
6232 // #> iwpriv wlan0 p2p_get peer_ifa
6233 // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
6235 if ( attr_contentlen )
6237 DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6238 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6239 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6240 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
6243 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
6245 // Re-invoke the persistent group.
6247 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6248 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6249 if ( attr_contentlen )
6251 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6253 // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
6254 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
6255 rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
6256 status_code = P2P_STATUS_SUCCESS;
6260 // The p2p device sending this p2p invitation request wants to be the persistent GO.
6261 if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
6263 u8 operatingch_info[5] = { 0x00 };
6264 if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
6266 if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
6268 // The operating channel is acceptable for this device.
6269 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
6270 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6271 pwdinfo->rx_invitereq_info.operation_ch[1]= 1; //Check whether GO is operating in channel 1;
6272 pwdinfo->rx_invitereq_info.operation_ch[2]= 6; //Check whether GO is operating in channel 6;
6273 pwdinfo->rx_invitereq_info.operation_ch[3]= 11; //Check whether GO is operating in channel 11;
6274 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6275 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6276 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
6277 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6278 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6279 status_code = P2P_STATUS_SUCCESS;
6283 // The operating channel isn't supported by this device.
6284 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6285 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
6286 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6287 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6292 // Commented by Albert 20121130
6293 // Intel will use the different P2P IE to store the operating channel information
6294 // Workaround for Intel WiDi 3.5
6295 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6296 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6297 status_code = P2P_STATUS_SUCCESS;
6302 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6303 #ifdef CONFIG_INTEL_WIDI
6304 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6305 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6306 #endif //CONFIG_INTEL_WIDI
6308 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6314 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6315 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6320 // Received the invitation to join a P2P group.
6322 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6323 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6324 if ( attr_contentlen )
6326 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6328 // In this case, the GO can't be myself.
6329 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6330 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6334 // The p2p device sending this p2p invitation request wants to join an existing P2P group
6335 // Commented by Albert 2012/06/28
6336 // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
6337 // The peer device address should be the destination address for the provisioning discovery request.
6338 // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
6339 // The peer interface address should be the address for WPS mac address
6340 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6341 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6342 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
6343 status_code = P2P_STATUS_SUCCESS;
6348 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6349 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6355 DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
6356 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6359 DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
6361 pwdinfo->inviteresp_info.token = frame_body[ 7 ];
6362 issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
6363 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6365 #ifdef CONFIG_INTEL_WIDI
6366 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6367 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6368 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6369 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6371 #endif //CONFIG_INTEL_WIDI
6374 case P2P_INVIT_RESP:
6376 u8 attr_content = 0x00;
6377 u32 attr_contentlen = 0;
6379 DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
6380 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6381 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6383 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6385 if ( attr_contentlen == 1 )
6387 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
6388 pwdinfo->invitereq_info.benable = _FALSE;
6390 if ( attr_content == P2P_STATUS_SUCCESS )
6392 if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6393 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
6395 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6397 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
6401 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6402 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6407 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6408 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6413 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6414 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6417 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
6419 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6423 case P2P_DEVDISC_REQ:
6425 process_p2p_devdisc_req(pwdinfo, pframe, len);
6429 case P2P_DEVDISC_RESP:
6431 process_p2p_devdisc_resp(pwdinfo, pframe, len);
6435 case P2P_PROVISION_DISC_REQ:
6436 DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
6437 process_p2p_provdisc_req(pwdinfo, pframe, len);
6438 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6441 //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6442 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6443 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6445 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6446 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6447 #ifdef CONFIG_INTEL_WIDI
6448 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6449 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6450 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6451 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6453 #endif //CONFIG_INTEL_WIDI
6456 case P2P_PROVISION_DISC_RESP:
6457 // Commented by Albert 20110707
6458 // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
6459 DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
6460 // Commented by Albert 20110426
6461 // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
6462 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6463 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6464 process_p2p_provdisc_resp(pwdinfo, pframe);
6465 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6476 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6482 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6484 unsigned int ret = _FAIL;
6485 u8 *pframe = precv_frame->u.hdr.rx_data;
6486 uint frame_len = precv_frame->u.hdr.len;
6487 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6489 if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6490 ret = on_action_public_p2p(precv_frame);
6496 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6498 unsigned int ret = _FAIL;
6499 u8 *pframe = precv_frame->u.hdr.rx_data;
6500 uint frame_len = precv_frame->u.hdr.len;
6501 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6503 _adapter *adapter = precv_frame->u.hdr.adapter;
6507 token = frame_body[2];
6509 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
6512 #ifdef CONFIG_IOCTL_CFG80211
6513 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
6514 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
6523 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6525 unsigned int ret = _FAIL;
6526 u8 *pframe = precv_frame->u.hdr.rx_data;
6527 uint frame_len = precv_frame->u.hdr.len;
6528 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6529 u8 category, action;
6531 /* check RA matches or not */
6532 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6535 category = frame_body[0];
6536 if(category != RTW_WLAN_CATEGORY_PUBLIC)
6539 action = frame_body[1];
6541 case ACT_PUBLIC_VENDOR:
6542 ret = on_action_public_vendor(precv_frame);
6545 ret = on_action_public_default(precv_frame, action);
6553 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
6555 u8 *pframe = precv_frame->u.hdr.rx_data;
6556 uint frame_len = precv_frame->u.hdr.len;
6557 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6558 u8 category, action;
6560 /* check RA matches or not */
6561 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6564 category = frame_body[0];
6565 if(category != RTW_WLAN_CATEGORY_HT)
6568 action = frame_body[1];
6570 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
6571 #ifdef CONFIG_BEAMFORMING
6572 //DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");
6573 beamforming_get_report_frame(padapter, precv_frame);
6574 #endif //CONFIG_BEAMFORMING
6585 #ifdef CONFIG_IEEE80211W
6586 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
6588 u8 *pframe = precv_frame->u.hdr.rx_data;
6589 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
6590 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6594 DBG_871X("OnAction_sa_query\n");
6596 switch (pframe[WLAN_HDR_A3_LEN+1])
6598 case 0: //SA Query req
6599 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short));
6600 DBG_871X("OnAction_sa_query request,action=%d, tid=%04x\n", pframe[WLAN_HDR_A3_LEN+1], tid);
6601 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid);
6604 case 1: //SA Query rsp
6605 _cancel_timer_ex(&pmlmeext->sa_query_timer);
6606 DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], pframe[WLAN_HDR_A3_LEN+2]);
6614 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
6615 for(pp=0;pp< pattrib->pkt_len; pp++)
6616 printk(" %02x ", pframe[pp]);
6622 #endif //CONFIG_IEEE80211W
6624 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
6629 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
6631 #ifdef CONFIG_80211AC_VHT
6632 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
6633 u8 *pframe = precv_frame->u.hdr.rx_data;
6634 uint frame_len = precv_frame->u.hdr.len;
6635 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6636 u8 category, action;
6637 struct sta_info *psta = NULL;
6639 /* check RA matches or not */
6640 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6643 category = frame_body[0];
6644 if(category != RTW_WLAN_CATEGORY_VHT)
6647 action = frame_body[1];
6649 case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
6650 #ifdef CONFIG_BEAMFORMING
6651 //DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");
6652 beamforming_get_report_frame(padapter, precv_frame);
6653 #endif //CONFIG_BEAMFORMING
6655 case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
6656 // CategoryCode(1) + ActionCode(1) + OpModeNotification(1)
6657 //DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n");
6658 psta = rtw_get_stainfo(&padapter->stapriv, prxattrib->ta);
6660 rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
6667 #endif //CONFIG_80211AC_VHT
6672 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
6676 u8 category, OUI_Subtype, dialogToken=0;
6677 u8 *pframe = precv_frame->u.hdr.rx_data;
6678 uint len = precv_frame->u.hdr.len;
6679 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6681 //check RA matches or not
6682 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6685 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6687 category = frame_body[0];
6688 if(category != RTW_WLAN_CATEGORY_P2P)
6691 if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
6694 #ifdef CONFIG_IOCTL_CFG80211
6695 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
6697 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
6701 #endif //CONFIG_IOCTL_CFG80211
6703 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6704 OUI_Subtype = frame_body[5];
6705 dialogToken = frame_body[6];
6709 case P2P_NOTICE_OF_ABSENCE:
6713 case P2P_PRESENCE_REQUEST:
6715 process_p2p_presence_req(pwdinfo, pframe, len);
6719 case P2P_PRESENCE_RESPONSE:
6723 case P2P_GO_DISC_REQUEST:
6738 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
6741 unsigned char category;
6742 struct action_handler *ptable;
6743 unsigned char *frame_body;
6744 u8 *pframe = precv_frame->u.hdr.rx_data;
6746 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6748 category = frame_body[0];
6750 for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
6752 ptable = &OnAction_tbl[i];
6754 if(category == ptable->num)
6755 ptable->func(padapter, precv_frame);
6763 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
6766 //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
6770 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
6772 struct xmit_frame *pmgntframe;
6773 struct xmit_buf *pxmitbuf;
6776 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
6778 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
6780 if (pmgntframe == NULL) {
6781 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
6785 if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
6786 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
6787 rtw_free_xmitframe(pxmitpriv, pmgntframe);
6792 pmgntframe->frame_tag = MGNT_FRAMETAG;
6793 pmgntframe->pxmitbuf = pxmitbuf;
6794 pmgntframe->buf_addr = pxmitbuf->pbuf;
6795 pxmitbuf->priv_data = pmgntframe;
6802 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
6804 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
6807 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
6809 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
6813 /****************************************************************************
6815 Following are some TX fuctions for WiFi MLME
6817 *****************************************************************************/
6819 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
6821 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6823 pmlmeext->tx_rate = rate;
6824 //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
6827 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
6830 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6831 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6832 //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
6834 pattrib->hdrlen = 24;
6835 pattrib->nr_frags = 1;
6836 pattrib->priority = 7;
6837 pattrib->mac_id = 0;
6838 pattrib->qsel = QSLT_MGNT;
6840 pattrib->pktlen = 0;
6842 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
6843 wireless_mode = WIRELESS_11B;
6845 wireless_mode = WIRELESS_11G;
6846 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
6847 pattrib->rate = pmlmeext->tx_rate;
6849 pattrib->encrypt = _NO_PRIVACY_;
6850 pattrib->bswenc = _FALSE;
6852 pattrib->qos_en = _FALSE;
6853 pattrib->ht_en = _FALSE;
6854 pattrib->bwmode = CHANNEL_WIDTH_20;
6855 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6856 pattrib->sgi = _FALSE;
6858 pattrib->seqnum = pmlmeext->mgnt_seq;
6860 pattrib->retry_ctrl = _TRUE;
6862 pattrib->mbssid = 0;
6863 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
6867 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
6870 struct pkt_attrib *pattrib = &pmgntframe->attrib;
6872 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6874 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
6875 _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
6878 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
6880 if(padapter->bSurpriseRemoved == _TRUE ||
6881 padapter->bDriverStopped == _TRUE)
6883 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
6884 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
6888 rtw_hal_mgnt_xmit(padapter, pmgntframe);
6891 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
6895 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6896 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
6897 struct submit_ctx sctx;
6899 if(padapter->bSurpriseRemoved == _TRUE ||
6900 padapter->bDriverStopped == _TRUE)
6902 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
6903 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
6907 rtw_sctx_init(&sctx, timeout_ms);
6908 pxmitbuf->sctx = &sctx;
6910 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
6912 if (ret == _SUCCESS)
6913 ret = rtw_sctx_wait(&sctx, __func__);
6915 _enter_critical(&pxmitpriv->lock_sctx, &irqL);
6916 pxmitbuf->sctx = NULL;
6917 _exit_critical(&pxmitpriv->lock_sctx, &irqL);
6922 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
6924 #ifdef CONFIG_XMIT_ACK
6925 static u8 seq_no = 0;
6927 u32 timeout_ms = 500;// 500ms
6928 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6929 #ifdef CONFIG_CONCURRENT_MODE
6930 if (padapter->pbuddy_adapter && !padapter->isprimary)
6931 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
6934 if(padapter->bSurpriseRemoved == _TRUE ||
6935 padapter->bDriverStopped == _TRUE)
6937 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
6938 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
6942 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
6943 pxmitpriv->ack_tx = _TRUE;
6944 pxmitpriv->seq_no = seq_no++;
6945 pmgntframe->ack_report = 1;
6946 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
6947 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
6950 pxmitpriv->ack_tx = _FALSE;
6951 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
6954 #else //!CONFIG_XMIT_ACK
6955 dump_mgntframe(padapter, pmgntframe);
6958 #endif //!CONFIG_XMIT_ACK
6961 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6967 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6969 //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
6971 if(ssid_ie && ssid_len_ori>0)
6973 switch(hidden_ssid_mode)
6977 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6980 remain_len = ies_len -(next_ie-ies);
6983 _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
6984 len_diff -= ssid_len_ori;
6989 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6999 void issue_beacon(_adapter *padapter, int timeout_ms)
7001 struct xmit_frame *pmgntframe;
7002 struct pkt_attrib *pattrib;
7003 unsigned char *pframe;
7004 struct rtw_ieee80211_hdr *pwlanhdr;
7005 unsigned short *fctrl;
7006 unsigned int rate_len;
7007 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7008 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7010 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7011 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7012 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7013 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7014 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7015 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7017 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7021 //DBG_871X("%s\n", __FUNCTION__);
7023 #ifdef CONFIG_BCN_ICF
7024 if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL)
7026 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7029 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7032 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7033 _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7034 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7037 pattrib = &pmgntframe->attrib;
7038 update_mgntframe_attrib(padapter, pattrib);
7039 pattrib->qsel = QSLT_BEACON;
7040 #ifdef CONFIG_CONCURRENT_MODE
7041 if(padapter->iface_type == IFACE_PORT1)
7042 pattrib->mbssid = 1;
7045 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7047 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7048 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7051 fctrl = &(pwlanhdr->frame_ctl);
7054 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7055 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7056 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7058 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7059 //pmlmeext->mgnt_seq++;
7060 SetFrameSubType(pframe, WIFI_BEACON);
7062 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7063 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7065 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7067 //DBG_871X("ie len=%d\n", cur_network->IELength);
7069 // for P2P : Primary Device Type & Device Name
7070 u32 wpsielen=0, insert_len=0;
7072 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
7074 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
7076 uint wps_offset, remainder_ielen;
7077 u8 *premainder_ie, *pframe_wscie;
7079 wps_offset = (uint)(wpsie - cur_network->IEs);
7081 premainder_ie = wpsie + wpsielen;
7083 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7085 #ifdef CONFIG_IOCTL_CFG80211
7086 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7088 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
7090 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7091 pframe += wps_offset;
7092 pattrib->pktlen += wps_offset;
7094 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7095 pframe += pmlmepriv->wps_beacon_ie_len;
7096 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7098 //copy remainder_ie to pframe
7099 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7100 pframe += remainder_ielen;
7101 pattrib->pktlen += remainder_ielen;
7105 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7106 pframe += cur_network->IELength;
7107 pattrib->pktlen += cur_network->IELength;
7111 #endif //CONFIG_IOCTL_CFG80211
7113 pframe_wscie = pframe + wps_offset;
7114 _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
7115 pframe += (wps_offset + wpsielen);
7116 pattrib->pktlen += (wps_offset + wpsielen);
7118 //now pframe is end of wsc ie, insert Primary Device Type & Device Name
7119 // Primary Device Type
7121 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
7125 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
7130 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7134 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
7138 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7144 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7148 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
7152 _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
7153 insert_len += pwdinfo->device_name_len;
7156 //update wsc ie length
7157 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
7159 //pframe move to end
7161 pattrib->pktlen += insert_len;
7163 //copy remainder_ie to pframe
7164 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7165 pframe += remainder_ielen;
7166 pattrib->pktlen += remainder_ielen;
7173 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7174 len_diff = update_hidden_ssid(
7175 pframe+_BEACON_IE_OFFSET_
7176 , cur_network->IELength-_BEACON_IE_OFFSET_
7177 , pmlmeinfo->hidden_ssid_mode
7179 pframe += (cur_network->IELength+len_diff);
7180 pattrib->pktlen += (cur_network->IELength+len_diff);
7187 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
7188 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
7189 if (wps_ie && wps_ielen>0) {
7190 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
7193 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7195 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7199 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
7202 #ifdef CONFIG_IOCTL_CFG80211
7203 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7205 len = pmlmepriv->p2p_beacon_ie_len;
7206 if(pmlmepriv->p2p_beacon_ie && len>0)
7207 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7210 #endif //CONFIG_IOCTL_CFG80211
7212 len = build_beacon_p2p_ie(pwdinfo, pframe);
7216 pattrib->pktlen += len;
7218 #ifdef CONFIG_IOCTL_CFG80211
7219 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
7220 #endif //CONFIG_IOCTL_CFG80211
7222 len = build_beacon_wfd_ie( pwdinfo, pframe );
7224 #ifdef CONFIG_IOCTL_CFG80211
7228 if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
7230 len = pmlmepriv->wfd_beacon_ie_len;
7231 _rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
7234 #endif //CONFIG_IOCTL_CFG80211
7236 pattrib->pktlen += len;
7245 //below for ad-hoc mode
7247 //timestamp will be inserted by hardware
7249 pattrib->pktlen += 8;
7251 // beacon interval: 2 bytes
7253 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7256 pattrib->pktlen += 2;
7258 // capability info: 2 bytes
7260 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7263 pattrib->pktlen += 2;
7266 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7268 // supported rates...
7269 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7270 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7273 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7275 //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7279 // IBSS Parameter Set...
7280 //ATIMWindow = cur->Configuration.ATIMWindow;
7282 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7285 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7289 // EXTERNDED SUPPORTED RATE
7292 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7300 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7301 pmlmepriv->update_bcn = _FALSE;
7303 _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7304 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7306 if ((pattrib->pktlen + TXDESC_SIZE) > 512)
7308 DBG_871X("beacon frame too large\n");
7312 pattrib->last_txcmdsz = pattrib->pktlen;
7314 //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
7316 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7318 dump_mgntframe(padapter, pmgntframe);
7322 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7324 struct xmit_frame *pmgntframe;
7325 struct pkt_attrib *pattrib;
7326 unsigned char *pframe;
7327 struct rtw_ieee80211_hdr *pwlanhdr;
7328 unsigned short *fctrl;
7329 unsigned char *mac, *bssid;
7330 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7331 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7334 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7335 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7336 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7337 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7338 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7339 unsigned int rate_len;
7341 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7347 //DBG_871X("%s\n", __FUNCTION__);
7352 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7354 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7360 pattrib = &pmgntframe->attrib;
7361 update_mgntframe_attrib(padapter, pattrib);
7363 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7365 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7366 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7368 mac = adapter_mac_addr(padapter);
7369 bssid = cur_network->MacAddress;
7371 fctrl = &(pwlanhdr->frame_ctl);
7373 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7374 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7375 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7377 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7378 pmlmeext->mgnt_seq++;
7379 SetFrameSubType(fctrl, WIFI_PROBERSP);
7381 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7382 pattrib->pktlen = pattrib->hdrlen;
7383 pframe += pattrib->hdrlen;
7386 if(cur_network->IELength>MAX_IE_SZ)
7389 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7390 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7392 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
7394 //inerset & update wps_probe_resp_ie
7395 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
7397 uint wps_offset, remainder_ielen;
7400 wps_offset = (uint)(pwps_ie - cur_network->IEs);
7402 premainder_ie = pwps_ie + wps_ielen;
7404 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
7406 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7407 pframe += wps_offset;
7408 pattrib->pktlen += wps_offset;
7410 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
7411 if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
7413 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
7414 pframe += wps_ielen+2;
7415 pattrib->pktlen += wps_ielen+2;
7418 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
7420 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7421 pframe += remainder_ielen;
7422 pattrib->pktlen += remainder_ielen;
7427 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7428 pframe += cur_network->IELength;
7429 pattrib->pktlen += cur_network->IELength;
7432 /* retrieve SSID IE from cur_network->Ssid */
7436 sint ssid_ielen_diff;
7438 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
7440 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
7441 (pframe-ies)-_FIXED_IE_LENGTH_);
7443 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
7445 if (ssid_ie && cur_network->Ssid.SsidLength) {
7446 uint remainder_ielen;
7448 remainder_ie = ssid_ie+2;
7449 remainder_ielen = (pframe-remainder_ie);
7451 if (remainder_ielen > MAX_IE_SZ) {
7452 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
7453 remainder_ielen = MAX_IE_SZ;
7456 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
7457 _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
7458 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
7459 _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
7461 pframe += ssid_ielen_diff;
7462 pattrib->pktlen += ssid_ielen_diff;
7470 //timestamp will be inserted by hardware
7472 pattrib->pktlen += 8;
7474 // beacon interval: 2 bytes
7476 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7479 pattrib->pktlen += 2;
7481 // capability info: 2 bytes
7483 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7486 pattrib->pktlen += 2;
7488 //below for ad-hoc mode
7491 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7493 // supported rates...
7494 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7495 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7498 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7500 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7504 // IBSS Parameter Set...
7505 //ATIMWindow = cur->Configuration.ATIMWindow;
7507 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7510 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7514 // EXTERNDED SUPPORTED RATE
7517 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7526 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
7527 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
7528 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec))
7531 #ifdef CONFIG_IOCTL_CFG80211
7532 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7534 //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
7535 len = pmlmepriv->p2p_go_probe_resp_ie_len;
7536 if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
7537 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
7540 #endif //CONFIG_IOCTL_CFG80211
7542 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
7546 pattrib->pktlen += len;
7549 #ifdef CONFIG_IOCTL_CFG80211
7550 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
7551 #endif //CONFIG_IOCTL_CFG80211
7553 len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
7555 #ifdef CONFIG_IOCTL_CFG80211
7559 if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
7561 len = pmlmepriv->wfd_probe_resp_ie_len;
7562 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
7565 #endif //CONFIG_IOCTL_CFG80211
7567 pattrib->pktlen += len;
7574 #ifdef CONFIG_AUTO_AP_MODE
7576 struct sta_info *psta;
7577 struct sta_priv *pstapriv = &padapter->stapriv;
7579 DBG_871X("(%s)\n", __FUNCTION__);
7582 psta = rtw_get_stainfo(pstapriv, da);
7583 if (psta && psta->isrc && psta->pid>0)
7585 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
7586 u8 RC_INFO[14] = {0};
7587 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
7588 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
7590 DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
7591 psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
7593 //append vendor specific ie
7594 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
7595 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
7596 _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
7597 _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
7599 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
7602 #endif //CONFIG_AUTO_AP_MODE
7605 pattrib->last_txcmdsz = pattrib->pktlen;
7608 dump_mgntframe(padapter, pmgntframe);
7614 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
7617 struct xmit_frame *pmgntframe;
7618 struct pkt_attrib *pattrib;
7619 unsigned char *pframe;
7620 struct rtw_ieee80211_hdr *pwlanhdr;
7621 unsigned short *fctrl;
7623 unsigned char bssrate[NumRates];
7624 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7625 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7626 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7627 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7628 int bssrate_len = 0;
7629 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7631 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("+issue_probereq\n"));
7633 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7639 pattrib = &pmgntframe->attrib;
7640 update_mgntframe_attrib(padapter, pattrib);
7643 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7645 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7646 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7648 mac = adapter_mac_addr(padapter);
7650 fctrl = &(pwlanhdr->frame_ctl);
7655 // unicast probe request frame
7656 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7657 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
7661 // broadcast probe request frame
7662 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7663 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
7666 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7668 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7669 pmlmeext->mgnt_seq++;
7670 SetFrameSubType(pframe, WIFI_PROBEREQ);
7672 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
7673 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7676 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
7678 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
7680 get_rate_set(padapter, bssrate, &bssrate_len);
7682 if (bssrate_len > 8)
7684 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
7685 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
7689 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
7693 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
7696 //add wps_ie for wps2.0
7697 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
7699 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
7700 pframe += pmlmepriv->wps_probe_req_ie_len;
7701 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
7702 //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
7706 pattrib->last_txcmdsz = pattrib->pktlen;
7708 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
7711 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
7713 dump_mgntframe(padapter, pmgntframe);
7721 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
7723 _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
7726 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
7727 int try_cnt, int wait_ms)
7731 u32 start = rtw_get_current_time();
7735 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE);
7739 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7742 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
7743 rtw_msleep_os(wait_ms);
7745 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
7749 #ifndef DBG_XMIT_ACK
7754 if (try_cnt && wait_ms) {
7756 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
7757 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
7758 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7760 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7761 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
7762 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7768 // if psta == NULL, indiate we are station(client) now...
7769 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
7771 struct xmit_frame *pmgntframe;
7772 struct pkt_attrib *pattrib;
7773 unsigned char *pframe;
7774 struct rtw_ieee80211_hdr *pwlanhdr;
7775 unsigned short *fctrl;
7777 unsigned short val16;
7778 int use_shared_key = 0;
7779 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7780 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7781 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7783 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7789 pattrib = &pmgntframe->attrib;
7790 update_mgntframe_attrib(padapter, pattrib);
7792 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7794 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7795 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7797 fctrl = &(pwlanhdr->frame_ctl);
7800 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7801 pmlmeext->mgnt_seq++;
7802 SetFrameSubType(pframe, WIFI_AUTH);
7804 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7805 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7808 if(psta)// for AP mode
7810 #ifdef CONFIG_NATIVEAP_MLME
7812 _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
7813 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7814 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7817 // setting auth algo number
7818 val16 = (u16)psta->authalg;
7820 if(status != _STATS_SUCCESSFUL_)
7824 val16 = cpu_to_le16(val16);
7828 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
7830 // setting auth seq number
7831 val16 =(u16)psta->auth_seq;
7832 val16 = cpu_to_le16(val16);
7833 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
7835 // setting status code...
7837 val16 = cpu_to_le16(val16);
7838 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
7840 // added challenging text...
7841 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
7843 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
7849 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
7850 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7851 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
7853 // setting auth algo number
7854 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
7856 val16 = cpu_to_le16(val16);
7859 //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
7861 //setting IV for auth seq #3
7862 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
7864 //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
7865 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
7866 val32 = cpu_to_le32(val32);
7867 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
7869 pattrib->iv_len = 4;
7872 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
7874 // setting auth seq number
7875 val16 = pmlmeinfo->auth_seq;
7876 val16 = cpu_to_le16(val16);
7877 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
7880 // setting status code...
7882 val16 = cpu_to_le16(val16);
7883 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
7885 // then checking to see if sending challenging text...
7886 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
7888 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
7892 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7894 pattrib->encrypt = _WEP40_;
7896 pattrib->icv_len = 4;
7898 pattrib->pktlen += pattrib->icv_len;
7904 pattrib->last_txcmdsz = pattrib->pktlen;
7906 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
7907 DBG_871X("%s\n", __FUNCTION__);
7908 dump_mgntframe(padapter, pmgntframe);
7914 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
7916 #ifdef CONFIG_AP_MODE
7917 struct xmit_frame *pmgntframe;
7918 struct rtw_ieee80211_hdr *pwlanhdr;
7919 struct pkt_attrib *pattrib;
7920 unsigned char *pbuf, *pframe;
7922 unsigned short *fctrl;
7923 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7924 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7925 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7926 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7927 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
7928 u8 *ie = pnetwork->IEs;
7930 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7937 DBG_871X("%s\n", __FUNCTION__);
7939 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7945 pattrib = &pmgntframe->attrib;
7946 update_mgntframe_attrib(padapter, pattrib);
7949 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7951 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7952 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7954 fctrl = &(pwlanhdr->frame_ctl);
7957 _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
7958 _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
7959 _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7962 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7963 pmlmeext->mgnt_seq++;
7964 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
7965 SetFrameSubType(pwlanhdr, pkt_type);
7969 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7970 pattrib->pktlen += pattrib->hdrlen;
7971 pframe += pattrib->hdrlen;
7974 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
7976 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
7978 status = cpu_to_le16(status);
7979 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&status, &(pattrib->pktlen));
7981 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
7982 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
7984 if (pstat->bssratelen <= 8)
7986 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
7990 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
7991 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
7994 #ifdef CONFIG_80211N_HT
7995 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
7999 //FILL HT CAP INFO IE
8000 //p = hostapd_eid_ht_capabilities_info(hapd, p);
8001 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8002 if(pbuf && ie_len>0)
8004 _rtw_memcpy(pframe, pbuf, ie_len+2);
8005 pframe += (ie_len+2);
8006 pattrib->pktlen +=(ie_len+2);
8009 //FILL HT ADD INFO IE
8010 //p = hostapd_eid_ht_operation(hapd, p);
8011 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8012 if(pbuf && ie_len>0)
8014 _rtw_memcpy(pframe, pbuf, ie_len+2);
8015 pframe += (ie_len+2);
8016 pattrib->pktlen +=(ie_len+2);
8022 #ifdef CONFIG_80211AC_VHT
8023 if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option))
8028 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8029 if(pbuf && ie_len>0)
8031 _rtw_memcpy(pframe, pbuf, ie_len+2);
8032 pframe += (ie_len+2);
8033 pattrib->pktlen +=(ie_len+2);
8036 //FILL VHT OPERATION IE
8037 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8038 if(pbuf && ie_len>0)
8040 _rtw_memcpy(pframe, pbuf, ie_len+2);
8041 pframe += (ie_len+2);
8042 pattrib->pktlen +=(ie_len+2);
8045 #endif //CONFIG_80211AC_VHT
8048 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
8051 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
8053 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
8055 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
8056 if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
8058 _rtw_memcpy(pframe, pbuf, ie_len+2);
8059 pframe += (ie_len+2);
8060 pattrib->pktlen +=(ie_len+2);
8065 if ((pbuf == NULL) || (ie_len == 0))
8074 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8076 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8079 //add WPS IE ie for wps 2.0
8080 if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
8082 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8084 pframe += pmlmepriv->wps_assoc_resp_ie_len;
8085 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8089 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
8091 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
8095 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8098 pattrib->pktlen += len;
8102 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8103 #ifdef CONFIG_IOCTL_CFG80211
8104 && (_TRUE == pwdinfo->wfd_info->wfd_enable)
8105 #endif //CONFIG_IOCTL_CFG80211
8108 wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
8110 pattrib->pktlen += wfdielen;
8115 pattrib->last_txcmdsz = pattrib->pktlen;
8117 dump_mgntframe(padapter, pmgntframe);
8122 void issue_assocreq(_adapter *padapter)
8125 struct xmit_frame *pmgntframe;
8126 struct pkt_attrib *pattrib;
8127 unsigned char *pframe, *p;
8128 struct rtw_ieee80211_hdr *pwlanhdr;
8129 unsigned short *fctrl;
8130 unsigned short val16;
8131 unsigned int i, j, ie_len, index=0;
8132 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8133 PNDIS_802_11_VARIABLE_IEs pIE;
8134 struct registry_priv *pregpriv = &padapter->registrypriv;
8135 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8136 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8137 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8138 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8139 int bssrate_len = 0, sta_bssrate_len = 0;
8140 u8 vs_ie_length = 0;
8142 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8143 u8 p2pie[ 255 ] = { 0x00 };
8154 u8 pow_cap_ele[2] = { 0x00 };
8155 u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
8158 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8162 pattrib = &pmgntframe->attrib;
8163 update_mgntframe_attrib(padapter, pattrib);
8166 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8168 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8169 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8171 fctrl = &(pwlanhdr->frame_ctl);
8173 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8174 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8175 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8177 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8178 pmlmeext->mgnt_seq++;
8179 SetFrameSubType(pframe, WIFI_ASSOCREQ);
8181 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8182 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8187 _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8188 cap |= cap_SpecMgmt;
8189 _rtw_memcpy(pframe, &cap, 2);
8191 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8195 pattrib->pktlen += 2;
8198 //todo: listen interval for power saving
8199 val16 = cpu_to_le16(3);
8200 _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
8202 pattrib->pktlen += 2;
8205 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8209 if(pmlmeext->cur_channel > 14)
8211 pow_cap_ele[0] = 13; // Minimum transmit power capability
8212 pow_cap_ele[1] = 21; // Maximum transmit power capability
8213 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8215 //supported channels
8217 if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
8219 sup_ch[0] = 1; //First channel number
8220 sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel
8224 sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8225 sup_ch[idx_5g++] = 1;
8229 while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
8230 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8234 //supported rate & extended supported rate
8236 #if 1 // Check if the AP's supported rates are also supported by STA.
8237 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8238 //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
8240 if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
8242 sta_bssrate_len = 4;
8246 //for (i = 0; i < sta_bssrate_len; i++) {
8247 // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
8250 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8251 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8252 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8256 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8257 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8260 // Check if the AP's supported rates are also supported by STA.
8261 for (j=0; j < sta_bssrate_len; j++) {
8262 // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8263 if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
8264 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
8265 //DBG_871X("match i = %d, j=%d\n", i, j);
8268 //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
8272 if (j == sta_bssrate_len) {
8273 // the rate is not supported by STA
8274 DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8276 // the rate is supported by STA
8277 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8281 bssrate_len = index;
8282 DBG_871X("bssrate_len = %d\n", bssrate_len);
8284 #else // Check if the AP's supported rates are also supported by STA.
8286 get_rate_set(padapter, bssrate, &bssrate_len);
8288 for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8289 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
8291 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8294 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8297 #endif // Check if the AP's supported rates are also supported by STA.
8299 if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8300 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8301 rtw_free_xmitframe(pxmitpriv, pmgntframe);
8302 goto exit; //don't connect to AP if no joint supported rate
8306 if (bssrate_len > 8)
8308 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8309 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8311 else if (bssrate_len > 0)
8313 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8315 DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n",__FUNCTION__);
8318 //vendor specific IE, such as WPA, WMM, WPS
8319 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
8321 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8323 switch (pIE->ElementID)
8325 case _VENDOR_SPECIFIC_IE_:
8326 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8327 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8328 (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8330 vs_ie_length = pIE->Length;
8331 if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8333 //Commented by Kurt 20110629
8334 //In some older APs, WPS handshake
8335 //would be fail if we append vender extensions informations to AP
8340 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8345 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8347 #ifdef CONFIG_80211N_HT
8348 case EID_HTCapability:
8349 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8350 if (!(is_ap_in_tkip(padapter)))
8352 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8354 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8356 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8361 case EID_EXTCapability:
8362 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8363 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8366 #endif //CONFIG_80211N_HT
8367 #ifdef CONFIG_80211AC_VHT
8368 case EID_VHTCapability:
8369 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8370 pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8374 case EID_OpModeNotification:
8375 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8376 pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
8379 #endif // CONFIG_80211AC_VHT
8384 i += (pIE->Length + 2);
8387 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8389 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8393 #ifdef CONFIG_WAPI_SUPPORT
8394 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
8400 #ifdef CONFIG_IOCTL_CFG80211
8401 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8403 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
8405 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
8406 pframe += pmlmepriv->p2p_assoc_req_ie_len;
8407 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
8411 #endif //CONFIG_IOCTL_CFG80211
8413 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
8415 // Should add the P2P IE in the association request frame.
8419 p2pie[ p2pielen++ ] = 0x50;
8420 p2pie[ p2pielen++ ] = 0x6F;
8421 p2pie[ p2pielen++ ] = 0x9A;
8422 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
8424 // Commented by Albert 20101109
8425 // According to the P2P Specification, the association request frame should contain 3 P2P attributes
8426 // 1. P2P Capability
8427 // 2. Extended Listen Timing
8429 // Commented by Albert 20110516
8434 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
8437 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
8441 // Device Capability Bitmap, 1 byte
8442 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
8444 // Group Capability Bitmap, 1 byte
8445 if ( pwdinfo->persistent_supported )
8446 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
8448 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
8450 // Extended Listen Timing
8452 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
8455 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
8459 // Availability Period
8460 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
8463 // Availability Interval
8464 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
8469 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
8472 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
8473 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
8474 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
8478 // P2P Device Address
8479 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
8480 p2pielen += ETH_ALEN;
8483 // This field should be big endian. Noted by P2P specification.
8484 if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
8485 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
8487 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
8491 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
8496 // Primary Device Type
8498 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
8502 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
8506 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
8509 // Number of Secondary Device Types
8510 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
8514 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
8518 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
8522 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
8523 p2pielen += pwdinfo->device_name_len;
8527 p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
8530 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
8534 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address
8535 p2pielen += ETH_ALEN;
8537 p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count
8539 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List
8540 p2pielen += ETH_ALEN;
8542 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
8545 //wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
8546 //pframe += wfdielen;
8547 //pattrib->pktlen += wfdielen;
8555 #ifdef CONFIG_IOCTL_CFG80211
8556 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
8557 #endif //CONFIG_IOCTL_CFG80211
8559 wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
8561 pattrib->pktlen += wfdielen;
8563 #ifdef CONFIG_IOCTL_CFG80211
8564 else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
8567 _rtw_memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
8568 pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
8569 pframe += pmlmepriv->wfd_assoc_req_ie_len;
8571 #endif //CONFIG_IOCTL_CFG80211
8574 pattrib->last_txcmdsz = pattrib->pktlen;
8575 dump_mgntframe(padapter, pmgntframe);
8580 if (ret == _SUCCESS)
8581 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
8583 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
8588 //when wait_ack is ture, this function shoule be called at process context
8589 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
8592 struct xmit_frame *pmgntframe;
8593 struct pkt_attrib *pattrib;
8594 unsigned char *pframe;
8595 struct rtw_ieee80211_hdr *pwlanhdr;
8596 unsigned short *fctrl;
8597 struct xmit_priv *pxmitpriv;
8598 struct mlme_ext_priv *pmlmeext;
8599 struct mlme_ext_info *pmlmeinfo;
8601 //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
8606 pxmitpriv = &(padapter->xmitpriv);
8607 pmlmeext = &(padapter->mlmeextpriv);
8608 pmlmeinfo = &(pmlmeext->mlmext_info);
8610 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8616 pattrib = &pmgntframe->attrib;
8617 update_mgntframe_attrib(padapter, pattrib);
8618 pattrib->retry_ctrl = _FALSE;
8620 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8622 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8623 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8625 fctrl = &(pwlanhdr->frame_ctl);
8628 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
8632 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
8642 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8643 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8644 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8646 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8647 pmlmeext->mgnt_seq++;
8648 SetFrameSubType(pframe, WIFI_DATA_NULL);
8650 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8651 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8653 pattrib->last_txcmdsz = pattrib->pktlen;
8657 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8661 dump_mgntframe(padapter, pmgntframe);
8670 * [IMPORTANT] Don't call this function in interrupt context
8672 * When wait_ms > 0, this function shoule be called at process context
8673 * da == NULL for station mode
8675 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
8679 u32 start = rtw_get_current_time();
8680 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8681 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8682 struct sta_info *psta;
8685 /* da == NULL, assum it's null data for sta to ap*/
8687 da = get_my_bssid(&(pmlmeinfo->network));
8689 psta = rtw_get_stainfo(&padapter->stapriv, da);
8692 rtw_hal_macid_sleep(padapter, psta->mac_id);
8694 rtw_hal_macid_wakeup(padapter, psta->mac_id);
8696 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
8697 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
8702 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
8706 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
8709 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8710 rtw_msleep_os(wait_ms);
8712 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8716 #ifndef DBG_XMIT_ACK
8721 if (try_cnt && wait_ms) {
8723 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8724 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8725 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8727 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8728 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8729 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8736 * [IMPORTANT] This function run in interrupt context
8738 * The null data packet would be sent without power bit,
8739 * and not guarantee success.
8741 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
8744 struct mlme_ext_priv *pmlmeext;
8745 struct mlme_ext_info *pmlmeinfo;
8748 pmlmeext = &padapter->mlmeextpriv;
8749 pmlmeinfo = &pmlmeext->mlmext_info;
8751 /* da == NULL, assum it's null data for sta to ap*/
8753 da = get_my_bssid(&(pmlmeinfo->network));
8755 ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
8760 //when wait_ack is ture, this function shoule be called at process context
8761 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
8764 struct xmit_frame *pmgntframe;
8765 struct pkt_attrib *pattrib;
8766 unsigned char *pframe;
8767 struct rtw_ieee80211_hdr *pwlanhdr;
8768 unsigned short *fctrl, *qc;
8769 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8770 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8771 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8773 DBG_871X("%s\n", __FUNCTION__);
8775 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8781 pattrib = &pmgntframe->attrib;
8782 update_mgntframe_attrib(padapter, pattrib);
8784 pattrib->hdrlen +=2;
8785 pattrib->qos_en = _TRUE;
8787 pattrib->ack_policy = 0;
8790 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8792 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8793 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8795 fctrl = &(pwlanhdr->frame_ctl);
8798 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
8802 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
8810 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
8812 SetPriority(qc, tid);
8814 SetEOSP(qc, pattrib->eosp);
8816 SetAckpolicy(qc, pattrib->ack_policy);
8818 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8819 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8820 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8822 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8823 pmlmeext->mgnt_seq++;
8824 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
8826 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8827 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8829 pattrib->last_txcmdsz = pattrib->pktlen;
8833 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8837 dump_mgntframe(padapter, pmgntframe);
8845 //when wait_ms >0 , this function shoule be called at process context
8846 //da == NULL for station mode
8847 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
8851 u32 start = rtw_get_current_time();
8852 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8853 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8855 /* da == NULL, assum it's null data for sta to ap*/
8857 da = get_my_bssid(&(pmlmeinfo->network));
8861 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
8865 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
8868 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8869 rtw_msleep_os(wait_ms);
8871 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8875 #ifndef DBG_XMIT_ACK
8880 if (try_cnt && wait_ms) {
8882 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8883 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8884 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8886 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8887 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8888 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8894 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
8896 struct xmit_frame *pmgntframe;
8897 struct pkt_attrib *pattrib;
8898 unsigned char *pframe;
8899 struct rtw_ieee80211_hdr *pwlanhdr;
8900 unsigned short *fctrl;
8901 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8902 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8903 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8906 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
8909 //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
8912 if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
8914 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
8915 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
8919 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8925 pattrib = &pmgntframe->attrib;
8926 update_mgntframe_attrib(padapter, pattrib);
8927 pattrib->retry_ctrl = _FALSE;
8929 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8931 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8932 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8934 fctrl = &(pwlanhdr->frame_ctl);
8937 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8938 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8939 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8941 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8942 pmlmeext->mgnt_seq++;
8943 SetFrameSubType(pframe, WIFI_DEAUTH);
8945 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8946 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8948 reason = cpu_to_le16(reason);
8949 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
8951 pattrib->last_txcmdsz = pattrib->pktlen;
8956 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8960 dump_mgntframe(padapter, pmgntframe);
8968 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
8970 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
8971 return _issue_deauth(padapter, da, reason, _FALSE);
8974 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
8979 u32 start = rtw_get_current_time();
8983 ret = _issue_deauth(padapter, da, reason, wait_ms>0?_TRUE:_FALSE);
8987 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
8990 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8991 rtw_msleep_os(wait_ms);
8993 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8997 #ifndef DBG_XMIT_ACK
9002 if (try_cnt && wait_ms) {
9004 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9005 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9006 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9008 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9009 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9010 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9016 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9019 _list *plist, *phead;
9020 struct xmit_frame *pmgntframe;
9021 struct pkt_attrib *pattrib;
9022 unsigned char *pframe;
9023 struct rtw_ieee80211_hdr *pwlanhdr;
9024 unsigned short *fctrl;
9025 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9026 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9027 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9028 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9031 DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9032 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9034 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9038 pattrib = &pmgntframe->attrib;
9039 update_mgntframe_attrib(padapter, pattrib);
9041 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9043 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9044 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9046 fctrl = &(pwlanhdr->frame_ctl);
9049 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9050 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9051 _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9053 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9054 pmlmeext->mgnt_seq++;
9055 SetFrameSubType(pframe, WIFI_ACTION);
9057 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9058 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9060 /* category, action */
9062 u8 category, action;
9063 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9064 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9066 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9067 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9070 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9071 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9072 hal_ch_offset_to_secondary_ch_offset(ch_offset));
9074 pattrib->last_txcmdsz = pattrib->pktlen;
9076 dump_mgntframe(padapter, pmgntframe);
9080 #ifdef CONFIG_IEEE80211W
9081 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid)
9083 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
9085 struct xmit_frame *pmgntframe;
9086 struct pkt_attrib *pattrib;
9088 struct rtw_ieee80211_hdr *pwlanhdr;
9090 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9091 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9092 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9093 struct sta_info *psta;
9094 struct sta_priv *pstapriv = &padapter->stapriv;
9095 struct registry_priv *pregpriv = &padapter->registrypriv;
9098 DBG_871X("%s\n", __FUNCTION__);
9100 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9102 DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9107 pattrib = &pmgntframe->attrib;
9108 update_mgntframe_attrib(padapter, pattrib);
9110 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9112 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9113 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9115 fctrl = &(pwlanhdr->frame_ctl);
9119 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9121 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9122 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9123 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9125 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9126 pmlmeext->mgnt_seq++;
9127 SetFrameSubType(pframe, WIFI_ACTION);
9129 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9130 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9132 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9133 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9137 case 0: //SA Query req
9138 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9139 pmlmeext->sa_query_seq++;
9140 //send sa query request to AP, AP should reply sa query response in 1 second
9141 set_sa_query_timer(pmlmeext, 1000);
9144 case 1: //SA Query rsp
9145 tid = cpu_to_le16(tid);
9146 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9152 pattrib->last_txcmdsz = pattrib->pktlen;
9154 dump_mgntframe(padapter, pmgntframe);
9156 #endif //CONFIG_IEEE80211W
9159 * issue_action_ba - internal function to TX Block Ack action frame
9160 * @padapter: the adapter to TX
9161 * @raddr: receiver address
9162 * @action: Block Ack Action
9164 * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9165 * @status: status/reason code. used by ADDBA_RESP, DELBA
9166 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9167 * @wait_ack: used xmit ack
9170 * _SUCCESS: No xmit ack is used or acked
9171 * _FAIL: not acked when using xmit ack
9173 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9174 , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9177 u8 category = RTW_WLAN_CATEGORY_BACK;
9180 u16 BA_timeout_value;
9181 u16 BA_starting_seqctrl;
9182 struct xmit_frame *pmgntframe;
9183 struct pkt_attrib *pattrib;
9185 struct rtw_ieee80211_hdr *pwlanhdr;
9187 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9188 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9189 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9190 struct sta_info *psta;
9191 struct sta_priv *pstapriv = &padapter->stapriv;
9192 struct registry_priv *pregpriv = &padapter->registrypriv;
9194 #ifdef CONFIG_80211N_HT
9196 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9200 pattrib = &pmgntframe->attrib;
9201 update_mgntframe_attrib(padapter, pattrib);
9203 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9205 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9206 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9208 fctrl = &(pwlanhdr->frame_ctl);
9211 //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9212 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9213 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9214 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9216 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9217 pmlmeext->mgnt_seq++;
9218 SetFrameSubType(pframe, WIFI_ACTION);
9220 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9221 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9223 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9224 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9230 case RTW_WLAN_ACTION_ADDBA_REQ:
9232 pmlmeinfo->dialogToken++;
9233 } while (pmlmeinfo->dialogToken == 0);
9234 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9236 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9237 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9239 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9242 BA_para_set = cpu_to_le16(BA_para_set);
9243 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9245 //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
9246 BA_timeout_value = 5000;//~ 5ms
9247 BA_timeout_value = cpu_to_le16(BA_timeout_value);
9248 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9250 //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
9251 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
9253 start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1;
9255 DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9257 psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9259 BA_starting_seqctrl = start_seq << 4;
9262 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9263 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9266 case RTW_WLAN_ACTION_ADDBA_RESP:
9267 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9268 status = cpu_to_le16(status);
9269 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9271 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9273 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9274 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9276 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9277 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9279 if (!padapter->registrypriv.wifi_spec) {
9280 if(pregpriv->ampdu_amsdu==0)//disabled
9281 BA_para_set &= ~BIT(0);
9282 else if(pregpriv->ampdu_amsdu==1)//enabled
9283 BA_para_set |= BIT(0);
9286 BA_para_set = cpu_to_le16(BA_para_set);
9288 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9289 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9292 case RTW_WLAN_ACTION_DELBA:
9294 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9295 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9297 BA_para_set = cpu_to_le16(BA_para_set);
9298 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9299 status = cpu_to_le16(status);
9300 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9307 pattrib->last_txcmdsz = pattrib->pktlen;
9310 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9312 dump_mgntframe(padapter, pmgntframe);
9317 #endif //CONFIG_80211N_HT
9322 * issue_addba_req - TX ADDBA_REQ
9323 * @adapter: the adapter to TX
9324 * @ra: receiver address
9327 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
9329 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
9336 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
9337 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
9342 * issue_addba_rsp - TX ADDBA_RESP
9343 * @adapter: the adapter to TX
9344 * @ra: receiver address
9346 * @status: status code
9347 * @size: the announced AMPDU buffer size
9349 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
9351 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9358 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
9359 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
9363 * issue_del_ba - TX DELBA
9364 * @adapter: the adapter to TX
9365 * @ra: receiver address
9367 * @reason: reason code
9368 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9370 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
9372 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
9379 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
9380 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
9384 * issue_del_ba_ex - TX DELBA with xmit ack options
9385 * @adapter: the adapter to TX
9386 * @ra: receiver address
9388 * @reason: reason code
9389 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9390 * @try_cnt: the max driver level TX count to try
9391 * @wait_ms: the waiting ms for each driver level TX
9393 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
9394 , int try_cnt, int wait_ms)
9398 u32 start = rtw_get_current_time();
9401 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
9406 , wait_ms > 0?_TRUE:_FALSE
9411 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
9414 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9415 rtw_msleep_os(wait_ms);
9417 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9421 #ifndef DBG_XMIT_ACK
9426 if (try_cnt && wait_ms) {
9427 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
9428 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
9429 , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9435 static void issue_action_BSSCoexistPacket(_adapter *padapter)
9438 _list *plist, *phead;
9439 unsigned char category, action;
9440 struct xmit_frame *pmgntframe;
9441 struct pkt_attrib *pattrib;
9442 unsigned char *pframe;
9443 struct rtw_ieee80211_hdr *pwlanhdr;
9444 unsigned short *fctrl;
9445 struct wlan_network *pnetwork = NULL;
9446 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9447 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9448 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9449 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9450 _queue *queue = &(pmlmepriv->scanned_queue);
9451 u8 InfoContent[16] = {0};
9453 #ifdef CONFIG_80211N_HT
9454 if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
9457 if(_TRUE == pmlmeinfo->bwmode_updated)
9461 DBG_871X("%s\n", __FUNCTION__);
9464 category = RTW_WLAN_CATEGORY_PUBLIC;
9465 action = ACT_PUBLIC_BSSCOEXIST;
9467 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9473 pattrib = &pmgntframe->attrib;
9474 update_mgntframe_attrib(padapter, pattrib);
9476 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9478 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9479 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9481 fctrl = &(pwlanhdr->frame_ctl);
9484 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9485 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9486 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9488 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9489 pmlmeext->mgnt_seq++;
9490 SetFrameSubType(pframe, WIFI_ACTION);
9492 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9493 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9495 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9496 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9500 if(pmlmepriv->num_FortyMHzIntolerant>0)
9504 iedata |= BIT(2);//20 MHz BSS Width Request
9506 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
9512 _rtw_memset(ICS, 0, sizeof(ICS));
9513 if(pmlmepriv->num_sta_no_ht>0)
9517 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
9519 phead = get_list_head(queue);
9520 plist = get_next(phead);
9526 WLAN_BSSID_EX *pbss_network;
9528 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
9531 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
9533 plist = get_next(plist);
9535 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
9537 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
9538 if((p==NULL) || (len==0))//non-HT
9540 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
9543 ICS[0][pbss_network->Configuration.DSConfig]=1;
9551 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
9561 //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
9570 InfoContent[k] = j; //channel number
9571 //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
9577 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
9587 pattrib->last_txcmdsz = pattrib->pktlen;
9589 dump_mgntframe(padapter, pmgntframe);
9590 #endif //CONFIG_80211N_HT
9593 // Spatial Multiplexing Powersave (SMPS) action frame
9594 int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack)
9598 unsigned char category = RTW_WLAN_CATEGORY_HT;
9599 u8 action = RTW_WLAN_ACTION_HT_SM_PS;
9600 u8 sm_power_control=0;
9601 struct xmit_frame *pmgntframe;
9602 struct pkt_attrib *pattrib;
9603 unsigned char *pframe;
9604 struct rtw_ieee80211_hdr *pwlanhdr;
9605 unsigned short *fctrl;
9606 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9607 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9608 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9611 if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED)
9613 sm_power_control = sm_power_control & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable
9615 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC)
9617 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
9618 sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode
9620 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC)
9622 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
9623 sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode
9628 DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode );
9630 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9634 pattrib = &pmgntframe->attrib;
9635 update_mgntframe_attrib(padapter, pattrib);
9637 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9639 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9640 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9642 fctrl = &(pwlanhdr->frame_ctl);
9645 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
9646 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9647 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
9649 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9650 pmlmeext->mgnt_seq++;
9651 SetFrameSubType(pframe, WIFI_ACTION);
9653 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9654 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9656 /* category, action */
9657 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9658 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9660 pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
9662 pattrib->last_txcmdsz = pattrib->pktlen;
9666 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9670 dump_mgntframe(padapter, pmgntframe);
9674 if (ret != _SUCCESS)
9675 DBG_8192C("%s, ack to\n", __func__);
9680 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
9684 u32 start = rtw_get_current_time();
9687 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE );
9691 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
9694 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9695 rtw_msleep_os(wait_ms);
9697 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9701 #ifndef DBG_XMIT_ACK
9706 if (try_cnt && wait_ms) {
9708 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
9709 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
9710 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9712 DBG_871X(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
9713 FUNC_ADPT_ARG(padapter),
9714 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9721 int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode )
9723 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
9724 return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE );
9728 * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
9729 * @adapter: the adapter to which @sta belongs
9730 * @initiator: if we are the initiator of AMPDU association
9731 * @sta: the sta to be checked
9732 * @tid: the tid to be checked
9733 * @force: cancel and send DELBA even when no AMPDU association is setup
9734 * @wait_ack: send delba with xmit ack (valid when initiator == 0)
9737 * _FAIL if sta is NULL
9738 * when initiator is 1, always _SUCCESS
9739 * when initiator is 0, _SUCCESS if DELBA is acked
9741 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
9742 , u8 force, int wait_ack)
9751 if (initiator == 0) {
9753 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
9754 u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
9756 sta->recvreorder_ctrl[tid].enable = _FALSE;
9757 sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
9759 if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
9762 ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
9764 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
9766 if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
9767 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
9769 } else if (initiator == 1) {
9771 #ifdef CONFIG_80211N_HT
9772 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
9773 sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
9774 sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
9775 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
9784 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
9787 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
9790 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
9793 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
9796 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
9798 struct sta_priv *pstapriv = &padapter->stapriv;
9799 struct sta_info *psta = NULL;
9800 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9801 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9804 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
9805 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
9808 psta = rtw_get_stainfo(pstapriv, addr);
9813 DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR");
9814 if (initiator == 1) /* originator */
9815 DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
9818 for (tid = 0; tid < TID_NUM; tid++)
9819 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
9824 unsigned int send_beacon(_adapter *padapter)
9826 u8 bxmitok = _FALSE;
9829 //#ifdef CONFIG_CONCURRENT_MODE
9830 //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9831 //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9832 //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
9833 //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
9836 #ifdef CONFIG_PCI_HCI
9837 //DBG_871X("%s\n", __FUNCTION__);
9839 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
9841 /* 8192EE Port select for Beacon DL */
9842 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
9844 issue_beacon(padapter, 0);
9849 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
9850 u32 start = rtw_get_current_time();
9852 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
9853 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
9855 issue_beacon(padapter, 100);
9859 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
9861 }while((poll%10)!=0 && _FALSE == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
9863 }while(_FALSE == bxmitok && issue<100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
9865 if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
9871 if(_FALSE == bxmitok)
9873 DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
9878 u32 passing_time = rtw_get_passing_time_ms(start);
9880 if(passing_time > 100 || issue > 3)
9881 DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
9883 // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
9892 /****************************************************************************
9894 Following are some utitity fuctions for WiFi MLME
9896 *****************************************************************************/
9898 BOOLEAN IsLegal5GChannel(
9899 IN PADAPTER Adapter,
9904 u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
9905 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
9906 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
9908 for(i=0;i<sizeof(Channel_5G);i++)
9909 if(channel == Channel_5G[i])
9914 void site_survey(_adapter *padapter)
9916 unsigned char survey_channel = 0, val8;
9917 RT_SCAN_TYPE ScanType = SCAN_PASSIVE;
9918 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9919 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9921 u32 channel_scan_time_ms = 0,val32 = 0;
9925 #ifdef CONFIG_CONCURRENT_MODE
9927 #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH)
9928 u8 stay_buddy_ch = 0;
9930 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9931 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
9932 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
9934 #endif //CONFIG_CONCURRENT_MODE
9935 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
9936 static unsigned char prev_survey_channel = 0;
9937 static unsigned int p2p_scan_count = 0;
9939 if ( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
9941 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
9943 survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
9947 survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
9949 ScanType = SCAN_ACTIVE;
9951 else if(rtw_p2p_findphase_ex_is_social(pwdinfo))
9953 // Commented by Albert 2011/06/03
9954 // The driver is in the find phase, it should go through the social channel.
9956 survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
9957 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
9958 if (ch_set_idx >= 0)
9959 ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
9961 ScanType = SCAN_ACTIVE;
9966 struct rtw_ieee80211_channel *ch;
9967 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
9968 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
9969 survey_channel = ch->hw_value;
9970 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
9976 DBG_871X(FUNC_ADPT_FMT" ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
9977 , FUNC_ADPT_ARG(padapter)
9979 , pwdinfo->find_phase_state_exchange_cnt, pmlmeext->sitesurvey_res.channel_idx
9980 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
9981 , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
9982 , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
9985 DBG_871X(FUNC_ADPT_FMT" ch:%u (cnt:%u) at %dms, %c%c%c\n"
9986 , FUNC_ADPT_ARG(padapter)
9988 , pmlmeext->sitesurvey_res.channel_idx
9989 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
9990 , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
9991 , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
9993 #endif // CONFIG_P2P
9994 #ifdef DBG_FIXED_CHAN
9995 DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
9999 if(survey_channel != 0)
10001 //PAUSE 4-AC Queue when site_survey
10002 //rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
10004 //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
10005 #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH)
10006 if ((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
10007 if (pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH) {
10008 if (pmlmeinfo->backop_cnt == 0)
10010 else if (pmlmeinfo->backop_cnt == RTW_STAY_AP_CH_MILLISECOND)
10013 if (stay_buddy_ch == 2) {
10014 pmlmeinfo->scan_cnt = 1;
10015 pmlmeinfo->backop_cnt = 0;
10016 } else if (stay_buddy_ch == 1) {
10017 pmlmeinfo->backop_cnt++;
10018 survey_channel = pbuddy_mlmeext->cur_channel;
10020 pmlmeinfo->backop_cnt++;
10021 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
10025 pmlmeinfo->scan_cnt++;
10028 if (pmlmeinfo->backop_cnt > 0) {
10030 pmlmeinfo->scan_cnt = 1;
10031 pmlmeinfo->backop_cnt = 0;
10035 if(pmlmeext->sitesurvey_res.channel_idx == 0)
10037 #ifdef DBG_FIXED_CHAN
10038 if(pmlmeext->fixed_chan !=0xff)
10039 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10042 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10046 #ifdef DBG_FIXED_CHAN
10047 if(pmlmeext->fixed_chan!=0xff)
10048 SelectChannel(padapter, pmlmeext->fixed_chan);
10051 SelectChannel(padapter, survey_channel);
10054 #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH)
10055 if( stay_buddy_ch == 1 )
10057 val8 = 0; //survey done
10058 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
10060 if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
10061 check_buddy_fwstate(padapter, _FW_LINKED))
10063 update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
10066 else if( stay_buddy_ch == 2 )
10068 val8 = 1; //under site survey
10069 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
10073 if(ScanType == SCAN_ACTIVE) //obey the channel plan setting...
10076 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
10077 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
10080 issue_probereq_p2p(padapter, NULL);
10081 issue_probereq_p2p(padapter, NULL);
10082 issue_probereq_p2p(padapter, NULL);
10085 #endif //CONFIG_P2P
10088 for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
10089 if(pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
10090 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
10091 if (padapter->registrypriv.wifi_spec)
10092 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
10094 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
10095 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
10099 if(pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
10100 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
10101 if (padapter->registrypriv.wifi_spec)
10102 issue_probereq(padapter, NULL, NULL);
10104 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
10105 issue_probereq(padapter, NULL, NULL);
10110 #if defined(CONFIG_ATMEL_RC_PATCH)
10111 // treat wlan0 & p2p0 in same way, may be changed in near feature.
10112 // assume home channel is 6, channel switch sequence will be
10113 // 1,2-6-3,4-6-5,6-6-7,8-6-9,10-6-11,12-6-13,14
10114 //if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)==_TRUE)
10116 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
10117 channel_scan_time_ms = 20;
10119 channel_scan_time_ms = 40;
10121 channel_scan_time_ms = pmlmeext->chan_scan_time;
10124 set_survey_timer(pmlmeext, channel_scan_time_ms);
10125 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
10127 struct noise_info info;
10128 info.bPauseDIG = _FALSE;
10130 info.max_time = channel_scan_time_ms/2;//ms
10131 info.chan = survey_channel;
10132 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&info, _FALSE);
10140 // channel number is 0 or this channel is not valid.
10142 #ifdef CONFIG_CONCURRENT_MODE
10147 if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0)
10150 DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
10151 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
10153 #ifdef CONFIG_IOCTL_CFG80211
10154 else if(padapter->pbuddy_adapter
10155 && pbuddy_adapter->wdinfo.driver_interface == DRIVER_CFG80211
10156 && adapter_wdev_data(pbuddy_adapter)->p2p_enabled
10157 && rtw_p2p_chk_state(&pbuddy_adapter->wdinfo, P2P_STATE_LISTEN)
10160 cur_channel = pbuddy_adapter->wdinfo.listen_channel;
10161 cur_bwmode = pbuddy_mlmeext->cur_bwmode;
10162 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
10167 cur_channel = pmlmeext->cur_channel;
10168 cur_bwmode = pmlmeext->cur_bwmode;
10169 cur_ch_offset = pmlmeext->cur_ch_offset;
10175 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
10177 if( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
10179 // Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT.
10180 // This will let the following flow to run the scanning end.
10181 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
10183 #ifdef CONFIG_DBG_P2P
10184 DBG_871X( "[%s] find phase exchange cnt = %d\n", __FUNCTION__, pwdinfo->find_phase_state_exchange_cnt );
10188 if(rtw_p2p_findphase_ex_is_needed(pwdinfo))
10190 // Set the P2P State to the listen state of find phase and set the current channel to the listen channel
10191 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10192 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
10193 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
10195 //turn on phy-dynamic functions
10196 Restore_DM_Func_Flag(padapter);
10198 initialgain = 0xff; //restore RX GAIN
10199 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
10201 _set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) );
10204 #endif //CONFIG_P2P
10207 #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH)
10208 pmlmeinfo->scan_cnt = 0;
10209 pmlmeinfo->backop_cnt = 0;
10212 #ifdef CONFIG_ANTENNA_DIVERSITY
10213 // 20100721:Interrupt scan operation here.
10214 // For SW antenna diversity before link, it needs to switch to another antenna and scan again.
10215 // It compares the scan result and select beter one to do connection.
10216 if(rtw_hal_antdiv_before_linked(padapter))
10218 pmlmeext->sitesurvey_res.bss_cnt = 0;
10219 pmlmeext->sitesurvey_res.channel_idx = -1;
10220 pmlmeext->chan_scan_time = SURVEY_TO /2;
10221 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
10227 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
10229 #ifdef CONFIG_CONCURRENT_MODE
10230 if( pwdinfo->driver_interface == DRIVER_WEXT )
10232 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
10234 _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
10237 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
10239 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
10242 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
10243 #endif //CONFIG_P2P
10245 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
10247 //switch back to the original channel
10248 //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
10251 #ifdef CONFIG_CONCURRENT_MODE
10252 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
10256 if( (pwdinfo->driver_interface == DRIVER_WEXT) && (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) )
10257 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10259 #endif //CONFIG_P2P
10260 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
10262 #endif //CONFIG_CONCURRENT_MODE
10265 //flush 4-AC Queue after site_survey
10267 //rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
10270 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10272 //turn on phy-dynamic functions
10273 Restore_DM_Func_Flag(padapter);
10275 initialgain = 0xff; //restore RX GAIN
10276 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
10279 if (is_client_associated_to_ap(padapter) == _TRUE)
10281 issue_nulldata(padapter, NULL, 0, 3, 500);
10283 #ifdef CONFIG_CONCURRENT_MODE
10284 if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
10286 DBG_871X("adapter is surveydone(buddy_adapter is linked), issue nulldata(pwrbit=0)\n");
10288 issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
10292 #ifdef CONFIG_CONCURRENT_MODE
10293 else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
10295 issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
10299 val8 = 0; //survey done
10300 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
10302 report_surveydone_event(padapter);
10304 pmlmeext->chan_scan_time = SURVEY_TO;
10305 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
10307 issue_action_BSSCoexistPacket(padapter);
10308 issue_action_BSSCoexistPacket(padapter);
10309 issue_action_BSSCoexistPacket(padapter);
10313 #ifdef CONFIG_CONCURRENT_MODE
10314 if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
10315 check_buddy_fwstate(padapter, _FW_LINKED))
10318 DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
10320 DBG_871X("restart pbuddy_adapter's beacon\n");
10322 update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
10332 //collect bss info from Beacon and Probe request/response frames.
10333 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10338 u16 val16, subtype;
10339 u8 *pframe = precv_frame->u.hdr.rx_data;
10340 u32 packet_len = precv_frame->u.hdr.len;
10342 struct registry_priv *pregistrypriv = &padapter->registrypriv;
10343 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10344 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10346 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10348 if (len > MAX_IE_SZ)
10350 //DBG_871X("IE too long for survey event\n");
10354 _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10356 subtype = GetFrameSubType(pframe);
10358 if(subtype==WIFI_BEACON) {
10359 bssid->Reserved[0] = 1;
10360 ie_offset = _BEACON_IE_OFFSET_;
10362 // FIXME : more type
10363 if (subtype == WIFI_PROBERSP) {
10364 ie_offset = _PROBERSP_IE_OFFSET_;
10365 bssid->Reserved[0] = 3;
10367 else if (subtype == WIFI_PROBEREQ) {
10368 ie_offset = _PROBEREQ_IE_OFFSET_;
10369 bssid->Reserved[0] = 2;
10372 bssid->Reserved[0] = 0;
10373 ie_offset = _FIXED_IE_LENGTH_;
10377 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10379 //below is to copy the information element
10380 bssid->IELength = len;
10381 _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10383 //get the signal strength
10384 //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
10385 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
10386 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
10387 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
10388 #ifdef CONFIG_ANTENNA_DIVERSITY
10389 //rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna));
10390 rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna);
10394 if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
10396 DBG_871X("marc: cannot find SSID for survey event\n");
10402 if (len > NDIS_802_11_LENGTH_SSID)
10404 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10407 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10408 bssid->Ssid.SsidLength = *(p + 1);
10412 bssid->Ssid.SsidLength = 0;
10415 _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10417 //checking rate info...
10419 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10422 if (len > NDIS_802_11_LENGTH_RATES_EX)
10424 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10427 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10431 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10434 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
10436 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10439 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10444 if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10446 bssid->NetworkTypeInUse = Ndis802_11DS;
10451 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10455 if (subtype == WIFI_PROBEREQ)
10459 // Set Listion Channel
10460 if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen)))
10462 u32 attr_contentlen = 0;
10463 u8 listen_ch[5] = { 0x00 };
10465 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen) != NULL)
10466 bssid->Configuration.DSConfig = listen_ch[4];
10468 return _FALSE; // Intel device maybe no bring Listen Channel
10470 { // use current channel
10471 bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10472 DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10476 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10477 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10478 bssid->Privacy = 1;
10481 #endif //CONFIG_P2P
10483 if (bssid->IELength < 12)
10486 // Checking for DSConfig
10487 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10489 bssid->Configuration.DSConfig = 0;
10490 bssid->Configuration.Length = 0;
10494 bssid->Configuration.DSConfig = *(p + 2);
10497 {// In 5G, some ap do not have DSSET IE
10498 // checking HT info for channel
10499 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10502 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10503 bssid->Configuration.DSConfig = HT_info->primary_channel;
10506 { // use current channel
10507 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
10511 _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
10512 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
10514 val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
10516 if (val16 & BIT(0))
10518 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10519 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10523 bssid->InfrastructureMode = Ndis802_11IBSS;
10524 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10527 if (val16 & BIT(4))
10528 bssid->Privacy = 1;
10530 bssid->Privacy = 0;
10532 bssid->Configuration.ATIMWindow = 0;
10534 //20/40 BSS Coexistence check
10535 if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
10537 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10538 #ifdef CONFIG_80211N_HT
10539 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10542 struct HT_caps_element *pHT_caps;
10543 pHT_caps = (struct HT_caps_element *)(p + 2);
10545 if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
10547 pmlmepriv->num_FortyMHzIntolerant++;
10552 pmlmepriv->num_sta_no_ht++;
10554 #endif //CONFIG_80211N_HT
10558 #ifdef CONFIG_INTEL_WIDI
10559 //process_intel_widi_query_or_tigger(padapter, bssid);
10560 if(process_intel_widi_query_or_tigger(padapter, bssid))
10564 #endif // CONFIG_INTEL_WIDI
10566 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10567 if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10568 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10569 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10570 , rtw_get_oper_ch(padapter)
10571 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10576 // mark bss info receving from nearby channel as SignalQuality 101
10577 if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10579 bssid->PhyInfo.SignalQuality= 101;
10585 void start_create_ibss(_adapter* padapter)
10587 unsigned short caps;
10590 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10591 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10592 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10593 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10594 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10596 //update wireless mode
10597 update_wireless_mode(padapter);
10599 //udpate capability
10600 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10601 update_capinfo(padapter, caps);
10602 if(caps&cap_IBSS)//adhoc master
10604 //set_opmode_cmd(padapter, adhoc);//removed
10607 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10609 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
10612 //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
10613 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10615 beacon_timing_control(padapter);
10617 //set msr to WIFI_FW_ADHOC_STATE
10618 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10619 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10622 if(send_beacon(padapter)==_FAIL)
10624 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
10626 report_join_res(padapter, -1);
10627 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10631 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10633 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10635 report_join_res(padapter, 1);
10636 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10637 rtw_indicate_connect(padapter);
10642 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
10645 //update bc/mc sta_info
10646 update_bmc_sta(padapter);
10650 void start_clnt_join(_adapter* padapter)
10652 unsigned short caps;
10654 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10655 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10656 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10657 int beacon_timeout;
10658 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
10660 //update wireless mode
10661 update_wireless_mode(padapter);
10663 //udpate capability
10664 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10665 update_capinfo(padapter, caps);
10667 //check if sta is ASIX peer and fix IOT issue if it is.
10668 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
10669 u8 iot_flag = _TRUE;
10670 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10675 Set_MSR(padapter, WIFI_FW_STATION_STATE);
10677 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
10679 #ifdef CONFIG_WAPI_SUPPORT
10680 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
10682 //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
10686 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10688 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10689 // Because of AP's not receiving deauth before
10690 // AP may: 1)not response auth or 2)deauth us after link is complete
10691 // issue deauth before issuing auth to deal with the situation
10693 // Commented by Albert 2012/07/21
10694 // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
10697 _queue *queue = &(padapter->mlmepriv.scanned_queue);
10698 _list *head = get_list_head(queue);
10699 _list *pos = get_next(head);
10700 struct wlan_network *scanned = NULL;
10703 bool has_p2p_ie = _FALSE;
10705 _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10707 for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
10709 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
10711 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
10712 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
10714 ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
10715 if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
10716 has_p2p_ie = _TRUE;
10721 _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10723 if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
10724 #endif /* CONFIG_P2P */
10725 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
10726 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
10728 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
10730 //here wait for receiving the beacon to start auth
10731 //and enable a timer
10732 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
10733 set_link_timer(pmlmeext, beacon_timeout);
10734 _set_timer( &padapter->mlmepriv.assoc_timer,
10735 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
10737 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
10739 else if (caps&cap_IBSS) //adhoc client
10741 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
10744 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10746 beacon_timing_control(padapter);
10748 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10750 report_join_res(padapter, 1);
10754 //DBG_871X("marc: invalid cap:%x\n", caps);
10760 void start_clnt_auth(_adapter* padapter)
10762 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10763 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10765 _cancel_timer_ex(&pmlmeext->link_timer);
10767 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
10768 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
10770 pmlmeinfo->auth_seq = 1;
10771 pmlmeinfo->reauth_count = 0;
10772 pmlmeinfo->reassoc_count = 0;
10773 pmlmeinfo->link_count = 0;
10774 pmlmeext->retry = 0;
10777 DBG_871X_LEVEL(_drv_always_, "start auth\n");
10778 issue_auth(padapter, NULL, 0);
10780 set_link_timer(pmlmeext, REAUTH_TO);
10785 void start_clnt_assoc(_adapter* padapter)
10787 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10788 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10790 _cancel_timer_ex(&pmlmeext->link_timer);
10792 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
10793 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
10795 issue_assocreq(padapter);
10797 set_link_timer(pmlmeext, REASSOC_TO);
10800 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
10802 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10803 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10805 if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
10808 DBG_871X("%s\n", __FUNCTION__);
10810 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
10812 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
10814 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10815 report_del_sta_event(padapter, MacAddr, reason);
10818 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
10820 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10821 report_join_res(padapter, -2);
10828 #ifdef CONFIG_80211D
10829 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
10831 struct registry_priv *pregistrypriv;
10832 struct mlme_ext_priv *pmlmeext;
10833 RT_CHANNEL_INFO *chplan_new;
10838 pregistrypriv = &padapter->registrypriv;
10839 pmlmeext = &padapter->mlmeextpriv;
10841 // Adjust channel plan by AP Country IE
10842 if (pregistrypriv->enable80211d &&
10843 (!pmlmeext->update_channel_plan_by_ap_done))
10847 RT_CHANNEL_PLAN chplan_ap;
10848 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
10850 u8 fcn; // first channel number
10851 u8 noc; // number of channel
10854 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
10856 if (len < 6) return;
10862 _rtw_memset(country, 0, 4);
10863 _rtw_memcpy(country, p, 3);
10865 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
10866 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
10869 while ((ie - p) >= 3)
10875 for (j = 0; j < noc; j++)
10877 if (fcn <= 14) channel = fcn + j; // 2.4 GHz
10878 else channel = fcn + j*4; // 5 GHz
10880 chplan_ap.Channel[i++] = channel;
10885 #ifdef CONFIG_DEBUG_RTL871X
10887 DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
10888 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
10890 DBG_8192C("%02d,", chplan_ap.Channel[i]);
10896 _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
10897 #ifdef CONFIG_DEBUG_RTL871X
10899 DBG_871X("%s: STA channel plan {", __FUNCTION__);
10900 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
10902 DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
10908 _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
10909 chplan_new = pmlmeext->channel_set;
10912 if (pregistrypriv->wireless_mode & WIRELESS_11G)
10915 if ((i == MAX_CHANNEL_NUM) ||
10916 (chplan_sta[i].ChannelNum == 0) ||
10917 (chplan_sta[i].ChannelNum > 14))
10920 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
10923 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
10925 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
10926 chplan_new[k].ScanType = SCAN_ACTIVE;
10931 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
10933 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
10934 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
10935 chplan_new[k].ScanType = SCAN_PASSIVE;
10939 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
10941 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
10942 chplan_new[k].ScanType = SCAN_ACTIVE;
10948 // change AP not support channel to Passive scan
10949 while ((i < MAX_CHANNEL_NUM) &&
10950 (chplan_sta[i].ChannelNum != 0) &&
10951 (chplan_sta[i].ChannelNum <= 14))
10953 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
10954 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
10955 chplan_new[k].ScanType = SCAN_PASSIVE;
10960 // add channel AP supported
10961 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
10963 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
10964 chplan_new[k].ScanType = SCAN_ACTIVE;
10971 // keep original STA 2.4G channel plan
10972 while ((i < MAX_CHANNEL_NUM) &&
10973 (chplan_sta[i].ChannelNum != 0) &&
10974 (chplan_sta[i].ChannelNum <= 14))
10976 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
10977 chplan_new[k].ScanType = chplan_sta[i].ScanType;
10982 // skip AP 2.4G channel plan
10983 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
10989 if (pregistrypriv->wireless_mode & WIRELESS_11A)
10992 if ((i >= MAX_CHANNEL_NUM) ||
10993 (chplan_sta[i].ChannelNum == 0))
10996 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
10999 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11001 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11002 chplan_new[k].ScanType = SCAN_ACTIVE;
11007 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11009 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11010 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11011 chplan_new[k].ScanType = SCAN_PASSIVE;
11015 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11017 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11018 chplan_new[k].ScanType = SCAN_ACTIVE;
11024 // change AP not support channel to Passive scan
11025 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11027 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11028 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11029 chplan_new[k].ScanType = SCAN_PASSIVE;
11034 // add channel AP supported
11035 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
11037 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11038 chplan_new[k].ScanType = SCAN_ACTIVE;
11045 // keep original STA 5G channel plan
11046 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11048 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11049 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11055 pmlmeext->update_channel_plan_by_ap_done = 1;
11057 #ifdef CONFIG_DEBUG_RTL871X
11059 DBG_871X("%s: new STA channel plan {", __FUNCTION__);
11060 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11062 DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
11069 // recover the right channel index
11070 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11072 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11074 if (chplan_new[k].ChannelNum == channel) {
11075 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11076 ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11077 __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
11078 pmlmeext->sitesurvey_res.channel_idx = k;
11086 // If channel is used by AP, set channel scan type to active
11087 channel = bssid->Configuration.DSConfig;
11088 chplan_new = pmlmeext->channel_set;
11090 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
11092 if (chplan_new[i].ChannelNum == channel)
11094 if (chplan_new[i].ScanType == SCAN_PASSIVE)
11096 //5G Bnad 2, 3 (DFS) doesn't change to active scan
11097 if(channel >= 52 && channel <= 144)
11100 chplan_new[i].ScanType = SCAN_ACTIVE;
11101 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11102 ("%s: change channel %d scan type from passive to active\n",
11103 __FUNCTION__, channel));
11112 /****************************************************************************
11114 Following are the functions to report events
11116 *****************************************************************************/
11118 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11120 struct cmd_obj *pcmd_obj;
11123 struct survey_event *psurvey_evt;
11124 struct C2HEvent_Header *pc2h_evt_hdr;
11125 struct mlme_ext_priv *pmlmeext;
11126 struct cmd_priv *pcmdpriv;
11127 //u8 *pframe = precv_frame->u.hdr.rx_data;
11128 //uint len = precv_frame->u.hdr.len;
11133 pmlmeext = &padapter->mlmeextpriv;
11134 pcmdpriv = &padapter->cmdpriv;
11137 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11142 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11143 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11145 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11149 _rtw_init_listhead(&pcmd_obj->list);
11151 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11152 pcmd_obj->cmdsz = cmdsz;
11153 pcmd_obj->parmbuf = pevtcmd;
11155 pcmd_obj->rsp = NULL;
11156 pcmd_obj->rspsz = 0;
11158 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11159 pc2h_evt_hdr->len = sizeof(struct survey_event);
11160 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11161 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11163 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11165 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
11167 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11168 rtw_mfree((u8 *)pevtcmd, cmdsz);
11172 #ifdef CONFIG_80211D
11173 process_80211d(padapter, &psurvey_evt->bss);
11176 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11178 pmlmeext->sitesurvey_res.bss_cnt++;
11184 void report_surveydone_event(_adapter *padapter)
11186 struct cmd_obj *pcmd_obj;
11189 struct surveydone_event *psurveydone_evt;
11190 struct C2HEvent_Header *pc2h_evt_hdr;
11191 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11192 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11194 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11199 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11200 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11202 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11206 _rtw_init_listhead(&pcmd_obj->list);
11208 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11209 pcmd_obj->cmdsz = cmdsz;
11210 pcmd_obj->parmbuf = pevtcmd;
11212 pcmd_obj->rsp = NULL;
11213 pcmd_obj->rspsz = 0;
11215 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11216 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11217 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11218 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11220 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11221 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11223 DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11225 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11231 void report_join_res(_adapter *padapter, int res)
11233 struct cmd_obj *pcmd_obj;
11236 struct joinbss_event *pjoinbss_evt;
11237 struct C2HEvent_Header *pc2h_evt_hdr;
11238 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11239 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11240 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11242 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11247 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11248 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11250 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11254 _rtw_init_listhead(&pcmd_obj->list);
11256 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11257 pcmd_obj->cmdsz = cmdsz;
11258 pcmd_obj->parmbuf = pevtcmd;
11260 pcmd_obj->rsp = NULL;
11261 pcmd_obj->rspsz = 0;
11263 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11264 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11265 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11266 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11268 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11269 _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11270 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
11272 DBG_871X("report_join_res(%d)\n", res);
11275 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11278 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11284 void report_wmm_edca_update(_adapter *padapter)
11286 struct cmd_obj *pcmd_obj;
11289 struct wmm_event *pwmm_event;
11290 struct C2HEvent_Header *pc2h_evt_hdr;
11291 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11292 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11293 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11295 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11300 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11301 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11303 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11307 _rtw_init_listhead(&pcmd_obj->list);
11309 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11310 pcmd_obj->cmdsz = cmdsz;
11311 pcmd_obj->parmbuf = pevtcmd;
11313 pcmd_obj->rsp = NULL;
11314 pcmd_obj->rspsz = 0;
11316 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11317 pc2h_evt_hdr->len = sizeof(struct wmm_event);
11318 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11319 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11321 pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11322 pwmm_event->wmm =0;
11324 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11330 void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
11332 struct cmd_obj *pcmd_obj;
11335 struct sta_info *psta;
11337 struct stadel_event *pdel_sta_evt;
11338 struct C2HEvent_Header *pc2h_evt_hdr;
11339 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11340 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11342 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11347 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11348 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11350 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11354 _rtw_init_listhead(&pcmd_obj->list);
11356 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11357 pcmd_obj->cmdsz = cmdsz;
11358 pcmd_obj->parmbuf = pevtcmd;
11360 pcmd_obj->rsp = NULL;
11361 pcmd_obj->rspsz = 0;
11363 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11364 pc2h_evt_hdr->len = sizeof(struct stadel_event);
11365 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11366 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11368 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11369 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11370 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
11373 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11375 mac_id = (int)psta->mac_id;
11379 pdel_sta_evt->mac_id = mac_id;
11381 DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
11383 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11388 void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
11390 struct cmd_obj *pcmd_obj;
11393 struct stassoc_event *padd_sta_evt;
11394 struct C2HEvent_Header *pc2h_evt_hdr;
11395 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11396 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11398 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11403 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11404 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11406 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11410 _rtw_init_listhead(&pcmd_obj->list);
11412 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11413 pcmd_obj->cmdsz = cmdsz;
11414 pcmd_obj->parmbuf = pevtcmd;
11416 pcmd_obj->rsp = NULL;
11417 pcmd_obj->rspsz = 0;
11419 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11420 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11421 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11422 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11424 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11425 _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11426 padd_sta_evt->cam_id = cam_idx;
11428 DBG_871X("report_add_sta_event: add STA\n");
11430 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11436 bool rtw_port_switch_chk(_adapter *adapter)
11438 bool switch_needed = _FALSE;
11439 #ifdef CONFIG_CONCURRENT_MODE
11440 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11441 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11442 struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11443 _adapter *if_port0 = NULL;
11444 _adapter *if_port1 = NULL;
11445 struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11446 struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11449 for (i = 0; i < dvobj->iface_nums; i++) {
11450 if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) {
11451 if_port0 = dvobj->padapters[i];
11452 if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11454 else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) {
11455 if_port1 = dvobj->padapters[i];
11456 if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11460 if (if_port0 == NULL) {
11465 if (if_port1 == NULL) {
11470 #ifdef DBG_RUNTIME_PORT_SWITCH
11471 DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11472 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11473 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11474 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11475 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11476 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11477 #endif /* DBG_RUNTIME_PORT_SWITCH */
11479 #ifdef CONFIG_WOWLAN
11480 /* WOWLAN interface(primary, for now) should be port0 */
11481 if (pwrctl->wowlan_mode == _TRUE) {
11482 if(!is_primary_adapter(if_port0)) {
11483 DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11484 switch_needed = _TRUE;
11488 #endif /* CONFIG_WOWLAN */
11490 /* AP should use port0 for ctl frame's ack */
11491 if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11492 DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11493 switch_needed = _TRUE;
11497 /* GC should use port0 for p2p ps */
11498 if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11499 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11500 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11501 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11503 DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11504 switch_needed = _TRUE;
11508 /* port1 linked, but port0 not linked */
11509 if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11510 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11511 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11513 DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11514 switch_needed = _TRUE;
11519 #ifdef DBG_RUNTIME_PORT_SWITCH
11520 DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11521 #endif /* DBG_RUNTIME_PORT_SWITCH */
11522 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11523 #endif /* CONFIG_CONCURRENT_MODE */
11524 return switch_needed;
11527 /****************************************************************************
11529 Following are the event callback functions
11531 *****************************************************************************/
11533 //for sta/adhoc mode
11534 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11537 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11538 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11539 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11542 VCS_update(padapter, psta);
11544 #ifdef CONFIG_80211N_HT
11546 if(pmlmepriv->htpriv.ht_option)
11548 psta->htpriv.ht_option = _TRUE;
11550 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11552 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
11554 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11555 psta->htpriv.sgi_20m = _TRUE;
11557 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11558 psta->htpriv.sgi_40m = _TRUE;
11560 psta->qos_option = _TRUE;
11562 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11563 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11564 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11566 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11569 #endif //CONFIG_80211N_HT
11571 #ifdef CONFIG_80211N_HT
11572 psta->htpriv.ht_option = _FALSE;
11574 psta->htpriv.ampdu_enable = _FALSE;
11576 psta->htpriv.sgi_20m = _FALSE;
11577 psta->htpriv.sgi_40m = _FALSE;
11578 #endif //CONFIG_80211N_HT
11579 psta->qos_option = _FALSE;
11583 #ifdef CONFIG_80211N_HT
11584 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11586 psta->htpriv.agg_enable_bitmap = 0x0;//reset
11587 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
11588 #endif //CONFIG_80211N_HT
11590 psta->bw_mode = pmlmeext->cur_bwmode;
11593 if(pmlmepriv->qospriv.qos_option)
11594 psta->qos_option = _TRUE;
11596 #ifdef CONFIG_80211AC_VHT
11597 _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11598 #endif //CONFIG_80211AC_VHT
11600 update_ldpc_stbc_cap(psta);
11602 _enter_critical_bh(&psta->lock, &irqL);
11603 psta->state = _FW_LINKED;
11604 _exit_critical_bh(&psta->lock, &irqL);
11608 static void rtw_mlmeext_disconnect(_adapter *padapter)
11610 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11611 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11612 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11613 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11614 u8 state_backup = (pmlmeinfo->state&0x03);
11615 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
11617 //set_opmode_cmd(padapter, infra_client_with_mlme);
11621 * For safety, prevent from keeping macid sleep.
11622 * If we can sure all power mode enter/leave are paired,
11623 * this check can be removed.
11626 /* wakeup macid after disconnect. */
11628 struct sta_info *psta;
11629 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork));
11631 rtw_hal_macid_wakeup(padapter, psta->mac_id);
11635 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11636 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11638 //set MSR to no link state -> infra. mode
11639 Set_MSR(padapter, _HW_STATE_STATION_);
11641 //check if sta is ASIX peer and fix IOT issue if it is.
11642 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
11643 u8 iot_flag = _FALSE;
11644 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11646 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11648 if(state_backup == WIFI_FW_STATION_STATE)
11650 if (rtw_port_switch_chk(padapter) == _TRUE) {
11651 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11654 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11656 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11662 #ifdef CONFIG_CONCURRENT_MODE
11663 if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
11664 #endif //CONFIG_CONCURRENT_MODE
11667 //switch to the 20M Hz mode after disconnect
11668 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11669 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11671 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11675 #ifdef CONFIG_FCS_MODE
11678 PADAPTER pbuddy_adapter;
11679 struct mlme_ext_priv *pbuddy_mlmeext;
11681 if(EN_FCS(padapter))
11683 pbuddy_adapter = padapter->pbuddy_adapter;
11684 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11686 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11688 //switch to buddy's channel setting if buddy is linked
11689 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
11692 #endif //!CONFIG_FCS_MODE
11695 flush_all_cam_entry(padapter);
11697 _cancel_timer_ex(&pmlmeext->link_timer);
11699 //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE;
11700 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11701 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11704 padapter->tdlsinfo.ap_prohibited = _FALSE;
11706 /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11707 if (padapter->registrypriv.wifi_spec == 1)
11709 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
11711 #endif /* CONFIG_TDLS */
11715 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
11717 struct sta_info *psta, *psta_bmc;
11718 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11719 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11720 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
11721 struct sta_priv *pstapriv = &padapter->stapriv;
11727 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11728 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11730 goto exit_mlmeext_joinbss_event_callback;
11733 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11735 //update bc/mc sta_info
11736 update_bmc_sta(padapter);
11740 //turn on dynamic functions
11741 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
11743 // update IOT-releated issue
11744 update_IOT_info(padapter);
11746 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
11749 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
11751 //udpate capability
11752 update_capinfo(padapter, pmlmeinfo->capability);
11754 //WMM, Update EDCA param
11755 WMMOnAssocRsp(padapter);
11758 HTOnAssocRsp(padapter);
11760 #ifdef CONFIG_80211AC_VHT
11762 VHTOnAssocRsp(padapter);
11765 #ifndef CONFIG_CONCURRENT_MODE
11766 // Call set_channel_bwmode when the CONFIG_CONCURRENT_MODE doesn't be defined.
11767 //Set cur_channel&cur_bwmode&cur_ch_offset
11768 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11771 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
11772 if (psta) //only for infra. mode
11774 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
11776 //DBG_871X("set_sta_rate\n");
11778 psta->wireless_mode = pmlmeext->cur_wireless_mode;
11780 //set per sta rate after updating HT cap.
11781 set_sta_rate(padapter, psta);
11783 rtw_sta_media_status_rpt(padapter, psta, 1);
11785 /* wakeup macid after join bss successfully to ensure
11786 the subsequent data frames can be sent out normally */
11787 rtw_hal_macid_wakeup(padapter, psta->mac_id);
11790 if (rtw_port_switch_chk(padapter) == _TRUE)
11791 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11794 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11796 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11799 correct_TSF(padapter, pmlmeext);
11801 //set_link_timer(pmlmeext, DISCONNECT_TO);
11805 if(get_iface_type(padapter) == IFACE_PORT0)
11806 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
11809 #ifdef CONFIG_BEAMFORMING
11811 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
11814 exit_mlmeext_joinbss_event_callback:
11816 #ifdef CONFIG_CONCURRENT_MODE
11817 concurrent_chk_joinbss_done(padapter, join_res);
11820 DBG_871X("=>%s\n", __FUNCTION__);
11824 //currently only adhoc mode will go here
11825 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
11827 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11828 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11831 DBG_871X("%s\n", __FUNCTION__);
11833 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11835 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
11842 //update_TSF(pmlmeext, pframe, len);
11845 correct_TSF(padapter, pmlmeext);
11848 if(send_beacon(padapter)==_FAIL)
11850 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
11852 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
11857 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
11862 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11865 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
11867 psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates);
11868 _rtw_memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen);
11870 //update adhoc sta_info
11871 update_sta_info(padapter, psta);
11873 rtw_hal_update_sta_rate_mask(padapter, psta);
11875 // ToDo: HT for Ad-hoc
11876 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
11877 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
11880 Update_RA_Entry(padapter, psta);
11883 void mlmeext_sta_del_event_callback(_adapter *padapter)
11885 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11886 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11888 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
11890 rtw_mlmeext_disconnect(padapter);
11895 /****************************************************************************
11897 Following are the functions for the timer handlers
11899 *****************************************************************************/
11900 void _linked_info_dump(_adapter *padapter)
11903 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11904 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11905 int UndecoratedSmoothedPWDB = 0;
11906 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
11907 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
11909 if(padapter->bLinkInfoDump){
11911 DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter));
11913 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11915 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
11917 DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
11918 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB);
11920 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
11923 _list *phead, *plist;
11925 struct sta_info *psta=NULL;
11926 struct sta_priv *pstapriv = &padapter->stapriv;
11928 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
11929 phead = &pstapriv->asoc_list;
11930 plist = get_next(phead);
11931 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
11933 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
11934 plist = get_next(plist);
11936 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n",
11937 MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB);
11939 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
11942 for(i=0; i<macid_ctl->num; i++)
11944 if(rtw_macid_is_used(macid_ctl, i)
11945 && !rtw_macid_is_bmc(macid_ctl, i) /* skip bc/mc sta */
11947 //============ tx info ============
11948 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i);
11951 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_RX_INFO_DUMP, NULL);
11959 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
11962 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11963 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11965 #ifdef DBG_EXPIRATION_CHK
11966 DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
11967 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
11969 , FUNC_ADPT_ARG(padapter)
11970 , STA_RX_PKTS_DIFF_ARG(psta)
11971 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
11972 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
11973 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
11974 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
11975 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
11976 , pmlmeinfo->bcn_interval*/
11980 DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
11981 , padapter->xmitpriv.tx_pkts
11982 , pmlmeinfo->link_count
11986 if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
11987 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
11988 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
11998 sta_update_last_rx_pkts(psta);
12004 void linked_status_chk_tdls(_adapter *padapter)
12006 struct candidate_pool{
12007 struct sta_info *psta;
12010 struct sta_priv *pstapriv = &padapter->stapriv;
12013 struct sta_info *psta;
12014 int i, num_teardown=0, num_checkalive=0;
12015 _list *plist, *phead;
12016 struct tdls_txmgmt txmgmt;
12017 struct candidate_pool checkalive[NUM_STA];
12018 struct candidate_pool teardown[NUM_STA];
12019 #define ALIVE_MIN 2
12020 #define ALIVE_MAX 5
12022 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12023 _rtw_memset(checkalive, 0x00, sizeof(checkalive));
12024 _rtw_memset(teardown, 0x00, sizeof(teardown));
12026 if((padapter->tdlsinfo.link_established == _TRUE)){
12027 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12028 for(i=0; i< NUM_STA; i++)
12030 phead = &(pstapriv->sta_hash[i]);
12031 plist = get_next(phead);
12033 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12035 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12036 plist = get_next(plist);
12038 if(psta->tdls_sta_state & TDLS_LINKED_STATE)
12040 psta->alive_count++;
12041 if(psta->alive_count >= ALIVE_MIN)
12043 #ifdef CONFIG_XMIT_ACK
12044 if(psta->sta_stats.last_rx_data_pkts >= psta->sta_stats.rx_data_pkts)
12046 if((psta->sta_stats.last_rx_data_pkts >= psta->sta_stats.rx_data_pkts) &&
12047 (!(psta->tdls_sta_state & TDLS_ALIVE_STATE)) )
12050 if(psta->alive_count < ALIVE_MAX)
12052 _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12053 checkalive[num_checkalive].psta = psta;
12058 _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12059 teardown[num_teardown].psta = psta;
12065 psta->tdls_sta_state &= (~TDLS_ALIVE_STATE);
12066 psta->alive_count = 0;
12069 psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12073 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12075 if(num_checkalive > 0)
12077 for(i=0; i< num_checkalive; i++)
12079 #ifdef CONFIG_XMIT_ACK
12080 ack_chk = issue_nulldata_to_TDLS_peer_STA(padapter, checkalive[i].addr, 0, 3, 500);
12082 if(ack_chk == _SUCCESS)
12084 checkalive[i].psta->alive_count = 0;
12087 checkalive[i].psta->tdls_sta_state &= (~TDLS_ALIVE_STATE);
12088 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12089 issue_tdls_dis_req(padapter, &txmgmt);
12090 issue_tdls_dis_req(padapter, &txmgmt);
12091 issue_tdls_dis_req(padapter, &txmgmt);
12092 #endif //CONFIG_XMIT_ACK
12096 if(num_teardown > 0)
12098 for(i=0; i< num_teardown; i++)
12100 DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12101 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12102 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12103 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12109 #endif //CONFIG_TDLS
12111 //from_timer == 1 means driver is in LPS
12112 void linked_status_chk(_adapter *padapter, u8 from_timer)
12115 struct sta_info *psta;
12116 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12117 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12118 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12119 struct sta_priv *pstapriv = &padapter->stapriv;
12122 if (is_client_associated_to_ap(padapter))
12124 //linked infrastructure client mode
12126 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12128 int link_count_limit;
12130 #if defined(DBG_ROAMING_TEST)
12132 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12138 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12141 link_count_limit = 3; // 8 sec
12143 link_count_limit = 15; // 32 sec
12146 #endif // CONFIG_P2P
12149 link_count_limit = 7; // 16 sec
12151 link_count_limit = 29; // 60 sec
12155 #ifdef CONFIG_TDLS_CH_SW
12156 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12158 #endif /* CONFIG_TDLS_CH_SW */
12160 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12161 linked_status_chk_tdls(padapter);
12162 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12163 #endif /* CONFIG_TDLS */
12165 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12167 bool is_p2p_enable = _FALSE;
12169 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12172 if (chk_ap_is_alive(padapter, psta) == _FALSE)
12175 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12178 #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12179 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
12180 u8 backup_oper_channel=0;
12182 /* switch to correct channel of current network before issue keep-alive frames */
12183 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12184 backup_oper_channel = rtw_get_oper_ch(padapter);
12185 SelectChannel(padapter, pmlmeext->cur_channel);
12188 if (rx_chk != _SUCCESS)
12189 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12191 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12192 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12193 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12194 if (tx_chk == _SUCCESS && !is_p2p_enable)
12198 /* back to the original operation channel */
12199 if(backup_oper_channel>0)
12200 SelectChannel(padapter, backup_oper_channel);
12204 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12206 if (rx_chk != _SUCCESS) {
12207 if (pmlmeext->retry == 0) {
12208 #ifdef DBG_EXPIRATION_CHK
12209 DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12211 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12212 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12213 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12217 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
12218 #ifdef DBG_EXPIRATION_CHK
12219 DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0);
12221 tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0);
12225 if (rx_chk == _FAIL) {
12227 if (pmlmeext->retry > rx_chk_limit) {
12228 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
12229 FUNC_ADPT_ARG(padapter));
12230 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12231 , WLAN_REASON_EXPIRATION_CHK);
12235 pmlmeext->retry = 0;
12238 if (tx_chk == _FAIL) {
12239 pmlmeinfo->link_count %= (link_count_limit+1);
12241 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12242 pmlmeinfo->link_count = 0;
12245 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12248 else if (is_client_associated_to_ibss(padapter))
12251 //for each assoc list entry to check the rx pkt counter
12252 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
12254 if (pmlmeinfo->FW_sta_info[i].status == 1)
12256 psta = pmlmeinfo->FW_sta_info[i].psta;
12258 if(NULL==psta) continue;
12260 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
12263 if(pmlmeinfo->FW_sta_info[i].retry<3)
12265 pmlmeinfo->FW_sta_info[i].retry++;
12269 pmlmeinfo->FW_sta_info[i].retry = 0;
12270 pmlmeinfo->FW_sta_info[i].status = 0;
12271 report_del_sta_event(padapter, psta->hwaddr
12272 , 65535// indicate disconnect caused by no rx
12278 pmlmeinfo->FW_sta_info[i].retry = 0;
12279 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
12284 //set_link_timer(pmlmeext, DISCONNECT_TO);
12290 void survey_timer_hdl(_adapter *padapter)
12292 struct cmd_obj *ph2c;
12293 struct sitesurvey_parm *psurveyPara;
12294 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
12295 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12297 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12300 //DBG_871X("marc: survey timer\n");
12302 //issue rtw_sitesurvey_cmd
12303 if (pmlmeext->sitesurvey_res.state > SCAN_START)
12305 if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
12307 #if defined(CONFIG_STA_MODE_SCAN_UNDER_AP_MODE) || defined(CONFIG_ATMEL_RC_PATCH)
12308 if (padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH
12309 || padapter->mlmeextpriv.mlmext_info.backop_cnt == RTW_STAY_AP_CH_MILLISECOND)
12311 pmlmeext->sitesurvey_res.channel_idx++;
12314 if(pmlmeext->scan_abort == _TRUE)
12317 if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12319 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
12320 pmlmeext->sitesurvey_res.channel_idx = 3;
12321 DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
12322 , pmlmeext->sitesurvey_res.channel_idx
12323 , pwdinfo->find_phase_state_exchange_cnt
12329 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
12330 DBG_871X("%s idx:%d\n", __FUNCTION__
12331 , pmlmeext->sitesurvey_res.channel_idx
12335 pmlmeext->scan_abort = _FALSE;//reset
12338 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
12340 goto exit_survey_timer_hdl;
12343 if ((psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm))) == NULL)
12345 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
12346 goto exit_survey_timer_hdl;
12349 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12350 rtw_enqueue_cmd(pcmdpriv, ph2c);
12354 exit_survey_timer_hdl:
12359 void link_timer_hdl(_adapter *padapter)
12361 //static unsigned int rx_pkt = 0;
12362 //static u64 tx_cnt = 0;
12363 //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12364 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12365 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12366 //struct sta_priv *pstapriv = &padapter->stapriv;
12369 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
12371 DBG_871X("link_timer_hdl:no beacon while connecting\n");
12372 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12373 report_join_res(padapter, -3);
12375 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
12378 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
12380 //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
12382 pmlmeinfo->state = 0;
12383 report_join_res(padapter, -1);
12388 // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
12389 // pmlmeinfo->reauth_count = 0;
12393 DBG_871X("link_timer_hdl: auth timeout and try again\n");
12394 pmlmeinfo->auth_seq = 1;
12395 issue_auth(padapter, NULL, 0);
12396 set_link_timer(pmlmeext, REAUTH_TO);
12398 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
12401 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
12403 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12404 report_join_res(padapter, -2);
12408 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
12409 issue_assocreq(padapter);
12410 set_link_timer(pmlmeext, REASSOC_TO);
12413 else if (is_client_associated_to_ap(padapter))
12415 //linked infrastructure client mode
12416 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12418 /*to monitor whether the AP is alive or not*/
12419 if (rx_pkt == psta->sta_stats.rx_pkts)
12421 receive_disconnect(padapter, pmlmeinfo->network.MacAddress);
12426 rx_pkt = psta->sta_stats.rx_pkts;
12427 set_link_timer(pmlmeext, DISCONNECT_TO);
12430 //update the EDCA paramter according to the Tx/RX mode
12431 update_EDCA_param(padapter);
12433 /*to send the AP a nulldata if no frame is xmitted in order to keep alive*/
12434 if (pmlmeinfo->link_count++ == 0)
12436 tx_cnt = pxmitpriv->tx_pkts;
12438 else if ((pmlmeinfo->link_count & 0xf) == 0)
12440 if (tx_cnt == pxmitpriv->tx_pkts)
12442 issue_nulldata_in_interrupt(padapter, NULL, 0);
12445 tx_cnt = pxmitpriv->tx_pkts;
12447 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12449 else if (is_client_associated_to_ibss(padapter))
12452 //for each assoc list entry to check the rx pkt counter
12453 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
12455 if (pmlmeinfo->FW_sta_info[i].status == 1)
12457 psta = pmlmeinfo->FW_sta_info[i].psta;
12459 if (pmlmeinfo->FW_sta_info[i].rx_pkt == psta->sta_stats.rx_pkts)
12461 pmlmeinfo->FW_sta_info[i].status = 0;
12462 report_del_sta_event(padapter, psta->hwaddr);
12466 pmlmeinfo->FW_sta_info[i].rx_pkt = psta->sta_stats.rx_pkts;
12471 set_link_timer(pmlmeext, DISCONNECT_TO);
12478 void addba_timer_hdl(struct sta_info *psta)
12480 #ifdef CONFIG_80211N_HT
12481 struct ht_priv *phtpriv;
12486 phtpriv = &psta->htpriv;
12488 if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
12490 if(phtpriv->candidate_tid_bitmap)
12491 phtpriv->candidate_tid_bitmap=0x0;
12494 #endif //CONFIG_80211N_HT
12497 #ifdef CONFIG_IEEE80211W
12498 void sa_query_timer_hdl(_adapter *padapter)
12500 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12501 struct mlme_priv * pmlmepriv = &padapter->mlmepriv;
12504 _enter_critical_bh(&pmlmepriv->lock, &irqL);
12506 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12508 rtw_disassoc_cmd(padapter, 0, _TRUE);
12509 rtw_indicate_disconnect(padapter);
12510 rtw_free_assoc_resources(padapter, 1);
12513 _exit_critical_bh(&pmlmepriv->lock, &irqL);
12514 DBG_871X("SA query timeout disconnect\n");
12516 #endif //CONFIG_IEEE80211W
12518 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
12520 return H2C_SUCCESS;
12523 #ifdef CONFIG_AUTO_AP_MODE
12524 void rtw_start_auto_ap(_adapter *adapter)
12526 DBG_871X("%s\n", __FUNCTION__);
12528 rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
12530 rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE);
12533 static int rtw_auto_ap_start_beacon(_adapter *adapter)
12538 u8 supportRate[16];
12539 int sz = 0, rateLen;
12541 u8 wireless_mode, oper_channel;
12542 u8 ssid[3] = {0}; //hidden ssid
12543 u32 ssid_len = sizeof(ssid);
12544 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
12547 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
12552 pbuf = rtw_zmalloc(len);
12560 //timestamp will be inserted by hardware
12564 //beacon interval : 2bytes
12565 *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
12571 *(u16*)ie |= cpu_to_le16(cap_ESS);
12572 *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
12573 //*(u16*)ie |= cpu_to_le16(cap_Privacy);
12578 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
12581 wireless_mode = WIRELESS_11BG_24N;
12582 rtw_set_supported_rate(supportRate, wireless_mode) ;
12583 rateLen = rtw_get_rateset_len(supportRate);
12586 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
12590 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
12595 if(check_buddy_fwstate(adapter, _FW_LINKED) &&
12596 check_buddy_fwstate(adapter, WIFI_STATION_STATE))
12598 PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
12599 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
12601 oper_channel = pbuddy_mlmeext->cur_channel;
12605 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
12607 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
12609 //ext supported rates
12612 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
12615 DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
12617 //lunch ap mode & start to issue beacon
12618 if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS)
12628 rtw_mfree(pbuf, len);
12633 #endif//CONFIG_AUTO_AP_MODE
12635 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
12638 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12639 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12640 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
12642 if(psetop->mode == Ndis802_11APMode)
12644 pmlmeinfo->state = WIFI_FW_AP_STATE;
12645 type = _HW_STATE_AP_;
12646 #ifdef CONFIG_NATIVEAP_MLME
12647 //start_ap_mode(padapter);
12650 else if(psetop->mode == Ndis802_11Infrastructure)
12652 pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
12653 pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE
12654 type = _HW_STATE_STATION_;
12656 else if(psetop->mode == Ndis802_11IBSS)
12658 type = _HW_STATE_ADHOC_;
12659 } else if (psetop->mode == Ndis802_11Monitor) {
12660 type = _HW_STATE_MONITOR_;
12664 type = _HW_STATE_NOLINK_;
12667 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
12668 //Set_NETYPE0_MSR(padapter, type);
12671 #ifdef CONFIG_AUTO_AP_MODE
12672 if(psetop->mode == Ndis802_11APMode)
12673 rtw_auto_ap_start_beacon(padapter);
12676 if (rtw_port_switch_chk(padapter) == _TRUE)
12678 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12680 if(psetop->mode == Ndis802_11APMode)
12681 adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages
12682 else if (psetop->mode == Ndis802_11Infrastructure) {
12684 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12686 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
12691 #ifdef CONFIG_BT_COEXIST
12692 if (psetop->mode == Ndis802_11APMode)
12694 // Do this after port switch to
12695 // prevent from downloading rsvd page to wrong port
12696 rtw_btcoex_MediaStatusNotify(padapter, 1); //connect
12698 #endif // CONFIG_BT_COEXIST
12700 return H2C_SUCCESS;
12704 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
12706 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12707 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12708 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
12709 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
12712 #ifdef CONFIG_AP_MODE
12713 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
12714 WLAN_BSSID_EX *network = &padapter->mlmepriv.cur_network.network;
12715 start_bss_network(padapter, (u8*)network);
12716 return H2C_SUCCESS;
12720 //below is for ad-hoc master
12721 if(pparm->network.InfrastructureMode == Ndis802_11IBSS)
12723 rtw_joinbss_reset(padapter);
12725 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12726 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12727 pmlmeinfo->ERP_enable = 0;
12728 pmlmeinfo->WMM_enable = 0;
12729 pmlmeinfo->HT_enable = 0;
12730 pmlmeinfo->HT_caps_enable = 0;
12731 pmlmeinfo->HT_info_enable = 0;
12732 pmlmeinfo->agg_enable_bitmap = 0;
12733 pmlmeinfo->candidate_tid_bitmap = 0;
12735 //config the initial gain under linking, need to write the BB registers
12736 //initialgain = 0x1E;
12737 //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
12739 //disable dynamic functions, such as high power, DIG
12740 Save_DM_Func_Flag(padapter);
12741 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
12743 //cancel link timer
12744 _cancel_timer_ex(&pmlmeext->link_timer);
12747 flush_all_cam_entry(padapter);
12749 _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
12750 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
12752 if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
12753 return H2C_PARAMETERS_ERROR;
12755 _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
12757 start_create_ibss(padapter);
12761 return H2C_SUCCESS;
12765 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
12768 PNDIS_802_11_VARIABLE_IEs pIE;
12769 struct registry_priv *pregpriv = &padapter->registrypriv;
12770 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12771 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12772 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
12773 #ifdef CONFIG_ANTENNA_DIVERSITY
12774 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
12775 #endif //CONFIG_ANTENNA_DIVERSITY
12782 //check already connecting to AP or not
12783 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12785 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
12787 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
12789 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12792 flush_all_cam_entry(padapter);
12794 _cancel_timer_ex(&pmlmeext->link_timer);
12796 //set MSR to nolink -> infra. mode
12797 //Set_MSR(padapter, _HW_STATE_NOLINK_);
12798 Set_MSR(padapter, _HW_STATE_STATION_);
12801 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
12804 #ifdef CONFIG_ANTENNA_DIVERSITY
12805 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
12808 #ifdef CONFIG_WAPI_SUPPORT
12809 rtw_wapi_clear_all_cam_entry(padapter);
12812 rtw_joinbss_reset(padapter);
12814 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12815 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12816 pmlmeinfo->ERP_enable = 0;
12817 pmlmeinfo->WMM_enable = 0;
12818 pmlmeinfo->HT_enable = 0;
12819 pmlmeinfo->HT_caps_enable = 0;
12820 pmlmeinfo->HT_info_enable = 0;
12821 pmlmeinfo->agg_enable_bitmap = 0;
12822 pmlmeinfo->candidate_tid_bitmap = 0;
12823 pmlmeinfo->bwmode_updated = _FALSE;
12824 //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
12825 pmlmeinfo->VHT_enable = 0;
12827 _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
12828 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
12830 if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
12831 return H2C_PARAMETERS_ERROR;
12833 if (pnetwork->IELength < 2) {
12834 report_join_res(padapter, (-4));
12835 return H2C_SUCCESS;
12837 _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
12839 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
12840 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
12842 //Check AP vendor to move rtw_joinbss_cmd()
12843 //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
12845 //sizeof(NDIS_802_11_FIXED_IEs)
12846 for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
12847 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
12849 switch (pIE->ElementID)
12851 case _VENDOR_SPECIFIC_IE_://Get WMM IE.
12852 if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
12854 WMM_param_handler(padapter, pIE);
12858 case _HT_CAPABILITY_IE_: //Get HT Cap IE.
12859 pmlmeinfo->HT_caps_enable = 1;
12862 case _HT_EXTRA_INFO_IE_: //Get HT Info IE.
12863 #ifdef CONFIG_80211N_HT
12864 pmlmeinfo->HT_info_enable = 1;
12866 //spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz
12868 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
12870 if (pnetwork->Configuration.DSConfig > 14) {
12871 if ((pregpriv->bw_mode >> 4) > CHANNEL_WIDTH_20)
12874 if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
12878 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2)))
12880 //switch to the 40M Hz mode according to the AP
12881 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
12882 switch (pht_info->infos[0] & 0x3)
12885 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
12889 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
12893 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12894 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12898 DBG_871X("set HT ch/bw before connected\n");
12901 #endif //CONFIG_80211N_HT
12903 #ifdef CONFIG_80211AC_VHT
12904 case EID_VHTCapability://Get VHT Cap IE.
12905 pmlmeinfo->VHT_enable = 1;
12908 case EID_VHTOperation://Get VHT Operation IE.
12909 if((GET_VHT_OPERATION_ELE_CHL_WIDTH(pIE->data) >= 1)
12910 && ((pregpriv->bw_mode >> 4) >= CHANNEL_WIDTH_80)) {
12911 pmlmeext->cur_bwmode = CHANNEL_WIDTH_80;
12912 DBG_871X("VHT center ch = %d\n", GET_VHT_OPERATION_ELE_CENTER_FREQ1(pIE->data));
12913 DBG_871X("set VHT ch/bw before connected\n");
12921 i += (pIE->Length + 2);
12924 if (padapter->registrypriv.wifi_spec) {
12925 // for WiFi test, follow WMM test plan spec
12926 acparm = 0x002F431C; // VO
12927 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
12928 acparm = 0x005E541C; // VI
12929 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
12930 acparm = 0x0000A525; // BE
12931 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
12932 acparm = 0x0000A549; // BK
12933 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
12935 // for WiFi test, mixed mode with intel STA under bg mode throughput issue
12936 if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
12937 acparm = 0x00004320;
12938 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
12942 acparm = 0x002F3217; // VO
12943 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
12944 acparm = 0x005E4317; // VI
12945 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
12946 acparm = 0x00105320; // BE
12947 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
12948 acparm = 0x0000A444; // BK
12949 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
12953 /* check channel, bandwidth, offset and switch */
12954 if(rtw_chk_start_clnt_join(padapter, &ch, &bw, &offset) == _FAIL) {
12955 report_join_res(padapter, (-4));
12956 return H2C_SUCCESS;
12959 //disable dynamic functions, such as high power, DIG
12960 //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
12962 //config the initial gain under linking, need to write the BB registers
12963 //initialgain = 0x1E;
12964 //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
12966 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
12968 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12969 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
12971 set_channel_bwmode(padapter, ch, offset, bw);
12973 //cancel link timer
12974 _cancel_timer_ex(&pmlmeext->link_timer);
12976 start_clnt_join(padapter);
12978 return H2C_SUCCESS;
12982 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
12984 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
12985 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12986 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12987 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
12990 if (is_client_associated_to_ap(padapter))
12993 if(padapter->mlmepriv.handle_dfs == _FALSE)
12994 #endif //CONFIG_DFS
12995 #ifdef CONFIG_PLATFORM_ROCKCHIPS
12996 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
12997 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
12999 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
13000 #endif //CONFIG_PLATFORM_ROCKCHIPS
13004 if( padapter->mlmepriv.handle_dfs == _TRUE )
13005 padapter->mlmepriv.handle_dfs = _FALSE;
13006 #endif //CONFIG_DFS
13008 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13012 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13015 rtw_mlmeext_disconnect(padapter);
13017 rtw_free_uc_swdec_pending_queue(padapter);
13019 return H2C_SUCCESS;
13022 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13024 /* interval larger than this is treated as backgroud scan */
13025 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13026 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13029 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13030 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13032 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13033 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13036 #define SCAN_SPARSE_CH_NUM_INVALID 255
13038 static u8 token = 255;
13040 bool busy_traffic = _FALSE;
13041 bool miracast_enabled = _FALSE;
13042 bool bg_scan = _FALSE;
13043 u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13044 u8 scan_division_num;
13045 u8 ret_num = ch_num;
13046 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13047 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13049 if (regsty->wifi_spec)
13052 /* assume ch_num > 6 is normal scan */
13056 if (mlmeext->last_scan_time == 0)
13057 mlmeext->last_scan_time = rtw_get_current_time();
13059 interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13061 if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE
13062 #ifdef CONFIG_CONCURRENT_MODE
13063 || (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
13066 busy_traffic = _TRUE;
13069 if (is_miracast_enabled(adapter->wfd_info.stack_wfd_mode)
13070 #ifdef CONFIG_CONCURRENT_MODE
13071 || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter->wfd_info.stack_wfd_mode))
13074 miracast_enabled = _TRUE;
13077 if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13080 /* max_allow_ch by conditions*/
13082 #if RTW_SCAN_SPARSE_MIRACAST
13083 if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13084 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13087 #if RTW_SCAN_SPARSE_BG
13088 if (bg_scan == _TRUE)
13089 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13093 if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13097 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0);
13098 token = (token + 1) % scan_division_num;
13101 DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token);
13103 for (i = 0; i < ch_num; i++) {
13104 if (ch[i].hw_value && (i % scan_division_num) == token
13107 _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13112 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13115 mlmeext->last_scan_time = rtw_get_current_time();
13122 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13123 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13126 int scan_ch_num = 0;
13128 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13131 _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
13133 /* acquire channels from in */
13135 for (i=0;i<in_num;i++) {
13138 DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13140 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
13141 && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
13142 && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE
13145 if (j >= out_num) {
13146 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13147 FUNC_ADPT_ARG(padapter), out_num);
13151 _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13153 if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13154 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13162 /* if out is empty, use channel_set as default */
13164 for (i=0;i<pmlmeext->max_chan_nums;i++) {
13167 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
13169 if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) {
13171 if (j >= out_num) {
13172 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13173 FUNC_ADPT_ARG(padapter), out_num);
13177 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
13179 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
13180 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13188 j = rtw_scan_sparse(padapter, out, j);
13193 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
13195 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13196 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
13197 u8 bdelayscan = _FALSE;
13201 struct dvobj_priv *psdpriv = padapter->dvobj;
13202 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13205 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
13207 #ifdef DBG_CHECK_FW_PS_STATE
13208 if(rtw_fw_ps_state(padapter) == _FAIL)
13210 DBG_871X("scan without leave 32k\n");
13211 pdbgpriv->dbg_scan_pwr_state_cnt++;
13213 #endif //DBG_CHECK_FW_PS_STATE
13215 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE)
13217 #ifdef CONFIG_CONCURRENT_MODE
13218 //for first time sitesurvey_cmd
13219 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
13220 #endif //CONFIG_CONCURRENT_MODE
13222 pmlmeext->sitesurvey_res.state = SCAN_START;
13223 pmlmeext->sitesurvey_res.bss_cnt = 0;
13224 pmlmeext->sitesurvey_res.channel_idx = 0;
13226 for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
13227 if(pparm->ssid[i].SsidLength) {
13228 _rtw_memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
13229 pmlmeext->sitesurvey_res.ssid[i].SsidLength= pparm->ssid[i].SsidLength;
13231 pmlmeext->sitesurvey_res.ssid[i].SsidLength= 0;
13235 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
13236 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
13237 , pparm->ch, pparm->ch_num
13240 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
13242 //issue null data if associating to the AP
13243 if (is_client_associated_to_ap(padapter) == _TRUE)
13245 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
13247 issue_nulldata(padapter, NULL, 1, 3, 500);
13249 #ifdef CONFIG_CONCURRENT_MODE
13250 if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
13252 DBG_871X("adapter is scanning(buddy_adapter is linked), issue nulldata(pwrbit=1)\n");
13254 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
13257 bdelayscan = _TRUE;
13259 #ifdef CONFIG_CONCURRENT_MODE
13260 else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
13263 if(padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1)
13265 issue_tunneled_probe_req(padapter->pbuddy_adapter);
13267 #endif //CONFIG_TDLS
13269 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
13271 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
13273 bdelayscan = _TRUE;
13278 //delay 50ms to protect nulldata(1).
13279 set_survey_timer(pmlmeext, 50);
13280 return H2C_SUCCESS;
13284 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL))
13286 #ifdef CONFIG_FIND_BEST_CHANNEL
13288 for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
13289 pmlmeext->channel_set[i].rx_count = 0;
13292 #endif /* CONFIG_FIND_BEST_CHANNEL */
13294 //config the initial gain under scaning, need to write the BB registers
13296 #ifdef CONFIG_IOCTL_CFG80211
13297 if(adapter_wdev_data(padapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211 )
13298 initialgain = 0x30;
13300 #endif //CONFIG_IOCTL_CFG80211
13301 if ( !rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) )
13302 initialgain = 0x28;
13304 #endif //CONFIG_P2P
13305 initialgain = 0x1e;
13307 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
13309 //disable dynamic functions, such as high power, DIG
13310 Save_DM_Func_Flag(padapter);
13311 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
13313 //set MSR to no link state
13314 Set_MSR(padapter, _HW_STATE_NOLINK_);
13316 val8 = 1; //under site survey
13317 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
13319 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
13322 site_survey(padapter);
13324 return H2C_SUCCESS;
13328 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
13330 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
13331 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13332 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13334 if (pparm->mode < 4)
13336 pmlmeinfo->auth_algo = pparm->mode;
13339 return H2C_SUCCESS;
13342 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
13346 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
13347 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13348 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13349 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13352 //main tx key for wep.
13354 pmlmeinfo->key_index = pparm->keyid;
13356 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid);
13360 if (cam_id > 3) /* not default key, searched by A2 */
13361 addr = get_bssid(&padapter->mlmepriv);
13365 ctrl = BIT(15) | BIT6 |((pparm->algorithm) << 2) | pparm->keyid;
13366 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
13367 DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
13368 ,cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
13371 #ifdef DYNAMIC_CAMID_ALLOC
13372 if (cam_id >=0 && cam_id <=3)
13373 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE);
13376 //allow multicast packets to driver
13377 rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
13379 return H2C_SUCCESS;
13382 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
13386 u8 ret = H2C_SUCCESS;
13387 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13388 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13389 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
13390 struct sta_priv *pstapriv = &padapter->stapriv;
13391 struct sta_info *psta;
13393 if(pparm->algorithm == _NO_PRIVACY_)
13396 psta = rtw_get_stainfo(pstapriv, pparm->addr);
13398 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
13399 ret = H2C_REJECTED;
13403 pmlmeinfo->enc_algo = pparm->algorithm;
13404 cam_id = rtw_camid_alloc(padapter, psta, 0);
13409 if(pparm->algorithm == _NO_PRIVACY_) {
13410 while((cam_id = rtw_camid_search(padapter, pparm->addr, -1)) >= 0) {
13411 DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
13412 clear_cam_entry(padapter, cam_id);
13413 rtw_camid_free(padapter,cam_id);
13416 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
13417 cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
13418 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
13419 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
13421 ret = H2C_SUCCESS_RSP;
13427 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
13429 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
13430 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13431 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13433 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
13436 return H2C_SUCCESS;
13438 #ifdef CONFIG_80211N_HT
13439 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
13440 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13442 //pmlmeinfo->ADDBA_retry_count = 0;
13443 //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
13444 //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
13445 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
13446 //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
13447 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
13450 else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
13451 (psta->htpriv.ht_option==_TRUE) &&
13452 (psta->htpriv.ampdu_enable==_TRUE) )
13454 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
13455 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
13460 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
13462 #endif //CONFIG_80211N_HT
13463 return H2C_SUCCESS;
13467 u8 chk_bmc_sleepq_cmd(_adapter* padapter)
13469 struct cmd_obj *ph2c;
13470 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
13475 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
13481 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
13483 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
13492 u8 set_tx_beacon_cmd(_adapter* padapter)
13494 struct cmd_obj *ph2c;
13495 struct Tx_Beacon_param *ptxBeacon_parm;
13496 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
13497 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13498 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13504 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
13510 if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
13512 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
13517 _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
13519 len_diff = update_hidden_ssid(
13520 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
13521 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
13522 , pmlmeinfo->hidden_ssid_mode
13524 ptxBeacon_parm->network.IELength += len_diff;
13526 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
13528 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
13539 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
13541 u8 evt_code, evt_seq;
13544 void (*event_callback)(_adapter *dev, u8 *pbuf);
13545 struct evt_priv *pevt_priv = &(padapter->evtpriv);
13548 goto _abort_event_;
13550 peventbuf = (uint*)pbuf;
13551 evt_sz = (u16)(*peventbuf&0xffff);
13552 evt_seq = (u8)((*peventbuf>>24)&0x7f);
13553 evt_code = (u8)((*peventbuf>>16)&0xff);
13556 #ifdef CHECK_EVENT_SEQ
13557 // checking event sequence...
13558 if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
13560 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)));
13562 pevt_priv->event_seq = (evt_seq+1)&0x7f;
13564 goto _abort_event_;
13568 // checking if event code is valid
13569 if (evt_code >= MAX_C2HEVT)
13571 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
13572 goto _abort_event_;
13575 // checking if event size match the event parm size
13576 if ((wlanevents[evt_code].parmsize != 0) &&
13577 (wlanevents[evt_code].parmsize != evt_sz))
13580 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
13581 evt_code, wlanevents[evt_code].parmsize, evt_sz));
13582 goto _abort_event_;
13586 ATOMIC_INC(&pevt_priv->event_seq);
13592 event_callback = wlanevents[evt_code].event_callback;
13593 event_callback(padapter, (u8*)peventbuf);
13595 pevt_priv->evt_done_cnt++;
13602 return H2C_SUCCESS;
13606 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
13609 return H2C_PARAMETERS_ERROR;
13611 return H2C_SUCCESS;
13614 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
13616 #ifdef CONFIG_AP_MODE
13618 struct sta_info *psta_bmc;
13619 _list *xmitframe_plist, *xmitframe_phead;
13620 struct xmit_frame *pxmitframe=NULL;
13621 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
13622 struct sta_priv *pstapriv = &padapter->stapriv;
13625 psta_bmc = rtw_get_bcmc_stainfo(padapter);
13627 return H2C_SUCCESS;
13629 if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
13631 #ifndef CONFIG_PCI_HCI
13632 rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
13634 //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
13635 _enter_critical_bh(&pxmitpriv->lock, &irqL);
13637 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
13638 xmitframe_plist = get_next(xmitframe_phead);
13640 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
13642 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
13644 xmitframe_plist = get_next(xmitframe_plist);
13646 rtw_list_delete(&pxmitframe->list);
13648 psta_bmc->sleepq_len--;
13649 if(psta_bmc->sleepq_len>0)
13650 pxmitframe->attrib.mdata = 1;
13652 pxmitframe->attrib.mdata = 0;
13654 pxmitframe->attrib.triggered=1;
13656 if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
13657 pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ
13660 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
13661 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
13663 rtw_os_xmit_complete(padapter, pxmitframe);
13665 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
13667 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
13670 //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
13671 _exit_critical_bh(&pxmitpriv->lock, &irqL);
13673 if (padapter->interface_type != RTW_PCIE) {
13674 /* check hi queue and bmc_sleepq */
13675 rtw_chk_hi_queue_cmd(padapter);
13680 return H2C_SUCCESS;
13683 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
13685 if(send_beacon(padapter)==_FAIL)
13687 DBG_871X("issue_beacon, fail!\n");
13688 return H2C_PARAMETERS_ERROR;
13691 /* tx bc/mc frames after update TIM */
13692 chk_bmc_sleepq_hdl(padapter, NULL);
13694 return H2C_SUCCESS;
13697 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork)
13699 u8 network_type,rate_len, total_rate_len,remainder_rate_len;
13700 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
13701 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13704 //DBG_871X("%s\n", __FUNCTION__);
13706 if(pmlmeext->cur_channel >= 36)
13708 network_type = WIRELESS_11A;
13709 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
13710 DBG_871X("%s(): change to 5G Band\n",__FUNCTION__);
13711 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
13715 network_type = WIRELESS_11BG;
13716 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
13717 DBG_871X("%s(): change to 2.4G Band\n",__FUNCTION__);
13718 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
13721 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
13723 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
13724 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
13726 if(total_rate_len > 8)
13729 remainder_rate_len = total_rate_len - 8;
13733 rate_len = total_rate_len;
13734 remainder_rate_len = 0;
13737 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
13739 if(remainder_rate_len)
13741 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
13745 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
13749 #ifdef CONFIG_CONCURRENT_MODE
13750 sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
13752 PADAPTER pbuddy_adapter;
13753 struct mlme_ext_priv *pbuddy_mlmeext;
13754 struct mlme_ext_info *pbuddy_mlmeinfo;
13756 if(padapter == NULL)
13759 pbuddy_adapter = padapter->pbuddy_adapter;
13761 if(pbuddy_adapter == NULL)
13765 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
13766 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
13768 if((pbuddy_mlmeinfo->state&0x03) == state)
13775 void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
13777 struct mlme_ext_priv *pmlmeext;
13778 struct mlme_ext_info *pmlmeinfo;
13779 PADAPTER pbuddy_adapter;
13780 struct mlme_priv *pbuddy_mlmepriv;
13781 struct mlme_ext_priv *pbuddy_mlmeext;
13782 struct mlme_ext_info *pbuddy_mlmeinfo;
13783 WLAN_BSSID_EX *pbuddy_network_mlmeext;
13784 WLAN_BSSID_EX *pnetwork;
13786 pmlmeext = &padapter->mlmeextpriv;
13787 pmlmeinfo = &(pmlmeext->mlmext_info);
13790 if(!rtw_buddy_adapter_up(padapter))
13792 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
13796 pbuddy_adapter = padapter->pbuddy_adapter;
13797 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
13798 pnetwork = (WLAN_BSSID_EX *)&pbuddy_mlmepriv->cur_network.network;
13799 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
13800 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
13801 pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
13803 if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
13804 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
13806 //restart and update beacon
13808 DBG_871X("after join,primary adapter, CH=%d, BW=%d, offset=%d\n"
13809 , pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
13816 u8 change_band = _FALSE;
13817 struct HT_info_element *pht_info=NULL;
13819 if((pmlmeext->cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) ||
13820 (pmlmeext->cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14))
13821 change_band = _TRUE;
13823 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
13826 pht_info = (struct HT_info_element *)(p+2);
13827 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; //no secondary channel is present
13830 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
13831 #ifdef CONFIG_80211AC_VHT
13832 if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)
13834 u8 *pvht_cap_ie, *pvht_op_ie;
13835 int vht_cap_ielen, vht_op_ielen;
13837 pvht_cap_ie = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTCapability, &vht_cap_ielen, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
13838 pvht_op_ie = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &vht_op_ielen, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
13840 if(pmlmeext->cur_channel <= 14) // downgrade to 20/40Mhz
13842 //modify vht cap ie
13843 if( pvht_cap_ie && vht_cap_ielen)
13845 SET_VHT_CAPABILITY_ELE_SHORT_GI80M(pvht_cap_ie+2, 0);
13849 if( pvht_op_ie && vht_op_ielen)
13851 SET_VHT_OPERATION_ELE_CHL_WIDTH(pvht_op_ie+2, 0); //change to 20/40Mhz
13852 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, 0);
13853 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(pvht_op_ie+2, 0);
13854 //SET_VHT_OPERATION_ELE_BASIC_MCS_SET(p+2, 0xFFFF);
13855 pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
13862 pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_80;
13864 if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||
13865 pmlmeext->cur_bwmode == CHANNEL_WIDTH_80)
13867 pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
13869 else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_20)
13871 pbuddy_mlmeext->cur_ch_offset = rtw_get_offset_by_ch(pmlmeext->cur_channel);
13874 //modify ht info ie
13876 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
13878 switch(pbuddy_mlmeext->cur_ch_offset)
13880 case HAL_PRIME_CHNL_OFFSET_LOWER:
13882 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
13883 //cur_bwmode = CHANNEL_WIDTH_40;
13885 case HAL_PRIME_CHNL_OFFSET_UPPER:
13887 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
13888 //cur_bwmode = CHANNEL_WIDTH_40;
13890 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
13893 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
13894 pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13895 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13900 center_freq = rtw_get_center_ch(pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, HAL_PRIME_CHNL_OFFSET_LOWER);
13901 if( pvht_op_ie && vht_op_ielen)
13902 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, center_freq);
13904 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
13909 #endif //CONFIG_80211AC_VHT
13911 if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)
13913 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
13916 pht_info = (struct HT_info_element *)(p+2);
13917 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; //no secondary channel is present
13920 if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||
13921 pmlmeext->cur_bwmode == CHANNEL_WIDTH_80)
13923 pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
13925 //to update cur_ch_offset value in beacon
13928 switch(pmlmeext->cur_ch_offset)
13930 case HAL_PRIME_CHNL_OFFSET_LOWER:
13931 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
13933 case HAL_PRIME_CHNL_OFFSET_UPPER:
13934 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
13936 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
13944 else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_20)
13946 pbuddy_mlmeext->cur_ch_offset = rtw_get_offset_by_ch(pmlmeext->cur_channel);
13948 switch(pbuddy_mlmeext->cur_ch_offset)
13950 case HAL_PRIME_CHNL_OFFSET_LOWER:
13952 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
13953 pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
13955 case HAL_PRIME_CHNL_OFFSET_UPPER:
13957 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
13958 pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_40;
13960 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
13963 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
13964 pbuddy_mlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13965 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13971 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
13976 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
13980 // to update channel value in beacon
13981 pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
13982 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
13984 *(p + 2) = pmlmeext->cur_channel;
13986 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
13989 pht_info = (struct HT_info_element *)(p+2);
13990 pht_info->primary_channel = pmlmeext->cur_channel;
13993 //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE
13994 if(change_band == _TRUE)
13995 change_band_update_ie(pbuddy_adapter, pbuddy_network_mlmeext);
13999 // switch back to original channel/bwmode/ch_offset;
14000 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
14003 DBG_871X("after join, second adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
14005 DBG_871X("update pbuddy_adapter's beacon\n");
14007 _rtw_memcpy(pnetwork, pbuddy_network_mlmeext, sizeof(WLAN_BSSID_EX));
14008 //update bmc rate to avoid bb cck hang
14009 update_bmc_sta(pbuddy_adapter);
14010 update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
14013 else if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) &&
14014 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
14018 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
14019 if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||
14020 pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)
14021 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
14022 else if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||
14023 pmlmeext->cur_bwmode == CHANNEL_WIDTH_80)
14024 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
14026 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14030 // switch back to original channel/bwmode/ch_offset;
14031 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
14036 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
14040 #endif //CONFIG_CONCURRENT_MODE
14042 int rtw_chk_start_clnt_join(_adapter *padapter, u8 *ch, u8 *bw, u8 *offset)
14044 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14045 unsigned char cur_ch = pmlmeext->cur_channel;
14046 unsigned char cur_bw = pmlmeext->cur_bwmode;
14047 unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
14048 bool chbw_allow = _TRUE;
14049 bool connect_allow = _TRUE;
14051 #ifdef CONFIG_CONCURRENT_MODE
14052 PADAPTER pbuddy_adapter;
14053 struct mlme_ext_priv *pbuddy_mlmeext;
14054 struct mlme_ext_info *pbuddy_pmlmeinfo;
14055 struct mlme_priv *pbuddy_mlmepriv;
14058 if (!ch || !bw || !offset) {
14059 connect_allow = _FALSE;
14065 connect_allow = _FALSE;
14066 DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n"
14067 , FUNC_ADPT_ARG(padapter), cur_ch);
14072 #ifdef CONFIG_CONCURRENT_MODE
14073 if (!rtw_buddy_adapter_up(padapter)) {
14077 pbuddy_adapter = padapter->pbuddy_adapter;
14078 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
14079 pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info);
14080 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
14082 if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)//for AP MODE
14084 DBG_871X("start_clnt_join: "ADPT_FMT"(ch=%d, bw=%d, ch_offset=%d)"
14085 ", "ADPT_FMT" AP mode(ch=%d, bw=%d, ch_offset=%d)\n",
14086 ADPT_ARG(padapter), pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset,
14087 ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
14089 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
14091 chbw_allow = _FALSE;
14093 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
14094 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
14095 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
14097 chbw_allow = _FALSE;
14099 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_20) &&
14100 ((pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40)||
14101 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)) )
14103 cur_ch = pmlmeext->cur_channel;
14104 cur_bw = pbuddy_mlmeext->cur_bwmode;
14105 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
14108 DBG_871X("start_clnt_join: connect_allow:%d, chbw_allow:%d\n", connect_allow, chbw_allow);
14109 if (chbw_allow == _FALSE) {
14110 #ifdef CONFIG_SPCT_CH_SWITCH
14112 rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
14116 //issue deauth to all stas if if2 is at ap mode
14117 rtw_sta_flush(pbuddy_adapter);
14119 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14122 else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE &&
14123 check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) //for Client Mode/p2p client
14125 DBG_871X("start_clnt_join: "ADPT_FMT"(ch=%d, bw=%d, ch_offset=%d)"
14126 ", "ADPT_FMT" STA mode(ch=%d, bw=%d, ch_offset=%d)\n",
14127 ADPT_ARG(padapter), pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset,
14128 ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
14130 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
14132 chbw_allow = _FALSE;
14134 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_20) &&
14135 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40))
14137 cur_bw = CHANNEL_WIDTH_40;
14138 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
14140 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_20) &&
14141 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80))
14143 cur_bw = CHANNEL_WIDTH_80;
14144 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
14146 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
14147 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
14148 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
14150 chbw_allow = _FALSE;
14152 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_40) &&
14153 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80))
14155 if(pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)
14157 chbw_allow = _FALSE;
14161 cur_bw = CHANNEL_WIDTH_80;
14164 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_80) &&
14165 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40))
14167 if(pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)
14169 chbw_allow = _FALSE;
14172 else if((pmlmeext->cur_bwmode == CHANNEL_WIDTH_80) &&
14173 (pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80))
14175 if(pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)
14177 chbw_allow = _FALSE;
14182 connect_allow = chbw_allow;
14184 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
14185 #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
14186 /* wlan0-sta mode has higher priority than p2p0-p2p client */
14187 if (!rtw_p2p_chk_state(&(pbuddy_adapter->wdinfo), P2P_STATE_NONE)
14188 && pbuddy_adapter->wdinfo.driver_interface == DRIVER_CFG80211)
14190 connect_allow = _TRUE;
14192 #endif /* CONFIG_P2P && CONFIG_IOCTL_CFG80211 */
14194 connect_allow = _TRUE;
14195 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
14197 DBG_871X("start_clnt_join: connect_allow:%d, chbw_allow:%d\n", connect_allow, chbw_allow);
14198 if (connect_allow == _TRUE && chbw_allow == _FALSE) {
14199 /* disconnect buddy's connection */
14200 rtw_disassoc_cmd(pbuddy_adapter, 500, _FALSE);
14201 rtw_indicate_disconnect(pbuddy_adapter);
14202 rtw_free_assoc_resources(pbuddy_adapter, 1);
14206 #endif /* CONFIG_CONCURRENT_MODE */
14210 if (connect_allow == _TRUE) {
14211 DBG_871X("start_join_set_ch_bw: ch=%d, bwmode=%d, ch_offset=%d\n", cur_ch, cur_bw, cur_ch_offset);
14214 *offset = cur_ch_offset;
14217 return connect_allow == _TRUE ? _SUCCESS : _FAIL;
14220 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
14221 int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
14223 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
14225 struct mlme_ext_priv *mlmeext;
14228 u8 bw_ret = CHANNEL_WIDTH_20;
14229 u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14233 if (bw) *bw = CHANNEL_WIDTH_20;
14234 if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14236 for (i = 0; i<dvobj->iface_nums; i++) {
14237 iface = dvobj->padapters[i];
14238 mlmeext = &iface->mlmeextpriv;
14240 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
14244 ch_ret = mlmeext->cur_channel;
14245 bw_ret = mlmeext->cur_bwmode;
14246 offset_ret = mlmeext->cur_ch_offset;
14251 if (ch_ret != mlmeext->cur_channel) {
14256 if (bw_ret < mlmeext->cur_bwmode) {
14257 bw_ret = mlmeext->cur_bwmode;
14258 offset_ret = mlmeext->cur_ch_offset;
14259 } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
14268 if (ch) *ch = ch_ret;
14269 if (bw) *bw = bw_ret;
14270 if (offset) *offset = offset_ret;
14276 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
14278 struct set_ch_parm *set_ch_parm;
14279 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
14280 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14283 return H2C_PARAMETERS_ERROR;
14285 set_ch_parm = (struct set_ch_parm *)pbuf;
14287 DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
14288 FUNC_NDEV_ARG(padapter->pnetdev),
14289 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
14291 pmlmeext->cur_channel = set_ch_parm->ch;
14292 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
14293 pmlmeext->cur_bwmode = set_ch_parm->bw;
14295 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
14297 return H2C_SUCCESS;
14300 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
14302 struct SetChannelPlan_param *setChannelPlan_param;
14303 struct mlme_priv *mlme = &padapter->mlmepriv;
14304 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14307 return H2C_PARAMETERS_ERROR;
14309 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
14311 if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) {
14312 return H2C_PARAMETERS_ERROR;
14315 mlme->ChannelPlan = setChannelPlan_param->channel_plan;
14317 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
14318 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
14320 rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE);
14322 #ifdef CONFIG_IOCTL_CFG80211
14323 rtw_reg_notify_by_driver(padapter);
14324 #endif //CONFIG_IOCTL_CFG80211
14326 return H2C_SUCCESS;
14329 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
14331 struct LedBlink_param *ledBlink_param;
14334 return H2C_PARAMETERS_ERROR;
14336 ledBlink_param = (struct LedBlink_param *)pbuf;
14338 #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
14339 BlinkHandler((PLED_DATA)ledBlink_param->pLed);
14342 return H2C_SUCCESS;
14345 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
14348 struct SetChannelSwitch_param *setChannelSwitch_param;
14350 u8 gval8 = 0x00, sval8 = 0xff;
14353 return H2C_PARAMETERS_ERROR;
14355 setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
14356 new_ch_no = setChannelSwitch_param->new_ch_no;
14358 rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
14360 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
14362 DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
14363 SelectChannel(padapter, new_ch_no);
14365 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
14367 rtw_disassoc_cmd(padapter, 0, _FALSE);
14368 rtw_indicate_disconnect(padapter);
14369 rtw_free_assoc_resources(padapter, 1);
14370 rtw_free_network_queue(padapter, _TRUE);
14372 if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
14373 DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
14376 return H2C_SUCCESS;
14378 return H2C_REJECTED;
14379 #endif //CONFIG_DFS
14383 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
14387 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
14388 #ifdef CONFIG_TDLS_CH_SW
14389 struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
14391 struct TDLSoption_param *TDLSoption;
14392 struct sta_info *ptdls_sta = NULL;
14393 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14394 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
14395 u8 survey_channel, i, min, option;
14396 struct tdls_txmgmt txmgmt;
14397 u32 setchtime, resp_sleep = 0, wait_time;
14398 u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14401 return H2C_PARAMETERS_ERROR;
14403 TDLSoption = (struct TDLSoption_param *)pbuf;
14404 option = TDLSoption->option;
14406 if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
14407 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
14408 if (ptdls_sta == NULL) {
14409 return H2C_REJECTED;
14412 if (!(option == TDLS_RS_RCR || option == TDLS_CH_SW_BACK))
14413 return H2C_REJECTED;
14416 //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
14417 //DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
14420 case TDLS_ESTABLISHED:
14422 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
14423 /* So we can receive all kinds of data frames. */
14426 //leave ALL PS when TDLS is established
14427 rtw_pwr_wakeup(padapter);
14429 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
14430 DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
14432 pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta;
14433 /* Set TDLS sta rate. */
14434 /* Update station supportRate */
14435 rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
14436 if (pmlmeext->cur_channel > 14) {
14437 if (ptdls_sta->ra_mask & 0xffff000)
14438 sta_band |= WIRELESS_11_5N ;
14440 if (ptdls_sta->ra_mask & 0xff0)
14441 sta_band |= WIRELESS_11A;
14444 #ifdef CONFIG_80211AC_VHT
14445 if (ptdls_sta->vhtpriv.vht_option)
14446 sta_band = WIRELESS_11_5AC;
14450 if (ptdls_sta->ra_mask & 0xffff000)
14451 sta_band |= WIRELESS_11_24N;
14453 if (ptdls_sta->ra_mask & 0xff0)
14454 sta_band |= WIRELESS_11G;
14456 if (ptdls_sta->ra_mask & 0x0f)
14457 sta_band |= WIRELESS_11B;
14459 ptdls_sta->wireless_mode = sta_band;
14460 ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta);
14461 set_sta_rate(padapter, ptdls_sta);
14462 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
14464 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE);
14467 case TDLS_ISSUE_PTI:
14468 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
14469 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
14470 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
14472 #ifdef CONFIG_TDLS_CH_SW
14473 case TDLS_CH_SW_RESP:
14474 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
14475 txmgmt.status_code = 0;
14476 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
14478 issue_nulldata(padapter, NULL, 1, 0, 0);
14480 DBG_871X("issue tdls channel switch response\n");
14481 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
14483 rtw_msleep_os(resp_sleep);
14485 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
14486 /* then we just SelectChannel to AP's channel*/
14487 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
14488 SelectChannel(padapter, padapter->mlmeextpriv.cur_channel);
14489 issue_nulldata(padapter, NULL, 0, 0, 0);
14490 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
14491 ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
14495 _set_timer(&ptdls_sta->delay_timer, pmlmeinfo->bcn_interval - 40);
14497 /* Continue following actions */
14500 issue_nulldata(padapter, NULL, 1, 0, 0);
14501 _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout)/1000);
14503 setchtime = rtw_systime_to_ms(rtw_get_current_time());
14504 SelectChannel(padapter, pchsw_info->off_ch_num);
14505 setchtime = rtw_systime_to_ms(rtw_get_current_time()) - setchtime;
14506 setchtime += resp_sleep;
14508 if (pmlmeext->cur_channel != rtw_get_oper_ch(padapter))
14509 issue_nulldata(padapter, NULL, 0, 0, 0);
14510 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
14512 if ((u32)ptdls_sta->ch_switch_time/1000 > setchtime)
14513 wait_time = (u32)ptdls_sta->ch_switch_time/1000 - setchtime;
14518 rtw_msleep_os(wait_time);
14520 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
14521 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
14524 case TDLS_CH_SW_BACK:
14525 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
14526 ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
14527 SelectChannel(padapter, padapter->mlmeextpriv.cur_channel);
14528 issue_nulldata(padapter, NULL, 0, 0, 0);
14532 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
14533 DBG_871X("wirte REG_RCR, set bit6 on\n");
14535 case TDLS_TEAR_STA:
14536 #ifdef CONFIG_TDLS_CH_SW
14537 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
14538 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
14539 TDLS_CH_SWITCH_ON_STATE |
14540 TDLS_PEER_AT_OFF_STATE);
14541 ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
14542 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
14545 rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
14546 free_tdls_sta(padapter, ptdls_sta);
14550 //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
14552 return H2C_SUCCESS;
14554 return H2C_REJECTED;
14555 #endif /* CONFIG_TDLS */
14559 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
14561 struct RunInThread_param *p;
14565 return H2C_PARAMETERS_ERROR;
14566 p = (struct RunInThread_param*)pbuf;
14569 p->func(p->context);
14571 return H2C_SUCCESS;