1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20 #define _RTW_MLME_EXT_C_
21
22 #include <drv_types.h>
23 #ifdef CONFIG_IOCTL_CFG80211
24 #include <rtw_wifi_regd.h>
25 #endif //CONFIG_IOCTL_CFG80211
26 #include <hal_data.h>
27
28
29 struct mlme_handler mlme_sta_tbl[]={
30 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
31 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
32 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
33 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
34 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
35 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
36
37 /*----------------------------------------------------------
38 below 2 are reserved
39 -----------------------------------------------------------*/
40 {0, "DoReserved", &DoReserved},
41 {0, "DoReserved", &DoReserved},
42 {WIFI_BEACON, "OnBeacon", &OnBeacon},
43 {WIFI_ATIM, "OnATIM", &OnAtim},
44 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
45 {WIFI_AUTH, "OnAuth", &OnAuthClient},
46 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
47 {WIFI_ACTION, "OnAction", &OnAction},
48 {WIFI_ACTION_NOACK,"OnActionNoAck", &OnAction},
49 };
50
51 #ifdef _CONFIG_NATIVEAP_MLME_
52 struct mlme_handler mlme_ap_tbl[]={
53 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
54 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
55 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
56 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
57 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
58 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
59
60 /*----------------------------------------------------------
61 below 2 are reserved
62 -----------------------------------------------------------*/
63 {0, "DoReserved", &DoReserved},
64 {0, "DoReserved", &DoReserved},
65 {WIFI_BEACON, "OnBeacon", &OnBeacon},
66 {WIFI_ATIM, "OnATIM", &OnAtim},
67 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
68 {WIFI_AUTH, "OnAuth", &OnAuth},
69 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
70 {WIFI_ACTION, "OnAction", &OnAction},
71 {WIFI_ACTION_NOACK,"OnActionNoAck", &OnAction},
72 };
73 #endif
74
75 struct action_handler OnAction_tbl[]={
76 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
77 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
78 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
79 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
80 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
81 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
82 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
83 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
84 #ifdef CONFIG_IEEE80211W
85 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
86 #else
87 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
88 #endif //CONFIG_IEEE80211W
89 //add for CONFIG_IEEE80211W
90 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
91 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
92 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
93 {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
94 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
95 };
96
97
98 u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0};
99
100 /**************************************************
101 OUI definitions for the vendor specific IE
102 ***************************************************/
103 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
104 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
105 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
106 unsigned char P2P_OUI[] = {0x50,0x6F,0x9A,0x09};
107 unsigned char WFD_OUI[] = {0x50,0x6F,0x9A,0x0A};
108
109 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
110 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
111
112 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
113 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
114
115 extern unsigned char REALTEK_96B_IE[];
116
117
118 /********************************************************
119 ChannelPlan definitions
120 *********************************************************/
121 /*static RT_CHANNEL_PLAN DefaultChannelPlan[RT_CHANNEL_DOMAIN_MAX] = {
122 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},32}, // 0x00, RT_CHANNEL_DOMAIN_FCC
123 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},31}, // 0x01, RT_CHANNEL_DOMAIN_IC
124 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32}, // 0x02, RT_CHANNEL_DOMAIN_ETSI
125 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x03, RT_CHANNEL_DOMAIN_SPAIN
126 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x04, RT_CHANNEL_DOMAIN_FRANCE
127 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x05, RT_CHANNEL_DOMAIN_MKK
128 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x06, RT_CHANNEL_DOMAIN_MKK1
129 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, // 0x07, RT_CHANNEL_DOMAIN_ISRAEL
130 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // 0x08, RT_CHANNEL_DOMAIN_TELEC
131 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
132 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
133 {{1,2,3,4,5,6,7,8,9,10,11,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},26}, // 0x0B, RT_CHANNEL_DOMAIN_TAIWAN
134 {{1,2,3,4,5,6,7,8,9,10,11,12,13,149,153,157,161,165},18}, // 0x0C, RT_CHANNEL_DOMAIN_CHINA
135 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, // 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
136 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},31}, // 0x0E, RT_CHANNEL_DOMAIN_KOREA
137 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, // 0x0F, RT_CHANNEL_DOMAIN_TURKEY
138 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32}, // 0x10, RT_CHANNEL_DOMAIN_JAPAN
139 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,149,153,157,161,165},20}, // 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
140 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48},17}, // 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
141 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},37}, // 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
142 {{1,2,3,4,5,6,7,8,9,10,11,56,60,64,149,153,157,161,165},19}, // 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
143 };*/
144
145 static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
146 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13
147 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, // 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1
148 {{1,2,3,4,5,6,7,8,9,10,11},11}, // 0x02, RT_CHANNEL_DOMAIN_2G_FCC1
149 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1
150 {{10,11,12,13},4}, // 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2
151 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, // 0x05, RT_CHANNEL_DOMAIN_2G_GLOBAL , Passive scan CH 12, 13, 14
152 {{},0}, // 0x06, RT_CHANNEL_DOMAIN_2G_NULL
153 };
154
155 static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
156 {{},0}, // 0x00, RT_CHANNEL_DOMAIN_5G_NULL
157 {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19}, // 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1
158 {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24}, // 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2
159 {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165},22}, // 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3
160 {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24}, // 0x04, RT_CHANNEL_DOMAIN_5G_FCC1
161 {{36,40,44,48,149,153,157,161,165},9}, // 0x05, RT_CHANNEL_DOMAIN_5G_FCC2
162 {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, // 0x06, RT_CHANNEL_DOMAIN_5G_FCC3
163 {{36,40,44,48,52,56,60,64,149,153,157,161},12}, // 0x07, RT_CHANNEL_DOMAIN_5G_FCC4
164 {{149,153,157,161,165},5}, // 0x08, RT_CHANNEL_DOMAIN_5G_FCC5
165 {{36,40,44,48,52,56,60,64},8}, // 0x09, RT_CHANNEL_DOMAIN_5G_FCC6
166 {{36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},20}, // 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1
167 {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},20}, // 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1
168 {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19}, // 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1
169 {{36,40,44,48,52,56,60,64},8}, // 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2
170 {{100,104,108,112,116,120,124,128,132,136,140},11}, // 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3
171 {{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15}, // 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1
172 {{56,60,64,149,153,157,161,165},8}, // 0x10, RT_CHANNEL_DOMAIN_5G_NCC2
173 {{149,153,157,161,165},5}, // 0x11, RT_CHANNEL_DOMAIN_5G_NCC3
174 {{36,40,44,48},4}, // 0x12, RT_CHANNEL_DOMAIN_5G_ETSI4
175 {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x13, RT_CHANNEL_DOMAIN_5G_ETSI5
176 {{149,153,157,161},4}, // 0x14, RT_CHANNEL_DOMAIN_5G_FCC8
177 {{36,40,44,48,52,56,60,64},8}, // 0x15, RT_CHANNEL_DOMAIN_5G_ETSI6
178 {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, // 0x16, RT_CHANNEL_DOMAIN_5G_ETSI7
179 {{36,40,44,48,149,153,157,161,165},9}, // 0x17, RT_CHANNEL_DOMAIN_5G_ETSI8
180 {{100,104,108,112,116,120,124,128,132,136,140},11}, // 0x18, RT_CHANNEL_DOMAIN_5G_ETSI9
181 {{149,153,157,161,165},5}, // 0x19, RT_CHANNEL_DOMAIN_5G_ETSI10
182 {{36,40,44,48,52,56,60,64,132,136,140,149,153,157,161,165},16}, // 0x1A, RT_CHANNEL_DOMAIN_5G_ETSI11
183 {{52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},17}, // 0x1B, RT_CHANNEL_DOMAIN_5G_NCC4
184 {{149,153,157,161},4}, // 0x1C, RT_CHANNEL_DOMAIN_5G_ETSI12
185 {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x1D, RT_CHANNEL_DOMAIN_5G_FCC9
186 {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140},16}, // 0x1E, RT_CHANNEL_DOMAIN_5G_ETSI13
187 {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161},20}, // 0x1F, RT_CHANNEL_DOMAIN_5G_FCC10
188 {{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161},19}, // 0x20, RT_CHANNEL_DOMAIN_5G_KCC2
189 {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x21, RT_CHANNEL_DOMAIN_5G_FCC11
190 {{56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},16}, // 0x22, RT_CHANNEL_DOMAIN_5G_NCC5
191 {{36,40,44,48},4}, // 0x23, RT_CHANNEL_DOMAIN_5G_MKK4
192 //===== Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition =====
193 {{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21}, // 0x30, RT_CHANNEL_DOMAIN_5G_FCC
194 {{36,40,44,48},4}, // 0x31, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS
195 {{36,40,44,48,149,153,157,161},8}, // 0x32, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS
196 };
197
198 static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
199 //===== 0x00 ~ 0x1F , Old Define =====
200 {0x02,0x20}, //0x00, RT_CHANNEL_DOMAIN_FCC
201 {0x02,0x0A}, //0x01, RT_CHANNEL_DOMAIN_IC
202 {0x01,0x01}, //0x02, RT_CHANNEL_DOMAIN_ETSI
203 {0x01,0x00}, //0x03, RT_CHANNEL_DOMAIN_SPAIN
204 {0x01,0x00}, //0x04, RT_CHANNEL_DOMAIN_FRANCE
205 {0x03,0x00}, //0x05, RT_CHANNEL_DOMAIN_MKK
206 {0x03,0x00}, //0x06, RT_CHANNEL_DOMAIN_MKK1
207 {0x01,0x09}, //0x07, RT_CHANNEL_DOMAIN_ISRAEL
208 {0x03,0x09}, //0x08, RT_CHANNEL_DOMAIN_TELEC
209 {0x03,0x00}, //0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
210 {0x00,0x00}, //0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
211 {0x02,0x0F}, //0x0B, RT_CHANNEL_DOMAIN_TAIWAN
212 {0x01,0x08}, //0x0C, RT_CHANNEL_DOMAIN_CHINA
213 {0x02,0x06}, //0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
214 {0x02,0x0B}, //0x0E, RT_CHANNEL_DOMAIN_KOREA
215 {0x02,0x09}, //0x0F, RT_CHANNEL_DOMAIN_TURKEY
216 {0x01,0x01}, //0x10, RT_CHANNEL_DOMAIN_JAPAN
217 {0x02,0x05}, //0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
218 {0x01,0x21}, //0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
219 {0x00,0x04}, //0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
220 {0x02,0x10}, //0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
221 {0x00,0x21}, //0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS
222 {0x00,0x22}, //0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS
223 {0x03,0x21}, //0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
224 {0x06,0x08}, //0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS
225 {0x02,0x08}, //0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS
226 {0x00,0x00}, //0x1A,
227 {0x00,0x00}, //0x1B,
228 {0x00,0x00}, //0x1C,
229 {0x00,0x00}, //0x1D,
230 {0x00,0x00}, //0x1E,
231 {0x06,0x04}, //0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G
232 //===== 0x20 ~ 0x7F ,New Define =====
233 {0x00,0x00}, //0x20, RT_CHANNEL_DOMAIN_WORLD_NULL
234 {0x01,0x00}, //0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL
235 {0x02,0x00}, //0x22, RT_CHANNEL_DOMAIN_FCC1_NULL
236 {0x03,0x00}, //0x23, RT_CHANNEL_DOMAIN_MKK1_NULL
237 {0x04,0x00}, //0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL
238 {0x02,0x04}, //0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1
239 {0x00,0x01}, //0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1
240 {0x03,0x0C}, //0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1
241 {0x00,0x20}, //0x28, RT_CHANNEL_DOMAIN_5G_KCC2
242 {0x00,0x05}, //0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2
243 {0x00,0x00}, //0x2A,
244 {0x00,0x00}, //0x2B,
245 {0x00,0x00}, //0x2C,
246 {0x00,0x00}, //0x2D,
247 {0x00,0x00}, //0x2E,
248 {0x00,0x00}, //0x2F,
249 {0x00,0x06}, //0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3
250 {0x00,0x07}, //0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4
251 {0x00,0x08}, //0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5
252 {0x00,0x09}, //0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6
253 {0x02,0x21}, //0x34, RT_CHANNEL_DOMAIN_5G_FCC11
254 {0x00,0x02}, //0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2
255 {0x00,0x03}, //0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3
256 {0x03,0x0D}, //0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2
257 {0x03,0x0E}, //0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3
258 {0x02,0x22}, //0x39, RT_CHANNEL_DOMAIN_5G_NCC5
259 {0x00,0x00}, //0x3A,
260 {0x00,0x00}, //0x3B,
261 {0x00,0x00}, //0x3C,
262 {0x00,0x00}, //0x3D,
263 {0x00,0x00}, //0x3E,
264 {0x00,0x00}, //0x3F,
265 {0x02,0x10}, //0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2
266 {0x05,0x00}, //0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL
267 {0x01,0x12}, //0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4
268 {0x02,0x05}, //0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2
269 {0x02,0x11}, //0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3
270 {0x00,0x13}, //0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5
271 {0x02,0x14}, //0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8
272 {0x00,0x15}, //0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6
273 {0x00,0x16}, //0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7
274 {0x00,0x17}, //0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8
275 {0x00,0x00}, //0x4A,
276 {0x00,0x00}, //0x4B,
277 {0x00,0x00}, //0x4C,
278 {0x00,0x00}, //0x4D,
279 {0x00,0x00}, //0x4E,
280 {0x00,0x00}, //0x4F,
281 {0x00,0x18}, //0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9
282 {0x00,0x19}, //0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10
283 {0x00,0x1A}, //0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11
284 {0x02,0x1B}, //0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4
285 {0x00,0x1C}, //0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12
286 {0x02,0x1D}, //0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9
287 {0x00,0x1E}, //0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13
288 {0x02,0x1F}, //0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10
289 {0x01,0x23}, //0x58, RT_CHANNEL_DOMAIN_WORLD_MKK4
290 };
291
292 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x00,0x02}; //use the conbination for max channel numbers
293
294
295 #ifdef CONFIG_DFS_MASTER
rtw_rfctl_reset_cac(struct rf_ctl_t * rfctl)296 void rtw_rfctl_reset_cac(struct rf_ctl_t *rfctl)
297 {
298 if (rtw_is_long_cac_ch(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset))
299 rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_CE_MS);
300 else
301 rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_MS);
302 }
303
304 /*
305 * check if channel coverage includes new range and the new range is in DFS range
306 * called after radar_detect_ch,bw,offset is updated
307 */
rtw_is_cac_reset_needed(_adapter * adapter)308 bool rtw_is_cac_reset_needed(_adapter *adapter)
309 {
310 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
311 bool needed = _FALSE;
312 u32 pre_hi, pre_lo, hi, lo;
313
314 if (0)
315 DBG_871X("pre_radar_detect_ch:%d, pre_radar_detect_by_sta_link:%d\n"
316 , rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_by_sta_link);
317
318 if (rfctl->pre_radar_detect_by_sta_link == _TRUE)
319 goto exit;
320
321 if (rfctl->pre_radar_detect_ch == 0) {
322 needed = _TRUE;
323 goto exit;
324 }
325
326 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &hi, &lo) == _FALSE)
327 rtw_warn_on(1);
328 if (rtw_chbw_to_freq_range(rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_bw, rfctl->pre_radar_detect_offset, &pre_hi, &pre_lo) == _FALSE)
329 rtw_warn_on(1);
330
331 if (!rtw_is_range_a_in_b(hi, lo, pre_hi, pre_lo)) {
332 if (rtw_is_range_a_in_b(pre_hi, pre_lo, hi, lo)) {
333 /* currrent is supper set of previous */
334 if (rtw_is_dfs_range(hi, lo))
335 needed = _TRUE;
336 } else if (rtw_is_range_overlap(hi, lo, pre_hi, pre_lo)) {
337 /* currrent is not supper set of previous, but has overlap */
338 u32 new_hi, new_lo;
339
340 if (lo < pre_lo) {
341 new_hi = pre_lo;
342 new_lo = lo;
343 if (hi <= pre_lo || hi >= pre_hi) {
344 DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
345 , hi, lo, pre_hi, pre_lo);
346 rtw_warn_on(1);
347 goto exit;
348 }
349 } else if (hi > pre_hi) {
350 new_hi = hi;
351 new_lo = pre_hi;
352 if (lo >= pre_hi && lo <= pre_lo) {
353 DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
354 , hi, lo, pre_hi, pre_lo);
355 rtw_warn_on(1);
356 goto exit;
357 }
358 } else {
359 DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
360 , hi, lo, pre_hi, pre_lo);
361 rtw_warn_on(1);
362 goto exit;
363 }
364
365 if (rtw_is_dfs_range(new_hi, new_lo))
366 needed = _TRUE;
367
368 } else {
369 /* no overlap */
370 if (rtw_is_dfs_range(hi, lo))
371 needed = _TRUE;
372 }
373 }
374
375 exit:
376 return needed;
377 }
378
_rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)379 bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
380 {
381 bool ret = _FALSE;
382 u32 hi = 0, lo = 0;
383 u32 r_hi = 0, r_lo = 0;
384 int i;
385
386 if (rfctl->radar_detect_ch == 0)
387 goto exit;
388
389 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
390 rtw_warn_on(1);
391 goto exit;
392 }
393
394 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
395 , rfctl->radar_detect_bw, rfctl->radar_detect_offset
396 , &r_hi, &r_lo) == _FALSE) {
397 rtw_warn_on(1);
398 goto exit;
399 }
400
401 if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
402 ret = _TRUE;
403
404 exit:
405 return ret;
406 }
407
rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl)408 bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
409 {
410 return _rtw_rfctl_overlap_radar_detect_ch(rfctl
411 , rfctl_to_dvobj(rfctl)->oper_channel
412 , rfctl_to_dvobj(rfctl)->oper_bwmode
413 , rfctl_to_dvobj(rfctl)->oper_ch_offset);
414 }
415
rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t * rfctl)416 bool rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t *rfctl)
417 {
418 return (rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_UNDER_CAC(rfctl));
419 }
420
rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)421 bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
422 {
423 bool ret = _FALSE;
424 u32 hi = 0, lo = 0;
425 int i;
426
427 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
428 goto exit;
429
430 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
431 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
432 rtw_warn_on(1);
433 continue;
434 }
435
436 if (!CH_IS_NON_OCP(&ch_set[i]))
437 continue;
438
439 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
440 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
441 ) {
442 ret = _TRUE;
443 break;
444 }
445 }
446
447 exit:
448 return ret;
449 }
450
451 /**
452 * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
453 * @ch_set: the given channel set
454 * @ch: channel number on which radar is detected
455 * @bw: bandwidth on which radar is detected
456 * @offset: bandwidth offset on which radar is detected
457 * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
458 */
_rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)459 static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
460 {
461 u32 hi = 0, lo = 0;
462 int i;
463
464 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
465 goto exit;
466
467 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
468 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
469 rtw_warn_on(1);
470 continue;
471 }
472
473 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
474 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
475 ) {
476 if (ms >= 0)
477 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
478 else
479 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
480 }
481 }
482
483 exit:
484 return;
485 }
486
rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)487 inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
488 {
489 _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
490 }
491
rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)492 inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
493 {
494 _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
495 }
496 #endif /* CONFIG_DFS_MASTER */
497
rtw_choose_available_chbw(_adapter * adapter,u8 req_bw,u8 * dec_ch,u8 * dec_bw,u8 * dec_offset,u8 d_flags)498 bool rtw_choose_available_chbw(_adapter *adapter, u8 req_bw, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset, u8 d_flags)
499 {
500 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
501 int i;
502
503 if (!dec_ch || !dec_bw || !dec_offset) {
504 rtw_warn_on(1);
505 return _FAIL;
506 }
507
508 for (i = 0; i < mlmeext->max_chan_nums; i++) {
509
510 *dec_ch = mlmeext->channel_set[i].ChannelNum;
511 *dec_bw = req_bw;
512 if (*dec_bw == CHANNEL_WIDTH_20)
513 *dec_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
514 else
515 *dec_offset = rtw_get_offset_by_ch(*dec_ch);
516
517 if ((d_flags & RTW_CHF_2G) && *dec_ch <= 14)
518 continue;
519
520 if ((d_flags & RTW_CHF_5G) && *dec_ch > 14)
521 continue;
522
523 rtw_regsty_adjust_chbw(&adapter->registrypriv, *dec_ch, dec_bw, dec_offset);
524
525 if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
526 continue;
527
528 if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
529 continue;
530
531 if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
532 continue;
533
534 if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
535 continue;
536
537 if (!rtw_chset_is_ch_non_ocp(mlmeext->channel_set, *dec_ch, *dec_bw, *dec_offset))
538 break;
539 }
540
541 return (i < mlmeext->max_chan_nums)?_TRUE:_FALSE;
542 }
543
dump_chset(void * sel,RT_CHANNEL_INFO * ch_set)544 void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set)
545 {
546 u8 i;
547
548 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
549 DBG_871X_SEL_NL(sel, "ch:%3u, freq:%u, scan_type:%d"
550 , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType);
551
552 #ifdef CONFIG_FIND_BEST_CHANNEL
553 DBG_871X_SEL(sel, ", rx_count:%u", ch_set[i].rx_count);
554 #endif
555
556 #ifdef CONFIG_DFS_MASTER
557 if (rtw_is_dfs_ch(ch_set[i].ChannelNum, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
558 if (CH_IS_NON_OCP(&ch_set[i]))
559 DBG_871X_SEL(sel, ", non_ocp:%d"
560 , rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()));
561 else
562 DBG_871X_SEL(sel, ", non_ocp:N/A");
563 }
564 #endif
565
566 DBG_871X_SEL(sel, "\n");
567 }
568
569 DBG_871X_SEL_NL(sel, "total ch number:%d\n", i);
570 }
571
dump_ch_plan_test(void * sel)572 void dump_ch_plan_test(void *sel)
573 {
574 int i, j;
575
576 for (i = 0; i < RT_CHANNEL_DOMAIN_2G_MAX; i++) {
577 for (j = 0; j < RTW_ChannelPlan2G[i].Len; j++) {
578 if (rtw_ch2freq(RTW_ChannelPlan2G[i].Channel[j]) == 0)
579 DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan2G[i].Channel[j], i, j);
580 }
581 }
582
583 for (i = 0; i < RT_CHANNEL_DOMAIN_5G_MAX; i++) {
584 for (j = 0; j < RTW_ChannelPlan5G[i].Len; j++) {
585 if (rtw_ch2freq(RTW_ChannelPlan5G[i].Channel[j]) == 0)
586 DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan5G[i].Channel[j], i, j);
587 }
588 }
589 }
590
591 /*
592 * Search the @param ch in given @param ch_set
593 * @ch_set: the given channel set
594 * @ch: the given channel number
595 *
596 * return the index of channel_num in channel_set, -1 if not found
597 */
rtw_ch_set_search_ch(RT_CHANNEL_INFO * ch_set,const u32 ch)598 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
599 {
600 int i;
601 for(i=0;ch_set[i].ChannelNum!=0;i++){
602 if(ch == ch_set[i].ChannelNum)
603 break;
604 }
605
606 if(i >= ch_set[i].ChannelNum)
607 return -1;
608 return i;
609 }
610
611 /*
612 * Check the @param ch is fit with setband setting of @param adapter
613 * @adapter: the given adapter
614 * @ch: the given channel number
615 *
616 * return _TRUE when check valid, _FALSE not valid
617 */
rtw_mlme_band_check(_adapter * adapter,const u32 ch)618 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
619 {
620 if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
621 || (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
622 || (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
623 ) {
624 return _TRUE;
625 }
626 return _FALSE;
627 }
628
629 /****************************************************************************
630
631 Following are the initialization functions for WiFi MLME
632
633 *****************************************************************************/
634
init_hw_mlme_ext(_adapter * padapter)635 int init_hw_mlme_ext(_adapter *padapter)
636 {
637 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
638
639 //set_opmode_cmd(padapter, infra_client_with_mlme);//removed
640
641 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
642
643 return _SUCCESS;
644 }
645
init_mlme_default_rate_set(_adapter * padapter)646 void init_mlme_default_rate_set(_adapter* padapter)
647 {
648 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
649
650 unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,_9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
651 unsigned char mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
652 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0xff, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
653
654 _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
655 _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
656
657 _rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
658 }
659
init_mlme_ext_priv_value(_adapter * padapter)660 static void init_mlme_ext_priv_value(_adapter* padapter)
661 {
662 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
663 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
664
665 ATOMIC_SET(&pmlmeext->event_seq, 0);
666 pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
667 #ifdef CONFIG_IEEE80211W
668 pmlmeext->sa_query_seq = 0;
669 pmlmeext->mgnt_80211w_IPN=0;
670 pmlmeext->mgnt_80211w_IPN_rx=0;
671 #endif //CONFIG_IEEE80211W
672 pmlmeext->cur_channel = padapter->registrypriv.channel;
673 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
674 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
675
676 pmlmeext->retry = 0;
677
678 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
679
680 init_mlme_default_rate_set(padapter);
681
682 if(pmlmeext->cur_channel > 14)
683 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
684 else
685 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
686
687 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
688 pmlmeext->sitesurvey_res.channel_idx = 0;
689 pmlmeext->sitesurvey_res.bss_cnt = 0;
690 pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
691 pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
692 pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
693 #ifdef CONFIG_SCAN_BACKOP
694 mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
695 mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN|SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
696 pmlmeext->sitesurvey_res.scan_cnt = 0;
697 pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
698 pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
699 #endif
700 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
701 pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
702 #endif
703 pmlmeext->scan_abort = _FALSE;
704
705 pmlmeinfo->state = WIFI_FW_NULL_STATE;
706 pmlmeinfo->reauth_count = 0;
707 pmlmeinfo->reassoc_count = 0;
708 pmlmeinfo->link_count = 0;
709 pmlmeinfo->auth_seq = 0;
710 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
711 pmlmeinfo->key_index = 0;
712 pmlmeinfo->iv = 0;
713
714 pmlmeinfo->enc_algo = _NO_PRIVACY_;
715 pmlmeinfo->authModeToggle = 0;
716
717 _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
718
719 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
720 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
721
722 pmlmeinfo->dialogToken = 0;
723
724 pmlmeext->action_public_rxseq = 0xffff;
725 pmlmeext->action_public_dialog_token = 0xff;
726 }
727
has_channel(RT_CHANNEL_INFO * channel_set,u8 chanset_size,u8 chan)728 static int has_channel(RT_CHANNEL_INFO *channel_set,
729 u8 chanset_size,
730 u8 chan) {
731 int i;
732
733 for (i = 0; i < chanset_size; i++) {
734 if (channel_set[i].ChannelNum == chan) {
735 return 1;
736 }
737 }
738
739 return 0;
740 }
741
init_channel_list(_adapter * padapter,RT_CHANNEL_INFO * channel_set,u8 chanset_size,struct p2p_channels * channel_list)742 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
743 u8 chanset_size,
744 struct p2p_channels *channel_list) {
745
746 struct p2p_oper_class_map op_class[] = {
747 { IEEE80211G, 81, 1, 13, 1, BW20 },
748 { IEEE80211G, 82, 14, 14, 1, BW20 },
749 #if 0 /* Do not enable HT40 on 2 GHz */
750 { IEEE80211G, 83, 1, 9, 1, BW40PLUS },
751 { IEEE80211G, 84, 5, 13, 1, BW40MINUS },
752 #endif
753 { IEEE80211A, 115, 36, 48, 4, BW20 },
754 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
755 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
756 { IEEE80211A, 124, 149, 161, 4, BW20 },
757 { IEEE80211A, 125, 149, 169, 4, BW20 },
758 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
759 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
760 { -1, 0, 0, 0, 0, BW20 }
761 };
762
763 int cla, op;
764
765 cla = 0;
766
767 for (op = 0; op_class[op].op_class; op++) {
768 u8 ch;
769 struct p2p_oper_class_map *o = &op_class[op];
770 struct p2p_reg_class *reg = NULL;
771
772 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
773 if (!has_channel(channel_set, chanset_size, ch)) {
774 continue;
775 }
776
777 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
778 continue;
779
780 if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) &&
781 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
782 continue;
783
784 if (reg == NULL) {
785 reg = &channel_list->reg_class[cla];
786 cla++;
787 reg->reg_class = o->op_class;
788 reg->channels = 0;
789 }
790 reg->channel[reg->channels] = ch;
791 reg->channels++;
792 }
793 }
794 channel_list->reg_classes = cla;
795
796 }
797
init_channel_set(_adapter * padapter,u8 ChannelPlan,RT_CHANNEL_INFO * channel_set)798 static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
799 {
800 u8 index,chanset_size = 0;
801 u8 b5GBand = _FALSE, b2_4GBand = _FALSE;
802 u8 Index2G = 0, Index5G=0;
803
804 if (!rtw_is_channel_plan_valid(ChannelPlan)) {
805 DBG_871X("ChannelPlan ID %x error !!!!!\n",ChannelPlan);
806 return chanset_size;
807 }
808
809 _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
810
811 if(IsSupported24G(padapter->registrypriv.wireless_mode))
812 {
813 b2_4GBand = _TRUE;
814 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
815 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
816 else
817 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
818 }
819
820 if(IsSupported5G(padapter->registrypriv.wireless_mode))
821 {
822 b5GBand = _TRUE;
823 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
824 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
825 else
826 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
827 }
828
829 if(b2_4GBand)
830 {
831 for(index=0;index<RTW_ChannelPlan2G[Index2G].Len;index++)
832 {
833 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
834
835 if( (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||//Channel 1~11 is active, and 12~14 is passive
836 (RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan) )
837 {
838 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
839 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
840 else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
841 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
842 }
843 else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
844 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
845 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)// channel 12~13, passive scan
846 {
847 if(channel_set[chanset_size].ChannelNum <= 11)
848 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
849 else
850 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
851 }
852 else
853 {
854 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
855 }
856
857 chanset_size++;
858 }
859 }
860
861 if(b5GBand)
862 {
863 for(index=0;index<RTW_ChannelPlan5G[Index5G].Len;index++)
864 {
865 #ifdef CONFIG_DFS
866 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
867 if ( channel_set[chanset_size].ChannelNum <= 48
868 || channel_set[chanset_size].ChannelNum >= 149 )
869 {
870 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
871 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
872 else
873 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
874 }
875 else
876 {
877 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
878 }
879 chanset_size++;
880 #else /* CONFIG_DFS */
881 if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
882 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) {
883 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
884 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
885 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
886 else
887 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
888 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
889 chanset_size++;
890 }
891 #endif /* CONFIG_DFS */
892 }
893 }
894
895 Hal_ChannelPlanToRegulation(padapter, ChannelPlan);
896
897 DBG_871X("%s ChannelPlan ID %x Chan num:%d \n",__FUNCTION__,ChannelPlan,chanset_size);
898 return chanset_size;
899 }
900
init_mlme_ext_priv(_adapter * padapter)901 int init_mlme_ext_priv(_adapter* padapter)
902 {
903 int res = _SUCCESS;
904 struct registry_priv* pregistrypriv = &padapter->registrypriv;
905 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
906 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
907 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
908
909 // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
910 //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
911
912 pmlmeext->padapter = padapter;
913
914 //fill_fwpriv(padapter, &(pmlmeext->fwpriv));
915
916 init_mlme_ext_priv_value(padapter);
917 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
918
919 init_mlme_ext_timer(padapter);
920
921 #ifdef CONFIG_AP_MODE
922 init_mlme_ap_info(padapter);
923 #endif
924
925 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
926 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
927 pmlmeext->last_scan_time = 0;
928 pmlmeext->mlmeext_init = _TRUE;
929
930
931 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
932 pmlmeext->active_keep_alive_check = _TRUE;
933 #else
934 pmlmeext->active_keep_alive_check = _FALSE;
935 #endif
936
937 #ifdef DBG_FIXED_CHAN
938 pmlmeext->fixed_chan = 0xFF;
939 #endif
940
941 return res;
942
943 }
944
free_mlme_ext_priv(struct mlme_ext_priv * pmlmeext)945 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
946 {
947 _adapter *padapter = pmlmeext->padapter;
948
949 if (!padapter)
950 return;
951
952 if (rtw_is_drv_stopped(padapter)) {
953 _cancel_timer_ex(&pmlmeext->survey_timer);
954 _cancel_timer_ex(&pmlmeext->link_timer);
955 //_cancel_timer_ex(&pmlmeext->ADDBA_timer);
956 }
957 }
958
cmp_pkt_chnl_diff(_adapter * padapter,u8 * pframe,uint packet_len)959 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
960 { // if the channel is same, return 0. else return channel differential
961 uint len;
962 u8 channel;
963 u8 *p;
964 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
965 if (p)
966 {
967 channel = *(p + 2);
968 if(padapter->mlmeextpriv.cur_channel >= channel)
969 {
970 return (padapter->mlmeextpriv.cur_channel - channel);
971 }
972 else
973 {
974 return (channel-padapter->mlmeextpriv.cur_channel);
975 }
976 }
977 else
978 {
979 return 0;
980 }
981 }
982
_mgt_dispatcher(_adapter * padapter,struct mlme_handler * ptable,union recv_frame * precv_frame)983 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
984 {
985 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
986 u8 *pframe = precv_frame->u.hdr.rx_data;
987
988 if(ptable->func)
989 {
990 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
991 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
992 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
993 {
994 return;
995 }
996
997 ptable->func(padapter, precv_frame);
998 }
999
1000 }
1001
mgt_dispatcher(_adapter * padapter,union recv_frame * precv_frame)1002 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1003 {
1004 int index;
1005 struct mlme_handler *ptable;
1006 #ifdef CONFIG_AP_MODE
1007 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1008 #endif //CONFIG_AP_MODE
1009 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1010 u8 *pframe = precv_frame->u.hdr.rx_data;
1011 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
1012 struct dvobj_priv *psdpriv = padapter->dvobj;
1013 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1014
1015 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1016 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
1017 GetFrameType(pframe), GetFrameSubType(pframe)));
1018
1019 #if 0
1020 {
1021 u8 *pbuf;
1022 pbuf = GetAddr1Ptr(pframe);
1023 DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1024 pbuf = GetAddr2Ptr(pframe);
1025 DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1026 pbuf = GetAddr3Ptr(pframe);
1027 DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1028 }
1029 #endif
1030
1031 if (GetFrameType(pframe) != WIFI_MGT_TYPE)
1032 {
1033 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
1034 return;
1035 }
1036
1037 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1038 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1039 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1040 {
1041 return;
1042 }
1043
1044 ptable = mlme_sta_tbl;
1045
1046 index = GetFrameSubType(pframe) >> 4;
1047
1048 #ifdef CONFIG_TDLS
1049 if((index << 4)==WIFI_ACTION){
1050 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1051 if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) {
1052 DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe)));
1053 On_TDLS_Dis_Rsp(padapter, precv_frame);
1054 }
1055 }
1056 #endif //CONFIG_TDLS
1057
1058 if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler)))
1059 {
1060 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
1061 return;
1062 }
1063 ptable += index;
1064
1065 #if 1
1066 if (psta != NULL)
1067 {
1068 if (GetRetry(pframe))
1069 {
1070 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
1071 {
1072 /* drop the duplicate management frame */
1073 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
1074 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1075 return;
1076 }
1077 }
1078 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1079 }
1080 #else
1081
1082 if(GetRetry(pframe))
1083 {
1084 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
1085 //return;
1086 }
1087 #endif
1088
1089 #ifdef CONFIG_AP_MODE
1090 switch (GetFrameSubType(pframe))
1091 {
1092 case WIFI_AUTH:
1093 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1094 ptable->func = &OnAuth;
1095 else
1096 ptable->func = &OnAuthClient;
1097 //pass through
1098 case WIFI_ASSOCREQ:
1099 case WIFI_REASSOCREQ:
1100 _mgt_dispatcher(padapter, ptable, precv_frame);
1101 #ifdef CONFIG_HOSTAPD_MLME
1102 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1103 rtw_hostapd_mlme_rx(padapter, precv_frame);
1104 #endif
1105 break;
1106 case WIFI_PROBEREQ:
1107 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1108 {
1109 #ifdef CONFIG_HOSTAPD_MLME
1110 rtw_hostapd_mlme_rx(padapter, precv_frame);
1111 #else
1112 _mgt_dispatcher(padapter, ptable, precv_frame);
1113 #endif
1114 }
1115 else
1116 _mgt_dispatcher(padapter, ptable, precv_frame);
1117 break;
1118 case WIFI_BEACON:
1119 _mgt_dispatcher(padapter, ptable, precv_frame);
1120 break;
1121 case WIFI_ACTION:
1122 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1123 _mgt_dispatcher(padapter, ptable, precv_frame);
1124 break;
1125 default:
1126 _mgt_dispatcher(padapter, ptable, precv_frame);
1127 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1128 rtw_hostapd_mlme_rx(padapter, precv_frame);
1129 break;
1130 }
1131 #else
1132
1133 _mgt_dispatcher(padapter, ptable, precv_frame);
1134
1135 #endif
1136
1137 }
1138
1139 #ifdef CONFIG_P2P
p2p_listen_state_process(_adapter * padapter,unsigned char * da)1140 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1141 {
1142 bool response = _TRUE;
1143
1144 #ifdef CONFIG_IOCTL_CFG80211
1145 if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
1146 {
1147 if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE
1148 || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1149 || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1150 || padapter->mlmepriv.wps_probe_resp_ie == NULL
1151 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
1152 )
1153 {
1154 #ifdef CONFIG_DEBUG_CFG80211
1155 DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ",
1156 adapter_wdev_data(padapter)->p2p_enabled,
1157 padapter->mlmepriv.wps_probe_resp_ie,
1158 padapter->mlmepriv.p2p_probe_resp_ie);
1159 DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n",
1160 padapter->cfg80211_wdinfo.is_ro_ch,
1161 rtw_get_oper_ch(padapter),
1162 padapter->wdinfo.listen_channel);
1163 #endif
1164 response = _FALSE;
1165 }
1166 }
1167 else
1168 #endif //CONFIG_IOCTL_CFG80211
1169 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1170 {
1171 // do nothing if the device name is empty
1172 if ( !padapter->wdinfo.device_name_len )
1173 {
1174 response = _FALSE;
1175 }
1176 }
1177
1178 if (response == _TRUE)
1179 issue_probersp_p2p( padapter, da);
1180
1181 return _SUCCESS;
1182 }
1183 #endif //CONFIG_P2P
1184
1185
1186 /****************************************************************************
1187
1188 Following are the callback functions for each subtype of the management frames
1189
1190 *****************************************************************************/
1191
OnProbeReq(_adapter * padapter,union recv_frame * precv_frame)1192 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1193 {
1194 unsigned int ielen;
1195 unsigned char *p;
1196 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1197 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1198 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1199 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1200 u8 *pframe = precv_frame->u.hdr.rx_data;
1201 uint len = precv_frame->u.hdr.len;
1202 u8 is_valid_p2p_probereq = _FALSE;
1203
1204 #ifdef CONFIG_ATMEL_RC_PATCH
1205 u8 *target_ie=NULL, *wps_ie=NULL;
1206 u8 *start;
1207 uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1208 struct sta_info *psta;
1209 struct sta_priv *pstapriv = &padapter->stapriv;
1210 #endif
1211
1212
1213 #ifdef CONFIG_P2P
1214 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1215 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1216 u8 wifi_test_chk_rate = 1;
1217
1218 #ifdef CONFIG_IOCTL_CFG80211
1219 if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1220 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1221 && (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1222 ) {
1223 rtw_cfg80211_rx_probe_request(padapter, pframe, len);
1224 return _SUCCESS;
1225 }
1226 #endif /* CONFIG_IOCTL_CFG80211 */
1227
1228 if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1229 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
1230 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1231 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1232 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1233 )
1234 {
1235 // Commented by Albert 2011/03/17
1236 // mcs_rate = 0 -> CCK 1M rate
1237 // mcs_rate = 1 -> CCK 2M rate
1238 // mcs_rate = 2 -> CCK 5.5M rate
1239 // mcs_rate = 3 -> CCK 11M rate
1240 // In the P2P mode, the driver should not support the CCK rate
1241
1242 // Commented by Kurt 2012/10/16
1243 // IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
1244 if (padapter->registrypriv.wifi_spec == 1)
1245 {
1246 if ( pattrib->data_rate <= 3 )
1247 {
1248 wifi_test_chk_rate = 0;
1249 }
1250 }
1251
1252 if( wifi_test_chk_rate == 1 )
1253 {
1254 if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
1255 {
1256 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
1257 {
1258 // FIXME
1259 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1260 report_survey_event(padapter, precv_frame);
1261
1262 p2p_listen_state_process( padapter, get_sa(pframe));
1263
1264 return _SUCCESS;
1265 }
1266
1267 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1268 {
1269 goto _continue;
1270 }
1271 }
1272 }
1273 }
1274
1275 _continue:
1276 #endif //CONFIG_P2P
1277
1278 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1279 {
1280 return _SUCCESS;
1281 }
1282
1283 if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
1284 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
1285 {
1286 return _SUCCESS;
1287 }
1288
1289
1290 //DBG_871X("+OnProbeReq\n");
1291
1292
1293 #ifdef CONFIG_ATMEL_RC_PATCH
1294 if ((wps_ie = rtw_get_wps_ie(
1295 pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1296 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1297 NULL, &wps_ielen))) {
1298
1299 target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1300 }
1301 if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) {
1302 //psta->flag_atmel_rc = 1;
1303 unsigned char *sa_addr = get_sa(pframe);
1304 printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n",
1305 __func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5));
1306 _rtw_memcpy( pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1307 }
1308 #endif
1309
1310
1311 #ifdef CONFIG_AUTO_AP_MODE
1312 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1313 pmlmepriv->cur_network.join_res == _TRUE)
1314 {
1315 _irqL irqL;
1316 struct sta_info *psta;
1317 u8 *mac_addr, *peer_addr;
1318 struct sta_priv *pstapriv = &padapter->stapriv;
1319 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
1320 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
1321
1322 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1323 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1324
1325 if(!p || ielen !=14)
1326 goto _non_rc_device;
1327
1328 if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
1329 goto _non_rc_device;
1330
1331 if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
1332 {
1333 DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1334 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
1335
1336 goto _non_rc_device;
1337 }
1338
1339 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
1340
1341 //new a station
1342 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1343 if (psta == NULL)
1344 {
1345 // allocate a new one
1346 DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
1347 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1348 if (psta == NULL)
1349 {
1350 //TODO:
1351 DBG_871X(" Exceed the upper limit of supported clients...\n");
1352 return _SUCCESS;
1353 }
1354
1355 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1356 if (rtw_is_list_empty(&psta->asoc_list))
1357 {
1358 psta->expire_to = pstapriv->expire_to;
1359 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1360 pstapriv->asoc_list_cnt++;
1361 }
1362 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1363
1364 //generate pairing ID
1365 mac_addr = adapter_mac_addr(padapter);
1366 peer_addr = psta->hwaddr;
1367 psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
1368
1369 //update peer stainfo
1370 psta->isrc = _TRUE;
1371 //psta->aid = 0;
1372 //psta->mac_id = 2;
1373
1374 /* get a unique AID */
1375 if (psta->aid > 0) {
1376 DBG_871X("old AID %d\n", psta->aid);
1377 } else {
1378 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1379 if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1380 break;
1381
1382 if (psta->aid > pstapriv->max_num_sta) {
1383 psta->aid = 0;
1384 DBG_871X("no room for more AIDs\n");
1385 return _SUCCESS;
1386 } else {
1387 pstapriv->sta_aid[psta->aid - 1] = psta;
1388 DBG_871X("allocate new AID = (%d)\n", psta->aid);
1389 }
1390 }
1391
1392 psta->qos_option = 1;
1393 psta->bw_mode = CHANNEL_WIDTH_20;
1394 psta->ieee8021x_blocked = _FALSE;
1395 #ifdef CONFIG_80211N_HT
1396 psta->htpriv.ht_option = _TRUE;
1397 psta->htpriv.ampdu_enable = _FALSE;
1398 psta->htpriv.sgi_20m = _FALSE;
1399 psta->htpriv.sgi_40m = _FALSE;
1400 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1401 psta->htpriv.agg_enable_bitmap = 0x0;//reset
1402 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
1403 #endif
1404
1405 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1406
1407 _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1408
1409 _enter_critical_bh(&psta->lock, &irqL);
1410 psta->state |= _FW_LINKED;
1411 _exit_critical_bh(&psta->lock, &irqL);
1412
1413 report_add_sta_event(padapter, psta->hwaddr, psta->aid);
1414
1415 }
1416
1417 issue_probersp(padapter, get_sa(pframe), _FALSE);
1418
1419 return _SUCCESS;
1420
1421 }
1422
1423 _non_rc_device:
1424
1425 return _SUCCESS;
1426
1427 #endif //CONFIG_AUTO_AP_MODE
1428
1429
1430 #ifdef CONFIG_CONCURRENT_MODE
1431 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1432 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1433 {
1434 //don't process probe req
1435 return _SUCCESS;
1436 }
1437 #endif
1438
1439 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1440 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1441
1442
1443 //check (wildcard) SSID
1444 if (p != NULL)
1445 {
1446 if(is_valid_p2p_probereq == _TRUE)
1447 {
1448 goto _issue_probersp;
1449 }
1450
1451 if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1452 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1453 )
1454 {
1455 return _SUCCESS;
1456 }
1457
1458 _issue_probersp:
1459 if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1460 pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1461 {
1462 //DBG_871X("+issue_probersp during ap mode\n");
1463 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
1464 }
1465
1466 }
1467
1468 return _SUCCESS;
1469
1470 }
1471
OnProbeRsp(_adapter * padapter,union recv_frame * precv_frame)1472 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1473 {
1474 struct sta_info *psta;
1475 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1476 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1477 struct sta_priv *pstapriv = &padapter->stapriv;
1478 u8 *pframe = precv_frame->u.hdr.rx_data;
1479 #ifdef CONFIG_P2P
1480 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1481 #endif
1482
1483
1484 #ifdef CONFIG_P2P
1485 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
1486 {
1487 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
1488 {
1489 if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1490 {
1491 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
1492 {
1493 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1494 issue_p2p_provision_request( padapter,
1495 pwdinfo->tx_prov_disc_info.ssid.Ssid,
1496 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1497 pwdinfo->tx_prov_disc_info.peerDevAddr );
1498 }
1499 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
1500 {
1501 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1502 issue_p2p_provision_request( padapter,
1503 NULL,
1504 0,
1505 pwdinfo->tx_prov_disc_info.peerDevAddr );
1506 }
1507 }
1508 }
1509 return _SUCCESS;
1510 }
1511 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
1512 {
1513 if ( _TRUE == pwdinfo->nego_req_info.benable )
1514 {
1515 DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
1516 if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1517 {
1518 pwdinfo->nego_req_info.benable = _FALSE;
1519 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
1520 }
1521 }
1522 }
1523 else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
1524 {
1525 if ( _TRUE == pwdinfo->invitereq_info.benable )
1526 {
1527 DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
1528 if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1529 {
1530 pwdinfo->invitereq_info.benable = _FALSE;
1531 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
1532 }
1533 }
1534 }
1535 #endif
1536
1537
1538 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1539 report_survey_event(padapter, precv_frame);
1540 #ifdef CONFIG_CONCURRENT_MODE
1541 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1542 #endif
1543 return _SUCCESS;
1544 }
1545
1546 #if 0 //move to validate_recv_mgnt_frame
1547 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1548 {
1549 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1550 {
1551 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1552 {
1553 psta->sta_stats.rx_mgnt_pkts++;
1554 }
1555 }
1556 }
1557 #endif
1558
1559 return _SUCCESS;
1560
1561 }
1562
OnBeacon(_adapter * padapter,union recv_frame * precv_frame)1563 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1564 {
1565 int cam_idx;
1566 struct sta_info *psta;
1567 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1568 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1569 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1570 struct sta_priv *pstapriv = &padapter->stapriv;
1571 u8 *pframe = precv_frame->u.hdr.rx_data;
1572 uint len = precv_frame->u.hdr.len;
1573 WLAN_BSSID_EX *pbss;
1574 int ret = _SUCCESS;
1575 u8 *p = NULL;
1576 u32 ielen = 0;
1577 #ifdef CONFIG_TDLS
1578 struct sta_info *ptdls_sta;
1579 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1580 #endif /* CONFIG_TDLS */
1581
1582 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1583 p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
1584 if ((p != NULL) && (ielen > 0))
1585 {
1586 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
1587 {
1588 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
1589 DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe)));
1590 *(p + 1) = ielen - 1;
1591 }
1592 }
1593 #endif
1594
1595 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1596 report_survey_event(padapter, precv_frame);
1597 #ifdef CONFIG_CONCURRENT_MODE
1598 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1599 #endif
1600 return _SUCCESS;
1601 }
1602
1603 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1604 {
1605 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1606 {
1607 //we should update current network before auth, or some IE is wrong
1608 pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1609 if (pbss) {
1610 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1611 struct beacon_keys recv_beacon;
1612
1613 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1614 rtw_get_bcn_info(&(pmlmepriv->cur_network));
1615
1616 // update bcn keys
1617 if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1618 DBG_871X("%s: beacon keys ready\n", __func__);
1619 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1620 &recv_beacon, sizeof(recv_beacon));
1621 pmlmepriv->new_beacon_cnts = 0;
1622 }
1623 else {
1624 DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__);
1625 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1626 pmlmepriv->new_beacon_cnts = 0;
1627 }
1628 }
1629 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1630 }
1631
1632 //check the vendor of the assoc AP
1633 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
1634
1635 //update TSF Value
1636 update_TSF(pmlmeext, pframe, len);
1637
1638 //reset for adaptive_early_32k
1639 pmlmeext->adaptive_tsf_done = _FALSE;
1640 pmlmeext->DrvBcnEarly = 0xff;
1641 pmlmeext->DrvBcnTimeOut = 0xff;
1642 pmlmeext->bcn_cnt = 0;
1643 _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1644 _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1645
1646 #ifdef CONFIG_P2P_PS
1647 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1648 #endif //CONFIG_P2P_PS
1649
1650 #if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE)
1651 if (padapter->registrypriv.wifi_spec) {
1652 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1653 if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
1654 DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n ");
1655 return _SUCCESS;
1656 }
1657 }
1658 }
1659 #endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE
1660
1661 //start auth
1662 start_clnt_auth(padapter);
1663
1664 return _SUCCESS;
1665 }
1666
1667 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1668 {
1669 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1670 {
1671 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1672 //Merge from 8712 FW code
1673 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
1674 { // join wrong channel, deauth and reconnect
1675 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1676
1677 report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE);
1678 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1679 return _SUCCESS;
1680 }
1681 #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
1682
1683 ret = rtw_check_bcn_info(padapter, pframe, len);
1684 if (!ret) {
1685 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1686 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0);
1687 return _SUCCESS;
1688 }
1689 //update WMM, ERP in the beacon
1690 //todo: the timer is used instead of the number of the beacon received
1691 if ((sta_rx_pkts(psta) & 0xf) == 0)
1692 {
1693 //DBG_871X("update_bcn_info\n");
1694 update_beacon_info(padapter, pframe, len, psta);
1695 }
1696
1697 adaptive_early_32k(pmlmeext, pframe, len);
1698
1699 #ifdef CONFIG_TDLS
1700 #ifdef CONFIG_TDLS_CH_SW
1701 if (padapter->tdlsinfo.ch_switch_prohibited == _FALSE)
1702 {
1703 /* Send TDLS Channel Switch Request when receiving Beacon */
1704 if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1705 ptdlsinfo->chsw_info.ch_sw_state |= TDLS_WAIT_CH_RSP_STATE;
1706 /* DBG_871X("[%s] issue_tdls_ch_switch_req to "MAC_FMT"\n", __FUNCTION__, MAC_ARG(padapter->tdlsinfo.chsw_info.addr)); */
1707 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1708 if (ptdls_sta != NULL) {
1709 if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
1710 issue_tdls_ch_switch_req(padapter, ptdls_sta);
1711 }
1712 }
1713 }
1714 #endif
1715 #endif /* CONFIG_TDLS */
1716
1717 #ifdef CONFIG_DFS
1718 process_csa_ie(padapter, pframe, len); //channel switch announcement
1719 #endif //CONFIG_DFS
1720
1721 #ifdef CONFIG_P2P_PS
1722 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1723 #endif //CONFIG_P2P_PS
1724
1725 #if 0 //move to validate_recv_mgnt_frame
1726 psta->sta_stats.rx_mgnt_pkts++;
1727 #endif
1728 }
1729 }
1730 else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
1731 {
1732 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1733 {
1734 //update WMM, ERP in the beacon
1735 //todo: the timer is used instead of the number of the beacon received
1736 if ((sta_rx_pkts(psta) & 0xf) == 0)
1737 {
1738 //DBG_871X("update_bcn_info\n");
1739 update_beacon_info(padapter, pframe, len, psta);
1740 }
1741
1742 #if 0 //move to validate_recv_mgnt_frame
1743 psta->sta_stats.rx_mgnt_pkts++;
1744 #endif
1745 }
1746 else
1747 {
1748 //allocate a new CAM entry for IBSS station
1749 if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
1750 {
1751 goto _END_ONBEACON_;
1752 }
1753
1754 //get supported rate
1755 if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL)
1756 {
1757 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
1758 goto _END_ONBEACON_;
1759 }
1760
1761 //update TSF Value
1762 update_TSF(pmlmeext, pframe, len);
1763
1764 //report sta add event
1765 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
1766 }
1767 }
1768 }
1769
1770 _END_ONBEACON_:
1771
1772 return _SUCCESS;
1773
1774 }
1775
OnAuth(_adapter * padapter,union recv_frame * precv_frame)1776 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1777 {
1778 #ifdef CONFIG_AP_MODE
1779 _irqL irqL;
1780 unsigned int auth_mode, seq, ie_len;
1781 unsigned char *sa, *p;
1782 u16 algorithm;
1783 int status;
1784 static struct sta_info stat;
1785 struct sta_info *pstat=NULL;
1786 struct sta_priv *pstapriv = &padapter->stapriv;
1787 struct security_priv *psecuritypriv = &padapter->securitypriv;
1788 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1789 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1790 u8 *pframe = precv_frame->u.hdr.rx_data;
1791 uint len = precv_frame->u.hdr.len;
1792 u8 offset = 0;
1793
1794
1795 #ifdef CONFIG_CONCURRENT_MODE
1796 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1797 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1798 {
1799 //don't process auth request;
1800 return _SUCCESS;
1801 }
1802 #endif //CONFIG_CONCURRENT_MODE
1803
1804 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1805 return _FAIL;
1806
1807 DBG_871X("+OnAuth\n");
1808
1809 sa = GetAddr2Ptr(pframe);
1810
1811 auth_mode = psecuritypriv->dot11AuthAlgrthm;
1812
1813 if (GetPrivacy(pframe))
1814 {
1815 u8 *iv;
1816 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
1817
1818 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
1819 prxattrib->encrypt = _WEP40_;
1820
1821 iv = pframe+prxattrib->hdrlen;
1822 prxattrib->key_index = ((iv[3]>>6)&0x3);
1823
1824 prxattrib->iv_len = 4;
1825 prxattrib->icv_len = 4;
1826
1827 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
1828
1829 offset = 4;
1830 }
1831
1832 algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1833 seq = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1834
1835 DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
1836
1837 if (auth_mode == 2 &&
1838 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1839 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1840 auth_mode = 0;
1841
1842 if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled
1843 (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled
1844 {
1845 DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1846 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1847
1848 status = _STATS_NO_SUPP_ALG_;
1849
1850 goto auth_fail;
1851 }
1852
1853 #if 0 //ACL control
1854 phead = &priv->wlan_acl_list;
1855 plist = phead->next;
1856 //check sa
1857 if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected.
1858 res = FAIL;
1859 else
1860 res = SUCCESS;
1861
1862 while(plist != phead)
1863 {
1864 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
1865 plist = plist->next;
1866 if (!memcmp((void *)sa, paclnode->addr, 6)) {
1867 if (paclnode->mode & 2) { // deny
1868 res = FAIL;
1869 break;
1870 }
1871 else {
1872 res = SUCCESS;
1873 break;
1874 }
1875 }
1876 }
1877
1878 if (res != SUCCESS) {
1879 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
1880 return FAIL;
1881 }
1882 #else
1883 if(rtw_access_ctrl(padapter, sa) == _FALSE)
1884 {
1885 status = _STATS_UNABLE_HANDLE_STA_;
1886 goto auth_fail;
1887 }
1888 #endif
1889
1890 pstat = rtw_get_stainfo(pstapriv, sa);
1891 if (pstat == NULL)
1892 {
1893
1894 // allocate a new one
1895 DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
1896 pstat = rtw_alloc_stainfo(pstapriv, sa);
1897 if (pstat == NULL)
1898 {
1899 DBG_871X(" Exceed the upper limit of supported clients...\n");
1900 status = _STATS_UNABLE_HANDLE_STA_;
1901 goto auth_fail;
1902 }
1903
1904 pstat->state = WIFI_FW_AUTH_NULL;
1905 pstat->auth_seq = 0;
1906
1907 //pstat->flags = 0;
1908 //pstat->capability = 0;
1909 } else {
1910 #ifdef CONFIG_IEEE80211W
1911 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1912 #endif /* CONFIG_IEEE80211W */
1913 {
1914
1915 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1916 if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
1917 rtw_list_delete(&pstat->asoc_list);
1918 pstapriv->asoc_list_cnt--;
1919 if (pstat->expire_to > 0)
1920 ;/* TODO: STA re_auth within expire_to */
1921 }
1922 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1923
1924 if (seq == 1)
1925 ; /* TODO: STA re_auth and auth timeout */
1926
1927 }
1928 }
1929
1930 #ifdef CONFIG_IEEE80211W
1931 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1932 #endif /* CONFIG_IEEE80211W */
1933 {
1934 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
1935 if (rtw_is_list_empty(&pstat->auth_list)) {
1936
1937 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
1938 pstapriv->auth_list_cnt++;
1939 }
1940 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
1941 }
1942
1943 if (pstat->auth_seq == 0)
1944 pstat->expire_to = pstapriv->auth_to;
1945
1946
1947 if ((pstat->auth_seq + 1) != seq)
1948 {
1949 DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1950 seq, pstat->auth_seq+1);
1951 status = _STATS_OUT_OF_AUTH_SEQ_;
1952 goto auth_fail;
1953 }
1954
1955 if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
1956 {
1957 if (seq == 1)
1958 {
1959 #ifdef CONFIG_IEEE80211W
1960 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1961 #endif /* CONFIG_IEEE80211W */
1962 {
1963 pstat->state &= ~WIFI_FW_AUTH_NULL;
1964 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1965 pstat->expire_to = pstapriv->assoc_to;
1966 }
1967 pstat->authalg = algorithm;
1968 }
1969 else
1970 {
1971 DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1972 seq, pstat->auth_seq+1);
1973 status = _STATS_OUT_OF_AUTH_SEQ_;
1974 goto auth_fail;
1975 }
1976 }
1977 else // shared system or auto authentication
1978 {
1979 if (seq == 1)
1980 {
1981 //prepare for the challenging txt...
1982
1983 //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
1984 _rtw_memset((void *)pstat->chg_txt, 78, 128);
1985 #ifdef CONFIG_IEEE80211W
1986 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
1987 #endif /* CONFIG_IEEE80211W */
1988 {
1989 pstat->state &= ~WIFI_FW_AUTH_NULL;
1990 pstat->state |= WIFI_FW_AUTH_STATE;
1991 }
1992 pstat->authalg = algorithm;
1993 pstat->auth_seq = 2;
1994 }
1995 else if (seq == 3)
1996 {
1997 //checking for challenging txt...
1998 DBG_871X("checking for challenging txt...\n");
1999
2000 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2001 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2002
2003 if((p==NULL) || (ie_len<=0))
2004 {
2005 DBG_871X("auth rejected because challenge failure!(1)\n");
2006 status = _STATS_CHALLENGE_FAIL_;
2007 goto auth_fail;
2008 }
2009
2010 if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
2011 {
2012 #ifdef CONFIG_IEEE80211W
2013 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2014 #endif /* CONFIG_IEEE80211W */
2015 {
2016 pstat->state &= (~WIFI_FW_AUTH_STATE);
2017 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2018 /* challenging txt is correct... */
2019 pstat->expire_to = pstapriv->assoc_to;
2020 }
2021 }
2022 else
2023 {
2024 DBG_871X("auth rejected because challenge failure!\n");
2025 status = _STATS_CHALLENGE_FAIL_;
2026 goto auth_fail;
2027 }
2028 }
2029 else
2030 {
2031 DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2032 seq, pstat->auth_seq+1);
2033 status = _STATS_OUT_OF_AUTH_SEQ_;
2034 goto auth_fail;
2035 }
2036 }
2037
2038
2039 // Now, we are going to issue_auth...
2040 pstat->auth_seq = seq + 1;
2041
2042 #ifdef CONFIG_NATIVEAP_MLME
2043 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2044 #endif
2045
2046 if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2047 pstat->auth_seq = 0;
2048
2049
2050 return _SUCCESS;
2051
2052 auth_fail:
2053
2054 if(pstat)
2055 rtw_free_stainfo(padapter , pstat);
2056
2057 pstat = &stat;
2058 _rtw_memset((char *)pstat, '\0', sizeof(stat));
2059 pstat->auth_seq = 2;
2060 _rtw_memcpy(pstat->hwaddr, sa, 6);
2061
2062 #ifdef CONFIG_NATIVEAP_MLME
2063 issue_auth(padapter, pstat, (unsigned short)status);
2064 #endif
2065
2066 #endif
2067 return _FAIL;
2068
2069 }
2070
OnAuthClient(_adapter * padapter,union recv_frame * precv_frame)2071 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2072 {
2073 unsigned int seq, len, status, algthm, offset;
2074 unsigned char *p;
2075 unsigned int go2asoc = 0;
2076 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2077 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2078 u8 *pframe = precv_frame->u.hdr.rx_data;
2079 uint pkt_len = precv_frame->u.hdr.len;
2080
2081 DBG_871X("%s\n", __FUNCTION__);
2082
2083 //check A1 matches or not
2084 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2085 return _SUCCESS;
2086
2087 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2088 return _SUCCESS;
2089
2090 offset = (GetPrivacy(pframe))? 4: 0;
2091
2092 algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2093 seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2094 status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2095
2096 if (status != 0)
2097 {
2098 DBG_871X("clnt auth fail, status: %d\n", status);
2099 if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
2100 {
2101 if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2102 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2103 else
2104 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2105 //pmlmeinfo->reauth_count = 0;
2106 }
2107
2108 set_link_timer(pmlmeext, 1);
2109 goto authclnt_fail;
2110 }
2111
2112 if (seq == 2)
2113 {
2114 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2115 {
2116 // legendary shared system
2117 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2118 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2119
2120 if (p == NULL)
2121 {
2122 //DBG_871X("marc: no challenge text?\n");
2123 goto authclnt_fail;
2124 }
2125
2126 _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2127 pmlmeinfo->auth_seq = 3;
2128 issue_auth(padapter, NULL, 0);
2129 set_link_timer(pmlmeext, REAUTH_TO);
2130
2131 return _SUCCESS;
2132 }
2133 else
2134 {
2135 // open system
2136 go2asoc = 1;
2137 }
2138 }
2139 else if (seq == 4)
2140 {
2141 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2142 {
2143 go2asoc = 1;
2144 }
2145 else
2146 {
2147 goto authclnt_fail;
2148 }
2149 }
2150 else
2151 {
2152 // this is also illegal
2153 //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
2154 goto authclnt_fail;
2155 }
2156
2157 if (go2asoc)
2158 {
2159 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
2160 start_clnt_assoc(padapter);
2161 return _SUCCESS;
2162 }
2163
2164 authclnt_fail:
2165
2166 //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
2167
2168 return _FAIL;
2169
2170 }
2171
OnAssocReq(_adapter * padapter,union recv_frame * precv_frame)2172 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2173 {
2174 #ifdef CONFIG_AP_MODE
2175 _irqL irqL;
2176 u16 capab_info, listen_interval;
2177 struct rtw_ieee802_11_elems elems;
2178 struct sta_info *pstat;
2179 unsigned char reassoc, *p, *pos, *wpa_ie;
2180 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2181 int i, ie_len, wpa_ie_len, left;
2182 unsigned char supportRate[16];
2183 int supportRateNum;
2184 unsigned short status = _STATS_SUCCESSFUL_;
2185 unsigned short frame_type, ie_offset=0;
2186 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2187 struct security_priv *psecuritypriv = &padapter->securitypriv;
2188 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2189 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2190 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
2191 struct sta_priv *pstapriv = &padapter->stapriv;
2192 u8 *pframe = precv_frame->u.hdr.rx_data;
2193 uint pkt_len = precv_frame->u.hdr.len;
2194 #ifdef CONFIG_P2P
2195 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2196 u8 p2p_status_code = P2P_STATUS_SUCCESS;
2197 u8 *p2pie;
2198 u32 p2pielen = 0;
2199 #ifdef CONFIG_WFD
2200 u8 wfd_ie[ 128 ] = { 0x00 };
2201 u32 wfd_ielen = 0;
2202 #endif // CONFIG_WFD
2203 #endif //CONFIG_P2P
2204
2205 #ifdef CONFIG_CONCURRENT_MODE
2206 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
2207 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
2208 {
2209 //don't process assoc request;
2210 return _SUCCESS;
2211 }
2212 #endif //CONFIG_CONCURRENT_MODE
2213
2214 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2215 return _FAIL;
2216
2217 frame_type = GetFrameSubType(pframe);
2218 if (frame_type == WIFI_ASSOCREQ)
2219 {
2220 reassoc = 0;
2221 ie_offset = _ASOCREQ_IE_OFFSET_;
2222 }
2223 else // WIFI_REASSOCREQ
2224 {
2225 reassoc = 1;
2226 ie_offset = _REASOCREQ_IE_OFFSET_;
2227 }
2228
2229
2230 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2231 DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2232 "\n", reassoc, (unsigned long)pkt_len);
2233 return _FAIL;
2234 }
2235
2236 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2237 if (pstat == (struct sta_info *)NULL)
2238 {
2239 status = _RSON_CLS2_;
2240 goto asoc_class2_error;
2241 }
2242
2243 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
2244 //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2245 //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
2246 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
2247
2248 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2249 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2250
2251
2252 DBG_871X("%s\n", __FUNCTION__);
2253
2254 // check if this stat has been successfully authenticated/assocated
2255 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
2256 {
2257 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
2258 {
2259 status = _RSON_CLS2_;
2260 goto asoc_class2_error;
2261 }
2262 else
2263 {
2264 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2265 pstat->state |= WIFI_FW_ASSOC_STATE;
2266 }
2267 }
2268 else
2269 {
2270 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2271 pstat->state |= WIFI_FW_ASSOC_STATE;
2272 }
2273
2274
2275 #if 0// todo:tkip_countermeasures
2276 if (hapd->tkip_countermeasures) {
2277 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2278 goto fail;
2279 }
2280 #endif
2281
2282 pstat->capability = capab_info;
2283
2284 #if 0//todo:
2285 //check listen_interval
2286 if (listen_interval > hapd->conf->max_listen_interval) {
2287 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2288 HOSTAPD_LEVEL_DEBUG,
2289 "Too large Listen Interval (%d)",
2290 listen_interval);
2291 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2292 goto fail;
2293 }
2294
2295 pstat->listen_interval = listen_interval;
2296 #endif
2297
2298 //now parse all ieee802_11 ie to point to elems
2299 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2300 !elems.ssid) {
2301 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
2302 MAC_ARG(pstat->hwaddr));
2303 status = _STATS_FAILURE_;
2304 goto OnAssocReqFail;
2305 }
2306
2307
2308 // now we should check all the fields...
2309 // checking SSID
2310 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2311 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2312 if (p == NULL)
2313 {
2314 status = _STATS_FAILURE_;
2315 }
2316
2317 if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
2318 status = _STATS_FAILURE_;
2319 else
2320 {
2321 // check if ssid match
2322 if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2323 status = _STATS_FAILURE_;
2324
2325 if (ie_len != cur->Ssid.SsidLength)
2326 status = _STATS_FAILURE_;
2327 }
2328
2329 if(_STATS_SUCCESSFUL_ != status)
2330 goto OnAssocReqFail;
2331
2332 // check if the supported rate is ok
2333 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2334 if (p == NULL) {
2335 DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
2336 // use our own rate set as statoin used
2337 //_rtw_memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN);
2338 //supportRateNum = AP_BSSRATE_LEN;
2339
2340 status = _STATS_FAILURE_;
2341 goto OnAssocReqFail;
2342 }
2343 else {
2344 _rtw_memcpy(supportRate, p+2, ie_len);
2345 supportRateNum = ie_len;
2346
2347 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
2348 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2349 if (p != NULL) {
2350
2351 if(supportRateNum<=sizeof(supportRate))
2352 {
2353 _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
2354 supportRateNum += ie_len;
2355 }
2356 }
2357 }
2358
2359 //todo: mask supportRate between AP & STA -> move to update raid
2360 //get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0);
2361
2362 //update station supportRate
2363 pstat->bssratelen = supportRateNum;
2364 _rtw_memcpy(pstat->bssrateset, supportRate, supportRateNum);
2365 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2366
2367 //check RSN/WPA/WPS
2368 pstat->dot8021xalg = 0;
2369 pstat->wpa_psk = 0;
2370 pstat->wpa_group_cipher = 0;
2371 pstat->wpa2_group_cipher = 0;
2372 pstat->wpa_pairwise_cipher = 0;
2373 pstat->wpa2_pairwise_cipher = 0;
2374 _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2375 if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2376
2377 int group_cipher=0, pairwise_cipher=0;
2378
2379 wpa_ie = elems.rsn_ie;
2380 wpa_ie_len = elems.rsn_ie_len;
2381
2382 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2383 {
2384 pstat->dot8021xalg = 1;//psk, todo:802.1x
2385 pstat->wpa_psk |= BIT(1);
2386
2387 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
2388 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
2389
2390 if(!pstat->wpa2_group_cipher)
2391 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2392
2393 if(!pstat->wpa2_pairwise_cipher)
2394 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2395 }
2396 else
2397 {
2398 status = WLAN_STATUS_INVALID_IE;
2399 }
2400
2401 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2402
2403 int group_cipher=0, pairwise_cipher=0;
2404
2405 wpa_ie = elems.wpa_ie;
2406 wpa_ie_len = elems.wpa_ie_len;
2407
2408 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2409 {
2410 pstat->dot8021xalg = 1;//psk, todo:802.1x
2411 pstat->wpa_psk |= BIT(0);
2412
2413 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
2414 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
2415
2416 if(!pstat->wpa_group_cipher)
2417 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2418
2419 if(!pstat->wpa_pairwise_cipher)
2420 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2421
2422 }
2423 else
2424 {
2425 status = WLAN_STATUS_INVALID_IE;
2426 }
2427
2428 } else {
2429 wpa_ie = NULL;
2430 wpa_ie_len = 0;
2431 }
2432
2433 if(_STATS_SUCCESSFUL_ != status)
2434 goto OnAssocReqFail;
2435
2436 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2437 //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
2438 if(wpa_ie == NULL) {
2439 if (elems.wps_ie) {
2440 DBG_871X("STA included WPS IE in "
2441 "(Re)Association Request - assume WPS is "
2442 "used\n");
2443 pstat->flags |= WLAN_STA_WPS;
2444 //wpabuf_free(sta->wps_ie);
2445 //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
2446 // elems.wps_ie_len - 4);
2447 } else {
2448 DBG_871X("STA did not include WPA/RSN IE "
2449 "in (Re)Association Request - possible WPS "
2450 "use\n");
2451 pstat->flags |= WLAN_STA_MAYBE_WPS;
2452 }
2453
2454
2455 // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
2456 // that the selected registrar of AP is _FLASE
2457 if((psecuritypriv->wpa_psk >0)
2458 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
2459 {
2460 if(pmlmepriv->wps_beacon_ie)
2461 {
2462 u8 selected_registrar = 0;
2463
2464 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2465
2466 if(!selected_registrar)
2467 {
2468 DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2469
2470 status = _STATS_UNABLE_HANDLE_STA_;
2471
2472 goto OnAssocReqFail;
2473 }
2474 }
2475 }
2476
2477 }
2478 else
2479 {
2480 int copy_len;
2481
2482 if(psecuritypriv->wpa_psk == 0)
2483 {
2484 DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
2485 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2486
2487 status = WLAN_STATUS_INVALID_IE;
2488
2489 goto OnAssocReqFail;
2490
2491 }
2492
2493 if (elems.wps_ie) {
2494 DBG_871X("STA included WPS IE in "
2495 "(Re)Association Request - WPS is "
2496 "used\n");
2497 pstat->flags |= WLAN_STA_WPS;
2498 copy_len=0;
2499 }
2500 else
2501 {
2502 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
2503 }
2504
2505
2506 if(copy_len>0)
2507 _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
2508
2509 }
2510
2511
2512 // check if there is WMM IE & support WWM-PS
2513 pstat->flags &= ~WLAN_STA_WME;
2514 pstat->qos_option = 0;
2515 pstat->qos_info = 0;
2516 pstat->has_legacy_ac = _TRUE;
2517 pstat->uapsd_vo = 0;
2518 pstat->uapsd_vi = 0;
2519 pstat->uapsd_be = 0;
2520 pstat->uapsd_bk = 0;
2521 if (pmlmepriv->qospriv.qos_option)
2522 {
2523 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
2524 for (;;)
2525 {
2526 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2527 if (p != NULL) {
2528 if (_rtw_memcmp(p+2, WMM_IE, 6)) {
2529
2530 pstat->flags |= WLAN_STA_WME;
2531
2532 pstat->qos_option = 1;
2533 pstat->qos_info = *(p+8);
2534
2535 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
2536
2537 if((pstat->qos_info&0xf) !=0xf)
2538 pstat->has_legacy_ac = _TRUE;
2539 else
2540 pstat->has_legacy_ac = _FALSE;
2541
2542 if(pstat->qos_info&0xf)
2543 {
2544 if(pstat->qos_info&BIT(0))
2545 pstat->uapsd_vo = BIT(0)|BIT(1);
2546 else
2547 pstat->uapsd_vo = 0;
2548
2549 if(pstat->qos_info&BIT(1))
2550 pstat->uapsd_vi = BIT(0)|BIT(1);
2551 else
2552 pstat->uapsd_vi = 0;
2553
2554 if(pstat->qos_info&BIT(2))
2555 pstat->uapsd_bk = BIT(0)|BIT(1);
2556 else
2557 pstat->uapsd_bk = 0;
2558
2559 if(pstat->qos_info&BIT(3))
2560 pstat->uapsd_be = BIT(0)|BIT(1);
2561 else
2562 pstat->uapsd_be = 0;
2563
2564 }
2565
2566 break;
2567 }
2568 }
2569 else {
2570 break;
2571 }
2572 p = p + ie_len + 2;
2573 }
2574 }
2575
2576
2577 #ifdef CONFIG_80211N_HT
2578 /* save HT capabilities in the sta object */
2579 _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2580 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
2581 {
2582 pstat->flags |= WLAN_STA_HT;
2583
2584 pstat->flags |= WLAN_STA_WME;
2585
2586 _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
2587
2588 } else
2589 pstat->flags &= ~WLAN_STA_HT;
2590
2591
2592 if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
2593 {
2594 status = _STATS_FAILURE_;
2595 goto OnAssocReqFail;
2596 }
2597
2598 #endif /* CONFIG_80211N_HT */
2599
2600 #ifdef CONFIG_80211AC_VHT
2601 _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
2602 if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
2603 pstat->flags |= WLAN_STA_VHT;
2604
2605 _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
2606
2607 if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) {
2608 _rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1);
2609 }
2610 else // for Frame without Operating Mode notify ie; default: 80M
2611 {
2612 pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
2613 }
2614 }
2615 else {
2616 pstat->flags &= ~WLAN_STA_VHT;
2617 }
2618
2619 if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT))
2620 {
2621 status = _STATS_FAILURE_;
2622 goto OnAssocReqFail;
2623 }
2624 #endif /* CONFIG_80211AC_VHT */
2625
2626 if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
2627 ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
2628 (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2629
2630 DBG_871X("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr));
2631
2632 pstat->flags &= ~WLAN_STA_HT;
2633 pstat->flags &= ~WLAN_STA_VHT;
2634 /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2635 * goto OnAssocReqFail;
2636 */
2637 }
2638
2639
2640 //
2641 //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
2642 pstat->flags |= WLAN_STA_NONERP;
2643 for (i = 0; i < pstat->bssratelen; i++) {
2644 if ((pstat->bssrateset[i] & 0x7f) > 22) {
2645 pstat->flags &= ~WLAN_STA_NONERP;
2646 break;
2647 }
2648 }
2649
2650 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2651 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2652 else
2653 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2654
2655
2656
2657 if (status != _STATS_SUCCESSFUL_)
2658 goto OnAssocReqFail;
2659
2660 #ifdef CONFIG_P2P
2661 pstat->is_p2p_device = _FALSE;
2662 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2663 {
2664 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
2665 {
2666 pstat->is_p2p_device = _TRUE;
2667 if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
2668 {
2669 pstat->p2p_status_code = p2p_status_code;
2670 status = _STATS_CAP_FAIL_;
2671 goto OnAssocReqFail;
2672 }
2673 }
2674 #ifdef CONFIG_WFD
2675 if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
2676 {
2677 u8 attr_content[ 10 ] = { 0x00 };
2678 u32 attr_contentlen = 0;
2679
2680 DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ );
2681 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
2682 if ( attr_contentlen )
2683 {
2684 pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
2685 DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
2686 }
2687 }
2688 #endif
2689 }
2690 pstat->p2p_status_code = p2p_status_code;
2691 #endif //CONFIG_P2P
2692
2693 //TODO: identify_proprietary_vendor_ie();
2694 // Realtek proprietary IE
2695 // identify if this is Broadcom sta
2696 // identify if this is ralink sta
2697 // Customer proprietary IE
2698
2699
2700
2701 /* get a unique AID */
2702 if (pstat->aid > 0) {
2703 DBG_871X(" old AID %d\n", pstat->aid);
2704 } else {
2705 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2706 if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2707 if (pstat->aid > pstapriv->max_num_sta) {
2708 pstat->aid = 0;
2709
2710 DBG_871X(" no room for more AIDs\n");
2711
2712 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2713
2714 goto OnAssocReqFail;
2715
2716
2717 } else {
2718 pstapriv->sta_aid[pstat->aid - 1] = pstat;
2719 DBG_871X("allocate new AID = (%d)\n", pstat->aid);
2720 break;
2721 }
2722 }
2723 }
2724 }
2725
2726
2727 pstat->state &= (~WIFI_FW_ASSOC_STATE);
2728 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2729 /* DBG_871X("==================%s, %d, (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2730 , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */
2731 #ifdef CONFIG_IEEE80211W
2732 if (pstat->bpairwise_key_installed != _TRUE)
2733 #endif /* CONFIG_IEEE80211W */
2734 {
2735 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2736 if (!rtw_is_list_empty(&pstat->auth_list)) {
2737 rtw_list_delete(&pstat->auth_list);
2738 pstapriv->auth_list_cnt--;
2739 }
2740 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2741
2742 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2743 if (rtw_is_list_empty(&pstat->asoc_list)) {
2744 pstat->expire_to = pstapriv->expire_to;
2745 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2746 pstapriv->asoc_list_cnt++;
2747 }
2748 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2749 }
2750
2751 // now the station is qualified to join our BSS...
2752 if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
2753 {
2754 #ifdef CONFIG_NATIVEAP_MLME
2755 #ifdef CONFIG_IEEE80211W
2756 if (pstat->bpairwise_key_installed != _TRUE)
2757 #endif /* CONFIG_IEEE80211W */
2758 {
2759 /* .1 bss_cap_update & sta_info_update */
2760 bss_cap_update_on_sta_join(padapter, pstat);
2761 sta_info_update(padapter, pstat);
2762 }
2763 #ifdef CONFIG_IEEE80211W
2764 if (pstat->bpairwise_key_installed == _TRUE)
2765 status = _STATS_REFUSED_TEMPORARILY_;
2766 #endif /* CONFIG_IEEE80211W */
2767 //.2 issue assoc rsp before notify station join event.
2768 if (frame_type == WIFI_ASSOCREQ)
2769 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2770 else
2771 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2772
2773 #ifdef CONFIG_IOCTL_CFG80211
2774 _enter_critical_bh(&pstat->lock, &irqL);
2775 if(pstat->passoc_req)
2776 {
2777 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2778 pstat->passoc_req = NULL;
2779 pstat->assoc_req_len = 0;
2780 }
2781
2782 pstat->passoc_req = rtw_zmalloc(pkt_len);
2783 if(pstat->passoc_req)
2784 {
2785 _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2786 pstat->assoc_req_len = pkt_len;
2787 }
2788 _exit_critical_bh(&pstat->lock, &irqL);
2789 #endif //CONFIG_IOCTL_CFG80211
2790 #ifdef CONFIG_IEEE80211W
2791 if (pstat->bpairwise_key_installed != _TRUE)
2792 #endif /* CONFIG_IEEE80211W */
2793 {
2794 /* .3-(1) report sta add event */
2795 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
2796 }
2797 #ifdef CONFIG_IEEE80211W
2798 if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) {
2799 DBG_871X(MAC_FMT"\n", MAC_ARG(pstat->hwaddr));
2800 issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY);
2801 }
2802 #endif /* CONFIG_IEEE80211W */
2803 #endif //CONFIG_NATIVEAP_MLME
2804 }
2805
2806 return _SUCCESS;
2807
2808 asoc_class2_error:
2809
2810 #ifdef CONFIG_NATIVEAP_MLME
2811 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
2812 #endif
2813
2814 return _FAIL;
2815
2816 OnAssocReqFail:
2817
2818
2819 #ifdef CONFIG_NATIVEAP_MLME
2820 pstat->aid = 0;
2821 if (frame_type == WIFI_ASSOCREQ)
2822 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2823 else
2824 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2825 #endif
2826
2827
2828 #endif /* CONFIG_AP_MODE */
2829
2830 return _FAIL;
2831
2832 }
2833
OnAssocRsp(_adapter * padapter,union recv_frame * precv_frame)2834 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2835 {
2836 uint i;
2837 int res;
2838 unsigned short status;
2839 PNDIS_802_11_VARIABLE_IEs pIE = NULL;
2840 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2841 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2842 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2843 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
2844 u8 *pframe = precv_frame->u.hdr.rx_data;
2845 uint pkt_len = precv_frame->u.hdr.len;
2846 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
2847
2848 DBG_871X("%s\n", __FUNCTION__);
2849
2850 //check A1 matches or not
2851 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2852 return _SUCCESS;
2853
2854 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2855 return _SUCCESS;
2856
2857 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2858 return _SUCCESS;
2859
2860 _cancel_timer_ex(&pmlmeext->link_timer);
2861
2862 //status
2863 if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2864 {
2865 DBG_871X("assoc reject, status code: %d\n", status);
2866 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2867 res = -4;
2868 goto report_assoc_result;
2869 }
2870
2871 //get capabilities
2872 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2873
2874 //set slot time
2875 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2876
2877 //AID
2878 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2879
2880 //following are moved to join event callback function
2881 //to handle HT, WMM, rate adaptive, update MAC reg
2882 //for not to handle the synchronous IO in the tasklet
2883 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2884 {
2885 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2886
2887 switch (pIE->ElementID)
2888 {
2889 case _VENDOR_SPECIFIC_IE_:
2890 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM
2891 {
2892 WMM_param_handler(padapter, pIE);
2893 }
2894 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2895 else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD
2896 {
2897 DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ );
2898 WFD_info_handler( padapter, pIE );
2899 }
2900 #endif
2901 break;
2902
2903 #ifdef CONFIG_WAPI_SUPPORT
2904 case _WAPI_IE_:
2905 pWapiIE = pIE;
2906 break;
2907 #endif
2908
2909 case _HT_CAPABILITY_IE_: //HT caps
2910 HT_caps_handler(padapter, pIE);
2911 break;
2912
2913 case _HT_EXTRA_INFO_IE_: //HT info
2914 HT_info_handler(padapter, pIE);
2915 break;
2916
2917 #ifdef CONFIG_80211AC_VHT
2918 case EID_VHTCapability:
2919 VHT_caps_handler(padapter, pIE);
2920 break;
2921
2922 case EID_VHTOperation:
2923 VHT_operation_handler(padapter, pIE);
2924 break;
2925 #endif
2926
2927 case _ERPINFO_IE_:
2928 ERP_IE_handler(padapter, pIE);
2929 break;
2930 #ifdef CONFIG_TDLS
2931 case _EXT_CAP_IE_:
2932 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2933 padapter->tdlsinfo.ap_prohibited = _TRUE;
2934 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
2935 padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
2936 break;
2937 #endif /* CONFIG_TDLS */
2938 default:
2939 break;
2940 }
2941
2942 i += (pIE->Length + 2);
2943 }
2944
2945 #ifdef CONFIG_WAPI_SUPPORT
2946 if (pIE != NULL)
2947 rtw_wapi_on_assoc_ok(padapter, pIE);
2948 #endif
2949
2950 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
2951 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
2952
2953 //Update Basic Rate Table for spec, 2010-12-28 , by thomas
2954 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
2955
2956 report_assoc_result:
2957 if (res > 0) {
2958 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
2959 } else {
2960 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
2961 }
2962
2963 report_join_res(padapter, res);
2964
2965 return _SUCCESS;
2966 }
2967
OnDeAuth(_adapter * padapter,union recv_frame * precv_frame)2968 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
2969 {
2970 unsigned short reason;
2971 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2972 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2973 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2974 u8 *pframe = precv_frame->u.hdr.rx_data;
2975 #ifdef CONFIG_P2P
2976 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2977 #endif //CONFIG_P2P
2978
2979 //check A3
2980 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
2981 return _SUCCESS;
2982
2983 DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
2984
2985 #ifdef CONFIG_P2P
2986 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2987 {
2988 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2989 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2990 }
2991 #endif //CONFIG_P2P
2992
2993 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2994
2995 rtw_lock_rx_suspend_timeout(8000);
2996
2997 #ifdef CONFIG_AP_MODE
2998 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2999 {
3000 _irqL irqL;
3001 struct sta_info *psta;
3002 struct sta_priv *pstapriv = &padapter->stapriv;
3003
3004 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3005 //rtw_free_stainfo(padapter, psta);
3006 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3007
3008 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3009 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3010
3011 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3012 if(psta)
3013 {
3014 u8 updated = _FALSE;
3015
3016 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3017 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3018 {
3019 rtw_list_delete(&psta->asoc_list);
3020 pstapriv->asoc_list_cnt--;
3021 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3022
3023 }
3024 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3025
3026 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3027 }
3028
3029
3030 return _SUCCESS;
3031 }
3032 else
3033 #endif
3034 {
3035 int ignore_received_deauth = 0;
3036
3037 // Commented by Albert 20130604
3038 // Before sending the auth frame to start the STA/GC mode connection with AP/GO,
3039 // we will send the deauth first.
3040 // However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
3041 // Added the following code to avoid this case.
3042 if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
3043 ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
3044 {
3045 if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
3046 {
3047 ignore_received_deauth = 1;
3048 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3049 // TODO: 802.11r
3050 ignore_received_deauth = 1;
3051 }
3052 }
3053 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
3054 if(padapter->mlmepriv.not_indic_disco == _TRUE)
3055 ignore_received_deauth = 1;
3056 #endif
3057
3058 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3059 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth);
3060
3061 if ( 0 == ignore_received_deauth )
3062 {
3063 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3064 }
3065 }
3066 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3067 return _SUCCESS;
3068
3069 }
3070
OnDisassoc(_adapter * padapter,union recv_frame * precv_frame)3071 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3072 {
3073 unsigned short reason;
3074 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3075 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3076 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3077 u8 *pframe = precv_frame->u.hdr.rx_data;
3078 #ifdef CONFIG_P2P
3079 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3080 #endif //CONFIG_P2P
3081
3082 //check A3
3083 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3084 return _SUCCESS;
3085
3086 DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3087
3088 #ifdef CONFIG_P2P
3089 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3090 {
3091 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3092 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3093 }
3094 #endif //CONFIG_P2P
3095
3096 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3097
3098 rtw_lock_rx_suspend_timeout(8000);
3099
3100 #ifdef CONFIG_AP_MODE
3101 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3102 {
3103 _irqL irqL;
3104 struct sta_info *psta;
3105 struct sta_priv *pstapriv = &padapter->stapriv;
3106
3107 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3108 //rtw_free_stainfo(padapter, psta);
3109 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3110
3111 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3112 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3113
3114 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3115 if(psta)
3116 {
3117 u8 updated = _FALSE;
3118
3119 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3120 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3121 {
3122 rtw_list_delete(&psta->asoc_list);
3123 pstapriv->asoc_list_cnt--;
3124 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3125
3126 }
3127 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3128
3129 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3130 }
3131
3132 return _SUCCESS;
3133 }
3134 else
3135 #endif
3136 {
3137 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3138 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3139
3140 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3141 }
3142 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3143 return _SUCCESS;
3144
3145 }
3146
OnAtim(_adapter * padapter,union recv_frame * precv_frame)3147 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3148 {
3149 DBG_871X("%s\n", __FUNCTION__);
3150 return _SUCCESS;
3151 }
3152
on_action_spct_ch_switch(_adapter * padapter,struct sta_info * psta,u8 * ies,uint ies_len)3153 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3154 {
3155 unsigned int ret = _FAIL;
3156 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3157 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
3158
3159 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3160 ret = _SUCCESS;
3161 goto exit;
3162 }
3163
3164 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3165
3166 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3167 int ch_offset = -1;
3168 u8 bwmode;
3169 struct ieee80211_info_element *ie;
3170
3171 DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3172 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
3173
3174 for_each_ie(ie, ies, ies_len) {
3175 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3176 ch_switch_mode = ie->data[0];
3177 ch = ie->data[1];
3178 ch_switch_cnt = ie->data[2];
3179 DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3180 ch_switch_mode, ch, ch_switch_cnt);
3181 }
3182 else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3183 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3184 DBG_871X("ch_offset:%d\n", ch_offset);
3185 }
3186 }
3187
3188 if (ch == -1)
3189 return _SUCCESS;
3190
3191 if (ch_offset == -1)
3192 bwmode = mlmeext->cur_bwmode;
3193 else
3194 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3195 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3196
3197 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3198
3199 /* todo:
3200 * 1. the decision of channel switching
3201 * 2. things after channel switching
3202 */
3203
3204 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
3205 }
3206
3207 exit:
3208 return ret;
3209 }
3210
on_action_spct(_adapter * padapter,union recv_frame * precv_frame)3211 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3212 {
3213 unsigned int ret = _FAIL;
3214 struct sta_info *psta = NULL;
3215 struct sta_priv *pstapriv = &padapter->stapriv;
3216 u8 *pframe = precv_frame->u.hdr.rx_data;
3217 uint frame_len = precv_frame->u.hdr.len;
3218 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3219 u8 category;
3220 u8 action;
3221
3222 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3223
3224 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3225
3226 if (!psta)
3227 goto exit;
3228
3229 category = frame_body[0];
3230 if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3231 goto exit;
3232
3233 action = frame_body[1];
3234 switch (action) {
3235 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3236 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3237 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3238 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3239 break;
3240 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3241 #ifdef CONFIG_SPCT_CH_SWITCH
3242 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
3243 frame_len-(frame_body-pframe)-2);
3244 #endif
3245 break;
3246 default:
3247 break;
3248 }
3249
3250 exit:
3251 return ret;
3252 }
3253
OnAction_qos(_adapter * padapter,union recv_frame * precv_frame)3254 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3255 {
3256 return _SUCCESS;
3257 }
3258
OnAction_dls(_adapter * padapter,union recv_frame * precv_frame)3259 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3260 {
3261 return _SUCCESS;
3262 }
3263
3264 /**
3265 * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3266 * @adapter: the adapter to get target RX AMPDU buffer size
3267 *
3268 * Returns: the target RX AMPDU buffer size
3269 */
rtw_rx_ampdu_size(_adapter * adapter)3270 u8 rtw_rx_ampdu_size(_adapter *adapter)
3271 {
3272 u8 size;
3273 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3274
3275 if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) {
3276 size = adapter->fix_rx_ampdu_size;
3277 goto exit;
3278 }
3279
3280 #ifdef CONFIG_BT_COEXIST
3281 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3282 size = rtw_btcoex_GetAMPDUSize(adapter);
3283 goto exit;
3284 }
3285 #endif
3286
3287 /* for scan */
3288 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3289 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3290 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3291 ) {
3292 size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3293 goto exit;
3294 }
3295
3296 /* default value based on max_rx_ampdu_factor */
3297 if (adapter->driver_rx_ampdu_factor != 0xFF)
3298 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3299 else
3300 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3301
3302 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3303 size = 64;
3304 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3305 size = 32;
3306 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3307 size = 16;
3308 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3309 size = 8;
3310 else
3311 size = 64;
3312
3313 exit:
3314
3315 if (size > 127)
3316 size = 127;
3317
3318 return size;
3319 }
3320
3321 /**
3322 * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3323 * @adapter: the adapter to get the permission if RX AMPDU should be set up
3324 *
3325 * Returns: accept or not
3326 */
rtw_rx_ampdu_is_accept(_adapter * adapter)3327 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3328 {
3329 bool accept;
3330
3331 if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3332 accept = adapter->fix_rx_ampdu_accept;
3333 goto exit;
3334 }
3335
3336 #ifdef CONFIG_BT_COEXIST
3337 if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3338 accept = _FALSE;
3339 goto exit;
3340 }
3341 #endif
3342
3343 /* for scan */
3344 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3345 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3346 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3347 ) {
3348 accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3349 goto exit;
3350 }
3351
3352 /* default value for other cases */
3353 accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3354
3355 exit:
3356 return accept;
3357 }
3358
3359 /**
3360 * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3361 * @adapter: the adapter to set target RX AMPDU buffer size
3362 * @size: the target RX AMPDU buffer size to set
3363 * @reason: reason for the target RX AMPDU buffer size setting
3364 *
3365 * Returns: whether the target RX AMPDU buffer size is changed
3366 */
rtw_rx_ampdu_set_size(_adapter * adapter,u8 size,u8 reason)3367 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3368 {
3369 bool is_adj = _FALSE;
3370 struct mlme_ext_priv *mlmeext;
3371 struct mlme_ext_info *mlmeinfo;
3372
3373 mlmeext = &adapter->mlmeextpriv;
3374 mlmeinfo = &mlmeext->mlmext_info;
3375
3376 if (reason == RX_AMPDU_DRV_FIXED) {
3377 if (adapter->fix_rx_ampdu_size != size) {
3378 adapter->fix_rx_ampdu_size = size;
3379 is_adj = _TRUE;
3380 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3381 }
3382 } else if (reason == RX_AMPDU_DRV_SCAN) {
3383 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3384
3385 if (ss->rx_ampdu_size != size) {
3386 ss->rx_ampdu_size = size;
3387 is_adj = _TRUE;
3388 DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3389 }
3390 }
3391
3392 return is_adj;
3393 }
3394
3395 /**
3396 * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3397 * @adapter: the adapter to set if RX AMPDU should be set up
3398 * @accept: if RX AMPDU should be set up
3399 * @reason: reason for the permission if RX AMPDU should be set up
3400 *
3401 * Returns: whether the permission if RX AMPDU should be set up is changed
3402 */
rtw_rx_ampdu_set_accept(_adapter * adapter,u8 accept,u8 reason)3403 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3404 {
3405 bool is_adj = _FALSE;
3406 struct mlme_ext_priv *mlmeext;
3407 struct mlme_ext_info *mlmeinfo;
3408
3409 mlmeext = &adapter->mlmeextpriv;
3410 mlmeinfo = &mlmeext->mlmext_info;
3411
3412 if (reason == RX_AMPDU_DRV_FIXED) {
3413 if (adapter->fix_rx_ampdu_accept != accept) {
3414 adapter->fix_rx_ampdu_accept = accept;
3415 is_adj = _TRUE;
3416 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3417 }
3418 } else if (reason == RX_AMPDU_DRV_SCAN) {
3419 if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3420 adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3421 is_adj = _TRUE;
3422 DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3423 }
3424 }
3425
3426 return is_adj;
3427 }
3428
3429 /**
3430 * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3431 * @adapter: the adapter to which @sta belongs
3432 * @sta: the sta to be checked
3433 * @tid: the tid to be checked
3434 * @accept: the target permission if RX AMPDU should be set up
3435 * @size: the target RX AMPDU buffer size
3436 *
3437 * Returns:
3438 * 0: no canceled
3439 * 1: canceled by no permission
3440 * 2: canceled by different buffer size
3441 * 3: canceled by potential mismatched status
3442 *
3443 * Blocking function, may sleep
3444 */
rx_ampdu_apply_sta_tid(_adapter * adapter,struct sta_info * sta,u8 tid,u8 accept,u8 size)3445 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3446 {
3447 u8 ret = 0;
3448 struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3449
3450 if (reorder_ctl->enable == _FALSE) {
3451 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3452 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3453 ret = 3;
3454 }
3455 goto exit;
3456 }
3457
3458 if (accept == _FALSE) {
3459 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3460 ret = 1;
3461 } else if (reorder_ctl->ampdu_size != size) {
3462 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3463 ret = 2;
3464 }
3465
3466 exit:
3467 return ret;
3468 }
3469
3470 /**
3471 * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3472 * @adapter: the adapter to which @sta belongs
3473 * @sta: the sta to be checked
3474 * @accept: the target permission if RX AMPDU should be set up
3475 * @size: the target RX AMPDU buffer size
3476 *
3477 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3478 *
3479 * Blocking function, may sleep
3480 */
rx_ampdu_apply_sta(_adapter * adapter,struct sta_info * sta,u8 accept,u8 size)3481 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3482 {
3483 u8 change_cnt = 0;
3484 int i;
3485
3486 for (i = 0; i < TID_NUM; i++) {
3487 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3488 change_cnt++;
3489 }
3490
3491 return change_cnt;
3492 }
3493
3494 /**
3495 * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3496 * @adapter: the adapter to be applied
3497 *
3498 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3499 */
rtw_rx_ampdu_apply(_adapter * adapter)3500 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3501 {
3502 u16 adj_cnt = 0;
3503 struct mlme_ext_priv *mlmeext;
3504 struct sta_info *sta;
3505 u8 accept = rtw_rx_ampdu_is_accept(adapter);
3506 u8 size = rtw_rx_ampdu_size(adapter);
3507
3508 mlmeext = &adapter->mlmeextpriv;
3509
3510 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3511 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3512 if (sta)
3513 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3514 }
3515 #ifdef CONFIG_AP_MODE
3516 else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3517 _irqL irqL;
3518 _list *phead, *plist;
3519 u8 peer_num = 0;
3520 char peers[NUM_STA];
3521 struct sta_priv *pstapriv = &adapter->stapriv;
3522 int i;
3523
3524 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3525
3526 phead = &pstapriv->asoc_list;
3527 plist = get_next(phead);
3528
3529 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3530 int stainfo_offset;
3531
3532 sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3533 plist = get_next(plist);
3534
3535 stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3536 if (stainfo_offset_valid(stainfo_offset))
3537 peers[peer_num++] = stainfo_offset;
3538 }
3539
3540 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3541
3542 for (i = 0; i < peer_num; i++) {
3543 sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3544 if (sta)
3545 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3546 }
3547 }
3548 #endif /*CONFIG_AP_MODE*/
3549 return adj_cnt;
3550 }
3551
OnAction_back(_adapter * padapter,union recv_frame * precv_frame)3552 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3553 {
3554 u8 *addr;
3555 struct sta_info *psta=NULL;
3556 struct recv_reorder_ctrl *preorder_ctrl;
3557 unsigned char *frame_body;
3558 unsigned char category, action;
3559 unsigned short tid, status, reason_code = 0;
3560 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3561 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3562 u8 *pframe = precv_frame->u.hdr.rx_data;
3563 struct sta_priv *pstapriv = &padapter->stapriv;
3564 #ifdef CONFIG_80211N_HT
3565
3566 DBG_871X("%s\n", __FUNCTION__);
3567
3568 //check RA matches or not
3569 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3570 return _SUCCESS;
3571
3572 /*
3573 //check A1 matches or not
3574 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3575 return _SUCCESS;
3576 */
3577
3578 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3579 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3580 return _SUCCESS;
3581
3582 addr = GetAddr2Ptr(pframe);
3583 psta = rtw_get_stainfo(pstapriv, addr);
3584
3585 if(psta==NULL)
3586 return _SUCCESS;
3587
3588 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3589
3590 category = frame_body[0];
3591 if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
3592 {
3593 #ifdef CONFIG_TDLS
3594 if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3595 (psta->htpriv.ht_option==_TRUE) &&
3596 (psta->htpriv.ampdu_enable==_TRUE))
3597 {
3598 DBG_871X("Recv [%s] from direc link\n", __FUNCTION__);
3599 }
3600 else
3601 #endif //CONFIG_TDLS
3602 if (!pmlmeinfo->HT_enable)
3603 {
3604 return _SUCCESS;
3605 }
3606
3607 action = frame_body[1];
3608 DBG_871X("%s, action=%d\n", __FUNCTION__, action);
3609 switch (action)
3610 {
3611 case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
3612
3613 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3614 //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
3615 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
3616
3617 break;
3618
3619 case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
3620
3621 //status = frame_body[3] | (frame_body[4] << 8); //endian issue
3622 status = RTW_GET_LE16(&frame_body[3]);
3623 tid = ((frame_body[5] >> 2) & 0x7);
3624
3625 if (status == 0)
3626 { //successful
3627 DBG_871X("agg_enable for TID=%d\n", tid);
3628 psta->htpriv.agg_enable_bitmap |= 1 << tid;
3629 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3630 }
3631 else
3632 {
3633 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3634 }
3635 #ifdef CONFIG_AP_MODE
3636 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3637 {
3638 DBG_871X("%s alive check - rx ADDBA response\n", __func__);
3639 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3640 psta->expire_to = pstapriv->expire_to;
3641 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3642 }
3643 #endif
3644 //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
3645 break;
3646
3647 case RTW_WLAN_ACTION_DELBA: //DELBA
3648 if ((frame_body[3] & BIT(3)) == 0)
3649 {
3650 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3651 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3652
3653 //reason_code = frame_body[4] | (frame_body[5] << 8);
3654 reason_code = RTW_GET_LE16(&frame_body[4]);
3655 }
3656 else if((frame_body[3] & BIT(3)) == BIT(3))
3657 {
3658 tid = (frame_body[3] >> 4) & 0x0F;
3659
3660 preorder_ctrl = &psta->recvreorder_ctrl[tid];
3661 preorder_ctrl->enable = _FALSE;
3662 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3663 }
3664
3665 DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
3666 //todo: how to notify the host while receiving DELETE BA
3667 break;
3668
3669 default:
3670 break;
3671 }
3672 }
3673 #endif //CONFIG_80211N_HT
3674 return _SUCCESS;
3675 }
3676
3677 #ifdef CONFIG_P2P
3678
get_reg_classes_full_count(struct p2p_channels channel_list)3679 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
3680 int cnt = 0;
3681 int i;
3682
3683 for (i = 0; i < channel_list.reg_classes; i++) {
3684 cnt += channel_list.reg_class[i].channels;
3685 }
3686
3687 return cnt;
3688 }
3689
get_channel_cnt_24g_5gl_5gh(struct mlme_ext_priv * pmlmeext,u8 * p24g_cnt,u8 * p5gl_cnt,u8 * p5gh_cnt)3690 static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
3691 {
3692 int i = 0;
3693
3694 *p24g_cnt = 0;
3695 *p5gl_cnt = 0;
3696 *p5gh_cnt = 0;
3697
3698 for( i = 0; i < pmlmeext->max_chan_nums; i++ )
3699 {
3700 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
3701 {
3702 (*p24g_cnt)++;
3703 }
3704 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
3705 {
3706 // Just include the channel 36, 40, 44, 48 channels for 5G low
3707 (*p5gl_cnt)++;
3708 }
3709 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
3710 {
3711 // Just include the channel 149, 153, 157, 161 channels for 5G high
3712 (*p5gh_cnt)++;
3713 }
3714 }
3715 }
3716
issue_p2p_GO_request(_adapter * padapter,u8 * raddr)3717 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
3718 {
3719
3720 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3721 u8 action = P2P_PUB_ACTION_ACTION;
3722 u32 p2poui = cpu_to_be32(P2POUI);
3723 u8 oui_subtype = P2P_GO_NEGO_REQ;
3724 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3725 u8 wpsielen = 0, p2pielen = 0, i;
3726 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3727 u16 len_channellist_attr = 0;
3728 #ifdef CONFIG_WFD
3729 u32 wfdielen = 0;
3730 #endif //CONFIG_WFD
3731
3732 struct xmit_frame *pmgntframe;
3733 struct pkt_attrib *pattrib;
3734 unsigned char *pframe;
3735 struct rtw_ieee80211_hdr *pwlanhdr;
3736 unsigned short *fctrl;
3737 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3738 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3739 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3740 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3741
3742
3743 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3744 {
3745 return;
3746 }
3747
3748 DBG_871X( "[%s] In\n", __FUNCTION__ );
3749 //update attribute
3750 pattrib = &pmgntframe->attrib;
3751 update_mgntframe_attrib(padapter, pattrib);
3752
3753 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3754
3755 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3756 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3757
3758 fctrl = &(pwlanhdr->frame_ctl);
3759 *(fctrl) = 0;
3760
3761 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3762 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3763 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3764
3765 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3766 pmlmeext->mgnt_seq++;
3767 SetFrameSubType(pframe, WIFI_ACTION);
3768
3769 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3770 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3771
3772 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3773 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3774 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3775 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3776 pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value
3777 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3778
3779
3780
3781 // WPS Section
3782 wpsielen = 0;
3783 // WPS OUI
3784 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3785 wpsielen += 4;
3786
3787 // WPS version
3788 // Type:
3789 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3790 wpsielen += 2;
3791
3792 // Length:
3793 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3794 wpsielen += 2;
3795
3796 // Value:
3797 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
3798
3799 // Device Password ID
3800 // Type:
3801 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3802 wpsielen += 2;
3803
3804 // Length:
3805 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3806 wpsielen += 2;
3807
3808 // Value:
3809
3810 if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
3811 {
3812 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3813 }
3814 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
3815 {
3816 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3817 }
3818 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
3819 {
3820 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3821 }
3822
3823 wpsielen += 2;
3824
3825 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3826
3827
3828 // P2P IE Section.
3829
3830 // P2P OUI
3831 p2pielen = 0;
3832 p2pie[ p2pielen++ ] = 0x50;
3833 p2pie[ p2pielen++ ] = 0x6F;
3834 p2pie[ p2pielen++ ] = 0x9A;
3835 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
3836
3837 // Commented by Albert 20110306
3838 // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
3839 // 1. P2P Capability
3840 // 2. Group Owner Intent
3841 // 3. Configuration Timeout
3842 // 4. Listen Channel
3843 // 5. Extended Listen Timing
3844 // 6. Intended P2P Interface Address
3845 // 7. Channel List
3846 // 8. P2P Device Info
3847 // 9. Operating Channel
3848
3849
3850 // P2P Capability
3851 // Type:
3852 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3853
3854 // Length:
3855 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3856 p2pielen += 2;
3857
3858 // Value:
3859 // Device Capability Bitmap, 1 byte
3860 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3861
3862 // Group Capability Bitmap, 1 byte
3863 if ( pwdinfo->persistent_supported )
3864 {
3865 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3866 }
3867 else
3868 {
3869 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3870 }
3871
3872
3873 // Group Owner Intent
3874 // Type:
3875 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3876
3877 // Length:
3878 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3879 p2pielen += 2;
3880
3881 // Value:
3882 // Todo the tie breaker bit.
3883 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) & 0xFE );
3884
3885 // Configuration Timeout
3886 // Type:
3887 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3888
3889 // Length:
3890 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3891 p2pielen += 2;
3892
3893 // Value:
3894 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
3895 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
3896
3897
3898 // Listen Channel
3899 // Type:
3900 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
3901
3902 // Length:
3903 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3904 p2pielen += 2;
3905
3906 // Value:
3907 // Country String
3908 p2pie[ p2pielen++ ] = 'X';
3909 p2pie[ p2pielen++ ] = 'X';
3910
3911 // The third byte should be set to 0x04.
3912 // Described in the "Operating Channel Attribute" section.
3913 p2pie[ p2pielen++ ] = 0x04;
3914
3915 // Operating Class
3916 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
3917
3918 // Channel Number
3919 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listening channel number
3920
3921
3922 // Extended Listen Timing ATTR
3923 // Type:
3924 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
3925
3926 // Length:
3927 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
3928 p2pielen += 2;
3929
3930 // Value:
3931 // Availability Period
3932 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3933 p2pielen += 2;
3934
3935 // Availability Interval
3936 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3937 p2pielen += 2;
3938
3939
3940 // Intended P2P Interface Address
3941 // Type:
3942 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
3943
3944 // Length:
3945 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3946 p2pielen += 2;
3947
3948 // Value:
3949 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
3950 p2pielen += ETH_ALEN;
3951
3952
3953 // Channel List
3954 // Type:
3955 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3956
3957 // Length:
3958 // Country String(3)
3959 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
3960 // + number of channels in all classes
3961 len_channellist_attr = 3
3962 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
3963 + get_reg_classes_full_count(pmlmeext->channel_list);
3964
3965 #ifdef CONFIG_CONCURRENT_MODE
3966 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3967 {
3968 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3969 }
3970 else
3971 {
3972 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3973 }
3974 #else
3975
3976 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3977
3978 #endif
3979 p2pielen += 2;
3980
3981 // Value:
3982 // Country String
3983 p2pie[ p2pielen++ ] = 'X';
3984 p2pie[ p2pielen++ ] = 'X';
3985
3986 // The third byte should be set to 0x04.
3987 // Described in the "Operating Channel Attribute" section.
3988 p2pie[ p2pielen++ ] = 0x04;
3989
3990 // Channel Entry List
3991
3992 #ifdef CONFIG_CONCURRENT_MODE
3993 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3994 {
3995 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3996 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3997
3998 // Operating Class
3999 if ( pbuddy_mlmeext->cur_channel > 14 )
4000 {
4001 if ( pbuddy_mlmeext->cur_channel >= 149 )
4002 {
4003 p2pie[ p2pielen++ ] = 0x7c;
4004 }
4005 else
4006 {
4007 p2pie[ p2pielen++ ] = 0x73;
4008 }
4009 }
4010 else
4011 {
4012 p2pie[ p2pielen++ ] = 0x51;
4013 }
4014
4015 // Number of Channels
4016 // Just support 1 channel and this channel is AP's channel
4017 p2pie[ p2pielen++ ] = 1;
4018
4019 // Channel List
4020 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4021 }
4022 else
4023 {
4024 int i,j;
4025 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4026 // Operating Class
4027 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4028
4029 // Number of Channels
4030 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4031
4032 // Channel List
4033 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4034 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4035 }
4036 }
4037 }
4038 #else // CONFIG_CONCURRENT_MODE
4039 {
4040 int i,j;
4041 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4042 // Operating Class
4043 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4044
4045 // Number of Channels
4046 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4047
4048 // Channel List
4049 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4050 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4051 }
4052 }
4053 }
4054 #endif // CONFIG_CONCURRENT_MODE
4055
4056 // Device Info
4057 // Type:
4058 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4059
4060 // Length:
4061 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4062 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4063 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4064 p2pielen += 2;
4065
4066 // Value:
4067 // P2P Device Address
4068 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4069 p2pielen += ETH_ALEN;
4070
4071 // Config Method
4072 // This field should be big endian. Noted by P2P specification.
4073
4074 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4075
4076 p2pielen += 2;
4077
4078 // Primary Device Type
4079 // Category ID
4080 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4081 p2pielen += 2;
4082
4083 // OUI
4084 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4085 p2pielen += 4;
4086
4087 // Sub Category ID
4088 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4089 p2pielen += 2;
4090
4091 // Number of Secondary Device Types
4092 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4093
4094 // Device Name
4095 // Type:
4096 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4097 p2pielen += 2;
4098
4099 // Length:
4100 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4101 p2pielen += 2;
4102
4103 // Value:
4104 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4105 p2pielen += pwdinfo->device_name_len;
4106
4107
4108 // Operating Channel
4109 // Type:
4110 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4111
4112 // Length:
4113 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4114 p2pielen += 2;
4115
4116 // Value:
4117 // Country String
4118 p2pie[ p2pielen++ ] = 'X';
4119 p2pie[ p2pielen++ ] = 'X';
4120
4121 // The third byte should be set to 0x04.
4122 // Described in the "Operating Channel Attribute" section.
4123 p2pie[ p2pielen++ ] = 0x04;
4124
4125 // Operating Class
4126 if ( pwdinfo->operating_channel <= 14 )
4127 {
4128 // Operating Class
4129 p2pie[ p2pielen++ ] = 0x51;
4130 }
4131 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4132 {
4133 // Operating Class
4134 p2pie[ p2pielen++ ] = 0x73;
4135 }
4136 else
4137 {
4138 // Operating Class
4139 p2pie[ p2pielen++ ] = 0x7c;
4140 }
4141
4142 // Channel Number
4143 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4144
4145 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4146
4147 #ifdef CONFIG_WFD
4148 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4149 pframe += wfdielen;
4150 pattrib->pktlen += wfdielen;
4151 #endif //CONFIG_WFD
4152
4153 pattrib->last_txcmdsz = pattrib->pktlen;
4154
4155 dump_mgntframe(padapter, pmgntframe);
4156
4157 return;
4158
4159 }
4160
4161
issue_p2p_GO_response(_adapter * padapter,u8 * raddr,u8 * frame_body,uint len,u8 result)4162 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
4163 {
4164
4165 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4166 u8 action = P2P_PUB_ACTION_ACTION;
4167 u32 p2poui = cpu_to_be32(P2POUI);
4168 u8 oui_subtype = P2P_GO_NEGO_RESP;
4169 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4170 u8 p2pielen = 0, i;
4171 uint wpsielen = 0;
4172 u16 wps_devicepassword_id = 0x0000;
4173 uint wps_devicepassword_id_len = 0;
4174 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4175 u16 len_channellist_attr = 0;
4176
4177 struct xmit_frame *pmgntframe;
4178 struct pkt_attrib *pattrib;
4179 unsigned char *pframe;
4180 struct rtw_ieee80211_hdr *pwlanhdr;
4181 unsigned short *fctrl;
4182 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4183 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4184 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4185 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4186
4187 #ifdef CONFIG_WFD
4188 u32 wfdielen = 0;
4189 #endif //CONFIG_WFD
4190
4191 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4192 {
4193 return;
4194 }
4195
4196 DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result );
4197 //update attribute
4198 pattrib = &pmgntframe->attrib;
4199 update_mgntframe_attrib(padapter, pattrib);
4200
4201 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4202
4203 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4204 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4205
4206 fctrl = &(pwlanhdr->frame_ctl);
4207 *(fctrl) = 0;
4208
4209 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4210 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4211 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4212
4213 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4214 pmlmeext->mgnt_seq++;
4215 SetFrameSubType(pframe, WIFI_ACTION);
4216
4217 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4218 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4219
4220 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4221 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4222 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4223 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4224 pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
4225 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4226
4227 // Commented by Albert 20110328
4228 // Try to get the device password ID from the WPS IE of group negotiation request frame
4229 // WiFi Direct test plan 5.1.15
4230 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4231 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4232 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4233
4234 _rtw_memset( wpsie, 0x00, 255 );
4235 wpsielen = 0;
4236
4237 // WPS Section
4238 wpsielen = 0;
4239 // WPS OUI
4240 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4241 wpsielen += 4;
4242
4243 // WPS version
4244 // Type:
4245 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4246 wpsielen += 2;
4247
4248 // Length:
4249 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4250 wpsielen += 2;
4251
4252 // Value:
4253 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
4254
4255 // Device Password ID
4256 // Type:
4257 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4258 wpsielen += 2;
4259
4260 // Length:
4261 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4262 wpsielen += 2;
4263
4264 // Value:
4265 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4266 {
4267 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
4268 }
4269 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4270 {
4271 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
4272 }
4273 else
4274 {
4275 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
4276 }
4277 wpsielen += 2;
4278
4279 // Commented by Kurt 20120113
4280 // If some device wants to do p2p handshake without sending prov_disc_req
4281 // We have to get peer_req_cm from here.
4282 if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
4283 {
4284 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4285 {
4286 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
4287 }
4288 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4289 {
4290 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
4291 }
4292 else
4293 {
4294 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
4295 }
4296 }
4297
4298 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4299
4300
4301 // P2P IE Section.
4302
4303 // P2P OUI
4304 p2pielen = 0;
4305 p2pie[ p2pielen++ ] = 0x50;
4306 p2pie[ p2pielen++ ] = 0x6F;
4307 p2pie[ p2pielen++ ] = 0x9A;
4308 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4309
4310 // Commented by Albert 20100908
4311 // According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
4312 // 1. Status
4313 // 2. P2P Capability
4314 // 3. Group Owner Intent
4315 // 4. Configuration Timeout
4316 // 5. Operating Channel
4317 // 6. Intended P2P Interface Address
4318 // 7. Channel List
4319 // 8. Device Info
4320 // 9. Group ID ( Only GO )
4321
4322
4323 // ToDo:
4324
4325 // P2P Status
4326 // Type:
4327 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4328
4329 // Length:
4330 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4331 p2pielen += 2;
4332
4333 // Value:
4334 p2pie[ p2pielen++ ] = result;
4335
4336 // P2P Capability
4337 // Type:
4338 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4339
4340 // Length:
4341 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4342 p2pielen += 2;
4343
4344 // Value:
4345 // Device Capability Bitmap, 1 byte
4346
4347 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4348 {
4349 // Commented by Albert 2011/03/08
4350 // According to the P2P specification
4351 // if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
4352 p2pie[ p2pielen++ ] = 0;
4353 }
4354 else
4355 {
4356 // Be group owner or meet the error case
4357 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4358 }
4359
4360 // Group Capability Bitmap, 1 byte
4361 if ( pwdinfo->persistent_supported )
4362 {
4363 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4364 }
4365 else
4366 {
4367 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4368 }
4369
4370 // Group Owner Intent
4371 // Type:
4372 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
4373
4374 // Length:
4375 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4376 p2pielen += 2;
4377
4378 // Value:
4379 if ( pwdinfo->peer_intent & 0x01 )
4380 {
4381 // Peer's tie breaker bit is 1, our tie breaker bit should be 0
4382 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
4383 }
4384 else
4385 {
4386 // Peer's tie breaker bit is 0, our tie breaker bit should be 1
4387 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
4388 }
4389
4390
4391 // Configuration Timeout
4392 // Type:
4393 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4394
4395 // Length:
4396 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4397 p2pielen += 2;
4398
4399 // Value:
4400 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
4401 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
4402
4403 // Operating Channel
4404 // Type:
4405 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4406
4407 // Length:
4408 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4409 p2pielen += 2;
4410
4411 // Value:
4412 // Country String
4413 p2pie[ p2pielen++ ] = 'X';
4414 p2pie[ p2pielen++ ] = 'X';
4415
4416 // The third byte should be set to 0x04.
4417 // Described in the "Operating Channel Attribute" section.
4418 p2pie[ p2pielen++ ] = 0x04;
4419
4420 // Operating Class
4421 if ( pwdinfo->operating_channel <= 14 )
4422 {
4423 // Operating Class
4424 p2pie[ p2pielen++ ] = 0x51;
4425 }
4426 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4427 {
4428 // Operating Class
4429 p2pie[ p2pielen++ ] = 0x73;
4430 }
4431 else
4432 {
4433 // Operating Class
4434 p2pie[ p2pielen++ ] = 0x7c;
4435 }
4436
4437 // Channel Number
4438 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4439
4440 // Intended P2P Interface Address
4441 // Type:
4442 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4443
4444 // Length:
4445 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4446 p2pielen += 2;
4447
4448 // Value:
4449 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4450 p2pielen += ETH_ALEN;
4451
4452 // Channel List
4453 // Type:
4454 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4455
4456 // Country String(3)
4457 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4458 // + number of channels in all classes
4459 len_channellist_attr = 3
4460 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4461 + get_reg_classes_full_count(pmlmeext->channel_list);
4462
4463 #ifdef CONFIG_CONCURRENT_MODE
4464 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4465 {
4466 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4467 }
4468 else
4469 {
4470 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4471 }
4472 #else
4473
4474 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4475
4476 #endif
4477 p2pielen += 2;
4478
4479 // Value:
4480 // Country String
4481 p2pie[ p2pielen++ ] = 'X';
4482 p2pie[ p2pielen++ ] = 'X';
4483
4484 // The third byte should be set to 0x04.
4485 // Described in the "Operating Channel Attribute" section.
4486 p2pie[ p2pielen++ ] = 0x04;
4487
4488 // Channel Entry List
4489
4490 #ifdef CONFIG_CONCURRENT_MODE
4491 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4492 {
4493 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4494 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4495
4496 // Operating Class
4497 if ( pbuddy_mlmeext->cur_channel > 14 )
4498 {
4499 if ( pbuddy_mlmeext->cur_channel >= 149 )
4500 {
4501 p2pie[ p2pielen++ ] = 0x7c;
4502 }
4503 else
4504 {
4505 p2pie[ p2pielen++ ] = 0x73;
4506 }
4507 }
4508 else
4509 {
4510 p2pie[ p2pielen++ ] = 0x51;
4511 }
4512
4513 // Number of Channels
4514 // Just support 1 channel and this channel is AP's channel
4515 p2pie[ p2pielen++ ] = 1;
4516
4517 // Channel List
4518 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4519 }
4520 else
4521 {
4522 int i, j;
4523 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4524 // Operating Class
4525 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4526
4527 // Number of Channels
4528 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4529
4530 // Channel List
4531 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4532 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4533 }
4534 }
4535 }
4536 #else // CONFIG_CONCURRENT_MODE
4537 {
4538 int i, j;
4539 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4540 // Operating Class
4541 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4542
4543 // Number of Channels
4544 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4545
4546 // Channel List
4547 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4548 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4549 }
4550 }
4551 }
4552 #endif // CONFIG_CONCURRENT_MODE
4553
4554
4555 // Device Info
4556 // Type:
4557 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4558
4559 // Length:
4560 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4561 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4562 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4563 p2pielen += 2;
4564
4565 // Value:
4566 // P2P Device Address
4567 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4568 p2pielen += ETH_ALEN;
4569
4570 // Config Method
4571 // This field should be big endian. Noted by P2P specification.
4572
4573 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4574
4575 p2pielen += 2;
4576
4577 // Primary Device Type
4578 // Category ID
4579 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4580 p2pielen += 2;
4581
4582 // OUI
4583 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4584 p2pielen += 4;
4585
4586 // Sub Category ID
4587 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4588 p2pielen += 2;
4589
4590 // Number of Secondary Device Types
4591 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4592
4593 // Device Name
4594 // Type:
4595 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4596 p2pielen += 2;
4597
4598 // Length:
4599 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4600 p2pielen += 2;
4601
4602 // Value:
4603 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4604 p2pielen += pwdinfo->device_name_len;
4605
4606 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4607 {
4608 // Group ID Attribute
4609 // Type:
4610 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4611
4612 // Length:
4613 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4614 p2pielen += 2;
4615
4616 // Value:
4617 // p2P Device Address
4618 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4619 p2pielen += ETH_ALEN;
4620
4621 // SSID
4622 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4623 p2pielen += pwdinfo->nego_ssidlen;
4624
4625 }
4626
4627 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4628
4629 #ifdef CONFIG_WFD
4630 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4631 pframe += wfdielen;
4632 pattrib->pktlen += wfdielen;
4633 #endif //CONFIG_WFD
4634
4635 pattrib->last_txcmdsz = pattrib->pktlen;
4636
4637 dump_mgntframe(padapter, pmgntframe);
4638
4639 return;
4640
4641 }
4642
issue_p2p_GO_confirm(_adapter * padapter,u8 * raddr,u8 result)4643 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
4644 {
4645
4646 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4647 u8 action = P2P_PUB_ACTION_ACTION;
4648 u32 p2poui = cpu_to_be32(P2POUI);
4649 u8 oui_subtype = P2P_GO_NEGO_CONF;
4650 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4651 u8 wpsielen = 0, p2pielen = 0;
4652
4653 struct xmit_frame *pmgntframe;
4654 struct pkt_attrib *pattrib;
4655 unsigned char *pframe;
4656 struct rtw_ieee80211_hdr *pwlanhdr;
4657 unsigned short *fctrl;
4658 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4659 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4660 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4661 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4662 #ifdef CONFIG_WFD
4663 u32 wfdielen = 0;
4664 #endif //CONFIG_WFD
4665
4666 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4667 {
4668 return;
4669 }
4670
4671 DBG_871X( "[%s] In\n", __FUNCTION__ );
4672 //update attribute
4673 pattrib = &pmgntframe->attrib;
4674 update_mgntframe_attrib(padapter, pattrib);
4675
4676 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4677
4678 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4679 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4680
4681 fctrl = &(pwlanhdr->frame_ctl);
4682 *(fctrl) = 0;
4683
4684 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4685 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4686 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4687
4688 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4689 pmlmeext->mgnt_seq++;
4690 SetFrameSubType(pframe, WIFI_ACTION);
4691
4692 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4693 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4694
4695 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4696 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4697 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4698 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4699 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4700
4701
4702
4703 // P2P IE Section.
4704
4705 // P2P OUI
4706 p2pielen = 0;
4707 p2pie[ p2pielen++ ] = 0x50;
4708 p2pie[ p2pielen++ ] = 0x6F;
4709 p2pie[ p2pielen++ ] = 0x9A;
4710 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4711
4712 // Commented by Albert 20110306
4713 // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
4714 // 1. Status
4715 // 2. P2P Capability
4716 // 3. Operating Channel
4717 // 4. Channel List
4718 // 5. Group ID ( if this WiFi is GO )
4719
4720 // P2P Status
4721 // Type:
4722 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4723
4724 // Length:
4725 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4726 p2pielen += 2;
4727
4728 // Value:
4729 p2pie[ p2pielen++ ] = result;
4730
4731 // P2P Capability
4732 // Type:
4733 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4734
4735 // Length:
4736 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4737 p2pielen += 2;
4738
4739 // Value:
4740 // Device Capability Bitmap, 1 byte
4741 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4742
4743 // Group Capability Bitmap, 1 byte
4744 if ( pwdinfo->persistent_supported )
4745 {
4746 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4747 }
4748 else
4749 {
4750 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4751 }
4752
4753
4754 // Operating Channel
4755 // Type:
4756 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4757
4758 // Length:
4759 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4760 p2pielen += 2;
4761
4762 // Value:
4763 // Country String
4764 p2pie[ p2pielen++ ] = 'X';
4765 p2pie[ p2pielen++ ] = 'X';
4766
4767 // The third byte should be set to 0x04.
4768 // Described in the "Operating Channel Attribute" section.
4769 p2pie[ p2pielen++ ] = 0x04;
4770
4771
4772 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4773 {
4774 if ( pwdinfo->peer_operating_ch <= 14 )
4775 {
4776 // Operating Class
4777 p2pie[ p2pielen++ ] = 0x51;
4778 }
4779 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4780 {
4781 // Operating Class
4782 p2pie[ p2pielen++ ] = 0x73;
4783 }
4784 else
4785 {
4786 // Operating Class
4787 p2pie[ p2pielen++ ] = 0x7c;
4788 }
4789
4790 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4791 }
4792 else
4793 {
4794 if ( pwdinfo->operating_channel <= 14 )
4795 {
4796 // Operating Class
4797 p2pie[ p2pielen++ ] = 0x51;
4798 }
4799 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4800 {
4801 // Operating Class
4802 p2pie[ p2pielen++ ] = 0x73;
4803 }
4804 else
4805 {
4806 // Operating Class
4807 p2pie[ p2pielen++ ] = 0x7c;
4808 }
4809
4810 // Channel Number
4811 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4812 }
4813
4814
4815 // Channel List
4816 // Type:
4817 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4818
4819 *(u16*) ( p2pie + p2pielen ) = 6;
4820 p2pielen += 2;
4821
4822 // Country String
4823 p2pie[ p2pielen++ ] = 'X';
4824 p2pie[ p2pielen++ ] = 'X';
4825
4826 // The third byte should be set to 0x04.
4827 // Described in the "Operating Channel Attribute" section.
4828 p2pie[ p2pielen++ ] = 0x04;
4829
4830 // Value:
4831 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4832 {
4833 if ( pwdinfo->peer_operating_ch <= 14 )
4834 {
4835 // Operating Class
4836 p2pie[ p2pielen++ ] = 0x51;
4837 }
4838 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4839 {
4840 // Operating Class
4841 p2pie[ p2pielen++ ] = 0x73;
4842 }
4843 else
4844 {
4845 // Operating Class
4846 p2pie[ p2pielen++ ] = 0x7c;
4847 }
4848 p2pie[ p2pielen++ ] = 1;
4849 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4850 }
4851 else
4852 {
4853 if ( pwdinfo->operating_channel <= 14 )
4854 {
4855 // Operating Class
4856 p2pie[ p2pielen++ ] = 0x51;
4857 }
4858 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4859 {
4860 // Operating Class
4861 p2pie[ p2pielen++ ] = 0x73;
4862 }
4863 else
4864 {
4865 // Operating Class
4866 p2pie[ p2pielen++ ] = 0x7c;
4867 }
4868
4869 // Channel Number
4870 p2pie[ p2pielen++ ] = 1;
4871 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4872 }
4873
4874 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4875 {
4876 // Group ID Attribute
4877 // Type:
4878 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4879
4880 // Length:
4881 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4882 p2pielen += 2;
4883
4884 // Value:
4885 // p2P Device Address
4886 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4887 p2pielen += ETH_ALEN;
4888
4889 // SSID
4890 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4891 p2pielen += pwdinfo->nego_ssidlen;
4892 }
4893
4894 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4895
4896 #ifdef CONFIG_WFD
4897 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4898 pframe += wfdielen;
4899 pattrib->pktlen += wfdielen;
4900 #endif //CONFIG_WFD
4901
4902 pattrib->last_txcmdsz = pattrib->pktlen;
4903
4904 dump_mgntframe(padapter, pmgntframe);
4905
4906 return;
4907
4908 }
4909
issue_p2p_invitation_request(_adapter * padapter,u8 * raddr)4910 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
4911 {
4912
4913 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4914 u8 action = P2P_PUB_ACTION_ACTION;
4915 u32 p2poui = cpu_to_be32(P2POUI);
4916 u8 oui_subtype = P2P_INVIT_REQ;
4917 u8 p2pie[ 255 ] = { 0x00 };
4918 u8 p2pielen = 0, i;
4919 u8 dialogToken = 3;
4920 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4921 u16 len_channellist_attr = 0;
4922 #ifdef CONFIG_WFD
4923 u32 wfdielen = 0;
4924 #endif //CONFIG_WFD
4925 #ifdef CONFIG_CONCURRENT_MODE
4926 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4927 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4928 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4929 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4930 #endif
4931
4932 struct xmit_frame *pmgntframe;
4933 struct pkt_attrib *pattrib;
4934 unsigned char *pframe;
4935 struct rtw_ieee80211_hdr *pwlanhdr;
4936 unsigned short *fctrl;
4937 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4938 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4939 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4940 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4941
4942
4943 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4944 {
4945 return;
4946 }
4947
4948 //update attribute
4949 pattrib = &pmgntframe->attrib;
4950 update_mgntframe_attrib(padapter, pattrib);
4951
4952 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4953
4954 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4955 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4956
4957 fctrl = &(pwlanhdr->frame_ctl);
4958 *(fctrl) = 0;
4959
4960 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4961 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4962 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
4963
4964 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4965 pmlmeext->mgnt_seq++;
4966 SetFrameSubType(pframe, WIFI_ACTION);
4967
4968 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4969 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4970
4971 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4972 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4973 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4974 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4975 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4976
4977 // P2P IE Section.
4978
4979 // P2P OUI
4980 p2pielen = 0;
4981 p2pie[ p2pielen++ ] = 0x50;
4982 p2pie[ p2pielen++ ] = 0x6F;
4983 p2pie[ p2pielen++ ] = 0x9A;
4984 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4985
4986 // Commented by Albert 20101011
4987 // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
4988 // 1. Configuration Timeout
4989 // 2. Invitation Flags
4990 // 3. Operating Channel ( Only GO )
4991 // 4. P2P Group BSSID ( Should be included if I am the GO )
4992 // 5. Channel List
4993 // 6. P2P Group ID
4994 // 7. P2P Device Info
4995
4996 // Configuration Timeout
4997 // Type:
4998 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4999
5000 // Length:
5001 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5002 p2pielen += 2;
5003
5004 // Value:
5005 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
5006 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
5007
5008 // Invitation Flags
5009 // Type:
5010 p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
5011
5012 // Length:
5013 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5014 p2pielen += 2;
5015
5016 // Value:
5017 p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
5018
5019
5020 // Operating Channel
5021 // Type:
5022 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5023
5024 // Length:
5025 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5026 p2pielen += 2;
5027
5028 // Value:
5029 // Country String
5030 p2pie[ p2pielen++ ] = 'X';
5031 p2pie[ p2pielen++ ] = 'X';
5032
5033 // The third byte should be set to 0x04.
5034 // Described in the "Operating Channel Attribute" section.
5035 p2pie[ p2pielen++ ] = 0x04;
5036
5037 // Operating Class
5038 if ( pwdinfo->invitereq_info.operating_ch <= 14 )
5039 p2pie[ p2pielen++ ] = 0x51;
5040 else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
5041 p2pie[ p2pielen++ ] = 0x73;
5042 else
5043 p2pie[ p2pielen++ ] = 0x7c;
5044
5045 // Channel Number
5046 p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number
5047
5048 if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
5049 {
5050 // P2P Group BSSID
5051 // Type:
5052 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5053
5054 // Length:
5055 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5056 p2pielen += 2;
5057
5058 // Value:
5059 // P2P Device Address for GO
5060 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5061 p2pielen += ETH_ALEN;
5062 }
5063
5064 // Channel List
5065 // Type:
5066 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5067
5068
5069 // Length:
5070 // Country String(3)
5071 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5072 // + number of channels in all classes
5073 len_channellist_attr = 3
5074 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5075 + get_reg_classes_full_count(pmlmeext->channel_list);
5076
5077 #ifdef CONFIG_CONCURRENT_MODE
5078 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5079 {
5080 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5081 }
5082 else
5083 {
5084 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5085 }
5086 #else
5087
5088 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5089
5090 #endif
5091 p2pielen += 2;
5092
5093 // Value:
5094 // Country String
5095 p2pie[ p2pielen++ ] = 'X';
5096 p2pie[ p2pielen++ ] = 'X';
5097
5098 // The third byte should be set to 0x04.
5099 // Described in the "Operating Channel Attribute" section.
5100 p2pie[ p2pielen++ ] = 0x04;
5101
5102 // Channel Entry List
5103 #ifdef CONFIG_CONCURRENT_MODE
5104 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5105 {
5106 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5107 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5108
5109 // Operating Class
5110 if ( pbuddy_mlmeext->cur_channel > 14 )
5111 {
5112 if ( pbuddy_mlmeext->cur_channel >= 149 )
5113 {
5114 p2pie[ p2pielen++ ] = 0x7c;
5115 }
5116 else
5117 {
5118 p2pie[ p2pielen++ ] = 0x73;
5119 }
5120 }
5121 else
5122 {
5123 p2pie[ p2pielen++ ] = 0x51;
5124 }
5125
5126 // Number of Channels
5127 // Just support 1 channel and this channel is AP's channel
5128 p2pie[ p2pielen++ ] = 1;
5129
5130 // Channel List
5131 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5132 }
5133 else
5134 {
5135 int i, j;
5136 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5137 // Operating Class
5138 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5139
5140 // Number of Channels
5141 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5142
5143 // Channel List
5144 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5145 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5146 }
5147 }
5148 }
5149 #else // CONFIG_CONCURRENT_MODE
5150 {
5151 int i, j;
5152 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5153 // Operating Class
5154 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5155
5156 // Number of Channels
5157 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5158
5159 // Channel List
5160 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5161 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5162 }
5163 }
5164 }
5165 #endif // CONFIG_CONCURRENT_MODE
5166
5167
5168 // P2P Group ID
5169 // Type:
5170 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
5171
5172 // Length:
5173 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
5174 p2pielen += 2;
5175
5176 // Value:
5177 // P2P Device Address for GO
5178 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5179 p2pielen += ETH_ALEN;
5180
5181 // SSID
5182 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
5183 p2pielen += pwdinfo->invitereq_info.ssidlen;
5184
5185
5186 // Device Info
5187 // Type:
5188 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
5189
5190 // Length:
5191 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
5192 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
5193 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
5194 p2pielen += 2;
5195
5196 // Value:
5197 // P2P Device Address
5198 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5199 p2pielen += ETH_ALEN;
5200
5201 // Config Method
5202 // This field should be big endian. Noted by P2P specification.
5203 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
5204 p2pielen += 2;
5205
5206 // Primary Device Type
5207 // Category ID
5208 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5209 p2pielen += 2;
5210
5211 // OUI
5212 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
5213 p2pielen += 4;
5214
5215 // Sub Category ID
5216 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5217 p2pielen += 2;
5218
5219 // Number of Secondary Device Types
5220 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
5221
5222 // Device Name
5223 // Type:
5224 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5225 p2pielen += 2;
5226
5227 // Length:
5228 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
5229 p2pielen += 2;
5230
5231 // Value:
5232 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
5233 p2pielen += pwdinfo->device_name_len;
5234
5235 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5236
5237 #ifdef CONFIG_WFD
5238 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5239 pframe += wfdielen;
5240 pattrib->pktlen += wfdielen;
5241 #endif //CONFIG_WFD
5242
5243 pattrib->last_txcmdsz = pattrib->pktlen;
5244
5245 dump_mgntframe(padapter, pmgntframe);
5246
5247 return;
5248
5249 }
5250
issue_p2p_invitation_response(_adapter * padapter,u8 * raddr,u8 dialogToken,u8 status_code)5251 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
5252 {
5253
5254 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5255 u8 action = P2P_PUB_ACTION_ACTION;
5256 u32 p2poui = cpu_to_be32(P2POUI);
5257 u8 oui_subtype = P2P_INVIT_RESP;
5258 u8 p2pie[ 255 ] = { 0x00 };
5259 u8 p2pielen = 0, i;
5260 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5261 u16 len_channellist_attr = 0;
5262 #ifdef CONFIG_CONCURRENT_MODE
5263 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5264 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5265 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5266 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5267 #endif
5268 #ifdef CONFIG_WFD
5269 u32 wfdielen = 0;
5270 #endif //CONFIG_WFD
5271
5272 struct xmit_frame *pmgntframe;
5273 struct pkt_attrib *pattrib;
5274 unsigned char *pframe;
5275 struct rtw_ieee80211_hdr *pwlanhdr;
5276 unsigned short *fctrl;
5277 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5278 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5279 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5280 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
5281
5282
5283 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5284 {
5285 return;
5286 }
5287
5288 //update attribute
5289 pattrib = &pmgntframe->attrib;
5290 update_mgntframe_attrib(padapter, pattrib);
5291
5292 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5293
5294 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5295 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5296
5297 fctrl = &(pwlanhdr->frame_ctl);
5298 *(fctrl) = 0;
5299
5300 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5301 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5302 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5303
5304 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5305 pmlmeext->mgnt_seq++;
5306 SetFrameSubType(pframe, WIFI_ACTION);
5307
5308 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5309 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5310
5311 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5312 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5313 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5314 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5315 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5316
5317 // P2P IE Section.
5318
5319 // P2P OUI
5320 p2pielen = 0;
5321 p2pie[ p2pielen++ ] = 0x50;
5322 p2pie[ p2pielen++ ] = 0x6F;
5323 p2pie[ p2pielen++ ] = 0x9A;
5324 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
5325
5326 // Commented by Albert 20101005
5327 // According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
5328 // 1. Status
5329 // 2. Configuration Timeout
5330 // 3. Operating Channel ( Only GO )
5331 // 4. P2P Group BSSID ( Only GO )
5332 // 5. Channel List
5333
5334 // P2P Status
5335 // Type:
5336 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
5337
5338 // Length:
5339 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5340 p2pielen += 2;
5341
5342 // Value:
5343 // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
5344 // Sent the event receiving the P2P Invitation Req frame to DMP UI.
5345 // DMP had to compare the MAC address to find out the profile.
5346 // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
5347 // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
5348 // to NB to rebuild the persistent group.
5349 p2pie[ p2pielen++ ] = status_code;
5350
5351 // Configuration Timeout
5352 // Type:
5353 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5354
5355 // Length:
5356 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5357 p2pielen += 2;
5358
5359 // Value:
5360 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
5361 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
5362
5363 if( status_code == P2P_STATUS_SUCCESS )
5364 {
5365 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
5366 {
5367 // The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
5368 // In this case, the P2P Invitation response frame should carry the two more P2P attributes.
5369 // First one is operating channel attribute.
5370 // Second one is P2P Group BSSID attribute.
5371
5372 // Operating Channel
5373 // Type:
5374 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5375
5376 // Length:
5377 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5378 p2pielen += 2;
5379
5380 // Value:
5381 // Country String
5382 p2pie[ p2pielen++ ] = 'X';
5383 p2pie[ p2pielen++ ] = 'X';
5384
5385 // The third byte should be set to 0x04.
5386 // Described in the "Operating Channel Attribute" section.
5387 p2pie[ p2pielen++ ] = 0x04;
5388
5389 // Operating Class
5390 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
5391
5392 // Channel Number
5393 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
5394
5395
5396 // P2P Group BSSID
5397 // Type:
5398 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5399
5400 // Length:
5401 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5402 p2pielen += 2;
5403
5404 // Value:
5405 // P2P Device Address for GO
5406 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5407 p2pielen += ETH_ALEN;
5408
5409 }
5410
5411 // Channel List
5412 // Type:
5413 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5414
5415 // Length:
5416 // Country String(3)
5417 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5418 // + number of channels in all classes
5419 len_channellist_attr = 3
5420 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5421 + get_reg_classes_full_count(pmlmeext->channel_list);
5422
5423 #ifdef CONFIG_CONCURRENT_MODE
5424 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5425 {
5426 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5427 }
5428 else
5429 {
5430 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5431 }
5432 #else
5433
5434 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5435
5436 #endif
5437 p2pielen += 2;
5438
5439 // Value:
5440 // Country String
5441 p2pie[ p2pielen++ ] = 'X';
5442 p2pie[ p2pielen++ ] = 'X';
5443
5444 // The third byte should be set to 0x04.
5445 // Described in the "Operating Channel Attribute" section.
5446 p2pie[ p2pielen++ ] = 0x04;
5447
5448 // Channel Entry List
5449 #ifdef CONFIG_CONCURRENT_MODE
5450 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5451 {
5452 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5453 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5454
5455 // Operating Class
5456 if ( pbuddy_mlmeext->cur_channel > 14 )
5457 {
5458 if ( pbuddy_mlmeext->cur_channel >= 149 )
5459 {
5460 p2pie[ p2pielen++ ] = 0x7c;
5461 }
5462 else
5463 {
5464 p2pie[ p2pielen++ ] = 0x73;
5465 }
5466 }
5467 else
5468 {
5469 p2pie[ p2pielen++ ] = 0x51;
5470 }
5471
5472 // Number of Channels
5473 // Just support 1 channel and this channel is AP's channel
5474 p2pie[ p2pielen++ ] = 1;
5475
5476 // Channel List
5477 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5478 }
5479 else
5480 {
5481 int i, j;
5482 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5483 // Operating Class
5484 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5485
5486 // Number of Channels
5487 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5488
5489 // Channel List
5490 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5491 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5492 }
5493 }
5494 }
5495 #else // CONFIG_CONCURRENT_MODE
5496 {
5497 int i, j;
5498 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5499 // Operating Class
5500 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5501
5502 // Number of Channels
5503 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5504
5505 // Channel List
5506 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5507 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5508 }
5509 }
5510 }
5511 #endif // CONFIG_CONCURRENT_MODE
5512 }
5513
5514 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5515
5516 #ifdef CONFIG_WFD
5517 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5518 pframe += wfdielen;
5519 pattrib->pktlen += wfdielen;
5520 #endif //CONFIG_WFD
5521
5522 pattrib->last_txcmdsz = pattrib->pktlen;
5523
5524 dump_mgntframe(padapter, pmgntframe);
5525
5526 return;
5527
5528 }
5529
issue_p2p_provision_request(_adapter * padapter,u8 * pssid,u8 ussidlen,u8 * pdev_raddr)5530 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
5531 {
5532 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5533 u8 action = P2P_PUB_ACTION_ACTION;
5534 u8 dialogToken = 1;
5535 u32 p2poui = cpu_to_be32(P2POUI);
5536 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
5537 u8 wpsie[ 100 ] = { 0x00 };
5538 u8 wpsielen = 0;
5539 u32 p2pielen = 0;
5540 #ifdef CONFIG_WFD
5541 u32 wfdielen = 0;
5542 #endif //CONFIG_WFD
5543
5544 struct xmit_frame *pmgntframe;
5545 struct pkt_attrib *pattrib;
5546 unsigned char *pframe;
5547 struct rtw_ieee80211_hdr *pwlanhdr;
5548 unsigned short *fctrl;
5549 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5550 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5551 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5552 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5553
5554
5555 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5556 {
5557 return;
5558 }
5559
5560 DBG_871X( "[%s] In\n", __FUNCTION__ );
5561 //update attribute
5562 pattrib = &pmgntframe->attrib;
5563 update_mgntframe_attrib(padapter, pattrib);
5564
5565 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5566
5567 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5568 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5569
5570 fctrl = &(pwlanhdr->frame_ctl);
5571 *(fctrl) = 0;
5572
5573 _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5574 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5575 _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5576
5577 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5578 pmlmeext->mgnt_seq++;
5579 SetFrameSubType(pframe, WIFI_ACTION);
5580
5581 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5582 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5583
5584 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5585 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5586 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5587 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5588 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5589
5590 p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
5591
5592 pframe += p2pielen;
5593 pattrib->pktlen += p2pielen;
5594
5595 wpsielen = 0;
5596 // WPS OUI
5597 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5598 wpsielen += 4;
5599
5600 // WPS version
5601 // Type:
5602 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5603 wpsielen += 2;
5604
5605 // Length:
5606 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5607 wpsielen += 2;
5608
5609 // Value:
5610 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5611
5612 // Config Method
5613 // Type:
5614 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5615 wpsielen += 2;
5616
5617 // Length:
5618 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5619 wpsielen += 2;
5620
5621 // Value:
5622 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
5623 wpsielen += 2;
5624
5625 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5626
5627
5628 #ifdef CONFIG_WFD
5629 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5630 pframe += wfdielen;
5631 pattrib->pktlen += wfdielen;
5632 #endif //CONFIG_WFD
5633
5634 pattrib->last_txcmdsz = pattrib->pktlen;
5635
5636 dump_mgntframe(padapter, pmgntframe);
5637
5638 return;
5639
5640 }
5641
5642
is_matched_in_profilelist(u8 * peermacaddr,struct profile_info * profileinfo)5643 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
5644 {
5645 u8 i, match_result = 0;
5646
5647 DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5648 peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
5649
5650 for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
5651 {
5652 DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5653 profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
5654 if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
5655 {
5656 match_result = 1;
5657 DBG_871X( "[%s] Match!\n", __FUNCTION__ );
5658 break;
5659 }
5660 }
5661
5662 return (match_result );
5663 }
5664
issue_probersp_p2p(_adapter * padapter,unsigned char * da)5665 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5666 {
5667 struct xmit_frame *pmgntframe;
5668 struct pkt_attrib *pattrib;
5669 unsigned char *pframe;
5670 struct rtw_ieee80211_hdr *pwlanhdr;
5671 unsigned short *fctrl;
5672 unsigned char *mac;
5673 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5674 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5675 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5676 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5677 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5678 u16 beacon_interval = 100;
5679 u16 capInfo = 0;
5680 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5681 u8 wpsie[255] = { 0x00 };
5682 u32 wpsielen = 0, p2pielen = 0;
5683 #ifdef CONFIG_WFD
5684 u32 wfdielen = 0;
5685 #endif //CONFIG_WFD
5686 #ifdef CONFIG_INTEL_WIDI
5687 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5688 #endif //CONFIG_INTEL_WIDI
5689
5690 //DBG_871X("%s\n", __FUNCTION__);
5691
5692 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5693 {
5694 return;
5695 }
5696
5697 //update attribute
5698 pattrib = &pmgntframe->attrib;
5699 update_mgntframe_attrib(padapter, pattrib);
5700
5701 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5702
5703 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5704 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5705
5706 mac = adapter_mac_addr(padapter);
5707
5708 fctrl = &(pwlanhdr->frame_ctl);
5709 *(fctrl) = 0;
5710 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5711 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5712
5713 // Use the device address for BSSID field.
5714 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5715
5716 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5717 pmlmeext->mgnt_seq++;
5718 SetFrameSubType(fctrl, WIFI_PROBERSP);
5719
5720 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5721 pattrib->pktlen = pattrib->hdrlen;
5722 pframe += pattrib->hdrlen;
5723
5724 //timestamp will be inserted by hardware
5725 pframe += 8;
5726 pattrib->pktlen += 8;
5727
5728 // beacon interval: 2 bytes
5729 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5730 pframe += 2;
5731 pattrib->pktlen += 2;
5732
5733 // capability info: 2 bytes
5734 // ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
5735 capInfo |= cap_ShortPremble;
5736 capInfo |= cap_ShortSlot;
5737
5738 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5739 pframe += 2;
5740 pattrib->pktlen += 2;
5741
5742
5743 // SSID
5744 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5745
5746 // supported rates...
5747 // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5748 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5749
5750 // DS parameter set
5751 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5752
5753 #ifdef CONFIG_IOCTL_CFG80211
5754 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5755 {
5756 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
5757 {
5758 //WPS IE
5759 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5760 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5761 pframe += pmlmepriv->wps_probe_resp_ie_len;
5762
5763 //P2P IE
5764 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5765 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5766 pframe += pmlmepriv->p2p_probe_resp_ie_len;
5767 }
5768 }
5769 else
5770 #endif //CONFIG_IOCTL_CFG80211
5771 {
5772
5773 // Todo: WPS IE
5774 // Noted by Albert 20100907
5775 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
5776
5777 wpsielen = 0;
5778 // WPS OUI
5779 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5780 wpsielen += 4;
5781
5782 // WPS version
5783 // Type:
5784 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5785 wpsielen += 2;
5786
5787 // Length:
5788 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5789 wpsielen += 2;
5790
5791 // Value:
5792 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5793
5794 #ifdef CONFIG_INTEL_WIDI
5795 // Commented by Kurt
5796 // Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
5797 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5798 || pmlmepriv->num_p2p_sdt != 0 )
5799 {
5800 //Sec dev type
5801 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
5802 wpsielen += 2;
5803
5804 // Length:
5805 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5806 wpsielen += 2;
5807
5808 // Value:
5809 // Category ID
5810 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
5811 wpsielen += 2;
5812
5813 // OUI
5814 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
5815 wpsielen += 4;
5816
5817 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
5818 wpsielen += 2;
5819
5820 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
5821 {
5822 // Vendor Extension
5823 _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
5824 wpsielen += L2SDTA_SERVICE_VE_LEN;
5825 }
5826 }
5827 #endif //CONFIG_INTEL_WIDI
5828
5829 // WiFi Simple Config State
5830 // Type:
5831 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
5832 wpsielen += 2;
5833
5834 // Length:
5835 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5836 wpsielen += 2;
5837
5838 // Value:
5839 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; // Not Configured.
5840
5841 // Response Type
5842 // Type:
5843 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
5844 wpsielen += 2;
5845
5846 // Length:
5847 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5848 wpsielen += 2;
5849
5850 // Value:
5851 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5852
5853 // UUID-E
5854 // Type:
5855 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5856 wpsielen += 2;
5857
5858 // Length:
5859 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5860 wpsielen += 2;
5861
5862 // Value:
5863 if (pwdinfo->external_uuid == 0) {
5864 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
5865 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5866 } else {
5867 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5868 }
5869 wpsielen += 0x10;
5870
5871 // Manufacturer
5872 // Type:
5873 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
5874 wpsielen += 2;
5875
5876 // Length:
5877 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
5878 wpsielen += 2;
5879
5880 // Value:
5881 _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
5882 wpsielen += 7;
5883
5884 // Model Name
5885 // Type:
5886 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
5887 wpsielen += 2;
5888
5889 // Length:
5890 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
5891 wpsielen += 2;
5892
5893 // Value:
5894 _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
5895 wpsielen += 6;
5896
5897 // Model Number
5898 // Type:
5899 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
5900 wpsielen += 2;
5901
5902 // Length:
5903 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5904 wpsielen += 2;
5905
5906 // Value:
5907 wpsie[ wpsielen++ ] = 0x31; // character 1
5908
5909 // Serial Number
5910 // Type:
5911 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
5912 wpsielen += 2;
5913
5914 // Length:
5915 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
5916 wpsielen += 2;
5917
5918 // Value:
5919 _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
5920 wpsielen += ETH_ALEN;
5921
5922 // Primary Device Type
5923 // Type:
5924 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5925 wpsielen += 2;
5926
5927 // Length:
5928 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5929 wpsielen += 2;
5930
5931 // Value:
5932 // Category ID
5933 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5934 wpsielen += 2;
5935
5936 // OUI
5937 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
5938 wpsielen += 4;
5939
5940 // Sub Category ID
5941 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5942 wpsielen += 2;
5943
5944 // Device Name
5945 // Type:
5946 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5947 wpsielen += 2;
5948
5949 // Length:
5950 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
5951 wpsielen += 2;
5952
5953 // Value:
5954 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
5955 wpsielen += pwdinfo->device_name_len;
5956
5957 // Config Method
5958 // Type:
5959 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5960 wpsielen += 2;
5961
5962 // Length:
5963 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5964 wpsielen += 2;
5965
5966 // Value:
5967 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
5968 wpsielen += 2;
5969
5970
5971 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5972
5973
5974 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
5975 pframe += p2pielen;
5976 pattrib->pktlen += p2pielen;
5977 }
5978
5979 #ifdef CONFIG_WFD
5980 #ifdef CONFIG_IOCTL_CFG80211
5981 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
5982 #endif //CONFIG_IOCTL_CFG80211
5983 {
5984 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
5985 pframe += wfdielen;
5986 pattrib->pktlen += wfdielen;
5987 }
5988 #ifdef CONFIG_IOCTL_CFG80211
5989 else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
5990 {
5991 //WFD IE
5992 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
5993 pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
5994 pframe += pmlmepriv->wfd_probe_resp_ie_len;
5995 }
5996 #endif //CONFIG_IOCTL_CFG80211
5997 #endif //CONFIG_WFD
5998
5999 pattrib->last_txcmdsz = pattrib->pktlen;
6000
6001
6002 dump_mgntframe(padapter, pmgntframe);
6003
6004 return;
6005
6006 }
6007
_issue_probereq_p2p(_adapter * padapter,u8 * da,int wait_ack)6008 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6009 {
6010 int ret = _FAIL;
6011 struct xmit_frame *pmgntframe;
6012 struct pkt_attrib *pattrib;
6013 unsigned char *pframe;
6014 struct rtw_ieee80211_hdr *pwlanhdr;
6015 unsigned short *fctrl;
6016 unsigned char *mac;
6017 unsigned char bssrate[NumRates];
6018 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6019 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6020 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6021 int bssrate_len = 0;
6022 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6023 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6024 u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
6025 u16 wpsielen = 0, p2pielen = 0;
6026 #ifdef CONFIG_WFD
6027 u32 wfdielen = 0;
6028 #endif //CONFIG_WFD
6029
6030 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6031
6032
6033 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6034 {
6035 goto exit;
6036 }
6037
6038 //update attribute
6039 pattrib = &pmgntframe->attrib;
6040 update_mgntframe_attrib(padapter, pattrib);
6041
6042
6043 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6044
6045 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6046 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6047
6048 mac = adapter_mac_addr(padapter);
6049
6050 fctrl = &(pwlanhdr->frame_ctl);
6051 *(fctrl) = 0;
6052
6053 if (da) {
6054 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6055 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6056 } else {
6057 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
6058 {
6059 // This two flags will be set when this is only the P2P client mode.
6060 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6061 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6062 }
6063 else
6064 {
6065 // broadcast probe request frame
6066 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6067 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6068 }
6069 }
6070 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6071
6072 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6073 pmlmeext->mgnt_seq++;
6074 SetFrameSubType(pframe, WIFI_PROBEREQ);
6075
6076 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6077 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6078
6079 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6080 {
6081 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6082 }
6083 else
6084 {
6085 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6086 }
6087 // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
6088 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6089
6090 #ifdef CONFIG_IOCTL_CFG80211
6091 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
6092 {
6093 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
6094 {
6095 //WPS IE
6096 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6097 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6098 pframe += pmlmepriv->wps_probe_req_ie_len;
6099
6100 //P2P IE
6101 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6102 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6103 pframe += pmlmepriv->p2p_probe_req_ie_len;
6104 }
6105 }
6106 else
6107 #endif //CONFIG_IOCTL_CFG80211
6108 {
6109
6110 // WPS IE
6111 // Noted by Albert 20110221
6112 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
6113
6114 wpsielen = 0;
6115 // WPS OUI
6116 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
6117 wpsielen += 4;
6118
6119 // WPS version
6120 // Type:
6121 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
6122 wpsielen += 2;
6123
6124 // Length:
6125 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
6126 wpsielen += 2;
6127
6128 // Value:
6129 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
6130
6131 if( pmlmepriv->wps_probe_req_ie == NULL )
6132 {
6133 // UUID-E
6134 // Type:
6135 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
6136 wpsielen += 2;
6137
6138 // Length:
6139 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
6140 wpsielen += 2;
6141
6142 // Value:
6143 if (pwdinfo->external_uuid == 0) {
6144 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
6145 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6146 } else {
6147 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
6148 }
6149 wpsielen += 0x10;
6150
6151 // Config Method
6152 // Type:
6153 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6154 wpsielen += 2;
6155
6156 // Length:
6157 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6158 wpsielen += 2;
6159
6160 // Value:
6161 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6162 wpsielen += 2;
6163 }
6164
6165 // Device Name
6166 // Type:
6167 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6168 wpsielen += 2;
6169
6170 // Length:
6171 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6172 wpsielen += 2;
6173
6174 // Value:
6175 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6176 wpsielen += pwdinfo->device_name_len;
6177
6178 // Primary Device Type
6179 // Type:
6180 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6181 wpsielen += 2;
6182
6183 // Length:
6184 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6185 wpsielen += 2;
6186
6187 // Value:
6188 // Category ID
6189 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
6190 wpsielen += 2;
6191
6192 // OUI
6193 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6194 wpsielen += 4;
6195
6196 // Sub Category ID
6197 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
6198 wpsielen += 2;
6199
6200 // Device Password ID
6201 // Type:
6202 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
6203 wpsielen += 2;
6204
6205 // Length:
6206 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6207 wpsielen += 2;
6208
6209 // Value:
6210 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified
6211 wpsielen += 2;
6212
6213 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6214
6215 // P2P OUI
6216 p2pielen = 0;
6217 p2pie[ p2pielen++ ] = 0x50;
6218 p2pie[ p2pielen++ ] = 0x6F;
6219 p2pie[ p2pielen++ ] = 0x9A;
6220 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
6221
6222 // Commented by Albert 20110221
6223 // According to the P2P Specification, the probe request frame should contain 5 P2P attributes
6224 // 1. P2P Capability
6225 // 2. P2P Device ID if this probe request wants to find the specific P2P device
6226 // 3. Listen Channel
6227 // 4. Extended Listen Timing
6228 // 5. Operating Channel if this WiFi is working as the group owner now
6229
6230 // P2P Capability
6231 // Type:
6232 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
6233
6234 // Length:
6235 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
6236 p2pielen += 2;
6237
6238 // Value:
6239 // Device Capability Bitmap, 1 byte
6240 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
6241
6242 // Group Capability Bitmap, 1 byte
6243 if ( pwdinfo->persistent_supported )
6244 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6245 else
6246 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
6247
6248 // Listen Channel
6249 // Type:
6250 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
6251
6252 // Length:
6253 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6254 p2pielen += 2;
6255
6256 // Value:
6257 // Country String
6258 p2pie[ p2pielen++ ] = 'X';
6259 p2pie[ p2pielen++ ] = 'X';
6260
6261 // The third byte should be set to 0x04.
6262 // Described in the "Operating Channel Attribute" section.
6263 p2pie[ p2pielen++ ] = 0x04;
6264
6265 // Operating Class
6266 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
6267
6268 // Channel Number
6269 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listen channel
6270
6271
6272 // Extended Listen Timing
6273 // Type:
6274 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
6275
6276 // Length:
6277 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
6278 p2pielen += 2;
6279
6280 // Value:
6281 // Availability Period
6282 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6283 p2pielen += 2;
6284
6285 // Availability Interval
6286 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6287 p2pielen += 2;
6288
6289 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
6290 {
6291 // Operating Channel (if this WiFi is working as the group owner now)
6292 // Type:
6293 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
6294
6295 // Length:
6296 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6297 p2pielen += 2;
6298
6299 // Value:
6300 // Country String
6301 p2pie[ p2pielen++ ] = 'X';
6302 p2pie[ p2pielen++ ] = 'X';
6303
6304 // The third byte should be set to 0x04.
6305 // Described in the "Operating Channel Attribute" section.
6306 p2pie[ p2pielen++ ] = 0x04;
6307
6308 // Operating Class
6309 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
6310
6311 // Channel Number
6312 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
6313
6314 }
6315
6316 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
6317
6318 }
6319
6320 #ifdef CONFIG_WFD
6321 #ifdef CONFIG_IOCTL_CFG80211
6322 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
6323 #endif
6324 {
6325 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
6326 pframe += wfdielen;
6327 pattrib->pktlen += wfdielen;
6328 }
6329 #ifdef CONFIG_IOCTL_CFG80211
6330 else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
6331 {
6332 //WFD IE
6333 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
6334 pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
6335 pframe += pmlmepriv->wfd_probe_req_ie_len;
6336 }
6337 #endif //CONFIG_IOCTL_CFG80211
6338 #endif //CONFIG_WFD
6339
6340 pattrib->last_txcmdsz = pattrib->pktlen;
6341
6342 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6343
6344 if (wait_ack) {
6345 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6346 } else {
6347 dump_mgntframe(padapter, pmgntframe);
6348 ret = _SUCCESS;
6349 }
6350
6351 exit:
6352 return ret;
6353 }
6354
issue_probereq_p2p(_adapter * adapter,u8 * da)6355 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6356 {
6357 _issue_probereq_p2p(adapter, da, _FALSE);
6358 }
6359
6360 /*
6361 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6362 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
6363 * try_cnt means the maximal TX count to try
6364 */
issue_probereq_p2p_ex(_adapter * adapter,u8 * da,int try_cnt,int wait_ms)6365 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6366 {
6367 int ret;
6368 int i = 0;
6369 u32 start = rtw_get_current_time();
6370
6371 do
6372 {
6373 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
6374
6375 i++;
6376
6377 if (RTW_CANNOT_RUN(adapter))
6378 break;
6379
6380 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6381 rtw_msleep_os(wait_ms);
6382
6383 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6384
6385 if (ret != _FAIL) {
6386 ret = _SUCCESS;
6387 #ifndef DBG_XMIT_ACK
6388 goto exit;
6389 #endif
6390 }
6391
6392 if (try_cnt && wait_ms) {
6393 if (da)
6394 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6395 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6396 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6397 else
6398 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6399 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6400 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6401 }
6402 exit:
6403 return ret;
6404 }
6405
6406 #endif //CONFIG_P2P
6407
rtw_action_public_decache(union recv_frame * recv_frame,s32 token)6408 s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
6409 {
6410 _adapter *adapter = recv_frame->u.hdr.adapter;
6411 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6412 u8 *frame = recv_frame->u.hdr.rx_data;
6413 u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
6414 (recv_frame->u.hdr.attrib.frag_num & 0xf);
6415
6416 if (GetRetry(frame)) {
6417 if (token >= 0) {
6418 if ((seq_ctrl == mlmeext->action_public_rxseq)
6419 && (token == mlmeext->action_public_dialog_token))
6420 {
6421 DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6422 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6423 return _FAIL;
6424 }
6425 } else {
6426 if (seq_ctrl == mlmeext->action_public_rxseq) {
6427 DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
6428 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
6429 return _FAIL;
6430 }
6431 }
6432 }
6433
6434 mlmeext->action_public_rxseq = seq_ctrl;
6435
6436 if (token >= 0)
6437 mlmeext->action_public_dialog_token = token;
6438
6439 return _SUCCESS;
6440 }
6441
on_action_public_p2p(union recv_frame * precv_frame)6442 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6443 {
6444 _adapter *padapter = precv_frame->u.hdr.adapter;
6445 u8 *pframe = precv_frame->u.hdr.rx_data;
6446 uint len = precv_frame->u.hdr.len;
6447 u8 *frame_body;
6448 u8 dialogToken=0;
6449 #ifdef CONFIG_P2P
6450 u8 *p2p_ie;
6451 u32 p2p_ielen, wps_ielen;
6452 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6453 u8 result = P2P_STATUS_SUCCESS;
6454 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6455 u8 *merged_p2pie = NULL;
6456 u32 merged_p2p_ielen= 0;
6457 #endif //CONFIG_P2P
6458
6459 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6460
6461 dialogToken = frame_body[7];
6462
6463 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
6464 return _FAIL;
6465
6466 #ifdef CONFIG_P2P
6467 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
6468 #ifdef CONFIG_IOCTL_CFG80211
6469 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6470 {
6471 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
6472 }
6473 else
6474 #endif //CONFIG_IOCTL_CFG80211
6475 {
6476 // Do nothing if the driver doesn't enable the P2P function.
6477 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6478 return _SUCCESS;
6479
6480 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6481
6482 switch( frame_body[ 6 ] )//OUI Subtype
6483 {
6484 case P2P_GO_NEGO_REQ:
6485 {
6486 DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6487 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
6488
6489 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6490 {
6491 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6492 }
6493
6494 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6495 {
6496 // Commented by Albert 20110526
6497 // In this case, this means the previous nego fail doesn't be reset yet.
6498 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6499 // Restore the previous p2p state
6500 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6501 DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
6502 }
6503 #ifdef CONFIG_CONCURRENT_MODE
6504 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
6505 {
6506 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6507 }
6508 #endif // CONFIG_CONCURRENT_MODE
6509
6510 // Commented by Kurt 20110902
6511 //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6512 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6513 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6514
6515 // Commented by Kurt 20120113
6516 // Get peer_dev_addr here if peer doesn't issue prov_disc frame.
6517 if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
6518 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6519
6520 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
6521 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
6522 #ifdef CONFIG_INTEL_WIDI
6523 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6524 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6525 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6526 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6527 }
6528 #endif //CONFIG_INTEL_WIDI
6529
6530 // Commented by Albert 20110718
6531 // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
6532 #ifdef CONFIG_CONCURRENT_MODE
6533 // Commented by Albert 20120107
6534 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6535 #else // CONFIG_CONCURRENT_MODE
6536 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6537 #endif // CONFIG_CONCURRENT_MODE
6538 break;
6539 }
6540 case P2P_GO_NEGO_RESP:
6541 {
6542 DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6543
6544 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6545 {
6546 // Commented by Albert 20110425
6547 // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
6548 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6549 pwdinfo->nego_req_info.benable = _FALSE;
6550 result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
6551 issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
6552 if ( P2P_STATUS_SUCCESS == result )
6553 {
6554 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6555 {
6556 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6557 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6558 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6559 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6560 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6561 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6562 pwdinfo->p2p_info.scan_op_ch_only = 1;
6563 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6564 }
6565 }
6566
6567 // Reset the dialog token for group negotiation frames.
6568 pwdinfo->negotiation_dialog_token = 1;
6569
6570 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6571 {
6572 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6573 }
6574 }
6575 else
6576 {
6577 DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6578 }
6579
6580 break;
6581 }
6582 case P2P_GO_NEGO_CONF:
6583 {
6584 DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6585 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
6586 if ( P2P_STATUS_SUCCESS == result )
6587 {
6588 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6589 {
6590 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6591 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6592 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6593 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6594 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6595 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6596 pwdinfo->p2p_info.scan_op_ch_only = 1;
6597 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6598 }
6599 }
6600 break;
6601 }
6602 case P2P_INVIT_REQ:
6603 {
6604 // Added by Albert 2010/10/05
6605 // Received the P2P Invite Request frame.
6606
6607 DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
6608 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6609 {
6610 // Parse the necessary information from the P2P Invitation Request frame.
6611 // For example: The MAC address of sending this P2P Invitation Request frame.
6612 u32 attr_contentlen = 0;
6613 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6614 struct group_id_info group_id;
6615 u8 invitation_flag = 0;
6616 int j=0;
6617
6618 merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6619
6620 merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); // 2 is for EID and Length
6621 if (merged_p2pie == NULL)
6622 {
6623 DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
6624 goto exit;
6625 }
6626 _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
6627
6628 merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6629
6630 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6631 if ( attr_contentlen )
6632 {
6633
6634 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6635 // Commented by Albert 20120510
6636 // Copy to the pwdinfo->p2p_peer_interface_addr.
6637 // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
6638 // #> iwpriv wlan0 p2p_get peer_ifa
6639 // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
6640
6641 if ( attr_contentlen )
6642 {
6643 DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6644 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6645 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6646 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
6647 }
6648
6649 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
6650 {
6651 // Re-invoke the persistent group.
6652
6653 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6654 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6655 if ( attr_contentlen )
6656 {
6657 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6658 {
6659 // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
6660 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
6661 rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
6662 status_code = P2P_STATUS_SUCCESS;
6663 }
6664 else
6665 {
6666 // The p2p device sending this p2p invitation request wants to be the persistent GO.
6667 if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
6668 {
6669 u8 operatingch_info[5] = { 0x00 };
6670 if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
6671 {
6672 if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
6673 {
6674 // The operating channel is acceptable for this device.
6675 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
6676 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6677 pwdinfo->rx_invitereq_info.operation_ch[1]= 1; //Check whether GO is operating in channel 1;
6678 pwdinfo->rx_invitereq_info.operation_ch[2]= 6; //Check whether GO is operating in channel 6;
6679 pwdinfo->rx_invitereq_info.operation_ch[3]= 11; //Check whether GO is operating in channel 11;
6680 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6681 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6682 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
6683 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6684 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6685 status_code = P2P_STATUS_SUCCESS;
6686 }
6687 else
6688 {
6689 // The operating channel isn't supported by this device.
6690 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6691 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
6692 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6693 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6694 }
6695 }
6696 else
6697 {
6698 // Commented by Albert 20121130
6699 // Intel will use the different P2P IE to store the operating channel information
6700 // Workaround for Intel WiDi 3.5
6701 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6702 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6703 status_code = P2P_STATUS_SUCCESS;
6704 }
6705 }
6706 else
6707 {
6708 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6709 #ifdef CONFIG_INTEL_WIDI
6710 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6711 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6712 #endif //CONFIG_INTEL_WIDI
6713
6714 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6715 }
6716 }
6717 }
6718 else
6719 {
6720 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6721 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6722 }
6723 }
6724 else
6725 {
6726 // Received the invitation to join a P2P group.
6727
6728 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6729 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6730 if ( attr_contentlen )
6731 {
6732 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6733 {
6734 // In this case, the GO can't be myself.
6735 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6736 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6737 }
6738 else
6739 {
6740 // The p2p device sending this p2p invitation request wants to join an existing P2P group
6741 // Commented by Albert 2012/06/28
6742 // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
6743 // The peer device address should be the destination address for the provisioning discovery request.
6744 // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
6745 // The peer interface address should be the address for WPS mac address
6746 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6747 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6748 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
6749 status_code = P2P_STATUS_SUCCESS;
6750 }
6751 }
6752 else
6753 {
6754 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6755 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6756 }
6757 }
6758 }
6759 else
6760 {
6761 DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
6762 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6763 }
6764
6765 DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
6766
6767 pwdinfo->inviteresp_info.token = frame_body[ 7 ];
6768 issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
6769 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6770 }
6771 #ifdef CONFIG_INTEL_WIDI
6772 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6773 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6774 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6775 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6776 }
6777 #endif //CONFIG_INTEL_WIDI
6778 break;
6779 }
6780 case P2P_INVIT_RESP:
6781 {
6782 u8 attr_content = 0x00;
6783 u32 attr_contentlen = 0;
6784
6785 DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
6786 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6787 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6788 {
6789 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6790
6791 if ( attr_contentlen == 1 )
6792 {
6793 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
6794 pwdinfo->invitereq_info.benable = _FALSE;
6795
6796 if ( attr_content == P2P_STATUS_SUCCESS )
6797 {
6798 if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6799 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
6800 else
6801 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6802
6803 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
6804 }
6805 else
6806 {
6807 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6808 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6809 }
6810 }
6811 else
6812 {
6813 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6814 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6815 }
6816 }
6817 else
6818 {
6819 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6820 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6821 }
6822
6823 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
6824 {
6825 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6826 }
6827 break;
6828 }
6829 case P2P_DEVDISC_REQ:
6830
6831 process_p2p_devdisc_req(pwdinfo, pframe, len);
6832
6833 break;
6834
6835 case P2P_DEVDISC_RESP:
6836
6837 process_p2p_devdisc_resp(pwdinfo, pframe, len);
6838
6839 break;
6840
6841 case P2P_PROVISION_DISC_REQ:
6842 DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
6843 process_p2p_provdisc_req(pwdinfo, pframe, len);
6844 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6845
6846 //20110902 Kurt
6847 //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6848 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6849 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6850
6851 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6852 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6853 #ifdef CONFIG_INTEL_WIDI
6854 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6855 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6856 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6857 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6858 }
6859 #endif //CONFIG_INTEL_WIDI
6860 break;
6861
6862 case P2P_PROVISION_DISC_RESP:
6863 // Commented by Albert 20110707
6864 // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
6865 DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
6866 // Commented by Albert 20110426
6867 // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
6868 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6869 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6870 process_p2p_provdisc_resp(pwdinfo, pframe);
6871 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6872 break;
6873
6874 }
6875 }
6876
6877
6878 exit:
6879
6880 if(merged_p2pie)
6881 {
6882 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6883 }
6884 #endif //CONFIG_P2P
6885 return _SUCCESS;
6886 }
6887
on_action_public_vendor(union recv_frame * precv_frame)6888 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6889 {
6890 unsigned int ret = _FAIL;
6891 u8 *pframe = precv_frame->u.hdr.rx_data;
6892 uint frame_len = precv_frame->u.hdr.len;
6893 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6894
6895 if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6896 ret = on_action_public_p2p(precv_frame);
6897 }
6898
6899 return ret;
6900 }
6901
on_action_public_default(union recv_frame * precv_frame,u8 action)6902 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6903 {
6904 unsigned int ret = _FAIL;
6905 u8 *pframe = precv_frame->u.hdr.rx_data;
6906 uint frame_len = precv_frame->u.hdr.len;
6907 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6908 u8 token;
6909 _adapter *adapter = precv_frame->u.hdr.adapter;
6910 int cnt = 0;
6911 char msg[64];
6912
6913 token = frame_body[2];
6914
6915 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
6916 goto exit;
6917
6918 #ifdef CONFIG_IOCTL_CFG80211
6919 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
6920 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
6921 #endif
6922
6923 ret = _SUCCESS;
6924
6925 exit:
6926 return ret;
6927 }
6928
on_action_public(_adapter * padapter,union recv_frame * precv_frame)6929 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6930 {
6931 unsigned int ret = _FAIL;
6932 u8 *pframe = precv_frame->u.hdr.rx_data;
6933 uint frame_len = precv_frame->u.hdr.len;
6934 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6935 u8 category, action;
6936
6937 /* check RA matches or not */
6938 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6939 goto exit;
6940
6941 category = frame_body[0];
6942 if (category != RTW_WLAN_CATEGORY_PUBLIC)
6943 goto exit;
6944
6945 action = frame_body[1];
6946 switch (action) {
6947 case ACT_PUBLIC_BSSCOEXIST:
6948 #ifdef CONFIG_80211N_HT
6949 #ifdef CONFIG_AP_MODE
6950 /*20/40 BSS Coexistence Management frame is a Public Action frame*/
6951 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6952 rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6953 #endif /*CONFIG_AP_MODE*/
6954 #endif /*CONFIG_80211N_HT*/
6955 break;
6956 case ACT_PUBLIC_VENDOR:
6957 ret = on_action_public_vendor(precv_frame);
6958 break;
6959 default:
6960 ret = on_action_public_default(precv_frame, action);
6961 break;
6962 }
6963
6964 exit:
6965 return ret;
6966 }
6967
OnAction_ht(_adapter * padapter,union recv_frame * precv_frame)6968 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
6969 {
6970 u8 *pframe = precv_frame->u.hdr.rx_data;
6971 uint frame_len = precv_frame->u.hdr.len;
6972 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6973 u8 category, action;
6974
6975 /* check RA matches or not */
6976 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6977 goto exit;
6978
6979 category = frame_body[0];
6980 if (category != RTW_WLAN_CATEGORY_HT)
6981 goto exit;
6982
6983 action = frame_body[1];
6984 switch (action) {
6985 case RTW_WLAN_ACTION_HT_SM_PS:
6986 #ifdef CONFIG_80211N_HT
6987 #ifdef CONFIG_AP_MODE
6988 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6989 rtw_process_ht_action_smps(padapter, GetAddr2Ptr(pframe), frame_body[2]);
6990 #endif /*CONFIG_AP_MODE*/
6991 #endif /*CONFIG_80211N_HT*/
6992 break;
6993 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
6994 #ifdef CONFIG_BEAMFORMING
6995 //DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");
6996 beamforming_get_report_frame(padapter, precv_frame);
6997 #endif //CONFIG_BEAMFORMING
6998 break;
6999 default:
7000 break;
7001 }
7002
7003 exit:
7004
7005 return _SUCCESS;
7006 }
7007
7008 #ifdef CONFIG_IEEE80211W
OnAction_sa_query(_adapter * padapter,union recv_frame * precv_frame)7009 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7010 {
7011 u8 *pframe = precv_frame->u.hdr.rx_data;
7012 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7013 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7014 struct sta_info *psta;
7015 struct sta_priv *pstapriv = &padapter->stapriv;
7016 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7017 u16 tid;
7018 //Baron
7019
7020 DBG_871X("OnAction_sa_query\n");
7021
7022 switch (pframe[WLAN_HDR_A3_LEN+1])
7023 {
7024 case 0: //SA Query req
7025 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7026 DBG_871X("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7027 , pframe[WLAN_HDR_A3_LEN+1], tid, pframe[WLAN_HDR_A3_LEN+2], pframe[WLAN_HDR_A3_LEN+3]);
7028 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7029 break;
7030
7031 case 1: //SA Query rsp
7032 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
7033 if (psta != NULL)
7034 _cancel_timer_ex(&psta->dot11w_expire_timer);
7035
7036 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7037 DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], tid);
7038 break;
7039 default:
7040 break;
7041 }
7042 if(0)
7043 {
7044 int pp;
7045 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7046 for(pp=0;pp< pattrib->pkt_len; pp++)
7047 printk(" %02x ", pframe[pp]);
7048 printk("\n");
7049 }
7050
7051 return _SUCCESS;
7052 }
7053 #endif //CONFIG_IEEE80211W
7054
OnAction_wmm(_adapter * padapter,union recv_frame * precv_frame)7055 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7056 {
7057 return _SUCCESS;
7058 }
7059
OnAction_vht(_adapter * padapter,union recv_frame * precv_frame)7060 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7061 {
7062 #ifdef CONFIG_80211AC_VHT
7063 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
7064 u8 *pframe = precv_frame->u.hdr.rx_data;
7065 uint frame_len = precv_frame->u.hdr.len;
7066 struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7067 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7068 u8 category, action;
7069 struct sta_info *psta = NULL;
7070
7071 /* check RA matches or not */
7072 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7073 goto exit;
7074
7075 category = frame_body[0];
7076 if(category != RTW_WLAN_CATEGORY_VHT)
7077 goto exit;
7078
7079 action = frame_body[1];
7080 switch (action) {
7081 case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7082 #ifdef CONFIG_BEAMFORMING
7083 //DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");
7084 beamforming_get_report_frame(padapter, precv_frame);
7085 #endif //CONFIG_BEAMFORMING
7086 break;
7087 case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7088 // CategoryCode(1) + ActionCode(1) + OpModeNotification(1)
7089 //DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n");
7090 psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7091 if (psta)
7092 rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7093 break;
7094 default:
7095 break;
7096 }
7097
7098 exit:
7099 #endif //CONFIG_80211AC_VHT
7100
7101 return _SUCCESS;
7102 }
7103
OnAction_p2p(_adapter * padapter,union recv_frame * precv_frame)7104 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7105 {
7106 #ifdef CONFIG_P2P
7107 u8 *frame_body;
7108 u8 category, OUI_Subtype, dialogToken=0;
7109 u8 *pframe = precv_frame->u.hdr.rx_data;
7110 uint len = precv_frame->u.hdr.len;
7111 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
7112
7113 //check RA matches or not
7114 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7115 return _SUCCESS;
7116
7117 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7118
7119 category = frame_body[0];
7120 if(category != RTW_WLAN_CATEGORY_P2P)
7121 return _SUCCESS;
7122
7123 if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
7124 return _SUCCESS;
7125
7126 #ifdef CONFIG_IOCTL_CFG80211
7127 if (adapter_wdev_data(padapter)->p2p_enabled
7128 && pwdinfo->driver_interface == DRIVER_CFG80211
7129 ) {
7130 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
7131 return _SUCCESS;
7132 }
7133 else
7134 #endif //CONFIG_IOCTL_CFG80211
7135 {
7136 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7137 OUI_Subtype = frame_body[5];
7138 dialogToken = frame_body[6];
7139
7140 switch(OUI_Subtype)
7141 {
7142 case P2P_NOTICE_OF_ABSENCE:
7143
7144 break;
7145
7146 case P2P_PRESENCE_REQUEST:
7147
7148 process_p2p_presence_req(pwdinfo, pframe, len);
7149
7150 break;
7151
7152 case P2P_PRESENCE_RESPONSE:
7153
7154 break;
7155
7156 case P2P_GO_DISC_REQUEST:
7157
7158 break;
7159
7160 default:
7161 break;
7162
7163 }
7164 }
7165 #endif //CONFIG_P2P
7166
7167 return _SUCCESS;
7168
7169 }
7170
OnAction(_adapter * padapter,union recv_frame * precv_frame)7171 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7172 {
7173 int i;
7174 unsigned char category;
7175 struct action_handler *ptable;
7176 unsigned char *frame_body;
7177 u8 *pframe = precv_frame->u.hdr.rx_data;
7178
7179 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7180
7181 category = frame_body[0];
7182
7183 for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
7184 {
7185 ptable = &OnAction_tbl[i];
7186
7187 if(category == ptable->num)
7188 ptable->func(padapter, precv_frame);
7189
7190 }
7191
7192 return _SUCCESS;
7193
7194 }
7195
DoReserved(_adapter * padapter,union recv_frame * precv_frame)7196 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7197 {
7198
7199 //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
7200 return _SUCCESS;
7201 }
7202
_alloc_mgtxmitframe(struct xmit_priv * pxmitpriv,bool once)7203 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7204 {
7205 struct xmit_frame *pmgntframe;
7206 struct xmit_buf *pxmitbuf;
7207
7208 if (once)
7209 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7210 else
7211 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7212
7213 if (pmgntframe == NULL) {
7214 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7215 goto exit;
7216 }
7217
7218 if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
7219 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7220 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7221 pmgntframe = NULL;
7222 goto exit;
7223 }
7224
7225 pmgntframe->frame_tag = MGNT_FRAMETAG;
7226 pmgntframe->pxmitbuf = pxmitbuf;
7227 pmgntframe->buf_addr = pxmitbuf->pbuf;
7228 pxmitbuf->priv_data = pmgntframe;
7229
7230 exit:
7231 return pmgntframe;
7232
7233 }
7234
alloc_mgtxmitframe(struct xmit_priv * pxmitpriv)7235 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7236 {
7237 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7238 }
7239
alloc_mgtxmitframe_once(struct xmit_priv * pxmitpriv)7240 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7241 {
7242 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7243 }
7244
7245
7246 /****************************************************************************
7247
7248 Following are some TX fuctions for WiFi MLME
7249
7250 *****************************************************************************/
7251
update_mgnt_tx_rate(_adapter * padapter,u8 rate)7252 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7253 {
7254 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7255
7256 pmlmeext->tx_rate = rate;
7257 //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
7258 }
7259
update_mgntframe_attrib(_adapter * padapter,struct pkt_attrib * pattrib)7260 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7261 {
7262 u8 wireless_mode;
7263 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7264 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7265 struct sta_info *pbcmc_sta = NULL;
7266 //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
7267
7268 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7269
7270 pattrib->hdrlen = 24;
7271 pattrib->nr_frags = 1;
7272 pattrib->priority = 7;
7273
7274 if (pbcmc_sta)
7275 pattrib->mac_id = pbcmc_sta->mac_id;
7276 else {
7277 pattrib->mac_id = 0;
7278 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7279 }
7280 pattrib->qsel = QSLT_MGNT;
7281
7282 pattrib->pktlen = 0;
7283
7284 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7285 wireless_mode = WIRELESS_11B;
7286 else
7287 wireless_mode = WIRELESS_11G;
7288 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7289 pattrib->rate = pmlmeext->tx_rate;
7290
7291 pattrib->encrypt = _NO_PRIVACY_;
7292 pattrib->bswenc = _FALSE;
7293
7294 pattrib->qos_en = _FALSE;
7295 pattrib->ht_en = _FALSE;
7296 pattrib->bwmode = CHANNEL_WIDTH_20;
7297 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7298 pattrib->sgi = _FALSE;
7299
7300 pattrib->seqnum = pmlmeext->mgnt_seq;
7301
7302 pattrib->retry_ctrl = _TRUE;
7303
7304 pattrib->mbssid = 0;
7305 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7306
7307 }
7308
update_mgntframe_attrib_addr(_adapter * padapter,struct xmit_frame * pmgntframe)7309 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7310 {
7311 u8 *pframe;
7312 struct pkt_attrib *pattrib = &pmgntframe->attrib;
7313
7314 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7315
7316 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7317 _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
7318 }
7319
dump_mgntframe(_adapter * padapter,struct xmit_frame * pmgntframe)7320 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7321 {
7322 if (RTW_CANNOT_RUN(padapter)) {
7323 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7324 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7325 return;
7326 }
7327
7328 rtw_hal_mgnt_xmit(padapter, pmgntframe);
7329 }
7330
dump_mgntframe_and_wait(_adapter * padapter,struct xmit_frame * pmgntframe,int timeout_ms)7331 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7332 {
7333 s32 ret = _FAIL;
7334 _irqL irqL;
7335 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7336 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7337 struct submit_ctx sctx;
7338
7339 if (RTW_CANNOT_RUN(padapter)) {
7340 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7341 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7342 return ret;
7343 }
7344
7345 rtw_sctx_init(&sctx, timeout_ms);
7346 pxmitbuf->sctx = &sctx;
7347
7348 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7349
7350 if (ret == _SUCCESS)
7351 ret = rtw_sctx_wait(&sctx, __func__);
7352
7353 _enter_critical(&pxmitpriv->lock_sctx, &irqL);
7354 pxmitbuf->sctx = NULL;
7355 _exit_critical(&pxmitpriv->lock_sctx, &irqL);
7356
7357 return ret;
7358 }
7359
dump_mgntframe_and_wait_ack(_adapter * padapter,struct xmit_frame * pmgntframe)7360 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7361 {
7362 #ifdef CONFIG_XMIT_ACK
7363 static u8 seq_no = 0;
7364 s32 ret = _FAIL;
7365 u32 timeout_ms = 500;// 500ms
7366 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7367 #ifdef CONFIG_CONCURRENT_MODE
7368 if (padapter->pbuddy_adapter && !padapter->isprimary)
7369 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7370 #endif
7371
7372 if (RTW_CANNOT_RUN(padapter)) {
7373 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7374 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7375 return -1;
7376 }
7377
7378 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7379 pxmitpriv->ack_tx = _TRUE;
7380 pxmitpriv->seq_no = seq_no++;
7381 pmgntframe->ack_report = 1;
7382 rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7383 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7384 #ifdef CONFIG_XMIT_ACK_POLLING
7385 ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7386 #else
7387 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7388 #endif
7389 }
7390
7391 pxmitpriv->ack_tx = _FALSE;
7392 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7393
7394 return ret;
7395 #else //!CONFIG_XMIT_ACK
7396 dump_mgntframe(padapter, pmgntframe);
7397 rtw_msleep_os(50);
7398 return _SUCCESS;
7399 #endif //!CONFIG_XMIT_ACK
7400 }
7401
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)7402 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7403 {
7404 u8 *ssid_ie;
7405 sint ssid_len_ori;
7406 int len_diff = 0;
7407
7408 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
7409
7410 //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
7411
7412 if(ssid_ie && ssid_len_ori>0)
7413 {
7414 switch(hidden_ssid_mode)
7415 {
7416 case 1:
7417 {
7418 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7419 u32 remain_len = 0;
7420
7421 remain_len = ies_len -(next_ie-ies);
7422
7423 ssid_ie[1] = 0;
7424 _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
7425 len_diff -= ssid_len_ori;
7426
7427 break;
7428 }
7429 case 2:
7430 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7431 break;
7432 default:
7433 break;
7434 }
7435 }
7436
7437 return len_diff;
7438 }
7439
7440 #ifdef CONFIG_AP_MODE
issue_beacon(_adapter * padapter,int timeout_ms)7441 void issue_beacon(_adapter *padapter, int timeout_ms)
7442 {
7443 struct xmit_frame *pmgntframe;
7444 struct pkt_attrib *pattrib;
7445 unsigned char *pframe;
7446 struct rtw_ieee80211_hdr *pwlanhdr;
7447 unsigned short *fctrl;
7448 unsigned int rate_len;
7449 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7450 #if defined (CONFIG_NATIVEAP_MLME)
7451 _irqL irqL;
7452 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7453 #endif //#if defined (CONFIG_NATIVEAP_MLME)
7454 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7455 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7456 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7457 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7458 #ifdef CONFIG_P2P
7459 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7460 #endif //CONFIG_P2P
7461
7462
7463 //DBG_871X("%s\n", __FUNCTION__);
7464
7465 #ifdef CONFIG_BCN_ICF
7466 if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL)
7467 #else
7468 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7469 #endif
7470 {
7471 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7472 return;
7473 }
7474 #if defined (CONFIG_NATIVEAP_MLME)
7475 _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7476 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7477
7478 //update attribute
7479 pattrib = &pmgntframe->attrib;
7480 update_mgntframe_attrib(padapter, pattrib);
7481 pattrib->qsel = QSLT_BEACON;
7482 #ifdef CONFIG_CONCURRENT_MODE
7483 if(padapter->iface_type == IFACE_PORT1)
7484 pattrib->mbssid = 1;
7485 #endif
7486
7487 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7488
7489 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7490 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7491
7492
7493 fctrl = &(pwlanhdr->frame_ctl);
7494 *(fctrl) = 0;
7495
7496 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7497 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7498 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7499
7500 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7501 //pmlmeext->mgnt_seq++;
7502 SetFrameSubType(pframe, WIFI_BEACON);
7503
7504 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7505 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7506
7507 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7508 {
7509 //DBG_871X("ie len=%d\n", cur_network->IELength);
7510 #ifdef CONFIG_P2P
7511 // for P2P : Primary Device Type & Device Name
7512 u32 wpsielen=0, insert_len=0;
7513 u8 *wpsie=NULL;
7514 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
7515
7516 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
7517 {
7518 uint wps_offset, remainder_ielen;
7519 u8 *premainder_ie, *pframe_wscie;
7520
7521 wps_offset = (uint)(wpsie - cur_network->IEs);
7522
7523 premainder_ie = wpsie + wpsielen;
7524
7525 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7526
7527 #ifdef CONFIG_IOCTL_CFG80211
7528 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7529 {
7530 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
7531 {
7532 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7533 pframe += wps_offset;
7534 pattrib->pktlen += wps_offset;
7535
7536 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7537 pframe += pmlmepriv->wps_beacon_ie_len;
7538 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7539
7540 //copy remainder_ie to pframe
7541 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7542 pframe += remainder_ielen;
7543 pattrib->pktlen += remainder_ielen;
7544 }
7545 else
7546 {
7547 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7548 pframe += cur_network->IELength;
7549 pattrib->pktlen += cur_network->IELength;
7550 }
7551 }
7552 else
7553 #endif //CONFIG_IOCTL_CFG80211
7554 {
7555 pframe_wscie = pframe + wps_offset;
7556 _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
7557 pframe += (wps_offset + wpsielen);
7558 pattrib->pktlen += (wps_offset + wpsielen);
7559
7560 //now pframe is end of wsc ie, insert Primary Device Type & Device Name
7561 // Primary Device Type
7562 // Type:
7563 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
7564 insert_len += 2;
7565
7566 // Length:
7567 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
7568 insert_len += 2;
7569
7570 // Value:
7571 // Category ID
7572 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7573 insert_len += 2;
7574
7575 // OUI
7576 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
7577 insert_len += 4;
7578
7579 // Sub Category ID
7580 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7581 insert_len += 2;
7582
7583
7584 // Device Name
7585 // Type:
7586 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7587 insert_len += 2;
7588
7589 // Length:
7590 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
7591 insert_len += 2;
7592
7593 // Value:
7594 _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
7595 insert_len += pwdinfo->device_name_len;
7596
7597
7598 //update wsc ie length
7599 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
7600
7601 //pframe move to end
7602 pframe+=insert_len;
7603 pattrib->pktlen += insert_len;
7604
7605 //copy remainder_ie to pframe
7606 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7607 pframe += remainder_ielen;
7608 pattrib->pktlen += remainder_ielen;
7609 }
7610 }
7611 else
7612 #endif //CONFIG_P2P
7613 {
7614 int len_diff;
7615 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7616 len_diff = update_hidden_ssid(
7617 pframe+_BEACON_IE_OFFSET_
7618 , cur_network->IELength-_BEACON_IE_OFFSET_
7619 , pmlmeinfo->hidden_ssid_mode
7620 );
7621 pframe += (cur_network->IELength+len_diff);
7622 pattrib->pktlen += (cur_network->IELength+len_diff);
7623 }
7624
7625 {
7626 u8 *wps_ie;
7627 uint wps_ielen;
7628 u8 sr = 0;
7629 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
7630 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
7631 if (wps_ie && wps_ielen>0) {
7632 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
7633 }
7634 if (sr != 0)
7635 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7636 else
7637 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7638 }
7639
7640 #ifdef CONFIG_P2P
7641 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
7642 {
7643 u32 len;
7644 #ifdef CONFIG_IOCTL_CFG80211
7645 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7646 {
7647 len = pmlmepriv->p2p_beacon_ie_len;
7648 if(pmlmepriv->p2p_beacon_ie && len>0)
7649 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7650 }
7651 else
7652 #endif //CONFIG_IOCTL_CFG80211
7653 {
7654 len = build_beacon_p2p_ie(pwdinfo, pframe);
7655 }
7656
7657 pframe += len;
7658 pattrib->pktlen += len;
7659 #ifdef CONFIG_WFD
7660 #ifdef CONFIG_IOCTL_CFG80211
7661 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
7662 #endif //CONFIG_IOCTL_CFG80211
7663 {
7664 len = build_beacon_wfd_ie( pwdinfo, pframe );
7665 }
7666 #ifdef CONFIG_IOCTL_CFG80211
7667 else
7668 {
7669 len = 0;
7670 if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
7671 {
7672 len = pmlmepriv->wfd_beacon_ie_len;
7673 _rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
7674 }
7675 }
7676 #endif //CONFIG_IOCTL_CFG80211
7677 pframe += len;
7678 pattrib->pktlen += len;
7679 #endif //CONFIG_WFD
7680 }
7681 #endif //CONFIG_P2P
7682
7683 goto _issue_bcn;
7684
7685 }
7686
7687 //below for ad-hoc mode
7688
7689 //timestamp will be inserted by hardware
7690 pframe += 8;
7691 pattrib->pktlen += 8;
7692
7693 // beacon interval: 2 bytes
7694
7695 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7696
7697 pframe += 2;
7698 pattrib->pktlen += 2;
7699
7700 // capability info: 2 bytes
7701
7702 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7703
7704 pframe += 2;
7705 pattrib->pktlen += 2;
7706
7707 // SSID
7708 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7709
7710 // supported rates...
7711 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7712 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7713
7714 // DS parameter set
7715 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7716
7717 //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7718 {
7719 u8 erpinfo=0;
7720 u32 ATIMWindow;
7721 // IBSS Parameter Set...
7722 //ATIMWindow = cur->Configuration.ATIMWindow;
7723 ATIMWindow = 0;
7724 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7725
7726 //ERP IE
7727 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7728 }
7729
7730
7731 // EXTERNDED SUPPORTED RATE
7732 if (rate_len > 8)
7733 {
7734 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7735 }
7736
7737
7738 //todo:HT for adhoc
7739
7740 _issue_bcn:
7741
7742 #if defined (CONFIG_NATIVEAP_MLME)
7743 pmlmepriv->update_bcn = _FALSE;
7744
7745 _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7746 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7747
7748 if ((pattrib->pktlen + TXDESC_SIZE) > 512)
7749 {
7750 DBG_871X("beacon frame too large\n");
7751 return;
7752 }
7753
7754 pattrib->last_txcmdsz = pattrib->pktlen;
7755
7756 //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
7757 if(timeout_ms > 0)
7758 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7759 else
7760 dump_mgntframe(padapter, pmgntframe);
7761
7762 }
7763 #endif /*CONFIG_AP_MODE*/
7764
issue_probersp(_adapter * padapter,unsigned char * da,u8 is_valid_p2p_probereq)7765 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7766 {
7767 struct xmit_frame *pmgntframe;
7768 struct pkt_attrib *pattrib;
7769 unsigned char *pframe;
7770 struct rtw_ieee80211_hdr *pwlanhdr;
7771 unsigned short *fctrl;
7772 unsigned char *mac, *bssid;
7773 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7774 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7775 u8 *pwps_ie;
7776 uint wps_ielen;
7777 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7778 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7779 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7780 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7781 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7782 unsigned int rate_len;
7783 #ifdef CONFIG_P2P
7784 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7785 #ifdef CONFIG_WFD
7786 u32 wfdielen = 0;
7787 #endif //CONFIG_WFD
7788 #endif //CONFIG_P2P
7789
7790 //DBG_871X("%s\n", __FUNCTION__);
7791
7792 if(da == NULL)
7793 return;
7794
7795 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
7796 return;
7797
7798 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7799 {
7800 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7801 return;
7802 }
7803
7804
7805 //update attribute
7806 pattrib = &pmgntframe->attrib;
7807 update_mgntframe_attrib(padapter, pattrib);
7808
7809 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7810
7811 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7812 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7813
7814 mac = adapter_mac_addr(padapter);
7815 bssid = cur_network->MacAddress;
7816
7817 fctrl = &(pwlanhdr->frame_ctl);
7818 *(fctrl) = 0;
7819 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7820 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7821 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7822
7823 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7824 pmlmeext->mgnt_seq++;
7825 SetFrameSubType(fctrl, WIFI_PROBERSP);
7826
7827 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7828 pattrib->pktlen = pattrib->hdrlen;
7829 pframe += pattrib->hdrlen;
7830
7831
7832 if(cur_network->IELength>MAX_IE_SZ)
7833 return;
7834
7835 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7836 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7837 {
7838 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
7839
7840 //inerset & update wps_probe_resp_ie
7841 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
7842 {
7843 uint wps_offset, remainder_ielen;
7844 u8 *premainder_ie;
7845
7846 wps_offset = (uint)(pwps_ie - cur_network->IEs);
7847
7848 premainder_ie = pwps_ie + wps_ielen;
7849
7850 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
7851
7852 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7853 pframe += wps_offset;
7854 pattrib->pktlen += wps_offset;
7855
7856 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
7857 if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
7858 {
7859 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
7860 pframe += wps_ielen+2;
7861 pattrib->pktlen += wps_ielen+2;
7862 }
7863
7864 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
7865 {
7866 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7867 pframe += remainder_ielen;
7868 pattrib->pktlen += remainder_ielen;
7869 }
7870 }
7871 else
7872 {
7873 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7874 pframe += cur_network->IELength;
7875 pattrib->pktlen += cur_network->IELength;
7876 }
7877
7878 /* retrieve SSID IE from cur_network->Ssid */
7879 {
7880 u8 *ssid_ie;
7881 sint ssid_ielen;
7882 sint ssid_ielen_diff;
7883 u8 buf[MAX_IE_SZ];
7884 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
7885
7886 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
7887 (pframe-ies)-_FIXED_IE_LENGTH_);
7888
7889 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
7890
7891 if (ssid_ie && cur_network->Ssid.SsidLength) {
7892 uint remainder_ielen;
7893 u8 *remainder_ie;
7894 remainder_ie = ssid_ie+2;
7895 remainder_ielen = (pframe-remainder_ie);
7896
7897 if (remainder_ielen > MAX_IE_SZ) {
7898 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
7899 remainder_ielen = MAX_IE_SZ;
7900 }
7901
7902 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
7903 _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
7904 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
7905 _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
7906
7907 pframe += ssid_ielen_diff;
7908 pattrib->pktlen += ssid_ielen_diff;
7909 }
7910 }
7911 }
7912 else
7913 #endif
7914 {
7915
7916 //timestamp will be inserted by hardware
7917 pframe += 8;
7918 pattrib->pktlen += 8;
7919
7920 // beacon interval: 2 bytes
7921
7922 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7923
7924 pframe += 2;
7925 pattrib->pktlen += 2;
7926
7927 // capability info: 2 bytes
7928
7929 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7930
7931 pframe += 2;
7932 pattrib->pktlen += 2;
7933
7934 //below for ad-hoc mode
7935
7936 // SSID
7937 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7938
7939 // supported rates...
7940 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7941 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7942
7943 // DS parameter set
7944 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7945
7946 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7947 {
7948 u8 erpinfo=0;
7949 u32 ATIMWindow;
7950 // IBSS Parameter Set...
7951 //ATIMWindow = cur->Configuration.ATIMWindow;
7952 ATIMWindow = 0;
7953 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7954
7955 //ERP IE
7956 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7957 }
7958
7959
7960 // EXTERNDED SUPPORTED RATE
7961 if (rate_len > 8)
7962 {
7963 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7964 }
7965
7966
7967 //todo:HT for adhoc
7968
7969 }
7970
7971 #ifdef CONFIG_P2P
7972 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
7973 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
7974 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec))
7975 {
7976 u32 len;
7977 #ifdef CONFIG_IOCTL_CFG80211
7978 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7979 {
7980 //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
7981 len = pmlmepriv->p2p_go_probe_resp_ie_len;
7982 if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
7983 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
7984 }
7985 else
7986 #endif //CONFIG_IOCTL_CFG80211
7987 {
7988 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
7989 }
7990
7991 pframe += len;
7992 pattrib->pktlen += len;
7993
7994 #ifdef CONFIG_WFD
7995 #ifdef CONFIG_IOCTL_CFG80211
7996 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
7997 #endif //CONFIG_IOCTL_CFG80211
7998 {
7999 len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
8000 }
8001 #ifdef CONFIG_IOCTL_CFG80211
8002 else
8003 {
8004 len = 0;
8005 if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
8006 {
8007 len = pmlmepriv->wfd_probe_resp_ie_len;
8008 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
8009 }
8010 }
8011 #endif //CONFIG_IOCTL_CFG80211
8012 pframe += len;
8013 pattrib->pktlen += len;
8014 #endif //CONFIG_WFD
8015
8016 }
8017 #endif //CONFIG_P2P
8018
8019
8020 #ifdef CONFIG_AUTO_AP_MODE
8021 {
8022 struct sta_info *psta;
8023 struct sta_priv *pstapriv = &padapter->stapriv;
8024
8025 DBG_871X("(%s)\n", __FUNCTION__);
8026
8027 //check rc station
8028 psta = rtw_get_stainfo(pstapriv, da);
8029 if (psta && psta->isrc && psta->pid>0)
8030 {
8031 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
8032 u8 RC_INFO[14] = {0};
8033 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
8034 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8035
8036 DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8037 psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
8038
8039 //append vendor specific ie
8040 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8041 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8042 _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
8043 _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
8044
8045 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8046 }
8047 }
8048 #endif //CONFIG_AUTO_AP_MODE
8049
8050
8051 pattrib->last_txcmdsz = pattrib->pktlen;
8052
8053
8054 dump_mgntframe(padapter, pmgntframe);
8055
8056 return;
8057
8058 }
8059
_issue_probereq(_adapter * padapter,NDIS_802_11_SSID * pssid,u8 * da,u8 ch,bool append_wps,int wait_ack)8060 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
8061 {
8062 int ret = _FAIL;
8063 struct xmit_frame *pmgntframe;
8064 struct pkt_attrib *pattrib;
8065 unsigned char *pframe;
8066 struct rtw_ieee80211_hdr *pwlanhdr;
8067 unsigned short *fctrl;
8068 unsigned char *mac;
8069 unsigned char bssrate[NumRates];
8070 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8071 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8072 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8073 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8074 int bssrate_len = 0;
8075 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8076
8077 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8078 goto exit;
8079
8080 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8081 {
8082 goto exit;
8083 }
8084
8085 //update attribute
8086 pattrib = &pmgntframe->attrib;
8087 update_mgntframe_attrib(padapter, pattrib);
8088
8089
8090 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8091
8092 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8093 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8094
8095 mac = adapter_mac_addr(padapter);
8096
8097 fctrl = &(pwlanhdr->frame_ctl);
8098 *(fctrl) = 0;
8099
8100 if (da)
8101 {
8102 // unicast probe request frame
8103 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8104 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8105 }
8106 else
8107 {
8108 // broadcast probe request frame
8109 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8110 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8111 }
8112
8113 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8114
8115 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8116 pmlmeext->mgnt_seq++;
8117 SetFrameSubType(pframe, WIFI_PROBEREQ);
8118
8119 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
8120 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
8121
8122 if(pssid)
8123 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8124 else
8125 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8126
8127 get_rate_set(padapter, bssrate, &bssrate_len);
8128
8129 if (bssrate_len > 8)
8130 {
8131 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8132 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8133 }
8134 else
8135 {
8136 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8137 }
8138
8139 if (ch)
8140 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8141
8142 if (append_wps) {
8143 //add wps_ie for wps2.0
8144 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
8145 {
8146 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8147 pframe += pmlmepriv->wps_probe_req_ie_len;
8148 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8149 //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
8150 }
8151 }
8152
8153 pattrib->last_txcmdsz = pattrib->pktlen;
8154
8155 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
8156
8157 if (wait_ack) {
8158 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8159 } else {
8160 dump_mgntframe(padapter, pmgntframe);
8161 ret = _SUCCESS;
8162 }
8163
8164 exit:
8165 return ret;
8166 }
8167
issue_probereq(_adapter * padapter,NDIS_802_11_SSID * pssid,u8 * da)8168 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
8169 {
8170 _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8171 }
8172
8173 /*
8174 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8175 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
8176 * try_cnt means the maximal TX count to try
8177 */
issue_probereq_ex(_adapter * padapter,NDIS_802_11_SSID * pssid,u8 * da,u8 ch,bool append_wps,int try_cnt,int wait_ms)8178 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
8179 int try_cnt, int wait_ms)
8180 {
8181 int ret = _FAIL;
8182 int i = 0;
8183 u32 start = rtw_get_current_time();
8184
8185 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8186 goto exit;
8187
8188 do
8189 {
8190 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE);
8191
8192 i++;
8193
8194 if (RTW_CANNOT_RUN(padapter))
8195 break;
8196
8197 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8198 rtw_msleep_os(wait_ms);
8199
8200 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8201
8202 if (ret != _FAIL) {
8203 ret = _SUCCESS;
8204 #ifndef DBG_XMIT_ACK
8205 goto exit;
8206 #endif
8207 }
8208
8209 if (try_cnt && wait_ms) {
8210 if (da)
8211 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8212 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8213 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8214 else
8215 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8216 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8217 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8218 }
8219 exit:
8220 return ret;
8221 }
8222
8223 // if psta == NULL, indiate we are station(client) now...
issue_auth(_adapter * padapter,struct sta_info * psta,unsigned short status)8224 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8225 {
8226 struct xmit_frame *pmgntframe;
8227 struct pkt_attrib *pattrib;
8228 unsigned char *pframe;
8229 struct rtw_ieee80211_hdr *pwlanhdr;
8230 unsigned short *fctrl;
8231 unsigned int val32;
8232 unsigned short val16;
8233 int use_shared_key = 0;
8234 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8235 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8236 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8237
8238 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8239 return;
8240
8241 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8242 {
8243 return;
8244 }
8245
8246 //update attribute
8247 pattrib = &pmgntframe->attrib;
8248 update_mgntframe_attrib(padapter, pattrib);
8249
8250 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8251
8252 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8253 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8254
8255 fctrl = &(pwlanhdr->frame_ctl);
8256 *(fctrl) = 0;
8257
8258 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8259 pmlmeext->mgnt_seq++;
8260 SetFrameSubType(pframe, WIFI_AUTH);
8261
8262 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8263 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8264
8265
8266 if(psta)// for AP mode
8267 {
8268 #ifdef CONFIG_NATIVEAP_MLME
8269
8270 _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
8271 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8272 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8273
8274
8275 // setting auth algo number
8276 val16 = (u16)psta->authalg;
8277
8278 if(status != _STATS_SUCCESSFUL_)
8279 val16 = 0;
8280
8281 if (val16) {
8282 val16 = cpu_to_le16(val16);
8283 use_shared_key = 1;
8284 }
8285
8286 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8287
8288 // setting auth seq number
8289 val16 =(u16)psta->auth_seq;
8290 val16 = cpu_to_le16(val16);
8291 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8292
8293 // setting status code...
8294 val16 = status;
8295 val16 = cpu_to_le16(val16);
8296 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8297
8298 // added challenging text...
8299 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8300 {
8301 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8302 }
8303 #endif
8304 }
8305 else
8306 {
8307 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8308 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8309 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8310
8311 // setting auth algo number
8312 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
8313 if (val16) {
8314 val16 = cpu_to_le16(val16);
8315 use_shared_key = 1;
8316 }
8317 //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
8318
8319 //setting IV for auth seq #3
8320 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8321 {
8322 //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
8323 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8324 val32 = cpu_to_le32(val32);
8325 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8326
8327 pattrib->iv_len = 4;
8328 }
8329
8330 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8331
8332 // setting auth seq number
8333 val16 = pmlmeinfo->auth_seq;
8334 val16 = cpu_to_le16(val16);
8335 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8336
8337
8338 // setting status code...
8339 val16 = status;
8340 val16 = cpu_to_le16(val16);
8341 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8342
8343 // then checking to see if sending challenging text...
8344 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8345 {
8346 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8347
8348 SetPrivacy(fctrl);
8349
8350 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8351
8352 pattrib->encrypt = _WEP40_;
8353
8354 pattrib->icv_len = 4;
8355
8356 pattrib->pktlen += pattrib->icv_len;
8357
8358 }
8359
8360 }
8361
8362 pattrib->last_txcmdsz = pattrib->pktlen;
8363
8364 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8365 DBG_871X("%s\n", __FUNCTION__);
8366 dump_mgntframe(padapter, pmgntframe);
8367
8368 return;
8369 }
8370
8371
issue_asocrsp(_adapter * padapter,unsigned short status,struct sta_info * pstat,int pkt_type)8372 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8373 {
8374 #ifdef CONFIG_AP_MODE
8375 struct xmit_frame *pmgntframe;
8376 struct rtw_ieee80211_hdr *pwlanhdr;
8377 struct pkt_attrib *pattrib;
8378 unsigned char *pbuf, *pframe;
8379 unsigned short val, ie_status;
8380 unsigned short *fctrl;
8381 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8382 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8383 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8384 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8385 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8386 u8 *ie = pnetwork->IEs;
8387 #ifdef CONFIG_P2P
8388 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8389 #ifdef CONFIG_WFD
8390 u32 wfdielen = 0;
8391 #endif //CONFIG_WFD
8392
8393 #endif //CONFIG_P2P
8394
8395 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8396 return;
8397
8398 DBG_871X("%s\n", __FUNCTION__);
8399
8400 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8401 {
8402 return;
8403 }
8404
8405 //update attribute
8406 pattrib = &pmgntframe->attrib;
8407 update_mgntframe_attrib(padapter, pattrib);
8408
8409
8410 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8411
8412 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8413 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8414
8415 fctrl = &(pwlanhdr->frame_ctl);
8416 *(fctrl) = 0;
8417
8418 _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
8419 _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8420 _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8421
8422
8423 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8424 pmlmeext->mgnt_seq++;
8425 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8426 SetFrameSubType(pwlanhdr, pkt_type);
8427 else
8428 return;
8429
8430 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8431 pattrib->pktlen += pattrib->hdrlen;
8432 pframe += pattrib->hdrlen;
8433
8434 //capability
8435 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8436
8437 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8438
8439 ie_status = cpu_to_le16(status);
8440 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8441
8442 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
8443 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8444
8445 if (pstat->bssratelen <= 8)
8446 {
8447 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8448 }
8449 else
8450 {
8451 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8452 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
8453 }
8454
8455 #ifdef CONFIG_IEEE80211W
8456 if (status == _STATS_REFUSED_TEMPORARILY_) {
8457 u8 timeout_itvl[5];
8458 u32 timeout_interval = 3000;
8459 /* Association Comeback time */
8460 timeout_itvl[0] = 0x03;
8461 timeout_interval = cpu_to_le32(timeout_interval);
8462 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
8463 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8464 }
8465 #endif /* CONFIG_IEEE80211W */
8466
8467 #ifdef CONFIG_80211N_HT
8468 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
8469 {
8470 uint ie_len=0;
8471
8472 //FILL HT CAP INFO IE
8473 //p = hostapd_eid_ht_capabilities_info(hapd, p);
8474 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8475 if(pbuf && ie_len>0)
8476 {
8477 _rtw_memcpy(pframe, pbuf, ie_len+2);
8478 pframe += (ie_len+2);
8479 pattrib->pktlen +=(ie_len+2);
8480 }
8481
8482 //FILL HT ADD INFO IE
8483 //p = hostapd_eid_ht_operation(hapd, p);
8484 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8485 if(pbuf && ie_len>0)
8486 {
8487 _rtw_memcpy(pframe, pbuf, ie_len+2);
8488 pframe += (ie_len+2);
8489 pattrib->pktlen +=(ie_len+2);
8490 }
8491
8492 }
8493 #endif
8494
8495 /*adding EXT_CAPAB_IE */
8496 if (pmlmepriv->ext_capab_ie_len > 0) {
8497 uint ie_len = 0;
8498
8499 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8500 if (pbuf && ie_len > 0) {
8501 _rtw_memcpy(pframe, pbuf, ie_len+2);
8502 pframe += (ie_len+2);
8503 pattrib->pktlen += (ie_len+2);
8504 }
8505 }
8506
8507 #ifdef CONFIG_80211AC_VHT
8508 if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8509 && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8510 && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP))
8511 {
8512 u32 ie_len=0;
8513
8514 //FILL VHT CAP IE
8515 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8516 if(pbuf && ie_len>0)
8517 {
8518 _rtw_memcpy(pframe, pbuf, ie_len+2);
8519 pframe += (ie_len+2);
8520 pattrib->pktlen +=(ie_len+2);
8521 }
8522
8523 //FILL VHT OPERATION IE
8524 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8525 if(pbuf && ie_len>0)
8526 {
8527 _rtw_memcpy(pframe, pbuf, ie_len+2);
8528 pframe += (ie_len+2);
8529 pattrib->pktlen +=(ie_len+2);
8530 }
8531 }
8532 #endif //CONFIG_80211AC_VHT
8533
8534 //FILL WMM IE
8535 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
8536 {
8537 uint ie_len=0;
8538 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
8539
8540 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
8541 {
8542 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
8543 if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
8544 {
8545 _rtw_memcpy(pframe, pbuf, ie_len+2);
8546 pframe += (ie_len+2);
8547 pattrib->pktlen +=(ie_len+2);
8548
8549 break;
8550 }
8551
8552 if ((pbuf == NULL) || (ie_len == 0))
8553 {
8554 break;
8555 }
8556 }
8557
8558 }
8559
8560
8561 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8562 {
8563 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8564 }
8565
8566 //add WPS IE ie for wps 2.0
8567 if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
8568 {
8569 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8570
8571 pframe += pmlmepriv->wps_assoc_resp_ie_len;
8572 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8573 }
8574
8575 #ifdef CONFIG_P2P
8576 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
8577 {
8578 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
8579 {
8580 u32 len;
8581
8582 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8583
8584 pframe += len;
8585 pattrib->pktlen += len;
8586 }
8587 }
8588 #ifdef CONFIG_WFD
8589 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8590 #ifdef CONFIG_IOCTL_CFG80211
8591 && (_TRUE == pwdinfo->wfd_info->wfd_enable)
8592 #endif //CONFIG_IOCTL_CFG80211
8593 )
8594 {
8595 wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
8596 pframe += wfdielen;
8597 pattrib->pktlen += wfdielen;
8598 }
8599 #endif //CONFIG_WFD
8600 #endif //CONFIG_P2P
8601
8602 pattrib->last_txcmdsz = pattrib->pktlen;
8603
8604 dump_mgntframe(padapter, pmgntframe);
8605
8606 #endif
8607 }
8608
issue_assocreq(_adapter * padapter)8609 void issue_assocreq(_adapter *padapter)
8610 {
8611 int ret = _FAIL;
8612 struct xmit_frame *pmgntframe;
8613 struct pkt_attrib *pattrib;
8614 unsigned char *pframe, *p;
8615 struct rtw_ieee80211_hdr *pwlanhdr;
8616 unsigned short *fctrl;
8617 unsigned short val16;
8618 unsigned int i, j, ie_len, index=0;
8619 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8620 PNDIS_802_11_VARIABLE_IEs pIE;
8621 struct registry_priv *pregpriv = &padapter->registrypriv;
8622 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8623 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8624 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8625 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8626 int bssrate_len = 0, sta_bssrate_len = 0;
8627 u8 vs_ie_length = 0;
8628 #ifdef CONFIG_P2P
8629 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8630 u8 p2pie[ 255 ] = { 0x00 };
8631 u16 p2pielen = 0;
8632 #ifdef CONFIG_WFD
8633 u32 wfdielen = 0;
8634 #endif //CONFIG_WFD
8635 #endif //CONFIG_P2P
8636
8637 #ifdef CONFIG_DFS
8638 u16 cap;
8639
8640 /* Dot H */
8641 u8 pow_cap_ele[2] = { 0x00 };
8642 u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
8643 #endif //CONFIG_DFS
8644
8645 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8646 goto exit;
8647
8648 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8649 goto exit;
8650
8651 //update attribute
8652 pattrib = &pmgntframe->attrib;
8653 update_mgntframe_attrib(padapter, pattrib);
8654
8655
8656 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8657
8658 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8659 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8660
8661 fctrl = &(pwlanhdr->frame_ctl);
8662 *(fctrl) = 0;
8663 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8664 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8665 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8666
8667 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8668 pmlmeext->mgnt_seq++;
8669 SetFrameSubType(pframe, WIFI_ASSOCREQ);
8670
8671 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8672 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8673
8674 //caps
8675
8676 #ifdef CONFIG_DFS
8677 _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8678 cap |= cap_SpecMgmt;
8679 _rtw_memcpy(pframe, &cap, 2);
8680 #else
8681 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8682 #endif //CONFIG_DFS
8683
8684 pframe += 2;
8685 pattrib->pktlen += 2;
8686
8687 //listen interval
8688 //todo: listen interval for power saving
8689 val16 = cpu_to_le16(3);
8690 _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
8691 pframe += 2;
8692 pattrib->pktlen += 2;
8693
8694 //SSID
8695 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8696
8697 #ifdef CONFIG_DFS
8698 /* Dot H */
8699 if(pmlmeext->cur_channel > 14)
8700 {
8701 pow_cap_ele[0] = 13; // Minimum transmit power capability
8702 pow_cap_ele[1] = 21; // Maximum transmit power capability
8703 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8704
8705 //supported channels
8706 do{
8707 if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
8708 {
8709 sup_ch[0] = 1; //First channel number
8710 sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel
8711 }
8712 else
8713 {
8714 sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8715 sup_ch[idx_5g++] = 1;
8716 }
8717 sup_ch_idx++;
8718 }
8719 while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
8720 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8721 }
8722 #endif //CONFIG_DFS
8723
8724 //supported rate & extended supported rate
8725
8726 #if 1 // Check if the AP's supported rates are also supported by STA.
8727 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8728 //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
8729
8730 if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
8731 {
8732 sta_bssrate_len = 4;
8733 }
8734
8735
8736 //for (i = 0; i < sta_bssrate_len; i++) {
8737 // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
8738 //}
8739
8740 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8741 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8742 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8743 }
8744
8745
8746 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8747 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8748
8749
8750 // Check if the AP's supported rates are also supported by STA.
8751 for (j=0; j < sta_bssrate_len; j++) {
8752 // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8753 if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
8754 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
8755 //DBG_871X("match i = %d, j=%d\n", i, j);
8756 break;
8757 } else {
8758 //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
8759 }
8760 }
8761
8762 if (j == sta_bssrate_len) {
8763 // the rate is not supported by STA
8764 DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8765 } else {
8766 // the rate is supported by STA
8767 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8768 }
8769 }
8770
8771 bssrate_len = index;
8772 DBG_871X("bssrate_len = %d\n", bssrate_len);
8773
8774 #else // Check if the AP's supported rates are also supported by STA.
8775 #if 0
8776 get_rate_set(padapter, bssrate, &bssrate_len);
8777 #else
8778 for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8779 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
8780
8781 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8782 break;
8783
8784 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8785 }
8786 #endif
8787 #endif // Check if the AP's supported rates are also supported by STA.
8788
8789 if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8790 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8791 rtw_free_xmitframe(pxmitpriv, pmgntframe);
8792 goto exit; //don't connect to AP if no joint supported rate
8793 }
8794
8795
8796 if (bssrate_len > 8)
8797 {
8798 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8799 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8800 }
8801 else if (bssrate_len > 0)
8802 {
8803 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8804 } else {
8805 DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n",__FUNCTION__);
8806 }
8807
8808 //vendor specific IE, such as WPA, WMM, WPS
8809 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
8810 {
8811 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8812
8813 switch (pIE->ElementID)
8814 {
8815 case _VENDOR_SPECIFIC_IE_:
8816 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8817 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8818 (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8819 {
8820 vs_ie_length = pIE->Length;
8821 if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8822 {
8823 //Commented by Kurt 20110629
8824 //In some older APs, WPS handshake
8825 //would be fail if we append vender extensions informations to AP
8826
8827 vs_ie_length = 14;
8828 }
8829
8830 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8831 }
8832 break;
8833
8834 case EID_WPA2:
8835 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8836 break;
8837 #ifdef CONFIG_80211N_HT
8838 case EID_HTCapability:
8839 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8840 if (!(is_ap_in_tkip(padapter)))
8841 {
8842 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8843
8844 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8845
8846 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8847 }
8848 }
8849 break;
8850
8851 case EID_EXTCapability:
8852 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8853 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8854 }
8855 break;
8856 #endif //CONFIG_80211N_HT
8857 #ifdef CONFIG_80211AC_VHT
8858 case EID_VHTCapability:
8859 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8860 pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8861 }
8862 break;
8863
8864 case EID_OpModeNotification:
8865 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8866 pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
8867 }
8868 break;
8869 #endif // CONFIG_80211AC_VHT
8870 default:
8871 break;
8872 }
8873
8874 i += (pIE->Length + 2);
8875 }
8876
8877 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8878 {
8879 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8880 }
8881
8882
8883 #ifdef CONFIG_WAPI_SUPPORT
8884 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
8885 #endif
8886
8887
8888 #ifdef CONFIG_P2P
8889
8890 #ifdef CONFIG_IOCTL_CFG80211
8891 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8892 {
8893 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
8894 {
8895 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
8896 pframe += pmlmepriv->p2p_assoc_req_ie_len;
8897 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
8898 }
8899 }
8900 else
8901 #endif //CONFIG_IOCTL_CFG80211
8902 {
8903 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
8904 {
8905 // Should add the P2P IE in the association request frame.
8906 // P2P OUI
8907
8908 p2pielen = 0;
8909 p2pie[ p2pielen++ ] = 0x50;
8910 p2pie[ p2pielen++ ] = 0x6F;
8911 p2pie[ p2pielen++ ] = 0x9A;
8912 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
8913
8914 // Commented by Albert 20101109
8915 // According to the P2P Specification, the association request frame should contain 3 P2P attributes
8916 // 1. P2P Capability
8917 // 2. Extended Listen Timing
8918 // 3. Device Info
8919 // Commented by Albert 20110516
8920 // 4. P2P Interface
8921
8922 // P2P Capability
8923 // Type:
8924 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
8925
8926 // Length:
8927 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
8928 p2pielen += 2;
8929
8930 // Value:
8931 // Device Capability Bitmap, 1 byte
8932 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
8933
8934 // Group Capability Bitmap, 1 byte
8935 if ( pwdinfo->persistent_supported )
8936 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
8937 else
8938 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
8939
8940 // Extended Listen Timing
8941 // Type:
8942 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
8943
8944 // Length:
8945 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
8946 p2pielen += 2;
8947
8948 // Value:
8949 // Availability Period
8950 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
8951 p2pielen += 2;
8952
8953 // Availability Interval
8954 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
8955 p2pielen += 2;
8956
8957 // Device Info
8958 // Type:
8959 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
8960
8961 // Length:
8962 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
8963 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
8964 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
8965 p2pielen += 2;
8966
8967 // Value:
8968 // P2P Device Address
8969 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
8970 p2pielen += ETH_ALEN;
8971
8972 // Config Method
8973 // This field should be big endian. Noted by P2P specification.
8974 if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
8975 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
8976 {
8977 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
8978 }
8979 else
8980 {
8981 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
8982 }
8983
8984 p2pielen += 2;
8985
8986 // Primary Device Type
8987 // Category ID
8988 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
8989 p2pielen += 2;
8990
8991 // OUI
8992 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
8993 p2pielen += 4;
8994
8995 // Sub Category ID
8996 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
8997 p2pielen += 2;
8998
8999 // Number of Secondary Device Types
9000 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
9001
9002 // Device Name
9003 // Type:
9004 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
9005 p2pielen += 2;
9006
9007 // Length:
9008 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
9009 p2pielen += 2;
9010
9011 // Value:
9012 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
9013 p2pielen += pwdinfo->device_name_len;
9014
9015 // P2P Interface
9016 // Type:
9017 p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
9018
9019 // Length:
9020 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
9021 p2pielen += 2;
9022
9023 // Value:
9024 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address
9025 p2pielen += ETH_ALEN;
9026
9027 p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count
9028
9029 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List
9030 p2pielen += ETH_ALEN;
9031
9032 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
9033
9034 #ifdef CONFIG_WFD
9035 //wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
9036 //pframe += wfdielen;
9037 //pattrib->pktlen += wfdielen;
9038 #endif //CONFIG_WFD
9039 }
9040 }
9041
9042 #endif //CONFIG_P2P
9043
9044 #ifdef CONFIG_WFD
9045 #ifdef CONFIG_IOCTL_CFG80211
9046 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
9047 #endif //CONFIG_IOCTL_CFG80211
9048 {
9049 wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
9050 pframe += wfdielen;
9051 pattrib->pktlen += wfdielen;
9052 }
9053 #ifdef CONFIG_IOCTL_CFG80211
9054 else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
9055 {
9056 //WFD IE
9057 _rtw_memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
9058 pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
9059 pframe += pmlmepriv->wfd_assoc_req_ie_len;
9060 }
9061 #endif //CONFIG_IOCTL_CFG80211
9062 #endif //CONFIG_WFD
9063
9064 pattrib->last_txcmdsz = pattrib->pktlen;
9065 dump_mgntframe(padapter, pmgntframe);
9066
9067 ret = _SUCCESS;
9068
9069 exit:
9070 if (ret == _SUCCESS)
9071 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9072 else
9073 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9074
9075 return;
9076 }
9077
9078 //when wait_ack is ture, this function shoule be called at process context
_issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int wait_ack)9079 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9080 {
9081 int ret = _FAIL;
9082 struct xmit_frame *pmgntframe;
9083 struct pkt_attrib *pattrib;
9084 unsigned char *pframe;
9085 struct rtw_ieee80211_hdr *pwlanhdr;
9086 unsigned short *fctrl;
9087 struct xmit_priv *pxmitpriv;
9088 struct mlme_ext_priv *pmlmeext;
9089 struct mlme_ext_info *pmlmeinfo;
9090
9091 //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
9092
9093 if(!padapter)
9094 goto exit;
9095
9096 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9097 goto exit;
9098
9099 pxmitpriv = &(padapter->xmitpriv);
9100 pmlmeext = &(padapter->mlmeextpriv);
9101 pmlmeinfo = &(pmlmeext->mlmext_info);
9102
9103 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9104 {
9105 goto exit;
9106 }
9107
9108 //update attribute
9109 pattrib = &pmgntframe->attrib;
9110 update_mgntframe_attrib(padapter, pattrib);
9111 pattrib->retry_ctrl = _FALSE;
9112
9113 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9114
9115 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9116 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9117
9118 fctrl = &(pwlanhdr->frame_ctl);
9119 *(fctrl) = 0;
9120
9121 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9122 {
9123 SetFrDs(fctrl);
9124 }
9125 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9126 {
9127 SetToDs(fctrl);
9128 }
9129
9130 if (power_mode)
9131 {
9132 SetPwrMgt(fctrl);
9133 }
9134
9135 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9136 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9137 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9138
9139 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9140 pmlmeext->mgnt_seq++;
9141 SetFrameSubType(pframe, WIFI_DATA_NULL);
9142
9143 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9144 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9145
9146 pattrib->last_txcmdsz = pattrib->pktlen;
9147
9148 if(wait_ack)
9149 {
9150 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9151 }
9152 else
9153 {
9154 dump_mgntframe(padapter, pmgntframe);
9155 ret = _SUCCESS;
9156 }
9157
9158 exit:
9159 return ret;
9160 }
9161
9162 /*
9163 * [IMPORTANT] Don't call this function in interrupt context
9164 *
9165 * When wait_ms > 0, this function should be called at process context
9166 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9167 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9168 * try_cnt means the maximal TX count to try
9169 * da == NULL for station mode
9170 */
issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int try_cnt,int wait_ms)9171 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9172 {
9173 int ret = _FAIL;
9174 int i = 0;
9175 u32 start = rtw_get_current_time();
9176 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9177 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9178 struct sta_info *psta;
9179
9180 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9181 goto exit;
9182
9183 /* da == NULL, assum it's null data for sta to ap*/
9184 if (da == NULL)
9185 da = get_my_bssid(&(pmlmeinfo->network));
9186
9187 psta = rtw_get_stainfo(&padapter->stapriv, da);
9188 if (psta) {
9189 if (power_mode)
9190 rtw_hal_macid_sleep(padapter, psta->mac_id);
9191 else
9192 rtw_hal_macid_wakeup(padapter, psta->mac_id);
9193 } else {
9194 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
9195 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
9196 rtw_warn_on(1);
9197 }
9198
9199 do {
9200 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
9201
9202 i++;
9203
9204 if (RTW_CANNOT_RUN(padapter))
9205 break;
9206
9207 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9208 rtw_msleep_os(wait_ms);
9209
9210 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9211
9212 if (ret != _FAIL) {
9213 ret = _SUCCESS;
9214 #ifndef DBG_XMIT_ACK
9215 goto exit;
9216 #endif
9217 }
9218
9219 if (try_cnt && wait_ms) {
9220 if (da)
9221 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9222 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9223 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9224 else
9225 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9226 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9227 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9228 }
9229 exit:
9230 return ret;
9231 }
9232
9233 /*
9234 * [IMPORTANT] This function run in interrupt context
9235 *
9236 * The null data packet would be sent without power bit,
9237 * and not guarantee success.
9238 */
issue_nulldata_in_interrupt(PADAPTER padapter,u8 * da,unsigned int power_mode)9239 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
9240 {
9241 int ret;
9242 struct mlme_ext_priv *pmlmeext;
9243 struct mlme_ext_info *pmlmeinfo;
9244
9245
9246 pmlmeext = &padapter->mlmeextpriv;
9247 pmlmeinfo = &pmlmeext->mlmext_info;
9248
9249 /* da == NULL, assum it's null data for sta to ap*/
9250 if (da == NULL)
9251 da = get_my_bssid(&(pmlmeinfo->network));
9252
9253 ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
9254
9255 return ret;
9256 }
9257
9258 //when wait_ack is ture, this function shoule be called at process context
_issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,int wait_ack)9259 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
9260 {
9261 int ret = _FAIL;
9262 struct xmit_frame *pmgntframe;
9263 struct pkt_attrib *pattrib;
9264 unsigned char *pframe;
9265 struct rtw_ieee80211_hdr *pwlanhdr;
9266 unsigned short *fctrl, *qc;
9267 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9268 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9269 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9270
9271 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9272 goto exit;
9273
9274 DBG_871X("%s\n", __FUNCTION__);
9275
9276 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9277 {
9278 goto exit;
9279 }
9280
9281 //update attribute
9282 pattrib = &pmgntframe->attrib;
9283 update_mgntframe_attrib(padapter, pattrib);
9284
9285 pattrib->hdrlen +=2;
9286 pattrib->qos_en = _TRUE;
9287 pattrib->eosp = 1;
9288 pattrib->ack_policy = 0;
9289 pattrib->mdata = 0;
9290
9291 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9292
9293 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9294 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9295
9296 fctrl = &(pwlanhdr->frame_ctl);
9297 *(fctrl) = 0;
9298
9299 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9300 {
9301 SetFrDs(fctrl);
9302 }
9303 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9304 {
9305 SetToDs(fctrl);
9306 }
9307
9308 if(pattrib->mdata)
9309 SetMData(fctrl);
9310
9311 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9312
9313 SetPriority(qc, tid);
9314
9315 SetEOSP(qc, pattrib->eosp);
9316
9317 SetAckpolicy(qc, pattrib->ack_policy);
9318
9319 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9320 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9321 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9322
9323 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9324 pmlmeext->mgnt_seq++;
9325 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
9326
9327 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9328 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9329
9330 pattrib->last_txcmdsz = pattrib->pktlen;
9331
9332 if(wait_ack)
9333 {
9334 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9335 }
9336 else
9337 {
9338 dump_mgntframe(padapter, pmgntframe);
9339 ret = _SUCCESS;
9340 }
9341
9342 exit:
9343 return ret;
9344 }
9345
9346 /*
9347 * when wait_ms >0 , this function should be called at process context
9348 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9349 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9350 * try_cnt means the maximal TX count to try
9351 * da == NULL for station mode
9352 */
issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,int try_cnt,int wait_ms)9353 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
9354 {
9355 int ret = _FAIL;
9356 int i = 0;
9357 u32 start = rtw_get_current_time();
9358 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9359 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9360
9361 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9362 goto exit;
9363
9364 /* da == NULL, assum it's null data for sta to ap*/
9365 if (da == NULL)
9366 da = get_my_bssid(&(pmlmeinfo->network));
9367
9368 do
9369 {
9370 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
9371
9372 i++;
9373
9374 if (RTW_CANNOT_RUN(padapter))
9375 break;
9376
9377 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9378 rtw_msleep_os(wait_ms);
9379
9380 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9381
9382 if (ret != _FAIL) {
9383 ret = _SUCCESS;
9384 #ifndef DBG_XMIT_ACK
9385 goto exit;
9386 #endif
9387 }
9388
9389 if (try_cnt && wait_ms) {
9390 if (da)
9391 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9392 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9393 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9394 else
9395 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9396 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9397 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9398 }
9399 exit:
9400 return ret;
9401 }
9402
_issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason,u8 wait_ack,u8 key_type)9403 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9404 {
9405 struct xmit_frame *pmgntframe;
9406 struct pkt_attrib *pattrib;
9407 unsigned char *pframe;
9408 struct rtw_ieee80211_hdr *pwlanhdr;
9409 unsigned short *fctrl;
9410 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9411 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9412 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9413 int ret = _FAIL;
9414 #ifdef CONFIG_P2P
9415 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
9416 #endif //CONFIG_P2P
9417
9418 //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9419
9420 #ifdef CONFIG_P2P
9421 if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
9422 {
9423 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
9424 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
9425 }
9426 #endif //CONFIG_P2P
9427
9428 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9429 goto exit;
9430
9431 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9432 {
9433 goto exit;
9434 }
9435
9436 //update attribute
9437 pattrib = &pmgntframe->attrib;
9438 update_mgntframe_attrib(padapter, pattrib);
9439 pattrib->retry_ctrl = _FALSE;
9440 pattrib->key_type = key_type;
9441 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9442
9443 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9444 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9445
9446 fctrl = &(pwlanhdr->frame_ctl);
9447 *(fctrl) = 0;
9448
9449 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9450 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9451 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9452
9453 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9454 pmlmeext->mgnt_seq++;
9455 SetFrameSubType(pframe, WIFI_DEAUTH);
9456
9457 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9458 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9459
9460 reason = cpu_to_le16(reason);
9461 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9462
9463 pattrib->last_txcmdsz = pattrib->pktlen;
9464
9465
9466 if(wait_ack)
9467 {
9468 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9469 }
9470 else
9471 {
9472 dump_mgntframe(padapter, pmgntframe);
9473 ret = _SUCCESS;
9474 }
9475
9476 exit:
9477 return ret;
9478 }
9479
issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason)9480 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9481 {
9482 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9483 return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9484 }
9485
9486 #ifdef CONFIG_IEEE80211W
issue_deauth_11w(_adapter * padapter,unsigned char * da,unsigned short reason,u8 key_type)9487 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9488 {
9489 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9490 return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9491 }
9492 #endif /* CONFIG_IEEE80211W */
9493
9494 /*
9495 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9496 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9497 * try_cnt means the maximal TX count to try
9498 */
issue_deauth_ex(_adapter * padapter,u8 * da,unsigned short reason,int try_cnt,int wait_ms)9499 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9500 int wait_ms)
9501 {
9502 int ret = _FAIL;
9503 int i = 0;
9504 u32 start = rtw_get_current_time();
9505
9506 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9507 goto exit;
9508
9509 do
9510 {
9511 ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE:_FALSE, IEEE80211W_RIGHT_KEY);
9512
9513 i++;
9514
9515 if (RTW_CANNOT_RUN(padapter))
9516 break;
9517
9518 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9519 rtw_msleep_os(wait_ms);
9520
9521 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9522
9523 if (ret != _FAIL) {
9524 ret = _SUCCESS;
9525 #ifndef DBG_XMIT_ACK
9526 goto exit;
9527 #endif
9528 }
9529
9530 if (try_cnt && wait_ms) {
9531 if (da)
9532 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9533 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9534 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9535 else
9536 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9537 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9538 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9539 }
9540 exit:
9541 return ret;
9542 }
9543
issue_action_spct_ch_switch(_adapter * padapter,u8 * ra,u8 new_ch,u8 ch_offset)9544 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9545 {
9546 _irqL irqL;
9547 _list *plist, *phead;
9548 struct xmit_frame *pmgntframe;
9549 struct pkt_attrib *pattrib;
9550 unsigned char *pframe;
9551 struct rtw_ieee80211_hdr *pwlanhdr;
9552 unsigned short *fctrl;
9553 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9554 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9555 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9556 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9557
9558 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9559 return;
9560
9561 DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9562 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9563
9564 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9565 return;
9566
9567 //update attribute
9568 pattrib = &pmgntframe->attrib;
9569 update_mgntframe_attrib(padapter, pattrib);
9570
9571 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9572
9573 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9574 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9575
9576 fctrl = &(pwlanhdr->frame_ctl);
9577 *(fctrl) = 0;
9578
9579 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9580 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9581 _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9582
9583 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9584 pmlmeext->mgnt_seq++;
9585 SetFrameSubType(pframe, WIFI_ACTION);
9586
9587 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9588 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9589
9590 /* category, action */
9591 {
9592 u8 category, action;
9593 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9594 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9595
9596 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9597 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9598 }
9599
9600 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9601 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9602 hal_ch_offset_to_secondary_ch_offset(ch_offset));
9603
9604 pattrib->last_txcmdsz = pattrib->pktlen;
9605
9606 dump_mgntframe(padapter, pmgntframe);
9607
9608 }
9609
9610 #ifdef CONFIG_IEEE80211W
issue_action_SA_Query(_adapter * padapter,unsigned char * raddr,unsigned char action,unsigned short tid,u8 key_type)9611 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9612 {
9613 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
9614 u16 reason_code;
9615 struct xmit_frame *pmgntframe;
9616 struct pkt_attrib *pattrib;
9617 u8 *pframe;
9618 struct rtw_ieee80211_hdr *pwlanhdr;
9619 u16 *fctrl;
9620 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9621 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9622 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9623 struct sta_info *psta;
9624 struct sta_priv *pstapriv = &padapter->stapriv;
9625 struct registry_priv *pregpriv = &padapter->registrypriv;
9626 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9627
9628 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9629 return;
9630
9631 DBG_871X("%s, %04x\n", __FUNCTION__, tid);
9632
9633 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9634 {
9635 DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9636 return;
9637 }
9638
9639 //update attribute
9640 pattrib = &pmgntframe->attrib;
9641 update_mgntframe_attrib(padapter, pattrib);
9642 pattrib->key_type = key_type;
9643 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9644
9645 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9646 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9647
9648 fctrl = &(pwlanhdr->frame_ctl);
9649 *(fctrl) = 0;
9650
9651 if(raddr)
9652 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9653 else
9654 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9655 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9656 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9657
9658 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9659 pmlmeext->mgnt_seq++;
9660 SetFrameSubType(pframe, WIFI_ACTION);
9661
9662 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9663 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9664
9665 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9666 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9667
9668 switch (action)
9669 {
9670 case 0: //SA Query req
9671 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9672 pmlmeext->sa_query_seq++;
9673 /* send sa query request to AP, AP should reply sa query response in 1 second */
9674 if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9675 psta = rtw_get_stainfo(pstapriv, raddr);
9676 if (psta != NULL) {
9677 /* DBG_871X("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9678 _set_timer(&psta->dot11w_expire_timer, 1000);
9679 }
9680 }
9681 break;
9682
9683 case 1: //SA Query rsp
9684 tid = cpu_to_le16(tid);
9685 /* DBG_871X("rtw_set_fixed_ie, %04x\n", tid); */
9686 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9687 break;
9688 default:
9689 break;
9690 }
9691
9692 pattrib->last_txcmdsz = pattrib->pktlen;
9693
9694 dump_mgntframe(padapter, pmgntframe);
9695 }
9696 #endif //CONFIG_IEEE80211W
9697
9698 /**
9699 * issue_action_ba - internal function to TX Block Ack action frame
9700 * @padapter: the adapter to TX
9701 * @raddr: receiver address
9702 * @action: Block Ack Action
9703 * @tid: tid
9704 * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9705 * @status: status/reason code. used by ADDBA_RESP, DELBA
9706 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9707 * @wait_ack: used xmit ack
9708 *
9709 * Returns:
9710 * _SUCCESS: No xmit ack is used or acked
9711 * _FAIL: not acked when using xmit ack
9712 */
issue_action_ba(_adapter * padapter,unsigned char * raddr,unsigned char action,u8 tid,u8 size,u16 status,u8 initiator,int wait_ack)9713 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9714 , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9715 {
9716 int ret = _FAIL;
9717 u8 category = RTW_WLAN_CATEGORY_BACK;
9718 u16 start_seq;
9719 u16 BA_para_set;
9720 u16 BA_timeout_value;
9721 u16 BA_starting_seqctrl;
9722 struct xmit_frame *pmgntframe;
9723 struct pkt_attrib *pattrib;
9724 u8 *pframe;
9725 struct rtw_ieee80211_hdr *pwlanhdr;
9726 u16 *fctrl;
9727 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9728 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9729 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9730 struct sta_info *psta;
9731 struct sta_priv *pstapriv = &padapter->stapriv;
9732 struct registry_priv *pregpriv = &padapter->registrypriv;
9733
9734 #ifdef CONFIG_80211N_HT
9735
9736 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9737 goto exit;
9738
9739 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9740 goto exit;
9741
9742 //update attribute
9743 pattrib = &pmgntframe->attrib;
9744 update_mgntframe_attrib(padapter, pattrib);
9745
9746 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9747
9748 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9749 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9750
9751 fctrl = &(pwlanhdr->frame_ctl);
9752 *(fctrl) = 0;
9753
9754 //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9755 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9756 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9757 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9758
9759 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9760 pmlmeext->mgnt_seq++;
9761 SetFrameSubType(pframe, WIFI_ACTION);
9762
9763 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9764 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9765
9766 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9767 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9768
9769 if (category == 3)
9770 {
9771 switch (action)
9772 {
9773 case RTW_WLAN_ACTION_ADDBA_REQ:
9774 do {
9775 pmlmeinfo->dialogToken++;
9776 } while (pmlmeinfo->dialogToken == 0);
9777 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9778
9779 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9780 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9781 #else
9782 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9783 #endif
9784
9785 BA_para_set = cpu_to_le16(BA_para_set);
9786 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9787
9788 //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
9789 BA_timeout_value = 5000;//~ 5ms
9790 BA_timeout_value = cpu_to_le16(BA_timeout_value);
9791 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9792
9793 //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
9794 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
9795 {
9796 start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1;
9797
9798 DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9799
9800 psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9801
9802 BA_starting_seqctrl = start_seq << 4;
9803 }
9804
9805 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9806 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9807 break;
9808
9809 case RTW_WLAN_ACTION_ADDBA_RESP:
9810 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9811 status = cpu_to_le16(status);
9812 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9813
9814 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9815
9816 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9817 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9818
9819 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9820 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9821
9822 if (!padapter->registrypriv.wifi_spec) {
9823 if(pregpriv->ampdu_amsdu==0)//disabled
9824 BA_para_set &= ~BIT(0);
9825 else if(pregpriv->ampdu_amsdu==1)//enabled
9826 BA_para_set |= BIT(0);
9827 }
9828
9829 BA_para_set = cpu_to_le16(BA_para_set);
9830
9831 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9832 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9833 break;
9834
9835 case RTW_WLAN_ACTION_DELBA:
9836 BA_para_set = 0;
9837 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9838 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9839
9840 BA_para_set = cpu_to_le16(BA_para_set);
9841 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9842 status = cpu_to_le16(status);
9843 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9844 break;
9845 default:
9846 break;
9847 }
9848 }
9849
9850 pattrib->last_txcmdsz = pattrib->pktlen;
9851
9852 if (wait_ack) {
9853 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9854 } else {
9855 dump_mgntframe(padapter, pmgntframe);
9856 ret = _SUCCESS;
9857 }
9858
9859 exit:
9860 #endif //CONFIG_80211N_HT
9861 return ret;
9862 }
9863
9864 /**
9865 * issue_addba_req - TX ADDBA_REQ
9866 * @adapter: the adapter to TX
9867 * @ra: receiver address
9868 * @tid: tid
9869 */
issue_addba_req(_adapter * adapter,unsigned char * ra,u8 tid)9870 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
9871 {
9872 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
9873 , tid
9874 , 0 /* unused */
9875 , 0 /* unused */
9876 , 0 /* unused */
9877 , _FALSE
9878 );
9879 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
9880 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
9881
9882 }
9883
9884 /**
9885 * issue_addba_rsp - TX ADDBA_RESP
9886 * @adapter: the adapter to TX
9887 * @ra: receiver address
9888 * @tid: tid
9889 * @status: status code
9890 * @size: the announced AMPDU buffer size
9891 */
issue_addba_rsp(_adapter * adapter,unsigned char * ra,u8 tid,u16 status,u8 size)9892 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
9893 {
9894 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9895 , tid
9896 , size
9897 , status
9898 , 0 /* unused */
9899 , _FALSE
9900 );
9901 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
9902 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
9903 }
9904
9905 /**
9906 * issue_del_ba - TX DELBA
9907 * @adapter: the adapter to TX
9908 * @ra: receiver address
9909 * @tid: tid
9910 * @reason: reason code
9911 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9912 */
issue_del_ba(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator)9913 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
9914 {
9915 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
9916 , tid
9917 , 0 /* unused */
9918 , reason
9919 , initiator
9920 , _FALSE
9921 );
9922 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
9923 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
9924 }
9925
9926 /**
9927 * issue_del_ba_ex - TX DELBA with xmit ack options
9928 * @adapter: the adapter to TX
9929 * @ra: receiver address
9930 * @tid: tid
9931 * @reason: reason code
9932 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9933 * @try_cnt: the maximal TX count to try
9934 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9935 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9936 */
issue_del_ba_ex(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator,int try_cnt,int wait_ms)9937 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
9938 , int try_cnt, int wait_ms)
9939 {
9940 int ret = _FAIL;
9941 int i = 0;
9942 u32 start = rtw_get_current_time();
9943
9944 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
9945 goto exit;
9946
9947 do {
9948 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
9949 , tid
9950 , 0 /* unused */
9951 , reason
9952 , initiator
9953 , wait_ms > 0?_TRUE:_FALSE
9954 );
9955
9956 i++;
9957
9958 if (RTW_CANNOT_RUN(adapter))
9959 break;
9960
9961 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9962 rtw_msleep_os(wait_ms);
9963
9964 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9965
9966 if (ret != _FAIL) {
9967 ret = _SUCCESS;
9968 #ifndef DBG_XMIT_ACK
9969 /* goto exit; */
9970 #endif
9971 }
9972
9973 if (try_cnt && wait_ms) {
9974 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
9975 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
9976 , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9977 }
9978 exit:
9979 return ret;
9980 }
9981
issue_action_BSSCoexistPacket(_adapter * padapter)9982 static void issue_action_BSSCoexistPacket(_adapter *padapter)
9983 {
9984 _irqL irqL;
9985 _list *plist, *phead;
9986 unsigned char category, action;
9987 struct xmit_frame *pmgntframe;
9988 struct pkt_attrib *pattrib;
9989 unsigned char *pframe;
9990 struct rtw_ieee80211_hdr *pwlanhdr;
9991 unsigned short *fctrl;
9992 struct wlan_network *pnetwork = NULL;
9993 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9994 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9995 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9996 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9997 _queue *queue = &(pmlmepriv->scanned_queue);
9998 u8 InfoContent[16] = {0};
9999 u8 ICS[8][15];
10000 #ifdef CONFIG_80211N_HT
10001 if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
10002 return;
10003
10004 if(_TRUE == pmlmeinfo->bwmode_updated)
10005 return;
10006
10007 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10008 return;
10009
10010 DBG_871X("%s\n", __FUNCTION__);
10011
10012
10013 category = RTW_WLAN_CATEGORY_PUBLIC;
10014 action = ACT_PUBLIC_BSSCOEXIST;
10015
10016 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10017 {
10018 return;
10019 }
10020
10021 //update attribute
10022 pattrib = &pmgntframe->attrib;
10023 update_mgntframe_attrib(padapter, pattrib);
10024
10025 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10026
10027 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10028 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10029
10030 fctrl = &(pwlanhdr->frame_ctl);
10031 *(fctrl) = 0;
10032
10033 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10034 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10035 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10036
10037 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10038 pmlmeext->mgnt_seq++;
10039 SetFrameSubType(pframe, WIFI_ACTION);
10040
10041 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10042 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10043
10044 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10045 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10046
10047
10048 //
10049 if(pmlmepriv->num_FortyMHzIntolerant>0)
10050 {
10051 u8 iedata=0;
10052
10053 iedata |= BIT(2);//20 MHz BSS Width Request
10054
10055 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
10056
10057 }
10058
10059
10060 //
10061 _rtw_memset(ICS, 0, sizeof(ICS));
10062 if(pmlmepriv->num_sta_no_ht>0)
10063 {
10064 int i;
10065
10066 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10067
10068 phead = get_list_head(queue);
10069 plist = get_next(phead);
10070
10071 while(1)
10072 {
10073 int len;
10074 u8 *p;
10075 WLAN_BSSID_EX *pbss_network;
10076
10077 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
10078 break;
10079
10080 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
10081
10082 plist = get_next(plist);
10083
10084 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10085
10086 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10087 if((p==NULL) || (len==0))//non-HT
10088 {
10089 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
10090 continue;
10091
10092 ICS[0][pbss_network->Configuration.DSConfig]=1;
10093
10094 if(ICS[0][0] == 0)
10095 ICS[0][0] = 1;
10096 }
10097
10098 }
10099
10100 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10101
10102
10103 for(i= 0;i<8;i++)
10104 {
10105 if(ICS[i][0] == 1)
10106 {
10107 int j, k = 0;
10108
10109 InfoContent[k] = i;
10110 //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
10111 k++;
10112
10113 for(j=1;j<=14;j++)
10114 {
10115 if(ICS[i][j]==1)
10116 {
10117 if(k<16)
10118 {
10119 InfoContent[k] = j; //channel number
10120 //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
10121 k++;
10122 }
10123 }
10124 }
10125
10126 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10127
10128 }
10129
10130 }
10131
10132
10133 }
10134
10135
10136 pattrib->last_txcmdsz = pattrib->pktlen;
10137
10138 dump_mgntframe(padapter, pmgntframe);
10139 #endif //CONFIG_80211N_HT
10140 }
10141
10142 // Spatial Multiplexing Powersave (SMPS) action frame
_issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,u8 wait_ack)10143 int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack)
10144 {
10145
10146 int ret = _FAIL;
10147 unsigned char category = RTW_WLAN_CATEGORY_HT;
10148 u8 action = RTW_WLAN_ACTION_HT_SM_PS;
10149 u8 sm_power_control=0;
10150 struct xmit_frame *pmgntframe;
10151 struct pkt_attrib *pattrib;
10152 unsigned char *pframe;
10153 struct rtw_ieee80211_hdr *pwlanhdr;
10154 unsigned short *fctrl;
10155 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10156 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10157 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10158
10159
10160 if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED)
10161 {
10162 sm_power_control = sm_power_control & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable
10163 }
10164 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC)
10165 {
10166 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
10167 sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode
10168 }
10169 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC)
10170 {
10171 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
10172 sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode
10173 }
10174 else
10175 return ret;
10176
10177 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10178 return ret;
10179
10180 DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode );
10181
10182 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10183 return ret;
10184
10185 //update attribute
10186 pattrib = &pmgntframe->attrib;
10187 update_mgntframe_attrib(padapter, pattrib);
10188
10189 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10190
10191 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10192 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10193
10194 fctrl = &(pwlanhdr->frame_ctl);
10195 *(fctrl) = 0;
10196
10197 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10198 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10199 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10200
10201 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10202 pmlmeext->mgnt_seq++;
10203 SetFrameSubType(pframe, WIFI_ACTION);
10204
10205 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10206 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10207
10208 /* category, action */
10209 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10210 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10211
10212 pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10213
10214 pattrib->last_txcmdsz = pattrib->pktlen;
10215
10216 if(wait_ack)
10217 {
10218 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10219 }
10220 else
10221 {
10222 dump_mgntframe(padapter, pmgntframe);
10223 ret = _SUCCESS;
10224 }
10225
10226 if (ret != _SUCCESS)
10227 DBG_8192C("%s, ack to\n", __func__);
10228
10229 return ret;
10230 }
10231
10232 /*
10233 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10234 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10235 * try_cnt means the maximal TX count to try
10236 */
issue_action_SM_PS_wait_ack(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,int try_cnt,int wait_ms)10237 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10238 {
10239 int ret = _FAIL;
10240 int i = 0;
10241 u32 start = rtw_get_current_time();
10242
10243 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10244 goto exit;
10245
10246 do {
10247 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE );
10248
10249 i++;
10250
10251 if (RTW_CANNOT_RUN(padapter))
10252 break;
10253
10254 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
10255 rtw_msleep_os(wait_ms);
10256
10257 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
10258
10259 if (ret != _FAIL) {
10260 ret = _SUCCESS;
10261 #ifndef DBG_XMIT_ACK
10262 goto exit;
10263 #endif
10264 }
10265
10266 if (try_cnt && wait_ms) {
10267 if (raddr)
10268 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10269 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10270 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10271 else
10272 DBG_871X(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10273 FUNC_ADPT_ARG(padapter),
10274 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10275 }
10276 exit:
10277
10278 return ret;
10279 }
10280
issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode)10281 int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode )
10282 {
10283 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10284 return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE );
10285 }
10286
10287 /**
10288 * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10289 * @adapter: the adapter to which @sta belongs
10290 * @initiator: if we are the initiator of AMPDU association
10291 * @sta: the sta to be checked
10292 * @tid: the tid to be checked
10293 * @force: cancel and send DELBA even when no AMPDU association is setup
10294 * @wait_ack: send delba with xmit ack (valid when initiator == 0)
10295 *
10296 * Returns:
10297 * _FAIL if sta is NULL
10298 * when initiator is 1, always _SUCCESS
10299 * when initiator is 0, _SUCCESS if DELBA is acked
10300 */
_send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force,int wait_ack)10301 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10302 , u8 force, int wait_ack)
10303 {
10304 int ret = _SUCCESS;
10305
10306 if (sta == NULL) {
10307 ret = _FAIL;
10308 goto exit;
10309 }
10310
10311 if (initiator == 0) {
10312 /* recipient */
10313 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10314 u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10315
10316 sta->recvreorder_ctrl[tid].enable = _FALSE;
10317 sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10318
10319 if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10320 ret = _FAIL;
10321 else if (wait_ack)
10322 ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
10323 else
10324 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10325
10326 if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10327 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10328 }
10329 } else if (initiator == 1) {
10330 /* originator */
10331 #ifdef CONFIG_80211N_HT
10332 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10333 sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10334 sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10335 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10336 }
10337 #endif
10338 }
10339
10340 exit:
10341 return ret;
10342 }
10343
send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)10344 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10345 , u8 force)
10346 {
10347 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10348 }
10349
send_delba_sta_tid_wait_ack(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)10350 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10351 , u8 force)
10352 {
10353 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10354 }
10355
send_delba(_adapter * padapter,u8 initiator,u8 * addr)10356 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10357 {
10358 struct sta_priv *pstapriv = &padapter->stapriv;
10359 struct sta_info *psta = NULL;
10360 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10361 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10362 u16 tid;
10363
10364 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
10365 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10366 return _SUCCESS;
10367
10368 psta = rtw_get_stainfo(pstapriv, addr);
10369 if(psta==NULL)
10370 return _SUCCESS;
10371
10372 #if 0
10373 DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR");
10374 if (initiator == 1) /* originator */
10375 DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10376 #endif
10377
10378 for (tid = 0; tid < TID_NUM; tid++)
10379 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10380
10381 return _SUCCESS;
10382 }
10383 #ifdef CONFIG_AP_MODE
send_beacon(_adapter * padapter)10384 unsigned int send_beacon(_adapter *padapter)
10385 {
10386 u8 bxmitok = _FALSE;
10387 int issue=0;
10388 int poll = 0;
10389 //#ifdef CONFIG_CONCURRENT_MODE
10390 //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10391 //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10392 //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
10393 //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
10394 //#endif
10395
10396 #ifdef CONFIG_PCI_HCI
10397 //DBG_871X("%s\n", __FUNCTION__);
10398
10399 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10400
10401 /* 8192EE Port select for Beacon DL */
10402 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10403
10404 issue_beacon(padapter, 0);
10405
10406 return _SUCCESS;
10407 #endif
10408
10409 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10410 u32 start = rtw_get_current_time();
10411
10412 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10413 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10414 do{
10415 issue_beacon(padapter, 100);
10416 issue++;
10417 do {
10418 rtw_yield_os();
10419 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10420 poll++;
10421 } while ((poll%10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10422
10423 } while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter));
10424
10425 if (RTW_CANNOT_RUN(padapter))
10426 return _FAIL;
10427
10428
10429 if(_FALSE == bxmitok)
10430 {
10431 DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10432 return _FAIL;
10433 }
10434 else
10435 {
10436 u32 passing_time = rtw_get_passing_time_ms(start);
10437
10438 if(passing_time > 100 || issue > 3)
10439 DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10440 //else
10441 // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10442
10443 return _SUCCESS;
10444 }
10445
10446 #endif
10447
10448 }
10449 #endif
10450
10451 /****************************************************************************
10452
10453 Following are some utitity fuctions for WiFi MLME
10454
10455 *****************************************************************************/
10456
IsLegal5GChannel(IN PADAPTER Adapter,IN u8 channel)10457 BOOLEAN IsLegal5GChannel(
10458 IN PADAPTER Adapter,
10459 IN u8 channel)
10460 {
10461
10462 int i=0;
10463 u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
10464 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
10465 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
10466 161,163,165};
10467 for(i=0;i<sizeof(Channel_5G);i++)
10468 if(channel == Channel_5G[i])
10469 return _TRUE;
10470 return _FALSE;
10471 }
10472
10473 //collect bss info from Beacon and Probe request/response frames.
collect_bss_info(_adapter * padapter,union recv_frame * precv_frame,WLAN_BSSID_EX * bssid)10474 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10475 {
10476 int i;
10477 u32 len;
10478 u8 *p;
10479 u16 val16, subtype;
10480 u8 *pframe = precv_frame->u.hdr.rx_data;
10481 u32 packet_len = precv_frame->u.hdr.len;
10482 u8 ie_offset;
10483 struct registry_priv *pregistrypriv = &padapter->registrypriv;
10484 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10485 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10486
10487 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10488
10489 if (len > MAX_IE_SZ)
10490 {
10491 //DBG_871X("IE too long for survey event\n");
10492 return _FAIL;
10493 }
10494
10495 _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10496
10497 subtype = GetFrameSubType(pframe);
10498
10499 if(subtype==WIFI_BEACON) {
10500 bssid->Reserved[0] = 1;
10501 ie_offset = _BEACON_IE_OFFSET_;
10502 } else {
10503 // FIXME : more type
10504 if (subtype == WIFI_PROBERSP) {
10505 ie_offset = _PROBERSP_IE_OFFSET_;
10506 bssid->Reserved[0] = 3;
10507 }
10508 else if (subtype == WIFI_PROBEREQ) {
10509 ie_offset = _PROBEREQ_IE_OFFSET_;
10510 bssid->Reserved[0] = 2;
10511 }
10512 else {
10513 bssid->Reserved[0] = 0;
10514 ie_offset = _FIXED_IE_LENGTH_;
10515 }
10516 }
10517
10518 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10519
10520 //below is to copy the information element
10521 bssid->IELength = len;
10522 _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10523
10524 //get the signal strength
10525 //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
10526 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
10527 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
10528 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
10529 #ifdef CONFIG_ANTENNA_DIVERSITY
10530 //rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna));
10531 rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna);
10532 #endif
10533
10534 // checking SSID
10535 if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
10536 {
10537 DBG_871X("marc: cannot find SSID for survey event\n");
10538 return _FAIL;
10539 }
10540
10541 if (*(p + 1))
10542 {
10543 if (len > NDIS_802_11_LENGTH_SSID)
10544 {
10545 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10546 return _FAIL;
10547 }
10548 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10549 bssid->Ssid.SsidLength = *(p + 1);
10550 }
10551 else
10552 {
10553 bssid->Ssid.SsidLength = 0;
10554 }
10555
10556 _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10557
10558 //checking rate info...
10559 i = 0;
10560 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10561 if (p != NULL)
10562 {
10563 if (len > NDIS_802_11_LENGTH_RATES_EX)
10564 {
10565 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10566 return _FAIL;
10567 }
10568 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10569 i = len;
10570 }
10571
10572 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10573 if (p != NULL)
10574 {
10575 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
10576 {
10577 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10578 return _FAIL;
10579 }
10580 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10581 }
10582
10583 //todo:
10584 #if 0
10585 if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10586 {
10587 bssid->NetworkTypeInUse = Ndis802_11DS;
10588 }
10589 else
10590 #endif
10591 {
10592 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10593 }
10594
10595 #ifdef CONFIG_P2P
10596 if (subtype == WIFI_PROBEREQ)
10597 {
10598 u8 *p2p_ie;
10599 u32 p2p_ielen;
10600 // Set Listion Channel
10601 if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen)))
10602 {
10603 u32 attr_contentlen = 0;
10604 u8 listen_ch[5] = { 0x00 };
10605
10606 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10607 bssid->Configuration.DSConfig = listen_ch[4];
10608 } else
10609 { // use current channel
10610 bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10611 DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10612 }
10613
10614 // FIXME
10615 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10616 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10617 bssid->Privacy = 1;
10618 return _SUCCESS;
10619 }
10620 #endif //CONFIG_P2P
10621
10622 if (bssid->IELength < 12)
10623 return _FAIL;
10624
10625 // Checking for DSConfig
10626 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10627
10628 bssid->Configuration.DSConfig = 0;
10629 bssid->Configuration.Length = 0;
10630
10631 if (p)
10632 {
10633 bssid->Configuration.DSConfig = *(p + 2);
10634 }
10635 else
10636 {// In 5G, some ap do not have DSSET IE
10637 // checking HT info for channel
10638 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10639 if(p)
10640 {
10641 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10642 bssid->Configuration.DSConfig = HT_info->primary_channel;
10643 }
10644 else
10645 { // use current channel
10646 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
10647 }
10648 }
10649
10650 _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
10651 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
10652
10653 val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
10654
10655 if (val16 & BIT(0))
10656 {
10657 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10658 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10659 }
10660 else
10661 {
10662 bssid->InfrastructureMode = Ndis802_11IBSS;
10663 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10664 }
10665
10666 if (val16 & BIT(4))
10667 bssid->Privacy = 1;
10668 else
10669 bssid->Privacy = 0;
10670
10671 bssid->Configuration.ATIMWindow = 0;
10672
10673 //20/40 BSS Coexistence check
10674 if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
10675 {
10676 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10677 #ifdef CONFIG_80211N_HT
10678 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10679 if(p && len>0)
10680 {
10681 struct HT_caps_element *pHT_caps;
10682 pHT_caps = (struct HT_caps_element *)(p + 2);
10683
10684 if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
10685 {
10686 pmlmepriv->num_FortyMHzIntolerant++;
10687 }
10688 }
10689 else
10690 {
10691 pmlmepriv->num_sta_no_ht++;
10692 }
10693 #endif //CONFIG_80211N_HT
10694
10695 }
10696
10697 #ifdef CONFIG_INTEL_WIDI
10698 //process_intel_widi_query_or_tigger(padapter, bssid);
10699 if(process_intel_widi_query_or_tigger(padapter, bssid))
10700 {
10701 return _FAIL;
10702 }
10703 #endif // CONFIG_INTEL_WIDI
10704
10705 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10706 if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10707 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10708 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10709 , rtw_get_oper_ch(padapter)
10710 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10711 );
10712 }
10713 #endif
10714
10715 // mark bss info receving from nearby channel as SignalQuality 101
10716 if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10717 {
10718 bssid->PhyInfo.SignalQuality= 101;
10719 }
10720
10721 return _SUCCESS;
10722 }
10723 #ifdef CONFIG_ADHOC_MODE
start_create_ibss(_adapter * padapter)10724 void start_create_ibss(_adapter* padapter)
10725 {
10726 unsigned short caps;
10727 u8 val8;
10728 u8 join_type;
10729 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10730 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10731 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10732 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10733 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10734
10735 //update wireless mode
10736 update_wireless_mode(padapter);
10737
10738 //udpate capability
10739 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10740 update_capinfo(padapter, caps);
10741 if(caps&cap_IBSS)//adhoc master
10742 {
10743 //set_opmode_cmd(padapter, adhoc);//removed
10744
10745 val8 = 0xcf;
10746 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10747
10748 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
10749
10750 //switch channel
10751 //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
10752 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10753
10754 beacon_timing_control(padapter);
10755
10756 //set msr to WIFI_FW_ADHOC_STATE
10757 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10758 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10759
10760 //issue beacon
10761 if(send_beacon(padapter)==_FAIL)
10762 {
10763 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
10764
10765 report_join_res(padapter, -1);
10766 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10767 }
10768 else
10769 {
10770 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10771 join_type = 0;
10772 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10773
10774 report_join_res(padapter, 1);
10775 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10776 rtw_indicate_connect(padapter);
10777 }
10778 }
10779 else
10780 {
10781 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
10782 return;
10783 }
10784 //update bc/mc sta_info
10785 update_bmc_sta(padapter);
10786
10787 }
10788 #endif /*CONFIG_ADHOC_MODE*/
10789
start_clnt_join(_adapter * padapter)10790 void start_clnt_join(_adapter* padapter)
10791 {
10792 unsigned short caps;
10793 u8 val8;
10794 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10795 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10796 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10797 int beacon_timeout;
10798 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
10799 u8 E2500_ID[]= {0x20, 0xAA, 0x4B};
10800 u8 iot_flag = _FALSE;
10801
10802 //update wireless mode
10803 update_wireless_mode(padapter);
10804
10805 //udpate capability
10806 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10807 update_capinfo(padapter, caps);
10808
10809 //check if sta is ASIX peer and fix IOT issue if it is.
10810 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
10811 iot_flag = _TRUE;
10812 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10813 } else if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network),
10814 E2500_ID, 3)) {
10815 iot_flag = _TRUE;
10816 rtw_hal_set_hwreg(padapter, HW_VAR_E2500_IOT,
10817 (u8 *)(&iot_flag));
10818 DBG_871X("%s: Join with Linksys E2500\n", __func__);
10819 }
10820
10821 if (caps&cap_ESS)
10822 {
10823 Set_MSR(padapter, WIFI_FW_STATION_STATE);
10824
10825 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
10826
10827 #ifdef CONFIG_WAPI_SUPPORT
10828 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
10829 {
10830 //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
10831 val8 = 0x4c;
10832 }
10833 #endif
10834 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10835
10836 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10837 // Because of AP's not receiving deauth before
10838 // AP may: 1)not response auth or 2)deauth us after link is complete
10839 // issue deauth before issuing auth to deal with the situation
10840
10841 // Commented by Albert 2012/07/21
10842 // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
10843 {
10844 #ifdef CONFIG_P2P
10845 _queue *queue = &(padapter->mlmepriv.scanned_queue);
10846 _list *head = get_list_head(queue);
10847 _list *pos = get_next(head);
10848 struct wlan_network *scanned = NULL;
10849 u8 ie_offset = 0;
10850 _irqL irqL;
10851 bool has_p2p_ie = _FALSE;
10852
10853 _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10854
10855 for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
10856
10857 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
10858
10859 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
10860 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
10861 ) {
10862 ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
10863 if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
10864 has_p2p_ie = _TRUE;
10865 break;
10866 }
10867 }
10868
10869 _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10870
10871 if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
10872 #endif /* CONFIG_P2P */
10873 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
10874 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
10875 }
10876 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
10877
10878 //here wait for receiving the beacon to start auth
10879 //and enable a timer
10880 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
10881 set_link_timer(pmlmeext, beacon_timeout);
10882 _set_timer( &padapter->mlmepriv.assoc_timer,
10883 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
10884
10885 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
10886 }
10887 else if (caps&cap_IBSS) //adhoc client
10888 {
10889 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
10890
10891 val8 = 0xcf;
10892 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10893
10894 beacon_timing_control(padapter);
10895
10896 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10897
10898 report_join_res(padapter, 1);
10899 }
10900 else
10901 {
10902 //DBG_871X("marc: invalid cap:%x\n", caps);
10903 return;
10904 }
10905
10906 }
10907
start_clnt_auth(_adapter * padapter)10908 void start_clnt_auth(_adapter* padapter)
10909 {
10910 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10911 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10912
10913 _cancel_timer_ex(&pmlmeext->link_timer);
10914
10915 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
10916 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
10917
10918 pmlmeinfo->auth_seq = 1;
10919 pmlmeinfo->reauth_count = 0;
10920 pmlmeinfo->reassoc_count = 0;
10921 pmlmeinfo->link_count = 0;
10922 pmlmeext->retry = 0;
10923
10924
10925 DBG_871X_LEVEL(_drv_always_, "start auth\n");
10926 issue_auth(padapter, NULL, 0);
10927
10928 set_link_timer(pmlmeext, REAUTH_TO);
10929
10930 }
10931
10932
start_clnt_assoc(_adapter * padapter)10933 void start_clnt_assoc(_adapter* padapter)
10934 {
10935 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10936 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10937
10938 _cancel_timer_ex(&pmlmeext->link_timer);
10939
10940 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
10941 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
10942
10943 issue_assocreq(padapter);
10944
10945 set_link_timer(pmlmeext, REASSOC_TO);
10946 }
10947
receive_disconnect(_adapter * padapter,unsigned char * MacAddr,unsigned short reason)10948 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
10949 {
10950 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10951 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10952
10953 if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
10954 return _SUCCESS;
10955
10956 DBG_871X("%s\n", __FUNCTION__);
10957
10958 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
10959 {
10960 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
10961 {
10962 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10963 report_del_sta_event(padapter, MacAddr, reason, _TRUE);
10964
10965 }
10966 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
10967 {
10968 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10969 report_join_res(padapter, -2);
10970 } else
10971 DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
10972 }
10973
10974 return _SUCCESS;
10975 }
10976
10977 #ifdef CONFIG_80211D
process_80211d(PADAPTER padapter,WLAN_BSSID_EX * bssid)10978 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
10979 {
10980 struct registry_priv *pregistrypriv;
10981 struct mlme_ext_priv *pmlmeext;
10982 RT_CHANNEL_INFO *chplan_new;
10983 u8 channel;
10984 u8 i;
10985
10986
10987 pregistrypriv = &padapter->registrypriv;
10988 pmlmeext = &padapter->mlmeextpriv;
10989
10990 // Adjust channel plan by AP Country IE
10991 if (pregistrypriv->enable80211d &&
10992 (!pmlmeext->update_channel_plan_by_ap_done))
10993 {
10994 u8 *ie, *p;
10995 u32 len;
10996 RT_CHANNEL_PLAN chplan_ap;
10997 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
10998 u8 country[4];
10999 u8 fcn; // first channel number
11000 u8 noc; // number of channel
11001 u8 j, k;
11002
11003 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11004 if (!ie) return;
11005 if (len < 6) return;
11006
11007 ie += 2;
11008 p = ie;
11009 ie += len;
11010
11011 _rtw_memset(country, 0, 4);
11012 _rtw_memcpy(country, p, 3);
11013 p += 3;
11014 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11015 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
11016
11017 i = 0;
11018 while ((ie - p) >= 3)
11019 {
11020 fcn = *(p++);
11021 noc = *(p++);
11022 p++;
11023
11024 for (j = 0; j < noc; j++)
11025 {
11026 if (fcn <= 14) channel = fcn + j; // 2.4 GHz
11027 else channel = fcn + j*4; // 5 GHz
11028
11029 chplan_ap.Channel[i++] = channel;
11030 }
11031 }
11032 chplan_ap.Len = i;
11033
11034 #ifdef CONFIG_DEBUG_RTL871X
11035 i = 0;
11036 DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11037 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
11038 {
11039 DBG_8192C("%02d,", chplan_ap.Channel[i]);
11040 i++;
11041 }
11042 DBG_871X("}\n");
11043 #endif
11044
11045 _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
11046 #ifdef CONFIG_DEBUG_RTL871X
11047 i = 0;
11048 DBG_871X("%s: STA channel plan {", __FUNCTION__);
11049 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11050 {
11051 DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
11052 i++;
11053 }
11054 DBG_871X("}\n");
11055 #endif
11056
11057 _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
11058 chplan_new = pmlmeext->channel_set;
11059
11060 i = j = k = 0;
11061 if (pregistrypriv->wireless_mode & WIRELESS_11G)
11062 {
11063 do {
11064 if ((i == MAX_CHANNEL_NUM) ||
11065 (chplan_sta[i].ChannelNum == 0) ||
11066 (chplan_sta[i].ChannelNum > 14))
11067 break;
11068
11069 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11070 break;
11071
11072 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11073 {
11074 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11075 chplan_new[k].ScanType = SCAN_ACTIVE;
11076 i++;
11077 j++;
11078 k++;
11079 }
11080 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11081 {
11082 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11083 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11084 chplan_new[k].ScanType = SCAN_PASSIVE;
11085 i++;
11086 k++;
11087 }
11088 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11089 {
11090 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11091 chplan_new[k].ScanType = SCAN_ACTIVE;
11092 j++;
11093 k++;
11094 }
11095 } while (1);
11096
11097 // change AP not support channel to Passive scan
11098 while ((i < MAX_CHANNEL_NUM) &&
11099 (chplan_sta[i].ChannelNum != 0) &&
11100 (chplan_sta[i].ChannelNum <= 14))
11101 {
11102 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11103 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11104 chplan_new[k].ScanType = SCAN_PASSIVE;
11105 i++;
11106 k++;
11107 }
11108
11109 // add channel AP supported
11110 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11111 {
11112 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11113 chplan_new[k].ScanType = SCAN_ACTIVE;
11114 j++;
11115 k++;
11116 }
11117 }
11118 else
11119 {
11120 // keep original STA 2.4G channel plan
11121 while ((i < MAX_CHANNEL_NUM) &&
11122 (chplan_sta[i].ChannelNum != 0) &&
11123 (chplan_sta[i].ChannelNum <= 14))
11124 {
11125 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11126 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11127 i++;
11128 k++;
11129 }
11130
11131 // skip AP 2.4G channel plan
11132 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11133 {
11134 j++;
11135 }
11136 }
11137
11138 if (pregistrypriv->wireless_mode & WIRELESS_11A)
11139 {
11140 do {
11141 if ((i >= MAX_CHANNEL_NUM) ||
11142 (chplan_sta[i].ChannelNum == 0))
11143 break;
11144
11145 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11146 break;
11147
11148 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11149 {
11150 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11151 chplan_new[k].ScanType = SCAN_ACTIVE;
11152 i++;
11153 j++;
11154 k++;
11155 }
11156 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11157 {
11158 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11159 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11160 chplan_new[k].ScanType = SCAN_PASSIVE;
11161 i++;
11162 k++;
11163 }
11164 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11165 {
11166 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11167 chplan_new[k].ScanType = SCAN_ACTIVE;
11168 j++;
11169 k++;
11170 }
11171 } while (1);
11172
11173 // change AP not support channel to Passive scan
11174 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11175 {
11176 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11177 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11178 chplan_new[k].ScanType = SCAN_PASSIVE;
11179 i++;
11180 k++;
11181 }
11182
11183 // add channel AP supported
11184 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
11185 {
11186 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11187 chplan_new[k].ScanType = SCAN_ACTIVE;
11188 j++;
11189 k++;
11190 }
11191 }
11192 else
11193 {
11194 // keep original STA 5G channel plan
11195 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11196 {
11197 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11198 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11199 i++;
11200 k++;
11201 }
11202 }
11203
11204 pmlmeext->update_channel_plan_by_ap_done = 1;
11205
11206 #ifdef CONFIG_DEBUG_RTL871X
11207 k = 0;
11208 DBG_871X("%s: new STA channel plan {", __FUNCTION__);
11209 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11210 {
11211 DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
11212 k++;
11213 }
11214 DBG_871X("}\n");
11215 #endif
11216
11217 #if 0
11218 // recover the right channel index
11219 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11220 k = 0;
11221 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11222 {
11223 if (chplan_new[k].ChannelNum == channel) {
11224 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11225 ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11226 __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
11227 pmlmeext->sitesurvey_res.channel_idx = k;
11228 break;
11229 }
11230 k++;
11231 }
11232 #endif
11233 }
11234
11235 // If channel is used by AP, set channel scan type to active
11236 channel = bssid->Configuration.DSConfig;
11237 chplan_new = pmlmeext->channel_set;
11238 i = 0;
11239 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
11240 {
11241 if (chplan_new[i].ChannelNum == channel)
11242 {
11243 if (chplan_new[i].ScanType == SCAN_PASSIVE)
11244 {
11245 //5G Bnad 2, 3 (DFS) doesn't change to active scan
11246 if(channel >= 52 && channel <= 144)
11247 break;
11248
11249 chplan_new[i].ScanType = SCAN_ACTIVE;
11250 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11251 ("%s: change channel %d scan type from passive to active\n",
11252 __FUNCTION__, channel));
11253 }
11254 break;
11255 }
11256 i++;
11257 }
11258 }
11259 #endif
11260
11261 /****************************************************************************
11262
11263 Following are the functions to report events
11264
11265 *****************************************************************************/
11266
report_survey_event(_adapter * padapter,union recv_frame * precv_frame)11267 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11268 {
11269 struct cmd_obj *pcmd_obj;
11270 u8 *pevtcmd;
11271 u32 cmdsz;
11272 struct survey_event *psurvey_evt;
11273 struct C2HEvent_Header *pc2h_evt_hdr;
11274 struct mlme_ext_priv *pmlmeext;
11275 struct cmd_priv *pcmdpriv;
11276 //u8 *pframe = precv_frame->u.hdr.rx_data;
11277 //uint len = precv_frame->u.hdr.len;
11278
11279 if(!padapter)
11280 return;
11281
11282 pmlmeext = &padapter->mlmeextpriv;
11283 pcmdpriv = &padapter->cmdpriv;
11284
11285
11286 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11287 {
11288 return;
11289 }
11290
11291 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11292 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11293 {
11294 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11295 return;
11296 }
11297
11298 _rtw_init_listhead(&pcmd_obj->list);
11299
11300 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11301 pcmd_obj->cmdsz = cmdsz;
11302 pcmd_obj->parmbuf = pevtcmd;
11303
11304 pcmd_obj->rsp = NULL;
11305 pcmd_obj->rspsz = 0;
11306
11307 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11308 pc2h_evt_hdr->len = sizeof(struct survey_event);
11309 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11310 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11311
11312 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11313
11314 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
11315 {
11316 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11317 rtw_mfree((u8 *)pevtcmd, cmdsz);
11318 return;
11319 }
11320
11321 #ifdef CONFIG_80211D
11322 process_80211d(padapter, &psurvey_evt->bss);
11323 #endif
11324
11325 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11326
11327 pmlmeext->sitesurvey_res.bss_cnt++;
11328
11329 return;
11330
11331 }
11332
report_surveydone_event(_adapter * padapter)11333 void report_surveydone_event(_adapter *padapter)
11334 {
11335 struct cmd_obj *pcmd_obj;
11336 u8 *pevtcmd;
11337 u32 cmdsz;
11338 struct surveydone_event *psurveydone_evt;
11339 struct C2HEvent_Header *pc2h_evt_hdr;
11340 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11341 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11342
11343 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11344 {
11345 return;
11346 }
11347
11348 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11349 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11350 {
11351 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11352 return;
11353 }
11354
11355 _rtw_init_listhead(&pcmd_obj->list);
11356
11357 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11358 pcmd_obj->cmdsz = cmdsz;
11359 pcmd_obj->parmbuf = pevtcmd;
11360
11361 pcmd_obj->rsp = NULL;
11362 pcmd_obj->rspsz = 0;
11363
11364 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11365 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11366 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11367 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11368
11369 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11370 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11371
11372 DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11373
11374 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11375
11376 return;
11377
11378 }
11379
report_join_res(_adapter * padapter,int res)11380 void report_join_res(_adapter *padapter, int res)
11381 {
11382 struct cmd_obj *pcmd_obj;
11383 u8 *pevtcmd;
11384 u32 cmdsz;
11385 struct joinbss_event *pjoinbss_evt;
11386 struct C2HEvent_Header *pc2h_evt_hdr;
11387 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11388 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11389 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11390
11391 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11392 {
11393 return;
11394 }
11395
11396 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11397 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11398 {
11399 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11400 return;
11401 }
11402
11403 _rtw_init_listhead(&pcmd_obj->list);
11404
11405 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11406 pcmd_obj->cmdsz = cmdsz;
11407 pcmd_obj->parmbuf = pevtcmd;
11408
11409 pcmd_obj->rsp = NULL;
11410 pcmd_obj->rspsz = 0;
11411
11412 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11413 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11414 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11415 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11416
11417 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11418 _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11419 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
11420
11421 DBG_871X("report_join_res(%d)\n", res);
11422
11423
11424 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11425
11426
11427 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11428
11429 return;
11430
11431 }
11432
report_wmm_edca_update(_adapter * padapter)11433 void report_wmm_edca_update(_adapter *padapter)
11434 {
11435 struct cmd_obj *pcmd_obj;
11436 u8 *pevtcmd;
11437 u32 cmdsz;
11438 struct wmm_event *pwmm_event;
11439 struct C2HEvent_Header *pc2h_evt_hdr;
11440 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11441 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11442 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11443
11444 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11445 {
11446 return;
11447 }
11448
11449 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11450 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11451 {
11452 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11453 return;
11454 }
11455
11456 _rtw_init_listhead(&pcmd_obj->list);
11457
11458 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11459 pcmd_obj->cmdsz = cmdsz;
11460 pcmd_obj->parmbuf = pevtcmd;
11461
11462 pcmd_obj->rsp = NULL;
11463 pcmd_obj->rspsz = 0;
11464
11465 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11466 pc2h_evt_hdr->len = sizeof(struct wmm_event);
11467 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11468 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11469
11470 pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11471 pwmm_event->wmm =0;
11472
11473 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11474
11475 return;
11476
11477 }
11478
report_del_sta_event(_adapter * padapter,unsigned char * MacAddr,unsigned short reason,bool enqueue)11479 void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue)
11480 {
11481 struct cmd_obj *pcmd_obj;
11482 u8 *pevtcmd;
11483 u32 cmdsz;
11484 struct sta_info *psta;
11485 int mac_id = -1;
11486 struct stadel_event *pdel_sta_evt;
11487 struct C2HEvent_Header *pc2h_evt_hdr;
11488 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11489 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11490 u8 res = _SUCCESS;
11491
11492 /* prepare cmd parameter */
11493 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11494 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11495 if (pevtcmd == NULL) {
11496 res = _FAIL;
11497 goto exit;
11498 }
11499
11500 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11501 pc2h_evt_hdr->len = sizeof(struct stadel_event);
11502 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11503 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11504
11505 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11506 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11507 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
11508 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11509 if(psta)
11510 mac_id = (int)psta->mac_id;
11511 else
11512 mac_id = (-1);
11513 pdel_sta_evt->mac_id = mac_id;
11514
11515 if (!enqueue) {
11516 /* do directly */
11517 rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11518 rtw_mfree(pevtcmd, cmdsz);
11519 } else {
11520 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11521 if (pcmd_obj == NULL) {
11522 rtw_mfree(pevtcmd, cmdsz);
11523 res = _FAIL;
11524 goto exit;
11525 }
11526
11527 _rtw_init_listhead(&pcmd_obj->list);
11528 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11529 pcmd_obj->cmdsz = cmdsz;
11530 pcmd_obj->parmbuf = pevtcmd;
11531
11532 pcmd_obj->rsp = NULL;
11533 pcmd_obj->rspsz = 0;
11534
11535 res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11536 }
11537
11538 exit:
11539
11540 DBG_871X(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11541 , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11542
11543 return;
11544 }
11545
report_add_sta_event(_adapter * padapter,unsigned char * MacAddr,int cam_idx)11546 void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
11547 {
11548 struct cmd_obj *pcmd_obj;
11549 u8 *pevtcmd;
11550 u32 cmdsz;
11551 struct stassoc_event *padd_sta_evt;
11552 struct C2HEvent_Header *pc2h_evt_hdr;
11553 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11554 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11555
11556 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11557 {
11558 return;
11559 }
11560
11561 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11562 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11563 {
11564 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11565 return;
11566 }
11567
11568 _rtw_init_listhead(&pcmd_obj->list);
11569
11570 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11571 pcmd_obj->cmdsz = cmdsz;
11572 pcmd_obj->parmbuf = pevtcmd;
11573
11574 pcmd_obj->rsp = NULL;
11575 pcmd_obj->rspsz = 0;
11576
11577 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11578 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11579 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11580 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11581
11582 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11583 _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11584 padd_sta_evt->cam_id = cam_idx;
11585
11586 DBG_871X("report_add_sta_event: add STA\n");
11587
11588 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11589
11590 return;
11591 }
11592
11593
rtw_port_switch_chk(_adapter * adapter)11594 bool rtw_port_switch_chk(_adapter *adapter)
11595 {
11596 bool switch_needed = _FALSE;
11597 #ifdef CONFIG_CONCURRENT_MODE
11598 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11599 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11600 struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11601 _adapter *if_port0 = NULL;
11602 _adapter *if_port1 = NULL;
11603 struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11604 struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11605 int i;
11606
11607 for (i = 0; i < dvobj->iface_nums; i++) {
11608 if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) {
11609 if_port0 = dvobj->padapters[i];
11610 if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11611 }
11612 else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) {
11613 if_port1 = dvobj->padapters[i];
11614 if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11615 }
11616 }
11617
11618 if (if_port0 == NULL) {
11619 rtw_warn_on(1);
11620 goto exit;
11621 }
11622
11623 if (if_port1 == NULL) {
11624 rtw_warn_on(1);
11625 goto exit;
11626 }
11627
11628 #ifdef DBG_RUNTIME_PORT_SWITCH
11629 DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11630 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11631 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11632 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11633 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11634 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11635 #endif /* DBG_RUNTIME_PORT_SWITCH */
11636
11637 #ifdef CONFIG_WOWLAN
11638 /* WOWLAN interface(primary, for now) should be port0 */
11639 if (pwrctl->wowlan_mode == _TRUE) {
11640 if(!is_primary_adapter(if_port0)) {
11641 DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11642 switch_needed = _TRUE;
11643 }
11644 goto exit;
11645 }
11646 #endif /* CONFIG_WOWLAN */
11647
11648 /* AP should use port0 for ctl frame's ack */
11649 if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11650 DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11651 switch_needed = _TRUE;
11652 goto exit;
11653 }
11654
11655 /* GC should use port0 for p2p ps */
11656 if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11657 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11658 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11659 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11660 ) {
11661 DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11662 switch_needed = _TRUE;
11663 goto exit;
11664 }
11665
11666 /* port1 linked, but port0 not linked */
11667 if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11668 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11669 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11670 ) {
11671 DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11672 switch_needed = _TRUE;
11673 goto exit;
11674 }
11675
11676 exit:
11677 #ifdef DBG_RUNTIME_PORT_SWITCH
11678 DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11679 #endif /* DBG_RUNTIME_PORT_SWITCH */
11680 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11681 #endif /* CONFIG_CONCURRENT_MODE */
11682 return switch_needed;
11683 }
11684
11685 /****************************************************************************
11686
11687 Following are the event callback functions
11688
11689 *****************************************************************************/
11690
11691 //for sta/adhoc mode
update_sta_info(_adapter * padapter,struct sta_info * psta)11692 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11693 {
11694 _irqL irqL;
11695 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11696 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11697 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11698
11699 //ERP
11700 VCS_update(padapter, psta);
11701
11702 #ifdef CONFIG_80211N_HT
11703 //HT
11704 if(pmlmepriv->htpriv.ht_option)
11705 {
11706 psta->htpriv.ht_option = _TRUE;
11707
11708 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11709
11710 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
11711
11712 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11713 psta->htpriv.sgi_20m = _TRUE;
11714
11715 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11716 psta->htpriv.sgi_40m = _TRUE;
11717
11718 psta->qos_option = _TRUE;
11719
11720 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11721 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11722 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11723
11724 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11725 }
11726 else
11727 #endif //CONFIG_80211N_HT
11728 {
11729 #ifdef CONFIG_80211N_HT
11730 psta->htpriv.ht_option = _FALSE;
11731
11732 psta->htpriv.ampdu_enable = _FALSE;
11733
11734 psta->htpriv.sgi_20m = _FALSE;
11735 psta->htpriv.sgi_40m = _FALSE;
11736 #endif //CONFIG_80211N_HT
11737 psta->qos_option = _FALSE;
11738
11739 }
11740
11741 #ifdef CONFIG_80211N_HT
11742 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11743
11744 psta->htpriv.agg_enable_bitmap = 0x0;//reset
11745 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
11746 #endif //CONFIG_80211N_HT
11747
11748 psta->bw_mode = pmlmeext->cur_bwmode;
11749
11750 //QoS
11751 if(pmlmepriv->qospriv.qos_option)
11752 psta->qos_option = _TRUE;
11753
11754 #ifdef CONFIG_80211AC_VHT
11755 _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11756 #endif //CONFIG_80211AC_VHT
11757
11758 update_ldpc_stbc_cap(psta);
11759
11760 _enter_critical_bh(&psta->lock, &irqL);
11761 psta->state = _FW_LINKED;
11762 _exit_critical_bh(&psta->lock, &irqL);
11763
11764 }
11765
rtw_mlmeext_disconnect(_adapter * padapter)11766 static void rtw_mlmeext_disconnect(_adapter *padapter)
11767 {
11768 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11769 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11770 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11771 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11772 u8 state_backup = (pmlmeinfo->state&0x03);
11773 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
11774 u8 E2500_ID[]= {0x20, 0xAA, 0x4B};
11775 u8 iot_flag = _FALSE;
11776
11777 //set_opmode_cmd(padapter, infra_client_with_mlme);
11778
11779 #if 1
11780 /*
11781 * For safety, prevent from keeping macid sleep.
11782 * If we can sure all power mode enter/leave are paired,
11783 * this check can be removed.
11784 * Lucas@20131113
11785 */
11786 /* wakeup macid after disconnect. */
11787 {
11788 struct sta_info *psta;
11789 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork));
11790 if (psta)
11791 rtw_hal_macid_wakeup(padapter, psta->mac_id);
11792 }
11793 #endif
11794
11795 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11796 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11797
11798 //set MSR to no link state -> infra. mode
11799 Set_MSR(padapter, _HW_STATE_STATION_);
11800
11801 //check if sta is ASIX peer and fix IOT issue if it is.
11802 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3))
11803 rtw_hal_set_hwreg(padapter,
11804 HW_VAR_ASIX_IOT,
11805 (u8 *)(&iot_flag));
11806 else if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,E2500_ID ,3))
11807 rtw_hal_set_hwreg(padapter,
11808 HW_VAR_E2500_IOT,
11809 (u8 *)(&iot_flag));
11810
11811 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11812
11813 if(state_backup == WIFI_FW_STATION_STATE)
11814 {
11815 if (rtw_port_switch_chk(padapter) == _TRUE) {
11816 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11817 #ifdef CONFIG_LPS
11818 {
11819 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11820 if (port0_iface)
11821 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11822 }
11823 #endif
11824 }
11825 }
11826
11827 /* switch to the 20M Hz mode after disconnect */
11828 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11829 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11830
11831 #ifdef CONFIG_FCS_MODE
11832 if (EN_FCS(padapter))
11833 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11834 #endif
11835
11836 #ifdef CONFIG_DFS_MASTER
11837 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
11838 rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);
11839 else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
11840 rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED);
11841 #endif
11842
11843 {
11844 u8 ch, bw, offset;
11845
11846 if (rtw_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
11847 set_channel_bwmode(padapter, ch, offset, bw);
11848 }
11849
11850 flush_all_cam_entry(padapter);
11851
11852 _cancel_timer_ex(&pmlmeext->link_timer);
11853
11854 //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE;
11855 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11856 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11857
11858 #ifdef CONFIG_TDLS
11859 padapter->tdlsinfo.ap_prohibited = _FALSE;
11860
11861 /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11862 if (padapter->registrypriv.wifi_spec == 1)
11863 {
11864 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
11865 }
11866 #endif /* CONFIG_TDLS */
11867
11868 }
11869
mlmeext_joinbss_event_callback(_adapter * padapter,int join_res)11870 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
11871 {
11872 struct sta_info *psta, *psta_bmc;
11873 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11874 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11875 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
11876 struct sta_priv *pstapriv = &padapter->stapriv;
11877 u8 join_type;
11878 #ifdef CONFIG_ARP_KEEP_ALIVE
11879 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11880 #endif
11881
11882 if(join_res < 0)
11883 {
11884 join_type = 1;
11885 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11886 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11887
11888 goto exit_mlmeext_joinbss_event_callback;
11889 }
11890 #ifdef CONFIG_ARP_KEEP_ALIVE
11891 pmlmepriv->bGetGateway = 1;
11892 #endif
11893
11894 #ifdef CONFIG_ADHOC_MODE
11895 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11896 {
11897 //update bc/mc sta_info
11898 update_bmc_sta(padapter);
11899 }
11900 #endif
11901
11902
11903 //turn on dynamic functions
11904 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
11905
11906 // update IOT-releated issue
11907 update_IOT_info(padapter);
11908
11909 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
11910
11911 //BCN interval
11912 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
11913
11914 //udpate capability
11915 update_capinfo(padapter, pmlmeinfo->capability);
11916
11917 //WMM, Update EDCA param
11918 WMMOnAssocRsp(padapter);
11919
11920 //HT
11921 HTOnAssocRsp(padapter);
11922
11923 #ifdef CONFIG_80211AC_VHT
11924 //VHT
11925 VHTOnAssocRsp(padapter);
11926 #endif
11927
11928 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
11929 if (psta) //only for infra. mode
11930 {
11931 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
11932
11933 //DBG_871X("set_sta_rate\n");
11934
11935 psta->wireless_mode = pmlmeext->cur_wireless_mode;
11936
11937 //set per sta rate after updating HT cap.
11938 set_sta_rate(padapter, psta);
11939
11940 rtw_sta_media_status_rpt(padapter, psta, 1);
11941
11942 /* wakeup macid after join bss successfully to ensure
11943 the subsequent data frames can be sent out normally */
11944 rtw_hal_macid_wakeup(padapter, psta->mac_id);
11945 }
11946
11947 if (rtw_port_switch_chk(padapter) == _TRUE)
11948 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11949
11950 join_type = 2;
11951 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11952
11953 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11954 {
11955 // correcting TSF
11956 correct_TSF(padapter, pmlmeext);
11957
11958 //set_link_timer(pmlmeext, DISCONNECT_TO);
11959 }
11960
11961 #ifdef CONFIG_LPS
11962 if(get_iface_type(padapter) == IFACE_PORT0)
11963 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
11964 #endif
11965
11966 #ifdef CONFIG_BEAMFORMING
11967 if (psta)
11968 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
11969 #endif
11970
11971 exit_mlmeext_joinbss_event_callback:
11972
11973 rtw_join_done_chk_ch(padapter, join_res);
11974
11975 DBG_871X("=>%s - End to Connection without 4-way\n", __FUNCTION__);
11976 }
11977
11978
11979 //currently only adhoc mode will go here
mlmeext_sta_add_event_callback(_adapter * padapter,struct sta_info * psta)11980 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
11981 {
11982 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11983 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11984 u8 join_type;
11985
11986 DBG_871X("%s\n", __FUNCTION__);
11987
11988 #ifdef CONFIG_ADHOC_MODE
11989 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11990 {
11991 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
11992 {
11993 //nothing to do
11994 }
11995 else//adhoc client
11996 {
11997 //update TSF Value
11998 //update_TSF(pmlmeext, pframe, len);
11999
12000 // correcting TSF
12001 correct_TSF(padapter, pmlmeext);
12002
12003 //start beacon
12004 if(send_beacon(padapter)==_FAIL)
12005 {
12006 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
12007
12008 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
12009
12010 return;
12011 }
12012
12013 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12014
12015 }
12016
12017 join_type = 2;
12018 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12019 }
12020
12021 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
12022
12023 psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates);
12024 _rtw_memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen);
12025
12026 //update adhoc sta_info
12027 update_sta_info(padapter, psta);
12028
12029 rtw_hal_update_sta_rate_mask(padapter, psta);
12030
12031 // ToDo: HT for Ad-hoc
12032 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12033 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
12034
12035 //rate radaptive
12036 Update_RA_Entry(padapter, psta);
12037 #endif
12038 }
12039
mlmeext_sta_del_event_callback(_adapter * padapter)12040 void mlmeext_sta_del_event_callback(_adapter *padapter)
12041 {
12042 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12043 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12044
12045 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12046 {
12047 rtw_mlmeext_disconnect(padapter);
12048 }
12049
12050 }
12051
12052 /****************************************************************************
12053
12054 Following are the functions for the timer handlers
12055
12056 *****************************************************************************/
_linked_info_dump(_adapter * padapter)12057 void _linked_info_dump(_adapter *padapter)
12058 {
12059 int i;
12060 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12061 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12062 int UndecoratedSmoothedPWDB = 0;
12063 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
12064 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
12065
12066 if(padapter->bLinkInfoDump){
12067
12068 DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter));
12069
12070 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12071 {
12072 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
12073
12074 DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
12075 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB);
12076 }
12077 #ifdef CONFIG_AP_MODE
12078 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
12079 {
12080 _irqL irqL;
12081 _list *phead, *plist;
12082
12083 struct sta_info *psta=NULL;
12084 struct sta_priv *pstapriv = &padapter->stapriv;
12085
12086 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12087 phead = &pstapriv->asoc_list;
12088 plist = get_next(phead);
12089 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12090 {
12091 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
12092 plist = get_next(plist);
12093
12094 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n",
12095 MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB);
12096 }
12097 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12098
12099 }
12100 #endif /*CONFIG_AP_MODE*/
12101 for(i=0; i<macid_ctl->num; i++)
12102 {
12103 if(rtw_macid_is_used(macid_ctl, i)
12104 && !rtw_macid_is_bmc(macid_ctl, i) /* skip bc/mc sta */
12105 ) {
12106 //============ tx info ============
12107 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i);
12108 }
12109 }
12110 rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, NULL, _FALSE);
12111
12112 }
12113 }
rtw_delba_check(_adapter * padapter,struct sta_info * psta,u8 from_timer)12114 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12115 {
12116 int i = 0;
12117 int ret = _SUCCESS;
12118 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12119 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12120
12121 /*
12122 IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12123 AP is originator.AP does not transmit unicast packets when STA response its BAR.
12124 This case probably occur ap issue BAR after AP builds BA.
12125
12126 Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12127 The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12128 */
12129 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12130 for (i = 0; i < TID_NUM ; i++) {
12131 if (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) {
12132 if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12133 if (psta->recvreorder_ctrl[i].enable) {
12134 /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
12135 if (!from_timer)
12136 ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1);
12137 else
12138 issue_del_ba(padapter, psta->hwaddr, i, 39, 0);
12139 psta->recvreorder_ctrl[i].enable = _FALSE;
12140 if (ret != _FAIL)
12141 psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12142 rtw_reset_continual_no_rx_packet(psta, i);
12143 }
12144 }
12145 }
12146 else{
12147 /* The inactivity timer is reset when MPDUs to the TID is received. */
12148 rtw_reset_continual_no_rx_packet(psta, i);
12149 }
12150 }
12151 }
12152 }
12153
chk_ap_is_alive(_adapter * padapter,struct sta_info * psta)12154 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12155 {
12156 u8 ret = _FALSE;
12157 int i = 0;
12158 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12159 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12160
12161 #ifdef DBG_EXPIRATION_CHK
12162 DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12163 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12164 ", retry:%u\n"
12165 , FUNC_ADPT_ARG(padapter)
12166 , STA_RX_PKTS_DIFF_ARG(psta)
12167 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12168 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12169 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12170 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12171 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12172 , pmlmeinfo->bcn_interval*/
12173 , pmlmeext->retry
12174 );
12175
12176 DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12177 , padapter->xmitpriv.tx_pkts
12178 , pmlmeinfo->link_count
12179 );
12180 #endif
12181
12182 if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12183 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12184 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12185 )
12186 {
12187 ret = _FALSE;
12188 }
12189 else
12190 {
12191 ret = _TRUE;
12192 }
12193
12194 sta_update_last_rx_pkts(psta);
12195
12196 /*
12197 record last rx data packets for every tid.
12198 */
12199 for (i = 0; i < TID_NUM; i++)
12200 psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i];
12201
12202 return ret;
12203 }
12204
12205 #ifdef CONFIG_TDLS
chk_tdls_peer_sta_is_alive(_adapter * padapter,struct sta_info * psta)12206 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12207 {
12208 if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12209 && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12210 return _FALSE;
12211
12212 return _TRUE;
12213 }
12214
linked_status_chk_tdls(_adapter * padapter)12215 void linked_status_chk_tdls(_adapter *padapter)
12216 {
12217 struct candidate_pool{
12218 struct sta_info *psta;
12219 u8 addr[ETH_ALEN];
12220 };
12221 struct sta_priv *pstapriv = &padapter->stapriv;
12222 _irqL irqL;
12223 u8 ack_chk;
12224 struct sta_info *psta;
12225 int i, num_teardown=0, num_checkalive=0;
12226 _list *plist, *phead;
12227 struct tdls_txmgmt txmgmt;
12228 struct candidate_pool checkalive[NUM_STA];
12229 struct candidate_pool teardown[NUM_STA];
12230 #define ALIVE_MIN 2
12231 #define ALIVE_MAX 5
12232
12233 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12234 _rtw_memset(checkalive, 0x00, sizeof(checkalive));
12235 _rtw_memset(teardown, 0x00, sizeof(teardown));
12236
12237 if((padapter->tdlsinfo.link_established == _TRUE)){
12238 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12239 for(i=0; i< NUM_STA; i++)
12240 {
12241 phead = &(pstapriv->sta_hash[i]);
12242 plist = get_next(phead);
12243
12244 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12245 {
12246 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12247 plist = get_next(plist);
12248
12249 if(psta->tdls_sta_state & TDLS_LINKED_STATE)
12250 {
12251 psta->alive_count++;
12252 if(psta->alive_count >= ALIVE_MIN)
12253 {
12254 if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12255 if (psta->alive_count < ALIVE_MAX) {
12256 _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12257 checkalive[num_checkalive].psta = psta;
12258 num_checkalive++;
12259 }
12260 else
12261 {
12262 _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12263 teardown[num_teardown].psta = psta;
12264 num_teardown++;
12265 }
12266 }
12267 else
12268 {
12269 psta->alive_count = 0;
12270 }
12271 }
12272 psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12273 psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12274 }
12275 }
12276 }
12277 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12278
12279 if (num_checkalive > 0) {
12280 for (i = 0; i < num_checkalive; i++) {
12281 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12282 issue_tdls_dis_req(padapter, &txmgmt);
12283 issue_tdls_dis_req(padapter, &txmgmt);
12284 issue_tdls_dis_req(padapter, &txmgmt);
12285 }
12286 }
12287
12288 if(num_teardown > 0)
12289 {
12290 for(i=0; i< num_teardown; i++)
12291 {
12292 DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12293 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12294 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12295 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12296 }
12297 }
12298 }
12299
12300 }
12301 #endif //CONFIG_TDLS
12302
12303 //from_timer == 1 means driver is in LPS
linked_status_chk(_adapter * padapter,u8 from_timer)12304 void linked_status_chk(_adapter *padapter, u8 from_timer)
12305 {
12306 u32 i;
12307 struct sta_info *psta;
12308 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12309 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12310 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12311 struct sta_priv *pstapriv = &padapter->stapriv;
12312 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
12313 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12314
12315 if (is_client_associated_to_ap(padapter))
12316 {
12317 //linked infrastructure client mode
12318
12319 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12320 int rx_chk_limit;
12321 int link_count_limit;
12322
12323 #if defined(DBG_ROAMING_TEST)
12324 rx_chk_limit = 1;
12325 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12326 rx_chk_limit = 4;
12327 #else
12328 rx_chk_limit = 8;
12329 #endif
12330
12331 #ifdef CONFIG_ARP_KEEP_ALIVE
12332 if (!from_timer && pmlmepriv->bGetGateway == 1) {
12333 DBG_871X("do rtw_gw_addr_query()");
12334 if (rtw_gw_addr_query(padapter) == 0) {
12335 pmlmepriv->bGetGateway = 0;
12336 } else {
12337 _rtw_memset(pmlmepriv->gw_ip, 0, 4);
12338 _rtw_memset(pmlmepriv->gw_mac_addr, 0, 6);
12339 }
12340 }
12341 #endif
12342 #ifdef CONFIG_P2P
12343 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12344 {
12345 if(!from_timer)
12346 link_count_limit = 3; // 8 sec
12347 else
12348 link_count_limit = 15; // 32 sec
12349 }
12350 else
12351 #endif // CONFIG_P2P
12352 {
12353 if(!from_timer)
12354 link_count_limit = 7; // 16 sec
12355 else
12356 link_count_limit = 29; // 60 sec
12357 }
12358
12359 if (pwrpriv->disable_smart_ps)
12360 link_count_limit = 3; // 8 sec
12361 #ifdef CONFIG_TDLS
12362 #ifdef CONFIG_TDLS_CH_SW
12363 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12364 return;
12365 #endif /* CONFIG_TDLS_CH_SW */
12366
12367 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12368 linked_status_chk_tdls(padapter);
12369 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12370 #endif /* CONFIG_TDLS */
12371
12372 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12373 {
12374 bool is_p2p_enable = _FALSE;
12375 #ifdef CONFIG_P2P
12376 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12377 #endif
12378
12379 /*issue delba when ap does not tx data packet that is Broadcom ap */
12380 rtw_delba_check(padapter, psta, from_timer);
12381
12382 if (chk_ap_is_alive(padapter, psta) == _FALSE)
12383 rx_chk = _FAIL;
12384
12385 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12386 tx_chk = _FAIL;
12387
12388 #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12389 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
12390 u8 backup_oper_channel=0;
12391
12392 /* switch to correct channel of current network before issue keep-alive frames */
12393 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12394 backup_oper_channel = rtw_get_oper_ch(padapter);
12395 SelectChannel(padapter, pmlmeext->cur_channel);
12396 }
12397
12398 if (rx_chk != _SUCCESS)
12399 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12400
12401 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12402 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12403 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12404 if (tx_chk == _SUCCESS && !is_p2p_enable)
12405 rx_chk = _SUCCESS;
12406 }
12407
12408 /* back to the original operation channel */
12409 if(backup_oper_channel>0)
12410 SelectChannel(padapter, backup_oper_channel);
12411
12412 }
12413 else
12414 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12415 {
12416 if (rx_chk != _SUCCESS) {
12417 if (pmlmeext->retry == 0) {
12418 #ifdef DBG_EXPIRATION_CHK
12419 DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12420 #endif
12421 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12422 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12423 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12424 }
12425 }
12426
12427 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
12428 #ifdef DBG_EXPIRATION_CHK
12429 DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0);
12430 #endif
12431 tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0);
12432 }
12433 }
12434
12435 if (rx_chk == _FAIL) {
12436 pmlmeext->retry++;
12437 if (pmlmeext->retry > rx_chk_limit) {
12438 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
12439 FUNC_ADPT_ARG(padapter));
12440
12441 DBG_871X_LEVEL(_drv_always_, "%s: rx_chk_limit: %d\n",
12442 __func__, rx_chk_limit);
12443 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12444 , WLAN_REASON_EXPIRATION_CHK);
12445 return;
12446 }
12447 } else {
12448 pmlmeext->retry = 0;
12449 }
12450
12451 if (tx_chk == _FAIL) {
12452 pmlmeinfo->link_count %= (link_count_limit+1);
12453 } else {
12454 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12455 pmlmeinfo->link_count = 0;
12456 }
12457
12458 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12459
12460 }
12461 else if (is_client_associated_to_ibss(padapter))
12462 {
12463 //linked IBSS mode
12464 //for each assoc list entry to check the rx pkt counter
12465 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
12466 {
12467 if (pmlmeinfo->FW_sta_info[i].status == 1)
12468 {
12469 psta = pmlmeinfo->FW_sta_info[i].psta;
12470
12471 if(NULL==psta) continue;
12472
12473 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
12474 {
12475
12476 if(pmlmeinfo->FW_sta_info[i].retry<3)
12477 {
12478 pmlmeinfo->FW_sta_info[i].retry++;
12479 }
12480 else
12481 {
12482 pmlmeinfo->FW_sta_info[i].retry = 0;
12483 pmlmeinfo->FW_sta_info[i].status = 0;
12484 report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, _TRUE);
12485 }
12486 }
12487 else
12488 {
12489 pmlmeinfo->FW_sta_info[i].retry = 0;
12490 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
12491 }
12492 }
12493 }
12494
12495 //set_link_timer(pmlmeext, DISCONNECT_TO);
12496
12497 }
12498
12499 }
12500
survey_timer_hdl(_adapter * padapter)12501 void survey_timer_hdl(_adapter *padapter)
12502 {
12503 struct cmd_obj *cmd;
12504 struct sitesurvey_parm *psurveyPara;
12505 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12506 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12507 #ifdef CONFIG_P2P
12508 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12509 #endif
12510
12511 if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12512 cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12513 if (cmd == NULL) {
12514 rtw_warn_on(1);
12515 goto exit;
12516 }
12517
12518 psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12519 if (psurveyPara == NULL) {
12520 rtw_warn_on(1);
12521 rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12522 goto exit;
12523 }
12524
12525 init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12526 rtw_enqueue_cmd(pcmdpriv, cmd);
12527 }
12528
12529 exit:
12530 return;
12531 }
12532
link_timer_hdl(_adapter * padapter)12533 void link_timer_hdl(_adapter *padapter)
12534 {
12535 //static unsigned int rx_pkt = 0;
12536 //static u64 tx_cnt = 0;
12537 //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12538 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12539 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12540 //struct sta_priv *pstapriv = &padapter->stapriv;
12541
12542
12543 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
12544 {
12545 DBG_871X("link_timer_hdl:no beacon while connecting\n");
12546 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12547 report_join_res(padapter, -3);
12548 }
12549 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
12550 {
12551 //re-auth timer
12552 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
12553 {
12554 //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
12555 //{
12556 pmlmeinfo->state = 0;
12557 report_join_res(padapter, -1);
12558 return;
12559 //}
12560 //else
12561 //{
12562 // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
12563 // pmlmeinfo->reauth_count = 0;
12564 //}
12565 }
12566
12567 DBG_871X("link_timer_hdl: auth timeout and try again\n");
12568 pmlmeinfo->auth_seq = 1;
12569 issue_auth(padapter, NULL, 0);
12570 set_link_timer(pmlmeext, REAUTH_TO);
12571 }
12572 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
12573 {
12574 //re-assoc timer
12575 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
12576 {
12577 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12578 report_join_res(padapter, -2);
12579 return;
12580 }
12581
12582 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
12583 issue_assocreq(padapter);
12584 set_link_timer(pmlmeext, REASSOC_TO);
12585 }
12586 #if 0
12587 else if (is_client_associated_to_ap(padapter))
12588 {
12589 //linked infrastructure client mode
12590 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12591 {
12592 /*to monitor whether the AP is alive or not*/
12593 if (rx_pkt == psta->sta_stats.rx_pkts)
12594 {
12595 receive_disconnect(padapter, pmlmeinfo->network.MacAddress);
12596 return;
12597 }
12598 else
12599 {
12600 rx_pkt = psta->sta_stats.rx_pkts;
12601 set_link_timer(pmlmeext, DISCONNECT_TO);
12602 }
12603
12604 //update the EDCA paramter according to the Tx/RX mode
12605 update_EDCA_param(padapter);
12606
12607 /*to send the AP a nulldata if no frame is xmitted in order to keep alive*/
12608 if (pmlmeinfo->link_count++ == 0)
12609 {
12610 tx_cnt = pxmitpriv->tx_pkts;
12611 }
12612 else if ((pmlmeinfo->link_count & 0xf) == 0)
12613 {
12614 if (tx_cnt == pxmitpriv->tx_pkts)
12615 {
12616 issue_nulldata_in_interrupt(padapter, NULL, 0);
12617 }
12618
12619 tx_cnt = pxmitpriv->tx_pkts;
12620 }
12621 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12622 }
12623 else if (is_client_associated_to_ibss(padapter))
12624 {
12625 //linked IBSS mode
12626 //for each assoc list entry to check the rx pkt counter
12627 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
12628 {
12629 if (pmlmeinfo->FW_sta_info[i].status == 1)
12630 {
12631 psta = pmlmeinfo->FW_sta_info[i].psta;
12632
12633 if (pmlmeinfo->FW_sta_info[i].rx_pkt == psta->sta_stats.rx_pkts)
12634 {
12635 pmlmeinfo->FW_sta_info[i].status = 0;
12636 report_del_sta_event(padapter, psta->hwaddr);
12637 }
12638 else
12639 {
12640 pmlmeinfo->FW_sta_info[i].rx_pkt = psta->sta_stats.rx_pkts;
12641 }
12642 }
12643 }
12644
12645 set_link_timer(pmlmeext, DISCONNECT_TO);
12646 }
12647 #endif
12648
12649 return;
12650 }
12651
addba_timer_hdl(struct sta_info * psta)12652 void addba_timer_hdl(struct sta_info *psta)
12653 {
12654 #ifdef CONFIG_80211N_HT
12655 struct ht_priv *phtpriv;
12656
12657 if(!psta)
12658 return;
12659
12660 phtpriv = &psta->htpriv;
12661
12662 if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
12663 {
12664 if(phtpriv->candidate_tid_bitmap)
12665 phtpriv->candidate_tid_bitmap=0x0;
12666
12667 }
12668 #endif //CONFIG_80211N_HT
12669 }
12670
12671 #ifdef CONFIG_IEEE80211W
report_sta_timeout_event(_adapter * padapter,u8 * MacAddr,unsigned short reason)12672 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
12673 {
12674 struct cmd_obj *pcmd_obj;
12675 u8 *pevtcmd;
12676 u32 cmdsz;
12677 struct sta_info *psta;
12678 int mac_id;
12679 struct stadel_event *pdel_sta_evt;
12680 struct C2HEvent_Header *pc2h_evt_hdr;
12681 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12682 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12683
12684 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12685 if (pcmd_obj == NULL)
12686 return;
12687
12688 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
12689 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12690 if (pevtcmd == NULL) {
12691 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12692 return;
12693 }
12694
12695 _rtw_init_listhead(&pcmd_obj->list);
12696
12697 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
12698 pcmd_obj->cmdsz = cmdsz;
12699 pcmd_obj->parmbuf = pevtcmd;
12700
12701 pcmd_obj->rsp = NULL;
12702 pcmd_obj->rspsz = 0;
12703
12704 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
12705 pc2h_evt_hdr->len = sizeof(struct stadel_event);
12706 pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
12707 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12708
12709 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
12710 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12711 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12712
12713
12714 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12715 if (psta)
12716 mac_id = (int)psta->mac_id;
12717 else
12718 mac_id = (-1);
12719
12720 pdel_sta_evt->mac_id = mac_id;
12721
12722 DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
12723
12724 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12725
12726 return;
12727 }
12728
clnt_sa_query_timeout(_adapter * padapter)12729 void clnt_sa_query_timeout(_adapter *padapter)
12730 {
12731
12732 rtw_disassoc_cmd(padapter, 0, _TRUE);
12733 rtw_indicate_disconnect(padapter);
12734 rtw_free_assoc_resources(padapter, 1);
12735
12736 DBG_871X("SA query timeout client disconnect\n");
12737 }
12738
sa_query_timer_hdl(struct sta_info * psta)12739 void sa_query_timer_hdl(struct sta_info *psta)
12740 {
12741 _adapter *padapter = psta->padapter;
12742 _irqL irqL;
12743 struct sta_priv *pstapriv = &padapter->stapriv;
12744 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12745
12746 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
12747 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12748 clnt_sa_query_timeout(padapter);
12749 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
12750 report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID);
12751 }
12752
12753 #endif //CONFIG_IEEE80211W
12754
NULL_hdl(_adapter * padapter,u8 * pbuf)12755 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
12756 {
12757 return H2C_SUCCESS;
12758 }
12759
12760 #ifdef CONFIG_AUTO_AP_MODE
rtw_start_auto_ap(_adapter * adapter)12761 void rtw_start_auto_ap(_adapter *adapter)
12762 {
12763 DBG_871X("%s\n", __FUNCTION__);
12764
12765 rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
12766
12767 rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE);
12768 }
12769
rtw_auto_ap_start_beacon(_adapter * adapter)12770 static int rtw_auto_ap_start_beacon(_adapter *adapter)
12771 {
12772 int ret=0;
12773 u8 *pbuf = NULL;
12774 uint len;
12775 u8 supportRate[16];
12776 int sz = 0, rateLen;
12777 u8 * ie;
12778 u8 wireless_mode, oper_channel;
12779 u8 ssid[3] = {0}; //hidden ssid
12780 u32 ssid_len = sizeof(ssid);
12781 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
12782
12783
12784 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
12785 return -EINVAL;
12786
12787
12788 len = 128;
12789 pbuf = rtw_zmalloc(len);
12790 if(!pbuf)
12791 return -ENOMEM;
12792
12793
12794 //generate beacon
12795 ie = pbuf;
12796
12797 //timestamp will be inserted by hardware
12798 sz += 8;
12799 ie += sz;
12800
12801 //beacon interval : 2bytes
12802 *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
12803 sz += 2;
12804 ie += 2;
12805
12806 //capability info
12807 *(u16*)ie = 0;
12808 *(u16*)ie |= cpu_to_le16(cap_ESS);
12809 *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
12810 //*(u16*)ie |= cpu_to_le16(cap_Privacy);
12811 sz += 2;
12812 ie += 2;
12813
12814 //SSID
12815 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
12816
12817 //supported rates
12818 wireless_mode = WIRELESS_11BG_24N;
12819 rtw_set_supported_rate(supportRate, wireless_mode) ;
12820 rateLen = rtw_get_rateset_len(supportRate);
12821 if (rateLen > 8)
12822 {
12823 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
12824 }
12825 else
12826 {
12827 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
12828 }
12829
12830
12831 //DS parameter set
12832 if(check_buddy_fwstate(adapter, _FW_LINKED) &&
12833 check_buddy_fwstate(adapter, WIFI_STATION_STATE))
12834 {
12835 PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
12836 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
12837
12838 oper_channel = pbuddy_mlmeext->cur_channel;
12839 }
12840 else
12841 {
12842 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
12843 }
12844 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
12845
12846 //ext supported rates
12847 if (rateLen > 8)
12848 {
12849 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
12850 }
12851
12852 DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
12853
12854 //lunch ap mode & start to issue beacon
12855 if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS)
12856 {
12857
12858 }
12859 else
12860 {
12861 ret = -EINVAL;
12862 }
12863
12864
12865 rtw_mfree(pbuf, len);
12866
12867 return ret;
12868
12869 }
12870 #endif//CONFIG_AUTO_AP_MODE
12871
setopmode_hdl(_adapter * padapter,u8 * pbuf)12872 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
12873 {
12874 u8 type;
12875 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12876 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12877 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
12878
12879 if(psetop->mode == Ndis802_11APMode)
12880 {
12881 pmlmeinfo->state = WIFI_FW_AP_STATE;
12882 type = _HW_STATE_AP_;
12883 #ifdef CONFIG_NATIVEAP_MLME
12884 //start_ap_mode(padapter);
12885 #endif
12886 }
12887 else if(psetop->mode == Ndis802_11Infrastructure)
12888 {
12889 pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
12890 pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE
12891 type = _HW_STATE_STATION_;
12892 }
12893 else if(psetop->mode == Ndis802_11IBSS)
12894 {
12895 type = _HW_STATE_ADHOC_;
12896 } else if (psetop->mode == Ndis802_11Monitor) {
12897 type = _HW_STATE_MONITOR_;
12898 }
12899 else
12900 {
12901 type = _HW_STATE_NOLINK_;
12902 }
12903
12904 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
12905 //Set_NETYPE0_MSR(padapter, type);
12906
12907
12908 #ifdef CONFIG_AUTO_AP_MODE
12909 if(psetop->mode == Ndis802_11APMode)
12910 rtw_auto_ap_start_beacon(padapter);
12911 #endif
12912
12913 if (rtw_port_switch_chk(padapter) == _TRUE)
12914 {
12915 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12916
12917 if(psetop->mode == Ndis802_11APMode)
12918 adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages
12919 else if (psetop->mode == Ndis802_11Infrastructure) {
12920 #ifdef CONFIG_LPS
12921 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12922 if (port0_iface)
12923 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
12924 #endif
12925 }
12926 }
12927
12928 #ifdef CONFIG_BT_COEXIST
12929 if (psetop->mode == Ndis802_11APMode)
12930 {
12931 // Do this after port switch to
12932 // prevent from downloading rsvd page to wrong port
12933 rtw_btcoex_MediaStatusNotify(padapter, 1); //connect
12934 }
12935 #endif // CONFIG_BT_COEXIST
12936
12937 return H2C_SUCCESS;
12938
12939 }
12940
createbss_hdl(_adapter * padapter,u8 * pbuf)12941 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
12942 {
12943 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12944 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12945 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
12946 WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network;
12947 struct createbss_parm *parm = (struct createbss_parm *)pbuf;
12948 u8 ret = H2C_SUCCESS;
12949 //u8 initialgain;
12950
12951 #ifdef CONFIG_AP_MODE
12952 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
12953 start_bss_network(padapter, parm);
12954 goto exit;
12955 }
12956 #endif
12957
12958 #ifdef CONFIG_ADHOC_MODE
12959 /* below is for ad-hoc master */
12960 if (parm->adhoc) {
12961 rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
12962 rtw_joinbss_reset(padapter);
12963
12964 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12965 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12966 pmlmeinfo->ERP_enable = 0;
12967 pmlmeinfo->WMM_enable = 0;
12968 pmlmeinfo->HT_enable = 0;
12969 pmlmeinfo->HT_caps_enable = 0;
12970 pmlmeinfo->HT_info_enable = 0;
12971 pmlmeinfo->agg_enable_bitmap = 0;
12972 pmlmeinfo->candidate_tid_bitmap = 0;
12973
12974 //config the initial gain under linking, need to write the BB registers
12975 //initialgain = 0x1E;
12976 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
12977
12978 //disable dynamic functions, such as high power, DIG
12979 rtw_phydm_ability_backup(padapter);
12980 rtw_phydm_func_disable_all(padapter);
12981
12982 //cancel link timer
12983 _cancel_timer_ex(&pmlmeext->link_timer);
12984
12985 //clear CAM
12986 flush_all_cam_entry(padapter);
12987
12988 pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
12989 _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
12990 pnetwork->IELength = pdev_network->IELength;
12991
12992 if (pnetwork->IELength > MAX_IE_SZ) {
12993 ret = H2C_PARAMETERS_ERROR;
12994 goto ibss_post_hdl;
12995 }
12996
12997 _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
12998 start_create_ibss(padapter);
12999 } else
13000 #endif /*CONFIG_ADHOC_MODE*/
13001 {
13002 rtw_warn_on(1);
13003 ret = H2C_PARAMETERS_ERROR;
13004 }
13005
13006 ibss_post_hdl:
13007 rtw_create_ibss_post_hdl(padapter, ret);
13008
13009 exit:
13010 return ret;
13011 }
13012
13013 #ifdef CONFIG_IOCTL_CFG80211
rtw_set_wpa_version(struct security_priv * psecuritypriv,u32 wpa_version)13014 static int rtw_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
13015 {
13016 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
13017
13018 if (!wpa_version) {
13019 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
13020 return 0;
13021 }
13022
13023
13024 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
13025 {
13026 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
13027 }
13028
13029 /*
13030 if (wpa_version & NL80211_WPA_VERSION_2)
13031 {
13032 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
13033 }
13034 */
13035
13036 #ifdef CONFIG_WAPI_SUPPORT
13037 if (wpa_version & NL80211_WAPI_VERSION_1)
13038 {
13039 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
13040 }
13041 #endif
13042
13043 return 0;
13044
13045 }
13046
rtw_set_auth_type(struct security_priv * psecuritypriv,enum nl80211_auth_type sme_auth_type)13047 static int rtw_set_auth_type(struct security_priv *psecuritypriv,
13048 enum nl80211_auth_type sme_auth_type)
13049 {
13050 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
13051
13052
13053 switch (sme_auth_type) {
13054 case NL80211_AUTHTYPE_AUTOMATIC:
13055
13056 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
13057
13058 break;
13059 case NL80211_AUTHTYPE_OPEN_SYSTEM:
13060
13061 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
13062
13063 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
13064 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
13065
13066 #ifdef CONFIG_WAPI_SUPPORT
13067 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
13068 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
13069 #endif
13070
13071 break;
13072 case NL80211_AUTHTYPE_SHARED_KEY:
13073
13074 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
13075
13076 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
13077
13078
13079 break;
13080 default:
13081 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
13082 //return -ENOTSUPP;
13083 }
13084
13085 return 0;
13086
13087 }
13088
rtw_set_cipher(struct security_priv * psecuritypriv,u32 cipher,bool ucast)13089 static int rtw_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
13090 {
13091 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
13092
13093 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
13094 &psecuritypriv->dot118021XGrpPrivacy;
13095
13096 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
13097
13098
13099 if (!cipher) {
13100 *profile_cipher = _NO_PRIVACY_;
13101 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
13102 return 0;
13103 }
13104
13105 switch (cipher) {
13106 case IW_AUTH_CIPHER_NONE:
13107 *profile_cipher = _NO_PRIVACY_;
13108 ndisencryptstatus = Ndis802_11EncryptionDisabled;
13109 #ifdef CONFIG_WAPI_SUPPORT
13110 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
13111 {
13112 *profile_cipher = _SMS4_;
13113 }
13114 #endif
13115 break;
13116 case WLAN_CIPHER_SUITE_WEP40:
13117 *profile_cipher = _WEP40_;
13118 ndisencryptstatus = Ndis802_11Encryption1Enabled;
13119 break;
13120 case WLAN_CIPHER_SUITE_WEP104:
13121 *profile_cipher = _WEP104_;
13122 ndisencryptstatus = Ndis802_11Encryption1Enabled;
13123 break;
13124 case WLAN_CIPHER_SUITE_TKIP:
13125 *profile_cipher = _TKIP_;
13126 ndisencryptstatus = Ndis802_11Encryption2Enabled;
13127 break;
13128 case WLAN_CIPHER_SUITE_CCMP:
13129 *profile_cipher = _AES_;
13130 ndisencryptstatus = Ndis802_11Encryption3Enabled;
13131 break;
13132 #ifdef CONFIG_WAPI_SUPPORT
13133 case WLAN_CIPHER_SUITE_SMS4:
13134 *profile_cipher = _SMS4_;
13135 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
13136 break;
13137 #endif
13138 default:
13139 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
13140 return -ENOTSUPP;
13141 }
13142
13143 if(ucast)
13144 {
13145 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
13146
13147 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
13148 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
13149 }
13150
13151 return 0;
13152 }
13153
rtw_set_key_mgt(struct security_priv * psecuritypriv,u32 key_mgt)13154 static int rtw_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
13155 {
13156 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
13157
13158 if (key_mgt == WLAN_AKM_SUITE_8021X)
13159 //*auth_type = UMAC_AUTH_TYPE_8021X;
13160 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
13161 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
13162 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
13163 }
13164 #ifdef CONFIG_WAPI_SUPPORT
13165 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
13166 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
13167 }
13168 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
13169 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
13170 }
13171 #endif
13172 else {
13173 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
13174 //return -EINVAL;
13175 }
13176
13177 return 0;
13178 }
13179
rtw_set_wpa_ie(_adapter * padapter,u8 * pie,size_t ielen)13180 static int rtw_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
13181 {
13182 u8 *buf=NULL, *pos=NULL;
13183 u32 left;
13184 int group_cipher = 0, pairwise_cipher = 0;
13185 int ret = 0;
13186 int wpa_ielen=0;
13187 int wpa2_ielen=0;
13188 u8 *pwpa, *pwpa2;
13189 u8 null_addr[]= {0,0,0,0,0,0};
13190
13191 if (pie == NULL || !ielen) {
13192 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
13193 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
13194 goto exit;
13195 }
13196
13197 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
13198 ret = -EINVAL;
13199 goto exit;
13200 }
13201
13202 buf = rtw_zmalloc(ielen);
13203 if (buf == NULL){
13204 ret = -ENOMEM;
13205 goto exit;
13206 }
13207
13208 _rtw_memcpy(buf, pie , ielen);
13209
13210 //dump
13211 {
13212 int i;
13213 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
13214 for(i=0;i<ielen;i=i+8)
13215 DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7]);
13216 }
13217
13218 pos = buf;
13219 if(ielen < RSN_HEADER_LEN){
13220 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
13221 ret = -1;
13222 goto exit;
13223 }
13224
13225 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
13226 if(pwpa && wpa_ielen>0)
13227 {
13228 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
13229 {
13230 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
13231 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
13232 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
13233
13234 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
13235 }
13236 }
13237
13238 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
13239 if(pwpa2 && wpa2_ielen>0)
13240 {
13241 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
13242 {
13243 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
13244 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
13245 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
13246
13247 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
13248 }
13249 }
13250
13251 if (group_cipher == 0)
13252 {
13253 group_cipher = WPA_CIPHER_NONE;
13254 }
13255 if (pairwise_cipher == 0)
13256 {
13257 pairwise_cipher = WPA_CIPHER_NONE;
13258 }
13259
13260 switch(group_cipher)
13261 {
13262 case WPA_CIPHER_NONE:
13263 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
13264 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
13265 break;
13266 case WPA_CIPHER_WEP40:
13267 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
13268 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13269 break;
13270 case WPA_CIPHER_TKIP:
13271 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
13272 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
13273 break;
13274 case WPA_CIPHER_CCMP:
13275 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
13276 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
13277 break;
13278 case WPA_CIPHER_WEP104:
13279 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
13280 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13281 break;
13282 }
13283
13284 switch(pairwise_cipher)
13285 {
13286 case WPA_CIPHER_NONE:
13287 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
13288 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
13289 break;
13290 case WPA_CIPHER_WEP40:
13291 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
13292 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13293 break;
13294 case WPA_CIPHER_TKIP:
13295 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
13296 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
13297 break;
13298 case WPA_CIPHER_CCMP:
13299 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
13300 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
13301 break;
13302 case WPA_CIPHER_WEP104:
13303 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
13304 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
13305 break;
13306 }
13307
13308 {/* handle wps_ie */
13309 uint wps_ielen;
13310 u8 *wps_ie;
13311
13312 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
13313 if (wps_ie && wps_ielen > 0) {
13314 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
13315 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
13316 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
13317 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
13318 } else {
13319 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
13320 }
13321 }
13322
13323 #ifdef CONFIG_P2P
13324 {//check p2p_ie for assoc req;
13325 uint p2p_ielen=0;
13326 u8 *p2p_ie;
13327 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13328
13329 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
13330 {
13331 #ifdef CONFIG_DEBUG_CFG80211
13332 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
13333 #endif
13334
13335 if(pmlmepriv->p2p_assoc_req_ie)
13336 {
13337 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
13338 pmlmepriv->p2p_assoc_req_ie_len = 0;
13339 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
13340 pmlmepriv->p2p_assoc_req_ie = NULL;
13341 }
13342
13343 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
13344 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
13345 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
13346 goto exit;
13347 }
13348 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
13349 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
13350 }
13351 }
13352 #endif //CONFIG_P2P
13353
13354 #ifdef CONFIG_WFD
13355 {//check wfd_ie for assoc req;
13356 uint wfd_ielen=0;
13357 u8 *wfd_ie;
13358 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13359
13360 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
13361 {
13362 #ifdef CONFIG_DEBUG_CFG80211
13363 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
13364 #endif
13365
13366 if(pmlmepriv->wfd_assoc_req_ie)
13367 {
13368 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
13369 pmlmepriv->wfd_assoc_req_ie_len = 0;
13370 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
13371 pmlmepriv->wfd_assoc_req_ie = NULL;
13372 }
13373
13374 pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
13375 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
13376 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
13377 goto exit;
13378 }
13379 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
13380 }
13381 }
13382 #endif //CONFIG_WFD
13383
13384 //TKIP and AES disallow multicast packets until installing group key
13385 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
13386 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
13387 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
13388 //WPS open need to enable multicast
13389 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
13390 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
13391
13392 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
13393 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
13394 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
13395
13396 exit:
13397 if (buf)
13398 rtw_mfree(buf, ielen);
13399 if (ret)
13400 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
13401 return ret;
13402 }
13403
start_connect_cmd_hdl(_adapter * padapter,u8 * pbuf)13404 u8 start_connect_cmd_hdl(_adapter *padapter, u8 *pbuf)
13405 {
13406 NDIS_802_11_SSID ndis_ssid;
13407 NDIS_802_11_AUTHENTICATION_MODE authmode;
13408 struct cfg80211_connect_params *params = NULL;
13409 struct security_priv *psecuritypriv = &padapter->securitypriv;
13410 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13411 int ret = 0;
13412
13413 params = (struct cfg80211_connect_params *)pbuf;
13414
13415 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
13416 rtw_scan_abort(padapter);
13417 }
13418 #ifdef CONFIG_CONCURRENT_MODE
13419 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
13420 rtw_scan_abort(padapter->pbuddy_adapter);
13421 }
13422 #endif
13423
13424 DBG_871X("%s ====>\n", __func__);
13425 DBG_871X("wpa_version: %d cipher group:%d\n",
13426 params->crypto.wpa_versions, params->crypto.cipher_group);
13427
13428 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
13429 ndis_ssid.SsidLength = params->ssid_len;
13430 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
13431
13432 DBG_871X("ssid=%s, len=%d\n",
13433 ndis_ssid.Ssid, ndis_ssid.SsidLength);
13434
13435 if (params->bssid)
13436 DBG_871X("bssid="MAC_FMT"\n", MAC_ARG(params->bssid));
13437
13438 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
13439 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
13440 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
13441 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
13442 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
13443
13444 #ifdef CONFIG_WAPI_SUPPORT
13445 padapter->wapiInfo.bWapiEnable = false;
13446 #endif
13447
13448 rtw_set_wpa_version(psecuritypriv, params->crypto.wpa_versions);
13449
13450 rtw_set_auth_type(psecuritypriv, params->auth_type);
13451
13452 #ifdef CONFIG_WAPI_SUPPORT
13453 if(params->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
13454 padapter->wapiInfo.bWapiEnable = true;
13455 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
13456 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
13457 }
13458
13459 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI) {
13460 padapter->mlmeextpriv.mlmext_info.auth_algo =
13461 psecuritypriv->dot11AuthAlgrthm;
13462 }
13463 #endif
13464
13465 DBG_871X("%s, ie_len=%zu\n", __func__, params->ie_len);
13466
13467 ret = rtw_set_wpa_ie(padapter, (u8 *)params->ie, params->ie_len);
13468 if (ret < 0) {
13469 DBG_871X("%s: set wpa ie fail\n", __func__);
13470 return H2C_PARAMETERS_ERROR;
13471 }
13472
13473 if (params->crypto.n_ciphers_pairwise) {
13474 ret = rtw_set_cipher(psecuritypriv,
13475 params->crypto.ciphers_pairwise[0],
13476 _TRUE);
13477 if (ret < 0) {
13478 DBG_871X("%s: set wpa cipher fail\n", __func__);
13479 return H2C_PARAMETERS_ERROR;
13480 }
13481 }
13482
13483 //For WEP Shared auth
13484 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared ||
13485 psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) &&
13486 params->key) {
13487 u32 wep_key_idx, wep_key_len,wep_total_len;
13488 NDIS_802_11_WEP *pwep = NULL;
13489 DBG_871X("%s(): Shared/Auto WEP\n", __func__);
13490
13491 wep_key_idx = params->key_idx;
13492 wep_key_len = params->key_len;
13493
13494 if (params->key_idx > WEP_KEYS) {
13495 DBG_871X("%s: incorrect WEP key id.\n", __func__);
13496 return H2C_PARAMETERS_ERROR;
13497 }
13498
13499 if (wep_key_len > 0) {
13500 wep_key_len = wep_key_len <= 5 ? 5 : 13;
13501 wep_total_len = wep_key_len +
13502 FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
13503 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
13504 if (pwep == NULL) {
13505 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
13506 return H2C_PARAMETERS_ERROR;
13507 }
13508
13509 _rtw_memset(pwep, 0, wep_total_len);
13510
13511 pwep->KeyLength = wep_key_len;
13512 pwep->Length = wep_total_len;
13513
13514 if (wep_key_len==13) {
13515 padapter->securitypriv.dot11PrivacyAlgrthm =
13516 _WEP104_;
13517 padapter->securitypriv.dot118021XGrpPrivacy =
13518 _WEP104_;
13519 }
13520 }
13521 else {
13522 DBG_871X("%s: incorrect key length\n", __func__);
13523 return H2C_PARAMETERS_ERROR;
13524 }
13525
13526 pwep->KeyIndex = wep_key_idx;
13527 pwep->KeyIndex |= 0x80000000;
13528
13529 _rtw_memcpy(pwep->KeyMaterial, (void *)params->key,
13530 pwep->KeyLength);
13531
13532 if(rtw_set_802_11_add_wep(padapter, pwep) == _FAIL) {
13533 DBG_871X("%s: add wep fail\n", __func__);
13534 return H2C_PARAMETERS_ERROR;
13535 }
13536
13537 if (pwep)
13538 rtw_mfree((u8 *)pwep, wep_total_len);
13539 }
13540
13541 rtw_set_cipher(psecuritypriv,
13542 params->crypto.cipher_group, _FALSE);
13543
13544 if (params->crypto.n_akm_suites) {
13545 ret = rtw_set_key_mgt(psecuritypriv,
13546 params->crypto.akm_suites[0]);
13547 if (ret < 0) {
13548 DBG_871X("%s: set key mgt fail\n", __func__);
13549 return H2C_PARAMETERS_ERROR;
13550 }
13551 }
13552
13553 #ifdef CONFIG_WAPI_SUPPORT
13554 if(params->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK) {
13555 padapter->wapiInfo.bWapiPSK = true;
13556 } else if (params->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT) {
13557 padapter->wapiInfo.bWapiPSK = false;
13558 }
13559 #endif
13560
13561 authmode = psecuritypriv->ndisauthtype;
13562 rtw_set_802_11_authentication_mode(padapter, authmode);
13563
13564 ret = rtw_set_802_11_connect(padapter, (u8 *)params->bssid, &ndis_ssid);
13565 if (ret == _FALSE) {
13566 DBG_871X("%s: set connect fail\n", __func__);
13567 return H2C_PARAMETERS_ERROR;
13568 }
13569
13570 DBG_871X("%s: set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n",
13571 __func__,psecuritypriv->dot11AuthAlgrthm,
13572 psecuritypriv->dot11PrivacyAlgrthm,
13573 psecuritypriv->dot118021XGrpPrivacy);
13574
13575 return H2C_SUCCESS;
13576 }
13577 #endif
13578
join_cmd_hdl(_adapter * padapter,u8 * pbuf)13579 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13580 {
13581 u8 join_type;
13582 PNDIS_802_11_VARIABLE_IEs pIE;
13583 struct registry_priv *pregpriv = &padapter->registrypriv;
13584 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13585 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13586 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13587 #ifdef CONFIG_ANTENNA_DIVERSITY
13588 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
13589 #endif //CONFIG_ANTENNA_DIVERSITY
13590 u32 i;
13591 //u8 initialgain;
13592 //u32 acparm;
13593 u8 u_ch, u_bw, u_offset;
13594
13595 //check already connecting to AP or not
13596 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
13597 {
13598 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13599 {
13600 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13601 }
13602 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13603
13604 //clear CAM
13605 flush_all_cam_entry(padapter);
13606
13607 _cancel_timer_ex(&pmlmeext->link_timer);
13608
13609 //set MSR to nolink -> infra. mode
13610 //Set_MSR(padapter, _HW_STATE_NOLINK_);
13611 Set_MSR(padapter, _HW_STATE_STATION_);
13612
13613
13614 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13615 }
13616
13617 #ifdef CONFIG_ANTENNA_DIVERSITY
13618 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13619 #endif
13620
13621 #ifdef CONFIG_WAPI_SUPPORT
13622 rtw_wapi_clear_all_cam_entry(padapter);
13623 #endif
13624
13625 rtw_joinbss_reset(padapter);
13626
13627 pmlmeinfo->ERP_enable = 0;
13628 pmlmeinfo->WMM_enable = 0;
13629 pmlmeinfo->HT_enable = 0;
13630 pmlmeinfo->HT_caps_enable = 0;
13631 pmlmeinfo->HT_info_enable = 0;
13632 pmlmeinfo->agg_enable_bitmap = 0;
13633 pmlmeinfo->candidate_tid_bitmap = 0;
13634 pmlmeinfo->bwmode_updated = _FALSE;
13635 //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
13636 pmlmeinfo->VHT_enable = 0;
13637
13638 _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13639 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13640
13641 if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
13642 return H2C_PARAMETERS_ERROR;
13643
13644 if (pnetwork->IELength < 2) {
13645 report_join_res(padapter, (-4));
13646 return H2C_SUCCESS;
13647 }
13648 _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
13649
13650 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13651
13652 //Check AP vendor to move rtw_joinbss_cmd()
13653 //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
13654
13655 //sizeof(NDIS_802_11_FIXED_IEs)
13656 for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13657 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13658
13659 switch (pIE->ElementID)
13660 {
13661 case _VENDOR_SPECIFIC_IE_://Get WMM IE.
13662 if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
13663 {
13664 WMM_param_handler(padapter, pIE);
13665 }
13666 break;
13667
13668 #ifdef CONFIG_80211N_HT
13669 case _HT_CAPABILITY_IE_: //Get HT Cap IE.
13670 pmlmeinfo->HT_caps_enable = 1;
13671 break;
13672
13673 case _HT_EXTRA_INFO_IE_: //Get HT Info IE.
13674 pmlmeinfo->HT_info_enable = 1;
13675 break;
13676 #endif /* CONFIG_80211N_HT */
13677
13678 #ifdef CONFIG_80211AC_VHT
13679 case EID_VHTCapability://Get VHT Cap IE.
13680 pmlmeinfo->VHT_enable = 1;
13681 break;
13682
13683 case EID_VHTOperation://Get VHT Operation IE.
13684 break;
13685 #endif /* CONFIG_80211AC_VHT */
13686 default:
13687 break;
13688 }
13689
13690 i += (pIE->Length + 2);
13691 }
13692
13693 rtw_bss_get_chbw(pnetwork
13694 , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13695
13696 rtw_regsty_adjust_chbw(pregpriv, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13697
13698 #if 0
13699 if (padapter->registrypriv.wifi_spec) {
13700 // for WiFi test, follow WMM test plan spec
13701 acparm = 0x002F431C; // VO
13702 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13703 acparm = 0x005E541C; // VI
13704 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13705 acparm = 0x0000A525; // BE
13706 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13707 acparm = 0x0000A549; // BK
13708 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13709
13710 // for WiFi test, mixed mode with intel STA under bg mode throughput issue
13711 if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
13712 acparm = 0x00004320;
13713 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13714 }
13715 }
13716 else {
13717 acparm = 0x002F3217; // VO
13718 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13719 acparm = 0x005E4317; // VI
13720 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13721 acparm = 0x00105320; // BE
13722 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13723 acparm = 0x0000A444; // BK
13724 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13725 }
13726 #endif
13727
13728 /* check channel, bandwidth, offset and switch */
13729 if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
13730 report_join_res(padapter, (-4));
13731 return H2C_SUCCESS;
13732 }
13733
13734 //disable dynamic functions, such as high power, DIG
13735 /*rtw_phydm_func_disable_all(padapter);*/
13736
13737 //config the initial gain under linking, need to write the BB registers
13738 //initialgain = 0x1E;
13739 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13740
13741 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
13742 join_type = 0;
13743 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13744 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
13745
13746 set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
13747
13748 //cancel link timer
13749 _cancel_timer_ex(&pmlmeext->link_timer);
13750
13751 start_clnt_join(padapter);
13752
13753 return H2C_SUCCESS;
13754
13755 }
13756
disconnect_hdl(_adapter * padapter,unsigned char * pbuf)13757 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
13758 {
13759 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
13760 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13761 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13762 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13763 u8 val8;
13764
13765 if (is_client_associated_to_ap(padapter))
13766 {
13767 #ifdef CONFIG_DFS
13768 if(padapter->mlmepriv.handle_dfs == _FALSE)
13769 #endif //CONFIG_DFS
13770 #ifdef CONFIG_PLATFORM_ROCKCHIPS
13771 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
13772 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13773 #else
13774 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
13775 #endif //CONFIG_PLATFORM_ROCKCHIPS
13776 }
13777
13778 #ifdef CONFIG_DFS
13779 if( padapter->mlmepriv.handle_dfs == _TRUE )
13780 padapter->mlmepriv.handle_dfs = _FALSE;
13781 #endif //CONFIG_DFS
13782
13783 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13784 {
13785 //Stop BCN
13786 val8 = 0;
13787 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13788 }
13789
13790 rtw_mlmeext_disconnect(padapter);
13791
13792 rtw_free_uc_swdec_pending_queue(padapter);
13793
13794 return H2C_SUCCESS;
13795 }
13796
13797 static const char * const _scan_state_str[] = {
13798 "SCAN_DISABLE",
13799 "SCAN_START",
13800 "SCAN_PS_ANNC_WAIT",
13801 "SCAN_ENTER",
13802 "SCAN_PROCESS",
13803 "SCAN_BACKING_OP",
13804 "SCAN_BACK_OP",
13805 "SCAN_LEAVING_OP",
13806 "SCAN_LEAVE_OP",
13807 "SCAN_SW_ANTDIV_BL",
13808 "SCAN_TO_P2P_LISTEN",
13809 "SCAN_P2P_LISTEN",
13810 "SCAN_COMPLETE",
13811 "SCAN_STATE_MAX",
13812 };
13813
scan_state_str(u8 state)13814 const char *scan_state_str(u8 state)
13815 {
13816 state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
13817 return _scan_state_str[state];
13818 }
13819
scan_abort_hdl(_adapter * adapter)13820 static bool scan_abort_hdl(_adapter *adapter)
13821 {
13822 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13823 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13824 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13825 #ifdef CONFIG_P2P
13826 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13827 #endif
13828 bool ret = _FALSE;
13829
13830 if (pmlmeext->scan_abort == _TRUE) {
13831 #ifdef CONFIG_P2P
13832 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
13833 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
13834 ss->channel_idx = 3;
13835 DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
13836 , ss->channel_idx
13837 , pwdinfo->find_phase_state_exchange_cnt
13838 );
13839 } else
13840 #endif
13841 {
13842 ss->channel_idx = ss->ch_num;
13843 DBG_871X("%s idx:%d\n", __FUNCTION__
13844 , ss->channel_idx
13845 );
13846 }
13847 pmlmeext->scan_abort = _FALSE;
13848 ret = _TRUE;
13849 }
13850
13851 return ret;
13852 }
13853
rtw_scan_sparse(_adapter * adapter,struct rtw_ieee80211_channel * ch,u8 ch_num)13854 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13855 {
13856 /* interval larger than this is treated as backgroud scan */
13857 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13858 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13859 #endif
13860
13861 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13862 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13863 #endif
13864 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13865 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13866 #endif
13867
13868 #define SCAN_SPARSE_CH_NUM_INVALID 255
13869
13870 static u8 token = 255;
13871 u32 interval;
13872 bool busy_traffic = _FALSE;
13873 bool miracast_enabled = _FALSE;
13874 bool bg_scan = _FALSE;
13875 u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13876 u8 scan_division_num;
13877 u8 ret_num = ch_num;
13878 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13879 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13880
13881 if (regsty->wifi_spec)
13882 goto exit;
13883
13884 /* assume ch_num > 6 is normal scan */
13885 if (ch_num <= 6)
13886 goto exit;
13887
13888 if (mlmeext->last_scan_time == 0)
13889 mlmeext->last_scan_time = rtw_get_current_time();
13890
13891 interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13892
13893 if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE
13894 #ifdef CONFIG_CONCURRENT_MODE
13895 || (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
13896 #endif
13897 )
13898 busy_traffic = _TRUE;
13899
13900 #ifdef CONFIG_WFD
13901 if (is_miracast_enabled(adapter->wfd_info.stack_wfd_mode)
13902 #ifdef CONFIG_CONCURRENT_MODE
13903 || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter->wfd_info.stack_wfd_mode))
13904 #endif
13905 )
13906 miracast_enabled = _TRUE;
13907 #endif
13908
13909 if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13910 bg_scan = _TRUE;
13911
13912 /* max_allow_ch by conditions*/
13913
13914 #if RTW_SCAN_SPARSE_MIRACAST
13915 if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13916 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13917 #endif
13918
13919 #if RTW_SCAN_SPARSE_BG
13920 if (bg_scan == _TRUE)
13921 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13922 #endif
13923
13924
13925 if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13926 int i;
13927 int k = 0;
13928
13929 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0);
13930 token = (token + 1) % scan_division_num;
13931
13932 if (0)
13933 DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token);
13934
13935 for (i = 0; i < ch_num; i++) {
13936 if (ch[i].hw_value && (i % scan_division_num) == token
13937 ) {
13938 if (i != k)
13939 _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13940 k++;
13941 }
13942 }
13943
13944 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13945
13946 ret_num = k;
13947 mlmeext->last_scan_time = rtw_get_current_time();
13948 }
13949
13950 exit:
13951 return ret_num;
13952 }
13953
rtw_scan_ch_decision(_adapter * padapter,struct rtw_ieee80211_channel * out,u32 out_num,struct rtw_ieee80211_channel * in,u32 in_num)13954 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13955 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13956 {
13957 int i, j;
13958 int scan_ch_num = 0;
13959 int set_idx;
13960 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13961
13962 /* clear first */
13963 _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
13964
13965 /* acquire channels from in */
13966 j = 0;
13967 for (i=0;i<in_num;i++) {
13968
13969 if (0)
13970 DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13971
13972 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
13973 && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
13974 && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE
13975 )
13976 {
13977 if (j >= out_num) {
13978 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13979 FUNC_ADPT_ARG(padapter), out_num);
13980 break;
13981 }
13982
13983 _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13984
13985 if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13986 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13987
13988 j++;
13989 }
13990 if(j>=out_num)
13991 break;
13992 }
13993
13994 /* if out is empty, use channel_set as default */
13995 if(j == 0) {
13996 for (i=0;i<pmlmeext->max_chan_nums;i++) {
13997
13998 if (0)
13999 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
14000
14001 if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) {
14002
14003 if (j >= out_num) {
14004 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
14005 FUNC_ADPT_ARG(padapter), out_num);
14006 break;
14007 }
14008
14009 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
14010
14011 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
14012 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14013
14014 j++;
14015 }
14016 }
14017 }
14018
14019 /* scan_sparse */
14020 j = rtw_scan_sparse(padapter, out, j);
14021
14022 return j;
14023 }
14024
sitesurvey_res_reset(_adapter * adapter,struct sitesurvey_parm * parm)14025 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
14026 {
14027 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
14028 int i;
14029
14030 ss->bss_cnt = 0;
14031 ss->channel_idx = 0;
14032 #ifdef CONFIG_SCAN_BACKOP
14033 ss->scan_cnt = 0;
14034 #endif
14035 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14036 ss->is_sw_antdiv_bl_scan = 0;
14037 #endif
14038
14039 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14040 if (parm->ssid[i].SsidLength) {
14041 _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
14042 ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
14043 } else {
14044 ss->ssid[i].SsidLength = 0;
14045 }
14046 }
14047
14048 ss->ch_num = rtw_scan_ch_decision(adapter
14049 , ss->ch, RTW_CHANNEL_SCAN_AMOUNT
14050 , parm->ch, parm->ch_num
14051 );
14052
14053 ss->scan_mode = parm->scan_mode;
14054 }
14055
sitesurvey_pick_ch_behavior(_adapter * padapter,u8 * ch,RT_SCAN_TYPE * type)14056 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
14057 {
14058 u8 next_state;
14059 u8 scan_ch = 0;
14060 RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
14061 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14062 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
14063 struct ss_res *ss = &pmlmeext->sitesurvey_res;
14064
14065 #ifdef CONFIG_P2P
14066 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14067 #endif
14068
14069 /* handle scan abort request */
14070 scan_abort_hdl(padapter);
14071
14072 #ifdef CONFIG_P2P
14073 if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
14074 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
14075 scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
14076 else
14077 scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
14078 scan_type = SCAN_ACTIVE;
14079 } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
14080 /*
14081 * Commented by Albert 2011/06/03
14082 * The driver is in the find phase, it should go through the social channel.
14083 */
14084 int ch_set_idx;
14085
14086 scan_ch = pwdinfo->social_chan[ss->channel_idx];
14087 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch);
14088 if (ch_set_idx >= 0)
14089 scan_type = pmlmeext->channel_set[ch_set_idx].ScanType;
14090 else
14091 scan_type = SCAN_ACTIVE;
14092 } else
14093 #endif /* CONFIG_P2P */
14094 {
14095 struct rtw_ieee80211_channel *ch;
14096
14097 if (ss->channel_idx < ss->ch_num) {
14098 ch = &ss->ch[ss->channel_idx];
14099 scan_ch = ch->hw_value;
14100 scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
14101 }
14102 }
14103
14104 if (scan_ch != 0) {
14105 next_state = SCAN_PROCESS;
14106 #ifdef CONFIG_SCAN_BACKOP
14107 {
14108 u8 sta_num;
14109 u8 ld_sta_num;
14110 u8 ap_num;
14111 u8 ld_ap_num;
14112 u8 backop_flags = 0;
14113
14114 rtw_dev_iface_status(padapter, &sta_num, &ld_sta_num, NULL, &ap_num, &ld_ap_num);
14115
14116 if ((ld_sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN))
14117 || (sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL))
14118 ) {
14119 backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext);
14120 }
14121
14122 if ((ld_ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN))
14123 || (ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL))
14124 ) {
14125 backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext);
14126 }
14127
14128 if (backop_flags) {
14129 if (ss->scan_cnt < ss->scan_cnt_max) {
14130 ss->scan_cnt++;
14131 } else {
14132 mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
14133 next_state = SCAN_BACKING_OP;
14134 }
14135 }
14136 }
14137 #endif /* CONFIG_SCAN_BACKOP */
14138 #ifdef CONFIG_P2P
14139 } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
14140 /* go p2p listen */
14141 next_state = SCAN_TO_P2P_LISTEN;
14142 #endif
14143 #ifdef CONFIG_ANTENNA_DIVERSITY
14144 } else if (rtw_hal_antdiv_before_linked(padapter)) {
14145 /* go sw antdiv before link */
14146 next_state = SCAN_SW_ANTDIV_BL;
14147 #endif
14148 } else {
14149 next_state = SCAN_COMPLETE;
14150
14151 #if defined(DBG_SCAN_SW_ANTDIV_BL)
14152 {
14153 /* for SCAN_SW_ANTDIV_BL state testing */
14154 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14155 int i;
14156 bool is_linked = _FALSE;
14157
14158 for (i = 0; i < dvobj->iface_nums; i++) {
14159 if (rtw_linked_check(dvobj->padapters[i]))
14160 is_linked = _TRUE;
14161 }
14162
14163 if (!is_linked) {
14164 static bool fake_sw_antdiv_bl_state = 0;
14165
14166 if (fake_sw_antdiv_bl_state == 0) {
14167 next_state = SCAN_SW_ANTDIV_BL;
14168 fake_sw_antdiv_bl_state = 1;
14169 } else {
14170 fake_sw_antdiv_bl_state = 0;
14171 }
14172 }
14173 }
14174 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
14175 }
14176
14177 #ifdef CONFIG_SCAN_BACKOP
14178 if (next_state != SCAN_PROCESS)
14179 ss->scan_cnt = 0;
14180 #endif
14181
14182
14183 #ifdef DBG_FIXED_CHAN
14184 if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
14185 scan_ch = pmlmeext->fixed_chan;
14186 #endif
14187
14188 if (ch)
14189 *ch = scan_ch;
14190 if (type)
14191 *type = scan_type;
14192
14193 return next_state;
14194 }
14195
site_survey(_adapter * padapter,u8 survey_channel,RT_SCAN_TYPE ScanType)14196 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
14197 {
14198 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14199 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14200
14201 #ifdef CONFIG_P2P
14202 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
14203 #endif
14204
14205 if (survey_channel != 0) {
14206 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14207
14208 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14209 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
14210 ACS_OP acs_op = ACS_RESET;
14211
14212 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
14213 rtw_set_acs_channel(padapter, survey_channel);
14214 #ifdef DBG_AUTO_CHNL_SEL_NHM
14215 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n",
14216 ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
14217 #endif
14218 }
14219 #endif
14220
14221 if (ScanType == SCAN_ACTIVE) {
14222 #ifdef CONFIG_P2P
14223 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
14224 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14225 ) {
14226 issue_probereq_p2p(padapter, NULL);
14227 issue_probereq_p2p(padapter, NULL);
14228 issue_probereq_p2p(padapter, NULL);
14229 } else
14230 #endif /* CONFIG_P2P */
14231 {
14232 int i;
14233
14234 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14235 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
14236 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14237 if (padapter->registrypriv.wifi_spec)
14238 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
14239 else
14240 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
14241 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
14242 }
14243 }
14244
14245 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
14246 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14247 if (padapter->registrypriv.wifi_spec)
14248 issue_probereq(padapter, NULL, NULL);
14249 else
14250 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
14251 issue_probereq(padapter, NULL, NULL);
14252 }
14253 }
14254 }
14255 } else {
14256 /* channel number is 0 or this channel is not valid. */
14257 rtw_warn_on(1);
14258 }
14259
14260 return;
14261 }
14262
survey_done_set_ch_bw(_adapter * padapter)14263 void survey_done_set_ch_bw(_adapter *padapter)
14264 {
14265 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14266 u8 cur_channel = 0;
14267 u8 cur_bwmode;
14268 u8 cur_ch_offset;
14269
14270 if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
14271 if (0)
14272 DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
14273 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14274 } else {
14275 #ifdef CONFIG_P2P
14276 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14277 _adapter *iface;
14278 int i;
14279
14280 for (i = 0; i < dvobj->iface_nums; i++) {
14281 iface = dvobj->padapters[i];
14282 if (!iface)
14283 continue;
14284
14285 #ifdef CONFIG_IOCTL_CFG80211
14286 if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
14287 continue;
14288 #endif
14289
14290 if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
14291 cur_channel = iface->wdinfo.listen_channel;
14292 cur_bwmode = CHANNEL_WIDTH_20;
14293 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14294 if (0)
14295 DBG_871X(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
14296 FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
14297 break;
14298 }
14299 }
14300 #endif /* CONFIG_P2P */
14301
14302 if (cur_channel == 0) {
14303 cur_channel = pmlmeext->cur_channel;
14304 cur_bwmode = pmlmeext->cur_bwmode;
14305 cur_ch_offset = pmlmeext->cur_ch_offset;
14306 if (0)
14307 DBG_871X(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
14308 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14309 }
14310 }
14311
14312 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
14313 }
14314
14315 /**
14316 * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
14317 * @dvobj: the dvobj to check
14318 * @ps: power saving or not
14319 *
14320 * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
14321 */
sitesurvey_ps_annc(struct dvobj_priv * dvobj,bool ps)14322 u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps)
14323 {
14324 _adapter *adapter;
14325 int i;
14326 u8 ps_anc = 0;
14327
14328 for (i = 0; i < dvobj->iface_nums; i++) {
14329 adapter = dvobj->padapters[i];
14330 if (!adapter)
14331 continue;
14332
14333 if (ps) {
14334 if (is_client_associated_to_ap(adapter) == _TRUE) {
14335 /* TODO: TDLS peers */
14336 issue_nulldata(adapter, NULL, 1, 3, 500);
14337 ps_anc = 1;
14338 }
14339 } else {
14340 if (is_client_associated_to_ap(adapter) == _TRUE) {
14341 /* TODO: TDLS peers */
14342 issue_nulldata(adapter, NULL, 0, 3, 500);
14343 ps_anc = 1;
14344 }
14345 }
14346 }
14347
14348 return ps_anc;
14349 }
14350
sitesurvey_set_igi(_adapter * adapter,bool enter)14351 void sitesurvey_set_igi(_adapter *adapter, bool enter)
14352 {
14353 u8 igi;
14354 #ifdef CONFIG_P2P
14355 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
14356 #endif
14357
14358 if (enter) {
14359 #ifdef CONFIG_P2P
14360 #ifdef CONFIG_IOCTL_CFG80211
14361 if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211)
14362 igi = 0x30;
14363 else
14364 #endif /* CONFIG_IOCTL_CFG80211 */
14365 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
14366 igi = 0x28;
14367 else
14368 #endif /* CONFIG_P2P */
14369 igi = 0x1e;
14370 } else {
14371 igi = 0xff; /* restore RX GAIN */
14372 }
14373
14374 rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
14375 }
14376
sitesurvey_cmd_hdl(_adapter * padapter,u8 * pbuf)14377 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
14378 {
14379 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
14380 struct dvobj_priv *dvobj = padapter->dvobj;
14381 struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
14382 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14383 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14384 struct ss_res *ss = &pmlmeext->sitesurvey_res;
14385 u8 val8;
14386
14387 #ifdef CONFIG_P2P
14388 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14389 #endif
14390
14391 #ifdef DBG_CHECK_FW_PS_STATE
14392 if (rtw_fw_ps_state(padapter) == _FAIL) {
14393 DBG_871X("scan without leave 32k\n");
14394 pdbgpriv->dbg_scan_pwr_state_cnt++;
14395 }
14396 #endif /* DBG_CHECK_FW_PS_STATE */
14397
14398 /* increase channel idx */
14399 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
14400 ss->channel_idx++;
14401
14402 /* update scan state to next state (assigned by previous cmd hdl) */
14403 if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
14404 mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
14405
14406 operation_by_state:
14407 switch (mlmeext_scan_state(pmlmeext)) {
14408
14409 case SCAN_DISABLE:
14410 /*
14411 * SW parameter initialization
14412 */
14413
14414 sitesurvey_res_reset(padapter, pparm);
14415 mlmeext_set_scan_state(pmlmeext, SCAN_START);
14416 goto operation_by_state;
14417
14418 case SCAN_START:
14419 /*
14420 * prepare to leave operating channel
14421 */
14422
14423 /* apply rx ampdu setting */
14424 if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
14425 || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID
14426 ) {
14427 rtw_rx_ampdu_apply(padapter);
14428 }
14429
14430 /* clear HW TX queue before scan */
14431 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14432
14433 /* power save state announcement */
14434 if (sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)) {
14435 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14436 mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
14437 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14438 } else {
14439 mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
14440 goto operation_by_state;
14441 }
14442
14443 break;
14444
14445 case SCAN_ENTER:
14446 /*
14447 * HW register and DM setting for enter scan
14448 */
14449
14450 /* config the initial gain under scanning */
14451 sitesurvey_set_igi(padapter, 1);
14452
14453 /* disable dynamic functions, such as high power, DIG */
14454 rtw_phydm_ability_backup(padapter);
14455 rtw_phydm_func_for_offchannel(padapter);
14456
14457 /* set MSR to no link state */
14458 Set_MSR(padapter, _HW_STATE_NOLINK_);
14459 val8 = 1; /* under site survey */
14460 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14461
14462 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14463 goto operation_by_state;
14464
14465 case SCAN_PROCESS:
14466 {
14467 u8 scan_ch;
14468 RT_SCAN_TYPE scan_type;
14469 u8 next_state;
14470 u32 scan_ms;
14471
14472 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14473 if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) {
14474 ACS_OP acs_op = ACS_SELECT;
14475
14476 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
14477 }
14478 #endif
14479
14480 next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
14481 if (next_state != SCAN_PROCESS) {
14482 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14483 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
14484 rtw_set_acs_channel(padapter, 0);
14485 #ifdef DBG_AUTO_CHNL_SEL_NHM
14486 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
14487 #endif
14488 }
14489 #endif
14490
14491 mlmeext_set_scan_state(pmlmeext, next_state);
14492 goto operation_by_state;
14493 }
14494
14495 /* still SCAN_PROCESS state */
14496 if (0)
14497 #ifdef CONFIG_P2P
14498 DBG_871X(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
14499 , FUNC_ADPT_ARG(padapter)
14500 , mlmeext_scan_state_str(pmlmeext)
14501 , scan_ch
14502 , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
14503 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14504 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14505 , ss->ssid[0].SsidLength?'S':' '
14506 );
14507 #else
14508 DBG_871X(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n"
14509 , FUNC_ADPT_ARG(padapter)
14510 , mlmeext_scan_state_str(pmlmeext)
14511 , scan_ch
14512 , ss->channel_idx
14513 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14514 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14515 , ss->ssid[0].SsidLength?'S':' '
14516 );
14517 #endif /* CONFIG_P2P */
14518
14519 #ifdef DBG_FIXED_CHAN
14520 if (pmlmeext->fixed_chan != 0xff)
14521 DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
14522 #endif
14523
14524 site_survey(padapter, scan_ch, scan_type);
14525
14526 #if defined(CONFIG_ATMEL_RC_PATCH)
14527 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
14528 scan_ms = 20;
14529 else
14530 scan_ms = 40;
14531 #else
14532 scan_ms = ss->scan_ch_ms;
14533 #endif
14534
14535 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14536 if (ss->is_sw_antdiv_bl_scan)
14537 scan_ms = scan_ms/2;
14538 #endif
14539
14540 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14541 {
14542 struct noise_info info;
14543
14544 info.bPauseDIG = _FALSE;
14545 info.IGIValue = 0;
14546 info.max_time = scan_ms/2;
14547 info.chan = scan_ch;
14548 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
14549 }
14550 #endif
14551
14552 set_survey_timer(pmlmeext, scan_ms);
14553 break;
14554 }
14555
14556 #ifdef CONFIG_SCAN_BACKOP
14557 case SCAN_BACKING_OP:
14558 {
14559 u8 back_ch, back_bw, back_ch_offset;
14560
14561 if (rtw_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
14562 rtw_warn_on(1);
14563
14564 if (0)
14565 DBG_871X(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
14566 , FUNC_ADPT_ARG(padapter)
14567 , mlmeext_scan_state_str(pmlmeext)
14568 , back_ch, back_bw, back_ch_offset
14569 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14570 );
14571
14572 set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
14573
14574 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14575 val8 = 0; /* survey done */
14576 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14577
14578 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14579 sitesurvey_set_igi(padapter, 0);
14580 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14581 }
14582
14583 mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
14584 ss->backop_time = rtw_get_current_time();
14585
14586 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME)) {
14587 int i;
14588
14589 /* resume TX */
14590 for (i = 0; i < dvobj->iface_nums; i++) {
14591 if (!dvobj->padapters[i])
14592 continue;
14593
14594 rtw_os_xmit_schedule(dvobj->padapters[i]);
14595 }
14596 }
14597
14598 goto operation_by_state;
14599 }
14600
14601 case SCAN_BACK_OP:
14602 if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
14603 || pmlmeext->scan_abort
14604 ) {
14605 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
14606 goto operation_by_state;
14607 }
14608 set_survey_timer(pmlmeext, 50);
14609 break;
14610
14611 case SCAN_LEAVING_OP:
14612 /*
14613 * prepare to leave operating channel
14614 */
14615
14616 /* clear HW TX queue before scan */
14617 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14618
14619 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
14620 && sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)
14621 ) {
14622 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14623 mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
14624 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14625 } else {
14626 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
14627 goto operation_by_state;
14628 }
14629
14630 break;
14631
14632 case SCAN_LEAVE_OP:
14633 /*
14634 * HW register and DM setting for enter scan
14635 */
14636
14637 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14638 /* config the initial gain under scanning */
14639 sitesurvey_set_igi(padapter, 1);
14640 }
14641
14642 /* set MSR to no link state */
14643 Set_MSR(padapter, _HW_STATE_NOLINK_);
14644 val8 = 1; //under site survey
14645 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14646
14647 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14648 goto operation_by_state;
14649
14650 #endif /* CONFIG_SCAN_BACKOP */
14651
14652 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14653 case SCAN_SW_ANTDIV_BL:
14654 /*
14655 * 20100721
14656 * For SW antenna diversity before link, it needs to switch to another antenna and scan again.
14657 * It compares the scan result and select better one to do connection.
14658 */
14659 ss->bss_cnt = 0;
14660 ss->channel_idx = 0;
14661 ss->is_sw_antdiv_bl_scan = 1;
14662
14663 mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
14664 set_survey_timer(pmlmeext, ss->scan_ch_ms);
14665 break;
14666 #endif
14667
14668 #ifdef CONFIG_P2P
14669 case SCAN_TO_P2P_LISTEN:
14670 /*
14671 * Set the P2P State to the listen state of find phase
14672 * and set the current channel to the listen channel
14673 */
14674 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14675 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
14676
14677 /* turn on phy-dynamic functions */
14678 rtw_phydm_ability_restore(padapter);
14679
14680 sitesurvey_set_igi(padapter, 0);
14681
14682 mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
14683 _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
14684 break;
14685
14686 case SCAN_P2P_LISTEN:
14687 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14688 ss->channel_idx = 0;
14689 goto operation_by_state;
14690 #endif /* CONFIG_P2P */
14691
14692 case SCAN_COMPLETE:
14693 #ifdef CONFIG_P2P
14694 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14695 || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14696 ) {
14697 #ifdef CONFIG_CONCURRENT_MODE
14698 if (pwdinfo->driver_interface == DRIVER_WEXT) {
14699 if (check_buddy_fwstate(padapter, _FW_LINKED))
14700 _set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
14701 }
14702 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14703 #else
14704 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14705 #endif
14706 }
14707 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
14708 #endif /* CONFIG_P2P */
14709
14710 /* switch channel */
14711 survey_done_set_ch_bw(padapter);
14712
14713 /* config MSR */
14714 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14715 val8 = 0; /* survey done */
14716 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14717
14718 /* turn on phy-dynamic functions */
14719 rtw_phydm_ability_restore(padapter);
14720
14721 sitesurvey_set_igi(padapter, 0);
14722
14723 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14724
14725 /* apply rx ampdu setting */
14726 rtw_rx_ampdu_apply(padapter);
14727
14728 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
14729
14730 report_surveydone_event(padapter);
14731
14732 issue_action_BSSCoexistPacket(padapter);
14733 issue_action_BSSCoexistPacket(padapter);
14734 issue_action_BSSCoexistPacket(padapter);
14735 }
14736
14737 return H2C_SUCCESS;
14738 }
14739
setauth_hdl(_adapter * padapter,unsigned char * pbuf)14740 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
14741 {
14742 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
14743 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14744 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14745
14746 if (pparm->mode < 4)
14747 {
14748 pmlmeinfo->auth_algo = pparm->mode;
14749 }
14750
14751 return H2C_SUCCESS;
14752 }
14753
setkey_hdl(_adapter * padapter,u8 * pbuf)14754 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
14755 {
14756 u16 ctrl = 0;
14757 s16 cam_id = 0;
14758 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
14759 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14760 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14761 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14762 u8 *addr;
14763 bool used;
14764
14765 //main tx key for wep.
14766 if(pparm->set_tx)
14767 pmlmeinfo->key_index = pparm->keyid;
14768
14769 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used);
14770
14771 if (cam_id < 0)
14772 goto enable_mc;
14773
14774 if (cam_id > 3) /* not default key, searched by A2 */
14775 addr = get_bssid(&padapter->mlmepriv);
14776 else
14777 addr = null_addr;
14778
14779 #ifdef DYNAMIC_CAMID_ALLOC
14780 /* cam entry searched is pairwise key */
14781 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
14782 s16 camid_clr;
14783
14784 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
14785 , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
14786
14787 /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
14788 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14789 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14790
14791 /* clear group key */
14792 while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
14793 DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
14794 clear_cam_entry(padapter, camid_clr);
14795 rtw_camid_free(padapter, camid_clr);
14796 }
14797
14798 goto enable_mc;
14799 }
14800 #endif
14801
14802 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
14803 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
14804 DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
14805 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
14806
14807 #ifdef DYNAMIC_CAMID_ALLOC
14808 if (cam_id >=0 && cam_id <=3)
14809 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE);
14810 #endif
14811
14812 enable_mc:
14813 //allow multicast packets to driver
14814 rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
14815
14816 return H2C_SUCCESS;
14817 }
14818
set_stakey_hdl(_adapter * padapter,u8 * pbuf)14819 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
14820 {
14821 u16 ctrl = 0;
14822 s16 cam_id = 0;
14823 bool used;
14824 u8 ret = H2C_SUCCESS;
14825 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14826 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14827 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
14828 struct sta_priv *pstapriv = &padapter->stapriv;
14829 struct sta_info *psta;
14830
14831 if(pparm->algorithm == _NO_PRIVACY_)
14832 goto write_to_cam;
14833
14834 psta = rtw_get_stainfo(pstapriv, pparm->addr);
14835 if (!psta) {
14836 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
14837 ret = H2C_REJECTED;
14838 goto exit;
14839 }
14840
14841 pmlmeinfo->enc_algo = pparm->algorithm;
14842 cam_id = rtw_camid_alloc(padapter, psta, 0, &used);
14843 if (cam_id < 0)
14844 goto exit;
14845
14846 #ifdef DYNAMIC_CAMID_ALLOC
14847 /* cam entry searched is group key */
14848 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
14849 s16 camid_clr;
14850
14851 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
14852 , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
14853
14854 /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
14855 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14856 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14857
14858 /* clear group key */
14859 while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
14860 DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
14861 clear_cam_entry(padapter, camid_clr);
14862 rtw_camid_free(padapter, camid_clr);
14863 }
14864 }
14865 #endif
14866
14867 write_to_cam:
14868 if(pparm->algorithm == _NO_PRIVACY_) {
14869 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
14870 DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
14871 clear_cam_entry(padapter, cam_id);
14872 rtw_camid_free(padapter,cam_id);
14873 }
14874 } else {
14875 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
14876 cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
14877 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
14878 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
14879 }
14880 ret = H2C_SUCCESS_RSP;
14881
14882 exit:
14883 return ret;
14884 }
14885
add_ba_hdl(_adapter * padapter,unsigned char * pbuf)14886 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
14887 {
14888 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
14889 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14890 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14891
14892 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
14893
14894 if(!psta)
14895 return H2C_SUCCESS;
14896
14897 #ifdef CONFIG_80211N_HT
14898 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
14899 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
14900 {
14901 //pmlmeinfo->ADDBA_retry_count = 0;
14902 //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
14903 //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
14904 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14905 //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
14906 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14907 }
14908 #ifdef CONFIG_TDLS
14909 else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
14910 (psta->htpriv.ht_option==_TRUE) &&
14911 (psta->htpriv.ampdu_enable==_TRUE) )
14912 {
14913 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14914 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14915 }
14916 #endif //CONFIG
14917 else
14918 {
14919 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
14920 }
14921 #endif //CONFIG_80211N_HT
14922 return H2C_SUCCESS;
14923 }
14924
14925
chk_bmc_sleepq_cmd(_adapter * padapter)14926 u8 chk_bmc_sleepq_cmd(_adapter* padapter)
14927 {
14928 struct cmd_obj *ph2c;
14929 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14930 u8 res = _SUCCESS;
14931
14932 _func_enter_;
14933
14934 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14935 {
14936 res= _FAIL;
14937 goto exit;
14938 }
14939
14940 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
14941
14942 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14943
14944 exit:
14945
14946 _func_exit_;
14947
14948 return res;
14949 }
14950
set_tx_beacon_cmd(_adapter * padapter)14951 u8 set_tx_beacon_cmd(_adapter* padapter)
14952 {
14953 struct cmd_obj *ph2c;
14954 struct Tx_Beacon_param *ptxBeacon_parm;
14955 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14956 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14957 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14958 u8 res = _SUCCESS;
14959 int len_diff = 0;
14960
14961 _func_enter_;
14962
14963 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14964 {
14965 res= _FAIL;
14966 goto exit;
14967 }
14968
14969 if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
14970 {
14971 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
14972 res= _FAIL;
14973 goto exit;
14974 }
14975
14976 _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
14977
14978 len_diff = update_hidden_ssid(
14979 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
14980 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
14981 , pmlmeinfo->hidden_ssid_mode
14982 );
14983 ptxBeacon_parm->network.IELength += len_diff;
14984
14985 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
14986
14987 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14988
14989
14990 exit:
14991
14992 _func_exit_;
14993
14994 return res;
14995 }
14996
14997
mlme_evt_hdl(_adapter * padapter,unsigned char * pbuf)14998 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
14999 {
15000 u8 evt_code, evt_seq;
15001 u16 evt_sz;
15002 uint *peventbuf;
15003 void (*event_callback)(_adapter *dev, u8 *pbuf);
15004 struct evt_priv *pevt_priv = &(padapter->evtpriv);
15005
15006 if (pbuf == NULL)
15007 goto _abort_event_;
15008
15009 peventbuf = (uint*)pbuf;
15010 evt_sz = (u16)(*peventbuf&0xffff);
15011 evt_seq = (u8)((*peventbuf>>24)&0x7f);
15012 evt_code = (u8)((*peventbuf>>16)&0xff);
15013
15014
15015 #ifdef CHECK_EVENT_SEQ
15016 // checking event sequence...
15017 if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
15018 {
15019 RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("Evetn Seq Error! %d vs %d\n", (evt_seq & 0x7f), (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)));
15020
15021 pevt_priv->event_seq = (evt_seq+1)&0x7f;
15022
15023 goto _abort_event_;
15024 }
15025 #endif
15026
15027 // checking if event code is valid
15028 if (evt_code >= MAX_C2HEVT)
15029 {
15030 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
15031 goto _abort_event_;
15032 }
15033
15034 // checking if event size match the event parm size
15035 if ((wlanevents[evt_code].parmsize != 0) &&
15036 (wlanevents[evt_code].parmsize != evt_sz))
15037 {
15038
15039 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
15040 evt_code, wlanevents[evt_code].parmsize, evt_sz));
15041 goto _abort_event_;
15042
15043 }
15044
15045 ATOMIC_INC(&pevt_priv->event_seq);
15046
15047 peventbuf += 2;
15048
15049 if(peventbuf)
15050 {
15051 event_callback = wlanevents[evt_code].event_callback;
15052 event_callback(padapter, (u8*)peventbuf);
15053
15054 pevt_priv->evt_done_cnt++;
15055 }
15056
15057
15058 _abort_event_:
15059
15060
15061 return H2C_SUCCESS;
15062
15063 }
15064
h2c_msg_hdl(_adapter * padapter,unsigned char * pbuf)15065 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
15066 {
15067 if(!pbuf)
15068 return H2C_PARAMETERS_ERROR;
15069
15070 return H2C_SUCCESS;
15071 }
15072
chk_bmc_sleepq_hdl(_adapter * padapter,unsigned char * pbuf)15073 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
15074 {
15075 #ifdef CONFIG_AP_MODE
15076 _irqL irqL;
15077 struct sta_info *psta_bmc;
15078 _list *xmitframe_plist, *xmitframe_phead;
15079 struct xmit_frame *pxmitframe=NULL;
15080 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
15081 struct sta_priv *pstapriv = &padapter->stapriv;
15082
15083 //for BC/MC Frames
15084 psta_bmc = rtw_get_bcmc_stainfo(padapter);
15085 if(!psta_bmc)
15086 return H2C_SUCCESS;
15087
15088 if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
15089 {
15090 #ifndef CONFIG_PCI_HCI
15091 rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
15092 #endif
15093 //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15094 _enter_critical_bh(&pxmitpriv->lock, &irqL);
15095
15096 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
15097 xmitframe_plist = get_next(xmitframe_phead);
15098
15099 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
15100 {
15101 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
15102
15103 xmitframe_plist = get_next(xmitframe_plist);
15104
15105 rtw_list_delete(&pxmitframe->list);
15106
15107 psta_bmc->sleepq_len--;
15108 if(psta_bmc->sleepq_len>0)
15109 pxmitframe->attrib.mdata = 1;
15110 else
15111 pxmitframe->attrib.mdata = 0;
15112
15113 pxmitframe->attrib.triggered=1;
15114
15115 if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
15116 pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ
15117
15118 #if 0
15119 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15120 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
15121 {
15122 rtw_os_xmit_complete(padapter, pxmitframe);
15123 }
15124 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15125 #endif
15126 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
15127 }
15128
15129 //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15130 _exit_critical_bh(&pxmitpriv->lock, &irqL);
15131
15132 if (rtw_get_intf_type(padapter) != RTW_PCIE) {
15133 /* check hi queue and bmc_sleepq */
15134 rtw_chk_hi_queue_cmd(padapter);
15135 }
15136 }
15137 #endif
15138
15139 return H2C_SUCCESS;
15140 }
15141
tx_beacon_hdl(_adapter * padapter,unsigned char * pbuf)15142 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
15143 {
15144 #ifdef CONFIG_AP_MODE
15145 if(send_beacon(padapter)==_FAIL)
15146 {
15147 DBG_871X("issue_beacon, fail!\n");
15148 return H2C_PARAMETERS_ERROR;
15149 }
15150
15151
15152 if (padapter->registrypriv.wifi_spec == 1)
15153 return H2C_SUCCESS;
15154
15155 /* tx bc/mc frames after update TIM */
15156 chk_bmc_sleepq_hdl(padapter, NULL);
15157 #endif /* CONFIG_AP_MODE */
15158 return H2C_SUCCESS;
15159 }
15160
15161 #ifdef CONFIG_AP_MODE
15162 /*
15163 * according to channel
15164 * add/remove WLAN_BSSID_EX.IEs's ERP ie
15165 * set WLAN_BSSID_EX.SupportedRates
15166 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
15167 */
change_band_update_ie(_adapter * padapter,WLAN_BSSID_EX * pnetwork,u8 ch)15168 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
15169 {
15170 u8 network_type,rate_len, total_rate_len,remainder_rate_len;
15171 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
15172 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15173 u8 erpinfo=0x4;
15174
15175 if (ch >= 36) {
15176 network_type = WIRELESS_11A;
15177 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
15178 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
15179 } else {
15180 network_type = WIRELESS_11BG;
15181 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
15182 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
15183 }
15184
15185 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
15186
15187 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
15188
15189 if(total_rate_len > 8)
15190 {
15191 rate_len = 8;
15192 remainder_rate_len = total_rate_len - 8;
15193 }
15194 else
15195 {
15196 rate_len = total_rate_len;
15197 remainder_rate_len = 0;
15198 }
15199
15200 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
15201
15202 if(remainder_rate_len)
15203 {
15204 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
15205 }
15206 else
15207 {
15208 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
15209 }
15210
15211 pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
15212 }
15213 #endif /* CONFIG_AP_MODE */
15214
15215 #ifdef CONFIG_CONCURRENT_MODE
check_buddy_mlmeinfo_state(_adapter * padapter,u32 state)15216 sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
15217 {
15218 PADAPTER pbuddy_adapter;
15219 struct mlme_ext_priv *pbuddy_mlmeext;
15220 struct mlme_ext_info *pbuddy_mlmeinfo;
15221
15222 if(padapter == NULL)
15223 return _FALSE;
15224
15225 pbuddy_adapter = padapter->pbuddy_adapter;
15226
15227 if(pbuddy_adapter == NULL)
15228 return _FALSE;
15229
15230
15231 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
15232 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
15233
15234 if((pbuddy_mlmeinfo->state&0x03) == state)
15235 return _TRUE;
15236
15237 return _FALSE;
15238
15239 }
15240 #endif /* CONFIG_CONCURRENT_MODE */
15241
rtw_join_done_chk_ch(_adapter * adapter,int join_res)15242 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
15243 {
15244 #define DUMP_ADAPTERS_STATUS 0
15245
15246 struct dvobj_priv *dvobj;
15247 _adapter *iface;
15248 struct mlme_priv *mlme;
15249 struct mlme_ext_priv *mlmeext;
15250 u8 u_ch, u_offset, u_bw;
15251 int i;
15252
15253 dvobj = adapter_to_dvobj(adapter);
15254
15255 if (DUMP_ADAPTERS_STATUS) {
15256 DBG_871X(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
15257 dump_adapters_status(RTW_DBGDUMP , dvobj);
15258 }
15259
15260 if (join_res >= 0) {
15261 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
15262 dump_adapters_status(RTW_DBGDUMP , dvobj);
15263 rtw_warn_on(1);
15264 }
15265
15266 for (i = 0; i < dvobj->iface_nums; i++) {
15267 iface = dvobj->padapters[i];
15268 mlme = &iface->mlmepriv;
15269 mlmeext = &iface->mlmeextpriv;
15270
15271 if (!iface || iface == adapter)
15272 continue;
15273 #ifdef CONFIG_AP_MODE
15274 if (check_fwstate(mlme, WIFI_AP_STATE)
15275 && check_fwstate(mlme, WIFI_ASOC_STATE)
15276 ) {
15277 bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
15278 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
15279
15280 if (is_grouped == _FALSE) {
15281 /* handle AP which need to switch ch setting */
15282
15283 /* restore original bw, adjust bw by registry setting on target ch */
15284 mlmeext->cur_bwmode = mlme->ori_bw;
15285 mlmeext->cur_channel = u_ch;
15286 rtw_regsty_adjust_chbw(&iface->registrypriv
15287 , mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
15288
15289 rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
15290 , &u_ch, &u_bw, &u_offset);
15291
15292 rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
15293 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
15294
15295 _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
15296
15297 rtw_start_bss_hdl_after_chbw_decided(iface);
15298 }
15299
15300 update_beacon(iface, 0, NULL, _TRUE);
15301 }
15302 #endif /* CONFIG_AP_MODE */
15303 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15304 }
15305
15306 #ifdef CONFIG_DFS_MASTER
15307 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED);
15308 #endif
15309 } else {
15310 for (i = 0; i < dvobj->iface_nums; i++) {
15311 iface = dvobj->padapters[i];
15312 mlme = &iface->mlmepriv;
15313 mlmeext = &iface->mlmeextpriv;
15314
15315 if (!iface || iface == adapter)
15316 continue;
15317 #ifdef CONFIG_AP_MODE
15318 if (check_fwstate(mlme, WIFI_AP_STATE)
15319 && check_fwstate(mlme, WIFI_ASOC_STATE))
15320 update_beacon(iface, 0, NULL, _TRUE);
15321 #endif /* CONFIG_AP_MODE */
15322 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15323 }
15324 #ifdef CONFIG_DFS_MASTER
15325 rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED);
15326 #endif
15327 }
15328
15329 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
15330 set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
15331
15332 if (DUMP_ADAPTERS_STATUS) {
15333 DBG_871X(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
15334 dump_adapters_status(RTW_DBGDUMP , dvobj);
15335 }
15336 }
15337
rtw_chk_start_clnt_join(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)15338 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15339 {
15340 bool chbw_allow = _TRUE;
15341 bool connect_allow = _TRUE;
15342 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
15343 u8 cur_ch, cur_bw, cur_ch_offset;
15344 u8 u_ch, u_offset, u_bw;
15345
15346 u_ch = cur_ch = pmlmeext->cur_channel;
15347 u_bw = cur_bw = pmlmeext->cur_bwmode;
15348 u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
15349
15350 if (!ch || !bw || !offset) {
15351 connect_allow = _FALSE;
15352 rtw_warn_on(1);
15353 goto exit;
15354 }
15355
15356 if (cur_ch == 0) {
15357 connect_allow = _FALSE;
15358 DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n"
15359 , FUNC_ADPT_ARG(adapter), cur_ch);
15360 rtw_warn_on(1);
15361 goto exit;
15362 }
15363 DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15364
15365 #ifdef CONFIG_CONCURRENT_MODE
15366 {
15367 struct dvobj_priv *dvobj;
15368 _adapter *iface;
15369 struct mlme_priv *mlme;
15370 struct mlme_ext_priv *mlmeext;
15371 u8 sta_num;
15372 u8 ld_sta_num;
15373 u8 lg_sta_num;
15374 u8 ap_num;
15375 u8 ld_ap_num;
15376 int i;
15377
15378 dvobj = adapter_to_dvobj(adapter);
15379
15380 rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num);
15381 DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n"
15382 , FUNC_ADPT_ARG(adapter), ld_sta_num, ap_num);
15383
15384 if (!ld_sta_num && !ap_num) {
15385 /* consider linking STA? */
15386 goto connect_allow_hdl;
15387 }
15388
15389 if (rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
15390 dump_adapters_status(RTW_DBGDUMP , dvobj);
15391 rtw_warn_on(1);
15392 }
15393 DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
15394 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15395
15396 /* chbw_allow? */
15397 chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
15398 , u_ch, u_bw, u_offset);
15399
15400 DBG_871X(FUNC_ADPT_FMT" chbw_allow:%d\n"
15401 , FUNC_ADPT_ARG(adapter), chbw_allow);
15402
15403 if (chbw_allow == _TRUE) {
15404 rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
15405 rtw_warn_on(cur_ch != pmlmeext->cur_channel);
15406 rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
15407 rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
15408 goto connect_allow_hdl;
15409 }
15410
15411 /* chbw_allow is _FALSE, connect allow? */
15412 for (i = 0; i < dvobj->iface_nums; i++) {
15413 iface = dvobj->padapters[i];
15414 mlme = &iface->mlmepriv;
15415 mlmeext = &iface->mlmeextpriv;
15416
15417 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
15418 if (check_fwstate(mlme, WIFI_STATION_STATE)
15419 && check_fwstate(mlme, WIFI_ASOC_STATE)
15420 #if defined(CONFIG_P2P)
15421 && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
15422 #endif
15423 ) {
15424 connect_allow = _FALSE;
15425 break;
15426 }
15427 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
15428 }
15429 DBG_871X(FUNC_ADPT_FMT" connect_allow:%d\n"
15430 , FUNC_ADPT_ARG(adapter), connect_allow);
15431
15432 if (connect_allow == _FALSE)
15433 goto exit;
15434
15435 connect_allow_hdl:
15436 /* connect_allow == _TRUE */
15437
15438 #ifdef CONFIG_DFS_MASTER
15439 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING);
15440 #endif
15441
15442 if (chbw_allow == _FALSE) {
15443 u_ch = cur_ch;
15444 u_bw = cur_bw;
15445 u_offset = cur_ch_offset;
15446
15447 for (i = 0; i < dvobj->iface_nums; i++) {
15448 iface = dvobj->padapters[i];
15449 mlme = &iface->mlmepriv;
15450 mlmeext = &iface->mlmeextpriv;
15451
15452 if (!iface || iface == adapter)
15453 continue;
15454
15455 if (check_fwstate(mlme, WIFI_AP_STATE)
15456 && check_fwstate(mlme, WIFI_ASOC_STATE)
15457 ) {
15458 #ifdef CONFIG_SPCT_CH_SWITCH
15459 if (1)
15460 rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
15461 else
15462 #endif
15463 rtw_sta_flush(iface, _FALSE);
15464
15465 rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
15466 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15467 } else if (check_fwstate(mlme, WIFI_STATION_STATE)
15468 && check_fwstate(mlme, WIFI_ASOC_STATE)
15469 ) {
15470 rtw_disassoc_cmd(iface, 500, _FALSE);
15471 rtw_indicate_disconnect(iface);
15472 rtw_free_assoc_resources(iface, 1);
15473 }
15474 }
15475 }
15476 }
15477 #endif /* CONFIG_CONCURRENT_MODE */
15478
15479 exit:
15480
15481 if (connect_allow == _TRUE) {
15482 DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15483 *ch = u_ch;
15484 *bw = u_bw;
15485 *offset = u_offset;
15486 }
15487
15488 return connect_allow == _TRUE ? _SUCCESS : _FAIL;
15489 }
15490
15491 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
_rtw_get_ch_setting_union(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset,bool include_self)15492 int _rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
15493 {
15494 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15495 _adapter *iface;
15496 struct mlme_ext_priv *mlmeext;
15497 int i;
15498 u8 ch_ret = 0;
15499 u8 bw_ret = CHANNEL_WIDTH_20;
15500 u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15501 int num = 0;
15502
15503 if (ch) *ch = 0;
15504 if (bw) *bw = CHANNEL_WIDTH_20;
15505 if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15506
15507 for (i = 0; i<dvobj->iface_nums; i++) {
15508 iface = dvobj->padapters[i];
15509 mlmeext = &iface->mlmeextpriv;
15510
15511 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
15512 continue;
15513
15514 if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
15515 continue;
15516
15517 if (include_self == _FALSE && adapter == iface)
15518 continue;
15519
15520 if (num == 0) {
15521 ch_ret = mlmeext->cur_channel;
15522 bw_ret = mlmeext->cur_bwmode;
15523 offset_ret = mlmeext->cur_ch_offset;
15524 num++;
15525 continue;
15526 }
15527
15528 if (ch_ret != mlmeext->cur_channel) {
15529 num = 0;
15530 break;
15531 }
15532
15533 if (bw_ret < mlmeext->cur_bwmode) {
15534 bw_ret = mlmeext->cur_bwmode;
15535 offset_ret = mlmeext->cur_ch_offset;
15536 } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
15537 num = 0;
15538 break;
15539 }
15540
15541 num++;
15542 }
15543
15544 if (num) {
15545 if (ch) *ch = ch_ret;
15546 if (bw) *bw = bw_ret;
15547 if (offset) *offset = offset_ret;
15548 }
15549
15550 return num;
15551 }
15552
rtw_get_ch_setting_union(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)15553 inline int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15554 {
15555 return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 1);
15556 }
15557
rtw_get_ch_setting_union_no_self(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)15558 inline int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15559 {
15560 return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 0);
15561 }
15562
_rtw_dev_iface_status(_adapter * adapter,u8 * sta_num,u8 * ld_sta_num,u8 * lg_sta_num,u8 * ap_num,u8 * ld_ap_num,bool include_self)15563 void _rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15564 , u8 *ap_num, u8 *ld_ap_num, bool include_self)
15565 {
15566 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15567 _adapter *iface;
15568 struct mlme_ext_priv *mlmeext;
15569 struct mlme_ext_info *mlmeextinfo;
15570 int i;
15571 u8 sta_num_ret = 0;
15572 u8 ld_sta_num_ret = 0;
15573 u8 lg_sta_num_ret = 0;
15574 u8 ap_num_ret = 0;
15575 u8 ld_ap_num_ret = 0;
15576
15577 if (sta_num)
15578 *sta_num = 0;
15579 if (ld_sta_num)
15580 *ld_sta_num = 0;
15581 if (lg_sta_num)
15582 *lg_sta_num = 0;
15583 if (ap_num)
15584 *ap_num = 0;
15585 if (ld_ap_num)
15586 *ld_ap_num = 0;
15587
15588 for (i = 0; i < dvobj->iface_nums; i++) {
15589 iface = dvobj->padapters[i];
15590
15591 if (include_self == _FALSE && iface == adapter)
15592 continue;
15593
15594 mlmeext = &iface->mlmeextpriv;
15595
15596 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
15597 sta_num_ret++;
15598 if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
15599 ld_sta_num_ret++;
15600 if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
15601 lg_sta_num_ret++;
15602 }
15603
15604 if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
15605 && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
15606 ) {
15607 ap_num_ret++;
15608 if (iface->stapriv.asoc_sta_count > 2)
15609 ld_ap_num_ret++;
15610 }
15611 }
15612
15613 if (sta_num)
15614 *sta_num = sta_num_ret;
15615 if (ld_sta_num)
15616 *ld_sta_num = ld_sta_num_ret;
15617 if (lg_sta_num)
15618 *lg_sta_num = lg_sta_num_ret;
15619 if (ap_num)
15620 *ap_num = ap_num_ret;
15621 if (ld_ap_num)
15622 *ld_ap_num = ld_ap_num_ret;
15623 }
15624
rtw_dev_iface_status(_adapter * adapter,u8 * sta_num,u8 * ld_sta_num,u8 * lg_sta_num,u8 * ap_num,u8 * ld_ap_num)15625 inline void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15626 , u8 *ap_num, u8 *ld_ap_num)
15627 {
15628 return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 1);
15629 }
15630
rtw_dev_iface_status_no_self(_adapter * adapter,u8 * sta_num,u8 * ld_sta_num,u8 * lg_sta_num,u8 * ap_num,u8 * ld_ap_num)15631 inline void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15632 , u8 *ap_num, u8 *ld_ap_num)
15633 {
15634 return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 0);
15635 }
15636
set_ch_hdl(_adapter * padapter,u8 * pbuf)15637 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
15638 {
15639 struct set_ch_parm *set_ch_parm;
15640 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
15641 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15642
15643 if(!pbuf)
15644 return H2C_PARAMETERS_ERROR;
15645
15646 set_ch_parm = (struct set_ch_parm *)pbuf;
15647
15648 DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
15649 FUNC_NDEV_ARG(padapter->pnetdev),
15650 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
15651
15652 pmlmeext->cur_channel = set_ch_parm->ch;
15653 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
15654 pmlmeext->cur_bwmode = set_ch_parm->bw;
15655
15656 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
15657
15658 return H2C_SUCCESS;
15659 }
15660
set_chplan_hdl(_adapter * padapter,unsigned char * pbuf)15661 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
15662 {
15663 struct SetChannelPlan_param *setChannelPlan_param;
15664 struct mlme_priv *mlme = &padapter->mlmepriv;
15665 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15666
15667 if(!pbuf)
15668 return H2C_PARAMETERS_ERROR;
15669
15670 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
15671
15672 if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) {
15673 return H2C_PARAMETERS_ERROR;
15674 }
15675
15676 mlme->ChannelPlan = setChannelPlan_param->channel_plan;
15677
15678 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
15679 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
15680
15681 rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE);
15682
15683 #ifdef CONFIG_IOCTL_CFG80211
15684 rtw_reg_notify_by_driver(padapter);
15685 #endif //CONFIG_IOCTL_CFG80211
15686
15687 return H2C_SUCCESS;
15688 }
15689
led_blink_hdl(_adapter * padapter,unsigned char * pbuf)15690 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
15691 {
15692 struct LedBlink_param *ledBlink_param;
15693
15694 if(!pbuf)
15695 return H2C_PARAMETERS_ERROR;
15696
15697 ledBlink_param = (struct LedBlink_param *)pbuf;
15698
15699 #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
15700 BlinkHandler((PLED_DATA)ledBlink_param->pLed);
15701 #endif
15702
15703 return H2C_SUCCESS;
15704 }
15705
set_csa_hdl(_adapter * padapter,unsigned char * pbuf)15706 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
15707 {
15708 #ifdef CONFIG_DFS
15709 struct SetChannelSwitch_param *setChannelSwitch_param;
15710 u8 new_ch_no;
15711 u8 gval8 = 0x00, sval8 = 0xff;
15712
15713 if(!pbuf)
15714 return H2C_PARAMETERS_ERROR;
15715
15716 setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
15717 new_ch_no = setChannelSwitch_param->new_ch_no;
15718
15719 rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15720
15721 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
15722
15723 DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
15724 SelectChannel(padapter, new_ch_no);
15725
15726 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15727
15728 rtw_disassoc_cmd(padapter, 0, _FALSE);
15729 rtw_indicate_disconnect(padapter);
15730 rtw_free_assoc_resources(padapter, 1);
15731 rtw_free_network_queue(padapter, _TRUE);
15732
15733 if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
15734 DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
15735 }
15736
15737 return H2C_SUCCESS;
15738 #else
15739 return H2C_REJECTED;
15740 #endif //CONFIG_DFS
15741
15742 }
15743
tdls_hdl(_adapter * padapter,unsigned char * pbuf)15744 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
15745 {
15746 #ifdef CONFIG_TDLS
15747 _irqL irqL;
15748 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
15749 #ifdef CONFIG_TDLS_CH_SW
15750 struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
15751 #endif
15752 struct TDLSoption_param *TDLSoption;
15753 struct sta_info *ptdls_sta = NULL;
15754 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15755 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
15756 u8 survey_channel, i, min, option;
15757 struct tdls_txmgmt txmgmt;
15758 u32 setchtime, resp_sleep = 0, wait_time;
15759 u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15760
15761 if (!pbuf)
15762 return H2C_PARAMETERS_ERROR;
15763
15764 TDLSoption = (struct TDLSoption_param *)pbuf;
15765 option = TDLSoption->option;
15766
15767 if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
15768 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
15769 if (ptdls_sta == NULL) {
15770 return H2C_REJECTED;
15771 }
15772 } else {
15773 if (!(option == TDLS_RS_RCR || option == TDLS_CH_SW_BACK))
15774 return H2C_REJECTED;
15775 }
15776
15777 //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15778 //DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
15779
15780 switch (option) {
15781 case TDLS_ESTABLISHED:
15782 {
15783 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
15784 /* So we can receive all kinds of data frames. */
15785 u8 sta_band = 0;
15786
15787 //leave ALL PS when TDLS is established
15788 rtw_pwr_wakeup(padapter);
15789
15790 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
15791 DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
15792
15793 pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta;
15794 /* Set TDLS sta rate. */
15795 /* Update station supportRate */
15796 rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
15797 if (pmlmeext->cur_channel > 14) {
15798 if (ptdls_sta->ra_mask & 0xffff000)
15799 sta_band |= WIRELESS_11_5N ;
15800
15801 if (ptdls_sta->ra_mask & 0xff0)
15802 sta_band |= WIRELESS_11A;
15803
15804 /* 5G band */
15805 #ifdef CONFIG_80211AC_VHT
15806 if (ptdls_sta->vhtpriv.vht_option)
15807 sta_band = WIRELESS_11_5AC;
15808 #endif
15809
15810 } else {
15811 if (ptdls_sta->ra_mask & 0xffff000)
15812 sta_band |= WIRELESS_11_24N;
15813
15814 if (ptdls_sta->ra_mask & 0xff0)
15815 sta_band |= WIRELESS_11G;
15816
15817 if (ptdls_sta->ra_mask & 0x0f)
15818 sta_band |= WIRELESS_11B;
15819 }
15820 ptdls_sta->wireless_mode = sta_band;
15821 ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta);
15822 set_sta_rate(padapter, ptdls_sta);
15823 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
15824 /* Sta mode */
15825 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE);
15826 break;
15827 }
15828 case TDLS_ISSUE_PTI:
15829 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
15830 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
15831 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
15832 break;
15833 #ifdef CONFIG_TDLS_CH_SW
15834 case TDLS_CH_SW_RESP:
15835 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15836 txmgmt.status_code = 0;
15837 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15838
15839 issue_nulldata(padapter, NULL, 1, 0, 0);
15840
15841 DBG_871X("issue tdls channel switch response\n");
15842 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
15843 resp_sleep = 5;
15844 rtw_msleep_os(resp_sleep);
15845
15846 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
15847 /* then we just SelectChannel to AP's channel*/
15848 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
15849 SelectChannel(padapter, padapter->mlmeextpriv.cur_channel);
15850 issue_nulldata(padapter, NULL, 0, 0, 0);
15851 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15852 ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
15853 break;
15854 }
15855
15856 _set_timer(&ptdls_sta->delay_timer, pmlmeinfo->bcn_interval - 40);
15857
15858 /* Continue following actions */
15859
15860 case TDLS_CH_SW:
15861 issue_nulldata(padapter, NULL, 1, 0, 0);
15862 _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout)/1000);
15863
15864 setchtime = rtw_systime_to_ms(rtw_get_current_time());
15865 SelectChannel(padapter, pchsw_info->off_ch_num);
15866 setchtime = rtw_systime_to_ms(rtw_get_current_time()) - setchtime;
15867 setchtime += resp_sleep;
15868
15869 if (pmlmeext->cur_channel != rtw_get_oper_ch(padapter))
15870 issue_nulldata(padapter, NULL, 0, 0, 0);
15871 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15872
15873 if ((u32)ptdls_sta->ch_switch_time/1000 > setchtime)
15874 wait_time = (u32)ptdls_sta->ch_switch_time/1000 - setchtime;
15875 else
15876 wait_time = 0;
15877
15878 if (wait_time > 0)
15879 rtw_msleep_os(wait_time);
15880
15881 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
15882 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
15883
15884 break;
15885 case TDLS_CH_SW_BACK:
15886 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
15887 ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
15888 SelectChannel(padapter, padapter->mlmeextpriv.cur_channel);
15889 issue_nulldata(padapter, NULL, 0, 0, 0);
15890 break;
15891 #endif
15892 case TDLS_RS_RCR:
15893 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
15894 DBG_871X("wirte REG_RCR, set bit6 on\n");
15895 break;
15896 case TDLS_TEAR_STA:
15897 #ifdef CONFIG_TDLS_CH_SW
15898 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
15899 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
15900 TDLS_CH_SWITCH_ON_STATE |
15901 TDLS_PEER_AT_OFF_STATE);
15902 ATOMIC_SET(&pchsw_info->chsw_on, _FALSE);
15903 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
15904 }
15905 #endif
15906 rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
15907 free_tdls_sta(padapter, ptdls_sta);
15908 break;
15909 }
15910
15911 //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15912
15913 return H2C_SUCCESS;
15914 #else
15915 return H2C_REJECTED;
15916 #endif /* CONFIG_TDLS */
15917
15918 }
15919
run_in_thread_hdl(_adapter * padapter,u8 * pbuf)15920 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
15921 {
15922 struct RunInThread_param *p;
15923
15924
15925 if (NULL == pbuf)
15926 return H2C_PARAMETERS_ERROR;
15927 p = (struct RunInThread_param*)pbuf;
15928
15929 if (p->func)
15930 p->func(p->context);
15931
15932 return H2C_SUCCESS;
15933 }
15934
15935