1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _RTW_MLME_EXT_C_
22 #include <drv_types.h>
23 #ifdef CONFIG_IOCTL_CFG80211
24 #include <rtw_wifi_regd.h>
25 #endif //CONFIG_IOCTL_CFG80211
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},
37 /*----------------------------------------------------------
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},
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},
60 /*----------------------------------------------------------
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},
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},
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},
98 u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0};
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};
109 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
110 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
112 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
113 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
115 extern unsigned char REALTEK_96B_IE[];
117 #ifdef LEGACY_CHANNEL_PLAN_REF
118 /********************************************************
119 ChannelPlan definitions
120 *********************************************************/
121 static RT_CHANNEL_PLAN legacy_channel_plan[] = {
122 /* 0x00, RTW_CHPLAN_FCC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 32},
123 /* 0x01, RTW_CHPLAN_IC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 31},
124 /* 0x02, RTW_CHPLAN_ETSI */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32},
125 /* 0x03, RTW_CHPLAN_SPAIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
126 /* 0x04, RTW_CHPLAN_FRANCE */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
127 /* 0x05, RTW_CHPLAN_MKK */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
128 /* 0x06, RTW_CHPLAN_MKK1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
129 /* 0x07, RTW_CHPLAN_ISRAEL */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21},
130 /* 0x08, RTW_CHPLAN_TELEC */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},
131 /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
132 /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
133 /* 0x0B, RTW_CHPLAN_TAIWAN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 26},
134 /* 0x0C, RTW_CHPLAN_CHINA */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 149, 153, 157, 161, 165}, 18},
135 /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24},
136 /* 0x0E, RTW_CHPLAN_KOREA */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 31},
137 /* 0x0F, RTW_CHPLAN_TURKEY */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19},
138 /* 0x10, RTW_CHPLAN_JAPAN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 32},
139 /* 0x11, RTW_CHPLAN_FCC_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, 157, 161, 165}, 20},
140 /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48}, 17},
141 /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 37},
142 /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 56, 60, 64, 149, 153, 157, 161, 165}, 19},
146 static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[] = {
147 /* 0, RTW_RD_2G_NULL */ {{}, 0},
148 /* 1, RTW_RD_2G_WORLD */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
149 /* 2, RTW_RD_2G_ETSI1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
150 /* 3, RTW_RD_2G_FCC1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
151 /* 4, RTW_RD_2G_MKK1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
152 /* 5, RTW_RD_2G_ETSI2 */ {{10, 11, 12, 13}, 4},
153 /* 6, RTW_RD_2G_GLOBAL */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
154 /* 7, RTW_RD_2G_MKK2 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
155 /* 8, RTW_RD_2G_FCC2 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
158 static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[] = {
159 /* 0, RTW_RD_5G_NULL */ {{}, 0},
160 /* 1, RTW_RD_5G_ETSI1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},
161 /* 2, RTW_RD_5G_ETSI2 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
162 /* 3, RTW_RD_5G_ETSI3 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
163 /* 4, RTW_RD_5G_FCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
164 /* 5, RTW_RD_5G_FCC2 */ {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
165 /* 6, RTW_RD_5G_FCC3 */ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
166 /* 7, RTW_RD_5G_FCC4 */ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
167 /* 8, RTW_RD_5G_FCC5 */ {{149, 153, 157, 161, 165}, 5},
168 /* 9, RTW_RD_5G_FCC6 */ {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
169 /* 10, RTW_RD_5G_FCC7 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
170 /* 11, RTW_RD_5G_KCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161}, 19},
171 /* 12, RTW_RD_5G_MKK1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19},
172 /* 13, RTW_RD_5G_MKK2 */ {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
173 /* 14, RTW_RD_5G_MKK3 */ {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
174 /* 15, RTW_RD_5G_NCC1 */ {{56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 16},
175 /* 16, RTW_RD_5G_NCC2 */ {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
176 /* 17, RTW_RD_5G_NCC3 */ {{149, 153, 157, 161, 165}, 5},
177 /* 18, RTW_RD_5G_ETSI4 */ {{36, 40, 44, 48}, 4},
178 /* 19, RTW_RD_5G_ETSI5 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
179 /* 20, RTW_RD_5G_FCC8 */ {{149, 153, 157, 161}, 4},
180 /* 21, RTW_RD_5G_ETSI6 */ {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
181 /* 22, RTW_RD_5G_ETSI7 */ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
182 /* 23, RTW_RD_5G_ETSI8 */ {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
183 /* 24, RTW_RD_5G_ETSI9 */ {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
184 /* 25, RTW_RD_5G_ETSI10 */ {{149, 153, 157, 161, 165}, 5},
185 /* 26, RTW_RD_5G_ETSI11 */ {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165}, 16},
186 /* 27, RTW_RD_5G_NCC4 */ {{52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17},
187 /* 28, RTW_RD_5G_ETSI12 */ {{149, 153, 157, 161}, 4},
188 /* 29, RTW_RD_5G_FCC9 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
189 /* 30, RTW_RD_5G_ETSI13 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140}, 16},
190 /* 31, RTW_RD_5G_FCC10 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161}, 20},
191 /* 32, RTW_RD_5G_MKK4 */ {{36, 40, 44, 48}, 4},
192 /* 33, RTW_RD_5G_ETSI14 */ {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140}, 11},
194 /* === Below are driver defined for legacy channel plan compatible, NO static index assigned ==== */
195 /* RTW_RD_5G_OLD_FCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20},
196 /* RTW_RD_5G_OLD_NCC1 */ {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15},
197 /* RTW_RD_5G_OLD_KCC1 */ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20},
200 static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[] = {
201 /* ===== 0x00 ~ 0x1F, legacy channel plan ===== */
202 {RTW_RD_2G_FCC1, RTW_RD_5G_KCC1, TXPWR_LMT_FCC}, /* 0x00, RTW_CHPLAN_FCC */
203 {RTW_RD_2G_FCC1, RTW_RD_5G_OLD_FCC1, TXPWR_LMT_FCC}, /* 0x01, RTW_CHPLAN_IC */
204 {RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI}, /* 0x02, RTW_CHPLAN_ETSI */
205 {RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x03, RTW_CHPLAN_SPAIN */
206 {RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x04, RTW_CHPLAN_FRANCE */
207 {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK}, /* 0x05, RTW_CHPLAN_MKK */
208 {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK}, /* 0x06, RTW_CHPLAN_MKK1 */
209 {RTW_RD_2G_ETSI1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI}, /* 0x07, RTW_CHPLAN_ISRAEL */
210 {RTW_RD_2G_MKK1, RTW_RD_5G_FCC6, TXPWR_LMT_MKK}, /* 0x08, RTW_CHPLAN_TELEC */
211 {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */
212 {RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */
213 {RTW_RD_2G_FCC1, RTW_RD_5G_OLD_NCC1, TXPWR_LMT_FCC}, /* 0x0B, RTW_CHPLAN_TAIWAN */
214 {RTW_RD_2G_ETSI1, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI}, /* 0x0C, RTW_CHPLAN_CHINA */
215 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC3, TXPWR_LMT_WW}, /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ /* ETSI:Singapore, India. FCC:Mexico => WW */
216 {RTW_RD_2G_FCC1, RTW_RD_5G_OLD_KCC1, TXPWR_LMT_ETSI}, /* 0x0E, RTW_CHPLAN_KOREA */
217 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI}, /* 0x0F, RTW_CHPLAN_TURKEY */
218 {RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_MKK}, /* 0x10, RTW_CHPLAN_JAPAN */
219 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC}, /* 0x11, RTW_CHPLAN_FCC_NO_DFS */
220 {RTW_RD_2G_ETSI1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK}, /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */
221 {RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_WW}, /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */
222 {RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC}, /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */
223 {RTW_RD_2G_WORLD, RTW_RD_5G_FCC7, TXPWR_LMT_ETSI}, /* 0x15, RTW_CHPLAN_ETSI_NO_DFS */
224 {RTW_RD_2G_WORLD, RTW_RD_5G_NCC1, TXPWR_LMT_ETSI}, /* 0x16, RTW_CHPLAN_KOREA_NO_DFS */
225 {RTW_RD_2G_MKK1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK}, /* 0x17, RTW_CHPLAN_JAPAN_NO_DFS */
226 {RTW_RD_2G_NULL, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI}, /* 0x18, RTW_CHPLAN_PAKISTAN_NO_DFS */
227 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC}, /* 0x19, RTW_CHPLAN_TAIWAN2_NO_DFS */
228 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1A, */
229 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1B, */
230 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1C, */
231 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1D, */
232 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x1E, */
233 {RTW_RD_2G_NULL, RTW_RD_5G_FCC1, TXPWR_LMT_WW}, /* 0x1F, RTW_CHPLAN_WORLD_WIDE_ONLY_5G */
235 /* ===== 0x20 ~ 0x7F, new channel plan ===== */
236 {RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x20, RTW_CHPLAN_WORLD_NULL */
237 {RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x21, RTW_CHPLAN_ETSI1_NULL */
238 {RTW_RD_2G_FCC1, RTW_RD_5G_NULL, TXPWR_LMT_FCC}, /* 0x22, RTW_CHPLAN_FCC1_NULL */
239 {RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK}, /* 0x23, RTW_CHPLAN_MKK1_NULL */
240 {RTW_RD_2G_ETSI2, RTW_RD_5G_NULL, TXPWR_LMT_ETSI}, /* 0x24, RTW_CHPLAN_ETSI2_NULL */
241 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC1, TXPWR_LMT_FCC}, /* 0x25, RTW_CHPLAN_FCC1_FCC1 */
242 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI}, /* 0x26, RTW_CHPLAN_WORLD_ETSI1 */
243 {RTW_RD_2G_MKK1, RTW_RD_5G_MKK1, TXPWR_LMT_MKK}, /* 0x27, RTW_CHPLAN_MKK1_MKK1 */
244 {RTW_RD_2G_WORLD, RTW_RD_5G_KCC1, TXPWR_LMT_ETSI}, /* 0x28, RTW_CHPLAN_WORLD_KCC1 */
245 {RTW_RD_2G_WORLD, RTW_RD_5G_FCC2, TXPWR_LMT_FCC}, /* 0x29, RTW_CHPLAN_WORLD_FCC2 */
246 {RTW_RD_2G_FCC2, RTW_RD_5G_NULL, TXPWR_LMT_FCC}, /* 0x2A, RTW_CHPLAN_FCC2_NULL */
247 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2B, */
248 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2C, */
249 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2D, */
250 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2E, */
251 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x2F, */
252 {RTW_RD_2G_WORLD, RTW_RD_5G_FCC3, TXPWR_LMT_FCC}, /* 0x30, RTW_CHPLAN_WORLD_FCC3 */
253 {RTW_RD_2G_WORLD, RTW_RD_5G_FCC4, TXPWR_LMT_FCC}, /* 0x31, RTW_CHPLAN_WORLD_FCC4 */
254 {RTW_RD_2G_WORLD, RTW_RD_5G_FCC5, TXPWR_LMT_FCC}, /* 0x32, RTW_CHPLAN_WORLD_FCC5 */
255 {RTW_RD_2G_WORLD, RTW_RD_5G_FCC6, TXPWR_LMT_FCC}, /* 0x33, RTW_CHPLAN_WORLD_FCC6 */
256 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC7, TXPWR_LMT_FCC}, /* 0x34, RTW_CHPLAN_FCC1_FCC7 */
257 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI2, TXPWR_LMT_ETSI}, /* 0x35, RTW_CHPLAN_WORLD_ETSI2 */
258 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI3, TXPWR_LMT_ETSI}, /* 0x36, RTW_CHPLAN_WORLD_ETSI3 */
259 {RTW_RD_2G_MKK1, RTW_RD_5G_MKK2, TXPWR_LMT_MKK}, /* 0x37, RTW_CHPLAN_MKK1_MKK2 */
260 {RTW_RD_2G_MKK1, RTW_RD_5G_MKK3, TXPWR_LMT_MKK}, /* 0x38, RTW_CHPLAN_MKK1_MKK3 */
261 {RTW_RD_2G_FCC1, RTW_RD_5G_NCC1, TXPWR_LMT_FCC}, /* 0x39, RTW_CHPLAN_FCC1_NCC1 */
262 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3A, */
263 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3B, */
264 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3C, */
265 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3D, */
266 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3E, */
267 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x3F, */
268 {RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC}, /* 0x40, RTW_CHPLAN_FCC1_NCC2 */
269 {RTW_RD_2G_GLOBAL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x41, RTW_CHPLAN_GLOBAL_NULL */
270 {RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI4, TXPWR_LMT_ETSI}, /* 0x42, RTW_CHPLAN_ETSI1_ETSI4 */
271 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC}, /* 0x43, RTW_CHPLAN_FCC1_FCC2 */
272 {RTW_RD_2G_FCC1, RTW_RD_5G_NCC3, TXPWR_LMT_FCC}, /* 0x44, RTW_CHPLAN_FCC1_NCC3 */
273 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI5, TXPWR_LMT_ETSI}, /* 0x45, RTW_CHPLAN_WORLD_ETSI5 */
274 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC8, TXPWR_LMT_FCC}, /* 0x46, RTW_CHPLAN_FCC1_FCC8 */
275 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI6, TXPWR_LMT_ETSI}, /* 0x47, RTW_CHPLAN_WORLD_ETSI6 */
276 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI7, TXPWR_LMT_ETSI}, /* 0x48, RTW_CHPLAN_WORLD_ETSI7 */
277 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI8, TXPWR_LMT_ETSI}, /* 0x49, RTW_CHPLAN_WORLD_ETSI8 */
278 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4A, */
279 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4B, */
280 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4C, */
281 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4D, */
282 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4E, */
283 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x4F, */
284 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI9, TXPWR_LMT_ETSI}, /* 0x50, RTW_CHPLAN_WORLD_ETSI9 */
285 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI10, TXPWR_LMT_ETSI}, /* 0x51, RTW_CHPLAN_WORLD_ETSI10 */
286 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI11, TXPWR_LMT_ETSI}, /* 0x52, RTW_CHPLAN_WORLD_ETSI11 */
287 {RTW_RD_2G_FCC1, RTW_RD_5G_NCC4, TXPWR_LMT_FCC}, /* 0x53, RTW_CHPLAN_FCC1_NCC4 */
288 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI12, TXPWR_LMT_ETSI}, /* 0x54, RTW_CHPLAN_WORLD_ETSI12 */
289 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC9, TXPWR_LMT_FCC}, /* 0x55, RTW_CHPLAN_FCC1_FCC9 */
290 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI13, TXPWR_LMT_ETSI}, /* 0x56, RTW_CHPLAN_WORLD_ETSI13 */
291 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC10, TXPWR_LMT_FCC}, /* 0x57, RTW_CHPLAN_FCC1_FCC10 */
292 {RTW_RD_2G_MKK2, RTW_RD_5G_MKK4, TXPWR_LMT_MKK}, /* 0x58, RTW_CHPLAN_MKK2_MKK4 */
293 {RTW_RD_2G_WORLD, RTW_RD_5G_ETSI14, TXPWR_LMT_ETSI}, /* 0x59, RTW_CHPLAN_WORLD_ETSI14 */
294 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x5A, */
295 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x5B, */
296 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x5C, */
297 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x5D, */
298 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x5E, */
299 {RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW}, /* 0x5F, */
300 {RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC}, /* 0x60, RTW_CHPLAN_FCC1_FCC5 */
303 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {
304 RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_FCC /* 0x7F, Realtek Define */
307 bool rtw_chplan_is_empty(u8 id)
309 RT_CHANNEL_PLAN_MAP *chplan_map;
311 if (id == RTW_CHPLAN_REALTEK_DEFINE)
312 chplan_map = &RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE;
314 chplan_map = &RTW_ChannelPlanMap[id];
316 if (chplan_map->Index2G == RTW_RD_2G_NULL
317 && chplan_map->Index5G == RTW_RD_5G_NULL)
323 #ifdef CONFIG_DFS_MASTER
324 void rtw_rfctl_reset_cac(struct rf_ctl_t *rfctl)
326 if (rtw_is_long_cac_ch(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset))
327 rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_CE_MS);
329 rfctl->cac_end_time = rtw_get_current_time() + rtw_ms_to_systime(CAC_TIME_MS);
333 * check if channel coverage includes new range and the new range is in DFS range
334 * called after radar_detect_ch,bw,offset is updated
336 bool rtw_is_cac_reset_needed(_adapter *adapter)
338 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
339 bool needed = _FALSE;
340 u32 pre_hi, pre_lo, hi, lo;
343 DBG_871X("pre_radar_detect_ch:%d, pre_radar_detect_by_sta_link:%d\n"
344 , rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_by_sta_link);
346 if (rfctl->pre_radar_detect_by_sta_link == _TRUE)
349 if (rfctl->pre_radar_detect_ch == 0) {
354 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &hi, &lo) == _FALSE)
356 if (rtw_chbw_to_freq_range(rfctl->pre_radar_detect_ch, rfctl->pre_radar_detect_bw, rfctl->pre_radar_detect_offset, &pre_hi, &pre_lo) == _FALSE)
359 if (!rtw_is_range_a_in_b(hi, lo, pre_hi, pre_lo)) {
360 if (rtw_is_range_a_in_b(pre_hi, pre_lo, hi, lo)) {
361 /* currrent is supper set of previous */
362 if (rtw_is_dfs_range(hi, lo))
364 } else if (rtw_is_range_overlap(hi, lo, pre_hi, pre_lo)) {
365 /* currrent is not supper set of previous, but has overlap */
371 if (hi <= pre_lo || hi >= pre_hi) {
372 DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
373 , hi, lo, pre_hi, pre_lo);
377 } else if (hi > pre_hi) {
380 if (lo >= pre_hi && lo <= pre_lo) {
381 DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
382 , hi, lo, pre_hi, pre_lo);
387 DBG_871X_LEVEL(_drv_err_, "hi:%u, lo:%u, pre_hi:%u, pre_lo:%u\n"
388 , hi, lo, pre_hi, pre_lo);
393 if (rtw_is_dfs_range(new_hi, new_lo))
398 if (rtw_is_dfs_range(hi, lo))
407 bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
411 u32 r_hi = 0, r_lo = 0;
414 if (rfctl->radar_detect_ch == 0)
417 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
422 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
423 , rfctl->radar_detect_bw, rfctl->radar_detect_offset
424 , &r_hi, &r_lo) == _FALSE) {
429 if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
436 bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
438 return _rtw_rfctl_overlap_radar_detect_ch(rfctl
439 , rfctl_to_dvobj(rfctl)->oper_channel
440 , rfctl_to_dvobj(rfctl)->oper_bwmode
441 , rfctl_to_dvobj(rfctl)->oper_ch_offset);
444 bool rtw_rfctl_is_tx_blocked_by_cac(struct rf_ctl_t *rfctl)
446 return (rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_UNDER_CAC(rfctl));
449 bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
455 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
458 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
459 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
464 if (!CH_IS_NON_OCP(&ch_set[i]))
467 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
468 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
480 * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
481 * @ch_set: the given channel set
482 * @ch: channel number on which radar is detected
483 * @bw: bandwidth on which radar is detected
484 * @offset: bandwidth offset on which radar is detected
485 * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
487 static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
492 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
495 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
496 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
501 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
502 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
505 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
507 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
515 inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
517 _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
520 inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
522 _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
524 #endif /* CONFIG_DFS_MASTER */
526 bool rtw_choose_available_chbw(_adapter *adapter, u8 req_bw, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset, u8 d_flags)
528 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
531 if (!dec_ch || !dec_bw || !dec_offset) {
536 for (i = 0; i < mlmeext->max_chan_nums; i++) {
538 *dec_ch = mlmeext->channel_set[i].ChannelNum;
540 if (*dec_bw == CHANNEL_WIDTH_20)
541 *dec_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
543 *dec_offset = rtw_get_offset_by_ch(*dec_ch);
545 if ((d_flags & RTW_CHF_2G) && *dec_ch <= 14)
548 if ((d_flags & RTW_CHF_5G) && *dec_ch > 14)
551 rtw_adjust_chbw(adapter, *dec_ch, dec_bw, dec_offset);
553 if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
556 if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
559 if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_ch(*dec_ch, *dec_bw, *dec_offset))
562 if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(*dec_ch, *dec_bw, *dec_offset))
565 if (!rtw_chset_is_ch_non_ocp(mlmeext->channel_set, *dec_ch, *dec_bw, *dec_offset))
569 return (i < mlmeext->max_chan_nums)?_TRUE:_FALSE;
572 void dump_country_chplan(void *sel, const struct country_chplan *ent)
574 DBG_871X_SEL(sel, "\"%c%c\", 0x%02X%s\n"
575 , ent->alpha2[0], ent->alpha2[1], ent->chplan
576 , COUNTRY_CHPLAN_EN_11AC(ent) ? " ac" : ""
580 void dump_country_chplan_map(void *sel)
582 const struct country_chplan *ent;
585 #if RTW_DEF_MODULE_REGULATORY_CERT
586 DBG_871X_SEL(sel, "RTW_DEF_MODULE_REGULATORY_CERT:0x%x\n", RTW_DEF_MODULE_REGULATORY_CERT);
588 #ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP
589 DBG_871X_SEL(sel, "CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP\n");
592 for (code[0] = 'A'; code[0] <= 'Z'; code[0]++) {
593 for (code[1] = 'A'; code[1] <= 'Z'; code[1]++) {
594 ent = rtw_get_chplan_from_country(code);
598 dump_country_chplan(sel, ent);
603 void dump_chplan_id_list(void *sel)
607 for (i = 0; i < RTW_CHPLAN_MAX; i++) {
608 if (!rtw_is_channel_plan_valid(i))
611 DBG_871X_SEL(sel, "0x%02X ", i);
614 DBG_871X_SEL_NL(sel, "0x7F\n");
617 void dump_chplan_test(void *sel)
621 /* check invalid channel */
622 for (i = 0; i < RTW_RD_2G_MAX; i++) {
623 for (j = 0; j < RTW_ChannelPlan2G[i].Len; j++) {
624 if (rtw_ch2freq(RTW_ChannelPlan2G[i].Channel[j]) == 0)
625 DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan2G[i].Channel[j], i, j);
629 for (i = 0; i < RTW_RD_5G_MAX; i++) {
630 for (j = 0; j < RTW_ChannelPlan5G[i].Len; j++) {
631 if (rtw_ch2freq(RTW_ChannelPlan5G[i].Channel[j]) == 0)
632 DBG_871X_SEL_NL(sel, "invalid ch:%u at (%d,%d)\n", RTW_ChannelPlan5G[i].Channel[j], i, j);
637 void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set)
641 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
642 DBG_871X_SEL_NL(sel, "ch:%3u, freq:%u, scan_type:%d"
643 , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType);
645 #ifdef CONFIG_FIND_BEST_CHANNEL
646 DBG_871X_SEL(sel, ", rx_count:%u", ch_set[i].rx_count);
649 #ifdef CONFIG_DFS_MASTER
650 if (rtw_is_dfs_ch(ch_set[i].ChannelNum, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
651 if (CH_IS_NON_OCP(&ch_set[i]))
652 DBG_871X_SEL(sel, ", non_ocp:%d"
653 , rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()));
655 DBG_871X_SEL(sel, ", non_ocp:N/A");
659 DBG_871X_SEL(sel, "\n");
662 DBG_871X_SEL_NL(sel, "total ch number:%d\n", i);
665 void dump_cur_chset(void *sel, _adapter *adapter)
667 struct mlme_priv *mlme = &adapter->mlmepriv;
668 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
669 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
671 if (mlme->country_ent)
672 dump_country_chplan(sel, mlme->country_ent);
674 DBG_871X_SEL_NL(sel, "chplan:0x%02X\n", mlme->ChannelPlan);
676 DBG_871X_SEL_NL(sel, "2G_PLS:%u, 5G_PLS:%u\n"
677 , hal_data->Regulation2_4G, hal_data->Regulation5G);
678 dump_chset(sel, mlmeext->channel_set);
682 * Search the @param ch in given @param ch_set
683 * @ch_set: the given channel set
684 * @ch: the given channel number
686 * return the index of channel_num in channel_set, -1 if not found
688 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
691 for(i=0;ch_set[i].ChannelNum!=0;i++){
692 if(ch == ch_set[i].ChannelNum)
696 if(i >= ch_set[i].ChannelNum)
702 * Check the @param ch is fit with setband setting of @param adapter
703 * @adapter: the given adapter
704 * @ch: the given channel number
706 * return _TRUE when check valid, _FALSE not valid
708 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
710 if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
711 || (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
712 || (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
719 /****************************************************************************
721 Following are the initialization functions for WiFi MLME
723 *****************************************************************************/
725 int init_hw_mlme_ext(_adapter *padapter)
727 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
729 //set_opmode_cmd(padapter, infra_client_with_mlme);//removed
731 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
736 void init_mlme_default_rate_set(_adapter* padapter)
738 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
740 unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,_9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
741 unsigned char mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
742 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0xff, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
744 _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
745 _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
747 _rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
750 static void init_mlme_ext_priv_value(_adapter* padapter)
752 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
753 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
755 ATOMIC_SET(&pmlmeext->event_seq, 0);
756 pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
757 #ifdef CONFIG_IEEE80211W
758 pmlmeext->sa_query_seq = 0;
759 pmlmeext->mgnt_80211w_IPN=0;
760 pmlmeext->mgnt_80211w_IPN_rx=0;
761 #endif //CONFIG_IEEE80211W
762 pmlmeext->cur_channel = padapter->registrypriv.channel;
763 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
764 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
768 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
770 init_mlme_default_rate_set(padapter);
772 if(pmlmeext->cur_channel > 14)
773 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
775 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
777 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
778 pmlmeext->sitesurvey_res.channel_idx = 0;
779 pmlmeext->sitesurvey_res.bss_cnt = 0;
780 pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
781 pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
782 pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
783 #ifdef CONFIG_SCAN_BACKOP
784 mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
785 mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN|SS_BACKOP_PS_ANNC|SS_BACKOP_TX_RESUME);
786 pmlmeext->sitesurvey_res.scan_cnt = 0;
787 pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
788 pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
790 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
791 pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
793 pmlmeext->scan_abort = _FALSE;
795 pmlmeinfo->state = WIFI_FW_NULL_STATE;
796 pmlmeinfo->reauth_count = 0;
797 pmlmeinfo->reassoc_count = 0;
798 pmlmeinfo->link_count = 0;
799 pmlmeinfo->auth_seq = 0;
800 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
801 pmlmeinfo->key_index = 0;
804 pmlmeinfo->enc_algo = _NO_PRIVACY_;
805 pmlmeinfo->authModeToggle = 0;
807 _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
809 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
810 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
812 pmlmeinfo->dialogToken = 0;
814 pmlmeext->action_public_rxseq = 0xffff;
815 pmlmeext->action_public_dialog_token = 0xff;
818 static int has_channel(RT_CHANNEL_INFO *channel_set,
823 for (i = 0; i < chanset_size; i++) {
824 if (channel_set[i].ChannelNum == chan) {
832 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
834 struct p2p_channels *channel_list) {
835 struct registry_priv *regsty = adapter_to_regsty(padapter);
837 struct p2p_oper_class_map op_class[] = {
838 { IEEE80211G, 81, 1, 13, 1, BW20 },
839 { IEEE80211G, 82, 14, 14, 1, BW20 },
840 #if 0 /* Do not enable HT40 on 2 GHz */
841 { IEEE80211G, 83, 1, 9, 1, BW40PLUS },
842 { IEEE80211G, 84, 5, 13, 1, BW40MINUS },
844 { IEEE80211A, 115, 36, 48, 4, BW20 },
845 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
846 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
847 { IEEE80211A, 124, 149, 161, 4, BW20 },
848 { IEEE80211A, 125, 149, 169, 4, BW20 },
849 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
850 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
851 { -1, 0, 0, 0, 0, BW20 }
858 for (op = 0; op_class[op].op_class; op++) {
860 struct p2p_oper_class_map *o = &op_class[op];
861 struct p2p_reg_class *reg = NULL;
863 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
864 if (!has_channel(channel_set, chanset_size, ch)) {
868 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
871 if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) &&
872 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
876 reg = &channel_list->reg_class[cla];
878 reg->reg_class = o->op_class;
881 reg->channel[reg->channels] = ch;
885 channel_list->reg_classes = cla;
889 static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
891 u8 index,chanset_size = 0;
892 u8 b5GBand = _FALSE, b2_4GBand = _FALSE;
893 u8 Index2G = 0, Index5G=0;
894 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
897 if (!rtw_is_channel_plan_valid(ChannelPlan)) {
898 DBG_871X_LEVEL(_drv_err_, "ChannelPlan ID 0x%02X error !!!!!\n", ChannelPlan);
902 _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
904 if (IsSupported24G(padapter->registrypriv.wireless_mode))
907 if (IsSupported5G(padapter->registrypriv.wireless_mode))
911 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
912 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
914 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
916 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
917 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
919 if (RTW_CHPLAN_GLOBAL_DOAMIN == ChannelPlan
920 || RTW_CHPLAN_GLOBAL_NULL == ChannelPlan
922 /* Channel 1~11 is active, and 12~14 is passive */
923 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
924 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
925 else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
926 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
927 } else if (RTW_CHPLAN_WORLD_WIDE_13 == ChannelPlan
928 || RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan
929 || RTW_RD_2G_WORLD == Index2G
931 /* channel 12~13, passive scan */
932 if(channel_set[chanset_size].ChannelNum <= 11)
933 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
935 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
937 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
945 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
946 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
948 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
950 for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) {
952 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
953 if ( channel_set[chanset_size].ChannelNum <= 48
954 || channel_set[chanset_size].ChannelNum >= 149 )
956 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
957 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
959 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
963 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
966 #else /* CONFIG_DFS */
967 if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
968 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149
970 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
971 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
972 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
974 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
975 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
978 #endif /* CONFIG_DFS */
982 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) {
983 hal_data->Regulation2_4G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
984 hal_data->Regulation5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
986 hal_data->Regulation2_4G = RTW_ChannelPlanMap[ChannelPlan].regd;
987 hal_data->Regulation5G = RTW_ChannelPlanMap[ChannelPlan].regd;
990 #ifdef CONFIG_DFS_MASTER
991 for (i = 0; i < chanset_size; i++)
992 channel_set[i].non_ocp_end_time = rtw_get_current_time();
995 DBG_871X(FUNC_ADPT_FMT" ChannelPlan ID:0x%02x, ch num:%d\n"
996 , FUNC_ADPT_ARG(padapter), ChannelPlan, chanset_size);
1001 int init_mlme_ext_priv(_adapter* padapter)
1004 struct registry_priv* pregistrypriv = &padapter->registrypriv;
1005 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1006 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1007 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1009 // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
1010 //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
1012 pmlmeext->padapter = padapter;
1014 //fill_fwpriv(padapter, &(pmlmeext->fwpriv));
1016 init_mlme_ext_priv_value(padapter);
1017 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1019 init_mlme_ext_timer(padapter);
1021 #ifdef CONFIG_AP_MODE
1022 init_mlme_ap_info(padapter);
1025 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
1026 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
1027 pmlmeext->last_scan_time = 0;
1028 pmlmeext->mlmeext_init = _TRUE;
1031 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
1032 pmlmeext->active_keep_alive_check = _TRUE;
1034 pmlmeext->active_keep_alive_check = _FALSE;
1037 #ifdef DBG_FIXED_CHAN
1038 pmlmeext->fixed_chan = 0xFF;
1045 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
1047 _adapter *padapter = pmlmeext->padapter;
1052 if (rtw_is_drv_stopped(padapter)) {
1053 _cancel_timer_ex(&pmlmeext->survey_timer);
1054 _cancel_timer_ex(&pmlmeext->link_timer);
1055 //_cancel_timer_ex(&pmlmeext->ADDBA_timer);
1059 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
1060 { // if the channel is same, return 0. else return channel differential
1064 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
1068 if(padapter->mlmeextpriv.cur_channel >= channel)
1070 return (padapter->mlmeextpriv.cur_channel - channel);
1074 return (channel-padapter->mlmeextpriv.cur_channel);
1083 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1085 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1086 u8 *pframe = precv_frame->u.hdr.rx_data;
1090 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1091 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1092 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1097 ptable->func(padapter, precv_frame);
1102 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1105 struct mlme_handler *ptable;
1106 #ifdef CONFIG_AP_MODE
1107 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1108 #endif //CONFIG_AP_MODE
1109 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1110 u8 *pframe = precv_frame->u.hdr.rx_data;
1111 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
1112 struct dvobj_priv *psdpriv = padapter->dvobj;
1113 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1115 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1116 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
1117 GetFrameType(pframe), GetFrameSubType(pframe)));
1122 pbuf = GetAddr1Ptr(pframe);
1123 DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1124 pbuf = GetAddr2Ptr(pframe);
1125 DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1126 pbuf = GetAddr3Ptr(pframe);
1127 DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1131 if (GetFrameType(pframe) != WIFI_MGT_TYPE)
1133 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
1137 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1138 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1139 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1144 ptable = mlme_sta_tbl;
1146 index = GetFrameSubType(pframe) >> 4;
1149 if((index << 4)==WIFI_ACTION){
1150 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1151 if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) {
1152 DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe)));
1153 On_TDLS_Dis_Rsp(padapter, precv_frame);
1156 #endif //CONFIG_TDLS
1158 if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler)))
1160 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
1168 if (GetRetry(pframe))
1170 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
1172 /* drop the duplicate management frame */
1173 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
1174 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1178 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1182 if(GetRetry(pframe))
1184 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
1189 #ifdef CONFIG_AP_MODE
1190 switch (GetFrameSubType(pframe))
1193 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1194 ptable->func = &OnAuth;
1196 ptable->func = &OnAuthClient;
1199 case WIFI_REASSOCREQ:
1200 _mgt_dispatcher(padapter, ptable, precv_frame);
1201 #ifdef CONFIG_HOSTAPD_MLME
1202 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1203 rtw_hostapd_mlme_rx(padapter, precv_frame);
1207 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1209 #ifdef CONFIG_HOSTAPD_MLME
1210 rtw_hostapd_mlme_rx(padapter, precv_frame);
1212 _mgt_dispatcher(padapter, ptable, precv_frame);
1216 _mgt_dispatcher(padapter, ptable, precv_frame);
1219 _mgt_dispatcher(padapter, ptable, precv_frame);
1222 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1223 _mgt_dispatcher(padapter, ptable, precv_frame);
1226 _mgt_dispatcher(padapter, ptable, precv_frame);
1227 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1228 rtw_hostapd_mlme_rx(padapter, precv_frame);
1233 _mgt_dispatcher(padapter, ptable, precv_frame);
1240 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1242 bool response = _TRUE;
1244 #ifdef CONFIG_IOCTL_CFG80211
1245 if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
1247 if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE
1248 || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1249 || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1250 || padapter->mlmepriv.wps_probe_resp_ie == NULL
1251 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
1254 #ifdef CONFIG_DEBUG_CFG80211
1255 DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ",
1256 adapter_wdev_data(padapter)->p2p_enabled,
1257 padapter->mlmepriv.wps_probe_resp_ie,
1258 padapter->mlmepriv.p2p_probe_resp_ie);
1259 DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n",
1260 padapter->cfg80211_wdinfo.is_ro_ch,
1261 rtw_get_oper_ch(padapter),
1262 padapter->wdinfo.listen_channel);
1268 #endif //CONFIG_IOCTL_CFG80211
1269 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1271 // do nothing if the device name is empty
1272 if ( !padapter->wdinfo.device_name_len )
1278 if (response == _TRUE)
1279 issue_probersp_p2p( padapter, da);
1286 /****************************************************************************
1288 Following are the callback functions for each subtype of the management frames
1290 *****************************************************************************/
1292 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1296 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1297 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1298 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1299 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1300 u8 *pframe = precv_frame->u.hdr.rx_data;
1301 uint len = precv_frame->u.hdr.len;
1302 u8 is_valid_p2p_probereq = _FALSE;
1304 #ifdef CONFIG_ATMEL_RC_PATCH
1305 u8 *target_ie=NULL, *wps_ie=NULL;
1307 uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1308 struct sta_info *psta;
1309 struct sta_priv *pstapriv = &padapter->stapriv;
1314 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1315 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1316 u8 wifi_test_chk_rate = 1;
1318 #ifdef CONFIG_IOCTL_CFG80211
1319 if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1320 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1321 && (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1323 rtw_cfg80211_rx_probe_request(padapter, pframe, len);
1326 #endif /* CONFIG_IOCTL_CFG80211 */
1328 if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1329 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
1330 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1331 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1332 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1335 // Commented by Albert 2011/03/17
1336 // mcs_rate = 0 -> CCK 1M rate
1337 // mcs_rate = 1 -> CCK 2M rate
1338 // mcs_rate = 2 -> CCK 5.5M rate
1339 // mcs_rate = 3 -> CCK 11M rate
1340 // In the P2P mode, the driver should not support the CCK rate
1342 // Commented by Kurt 2012/10/16
1343 // IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
1344 if (padapter->registrypriv.wifi_spec == 1)
1346 if ( pattrib->data_rate <= 3 )
1348 wifi_test_chk_rate = 0;
1352 if( wifi_test_chk_rate == 1 )
1354 if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
1356 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
1359 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1360 report_survey_event(padapter, precv_frame);
1362 p2p_listen_state_process( padapter, get_sa(pframe));
1367 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1378 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1383 if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
1384 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
1390 //DBG_871X("+OnProbeReq\n");
1393 #ifdef CONFIG_ATMEL_RC_PATCH
1394 if ((wps_ie = rtw_get_wps_ie(
1395 pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1396 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1397 NULL, &wps_ielen))) {
1399 target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1401 if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) {
1402 //psta->flag_atmel_rc = 1;
1403 unsigned char *sa_addr = get_sa(pframe);
1404 printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n",
1405 __func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5));
1406 _rtw_memcpy( pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1411 #ifdef CONFIG_AUTO_AP_MODE
1412 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1413 pmlmepriv->cur_network.join_res == _TRUE)
1416 struct sta_info *psta;
1417 u8 *mac_addr, *peer_addr;
1418 struct sta_priv *pstapriv = &padapter->stapriv;
1419 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
1420 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
1422 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1423 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1425 if(!p || ielen !=14)
1426 goto _non_rc_device;
1428 if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
1429 goto _non_rc_device;
1431 if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
1433 DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1434 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
1436 goto _non_rc_device;
1439 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
1442 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1445 // allocate a new one
1446 DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
1447 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1451 DBG_871X(" Exceed the upper limit of supported clients...\n");
1455 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1456 if (rtw_is_list_empty(&psta->asoc_list))
1458 psta->expire_to = pstapriv->expire_to;
1459 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1460 pstapriv->asoc_list_cnt++;
1462 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1464 //generate pairing ID
1465 mac_addr = adapter_mac_addr(padapter);
1466 peer_addr = psta->hwaddr;
1467 psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
1469 //update peer stainfo
1474 /* get a unique AID */
1475 if (psta->aid > 0) {
1476 DBG_871X("old AID %d\n", psta->aid);
1478 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1479 if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1482 if (psta->aid > pstapriv->max_num_sta) {
1484 DBG_871X("no room for more AIDs\n");
1487 pstapriv->sta_aid[psta->aid - 1] = psta;
1488 DBG_871X("allocate new AID = (%d)\n", psta->aid);
1492 psta->qos_option = 1;
1493 psta->bw_mode = CHANNEL_WIDTH_20;
1494 psta->ieee8021x_blocked = _FALSE;
1495 #ifdef CONFIG_80211N_HT
1496 psta->htpriv.ht_option = _TRUE;
1497 psta->htpriv.ampdu_enable = _FALSE;
1498 psta->htpriv.sgi_20m = _FALSE;
1499 psta->htpriv.sgi_40m = _FALSE;
1500 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1501 psta->htpriv.agg_enable_bitmap = 0x0;//reset
1502 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
1505 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1507 _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1509 _enter_critical_bh(&psta->lock, &irqL);
1510 psta->state |= _FW_LINKED;
1511 _exit_critical_bh(&psta->lock, &irqL);
1513 report_add_sta_event(padapter, psta->hwaddr);
1517 issue_probersp(padapter, get_sa(pframe), _FALSE);
1527 #endif //CONFIG_AUTO_AP_MODE
1530 #ifdef CONFIG_CONCURRENT_MODE
1531 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1532 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1534 //don't process probe req
1539 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1540 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1543 //check (wildcard) SSID
1546 if(is_valid_p2p_probereq == _TRUE)
1548 goto _issue_probersp;
1551 if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1552 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1559 if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1560 pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1562 //DBG_871X("+issue_probersp during ap mode\n");
1563 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
1572 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1574 struct sta_info *psta;
1575 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1576 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1577 struct sta_priv *pstapriv = &padapter->stapriv;
1578 u8 *pframe = precv_frame->u.hdr.rx_data;
1580 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1585 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
1587 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
1589 if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1591 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
1593 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1594 issue_p2p_provision_request( padapter,
1595 pwdinfo->tx_prov_disc_info.ssid.Ssid,
1596 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1597 pwdinfo->tx_prov_disc_info.peerDevAddr );
1599 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
1601 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1602 issue_p2p_provision_request( padapter,
1605 pwdinfo->tx_prov_disc_info.peerDevAddr );
1611 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
1613 if ( _TRUE == pwdinfo->nego_req_info.benable )
1615 DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
1616 if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1618 pwdinfo->nego_req_info.benable = _FALSE;
1619 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
1623 else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
1625 if ( _TRUE == pwdinfo->invitereq_info.benable )
1627 DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
1628 if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1630 pwdinfo->invitereq_info.benable = _FALSE;
1631 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
1638 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1639 report_survey_event(padapter, precv_frame);
1640 #ifdef CONFIG_CONCURRENT_MODE
1641 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1646 #if 0 //move to validate_recv_mgnt_frame
1647 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1649 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1651 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1653 psta->sta_stats.rx_mgnt_pkts++;
1663 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1665 struct sta_info *psta;
1666 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1667 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1668 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1669 struct sta_priv *pstapriv = &padapter->stapriv;
1670 u8 *pframe = precv_frame->u.hdr.rx_data;
1671 uint len = precv_frame->u.hdr.len;
1672 WLAN_BSSID_EX *pbss;
1677 struct sta_info *ptdls_sta;
1678 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1679 #ifdef CONFIG_TDLS_CH_SW
1680 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
1682 #endif /* CONFIG_TDLS */
1684 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1685 p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
1686 if ((p != NULL) && (ielen > 0))
1688 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
1690 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
1691 DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe)));
1692 *(p + 1) = ielen - 1;
1697 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1698 report_survey_event(padapter, precv_frame);
1699 #ifdef CONFIG_CONCURRENT_MODE
1700 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1705 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1707 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1709 //we should update current network before auth, or some IE is wrong
1710 pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1712 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1713 struct beacon_keys recv_beacon;
1715 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1716 rtw_get_bcn_info(&(pmlmepriv->cur_network));
1719 if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1720 DBG_871X("%s: beacon keys ready\n", __func__);
1721 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1722 &recv_beacon, sizeof(recv_beacon));
1723 pmlmepriv->new_beacon_cnts = 0;
1726 DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__);
1727 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1728 pmlmepriv->new_beacon_cnts = 0;
1731 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1734 //check the vendor of the assoc AP
1735 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
1738 update_TSF(pmlmeext, pframe, len);
1740 //reset for adaptive_early_32k
1741 pmlmeext->adaptive_tsf_done = _FALSE;
1742 pmlmeext->DrvBcnEarly = 0xff;
1743 pmlmeext->DrvBcnTimeOut = 0xff;
1744 pmlmeext->bcn_cnt = 0;
1745 _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1746 _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1748 #ifdef CONFIG_P2P_PS
1749 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1750 #endif //CONFIG_P2P_PS
1752 #if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE)
1753 if (padapter->registrypriv.wifi_spec) {
1754 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1755 if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
1756 DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n ");
1761 #endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE
1764 start_clnt_auth(padapter);
1769 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1771 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1773 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1774 //Merge from 8712 FW code
1775 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
1776 { // join wrong channel, deauth and reconnect
1777 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1779 report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE, _FALSE);
1780 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1783 #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
1785 ret = rtw_check_bcn_info(padapter, pframe, len);
1787 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1788 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
1791 //update WMM, ERP in the beacon
1792 //todo: the timer is used instead of the number of the beacon received
1793 if ((sta_rx_pkts(psta) & 0xf) == 0)
1795 //DBG_871X("update_bcn_info\n");
1796 update_beacon_info(padapter, pframe, len, psta);
1799 adaptive_early_32k(pmlmeext, pframe, len);
1802 #ifdef CONFIG_TDLS_CH_SW
1803 if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE)
1805 /* Send TDLS Channel Switch Request when receiving Beacon */
1806 if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
1807 && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1808 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1809 if (ptdls_sta != NULL) {
1810 if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
1811 _set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
1816 #endif /* CONFIG_TDLS */
1819 process_csa_ie(padapter, pframe, len); //channel switch announcement
1822 #ifdef CONFIG_P2P_PS
1823 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1824 #endif //CONFIG_P2P_PS
1826 if (pmlmeext->en_hw_update_tsf)
1827 rtw_enable_hw_update_tsf_cmd(padapter);
1829 #if 0 //move to validate_recv_mgnt_frame
1830 psta->sta_stats.rx_mgnt_pkts++;
1834 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
1839 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1842 * update WMM, ERP in the beacon
1843 * todo: the timer is used instead of the number of the beacon received
1845 if ((sta_rx_pkts(psta) & 0xf) == 0)
1846 update_beacon_info(padapter, pframe, len, psta);
1848 if (pmlmeext->en_hw_update_tsf)
1849 rtw_enable_hw_update_tsf_cmd(padapter);
1852 rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_, rate_set, &rate_num);
1853 if (rate_num == 0) {
1854 DBG_871X(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
1855 goto _END_ONBEACON_;
1858 psta = rtw_alloc_stainfo(pstapriv, GetAddr2Ptr(pframe));
1860 DBG_871X(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
1861 goto _END_ONBEACON_;
1864 psta->expire_to = pstapriv->adhoc_expire_to;
1866 _rtw_memcpy(psta->bssrateset, rate_set, rate_num);
1867 psta->bssratelen = rate_num;
1870 update_TSF(pmlmeext, pframe, len);
1872 //report sta add event
1873 report_add_sta_event(padapter, GetAddr2Ptr(pframe));
1884 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1886 #ifdef CONFIG_AP_MODE
1888 unsigned int auth_mode, seq, ie_len;
1889 unsigned char *sa, *p;
1892 static struct sta_info stat;
1893 struct sta_info *pstat=NULL;
1894 struct sta_priv *pstapriv = &padapter->stapriv;
1895 struct security_priv *psecuritypriv = &padapter->securitypriv;
1896 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1897 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1898 u8 *pframe = precv_frame->u.hdr.rx_data;
1899 uint len = precv_frame->u.hdr.len;
1903 #ifdef CONFIG_CONCURRENT_MODE
1904 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1905 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1907 //don't process auth request;
1910 #endif //CONFIG_CONCURRENT_MODE
1912 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1915 DBG_871X("+OnAuth\n");
1917 sa = GetAddr2Ptr(pframe);
1919 auth_mode = psecuritypriv->dot11AuthAlgrthm;
1921 if (GetPrivacy(pframe))
1924 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
1926 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
1927 prxattrib->encrypt = _WEP40_;
1929 iv = pframe+prxattrib->hdrlen;
1930 prxattrib->key_index = ((iv[3]>>6)&0x3);
1932 prxattrib->iv_len = 4;
1933 prxattrib->icv_len = 4;
1935 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
1940 algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1941 seq = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1943 DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
1945 if (auth_mode == 2 &&
1946 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1947 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1950 if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled
1951 (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled
1953 DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1954 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1956 status = _STATS_NO_SUPP_ALG_;
1962 phead = &priv->wlan_acl_list;
1963 plist = phead->next;
1965 if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected.
1970 while(plist != phead)
1972 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
1973 plist = plist->next;
1974 if (!memcmp((void *)sa, paclnode->addr, 6)) {
1975 if (paclnode->mode & 2) { // deny
1986 if (res != SUCCESS) {
1987 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
1991 if(rtw_access_ctrl(padapter, sa) == _FALSE)
1993 status = _STATS_UNABLE_HANDLE_STA_;
1998 pstat = rtw_get_stainfo(pstapriv, sa);
2002 // allocate a new one
2003 DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
2004 pstat = rtw_alloc_stainfo(pstapriv, sa);
2007 DBG_871X(" Exceed the upper limit of supported clients...\n");
2008 status = _STATS_UNABLE_HANDLE_STA_;
2012 pstat->state = WIFI_FW_AUTH_NULL;
2013 pstat->auth_seq = 0;
2016 //pstat->capability = 0;
2018 #ifdef CONFIG_IEEE80211W
2019 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2020 #endif /* CONFIG_IEEE80211W */
2023 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2024 if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
2025 rtw_list_delete(&pstat->asoc_list);
2026 pstapriv->asoc_list_cnt--;
2027 if (pstat->expire_to > 0)
2028 ;/* TODO: STA re_auth within expire_to */
2030 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2033 ; /* TODO: STA re_auth and auth timeout */
2038 #ifdef CONFIG_IEEE80211W
2039 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2040 #endif /* CONFIG_IEEE80211W */
2042 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2043 if (rtw_is_list_empty(&pstat->auth_list)) {
2045 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2046 pstapriv->auth_list_cnt++;
2048 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2051 if (pstat->auth_seq == 0)
2052 pstat->expire_to = pstapriv->auth_to;
2055 if ((pstat->auth_seq + 1) != seq)
2057 DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2058 seq, pstat->auth_seq+1);
2059 status = _STATS_OUT_OF_AUTH_SEQ_;
2063 if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
2067 #ifdef CONFIG_IEEE80211W
2068 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2069 #endif /* CONFIG_IEEE80211W */
2071 pstat->state &= ~WIFI_FW_AUTH_NULL;
2072 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2073 pstat->expire_to = pstapriv->assoc_to;
2075 pstat->authalg = algorithm;
2079 DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2080 seq, pstat->auth_seq+1);
2081 status = _STATS_OUT_OF_AUTH_SEQ_;
2085 else // shared system or auto authentication
2089 //prepare for the challenging txt...
2091 //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
2092 _rtw_memset((void *)pstat->chg_txt, 78, 128);
2093 #ifdef CONFIG_IEEE80211W
2094 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2095 #endif /* CONFIG_IEEE80211W */
2097 pstat->state &= ~WIFI_FW_AUTH_NULL;
2098 pstat->state |= WIFI_FW_AUTH_STATE;
2100 pstat->authalg = algorithm;
2101 pstat->auth_seq = 2;
2105 //checking for challenging txt...
2106 DBG_871X("checking for challenging txt...\n");
2108 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2109 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2111 if((p==NULL) || (ie_len<=0))
2113 DBG_871X("auth rejected because challenge failure!(1)\n");
2114 status = _STATS_CHALLENGE_FAIL_;
2118 if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
2120 #ifdef CONFIG_IEEE80211W
2121 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2122 #endif /* CONFIG_IEEE80211W */
2124 pstat->state &= (~WIFI_FW_AUTH_STATE);
2125 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2126 /* challenging txt is correct... */
2127 pstat->expire_to = pstapriv->assoc_to;
2132 DBG_871X("auth rejected because challenge failure!\n");
2133 status = _STATS_CHALLENGE_FAIL_;
2139 DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2140 seq, pstat->auth_seq+1);
2141 status = _STATS_OUT_OF_AUTH_SEQ_;
2147 // Now, we are going to issue_auth...
2148 pstat->auth_seq = seq + 1;
2150 #ifdef CONFIG_NATIVEAP_MLME
2151 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2154 if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2155 pstat->auth_seq = 0;
2163 rtw_free_stainfo(padapter , pstat);
2166 _rtw_memset((char *)pstat, '\0', sizeof(stat));
2167 pstat->auth_seq = 2;
2168 _rtw_memcpy(pstat->hwaddr, sa, 6);
2170 #ifdef CONFIG_NATIVEAP_MLME
2171 issue_auth(padapter, pstat, (unsigned short)status);
2179 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2181 unsigned int seq, len, status, algthm, offset;
2183 unsigned int go2asoc = 0;
2184 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2185 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2186 u8 *pframe = precv_frame->u.hdr.rx_data;
2187 uint pkt_len = precv_frame->u.hdr.len;
2189 DBG_871X("%s\n", __FUNCTION__);
2191 //check A1 matches or not
2192 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2195 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2198 offset = (GetPrivacy(pframe))? 4: 0;
2200 algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2201 seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2202 status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2206 DBG_871X("clnt auth fail, status: %d\n", status);
2207 if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
2209 if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2210 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2212 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2213 //pmlmeinfo->reauth_count = 0;
2216 set_link_timer(pmlmeext, 1);
2222 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2224 // legendary shared system
2225 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2226 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2230 //DBG_871X("marc: no challenge text?\n");
2234 _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2235 pmlmeinfo->auth_seq = 3;
2236 issue_auth(padapter, NULL, 0);
2237 set_link_timer(pmlmeext, REAUTH_TO);
2249 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2260 // this is also illegal
2261 //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
2267 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
2268 start_clnt_assoc(padapter);
2274 //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
2280 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2282 #ifdef CONFIG_AP_MODE
2284 u16 capab_info, listen_interval;
2285 struct rtw_ieee802_11_elems elems;
2286 struct sta_info *pstat;
2287 unsigned char reassoc, *p, *pos, *wpa_ie;
2288 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2289 int i, ie_len, wpa_ie_len, left;
2292 unsigned short status = _STATS_SUCCESSFUL_;
2293 unsigned short frame_type, ie_offset=0;
2294 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2295 struct security_priv *psecuritypriv = &padapter->securitypriv;
2296 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2297 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2298 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
2299 struct sta_priv *pstapriv = &padapter->stapriv;
2300 u8 *pframe = precv_frame->u.hdr.rx_data;
2301 uint pkt_len = precv_frame->u.hdr.len;
2303 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2304 u8 p2p_status_code = P2P_STATUS_SUCCESS;
2309 #ifdef CONFIG_CONCURRENT_MODE
2310 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
2311 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
2313 //don't process assoc request;
2316 #endif //CONFIG_CONCURRENT_MODE
2318 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2321 frame_type = GetFrameSubType(pframe);
2322 if (frame_type == WIFI_ASSOCREQ)
2325 ie_offset = _ASOCREQ_IE_OFFSET_;
2327 else // WIFI_REASSOCREQ
2330 ie_offset = _REASOCREQ_IE_OFFSET_;
2334 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2335 DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2336 "\n", reassoc, (unsigned long)pkt_len);
2340 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2341 if (pstat == (struct sta_info *)NULL)
2343 status = _RSON_CLS2_;
2344 goto asoc_class2_error;
2347 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
2348 //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2349 //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
2350 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
2352 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2353 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2356 DBG_871X("%s\n", __FUNCTION__);
2358 // check if this stat has been successfully authenticated/assocated
2359 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
2361 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
2363 status = _RSON_CLS2_;
2364 goto asoc_class2_error;
2368 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2369 pstat->state |= WIFI_FW_ASSOC_STATE;
2374 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2375 pstat->state |= WIFI_FW_ASSOC_STATE;
2379 #if 0// todo:tkip_countermeasures
2380 if (hapd->tkip_countermeasures) {
2381 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2386 pstat->capability = capab_info;
2389 //check listen_interval
2390 if (listen_interval > hapd->conf->max_listen_interval) {
2391 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2392 HOSTAPD_LEVEL_DEBUG,
2393 "Too large Listen Interval (%d)",
2395 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2399 pstat->listen_interval = listen_interval;
2402 //now parse all ieee802_11 ie to point to elems
2403 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2405 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
2406 MAC_ARG(pstat->hwaddr));
2407 status = _STATS_FAILURE_;
2408 goto OnAssocReqFail;
2412 // now we should check all the fields...
2414 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2415 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2418 status = _STATS_FAILURE_;
2421 if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
2422 status = _STATS_FAILURE_;
2425 // check if ssid match
2426 if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2427 status = _STATS_FAILURE_;
2429 if (ie_len != cur->Ssid.SsidLength)
2430 status = _STATS_FAILURE_;
2433 if(_STATS_SUCCESSFUL_ != status)
2434 goto OnAssocReqFail;
2436 rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, rate_set, &rate_num);
2437 if (rate_num == 0) {
2438 DBG_871X(FUNC_ADPT_FMT" RX assoc-req with no supported rate\n", FUNC_ADPT_ARG(padapter));
2439 status = _STATS_FAILURE_;
2440 goto OnAssocReqFail;
2442 _rtw_memcpy(pstat->bssrateset, rate_set, rate_num);
2443 pstat->bssratelen = rate_num;
2444 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2447 pstat->dot8021xalg = 0;
2449 pstat->wpa_group_cipher = 0;
2450 pstat->wpa2_group_cipher = 0;
2451 pstat->wpa_pairwise_cipher = 0;
2452 pstat->wpa2_pairwise_cipher = 0;
2453 _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2454 if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2456 int group_cipher=0, pairwise_cipher=0;
2458 wpa_ie = elems.rsn_ie;
2459 wpa_ie_len = elems.rsn_ie_len;
2461 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2463 pstat->dot8021xalg = 1;//psk, todo:802.1x
2464 pstat->wpa_psk |= BIT(1);
2466 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
2467 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
2469 if(!pstat->wpa2_group_cipher)
2470 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2472 if(!pstat->wpa2_pairwise_cipher)
2473 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2477 status = WLAN_STATUS_INVALID_IE;
2480 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2482 int group_cipher=0, pairwise_cipher=0;
2484 wpa_ie = elems.wpa_ie;
2485 wpa_ie_len = elems.wpa_ie_len;
2487 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2489 pstat->dot8021xalg = 1;//psk, todo:802.1x
2490 pstat->wpa_psk |= BIT(0);
2492 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
2493 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
2495 if(!pstat->wpa_group_cipher)
2496 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2498 if(!pstat->wpa_pairwise_cipher)
2499 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2504 status = WLAN_STATUS_INVALID_IE;
2512 if(_STATS_SUCCESSFUL_ != status)
2513 goto OnAssocReqFail;
2515 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2516 //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
2517 if(wpa_ie == NULL) {
2519 DBG_871X("STA included WPS IE in "
2520 "(Re)Association Request - assume WPS is "
2522 pstat->flags |= WLAN_STA_WPS;
2523 //wpabuf_free(sta->wps_ie);
2524 //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
2525 // elems.wps_ie_len - 4);
2527 DBG_871X("STA did not include WPA/RSN IE "
2528 "in (Re)Association Request - possible WPS "
2530 pstat->flags |= WLAN_STA_MAYBE_WPS;
2534 // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
2535 // that the selected registrar of AP is _FLASE
2536 if((psecuritypriv->wpa_psk >0)
2537 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
2539 if(pmlmepriv->wps_beacon_ie)
2541 u8 selected_registrar = 0;
2543 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2545 if(!selected_registrar)
2547 DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2549 status = _STATS_UNABLE_HANDLE_STA_;
2551 goto OnAssocReqFail;
2561 if(psecuritypriv->wpa_psk == 0)
2563 DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
2564 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2566 status = WLAN_STATUS_INVALID_IE;
2568 goto OnAssocReqFail;
2573 DBG_871X("STA included WPS IE in "
2574 "(Re)Association Request - WPS is "
2576 pstat->flags |= WLAN_STA_WPS;
2581 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
2586 _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
2591 // check if there is WMM IE & support WWM-PS
2592 pstat->flags &= ~WLAN_STA_WME;
2593 pstat->qos_option = 0;
2594 pstat->qos_info = 0;
2595 pstat->has_legacy_ac = _TRUE;
2596 pstat->uapsd_vo = 0;
2597 pstat->uapsd_vi = 0;
2598 pstat->uapsd_be = 0;
2599 pstat->uapsd_bk = 0;
2600 if (pmlmepriv->qospriv.qos_option)
2602 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
2605 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2607 if (_rtw_memcmp(p+2, WMM_IE, 6)) {
2609 pstat->flags |= WLAN_STA_WME;
2611 pstat->qos_option = 1;
2612 pstat->qos_info = *(p+8);
2614 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
2616 if((pstat->qos_info&0xf) !=0xf)
2617 pstat->has_legacy_ac = _TRUE;
2619 pstat->has_legacy_ac = _FALSE;
2621 if(pstat->qos_info&0xf)
2623 if(pstat->qos_info&BIT(0))
2624 pstat->uapsd_vo = BIT(0)|BIT(1);
2626 pstat->uapsd_vo = 0;
2628 if(pstat->qos_info&BIT(1))
2629 pstat->uapsd_vi = BIT(0)|BIT(1);
2631 pstat->uapsd_vi = 0;
2633 if(pstat->qos_info&BIT(2))
2634 pstat->uapsd_bk = BIT(0)|BIT(1);
2636 pstat->uapsd_bk = 0;
2638 if(pstat->qos_info&BIT(3))
2639 pstat->uapsd_be = BIT(0)|BIT(1);
2641 pstat->uapsd_be = 0;
2656 #ifdef CONFIG_80211N_HT
2657 /* save HT capabilities in the sta object */
2658 _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2659 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
2661 pstat->flags |= WLAN_STA_HT;
2663 pstat->flags |= WLAN_STA_WME;
2665 _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
2668 pstat->flags &= ~WLAN_STA_HT;
2671 if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
2673 status = _STATS_FAILURE_;
2674 goto OnAssocReqFail;
2677 #endif /* CONFIG_80211N_HT */
2679 #ifdef CONFIG_80211AC_VHT
2680 _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
2681 if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
2682 pstat->flags |= WLAN_STA_VHT;
2684 _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
2686 if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1) {
2687 _rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1);
2689 else // for Frame without Operating Mode notify ie; default: 80M
2691 pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
2695 pstat->flags &= ~WLAN_STA_VHT;
2698 if((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT))
2700 status = _STATS_FAILURE_;
2701 goto OnAssocReqFail;
2703 #endif /* CONFIG_80211AC_VHT */
2705 if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
2706 ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
2707 (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2709 DBG_871X("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr));
2711 pstat->flags &= ~WLAN_STA_HT;
2712 pstat->flags &= ~WLAN_STA_VHT;
2713 /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2714 * goto OnAssocReqFail;
2720 //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
2721 pstat->flags |= WLAN_STA_NONERP;
2722 for (i = 0; i < pstat->bssratelen; i++) {
2723 if ((pstat->bssrateset[i] & 0x7f) > 22) {
2724 pstat->flags &= ~WLAN_STA_NONERP;
2729 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2730 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2732 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2736 if (status != _STATS_SUCCESSFUL_)
2737 goto OnAssocReqFail;
2740 pstat->is_p2p_device = _FALSE;
2741 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2743 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
2745 pstat->is_p2p_device = _TRUE;
2746 if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
2748 pstat->p2p_status_code = p2p_status_code;
2749 status = _STATS_CAP_FAIL_;
2750 goto OnAssocReqFail;
2754 rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
2757 pstat->p2p_status_code = p2p_status_code;
2760 //TODO: identify_proprietary_vendor_ie();
2761 // Realtek proprietary IE
2762 // identify if this is Broadcom sta
2763 // identify if this is ralink sta
2764 // Customer proprietary IE
2768 /* get a unique AID */
2769 if (pstat->aid > 0) {
2770 DBG_871X(" old AID %d\n", pstat->aid);
2772 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2773 if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2774 if (pstat->aid > pstapriv->max_num_sta) {
2777 DBG_871X(" no room for more AIDs\n");
2779 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2781 goto OnAssocReqFail;
2785 pstapriv->sta_aid[pstat->aid - 1] = pstat;
2786 DBG_871X("allocate new AID = (%d)\n", pstat->aid);
2794 pstat->state &= (~WIFI_FW_ASSOC_STATE);
2795 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2796 /* DBG_871X("==================%s, %d, (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2797 , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */
2798 #ifdef CONFIG_IEEE80211W
2799 if (pstat->bpairwise_key_installed != _TRUE)
2800 #endif /* CONFIG_IEEE80211W */
2802 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2803 if (!rtw_is_list_empty(&pstat->auth_list)) {
2804 rtw_list_delete(&pstat->auth_list);
2805 pstapriv->auth_list_cnt--;
2807 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2809 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2810 if (rtw_is_list_empty(&pstat->asoc_list)) {
2811 pstat->expire_to = pstapriv->expire_to;
2812 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2813 pstapriv->asoc_list_cnt++;
2815 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2818 // now the station is qualified to join our BSS...
2819 if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
2821 #ifdef CONFIG_NATIVEAP_MLME
2822 #ifdef CONFIG_IEEE80211W
2823 if (pstat->bpairwise_key_installed != _TRUE)
2824 #endif /* CONFIG_IEEE80211W */
2826 /* .1 bss_cap_update & sta_info_update */
2827 bss_cap_update_on_sta_join(padapter, pstat);
2828 sta_info_update(padapter, pstat);
2830 #ifdef CONFIG_IEEE80211W
2831 if (pstat->bpairwise_key_installed == _TRUE)
2832 status = _STATS_REFUSED_TEMPORARILY_;
2833 #endif /* CONFIG_IEEE80211W */
2834 //.2 issue assoc rsp before notify station join event.
2835 if (frame_type == WIFI_ASSOCREQ)
2836 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2838 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2840 #ifdef CONFIG_IOCTL_CFG80211
2841 _enter_critical_bh(&pstat->lock, &irqL);
2842 if(pstat->passoc_req)
2844 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2845 pstat->passoc_req = NULL;
2846 pstat->assoc_req_len = 0;
2849 pstat->passoc_req = rtw_zmalloc(pkt_len);
2850 if(pstat->passoc_req)
2852 _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2853 pstat->assoc_req_len = pkt_len;
2855 _exit_critical_bh(&pstat->lock, &irqL);
2856 #endif //CONFIG_IOCTL_CFG80211
2857 #ifdef CONFIG_IEEE80211W
2858 if (pstat->bpairwise_key_installed != _TRUE)
2859 #endif /* CONFIG_IEEE80211W */
2861 /* .3-(1) report sta add event */
2862 report_add_sta_event(padapter, pstat->hwaddr);
2864 #ifdef CONFIG_IEEE80211W
2865 if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) {
2866 DBG_871X(MAC_FMT"\n", MAC_ARG(pstat->hwaddr));
2867 issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY);
2869 #endif /* CONFIG_IEEE80211W */
2870 #endif //CONFIG_NATIVEAP_MLME
2877 #ifdef CONFIG_NATIVEAP_MLME
2878 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
2886 #ifdef CONFIG_NATIVEAP_MLME
2888 if (frame_type == WIFI_ASSOCREQ)
2889 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2891 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2895 #endif /* CONFIG_AP_MODE */
2901 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2905 unsigned short status;
2906 PNDIS_802_11_VARIABLE_IEs pIE;
2907 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2908 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2909 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2910 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
2911 u8 *pframe = precv_frame->u.hdr.rx_data;
2912 uint pkt_len = precv_frame->u.hdr.len;
2913 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
2915 DBG_871X("%s\n", __FUNCTION__);
2917 //check A1 matches or not
2918 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2921 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2924 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2927 _cancel_timer_ex(&pmlmeext->link_timer);
2930 if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2932 DBG_871X("assoc reject, status code: %d\n", status);
2933 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2935 goto report_assoc_result;
2939 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2942 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2945 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2947 //following are moved to join event callback function
2948 //to handle HT, WMM, rate adaptive, update MAC reg
2949 //for not to handle the synchronous IO in the tasklet
2950 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2952 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2954 switch (pIE->ElementID)
2956 case _VENDOR_SPECIFIC_IE_:
2957 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM
2959 WMM_param_handler(padapter, pIE);
2961 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2962 else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD
2964 rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
2969 #ifdef CONFIG_WAPI_SUPPORT
2975 case _HT_CAPABILITY_IE_: //HT caps
2976 HT_caps_handler(padapter, pIE);
2979 case _HT_EXTRA_INFO_IE_: //HT info
2980 HT_info_handler(padapter, pIE);
2983 #ifdef CONFIG_80211AC_VHT
2984 case EID_VHTCapability:
2985 VHT_caps_handler(padapter, pIE);
2988 case EID_VHTOperation:
2989 VHT_operation_handler(padapter, pIE);
2994 ERP_IE_handler(padapter, pIE);
2998 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2999 padapter->tdlsinfo.ap_prohibited = _TRUE;
3000 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
3001 padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
3003 #endif /* CONFIG_TDLS */
3008 i += (pIE->Length + 2);
3011 #ifdef CONFIG_WAPI_SUPPORT
3012 rtw_wapi_on_assoc_ok(padapter, pIE);
3015 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3016 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3018 //Update Basic Rate Table for spec, 2010-12-28 , by thomas
3019 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3021 report_assoc_result:
3023 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3025 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3028 report_join_res(padapter, res);
3033 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
3035 unsigned short reason;
3036 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3037 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3038 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3039 u8 *pframe = precv_frame->u.hdr.rx_data;
3041 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3045 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3048 DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3051 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3053 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3054 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3058 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3060 rtw_lock_rx_suspend_timeout(8000);
3062 #ifdef CONFIG_AP_MODE
3063 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3066 struct sta_info *psta;
3067 struct sta_priv *pstapriv = &padapter->stapriv;
3069 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3070 //rtw_free_stainfo(padapter, psta);
3071 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3073 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3074 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3076 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3079 u8 updated = _FALSE;
3081 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3082 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3084 rtw_list_delete(&psta->asoc_list);
3085 pstapriv->asoc_list_cnt--;
3086 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3089 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3091 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3100 int ignore_received_deauth = 0;
3102 // Commented by Albert 20130604
3103 // Before sending the auth frame to start the STA/GC mode connection with AP/GO,
3104 // we will send the deauth first.
3105 // However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
3106 // Added the following code to avoid this case.
3107 if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
3108 ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
3110 if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
3112 ignore_received_deauth = 1;
3113 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3115 ignore_received_deauth = 1;
3119 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3120 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth);
3122 if ( 0 == ignore_received_deauth )
3124 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason, _FALSE);
3127 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3132 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3134 unsigned short reason;
3135 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3136 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3137 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3138 u8 *pframe = precv_frame->u.hdr.rx_data;
3140 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3144 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3147 DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3150 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3152 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3153 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3157 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3159 rtw_lock_rx_suspend_timeout(8000);
3161 #ifdef CONFIG_AP_MODE
3162 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3165 struct sta_info *psta;
3166 struct sta_priv *pstapriv = &padapter->stapriv;
3168 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3169 //rtw_free_stainfo(padapter, psta);
3170 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3172 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3173 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3175 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3178 u8 updated = _FALSE;
3180 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3181 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3183 rtw_list_delete(&psta->asoc_list);
3184 pstapriv->asoc_list_cnt--;
3185 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3188 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3190 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3198 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3199 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3201 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason, _FALSE);
3203 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3208 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3210 DBG_871X("%s\n", __FUNCTION__);
3214 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3216 unsigned int ret = _FAIL;
3217 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3218 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
3220 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3225 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3227 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3230 struct ieee80211_info_element *ie;
3232 DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3233 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
3235 for_each_ie(ie, ies, ies_len) {
3236 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3237 ch_switch_mode = ie->data[0];
3239 ch_switch_cnt = ie->data[2];
3240 DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3241 ch_switch_mode, ch, ch_switch_cnt);
3243 else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3244 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3245 DBG_871X("ch_offset:%d\n", ch_offset);
3252 if (ch_offset == -1)
3253 bwmode = mlmeext->cur_bwmode;
3255 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3256 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3258 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3261 * 1. the decision of channel switching
3262 * 2. things after channel switching
3265 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
3272 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3274 unsigned int ret = _FAIL;
3275 struct sta_info *psta = NULL;
3276 struct sta_priv *pstapriv = &padapter->stapriv;
3277 u8 *pframe = precv_frame->u.hdr.rx_data;
3278 uint frame_len = precv_frame->u.hdr.len;
3279 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3283 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3285 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3290 category = frame_body[0];
3291 if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3294 action = frame_body[1];
3296 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3297 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3298 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3299 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3301 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3302 #ifdef CONFIG_SPCT_CH_SWITCH
3303 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
3304 frame_len-(frame_body-pframe)-2);
3315 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3320 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3326 * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3327 * @adapter: the adapter to get target RX AMPDU buffer size
3329 * Returns: the target RX AMPDU buffer size
3331 u8 rtw_rx_ampdu_size(_adapter *adapter)
3334 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3336 if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) {
3337 size = adapter->fix_rx_ampdu_size;
3341 #ifdef CONFIG_BT_COEXIST
3342 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3343 size = rtw_btcoex_GetAMPDUSize(adapter);
3349 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3350 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3351 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3353 size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3357 /* default value based on max_rx_ampdu_factor */
3358 if (adapter->driver_rx_ampdu_factor != 0xFF)
3359 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3361 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3363 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3365 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3367 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3369 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3383 * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3384 * @adapter: the adapter to get the permission if RX AMPDU should be set up
3386 * Returns: accept or not
3388 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3392 if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3393 accept = adapter->fix_rx_ampdu_accept;
3397 #ifdef CONFIG_BT_COEXIST
3398 if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3405 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3406 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3407 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3409 accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3413 /* default value for other cases */
3414 accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3421 * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3422 * @adapter: the adapter to set target RX AMPDU buffer size
3423 * @size: the target RX AMPDU buffer size to set
3424 * @reason: reason for the target RX AMPDU buffer size setting
3426 * Returns: whether the target RX AMPDU buffer size is changed
3428 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3430 bool is_adj = _FALSE;
3431 struct mlme_ext_priv *mlmeext;
3432 struct mlme_ext_info *mlmeinfo;
3434 mlmeext = &adapter->mlmeextpriv;
3435 mlmeinfo = &mlmeext->mlmext_info;
3437 if (reason == RX_AMPDU_DRV_FIXED) {
3438 if (adapter->fix_rx_ampdu_size != size) {
3439 adapter->fix_rx_ampdu_size = size;
3441 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3443 } else if (reason == RX_AMPDU_DRV_SCAN) {
3444 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3446 if (ss->rx_ampdu_size != size) {
3447 ss->rx_ampdu_size = size;
3449 DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3457 * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3458 * @adapter: the adapter to set if RX AMPDU should be set up
3459 * @accept: if RX AMPDU should be set up
3460 * @reason: reason for the permission if RX AMPDU should be set up
3462 * Returns: whether the permission if RX AMPDU should be set up is changed
3464 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3466 bool is_adj = _FALSE;
3467 struct mlme_ext_priv *mlmeext;
3468 struct mlme_ext_info *mlmeinfo;
3470 mlmeext = &adapter->mlmeextpriv;
3471 mlmeinfo = &mlmeext->mlmext_info;
3473 if (reason == RX_AMPDU_DRV_FIXED) {
3474 if (adapter->fix_rx_ampdu_accept != accept) {
3475 adapter->fix_rx_ampdu_accept = accept;
3477 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3479 } else if (reason == RX_AMPDU_DRV_SCAN) {
3480 if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3481 adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3483 DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3491 * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3492 * @adapter: the adapter to which @sta belongs
3493 * @sta: the sta to be checked
3494 * @tid: the tid to be checked
3495 * @accept: the target permission if RX AMPDU should be set up
3496 * @size: the target RX AMPDU buffer size
3500 * 1: canceled by no permission
3501 * 2: canceled by different buffer size
3502 * 3: canceled by potential mismatched status
3504 * Blocking function, may sleep
3506 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3509 struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3511 if (reorder_ctl->enable == _FALSE) {
3512 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3513 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3519 if (accept == _FALSE) {
3520 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3522 } else if (reorder_ctl->ampdu_size != size) {
3523 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3532 * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3533 * @adapter: the adapter to which @sta belongs
3534 * @sta: the sta to be checked
3535 * @accept: the target permission if RX AMPDU should be set up
3536 * @size: the target RX AMPDU buffer size
3538 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3540 * Blocking function, may sleep
3542 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3547 for (i = 0; i < TID_NUM; i++) {
3548 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3556 * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3557 * @adapter: the adapter to be applied
3559 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3561 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3564 struct mlme_ext_priv *mlmeext;
3565 struct sta_info *sta;
3566 u8 accept = rtw_rx_ampdu_is_accept(adapter);
3567 u8 size = rtw_rx_ampdu_size(adapter);
3569 mlmeext = &adapter->mlmeextpriv;
3571 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3572 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3574 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3576 } else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3578 _list *phead, *plist;
3580 char peers[NUM_STA];
3581 struct sta_priv *pstapriv = &adapter->stapriv;
3584 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3586 phead = &pstapriv->asoc_list;
3587 plist = get_next(phead);
3589 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3592 sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3593 plist = get_next(plist);
3595 stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3596 if (stainfo_offset_valid(stainfo_offset))
3597 peers[peer_num++] = stainfo_offset;
3600 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3602 for (i = 0; i < peer_num; i++) {
3603 sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3605 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3612 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3615 struct sta_info *psta=NULL;
3616 struct recv_reorder_ctrl *preorder_ctrl;
3617 unsigned char *frame_body;
3618 unsigned char category, action;
3619 unsigned short tid, status, reason_code = 0;
3620 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3621 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3622 u8 *pframe = precv_frame->u.hdr.rx_data;
3623 struct sta_priv *pstapriv = &padapter->stapriv;
3624 #ifdef CONFIG_80211N_HT
3626 DBG_871X("%s\n", __FUNCTION__);
3628 //check RA matches or not
3629 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3633 //check A1 matches or not
3634 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3638 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3639 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3642 addr = GetAddr2Ptr(pframe);
3643 psta = rtw_get_stainfo(pstapriv, addr);
3648 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3650 category = frame_body[0];
3651 if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
3654 if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3655 (psta->htpriv.ht_option==_TRUE) &&
3656 (psta->htpriv.ampdu_enable==_TRUE))
3658 DBG_871X("Recv [%s] from direc link\n", __FUNCTION__);
3661 #endif //CONFIG_TDLS
3662 if (!pmlmeinfo->HT_enable)
3667 action = frame_body[1];
3668 DBG_871X("%s, action=%d\n", __FUNCTION__, action);
3671 case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
3673 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3674 //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
3675 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
3679 case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
3681 //status = frame_body[3] | (frame_body[4] << 8); //endian issue
3682 status = RTW_GET_LE16(&frame_body[3]);
3683 tid = ((frame_body[5] >> 2) & 0x7);
3687 DBG_871X("agg_enable for TID=%d\n", tid);
3688 psta->htpriv.agg_enable_bitmap |= 1 << tid;
3689 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3693 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3696 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3698 DBG_871X("%s alive check - rx ADDBA response\n", __func__);
3699 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3700 psta->expire_to = pstapriv->expire_to;
3701 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3704 //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
3707 case RTW_WLAN_ACTION_DELBA: //DELBA
3708 if ((frame_body[3] & BIT(3)) == 0)
3710 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3711 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3713 //reason_code = frame_body[4] | (frame_body[5] << 8);
3714 reason_code = RTW_GET_LE16(&frame_body[4]);
3716 else if((frame_body[3] & BIT(3)) == BIT(3))
3718 tid = (frame_body[3] >> 4) & 0x0F;
3720 preorder_ctrl = &psta->recvreorder_ctrl[tid];
3721 preorder_ctrl->enable = _FALSE;
3722 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3725 DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
3726 //todo: how to notify the host while receiving DELETE BA
3733 #endif //CONFIG_80211N_HT
3739 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
3743 for (i = 0; i < channel_list.reg_classes; i++) {
3744 cnt += channel_list.reg_class[i].channels;
3750 static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
3758 for( i = 0; i < pmlmeext->max_chan_nums; i++ )
3760 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
3764 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
3766 // Just include the channel 36, 40, 44, 48 channels for 5G low
3769 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
3771 // Just include the channel 149, 153, 157, 161 channels for 5G high
3777 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
3780 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3781 u8 action = P2P_PUB_ACTION_ACTION;
3782 u32 p2poui = cpu_to_be32(P2POUI);
3783 u8 oui_subtype = P2P_GO_NEGO_REQ;
3784 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3785 u8 wpsielen = 0, p2pielen = 0, i;
3786 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3787 u16 len_channellist_attr = 0;
3792 struct xmit_frame *pmgntframe;
3793 struct pkt_attrib *pattrib;
3794 unsigned char *pframe;
3795 struct rtw_ieee80211_hdr *pwlanhdr;
3796 unsigned short *fctrl;
3797 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3798 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3799 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3800 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3803 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3808 DBG_871X( "[%s] In\n", __FUNCTION__ );
3810 pattrib = &pmgntframe->attrib;
3811 update_mgntframe_attrib(padapter, pattrib);
3813 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3815 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3816 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3818 fctrl = &(pwlanhdr->frame_ctl);
3821 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3822 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3823 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3825 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3826 pmlmeext->mgnt_seq++;
3827 SetFrameSubType(pframe, WIFI_ACTION);
3829 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3830 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3832 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3833 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3834 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3835 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3836 pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value
3837 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3844 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3849 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3853 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3857 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
3859 // Device Password ID
3861 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3865 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3870 if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
3872 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3874 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
3876 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3878 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
3880 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3885 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3892 p2pie[ p2pielen++ ] = 0x50;
3893 p2pie[ p2pielen++ ] = 0x6F;
3894 p2pie[ p2pielen++ ] = 0x9A;
3895 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
3897 // Commented by Albert 20110306
3898 // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
3899 // 1. P2P Capability
3900 // 2. Group Owner Intent
3901 // 3. Configuration Timeout
3902 // 4. Listen Channel
3903 // 5. Extended Listen Timing
3904 // 6. Intended P2P Interface Address
3906 // 8. P2P Device Info
3907 // 9. Operating Channel
3912 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3915 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3919 // Device Capability Bitmap, 1 byte
3920 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3922 // Group Capability Bitmap, 1 byte
3923 if ( pwdinfo->persistent_supported )
3925 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3929 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3933 // Group Owner Intent
3935 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3938 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3942 // Todo the tie breaker bit.
3943 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) & 0xFE );
3945 // Configuration Timeout
3947 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3950 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3954 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
3955 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
3960 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
3963 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3968 p2pie[ p2pielen++ ] = 'X';
3969 p2pie[ p2pielen++ ] = 'X';
3971 // The third byte should be set to 0x04.
3972 // Described in the "Operating Channel Attribute" section.
3973 p2pie[ p2pielen++ ] = 0x04;
3976 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
3979 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listening channel number
3982 // Extended Listen Timing ATTR
3984 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
3987 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
3991 // Availability Period
3992 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3995 // Availability Interval
3996 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
4000 // Intended P2P Interface Address
4002 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4005 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4009 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4010 p2pielen += ETH_ALEN;
4015 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4018 // Country String(3)
4019 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4020 // + number of channels in all classes
4021 len_channellist_attr = 3
4022 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
4023 + get_reg_classes_full_count(pmlmeext->channel_list);
4025 #ifdef CONFIG_CONCURRENT_MODE
4026 if (check_buddy_fwstate(padapter , _FW_LINKED)
4027 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4029 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4033 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4037 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4044 p2pie[ p2pielen++ ] = 'X';
4045 p2pie[ p2pielen++ ] = 'X';
4047 // The third byte should be set to 0x04.
4048 // Described in the "Operating Channel Attribute" section.
4049 p2pie[ p2pielen++ ] = 0x04;
4051 // Channel Entry List
4053 #ifdef CONFIG_CONCURRENT_MODE
4054 if (check_buddy_fwstate(padapter , _FW_LINKED)
4055 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4057 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4058 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4061 if ( pbuddy_mlmeext->cur_channel > 14 )
4063 if ( pbuddy_mlmeext->cur_channel >= 149 )
4065 p2pie[ p2pielen++ ] = 0x7c;
4069 p2pie[ p2pielen++ ] = 0x73;
4074 p2pie[ p2pielen++ ] = 0x51;
4077 // Number of Channels
4078 // Just support 1 channel and this channel is AP's channel
4079 p2pie[ p2pielen++ ] = 1;
4082 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4087 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4089 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4091 // Number of Channels
4092 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4095 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4096 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4100 #else // CONFIG_CONCURRENT_MODE
4103 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4105 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4107 // Number of Channels
4108 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4111 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4112 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4116 #endif // CONFIG_CONCURRENT_MODE
4120 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4123 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4124 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4125 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4129 // P2P Device Address
4130 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4131 p2pielen += ETH_ALEN;
4134 // This field should be big endian. Noted by P2P specification.
4136 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4140 // Primary Device Type
4142 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4146 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4150 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4153 // Number of Secondary Device Types
4154 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4158 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4162 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4166 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4167 p2pielen += pwdinfo->device_name_len;
4170 // Operating Channel
4172 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4175 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4180 p2pie[ p2pielen++ ] = 'X';
4181 p2pie[ p2pielen++ ] = 'X';
4183 // The third byte should be set to 0x04.
4184 // Described in the "Operating Channel Attribute" section.
4185 p2pie[ p2pielen++ ] = 0x04;
4188 if ( pwdinfo->operating_channel <= 14 )
4191 p2pie[ p2pielen++ ] = 0x51;
4193 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4196 p2pie[ p2pielen++ ] = 0x73;
4201 p2pie[ p2pielen++ ] = 0x7c;
4205 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4207 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4210 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4212 pattrib->pktlen += wfdielen;
4215 pattrib->last_txcmdsz = pattrib->pktlen;
4217 dump_mgntframe(padapter, pmgntframe);
4224 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
4227 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4228 u8 action = P2P_PUB_ACTION_ACTION;
4229 u32 p2poui = cpu_to_be32(P2POUI);
4230 u8 oui_subtype = P2P_GO_NEGO_RESP;
4231 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4234 u16 wps_devicepassword_id = 0x0000;
4235 uint wps_devicepassword_id_len = 0;
4236 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4237 u16 len_channellist_attr = 0;
4239 struct xmit_frame *pmgntframe;
4240 struct pkt_attrib *pattrib;
4241 unsigned char *pframe;
4242 struct rtw_ieee80211_hdr *pwlanhdr;
4243 unsigned short *fctrl;
4244 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4245 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4246 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4247 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4253 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4258 DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result );
4260 pattrib = &pmgntframe->attrib;
4261 update_mgntframe_attrib(padapter, pattrib);
4263 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4265 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4266 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4268 fctrl = &(pwlanhdr->frame_ctl);
4271 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4272 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4273 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4275 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4276 pmlmeext->mgnt_seq++;
4277 SetFrameSubType(pframe, WIFI_ACTION);
4279 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4280 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4282 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4283 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4284 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4285 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4286 pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
4287 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4289 // Commented by Albert 20110328
4290 // Try to get the device password ID from the WPS IE of group negotiation request frame
4291 // WiFi Direct test plan 5.1.15
4292 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4293 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4294 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4296 _rtw_memset( wpsie, 0x00, 255 );
4302 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4307 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4311 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4315 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
4317 // Device Password ID
4319 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4323 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4327 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4329 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
4331 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4333 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
4337 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
4341 // Commented by Kurt 20120113
4342 // If some device wants to do p2p handshake without sending prov_disc_req
4343 // We have to get peer_req_cm from here.
4344 if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
4346 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4348 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
4350 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4352 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
4356 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
4360 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4367 p2pie[ p2pielen++ ] = 0x50;
4368 p2pie[ p2pielen++ ] = 0x6F;
4369 p2pie[ p2pielen++ ] = 0x9A;
4370 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4372 // Commented by Albert 20100908
4373 // According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
4375 // 2. P2P Capability
4376 // 3. Group Owner Intent
4377 // 4. Configuration Timeout
4378 // 5. Operating Channel
4379 // 6. Intended P2P Interface Address
4382 // 9. Group ID ( Only GO )
4389 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4392 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4396 p2pie[ p2pielen++ ] = result;
4400 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4403 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4407 // Device Capability Bitmap, 1 byte
4409 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4411 // Commented by Albert 2011/03/08
4412 // According to the P2P specification
4413 // if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
4414 p2pie[ p2pielen++ ] = 0;
4418 // Be group owner or meet the error case
4419 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4422 // Group Capability Bitmap, 1 byte
4423 if ( pwdinfo->persistent_supported )
4425 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4429 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4432 // Group Owner Intent
4434 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
4437 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4441 if ( pwdinfo->peer_intent & 0x01 )
4443 // Peer's tie breaker bit is 1, our tie breaker bit should be 0
4444 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
4448 // Peer's tie breaker bit is 0, our tie breaker bit should be 1
4449 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
4453 // Configuration Timeout
4455 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4458 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4462 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
4463 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
4465 // Operating Channel
4467 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4470 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4475 p2pie[ p2pielen++ ] = 'X';
4476 p2pie[ p2pielen++ ] = 'X';
4478 // The third byte should be set to 0x04.
4479 // Described in the "Operating Channel Attribute" section.
4480 p2pie[ p2pielen++ ] = 0x04;
4483 if ( pwdinfo->operating_channel <= 14 )
4486 p2pie[ p2pielen++ ] = 0x51;
4488 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4491 p2pie[ p2pielen++ ] = 0x73;
4496 p2pie[ p2pielen++ ] = 0x7c;
4500 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4502 // Intended P2P Interface Address
4504 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4507 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4511 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4512 p2pielen += ETH_ALEN;
4516 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4518 // Country String(3)
4519 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4520 // + number of channels in all classes
4521 len_channellist_attr = 3
4522 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4523 + get_reg_classes_full_count(pmlmeext->channel_list);
4525 #ifdef CONFIG_CONCURRENT_MODE
4526 if (check_buddy_fwstate(padapter , _FW_LINKED)
4527 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4529 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4533 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4537 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4544 p2pie[ p2pielen++ ] = 'X';
4545 p2pie[ p2pielen++ ] = 'X';
4547 // The third byte should be set to 0x04.
4548 // Described in the "Operating Channel Attribute" section.
4549 p2pie[ p2pielen++ ] = 0x04;
4551 // Channel Entry List
4553 #ifdef CONFIG_CONCURRENT_MODE
4554 if (check_buddy_fwstate(padapter , _FW_LINKED)
4555 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4557 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4558 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4561 if ( pbuddy_mlmeext->cur_channel > 14 )
4563 if ( pbuddy_mlmeext->cur_channel >= 149 )
4565 p2pie[ p2pielen++ ] = 0x7c;
4569 p2pie[ p2pielen++ ] = 0x73;
4574 p2pie[ p2pielen++ ] = 0x51;
4577 // Number of Channels
4578 // Just support 1 channel and this channel is AP's channel
4579 p2pie[ p2pielen++ ] = 1;
4582 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4587 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4589 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4591 // Number of Channels
4592 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4595 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4596 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4600 #else // CONFIG_CONCURRENT_MODE
4603 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4605 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4607 // Number of Channels
4608 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4611 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4612 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4616 #endif // CONFIG_CONCURRENT_MODE
4621 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4624 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4625 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4626 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4630 // P2P Device Address
4631 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4632 p2pielen += ETH_ALEN;
4635 // This field should be big endian. Noted by P2P specification.
4637 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4641 // Primary Device Type
4643 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4647 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4651 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4654 // Number of Secondary Device Types
4655 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4659 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4663 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4667 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4668 p2pielen += pwdinfo->device_name_len;
4670 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4672 // Group ID Attribute
4674 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4677 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4681 // p2P Device Address
4682 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4683 p2pielen += ETH_ALEN;
4686 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4687 p2pielen += pwdinfo->nego_ssidlen;
4691 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4694 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4696 pattrib->pktlen += wfdielen;
4699 pattrib->last_txcmdsz = pattrib->pktlen;
4701 dump_mgntframe(padapter, pmgntframe);
4707 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
4710 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4711 u8 action = P2P_PUB_ACTION_ACTION;
4712 u32 p2poui = cpu_to_be32(P2POUI);
4713 u8 oui_subtype = P2P_GO_NEGO_CONF;
4714 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4715 u8 wpsielen = 0, p2pielen = 0;
4717 struct xmit_frame *pmgntframe;
4718 struct pkt_attrib *pattrib;
4719 unsigned char *pframe;
4720 struct rtw_ieee80211_hdr *pwlanhdr;
4721 unsigned short *fctrl;
4722 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4723 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4724 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4725 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4730 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4735 DBG_871X( "[%s] In\n", __FUNCTION__ );
4737 pattrib = &pmgntframe->attrib;
4738 update_mgntframe_attrib(padapter, pattrib);
4740 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4742 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4743 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4745 fctrl = &(pwlanhdr->frame_ctl);
4748 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4749 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4750 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4752 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4753 pmlmeext->mgnt_seq++;
4754 SetFrameSubType(pframe, WIFI_ACTION);
4756 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4757 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4759 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4760 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4761 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4762 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4763 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4771 p2pie[ p2pielen++ ] = 0x50;
4772 p2pie[ p2pielen++ ] = 0x6F;
4773 p2pie[ p2pielen++ ] = 0x9A;
4774 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4776 // Commented by Albert 20110306
4777 // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
4779 // 2. P2P Capability
4780 // 3. Operating Channel
4782 // 5. Group ID ( if this WiFi is GO )
4786 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4789 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4793 p2pie[ p2pielen++ ] = result;
4797 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4800 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4804 // Device Capability Bitmap, 1 byte
4805 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4807 // Group Capability Bitmap, 1 byte
4808 if ( pwdinfo->persistent_supported )
4810 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4814 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4818 // Operating Channel
4820 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4823 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4828 p2pie[ p2pielen++ ] = 'X';
4829 p2pie[ p2pielen++ ] = 'X';
4831 // The third byte should be set to 0x04.
4832 // Described in the "Operating Channel Attribute" section.
4833 p2pie[ p2pielen++ ] = 0x04;
4836 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4838 if ( pwdinfo->peer_operating_ch <= 14 )
4841 p2pie[ p2pielen++ ] = 0x51;
4843 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4846 p2pie[ p2pielen++ ] = 0x73;
4851 p2pie[ p2pielen++ ] = 0x7c;
4854 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4858 if ( pwdinfo->operating_channel <= 14 )
4861 p2pie[ p2pielen++ ] = 0x51;
4863 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4866 p2pie[ p2pielen++ ] = 0x73;
4871 p2pie[ p2pielen++ ] = 0x7c;
4875 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4881 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4883 *(u16*) ( p2pie + p2pielen ) = 6;
4887 p2pie[ p2pielen++ ] = 'X';
4888 p2pie[ p2pielen++ ] = 'X';
4890 // The third byte should be set to 0x04.
4891 // Described in the "Operating Channel Attribute" section.
4892 p2pie[ p2pielen++ ] = 0x04;
4895 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4897 if ( pwdinfo->peer_operating_ch <= 14 )
4900 p2pie[ p2pielen++ ] = 0x51;
4902 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4905 p2pie[ p2pielen++ ] = 0x73;
4910 p2pie[ p2pielen++ ] = 0x7c;
4912 p2pie[ p2pielen++ ] = 1;
4913 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4917 if ( pwdinfo->operating_channel <= 14 )
4920 p2pie[ p2pielen++ ] = 0x51;
4922 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4925 p2pie[ p2pielen++ ] = 0x73;
4930 p2pie[ p2pielen++ ] = 0x7c;
4934 p2pie[ p2pielen++ ] = 1;
4935 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4938 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4940 // Group ID Attribute
4942 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4945 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4949 // p2P Device Address
4950 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4951 p2pielen += ETH_ALEN;
4954 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4955 p2pielen += pwdinfo->nego_ssidlen;
4958 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4961 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4963 pattrib->pktlen += wfdielen;
4966 pattrib->last_txcmdsz = pattrib->pktlen;
4968 dump_mgntframe(padapter, pmgntframe);
4974 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
4977 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4978 u8 action = P2P_PUB_ACTION_ACTION;
4979 u32 p2poui = cpu_to_be32(P2POUI);
4980 u8 oui_subtype = P2P_INVIT_REQ;
4981 u8 p2pie[ 255 ] = { 0x00 };
4984 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4985 u16 len_channellist_attr = 0;
4989 #ifdef CONFIG_CONCURRENT_MODE
4990 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4991 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4992 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4993 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4996 struct xmit_frame *pmgntframe;
4997 struct pkt_attrib *pattrib;
4998 unsigned char *pframe;
4999 struct rtw_ieee80211_hdr *pwlanhdr;
5000 unsigned short *fctrl;
5001 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5002 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5003 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5004 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
5007 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5013 pattrib = &pmgntframe->attrib;
5014 update_mgntframe_attrib(padapter, pattrib);
5016 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5018 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5019 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5021 fctrl = &(pwlanhdr->frame_ctl);
5024 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5025 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5026 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5028 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5029 pmlmeext->mgnt_seq++;
5030 SetFrameSubType(pframe, WIFI_ACTION);
5032 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5033 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5035 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5036 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5037 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5038 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5039 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5045 p2pie[ p2pielen++ ] = 0x50;
5046 p2pie[ p2pielen++ ] = 0x6F;
5047 p2pie[ p2pielen++ ] = 0x9A;
5048 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
5050 // Commented by Albert 20101011
5051 // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
5052 // 1. Configuration Timeout
5053 // 2. Invitation Flags
5054 // 3. Operating Channel ( Only GO )
5055 // 4. P2P Group BSSID ( Should be included if I am the GO )
5058 // 7. P2P Device Info
5060 // Configuration Timeout
5062 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5065 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5069 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
5070 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
5074 p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
5077 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5081 p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
5084 // Operating Channel
5086 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5089 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5094 p2pie[ p2pielen++ ] = 'X';
5095 p2pie[ p2pielen++ ] = 'X';
5097 // The third byte should be set to 0x04.
5098 // Described in the "Operating Channel Attribute" section.
5099 p2pie[ p2pielen++ ] = 0x04;
5102 if ( pwdinfo->invitereq_info.operating_ch <= 14 )
5103 p2pie[ p2pielen++ ] = 0x51;
5104 else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
5105 p2pie[ p2pielen++ ] = 0x73;
5107 p2pie[ p2pielen++ ] = 0x7c;
5110 p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number
5112 if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
5116 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5119 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5123 // P2P Device Address for GO
5124 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5125 p2pielen += ETH_ALEN;
5130 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5134 // Country String(3)
5135 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5136 // + number of channels in all classes
5137 len_channellist_attr = 3
5138 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5139 + get_reg_classes_full_count(pmlmeext->channel_list);
5141 #ifdef CONFIG_CONCURRENT_MODE
5142 if (check_buddy_fwstate(padapter , _FW_LINKED)
5143 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5145 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5149 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5153 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5160 p2pie[ p2pielen++ ] = 'X';
5161 p2pie[ p2pielen++ ] = 'X';
5163 // The third byte should be set to 0x04.
5164 // Described in the "Operating Channel Attribute" section.
5165 p2pie[ p2pielen++ ] = 0x04;
5167 // Channel Entry List
5168 #ifdef CONFIG_CONCURRENT_MODE
5169 if (check_buddy_fwstate(padapter, _FW_LINKED)
5170 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5172 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5173 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5176 if ( pbuddy_mlmeext->cur_channel > 14 )
5178 if ( pbuddy_mlmeext->cur_channel >= 149 )
5180 p2pie[ p2pielen++ ] = 0x7c;
5184 p2pie[ p2pielen++ ] = 0x73;
5189 p2pie[ p2pielen++ ] = 0x51;
5192 // Number of Channels
5193 // Just support 1 channel and this channel is AP's channel
5194 p2pie[ p2pielen++ ] = 1;
5197 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5202 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5204 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5206 // Number of Channels
5207 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5210 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5211 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5215 #else // CONFIG_CONCURRENT_MODE
5218 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5220 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5222 // Number of Channels
5223 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5226 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5227 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5231 #endif // CONFIG_CONCURRENT_MODE
5236 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
5239 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
5243 // P2P Device Address for GO
5244 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5245 p2pielen += ETH_ALEN;
5248 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
5249 p2pielen += pwdinfo->invitereq_info.ssidlen;
5254 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
5257 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
5258 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
5259 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
5263 // P2P Device Address
5264 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5265 p2pielen += ETH_ALEN;
5268 // This field should be big endian. Noted by P2P specification.
5269 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
5272 // Primary Device Type
5274 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5278 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
5282 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5285 // Number of Secondary Device Types
5286 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
5290 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5294 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
5298 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
5299 p2pielen += pwdinfo->device_name_len;
5301 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5304 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5306 pattrib->pktlen += wfdielen;
5309 pattrib->last_txcmdsz = pattrib->pktlen;
5311 dump_mgntframe(padapter, pmgntframe);
5317 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
5320 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5321 u8 action = P2P_PUB_ACTION_ACTION;
5322 u32 p2poui = cpu_to_be32(P2POUI);
5323 u8 oui_subtype = P2P_INVIT_RESP;
5324 u8 p2pie[ 255 ] = { 0x00 };
5326 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5327 u16 len_channellist_attr = 0;
5328 #ifdef CONFIG_CONCURRENT_MODE
5329 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5330 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5331 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5332 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5338 struct xmit_frame *pmgntframe;
5339 struct pkt_attrib *pattrib;
5340 unsigned char *pframe;
5341 struct rtw_ieee80211_hdr *pwlanhdr;
5342 unsigned short *fctrl;
5343 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5344 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5345 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5346 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
5349 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5355 pattrib = &pmgntframe->attrib;
5356 update_mgntframe_attrib(padapter, pattrib);
5358 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5360 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5361 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5363 fctrl = &(pwlanhdr->frame_ctl);
5366 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5367 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5368 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5370 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5371 pmlmeext->mgnt_seq++;
5372 SetFrameSubType(pframe, WIFI_ACTION);
5374 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5375 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5377 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5378 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5379 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5380 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5381 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5387 p2pie[ p2pielen++ ] = 0x50;
5388 p2pie[ p2pielen++ ] = 0x6F;
5389 p2pie[ p2pielen++ ] = 0x9A;
5390 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
5392 // Commented by Albert 20101005
5393 // According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
5395 // 2. Configuration Timeout
5396 // 3. Operating Channel ( Only GO )
5397 // 4. P2P Group BSSID ( Only GO )
5402 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
5405 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5409 // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
5410 // Sent the event receiving the P2P Invitation Req frame to DMP UI.
5411 // DMP had to compare the MAC address to find out the profile.
5412 // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
5413 // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
5414 // to NB to rebuild the persistent group.
5415 p2pie[ p2pielen++ ] = status_code;
5417 // Configuration Timeout
5419 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5422 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5426 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
5427 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
5429 if( status_code == P2P_STATUS_SUCCESS )
5431 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
5433 // The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
5434 // In this case, the P2P Invitation response frame should carry the two more P2P attributes.
5435 // First one is operating channel attribute.
5436 // Second one is P2P Group BSSID attribute.
5438 // Operating Channel
5440 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5443 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5448 p2pie[ p2pielen++ ] = 'X';
5449 p2pie[ p2pielen++ ] = 'X';
5451 // The third byte should be set to 0x04.
5452 // Described in the "Operating Channel Attribute" section.
5453 p2pie[ p2pielen++ ] = 0x04;
5456 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
5459 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
5464 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5467 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5471 // P2P Device Address for GO
5472 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5473 p2pielen += ETH_ALEN;
5479 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5482 // Country String(3)
5483 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5484 // + number of channels in all classes
5485 len_channellist_attr = 3
5486 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5487 + get_reg_classes_full_count(pmlmeext->channel_list);
5489 #ifdef CONFIG_CONCURRENT_MODE
5490 if (check_buddy_fwstate(padapter, _FW_LINKED)
5491 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5493 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5497 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5501 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5508 p2pie[ p2pielen++ ] = 'X';
5509 p2pie[ p2pielen++ ] = 'X';
5511 // The third byte should be set to 0x04.
5512 // Described in the "Operating Channel Attribute" section.
5513 p2pie[ p2pielen++ ] = 0x04;
5515 // Channel Entry List
5516 #ifdef CONFIG_CONCURRENT_MODE
5517 if (check_buddy_fwstate(padapter , _FW_LINKED)
5518 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5520 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5521 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5524 if ( pbuddy_mlmeext->cur_channel > 14 )
5526 if ( pbuddy_mlmeext->cur_channel >= 149 )
5528 p2pie[ p2pielen++ ] = 0x7c;
5532 p2pie[ p2pielen++ ] = 0x73;
5537 p2pie[ p2pielen++ ] = 0x51;
5540 // Number of Channels
5541 // Just support 1 channel and this channel is AP's channel
5542 p2pie[ p2pielen++ ] = 1;
5545 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5550 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5552 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5554 // Number of Channels
5555 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5558 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5559 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5563 #else // CONFIG_CONCURRENT_MODE
5566 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5568 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5570 // Number of Channels
5571 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5574 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5575 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5579 #endif // CONFIG_CONCURRENT_MODE
5582 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5585 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5587 pattrib->pktlen += wfdielen;
5590 pattrib->last_txcmdsz = pattrib->pktlen;
5592 dump_mgntframe(padapter, pmgntframe);
5598 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
5600 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5601 u8 action = P2P_PUB_ACTION_ACTION;
5603 u32 p2poui = cpu_to_be32(P2POUI);
5604 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
5605 u8 wpsie[ 100 ] = { 0x00 };
5612 struct xmit_frame *pmgntframe;
5613 struct pkt_attrib *pattrib;
5614 unsigned char *pframe;
5615 struct rtw_ieee80211_hdr *pwlanhdr;
5616 unsigned short *fctrl;
5617 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5618 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5619 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5620 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5623 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5628 DBG_871X( "[%s] In\n", __FUNCTION__ );
5630 pattrib = &pmgntframe->attrib;
5631 update_mgntframe_attrib(padapter, pattrib);
5633 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5635 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5636 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5638 fctrl = &(pwlanhdr->frame_ctl);
5641 _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5642 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5643 _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5645 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5646 pmlmeext->mgnt_seq++;
5647 SetFrameSubType(pframe, WIFI_ACTION);
5649 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5650 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5652 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5653 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5654 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5655 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5656 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5658 p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
5661 pattrib->pktlen += p2pielen;
5665 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5670 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5674 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5678 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5682 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5686 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5690 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
5693 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5697 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5699 pattrib->pktlen += wfdielen;
5702 pattrib->last_txcmdsz = pattrib->pktlen;
5704 dump_mgntframe(padapter, pmgntframe);
5711 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
5713 u8 i, match_result = 0;
5715 DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5716 peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
5718 for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
5720 DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5721 profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
5722 if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
5725 DBG_871X( "[%s] Match!\n", __FUNCTION__ );
5730 return (match_result );
5733 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5735 struct xmit_frame *pmgntframe;
5736 struct pkt_attrib *pattrib;
5737 unsigned char *pframe;
5738 struct rtw_ieee80211_hdr *pwlanhdr;
5739 unsigned short *fctrl;
5741 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5742 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5743 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5744 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5745 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5746 u16 beacon_interval = 100;
5748 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5749 u8 wpsie[255] = { 0x00 };
5750 u32 wpsielen = 0, p2pielen = 0;
5754 #ifdef CONFIG_INTEL_WIDI
5755 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5756 #endif //CONFIG_INTEL_WIDI
5758 //DBG_871X("%s\n", __FUNCTION__);
5760 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5766 pattrib = &pmgntframe->attrib;
5767 update_mgntframe_attrib(padapter, pattrib);
5769 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5771 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5772 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5774 mac = adapter_mac_addr(padapter);
5776 fctrl = &(pwlanhdr->frame_ctl);
5778 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5779 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5781 // Use the device address for BSSID field.
5782 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5784 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5785 pmlmeext->mgnt_seq++;
5786 SetFrameSubType(fctrl, WIFI_PROBERSP);
5788 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5789 pattrib->pktlen = pattrib->hdrlen;
5790 pframe += pattrib->hdrlen;
5792 //timestamp will be inserted by hardware
5794 pattrib->pktlen += 8;
5796 // beacon interval: 2 bytes
5797 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5799 pattrib->pktlen += 2;
5801 // capability info: 2 bytes
5802 // ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
5803 capInfo |= cap_ShortPremble;
5804 capInfo |= cap_ShortSlot;
5806 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5808 pattrib->pktlen += 2;
5812 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5814 // supported rates...
5815 // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5816 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5819 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5821 #ifdef CONFIG_IOCTL_CFG80211
5822 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5824 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
5827 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5828 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5829 pframe += pmlmepriv->wps_probe_resp_ie_len;
5832 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5833 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5834 pframe += pmlmepriv->p2p_probe_resp_ie_len;
5838 #endif //CONFIG_IOCTL_CFG80211
5842 // Noted by Albert 20100907
5843 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
5847 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5852 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5856 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5860 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5862 #ifdef CONFIG_INTEL_WIDI
5863 // Commented by Kurt
5864 // Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
5865 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5866 || pmlmepriv->num_p2p_sdt != 0 )
5869 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
5873 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5878 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
5882 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
5885 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
5888 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
5891 _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
5892 wpsielen += L2SDTA_SERVICE_VE_LEN;
5895 #endif //CONFIG_INTEL_WIDI
5897 // WiFi Simple Config State
5899 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
5903 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5907 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; // Not Configured.
5911 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
5915 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5919 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5923 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5927 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5931 if (pwdinfo->external_uuid == 0) {
5932 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
5933 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5935 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5941 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
5945 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
5949 _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
5954 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
5958 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
5962 _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
5967 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
5971 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5975 wpsie[ wpsielen++ ] = 0x31; // character 1
5979 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
5983 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
5987 _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
5988 wpsielen += ETH_ALEN;
5990 // Primary Device Type
5992 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5996 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6001 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
6005 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6009 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
6014 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6018 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6022 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6023 wpsielen += pwdinfo->device_name_len;
6027 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6031 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6035 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6039 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6042 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6044 pattrib->pktlen += p2pielen;
6048 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6050 pattrib->pktlen += wfdielen;
6053 pattrib->last_txcmdsz = pattrib->pktlen;
6056 dump_mgntframe(padapter, pmgntframe);
6062 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6065 struct xmit_frame *pmgntframe;
6066 struct pkt_attrib *pattrib;
6067 unsigned char *pframe;
6068 struct rtw_ieee80211_hdr *pwlanhdr;
6069 unsigned short *fctrl;
6071 unsigned char bssrate[NumRates];
6072 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6073 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6074 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6075 int bssrate_len = 0;
6076 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6077 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6078 u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
6079 u16 wpsielen = 0, p2pielen = 0;
6084 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6087 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6093 pattrib = &pmgntframe->attrib;
6094 update_mgntframe_attrib(padapter, pattrib);
6097 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6099 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6100 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6102 mac = adapter_mac_addr(padapter);
6104 fctrl = &(pwlanhdr->frame_ctl);
6108 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6109 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6111 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
6113 // This two flags will be set when this is only the P2P client mode.
6114 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6115 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6119 // broadcast probe request frame
6120 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6121 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6124 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6126 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6127 pmlmeext->mgnt_seq++;
6128 SetFrameSubType(pframe, WIFI_PROBEREQ);
6130 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6131 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6133 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6135 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6139 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6141 // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
6142 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6144 #ifdef CONFIG_IOCTL_CFG80211
6145 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
6147 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
6150 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6151 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6152 pframe += pmlmepriv->wps_probe_req_ie_len;
6155 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6156 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6157 pframe += pmlmepriv->p2p_probe_req_ie_len;
6161 #endif //CONFIG_IOCTL_CFG80211
6165 // Noted by Albert 20110221
6166 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
6170 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
6175 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
6179 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
6183 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
6185 if( pmlmepriv->wps_probe_req_ie == NULL )
6189 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
6193 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
6197 if (pwdinfo->external_uuid == 0) {
6198 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
6199 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6201 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
6207 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6211 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6215 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6221 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6225 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6229 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6230 wpsielen += pwdinfo->device_name_len;
6232 // Primary Device Type
6234 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6238 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6243 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
6247 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6251 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
6254 // Device Password ID
6256 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
6260 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6264 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified
6267 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6271 p2pie[ p2pielen++ ] = 0x50;
6272 p2pie[ p2pielen++ ] = 0x6F;
6273 p2pie[ p2pielen++ ] = 0x9A;
6274 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
6276 // Commented by Albert 20110221
6277 // According to the P2P Specification, the probe request frame should contain 5 P2P attributes
6278 // 1. P2P Capability
6279 // 2. P2P Device ID if this probe request wants to find the specific P2P device
6280 // 3. Listen Channel
6281 // 4. Extended Listen Timing
6282 // 5. Operating Channel if this WiFi is working as the group owner now
6286 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
6289 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
6293 // Device Capability Bitmap, 1 byte
6294 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
6296 // Group Capability Bitmap, 1 byte
6297 if ( pwdinfo->persistent_supported )
6298 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6300 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
6304 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
6307 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6312 p2pie[ p2pielen++ ] = 'X';
6313 p2pie[ p2pielen++ ] = 'X';
6315 // The third byte should be set to 0x04.
6316 // Described in the "Operating Channel Attribute" section.
6317 p2pie[ p2pielen++ ] = 0x04;
6320 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
6323 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listen channel
6326 // Extended Listen Timing
6328 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
6331 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
6335 // Availability Period
6336 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6339 // Availability Interval
6340 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6343 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
6345 // Operating Channel (if this WiFi is working as the group owner now)
6347 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
6350 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6355 p2pie[ p2pielen++ ] = 'X';
6356 p2pie[ p2pielen++ ] = 'X';
6358 // The third byte should be set to 0x04.
6359 // Described in the "Operating Channel Attribute" section.
6360 p2pie[ p2pielen++ ] = 0x04;
6363 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
6366 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
6370 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
6375 wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6377 pattrib->pktlen += wfdielen;
6380 pattrib->last_txcmdsz = pattrib->pktlen;
6382 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6385 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6387 dump_mgntframe(padapter, pmgntframe);
6395 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6397 _issue_probereq_p2p(adapter, da, _FALSE);
6401 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6402 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
6403 * try_cnt means the maximal TX count to try
6405 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6409 u32 start = rtw_get_current_time();
6413 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
6417 if (RTW_CANNOT_RUN(adapter))
6420 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6421 rtw_msleep_os(wait_ms);
6423 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6427 #ifndef DBG_XMIT_ACK
6432 if (try_cnt && wait_ms) {
6434 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6435 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6436 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6438 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6439 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6440 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6448 s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
6450 _adapter *adapter = rframe->u.hdr.adapter;
6451 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6452 u8 *frame = rframe->u.hdr.rx_data;
6453 u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num&0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
6454 u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
6456 if (GetRetry(frame)) {
6457 if ((seq_ctrl == mlmeext->action_public_rxseq)
6458 && (token == mlmeext->action_public_dialog_token)
6460 DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6461 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6466 /* TODO: per sta seq & token */
6467 mlmeext->action_public_rxseq = seq_ctrl;
6468 mlmeext->action_public_dialog_token = token;
6473 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6475 _adapter *padapter = precv_frame->u.hdr.adapter;
6476 u8 *pframe = precv_frame->u.hdr.rx_data;
6477 uint len = precv_frame->u.hdr.len;
6481 u32 p2p_ielen, wps_ielen;
6482 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6483 u8 result = P2P_STATUS_SUCCESS;
6484 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6485 u8 *merged_p2pie = NULL;
6486 u32 merged_p2p_ielen= 0;
6489 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6492 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
6493 #ifdef CONFIG_IOCTL_CFG80211
6494 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6496 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
6499 #endif //CONFIG_IOCTL_CFG80211
6501 // Do nothing if the driver doesn't enable the P2P function.
6502 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6505 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6507 switch( frame_body[ 6 ] )//OUI Subtype
6509 case P2P_GO_NEGO_REQ:
6511 DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6512 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
6514 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6516 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6519 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6521 // Commented by Albert 20110526
6522 // In this case, this means the previous nego fail doesn't be reset yet.
6523 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6524 // Restore the previous p2p state
6525 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6526 DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
6528 #ifdef CONFIG_CONCURRENT_MODE
6529 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
6531 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6533 #endif // CONFIG_CONCURRENT_MODE
6535 // Commented by Kurt 20110902
6536 //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6537 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6538 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6540 // Commented by Kurt 20120113
6541 // Get peer_dev_addr here if peer doesn't issue prov_disc frame.
6542 if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
6543 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6545 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
6546 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
6547 #ifdef CONFIG_INTEL_WIDI
6548 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6549 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6550 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6551 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6553 #endif //CONFIG_INTEL_WIDI
6555 // Commented by Albert 20110718
6556 // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
6557 #ifdef CONFIG_CONCURRENT_MODE
6558 // Commented by Albert 20120107
6559 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6560 #else // CONFIG_CONCURRENT_MODE
6561 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6562 #endif // CONFIG_CONCURRENT_MODE
6565 case P2P_GO_NEGO_RESP:
6567 DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6569 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6571 // Commented by Albert 20110425
6572 // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
6573 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6574 pwdinfo->nego_req_info.benable = _FALSE;
6575 result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
6576 issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
6577 if ( P2P_STATUS_SUCCESS == result )
6579 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6581 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6582 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6583 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6584 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6585 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6586 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6587 pwdinfo->p2p_info.scan_op_ch_only = 1;
6588 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6592 // Reset the dialog token for group negotiation frames.
6593 pwdinfo->negotiation_dialog_token = 1;
6595 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6597 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6602 DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6607 case P2P_GO_NEGO_CONF:
6609 DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6610 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
6611 if ( P2P_STATUS_SUCCESS == result )
6613 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6615 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6616 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6617 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6618 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6619 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6620 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6621 pwdinfo->p2p_info.scan_op_ch_only = 1;
6622 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6629 // Added by Albert 2010/10/05
6630 // Received the P2P Invite Request frame.
6632 DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
6633 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6635 // Parse the necessary information from the P2P Invitation Request frame.
6636 // For example: The MAC address of sending this P2P Invitation Request frame.
6637 u32 attr_contentlen = 0;
6638 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6639 struct group_id_info group_id;
6640 u8 invitation_flag = 0;
6643 merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6645 merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); // 2 is for EID and Length
6646 if (merged_p2pie == NULL)
6648 DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
6651 _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
6653 merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6655 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6656 if ( attr_contentlen )
6659 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6660 // Commented by Albert 20120510
6661 // Copy to the pwdinfo->p2p_peer_interface_addr.
6662 // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
6663 // #> iwpriv wlan0 p2p_get peer_ifa
6664 // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
6666 if ( attr_contentlen )
6668 DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6669 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6670 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6671 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
6674 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
6676 // Re-invoke the persistent group.
6678 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6679 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6680 if ( attr_contentlen )
6682 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6684 // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
6685 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
6686 rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
6687 status_code = P2P_STATUS_SUCCESS;
6691 // The p2p device sending this p2p invitation request wants to be the persistent GO.
6692 if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
6694 u8 operatingch_info[5] = { 0x00 };
6695 if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
6697 if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
6699 // The operating channel is acceptable for this device.
6700 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
6701 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6702 pwdinfo->rx_invitereq_info.operation_ch[1]= 1; //Check whether GO is operating in channel 1;
6703 pwdinfo->rx_invitereq_info.operation_ch[2]= 6; //Check whether GO is operating in channel 6;
6704 pwdinfo->rx_invitereq_info.operation_ch[3]= 11; //Check whether GO is operating in channel 11;
6705 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6706 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6707 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
6708 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6709 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6710 status_code = P2P_STATUS_SUCCESS;
6714 // The operating channel isn't supported by this device.
6715 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6716 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
6717 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6718 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6723 // Commented by Albert 20121130
6724 // Intel will use the different P2P IE to store the operating channel information
6725 // Workaround for Intel WiDi 3.5
6726 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6727 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6728 status_code = P2P_STATUS_SUCCESS;
6733 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6734 #ifdef CONFIG_INTEL_WIDI
6735 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6736 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6737 #endif //CONFIG_INTEL_WIDI
6739 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6745 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6746 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6751 // Received the invitation to join a P2P group.
6753 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6754 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6755 if ( attr_contentlen )
6757 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6759 // In this case, the GO can't be myself.
6760 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6761 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6765 // The p2p device sending this p2p invitation request wants to join an existing P2P group
6766 // Commented by Albert 2012/06/28
6767 // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
6768 // The peer device address should be the destination address for the provisioning discovery request.
6769 // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
6770 // The peer interface address should be the address for WPS mac address
6771 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6772 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6773 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
6774 status_code = P2P_STATUS_SUCCESS;
6779 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6780 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6786 DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
6787 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6790 DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
6792 pwdinfo->inviteresp_info.token = frame_body[ 7 ];
6793 issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
6794 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6796 #ifdef CONFIG_INTEL_WIDI
6797 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6798 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6799 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6800 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6802 #endif //CONFIG_INTEL_WIDI
6805 case P2P_INVIT_RESP:
6807 u8 attr_content = 0x00;
6808 u32 attr_contentlen = 0;
6810 DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
6811 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6812 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6814 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6816 if ( attr_contentlen == 1 )
6818 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
6819 pwdinfo->invitereq_info.benable = _FALSE;
6821 if ( attr_content == P2P_STATUS_SUCCESS )
6823 if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6824 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
6826 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6828 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
6832 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6833 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6838 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6839 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6844 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6845 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6848 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
6850 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6854 case P2P_DEVDISC_REQ:
6856 process_p2p_devdisc_req(pwdinfo, pframe, len);
6860 case P2P_DEVDISC_RESP:
6862 process_p2p_devdisc_resp(pwdinfo, pframe, len);
6866 case P2P_PROVISION_DISC_REQ:
6867 DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
6868 process_p2p_provdisc_req(pwdinfo, pframe, len);
6869 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6872 //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6873 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6874 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6876 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6877 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6878 #ifdef CONFIG_INTEL_WIDI
6879 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6880 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6881 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6882 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6884 #endif //CONFIG_INTEL_WIDI
6887 case P2P_PROVISION_DISC_RESP:
6888 // Commented by Albert 20110707
6889 // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
6890 DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
6891 // Commented by Albert 20110426
6892 // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
6893 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6894 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6895 process_p2p_provdisc_resp(pwdinfo, pframe);
6896 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6907 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6913 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6915 unsigned int ret = _FAIL;
6916 u8 *pframe = precv_frame->u.hdr.rx_data;
6917 uint frame_len = precv_frame->u.hdr.len;
6918 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6920 if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6921 if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
6924 if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
6925 rtw_rframe_del_wfd_ie(precv_frame, 8);
6927 ret = on_action_public_p2p(precv_frame);
6934 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6936 unsigned int ret = _FAIL;
6937 u8 *pframe = precv_frame->u.hdr.rx_data;
6938 uint frame_len = precv_frame->u.hdr.len;
6939 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6941 _adapter *adapter = precv_frame->u.hdr.adapter;
6945 token = frame_body[2];
6947 if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
6950 #ifdef CONFIG_IOCTL_CFG80211
6951 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
6952 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
6961 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6963 unsigned int ret = _FAIL;
6964 u8 *pframe = precv_frame->u.hdr.rx_data;
6965 uint frame_len = precv_frame->u.hdr.len;
6966 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6967 u8 category, action;
6969 /* check RA matches or not */
6970 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6973 category = frame_body[0];
6974 if (category != RTW_WLAN_CATEGORY_PUBLIC)
6977 action = frame_body[1];
6979 case ACT_PUBLIC_BSSCOEXIST:
6980 #ifdef CONFIG_80211N_HT
6981 #ifdef CONFIG_AP_MODE
6982 /*20/40 BSS Coexistence Management frame is a Public Action frame*/
6983 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6984 rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6985 #endif /*CONFIG_AP_MODE*/
6986 #endif /*CONFIG_80211N_HT*/
6988 case ACT_PUBLIC_VENDOR:
6989 ret = on_action_public_vendor(precv_frame);
6992 ret = on_action_public_default(precv_frame, action);
7000 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7002 u8 *pframe = precv_frame->u.hdr.rx_data;
7003 uint frame_len = precv_frame->u.hdr.len;
7004 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7005 u8 category, action;
7007 /* check RA matches or not */
7008 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7011 category = frame_body[0];
7012 if (category != RTW_WLAN_CATEGORY_HT)
7015 action = frame_body[1];
7017 case RTW_WLAN_ACTION_HT_SM_PS:
7018 #ifdef CONFIG_80211N_HT
7019 #ifdef CONFIG_AP_MODE
7020 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7021 rtw_process_ht_action_smps(padapter, GetAddr2Ptr(pframe), frame_body[2]);
7022 #endif /*CONFIG_AP_MODE*/
7023 #endif /*CONFIG_80211N_HT*/
7025 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7026 #ifdef CONFIG_BEAMFORMING
7027 /*DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7028 beamforming_get_report_frame(padapter, precv_frame);
7029 #endif /*CONFIG_BEAMFORMING*/
7040 #ifdef CONFIG_IEEE80211W
7041 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7043 u8 *pframe = precv_frame->u.hdr.rx_data;
7044 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7045 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7046 struct sta_info *psta;
7047 struct sta_priv *pstapriv = &padapter->stapriv;
7048 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7052 DBG_871X("OnAction_sa_query\n");
7054 switch (pframe[WLAN_HDR_A3_LEN+1])
7056 case 0: //SA Query req
7057 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7058 DBG_871X("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7059 , pframe[WLAN_HDR_A3_LEN+1], tid, pframe[WLAN_HDR_A3_LEN+2], pframe[WLAN_HDR_A3_LEN+3]);
7060 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7063 case 1: //SA Query rsp
7064 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
7066 _cancel_timer_ex(&psta->dot11w_expire_timer);
7068 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7069 DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], tid);
7077 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7078 for(pp=0;pp< pattrib->pkt_len; pp++)
7079 printk(" %02x ", pframe[pp]);
7085 #endif //CONFIG_IEEE80211W
7087 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7092 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7094 #ifdef CONFIG_80211AC_VHT
7095 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
7096 u8 *pframe = precv_frame->u.hdr.rx_data;
7097 uint frame_len = precv_frame->u.hdr.len;
7098 struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7099 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7100 u8 category, action;
7101 struct sta_info *psta = NULL;
7103 /* check RA matches or not */
7104 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7107 category = frame_body[0];
7108 if(category != RTW_WLAN_CATEGORY_VHT)
7111 action = frame_body[1];
7113 case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7114 #ifdef CONFIG_BEAMFORMING
7115 /*DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7116 beamforming_get_report_frame(padapter, precv_frame);
7117 #endif /*CONFIG_BEAMFORMING*/
7119 case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7120 // CategoryCode(1) + ActionCode(1) + OpModeNotification(1)
7121 //DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n");
7122 psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7124 rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7131 #endif //CONFIG_80211AC_VHT
7136 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7140 u8 category, OUI_Subtype, dialogToken=0;
7141 u8 *pframe = precv_frame->u.hdr.rx_data;
7142 uint len = precv_frame->u.hdr.len;
7143 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
7145 //check RA matches or not
7146 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7149 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7151 category = frame_body[0];
7152 if(category != RTW_WLAN_CATEGORY_P2P)
7155 if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
7158 #ifdef CONFIG_IOCTL_CFG80211
7159 if (adapter_wdev_data(padapter)->p2p_enabled
7160 && pwdinfo->driver_interface == DRIVER_CFG80211
7162 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
7166 #endif //CONFIG_IOCTL_CFG80211
7168 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7169 OUI_Subtype = frame_body[5];
7170 dialogToken = frame_body[6];
7174 case P2P_NOTICE_OF_ABSENCE:
7178 case P2P_PRESENCE_REQUEST:
7180 process_p2p_presence_req(pwdinfo, pframe, len);
7184 case P2P_PRESENCE_RESPONSE:
7188 case P2P_GO_DISC_REQUEST:
7203 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7206 unsigned char category;
7207 struct action_handler *ptable;
7208 unsigned char *frame_body;
7209 u8 *pframe = precv_frame->u.hdr.rx_data;
7211 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7213 category = frame_body[0];
7215 for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
7217 ptable = &OnAction_tbl[i];
7219 if(category == ptable->num)
7220 ptable->func(padapter, precv_frame);
7228 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7231 //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
7235 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7237 struct xmit_frame *pmgntframe;
7238 struct xmit_buf *pxmitbuf;
7241 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7243 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7245 if (pmgntframe == NULL) {
7246 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7250 if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
7251 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7252 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7257 pmgntframe->frame_tag = MGNT_FRAMETAG;
7258 pmgntframe->pxmitbuf = pxmitbuf;
7259 pmgntframe->buf_addr = pxmitbuf->pbuf;
7260 pxmitbuf->priv_data = pmgntframe;
7267 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7269 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7272 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7274 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7278 /****************************************************************************
7280 Following are some TX fuctions for WiFi MLME
7282 *****************************************************************************/
7284 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7286 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7288 pmlmeext->tx_rate = rate;
7289 //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
7293 void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7295 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7297 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7298 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7299 struct sta_info *psta = NULL;
7300 struct sta_priv *pstapriv = &padapter->stapriv;
7301 struct sta_info *pbcmc_sta = NULL;
7303 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7304 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7306 pattrib->hdrlen = 24;
7307 pattrib->nr_frags = 1;
7308 pattrib->priority = 7;
7311 pattrib->mac_id = pbcmc_sta->mac_id;
7313 pattrib->mac_id = 0;
7314 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7316 pattrib->qsel = QSLT_MGNT;
7318 pattrib->pktlen = 0;
7320 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7321 wireless_mode = WIRELESS_11B;
7323 wireless_mode = WIRELESS_11G;
7325 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7326 #ifdef CONFIG_80211AC_VHT
7327 if (pHalData->rf_type == RF_1T1R)
7328 pattrib->raid = RATEID_IDX_VHT_1SS;
7329 else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
7330 pattrib->raid = RATEID_IDX_VHT_2SS;
7331 else if (pHalData->rf_type == RF_3T3R)
7332 pattrib->raid = RATEID_IDX_VHT_3SS;
7334 pattrib->raid = RATEID_IDX_BGN_40M_1SS;
7337 #ifdef CONFIG_80211AC_VHT
7338 pattrib->rate = MGN_VHT1SS_MCS9;
7340 pattrib->rate = MGN_MCS7;
7343 pattrib->encrypt = _NO_PRIVACY_;
7344 pattrib->bswenc = _FALSE;
7346 pattrib->qos_en = _FALSE;
7348 pattrib->bwmode = CHANNEL_WIDTH_20;
7349 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7350 pattrib->sgi = _FALSE;
7352 pattrib->seqnum = pmlmeext->mgnt_seq;
7354 pattrib->retry_ctrl = _TRUE;
7356 pattrib->mbssid = 0;
7357 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7362 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7365 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7366 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7367 struct sta_info *psta = NULL;
7368 struct sta_priv *pstapriv = &padapter->stapriv;
7369 struct sta_info *pbcmc_sta = NULL;
7370 //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
7372 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7374 pattrib->hdrlen = 24;
7375 pattrib->nr_frags = 1;
7376 pattrib->priority = 7;
7379 pattrib->mac_id = pbcmc_sta->mac_id;
7381 pattrib->mac_id = 0;
7382 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7384 pattrib->qsel = QSLT_MGNT;
7386 pattrib->pktlen = 0;
7388 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7389 wireless_mode = WIRELESS_11B;
7391 wireless_mode = WIRELESS_11G;
7392 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7393 pattrib->rate = pmlmeext->tx_rate;
7395 pattrib->encrypt = _NO_PRIVACY_;
7396 pattrib->bswenc = _FALSE;
7398 pattrib->qos_en = _FALSE;
7399 pattrib->ht_en = _FALSE;
7400 pattrib->bwmode = CHANNEL_WIDTH_20;
7401 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7402 pattrib->sgi = _FALSE;
7404 pattrib->seqnum = pmlmeext->mgnt_seq;
7406 pattrib->retry_ctrl = _TRUE;
7408 pattrib->mbssid = 0;
7409 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7411 #ifdef CONFIG_BEAMFORMING
7412 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7414 update_attrib_txbf_info(padapter, pattrib, psta);
7419 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7422 struct pkt_attrib *pattrib = &pmgntframe->attrib;
7424 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7426 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7427 _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
7430 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7432 if (RTW_CANNOT_RUN(padapter)) {
7433 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7434 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7438 rtw_hal_mgnt_xmit(padapter, pmgntframe);
7441 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7445 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7446 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7447 struct submit_ctx sctx;
7449 if (RTW_CANNOT_RUN(padapter)) {
7450 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7451 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7455 rtw_sctx_init(&sctx, timeout_ms);
7456 pxmitbuf->sctx = &sctx;
7458 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7460 if (ret == _SUCCESS)
7461 ret = rtw_sctx_wait(&sctx, __func__);
7463 _enter_critical(&pxmitpriv->lock_sctx, &irqL);
7464 pxmitbuf->sctx = NULL;
7465 _exit_critical(&pxmitpriv->lock_sctx, &irqL);
7470 s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7472 #ifdef CONFIG_XMIT_ACK
7473 static u8 seq_no = 0;
7475 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7476 #ifdef CONFIG_CONCURRENT_MODE
7477 if (padapter->pbuddy_adapter && !padapter->isprimary)
7478 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7481 if (RTW_CANNOT_RUN(padapter)) {
7482 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7483 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7487 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7488 pxmitpriv->ack_tx = _TRUE;
7489 pxmitpriv->seq_no = seq_no++;
7490 pmgntframe->ack_report = 1;
7491 rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7492 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7493 #ifdef CONFIG_XMIT_ACK_POLLING
7494 ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7496 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7500 pxmitpriv->ack_tx = _FALSE;
7501 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7504 #else /* !CONFIG_XMIT_ACK */
7505 dump_mgntframe(padapter, pmgntframe);
7508 #endif /* !CONFIG_XMIT_ACK */
7511 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7513 /* In this case, use 500 ms as the default wait_ack timeout */
7514 return dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 500);
7518 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7524 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
7526 //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
7528 if(ssid_ie && ssid_len_ori>0)
7530 switch(hidden_ssid_mode)
7534 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7537 remain_len = ies_len -(next_ie-ies);
7540 _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
7541 len_diff -= ssid_len_ori;
7546 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7556 void issue_beacon(_adapter *padapter, int timeout_ms)
7558 struct xmit_frame *pmgntframe;
7559 struct pkt_attrib *pattrib;
7560 unsigned char *pframe;
7561 struct rtw_ieee80211_hdr *pwlanhdr;
7562 unsigned short *fctrl;
7563 unsigned int rate_len;
7564 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7565 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7567 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7568 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7569 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7570 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7571 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7572 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7574 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7578 //DBG_871X("%s\n", __FUNCTION__);
7580 #ifdef CONFIG_BCN_ICF
7581 if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL)
7583 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7586 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7589 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7590 _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7591 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7594 pattrib = &pmgntframe->attrib;
7595 update_mgntframe_attrib(padapter, pattrib);
7596 pattrib->qsel = QSLT_BEACON;
7597 #ifdef CONFIG_CONCURRENT_MODE
7598 if(padapter->iface_type == IFACE_PORT1)
7599 pattrib->mbssid = 1;
7602 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7604 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7605 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7608 fctrl = &(pwlanhdr->frame_ctl);
7611 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7612 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7613 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7615 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7616 //pmlmeext->mgnt_seq++;
7617 SetFrameSubType(pframe, WIFI_BEACON);
7619 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7620 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7622 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7624 //DBG_871X("ie len=%d\n", cur_network->IELength);
7626 // for P2P : Primary Device Type & Device Name
7627 u32 wpsielen=0, insert_len=0;
7629 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
7631 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
7633 uint wps_offset, remainder_ielen;
7634 u8 *premainder_ie, *pframe_wscie;
7636 wps_offset = (uint)(wpsie - cur_network->IEs);
7638 premainder_ie = wpsie + wpsielen;
7640 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7642 #ifdef CONFIG_IOCTL_CFG80211
7643 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7645 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
7647 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7648 pframe += wps_offset;
7649 pattrib->pktlen += wps_offset;
7651 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7652 pframe += pmlmepriv->wps_beacon_ie_len;
7653 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7655 //copy remainder_ie to pframe
7656 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7657 pframe += remainder_ielen;
7658 pattrib->pktlen += remainder_ielen;
7662 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7663 pframe += cur_network->IELength;
7664 pattrib->pktlen += cur_network->IELength;
7668 #endif //CONFIG_IOCTL_CFG80211
7670 pframe_wscie = pframe + wps_offset;
7671 _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
7672 pframe += (wps_offset + wpsielen);
7673 pattrib->pktlen += (wps_offset + wpsielen);
7675 //now pframe is end of wsc ie, insert Primary Device Type & Device Name
7676 // Primary Device Type
7678 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
7682 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
7687 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7691 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
7695 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7701 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7705 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
7709 _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
7710 insert_len += pwdinfo->device_name_len;
7713 //update wsc ie length
7714 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
7716 //pframe move to end
7718 pattrib->pktlen += insert_len;
7720 //copy remainder_ie to pframe
7721 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7722 pframe += remainder_ielen;
7723 pattrib->pktlen += remainder_ielen;
7730 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7731 len_diff = update_hidden_ssid(
7732 pframe+_BEACON_IE_OFFSET_
7733 , cur_network->IELength-_BEACON_IE_OFFSET_
7734 , pmlmeinfo->hidden_ssid_mode
7736 pframe += (cur_network->IELength+len_diff);
7737 pattrib->pktlen += (cur_network->IELength+len_diff);
7744 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
7745 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
7746 if (wps_ie && wps_ielen>0) {
7747 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
7750 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7752 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7756 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
7759 #ifdef CONFIG_IOCTL_CFG80211
7760 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7762 len = pmlmepriv->p2p_beacon_ie_len;
7763 if(pmlmepriv->p2p_beacon_ie && len>0)
7764 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7767 #endif //CONFIG_IOCTL_CFG80211
7769 len = build_beacon_p2p_ie(pwdinfo, pframe);
7773 pattrib->pktlen += len;
7776 len = rtw_append_beacon_wfd_ie(padapter, pframe);
7778 pattrib->pktlen += len;
7787 //below for ad-hoc mode
7789 //timestamp will be inserted by hardware
7791 pattrib->pktlen += 8;
7793 // beacon interval: 2 bytes
7795 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7798 pattrib->pktlen += 2;
7800 // capability info: 2 bytes
7802 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7805 pattrib->pktlen += 2;
7808 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7810 // supported rates...
7811 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7812 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7815 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7817 //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7821 // IBSS Parameter Set...
7822 //ATIMWindow = cur->Configuration.ATIMWindow;
7824 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7827 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7831 // EXTERNDED SUPPORTED RATE
7834 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7842 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7843 pmlmepriv->update_bcn = _FALSE;
7845 _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7846 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7848 if ((pattrib->pktlen + TXDESC_SIZE) > 512)
7850 DBG_871X("beacon frame too large\n");
7854 pattrib->last_txcmdsz = pattrib->pktlen;
7856 //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
7858 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7860 dump_mgntframe(padapter, pmgntframe);
7864 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7866 struct xmit_frame *pmgntframe;
7867 struct pkt_attrib *pattrib;
7868 unsigned char *pframe;
7869 struct rtw_ieee80211_hdr *pwlanhdr;
7870 unsigned short *fctrl;
7871 unsigned char *mac, *bssid;
7872 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7873 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7876 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7877 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7878 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7879 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7880 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7881 unsigned int rate_len;
7883 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7889 //DBG_871X("%s\n", __FUNCTION__);
7894 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
7897 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7899 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7905 pattrib = &pmgntframe->attrib;
7906 update_mgntframe_attrib(padapter, pattrib);
7908 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7910 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7911 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7913 mac = adapter_mac_addr(padapter);
7914 bssid = cur_network->MacAddress;
7916 fctrl = &(pwlanhdr->frame_ctl);
7918 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7919 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7920 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7922 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7923 pmlmeext->mgnt_seq++;
7924 SetFrameSubType(fctrl, WIFI_PROBERSP);
7926 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7927 pattrib->pktlen = pattrib->hdrlen;
7928 pframe += pattrib->hdrlen;
7931 if(cur_network->IELength>MAX_IE_SZ)
7934 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7935 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7937 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
7939 //inerset & update wps_probe_resp_ie
7940 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
7942 uint wps_offset, remainder_ielen;
7945 wps_offset = (uint)(pwps_ie - cur_network->IEs);
7947 premainder_ie = pwps_ie + wps_ielen;
7949 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
7951 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7952 pframe += wps_offset;
7953 pattrib->pktlen += wps_offset;
7955 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
7956 if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
7958 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
7959 pframe += wps_ielen+2;
7960 pattrib->pktlen += wps_ielen+2;
7963 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
7965 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7966 pframe += remainder_ielen;
7967 pattrib->pktlen += remainder_ielen;
7972 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7973 pframe += cur_network->IELength;
7974 pattrib->pktlen += cur_network->IELength;
7977 /* retrieve SSID IE from cur_network->Ssid */
7981 sint ssid_ielen_diff;
7983 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
7985 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
7986 (pframe-ies)-_FIXED_IE_LENGTH_);
7988 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
7990 if (ssid_ie && cur_network->Ssid.SsidLength) {
7991 uint remainder_ielen;
7993 remainder_ie = ssid_ie+2;
7994 remainder_ielen = (pframe-remainder_ie);
7996 if (remainder_ielen > MAX_IE_SZ) {
7997 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
7998 remainder_ielen = MAX_IE_SZ;
8001 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
8002 _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
8003 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
8004 _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8006 pframe += ssid_ielen_diff;
8007 pattrib->pktlen += ssid_ielen_diff;
8015 //timestamp will be inserted by hardware
8017 pattrib->pktlen += 8;
8019 // beacon interval: 2 bytes
8021 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8024 pattrib->pktlen += 2;
8026 // capability info: 2 bytes
8028 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8031 pattrib->pktlen += 2;
8033 //below for ad-hoc mode
8036 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8038 // supported rates...
8039 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8040 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8043 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8045 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
8049 // IBSS Parameter Set...
8050 //ATIMWindow = cur->Configuration.ATIMWindow;
8052 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8055 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8059 // EXTERNDED SUPPORTED RATE
8062 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8071 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8072 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8073 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec))
8076 #ifdef CONFIG_IOCTL_CFG80211
8077 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8079 //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
8080 len = pmlmepriv->p2p_go_probe_resp_ie_len;
8081 if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
8082 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8085 #endif //CONFIG_IOCTL_CFG80211
8087 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8091 pattrib->pktlen += len;
8094 len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8096 pattrib->pktlen += len;
8102 #ifdef CONFIG_AUTO_AP_MODE
8104 struct sta_info *psta;
8105 struct sta_priv *pstapriv = &padapter->stapriv;
8107 DBG_871X("(%s)\n", __FUNCTION__);
8110 psta = rtw_get_stainfo(pstapriv, da);
8111 if (psta && psta->isrc && psta->pid>0)
8113 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
8114 u8 RC_INFO[14] = {0};
8115 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
8116 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8118 DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8119 psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
8121 //append vendor specific ie
8122 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8123 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8124 _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
8125 _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
8127 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8130 #endif //CONFIG_AUTO_AP_MODE
8133 pattrib->last_txcmdsz = pattrib->pktlen;
8136 dump_mgntframe(padapter, pmgntframe);
8142 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
8145 struct xmit_frame *pmgntframe;
8146 struct pkt_attrib *pattrib;
8147 unsigned char *pframe;
8148 struct rtw_ieee80211_hdr *pwlanhdr;
8149 unsigned short *fctrl;
8151 unsigned char bssrate[NumRates];
8152 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8153 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8154 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8155 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8156 int bssrate_len = 0;
8157 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8159 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8162 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8168 pattrib = &pmgntframe->attrib;
8169 update_mgntframe_attrib(padapter, pattrib);
8172 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8174 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8175 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8177 mac = adapter_mac_addr(padapter);
8179 fctrl = &(pwlanhdr->frame_ctl);
8184 // unicast probe request frame
8185 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8186 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8190 // broadcast probe request frame
8191 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8192 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8195 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8197 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8198 pmlmeext->mgnt_seq++;
8199 SetFrameSubType(pframe, WIFI_PROBEREQ);
8201 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
8202 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
8205 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8207 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8209 get_rate_set(padapter, bssrate, &bssrate_len);
8211 if (bssrate_len > 8)
8213 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8214 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8218 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8222 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8225 //add wps_ie for wps2.0
8226 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
8228 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8229 pframe += pmlmepriv->wps_probe_req_ie_len;
8230 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8231 //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
8235 pattrib->last_txcmdsz = pattrib->pktlen;
8237 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
8240 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8242 dump_mgntframe(padapter, pmgntframe);
8250 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
8252 _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8256 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8257 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
8258 * try_cnt means the maximal TX count to try
8260 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
8261 int try_cnt, int wait_ms)
8265 u32 start = rtw_get_current_time();
8267 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8272 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE);
8276 if (RTW_CANNOT_RUN(padapter))
8279 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8280 rtw_msleep_os(wait_ms);
8282 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8286 #ifndef DBG_XMIT_ACK
8291 if (try_cnt && wait_ms) {
8293 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8294 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8295 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8297 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8298 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8299 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8305 // if psta == NULL, indiate we are station(client) now...
8306 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8308 struct xmit_frame *pmgntframe;
8309 struct pkt_attrib *pattrib;
8310 unsigned char *pframe;
8311 struct rtw_ieee80211_hdr *pwlanhdr;
8312 unsigned short *fctrl;
8314 unsigned short val16;
8315 int use_shared_key = 0;
8316 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8317 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8318 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8320 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8323 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8329 pattrib = &pmgntframe->attrib;
8330 update_mgntframe_attrib(padapter, pattrib);
8332 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8334 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8335 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8337 fctrl = &(pwlanhdr->frame_ctl);
8340 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8341 pmlmeext->mgnt_seq++;
8342 SetFrameSubType(pframe, WIFI_AUTH);
8344 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8345 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8348 if(psta)// for AP mode
8350 #ifdef CONFIG_NATIVEAP_MLME
8352 _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
8353 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8354 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8357 // setting auth algo number
8358 val16 = (u16)psta->authalg;
8360 if(status != _STATS_SUCCESSFUL_)
8364 val16 = cpu_to_le16(val16);
8368 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8370 // setting auth seq number
8371 val16 =(u16)psta->auth_seq;
8372 val16 = cpu_to_le16(val16);
8373 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8375 // setting status code...
8377 val16 = cpu_to_le16(val16);
8378 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8380 // added challenging text...
8381 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8383 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8389 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8390 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8391 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8393 // setting auth algo number
8394 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
8396 val16 = cpu_to_le16(val16);
8399 //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
8401 //setting IV for auth seq #3
8402 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8404 //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
8405 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8406 val32 = cpu_to_le32(val32);
8407 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8409 pattrib->iv_len = 4;
8412 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8414 // setting auth seq number
8415 val16 = pmlmeinfo->auth_seq;
8416 val16 = cpu_to_le16(val16);
8417 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8420 // setting status code...
8422 val16 = cpu_to_le16(val16);
8423 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8425 // then checking to see if sending challenging text...
8426 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8428 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8432 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8434 pattrib->encrypt = _WEP40_;
8436 pattrib->icv_len = 4;
8438 pattrib->pktlen += pattrib->icv_len;
8444 pattrib->last_txcmdsz = pattrib->pktlen;
8446 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8447 DBG_871X("%s\n", __FUNCTION__);
8448 dump_mgntframe(padapter, pmgntframe);
8454 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8456 #ifdef CONFIG_AP_MODE
8457 struct xmit_frame *pmgntframe;
8458 struct rtw_ieee80211_hdr *pwlanhdr;
8459 struct pkt_attrib *pattrib;
8460 unsigned char *pbuf, *pframe;
8461 unsigned short val, ie_status;
8462 unsigned short *fctrl;
8463 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8464 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8465 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8466 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8467 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8468 u8 *ie = pnetwork->IEs;
8470 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8477 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8480 DBG_871X("%s\n", __FUNCTION__);
8482 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8488 pattrib = &pmgntframe->attrib;
8489 update_mgntframe_attrib(padapter, pattrib);
8492 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8494 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8495 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8497 fctrl = &(pwlanhdr->frame_ctl);
8500 _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
8501 _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8502 _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8505 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8506 pmlmeext->mgnt_seq++;
8507 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8508 SetFrameSubType(pwlanhdr, pkt_type);
8512 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8513 pattrib->pktlen += pattrib->hdrlen;
8514 pframe += pattrib->hdrlen;
8517 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8519 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8521 ie_status = cpu_to_le16(status);
8522 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8524 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
8525 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8527 if (pstat->bssratelen <= 8)
8529 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8533 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8534 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
8537 #ifdef CONFIG_IEEE80211W
8538 if (status == _STATS_REFUSED_TEMPORARILY_) {
8540 u32 timeout_interval = 3000;
8541 /* Association Comeback time */
8542 timeout_itvl[0] = 0x03;
8543 timeout_interval = cpu_to_le32(timeout_interval);
8544 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
8545 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8547 #endif /* CONFIG_IEEE80211W */
8549 #ifdef CONFIG_80211N_HT
8550 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
8554 //FILL HT CAP INFO IE
8555 //p = hostapd_eid_ht_capabilities_info(hapd, p);
8556 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8557 if(pbuf && ie_len>0)
8559 _rtw_memcpy(pframe, pbuf, ie_len+2);
8560 pframe += (ie_len+2);
8561 pattrib->pktlen +=(ie_len+2);
8564 //FILL HT ADD INFO IE
8565 //p = hostapd_eid_ht_operation(hapd, p);
8566 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8567 if(pbuf && ie_len>0)
8569 _rtw_memcpy(pframe, pbuf, ie_len+2);
8570 pframe += (ie_len+2);
8571 pattrib->pktlen +=(ie_len+2);
8577 /*adding EXT_CAPAB_IE */
8578 if (pmlmepriv->ext_capab_ie_len > 0) {
8581 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8582 if (pbuf && ie_len > 0) {
8583 _rtw_memcpy(pframe, pbuf, ie_len+2);
8584 pframe += (ie_len+2);
8585 pattrib->pktlen += (ie_len+2);
8589 #ifdef CONFIG_80211AC_VHT
8590 if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8591 && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8592 && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP))
8597 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8598 if(pbuf && ie_len>0)
8600 _rtw_memcpy(pframe, pbuf, ie_len+2);
8601 pframe += (ie_len+2);
8602 pattrib->pktlen +=(ie_len+2);
8605 //FILL VHT OPERATION IE
8606 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8607 if(pbuf && ie_len>0)
8609 _rtw_memcpy(pframe, pbuf, ie_len+2);
8610 pframe += (ie_len+2);
8611 pattrib->pktlen +=(ie_len+2);
8614 #endif //CONFIG_80211AC_VHT
8617 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
8620 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
8622 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
8624 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
8625 if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
8627 _rtw_memcpy(pframe, pbuf, ie_len+2);
8628 pframe += (ie_len+2);
8629 pattrib->pktlen +=(ie_len+2);
8634 if ((pbuf == NULL) || (ie_len == 0))
8643 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8645 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8648 //add WPS IE ie for wps 2.0
8649 if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
8651 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8653 pframe += pmlmepriv->wps_assoc_resp_ie_len;
8654 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8658 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
8661 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
8663 if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
8664 len = pmlmepriv->p2p_assoc_resp_ie_len;
8665 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
8668 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8671 pattrib->pktlen += len;
8675 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8676 wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
8678 pattrib->pktlen += wfdielen;
8682 #endif /* CONFIG_P2P */
8684 pattrib->last_txcmdsz = pattrib->pktlen;
8686 dump_mgntframe(padapter, pmgntframe);
8691 void issue_assocreq(_adapter *padapter)
8694 struct xmit_frame *pmgntframe;
8695 struct pkt_attrib *pattrib;
8696 unsigned char *pframe, *p;
8697 struct rtw_ieee80211_hdr *pwlanhdr;
8698 unsigned short *fctrl;
8699 unsigned short val16;
8700 unsigned int i, j, ie_len, index=0;
8701 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8702 PNDIS_802_11_VARIABLE_IEs pIE;
8703 struct registry_priv *pregpriv = &padapter->registrypriv;
8704 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8705 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8706 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8707 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8708 int bssrate_len = 0, sta_bssrate_len = 0;
8709 u8 vs_ie_length = 0;
8711 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8712 u8 p2pie[ 255 ] = { 0x00 };
8723 u8 pow_cap_ele[2] = { 0x00 };
8724 u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
8727 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8730 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8734 pattrib = &pmgntframe->attrib;
8735 update_mgntframe_attrib(padapter, pattrib);
8738 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8740 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8741 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8743 fctrl = &(pwlanhdr->frame_ctl);
8745 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8746 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8747 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8749 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8750 pmlmeext->mgnt_seq++;
8751 SetFrameSubType(pframe, WIFI_ASSOCREQ);
8753 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8754 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8759 _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8760 cap |= cap_SpecMgmt;
8761 _rtw_memcpy(pframe, &cap, 2);
8763 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8767 pattrib->pktlen += 2;
8770 //todo: listen interval for power saving
8771 val16 = cpu_to_le16(3);
8772 _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
8774 pattrib->pktlen += 2;
8777 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8781 if(pmlmeext->cur_channel > 14)
8783 pow_cap_ele[0] = 13; // Minimum transmit power capability
8784 pow_cap_ele[1] = 21; // Maximum transmit power capability
8785 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8787 //supported channels
8789 if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
8791 sup_ch[0] = 1; //First channel number
8792 sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel
8796 sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8797 sup_ch[idx_5g++] = 1;
8801 while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
8802 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8806 //supported rate & extended supported rate
8808 #if 1 // Check if the AP's supported rates are also supported by STA.
8809 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8810 //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
8812 if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
8814 sta_bssrate_len = 4;
8818 //for (i = 0; i < sta_bssrate_len; i++) {
8819 // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
8822 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8823 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8824 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8828 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8829 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8832 // Check if the AP's supported rates are also supported by STA.
8833 for (j=0; j < sta_bssrate_len; j++) {
8834 // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8835 if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
8836 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
8837 //DBG_871X("match i = %d, j=%d\n", i, j);
8840 //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
8844 if (j == sta_bssrate_len) {
8845 // the rate is not supported by STA
8846 DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8848 // the rate is supported by STA
8849 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8853 bssrate_len = index;
8854 DBG_871X("bssrate_len = %d\n", bssrate_len);
8856 #else // Check if the AP's supported rates are also supported by STA.
8858 get_rate_set(padapter, bssrate, &bssrate_len);
8860 for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8861 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
8863 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8866 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8869 #endif // Check if the AP's supported rates are also supported by STA.
8871 if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8872 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8873 rtw_free_xmitframe(pxmitpriv, pmgntframe);
8874 goto exit; //don't connect to AP if no joint supported rate
8878 if (bssrate_len > 8)
8880 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8881 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8883 else if (bssrate_len > 0)
8885 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8887 DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n",__FUNCTION__);
8890 //vendor specific IE, such as WPA, WMM, WPS
8891 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
8893 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8895 switch (pIE->ElementID)
8897 case _VENDOR_SPECIFIC_IE_:
8898 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8899 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8900 (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8902 vs_ie_length = pIE->Length;
8903 if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8905 //Commented by Kurt 20110629
8906 //In some older APs, WPS handshake
8907 //would be fail if we append vender extensions informations to AP
8912 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8917 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8919 #ifdef CONFIG_80211N_HT
8920 case EID_HTCapability:
8921 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8922 if (!(is_ap_in_tkip(padapter)))
8924 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8926 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8928 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8933 case EID_EXTCapability:
8934 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8935 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8938 #endif //CONFIG_80211N_HT
8939 #ifdef CONFIG_80211AC_VHT
8940 case EID_VHTCapability:
8941 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8942 pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8946 case EID_OpModeNotification:
8947 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8948 pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
8951 #endif // CONFIG_80211AC_VHT
8956 i += (pIE->Length + 2);
8959 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8961 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8965 #ifdef CONFIG_WAPI_SUPPORT
8966 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
8972 #ifdef CONFIG_IOCTL_CFG80211
8973 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8975 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
8977 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
8978 pframe += pmlmepriv->p2p_assoc_req_ie_len;
8979 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
8983 #endif //CONFIG_IOCTL_CFG80211
8985 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
8987 // Should add the P2P IE in the association request frame.
8991 p2pie[ p2pielen++ ] = 0x50;
8992 p2pie[ p2pielen++ ] = 0x6F;
8993 p2pie[ p2pielen++ ] = 0x9A;
8994 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
8996 // Commented by Albert 20101109
8997 // According to the P2P Specification, the association request frame should contain 3 P2P attributes
8998 // 1. P2P Capability
8999 // 2. Extended Listen Timing
9001 // Commented by Albert 20110516
9006 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
9009 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
9013 // Device Capability Bitmap, 1 byte
9014 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
9016 // Group Capability Bitmap, 1 byte
9017 if ( pwdinfo->persistent_supported )
9018 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9020 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
9022 // Extended Listen Timing
9024 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
9027 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
9031 // Availability Period
9032 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9035 // Availability Interval
9036 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9041 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
9044 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
9045 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
9046 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
9050 // P2P Device Address
9051 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9052 p2pielen += ETH_ALEN;
9055 // This field should be big endian. Noted by P2P specification.
9056 if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
9057 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
9059 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
9063 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
9068 // Primary Device Type
9070 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
9074 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
9078 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
9081 // Number of Secondary Device Types
9082 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
9086 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
9090 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
9094 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
9095 p2pielen += pwdinfo->device_name_len;
9099 p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
9102 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
9106 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address
9107 p2pielen += ETH_ALEN;
9109 p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count
9111 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List
9112 p2pielen += ETH_ALEN;
9114 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
9121 wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
9123 pattrib->pktlen += wfdielen;
9126 pattrib->last_txcmdsz = pattrib->pktlen;
9127 dump_mgntframe(padapter, pmgntframe);
9132 if (ret == _SUCCESS)
9133 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9135 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9140 //when wait_ack is ture, this function shoule be called at process context
9141 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9144 struct xmit_frame *pmgntframe;
9145 struct pkt_attrib *pattrib;
9146 unsigned char *pframe;
9147 struct rtw_ieee80211_hdr *pwlanhdr;
9148 unsigned short *fctrl;
9149 struct xmit_priv *pxmitpriv;
9150 struct mlme_ext_priv *pmlmeext;
9151 struct mlme_ext_info *pmlmeinfo;
9153 //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
9158 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9161 pxmitpriv = &(padapter->xmitpriv);
9162 pmlmeext = &(padapter->mlmeextpriv);
9163 pmlmeinfo = &(pmlmeext->mlmext_info);
9165 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9171 pattrib = &pmgntframe->attrib;
9172 update_mgntframe_attrib(padapter, pattrib);
9173 pattrib->retry_ctrl = _FALSE;
9175 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9177 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9178 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9180 fctrl = &(pwlanhdr->frame_ctl);
9183 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9187 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9197 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9198 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9199 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9201 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9202 pmlmeext->mgnt_seq++;
9203 SetFrameSubType(pframe, WIFI_DATA_NULL);
9205 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9206 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9208 pattrib->last_txcmdsz = pattrib->pktlen;
9212 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9216 dump_mgntframe(padapter, pmgntframe);
9225 * [IMPORTANT] Don't call this function in interrupt context
9227 * When wait_ms > 0, this function should be called at process context
9228 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9229 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9230 * try_cnt means the maximal TX count to try
9231 * da == NULL for station mode
9233 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9237 u32 start = rtw_get_current_time();
9238 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9239 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9240 struct sta_info *psta;
9242 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9245 /* da == NULL, assum it's null data for sta to ap*/
9247 da = get_my_bssid(&(pmlmeinfo->network));
9249 psta = rtw_get_stainfo(&padapter->stapriv, da);
9252 rtw_hal_macid_sleep(padapter, psta->mac_id);
9254 rtw_hal_macid_wakeup(padapter, psta->mac_id);
9256 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
9257 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
9262 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
9266 if (RTW_CANNOT_RUN(padapter))
9269 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9270 rtw_msleep_os(wait_ms);
9272 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9276 #ifndef DBG_XMIT_ACK
9281 if (try_cnt && wait_ms) {
9283 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9284 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9285 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9287 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9288 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9289 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9296 * [IMPORTANT] This function run in interrupt context
9298 * The null data packet would be sent without power bit,
9299 * and not guarantee success.
9301 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
9304 struct mlme_ext_priv *pmlmeext;
9305 struct mlme_ext_info *pmlmeinfo;
9308 pmlmeext = &padapter->mlmeextpriv;
9309 pmlmeinfo = &pmlmeext->mlmext_info;
9311 /* da == NULL, assum it's null data for sta to ap*/
9313 da = get_my_bssid(&(pmlmeinfo->network));
9315 ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
9320 //when wait_ack is ture, this function shoule be called at process context
9321 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
9324 struct xmit_frame *pmgntframe;
9325 struct pkt_attrib *pattrib;
9326 unsigned char *pframe;
9327 struct rtw_ieee80211_hdr *pwlanhdr;
9328 unsigned short *fctrl, *qc;
9329 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9330 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9331 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9333 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9336 DBG_871X("%s\n", __FUNCTION__);
9338 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9344 pattrib = &pmgntframe->attrib;
9345 update_mgntframe_attrib(padapter, pattrib);
9347 pattrib->hdrlen +=2;
9348 pattrib->qos_en = _TRUE;
9350 pattrib->ack_policy = 0;
9353 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9355 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9356 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9358 fctrl = &(pwlanhdr->frame_ctl);
9361 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9365 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9373 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9375 SetPriority(qc, tid);
9377 SetEOSP(qc, pattrib->eosp);
9379 SetAckpolicy(qc, pattrib->ack_policy);
9381 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9382 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9383 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9385 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9386 pmlmeext->mgnt_seq++;
9387 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
9389 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9390 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9392 pattrib->last_txcmdsz = pattrib->pktlen;
9396 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9400 dump_mgntframe(padapter, pmgntframe);
9409 * when wait_ms >0 , this function should be called at process context
9410 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9411 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9412 * try_cnt means the maximal TX count to try
9413 * da == NULL for station mode
9415 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
9419 u32 start = rtw_get_current_time();
9420 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9421 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9423 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9426 /* da == NULL, assum it's null data for sta to ap*/
9428 da = get_my_bssid(&(pmlmeinfo->network));
9432 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
9436 if (RTW_CANNOT_RUN(padapter))
9439 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9440 rtw_msleep_os(wait_ms);
9442 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9446 #ifndef DBG_XMIT_ACK
9451 if (try_cnt && wait_ms) {
9453 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9454 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9455 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9457 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9458 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9459 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9465 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9467 struct xmit_frame *pmgntframe;
9468 struct pkt_attrib *pattrib;
9469 unsigned char *pframe;
9470 struct rtw_ieee80211_hdr *pwlanhdr;
9471 unsigned short *fctrl;
9472 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9473 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9474 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9477 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
9480 //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9483 if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
9485 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
9486 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
9490 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9493 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9499 pattrib = &pmgntframe->attrib;
9500 update_mgntframe_attrib(padapter, pattrib);
9501 pattrib->retry_ctrl = _FALSE;
9502 pattrib->key_type = key_type;
9503 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9505 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9506 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9508 fctrl = &(pwlanhdr->frame_ctl);
9511 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9512 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9513 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9515 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9516 pmlmeext->mgnt_seq++;
9517 SetFrameSubType(pframe, WIFI_DEAUTH);
9519 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9520 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9522 reason = cpu_to_le16(reason);
9523 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9525 pattrib->last_txcmdsz = pattrib->pktlen;
9530 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9534 dump_mgntframe(padapter, pmgntframe);
9542 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9544 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9545 return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9548 #ifdef CONFIG_IEEE80211W
9549 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9551 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9552 return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9554 #endif /* CONFIG_IEEE80211W */
9557 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9558 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9559 * try_cnt means the maximal TX count to try
9561 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9566 u32 start = rtw_get_current_time();
9568 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9573 ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE:_FALSE, IEEE80211W_RIGHT_KEY);
9577 if (RTW_CANNOT_RUN(padapter))
9580 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9581 rtw_msleep_os(wait_ms);
9583 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9587 #ifndef DBG_XMIT_ACK
9592 if (try_cnt && wait_ms) {
9594 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9595 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9596 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9598 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9599 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9600 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9606 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9609 _list *plist, *phead;
9610 struct xmit_frame *pmgntframe;
9611 struct pkt_attrib *pattrib;
9612 unsigned char *pframe;
9613 struct rtw_ieee80211_hdr *pwlanhdr;
9614 unsigned short *fctrl;
9615 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9616 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9617 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9618 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9620 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9623 DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9624 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9626 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9630 pattrib = &pmgntframe->attrib;
9631 update_mgntframe_attrib(padapter, pattrib);
9633 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9635 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9636 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9638 fctrl = &(pwlanhdr->frame_ctl);
9641 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9642 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9643 _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9645 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9646 pmlmeext->mgnt_seq++;
9647 SetFrameSubType(pframe, WIFI_ACTION);
9649 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9650 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9652 /* category, action */
9654 u8 category, action;
9655 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9656 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9658 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9659 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9662 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9663 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9664 hal_ch_offset_to_secondary_ch_offset(ch_offset));
9666 pattrib->last_txcmdsz = pattrib->pktlen;
9668 dump_mgntframe(padapter, pmgntframe);
9672 #ifdef CONFIG_IEEE80211W
9673 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9675 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
9677 struct xmit_frame *pmgntframe;
9678 struct pkt_attrib *pattrib;
9680 struct rtw_ieee80211_hdr *pwlanhdr;
9682 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9683 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9684 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9685 struct sta_info *psta;
9686 struct sta_priv *pstapriv = &padapter->stapriv;
9687 struct registry_priv *pregpriv = &padapter->registrypriv;
9688 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9690 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9693 DBG_871X("%s, %04x\n", __FUNCTION__, tid);
9695 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9697 DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9702 pattrib = &pmgntframe->attrib;
9703 update_mgntframe_attrib(padapter, pattrib);
9704 pattrib->key_type = key_type;
9705 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9707 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9708 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9710 fctrl = &(pwlanhdr->frame_ctl);
9714 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9716 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9717 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9718 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9720 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9721 pmlmeext->mgnt_seq++;
9722 SetFrameSubType(pframe, WIFI_ACTION);
9724 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9725 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9727 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9728 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9732 case 0: //SA Query req
9733 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9734 pmlmeext->sa_query_seq++;
9735 /* send sa query request to AP, AP should reply sa query response in 1 second */
9736 if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9737 psta = rtw_get_stainfo(pstapriv, raddr);
9739 /* DBG_871X("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9740 _set_timer(&psta->dot11w_expire_timer, 1000);
9745 case 1: //SA Query rsp
9746 tid = cpu_to_le16(tid);
9747 /* DBG_871X("rtw_set_fixed_ie, %04x\n", tid); */
9748 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9754 pattrib->last_txcmdsz = pattrib->pktlen;
9756 dump_mgntframe(padapter, pmgntframe);
9758 #endif //CONFIG_IEEE80211W
9761 * issue_action_ba - internal function to TX Block Ack action frame
9762 * @padapter: the adapter to TX
9763 * @raddr: receiver address
9764 * @action: Block Ack Action
9766 * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9767 * @status: status/reason code. used by ADDBA_RESP, DELBA
9768 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9769 * @wait_ack: used xmit ack
9772 * _SUCCESS: No xmit ack is used or acked
9773 * _FAIL: not acked when using xmit ack
9775 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9776 , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9779 u8 category = RTW_WLAN_CATEGORY_BACK;
9782 u16 BA_timeout_value;
9783 u16 BA_starting_seqctrl;
9784 struct xmit_frame *pmgntframe;
9785 struct pkt_attrib *pattrib;
9787 struct rtw_ieee80211_hdr *pwlanhdr;
9789 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9790 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9791 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9792 struct sta_info *psta;
9793 struct sta_priv *pstapriv = &padapter->stapriv;
9794 struct registry_priv *pregpriv = &padapter->registrypriv;
9796 #ifdef CONFIG_80211N_HT
9798 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9801 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9805 pattrib = &pmgntframe->attrib;
9806 update_mgntframe_attrib(padapter, pattrib);
9808 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9810 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9811 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9813 fctrl = &(pwlanhdr->frame_ctl);
9816 //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9817 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9818 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9819 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9821 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9822 pmlmeext->mgnt_seq++;
9823 SetFrameSubType(pframe, WIFI_ACTION);
9825 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9826 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9828 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9829 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9835 case RTW_WLAN_ACTION_ADDBA_REQ:
9837 pmlmeinfo->dialogToken++;
9838 } while (pmlmeinfo->dialogToken == 0);
9839 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9841 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9842 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9844 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9847 BA_para_set = cpu_to_le16(BA_para_set);
9848 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9850 //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
9851 BA_timeout_value = 5000;//~ 5ms
9852 BA_timeout_value = cpu_to_le16(BA_timeout_value);
9853 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9855 //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
9856 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
9858 start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1;
9860 DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9862 psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9864 BA_starting_seqctrl = start_seq << 4;
9867 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9868 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9871 case RTW_WLAN_ACTION_ADDBA_RESP:
9872 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9873 status = cpu_to_le16(status);
9874 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9876 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9878 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9879 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9881 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9882 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9884 if (!padapter->registrypriv.wifi_spec) {
9885 if(pregpriv->ampdu_amsdu==0)//disabled
9886 BA_para_set &= ~BIT(0);
9887 else if(pregpriv->ampdu_amsdu==1)//enabled
9888 BA_para_set |= BIT(0);
9891 BA_para_set = cpu_to_le16(BA_para_set);
9893 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9894 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9897 case RTW_WLAN_ACTION_DELBA:
9899 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9900 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9902 BA_para_set = cpu_to_le16(BA_para_set);
9903 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9904 status = cpu_to_le16(status);
9905 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9912 pattrib->last_txcmdsz = pattrib->pktlen;
9915 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9917 dump_mgntframe(padapter, pmgntframe);
9922 #endif //CONFIG_80211N_HT
9927 * issue_addba_req - TX ADDBA_REQ
9928 * @adapter: the adapter to TX
9929 * @ra: receiver address
9932 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
9934 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
9941 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
9942 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
9947 * issue_addba_rsp - TX ADDBA_RESP
9948 * @adapter: the adapter to TX
9949 * @ra: receiver address
9951 * @status: status code
9952 * @size: the announced AMPDU buffer size
9954 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
9956 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9963 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
9964 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
9968 * issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
9969 * @adapter: the adapter to TX
9970 * @ra: receiver address
9972 * @status: status code
9973 * @size: the announced AMPDU buffer size
9974 * @try_cnt: the maximal TX count to try
9975 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9976 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9978 inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
9982 u32 start = rtw_get_current_time();
9984 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
9988 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9998 if (RTW_CANNOT_RUN(adapter))
10001 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10002 rtw_msleep_os(wait_ms);
10004 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10006 if (ret != _FAIL) {
10008 #ifndef DBG_XMIT_ACK
10013 if (try_cnt && wait_ms) {
10014 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u%s, %d/%d in %u ms\n"
10015 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid
10016 , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10024 * issue_del_ba - TX DELBA
10025 * @adapter: the adapter to TX
10026 * @ra: receiver address
10028 * @reason: reason code
10029 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10031 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10033 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10040 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10041 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10045 * issue_del_ba_ex - TX DELBA with xmit ack options
10046 * @adapter: the adapter to TX
10047 * @ra: receiver address
10049 * @reason: reason code
10050 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10051 * @try_cnt: the maximal TX count to try
10052 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10053 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10055 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10056 , int try_cnt, int wait_ms)
10060 u32 start = rtw_get_current_time();
10062 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
10066 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10071 , wait_ms > 0?_TRUE:_FALSE
10076 if (RTW_CANNOT_RUN(adapter))
10079 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10080 rtw_msleep_os(wait_ms);
10082 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10084 if (ret != _FAIL) {
10086 #ifndef DBG_XMIT_ACK
10091 if (try_cnt && wait_ms) {
10092 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
10093 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
10094 , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10100 static void issue_action_BSSCoexistPacket(_adapter *padapter)
10103 _list *plist, *phead;
10104 unsigned char category, action;
10105 struct xmit_frame *pmgntframe;
10106 struct pkt_attrib *pattrib;
10107 unsigned char *pframe;
10108 struct rtw_ieee80211_hdr *pwlanhdr;
10109 unsigned short *fctrl;
10110 struct wlan_network *pnetwork = NULL;
10111 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10112 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10113 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10114 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10115 _queue *queue = &(pmlmepriv->scanned_queue);
10116 u8 InfoContent[16] = {0};
10118 #ifdef CONFIG_80211N_HT
10119 if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
10122 if(_TRUE == pmlmeinfo->bwmode_updated)
10125 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10128 DBG_871X("%s\n", __FUNCTION__);
10131 category = RTW_WLAN_CATEGORY_PUBLIC;
10132 action = ACT_PUBLIC_BSSCOEXIST;
10134 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10140 pattrib = &pmgntframe->attrib;
10141 update_mgntframe_attrib(padapter, pattrib);
10143 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10145 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10146 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10148 fctrl = &(pwlanhdr->frame_ctl);
10151 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10152 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10153 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10155 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10156 pmlmeext->mgnt_seq++;
10157 SetFrameSubType(pframe, WIFI_ACTION);
10159 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10160 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10162 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10163 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10167 if(pmlmepriv->num_FortyMHzIntolerant>0)
10171 iedata |= BIT(2);//20 MHz BSS Width Request
10173 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
10179 _rtw_memset(ICS, 0, sizeof(ICS));
10180 if(pmlmepriv->num_sta_no_ht>0)
10184 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10186 phead = get_list_head(queue);
10187 plist = get_next(phead);
10193 WLAN_BSSID_EX *pbss_network;
10195 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
10198 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
10200 plist = get_next(plist);
10202 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10204 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10205 if((p==NULL) || (len==0))//non-HT
10207 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
10210 ICS[0][pbss_network->Configuration.DSConfig]=1;
10218 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10227 InfoContent[k] = i;
10228 //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
10237 InfoContent[k] = j; //channel number
10238 //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
10244 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10254 pattrib->last_txcmdsz = pattrib->pktlen;
10256 dump_mgntframe(padapter, pmgntframe);
10257 #endif //CONFIG_80211N_HT
10260 // Spatial Multiplexing Powersave (SMPS) action frame
10261 int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack)
10265 unsigned char category = RTW_WLAN_CATEGORY_HT;
10266 u8 action = RTW_WLAN_ACTION_HT_SM_PS;
10267 u8 sm_power_control=0;
10268 struct xmit_frame *pmgntframe;
10269 struct pkt_attrib *pattrib;
10270 unsigned char *pframe;
10271 struct rtw_ieee80211_hdr *pwlanhdr;
10272 unsigned short *fctrl;
10273 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10274 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10275 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10278 if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED)
10280 sm_power_control = sm_power_control & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable
10282 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC)
10284 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
10285 sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode
10287 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC)
10289 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
10290 sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode
10295 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10298 DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode );
10300 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10304 pattrib = &pmgntframe->attrib;
10305 update_mgntframe_attrib(padapter, pattrib);
10307 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10309 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10310 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10312 fctrl = &(pwlanhdr->frame_ctl);
10315 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10316 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10317 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10319 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10320 pmlmeext->mgnt_seq++;
10321 SetFrameSubType(pframe, WIFI_ACTION);
10323 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10324 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10326 /* category, action */
10327 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10328 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10330 pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10332 pattrib->last_txcmdsz = pattrib->pktlen;
10336 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10340 dump_mgntframe(padapter, pmgntframe);
10344 if (ret != _SUCCESS)
10345 DBG_8192C("%s, ack to\n", __func__);
10351 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10352 * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10353 * try_cnt means the maximal TX count to try
10355 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10359 u32 start = rtw_get_current_time();
10361 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10365 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE );
10369 if (RTW_CANNOT_RUN(padapter))
10372 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
10373 rtw_msleep_os(wait_ms);
10375 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
10377 if (ret != _FAIL) {
10379 #ifndef DBG_XMIT_ACK
10384 if (try_cnt && wait_ms) {
10386 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10387 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10388 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10390 DBG_871X(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10391 FUNC_ADPT_ARG(padapter),
10392 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10399 int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode )
10401 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10402 return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE );
10406 * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10407 * @adapter: the adapter to which @sta belongs
10408 * @initiator: if we are the initiator of AMPDU association
10409 * @sta: the sta to be checked
10410 * @tid: the tid to be checked
10411 * @force: cancel and send DELBA even when no AMPDU association is setup
10412 * @wait_ack: send delba with xmit ack (valid when initiator == 0)
10415 * _FAIL if sta is NULL
10416 * when initiator is 1, always _SUCCESS
10417 * when initiator is 0, _SUCCESS if DELBA is acked
10419 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10420 , u8 force, int wait_ack)
10422 int ret = _SUCCESS;
10429 if (initiator == 0) {
10431 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10432 u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10434 sta->recvreorder_ctrl[tid].enable = _FALSE;
10435 sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10437 if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10440 ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
10442 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10444 if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10445 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10447 } else if (initiator == 1) {
10449 #ifdef CONFIG_80211N_HT
10450 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10451 sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10452 sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10453 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10462 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10465 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10468 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10471 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10474 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10476 struct sta_priv *pstapriv = &padapter->stapriv;
10477 struct sta_info *psta = NULL;
10478 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10479 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10482 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
10483 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10486 psta = rtw_get_stainfo(pstapriv, addr);
10491 DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR");
10492 if (initiator == 1) /* originator */
10493 DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10496 for (tid = 0; tid < TID_NUM; tid++)
10497 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10502 unsigned int send_beacon(_adapter *padapter)
10504 u8 bxmitok = _FALSE;
10507 #if defined(CONFIG_PCI_HCI) && defined(RTL8814AE_SW_BCN)
10508 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10510 //#ifdef CONFIG_CONCURRENT_MODE
10511 //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10512 //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10513 //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
10514 //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
10517 #ifdef CONFIG_PCI_HCI
10518 //DBG_871X("%s\n", __FUNCTION__);
10520 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10522 /* 8192EE Port select for Beacon DL */
10523 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10525 issue_beacon(padapter, 0);
10527 #ifdef RTL8814AE_SW_BCN
10528 if (pHalData->bCorrectBCN != 0)
10529 DBG_871X("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
10530 pHalData->bCorrectBCN = 1;
10536 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10537 u32 start = rtw_get_current_time();
10539 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10540 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10542 issue_beacon(padapter, 100);
10546 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10548 } while ((poll%10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10550 } while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter));
10552 if (RTW_CANNOT_RUN(padapter))
10556 if(_FALSE == bxmitok)
10558 DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10563 u32 passing_time = rtw_get_passing_time_ms(start);
10565 if(passing_time > 100 || issue > 3)
10566 DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10568 // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10570 rtw_hal_fw_correct_bcn(padapter);
10579 /****************************************************************************
10581 Following are some utitity fuctions for WiFi MLME
10583 *****************************************************************************/
10585 BOOLEAN IsLegal5GChannel(
10586 IN PADAPTER Adapter,
10591 u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
10592 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
10593 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
10595 for(i=0;i<sizeof(Channel_5G);i++)
10596 if(channel == Channel_5G[i])
10601 //collect bss info from Beacon and Probe request/response frames.
10602 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10607 u16 val16, subtype;
10608 u8 *pframe = precv_frame->u.hdr.rx_data;
10609 u32 packet_len = precv_frame->u.hdr.len;
10611 struct registry_priv *pregistrypriv = &padapter->registrypriv;
10612 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10613 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10615 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10617 if (len > MAX_IE_SZ)
10619 //DBG_871X("IE too long for survey event\n");
10623 _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10625 subtype = GetFrameSubType(pframe);
10627 if(subtype==WIFI_BEACON) {
10628 bssid->Reserved[0] = 1;
10629 ie_offset = _BEACON_IE_OFFSET_;
10631 // FIXME : more type
10632 if (subtype == WIFI_PROBERSP) {
10633 ie_offset = _PROBERSP_IE_OFFSET_;
10634 bssid->Reserved[0] = 3;
10636 else if (subtype == WIFI_PROBEREQ) {
10637 ie_offset = _PROBEREQ_IE_OFFSET_;
10638 bssid->Reserved[0] = 2;
10641 bssid->Reserved[0] = 0;
10642 ie_offset = _FIXED_IE_LENGTH_;
10646 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10648 //below is to copy the information element
10649 bssid->IELength = len;
10650 _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10652 //get the signal strength
10653 //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
10654 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
10655 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
10656 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
10657 #ifdef CONFIG_ANTENNA_DIVERSITY
10658 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
10662 if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
10664 DBG_871X("marc: cannot find SSID for survey event\n");
10670 if (len > NDIS_802_11_LENGTH_SSID)
10672 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10675 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10676 bssid->Ssid.SsidLength = *(p + 1);
10680 bssid->Ssid.SsidLength = 0;
10683 _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10685 //checking rate info...
10687 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10690 if (len > NDIS_802_11_LENGTH_RATES_EX)
10692 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10695 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10699 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10702 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
10704 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10707 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10712 if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10714 bssid->NetworkTypeInUse = Ndis802_11DS;
10719 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10723 if (subtype == WIFI_PROBEREQ)
10727 // Set Listion Channel
10728 if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen)))
10730 u32 attr_contentlen = 0;
10731 u8 listen_ch[5] = { 0x00 };
10733 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10734 bssid->Configuration.DSConfig = listen_ch[4];
10736 { // use current channel
10737 bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10738 DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10742 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10743 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10744 bssid->Privacy = 1;
10747 #endif //CONFIG_P2P
10749 if (bssid->IELength < 12)
10752 // Checking for DSConfig
10753 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10755 bssid->Configuration.DSConfig = 0;
10756 bssid->Configuration.Length = 0;
10760 bssid->Configuration.DSConfig = *(p + 2);
10763 {// In 5G, some ap do not have DSSET IE
10764 // checking HT info for channel
10765 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10768 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10769 bssid->Configuration.DSConfig = HT_info->primary_channel;
10772 { // use current channel
10773 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
10777 _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
10778 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
10780 val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
10782 if (val16 & BIT(0))
10784 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10785 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10789 bssid->InfrastructureMode = Ndis802_11IBSS;
10790 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10793 if (val16 & BIT(4))
10794 bssid->Privacy = 1;
10796 bssid->Privacy = 0;
10798 bssid->Configuration.ATIMWindow = 0;
10800 //20/40 BSS Coexistence check
10801 if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
10803 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10804 #ifdef CONFIG_80211N_HT
10805 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10808 struct HT_caps_element *pHT_caps;
10809 pHT_caps = (struct HT_caps_element *)(p + 2);
10811 if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
10813 pmlmepriv->num_FortyMHzIntolerant++;
10818 pmlmepriv->num_sta_no_ht++;
10820 #endif //CONFIG_80211N_HT
10824 #ifdef CONFIG_INTEL_WIDI
10825 //process_intel_widi_query_or_tigger(padapter, bssid);
10826 if(process_intel_widi_query_or_tigger(padapter, bssid))
10830 #endif // CONFIG_INTEL_WIDI
10832 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10833 if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10834 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10835 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10836 , rtw_get_oper_ch(padapter)
10837 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10842 // mark bss info receving from nearby channel as SignalQuality 101
10843 if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10845 bssid->PhyInfo.SignalQuality= 101;
10851 void start_create_ibss(_adapter* padapter)
10853 unsigned short caps;
10856 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10857 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10858 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10860 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10861 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10863 //update wireless mode
10864 update_wireless_mode(padapter);
10866 //udpate capability
10867 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10868 update_capinfo(padapter, caps);
10869 if(caps&cap_IBSS)//adhoc master
10871 //set_opmode_cmd(padapter, adhoc);//removed
10874 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10877 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10880 //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
10881 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10884 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10886 beacon_timing_control(padapter);
10888 //set msr to WIFI_FW_ADHOC_STATE
10889 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10890 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10893 if(send_beacon(padapter)==_FAIL)
10895 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
10897 report_join_res(padapter, -1);
10898 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10902 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10904 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10906 report_join_res(padapter, 1);
10907 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10908 rtw_indicate_connect(padapter);
10913 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
10916 //update bc/mc sta_info
10917 update_bmc_sta(padapter);
10921 void start_clnt_join(_adapter* padapter)
10923 unsigned short caps;
10925 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10926 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10927 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10928 int beacon_timeout;
10929 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
10931 //update wireless mode
10932 update_wireless_mode(padapter);
10934 //udpate capability
10935 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10936 update_capinfo(padapter, caps);
10938 //check if sta is ASIX peer and fix IOT issue if it is.
10939 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
10940 u8 iot_flag = _TRUE;
10941 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10946 Set_MSR(padapter, WIFI_FW_STATION_STATE);
10948 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
10950 #ifdef CONFIG_WAPI_SUPPORT
10951 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
10953 //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
10957 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10959 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10960 // Because of AP's not receiving deauth before
10961 // AP may: 1)not response auth or 2)deauth us after link is complete
10962 // issue deauth before issuing auth to deal with the situation
10964 // Commented by Albert 2012/07/21
10965 // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
10968 _queue *queue = &(padapter->mlmepriv.scanned_queue);
10969 _list *head = get_list_head(queue);
10970 _list *pos = get_next(head);
10971 struct wlan_network *scanned = NULL;
10974 bool has_p2p_ie = _FALSE;
10976 _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10978 for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
10980 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
10982 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
10983 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
10985 ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
10986 if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
10987 has_p2p_ie = _TRUE;
10992 _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10994 if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
10995 #endif /* CONFIG_P2P */
10996 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
10997 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
10999 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11001 //here wait for receiving the beacon to start auth
11002 //and enable a timer
11003 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11004 set_link_timer(pmlmeext, beacon_timeout);
11005 _set_timer( &padapter->mlmepriv.assoc_timer,
11006 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
11008 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11010 else if (caps&cap_IBSS) //adhoc client
11012 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11015 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11017 beacon_timing_control(padapter);
11019 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11021 report_join_res(padapter, 1);
11025 //DBG_871X("marc: invalid cap:%x\n", caps);
11031 void start_clnt_auth(_adapter* padapter)
11033 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11034 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11036 _cancel_timer_ex(&pmlmeext->link_timer);
11038 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
11039 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
11041 pmlmeinfo->auth_seq = 1;
11042 pmlmeinfo->reauth_count = 0;
11043 pmlmeinfo->reassoc_count = 0;
11044 pmlmeinfo->link_count = 0;
11045 pmlmeext->retry = 0;
11048 DBG_871X_LEVEL(_drv_always_, "start auth\n");
11049 issue_auth(padapter, NULL, 0);
11051 set_link_timer(pmlmeext, REAUTH_TO);
11056 void start_clnt_assoc(_adapter* padapter)
11058 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11059 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11061 _cancel_timer_ex(&pmlmeext->link_timer);
11063 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
11064 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
11066 issue_assocreq(padapter);
11068 set_link_timer(pmlmeext, REASSOC_TO);
11071 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, u8 locally_generated)
11073 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11074 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11076 if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
11079 DBG_871X("%s\n", __FUNCTION__);
11081 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11083 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11085 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11086 report_del_sta_event(padapter, MacAddr, reason, _TRUE, locally_generated);
11089 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
11091 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11092 report_join_res(padapter, -2);
11094 DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
11100 #ifdef CONFIG_80211D
11101 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
11103 struct registry_priv *pregistrypriv;
11104 struct mlme_ext_priv *pmlmeext;
11105 RT_CHANNEL_INFO *chplan_new;
11110 pregistrypriv = &padapter->registrypriv;
11111 pmlmeext = &padapter->mlmeextpriv;
11113 // Adjust channel plan by AP Country IE
11114 if (pregistrypriv->enable80211d &&
11115 (!pmlmeext->update_channel_plan_by_ap_done))
11119 RT_CHANNEL_PLAN chplan_ap;
11120 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
11122 u8 fcn; // first channel number
11123 u8 noc; // number of channel
11126 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11128 if (len < 6) return;
11134 _rtw_memset(country, 0, 4);
11135 _rtw_memcpy(country, p, 3);
11137 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11138 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
11141 while ((ie - p) >= 3)
11147 for (j = 0; j < noc; j++)
11149 if (fcn <= 14) channel = fcn + j; // 2.4 GHz
11150 else channel = fcn + j*4; // 5 GHz
11152 chplan_ap.Channel[i++] = channel;
11157 #ifdef CONFIG_DEBUG_RTL871X
11159 DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11160 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
11162 DBG_8192C("%02d,", chplan_ap.Channel[i]);
11168 _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
11169 #ifdef CONFIG_DEBUG_RTL871X
11171 DBG_871X("%s: STA channel plan {", __FUNCTION__);
11172 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11174 DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
11180 _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
11181 chplan_new = pmlmeext->channel_set;
11184 if (pregistrypriv->wireless_mode & WIRELESS_11G)
11187 if ((i == MAX_CHANNEL_NUM) ||
11188 (chplan_sta[i].ChannelNum == 0) ||
11189 (chplan_sta[i].ChannelNum > 14))
11192 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11195 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11197 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11198 chplan_new[k].ScanType = SCAN_ACTIVE;
11203 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11205 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11206 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11207 chplan_new[k].ScanType = SCAN_PASSIVE;
11211 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11213 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11214 chplan_new[k].ScanType = SCAN_ACTIVE;
11220 // change AP not support channel to Passive scan
11221 while ((i < MAX_CHANNEL_NUM) &&
11222 (chplan_sta[i].ChannelNum != 0) &&
11223 (chplan_sta[i].ChannelNum <= 14))
11225 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11226 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11227 chplan_new[k].ScanType = SCAN_PASSIVE;
11232 // add channel AP supported
11233 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11235 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11236 chplan_new[k].ScanType = SCAN_ACTIVE;
11243 // keep original STA 2.4G channel plan
11244 while ((i < MAX_CHANNEL_NUM) &&
11245 (chplan_sta[i].ChannelNum != 0) &&
11246 (chplan_sta[i].ChannelNum <= 14))
11248 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11249 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11254 // skip AP 2.4G channel plan
11255 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11261 if (pregistrypriv->wireless_mode & WIRELESS_11A)
11264 if ((i >= MAX_CHANNEL_NUM) ||
11265 (chplan_sta[i].ChannelNum == 0))
11268 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11271 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11273 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11274 chplan_new[k].ScanType = SCAN_ACTIVE;
11279 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11281 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11282 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11283 chplan_new[k].ScanType = SCAN_PASSIVE;
11287 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11289 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11290 chplan_new[k].ScanType = SCAN_ACTIVE;
11296 // change AP not support channel to Passive scan
11297 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11299 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11300 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11301 chplan_new[k].ScanType = SCAN_PASSIVE;
11306 // add channel AP supported
11307 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
11309 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11310 chplan_new[k].ScanType = SCAN_ACTIVE;
11317 // keep original STA 5G channel plan
11318 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11320 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11321 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11327 pmlmeext->update_channel_plan_by_ap_done = 1;
11329 #ifdef CONFIG_DEBUG_RTL871X
11331 DBG_871X("%s: new STA channel plan {", __FUNCTION__);
11332 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11334 DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
11341 // recover the right channel index
11342 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11344 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11346 if (chplan_new[k].ChannelNum == channel) {
11347 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11348 ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11349 __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
11350 pmlmeext->sitesurvey_res.channel_idx = k;
11358 // If channel is used by AP, set channel scan type to active
11359 channel = bssid->Configuration.DSConfig;
11360 chplan_new = pmlmeext->channel_set;
11362 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
11364 if (chplan_new[i].ChannelNum == channel)
11366 if (chplan_new[i].ScanType == SCAN_PASSIVE)
11368 //5G Bnad 2, 3 (DFS) doesn't change to active scan
11369 if(channel >= 52 && channel <= 144)
11372 chplan_new[i].ScanType = SCAN_ACTIVE;
11373 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11374 ("%s: change channel %d scan type from passive to active\n",
11375 __FUNCTION__, channel));
11384 /****************************************************************************
11386 Following are the functions to report events
11388 *****************************************************************************/
11390 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11392 struct cmd_obj *pcmd_obj;
11395 struct survey_event *psurvey_evt;
11396 struct C2HEvent_Header *pc2h_evt_hdr;
11397 struct mlme_ext_priv *pmlmeext;
11398 struct cmd_priv *pcmdpriv;
11399 //u8 *pframe = precv_frame->u.hdr.rx_data;
11400 //uint len = precv_frame->u.hdr.len;
11405 pmlmeext = &padapter->mlmeextpriv;
11406 pcmdpriv = &padapter->cmdpriv;
11409 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11414 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11415 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11417 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11421 _rtw_init_listhead(&pcmd_obj->list);
11423 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11424 pcmd_obj->cmdsz = cmdsz;
11425 pcmd_obj->parmbuf = pevtcmd;
11427 pcmd_obj->rsp = NULL;
11428 pcmd_obj->rspsz = 0;
11430 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11431 pc2h_evt_hdr->len = sizeof(struct survey_event);
11432 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11433 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11435 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11437 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
11439 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11440 rtw_mfree((u8 *)pevtcmd, cmdsz);
11444 #ifdef CONFIG_80211D
11445 process_80211d(padapter, &psurvey_evt->bss);
11448 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11450 pmlmeext->sitesurvey_res.bss_cnt++;
11456 void report_surveydone_event(_adapter *padapter)
11458 struct cmd_obj *pcmd_obj;
11461 struct surveydone_event *psurveydone_evt;
11462 struct C2HEvent_Header *pc2h_evt_hdr;
11463 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11464 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11466 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11471 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11472 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11474 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11478 _rtw_init_listhead(&pcmd_obj->list);
11480 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11481 pcmd_obj->cmdsz = cmdsz;
11482 pcmd_obj->parmbuf = pevtcmd;
11484 pcmd_obj->rsp = NULL;
11485 pcmd_obj->rspsz = 0;
11487 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11488 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11489 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11490 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11492 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11493 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11495 DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11497 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11503 void report_join_res(_adapter *padapter, int res)
11505 struct cmd_obj *pcmd_obj;
11508 struct joinbss_event *pjoinbss_evt;
11509 struct C2HEvent_Header *pc2h_evt_hdr;
11510 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11511 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11512 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11514 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11519 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11520 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11522 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11526 _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;
11532 pcmd_obj->rsp = NULL;
11533 pcmd_obj->rspsz = 0;
11535 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11536 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11537 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11538 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11540 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11541 _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11542 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
11544 DBG_871X("report_join_res(%d)\n", res);
11547 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11550 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11556 void report_wmm_edca_update(_adapter *padapter)
11558 struct cmd_obj *pcmd_obj;
11561 struct wmm_event *pwmm_event;
11562 struct C2HEvent_Header *pc2h_evt_hdr;
11563 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11564 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11565 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11567 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11572 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11573 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11575 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11579 _rtw_init_listhead(&pcmd_obj->list);
11581 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11582 pcmd_obj->cmdsz = cmdsz;
11583 pcmd_obj->parmbuf = pevtcmd;
11585 pcmd_obj->rsp = NULL;
11586 pcmd_obj->rspsz = 0;
11588 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11589 pc2h_evt_hdr->len = sizeof(struct wmm_event);
11590 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11591 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11593 pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11594 pwmm_event->wmm =0;
11596 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11602 void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue, u8 locally_generated)
11604 struct cmd_obj *pcmd_obj;
11607 struct sta_info *psta;
11609 struct stadel_event *pdel_sta_evt;
11610 struct C2HEvent_Header *pc2h_evt_hdr;
11611 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11612 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11615 /* prepare cmd parameter */
11616 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11617 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11618 if (pevtcmd == NULL) {
11623 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11624 pc2h_evt_hdr->len = sizeof(struct stadel_event);
11625 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11626 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11628 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11629 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11630 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
11631 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11633 mac_id = (int)psta->mac_id;
11636 pdel_sta_evt->mac_id = mac_id;
11637 pdel_sta_evt->locally_generated = locally_generated;
11641 rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11642 rtw_mfree(pevtcmd, cmdsz);
11644 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11645 if (pcmd_obj == NULL) {
11646 rtw_mfree(pevtcmd, cmdsz);
11651 _rtw_init_listhead(&pcmd_obj->list);
11652 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11653 pcmd_obj->cmdsz = cmdsz;
11654 pcmd_obj->parmbuf = pevtcmd;
11656 pcmd_obj->rsp = NULL;
11657 pcmd_obj->rspsz = 0;
11659 res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11664 DBG_871X(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11665 , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11670 void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
11672 struct cmd_obj *pcmd_obj;
11675 struct stassoc_event *padd_sta_evt;
11676 struct C2HEvent_Header *pc2h_evt_hdr;
11677 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11678 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11680 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11685 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11686 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11688 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11692 _rtw_init_listhead(&pcmd_obj->list);
11694 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11695 pcmd_obj->cmdsz = cmdsz;
11696 pcmd_obj->parmbuf = pevtcmd;
11698 pcmd_obj->rsp = NULL;
11699 pcmd_obj->rspsz = 0;
11701 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11702 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11703 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11704 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11706 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11707 _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11709 DBG_871X("report_add_sta_event: add STA\n");
11711 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11717 bool rtw_port_switch_chk(_adapter *adapter)
11719 bool switch_needed = _FALSE;
11720 #ifdef CONFIG_CONCURRENT_MODE
11721 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11722 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11723 struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11724 _adapter *if_port0 = NULL;
11725 _adapter *if_port1 = NULL;
11726 struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11727 struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11730 for (i = 0; i < dvobj->iface_nums; i++) {
11731 if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) {
11732 if_port0 = dvobj->padapters[i];
11733 if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11735 else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) {
11736 if_port1 = dvobj->padapters[i];
11737 if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11741 if (if_port0 == NULL) {
11746 if (if_port1 == NULL) {
11751 #ifdef DBG_RUNTIME_PORT_SWITCH
11752 DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11753 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11754 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11755 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11756 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11757 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11758 #endif /* DBG_RUNTIME_PORT_SWITCH */
11760 #ifdef CONFIG_WOWLAN
11761 /* WOWLAN interface(primary, for now) should be port0 */
11762 if (pwrctl->wowlan_mode == _TRUE) {
11763 if(!is_primary_adapter(if_port0)) {
11764 DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11765 switch_needed = _TRUE;
11769 #endif /* CONFIG_WOWLAN */
11771 /* AP should use port0 for ctl frame's ack */
11772 if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11773 DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11774 switch_needed = _TRUE;
11778 /* GC should use port0 for p2p ps */
11779 if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11780 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11781 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11782 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11784 DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11785 switch_needed = _TRUE;
11789 /* port1 linked, but port0 not linked */
11790 if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11791 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11792 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11794 DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11795 switch_needed = _TRUE;
11800 #ifdef DBG_RUNTIME_PORT_SWITCH
11801 DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11802 #endif /* DBG_RUNTIME_PORT_SWITCH */
11803 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11804 #endif /* CONFIG_CONCURRENT_MODE */
11805 return switch_needed;
11808 /****************************************************************************
11810 Following are the event callback functions
11812 *****************************************************************************/
11814 //for sta/adhoc mode
11815 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11818 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11819 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11820 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11823 VCS_update(padapter, psta);
11825 #ifdef CONFIG_80211N_HT
11827 if(pmlmepriv->htpriv.ht_option)
11829 psta->htpriv.ht_option = _TRUE;
11831 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11833 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
11835 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11836 psta->htpriv.sgi_20m = _TRUE;
11838 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11839 psta->htpriv.sgi_40m = _TRUE;
11841 psta->qos_option = _TRUE;
11843 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11844 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11845 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11847 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11850 #endif //CONFIG_80211N_HT
11852 #ifdef CONFIG_80211N_HT
11853 psta->htpriv.ht_option = _FALSE;
11855 psta->htpriv.ampdu_enable = _FALSE;
11857 psta->htpriv.sgi_20m = _FALSE;
11858 psta->htpriv.sgi_40m = _FALSE;
11859 #endif //CONFIG_80211N_HT
11860 psta->qos_option = _FALSE;
11864 #ifdef CONFIG_80211N_HT
11865 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11867 psta->htpriv.agg_enable_bitmap = 0x0;//reset
11868 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
11869 #endif //CONFIG_80211N_HT
11871 psta->bw_mode = pmlmeext->cur_bwmode;
11874 if(pmlmepriv->qospriv.qos_option)
11875 psta->qos_option = _TRUE;
11877 #ifdef CONFIG_80211AC_VHT
11878 _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11879 #endif //CONFIG_80211AC_VHT
11881 update_ldpc_stbc_cap(psta);
11883 _enter_critical_bh(&psta->lock, &irqL);
11884 psta->state = _FW_LINKED;
11885 _exit_critical_bh(&psta->lock, &irqL);
11889 static void rtw_mlmeext_disconnect(_adapter *padapter)
11891 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11892 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11893 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11894 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11895 u8 state_backup = (pmlmeinfo->state&0x03);
11896 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
11898 //set_opmode_cmd(padapter, infra_client_with_mlme);
11900 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11901 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11903 //set MSR to no link state -> infra. mode
11904 Set_MSR(padapter, _HW_STATE_STATION_);
11906 //check if sta is ASIX peer and fix IOT issue if it is.
11907 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
11908 u8 iot_flag = _FALSE;
11909 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11911 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11913 if(state_backup == WIFI_FW_STATION_STATE)
11915 if (rtw_port_switch_chk(padapter) == _TRUE) {
11916 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11919 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11921 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11927 /* switch to the 20M Hz mode after disconnect */
11928 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11929 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11931 #ifdef CONFIG_FCS_MODE
11932 if (EN_FCS(padapter))
11933 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11936 #ifdef CONFIG_DFS_MASTER
11937 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
11938 rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);
11939 else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
11940 rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED);
11946 if (rtw_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
11947 set_channel_bwmode(padapter, ch, offset, bw);
11950 flush_all_cam_entry(padapter);
11952 _cancel_timer_ex(&pmlmeext->link_timer);
11954 //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE;
11955 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11956 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11959 padapter->tdlsinfo.ap_prohibited = _FALSE;
11961 /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11962 if (padapter->registrypriv.wifi_spec == 1)
11964 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
11966 #endif /* CONFIG_TDLS */
11970 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
11972 struct sta_info *psta, *psta_bmc;
11973 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11974 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11975 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
11976 struct sta_priv *pstapriv = &padapter->stapriv;
11978 #ifdef CONFIG_ARP_KEEP_ALIVE
11979 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11981 struct security_priv *psecuritypriv = &padapter->securitypriv;
11986 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11987 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11989 goto exit_mlmeext_joinbss_event_callback;
11991 #ifdef CONFIG_ARP_KEEP_ALIVE
11992 pmlmepriv->bGetGateway = 1;
11995 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
11997 //update bc/mc sta_info
11998 update_bmc_sta(padapter);
12002 //turn on dynamic functions
12003 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12005 // update IOT-releated issue
12006 update_IOT_info(padapter);
12008 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12011 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12013 //udpate capability
12014 update_capinfo(padapter, pmlmeinfo->capability);
12016 //WMM, Update EDCA param
12017 WMMOnAssocRsp(padapter);
12020 HTOnAssocRsp(padapter);
12022 #ifdef CONFIG_80211AC_VHT
12024 VHTOnAssocRsp(padapter);
12027 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12028 if (psta) //only for infra. mode
12030 //DBG_871X("set_sta_rate\n");
12032 psta->wireless_mode = pmlmeext->cur_wireless_mode;
12034 //set per sta rate after updating HT cap.
12035 set_sta_rate(padapter, psta);
12037 rtw_sta_media_status_rpt(padapter, psta, 1);
12039 /* wakeup macid after join bss successfully to ensure
12040 the subsequent data frames can be sent out normally */
12041 rtw_hal_macid_wakeup(padapter, psta->mac_id);
12044 #ifndef CONFIG_IOCTL_CFG80211
12045 if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12046 rtw_sec_restore_wep_key(padapter);
12047 #endif /* CONFIG_IOCTL_CFG80211 */
12049 if (rtw_port_switch_chk(padapter) == _TRUE)
12050 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12053 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12055 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12058 correct_TSF(padapter, pmlmeext);
12060 //set_link_timer(pmlmeext, DISCONNECT_TO);
12064 if(get_iface_type(padapter) == IFACE_PORT0)
12065 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
12068 #ifdef CONFIG_BEAMFORMING
12070 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12071 #endif/*CONFIG_BEAMFORMING*/
12073 exit_mlmeext_joinbss_event_callback:
12075 rtw_join_done_chk_ch(padapter, join_res);
12077 DBG_871X("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12080 //currently only adhoc mode will go here
12081 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12083 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12084 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12087 DBG_871X("%s\n", __FUNCTION__);
12089 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
12091 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
12098 //update_TSF(pmlmeext, pframe, len);
12101 correct_TSF(padapter, pmlmeext);
12104 if (send_beacon(padapter) == _FAIL)
12107 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12111 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12114 //update adhoc sta_info
12115 update_sta_info(padapter, psta);
12117 rtw_hal_update_sta_rate_mask(padapter, psta);
12119 // ToDo: HT for Ad-hoc
12120 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12121 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
12124 Update_RA_Entry(padapter, psta);
12127 void mlmeext_sta_del_event_callback(_adapter *padapter)
12129 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12130 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12132 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12134 rtw_mlmeext_disconnect(padapter);
12139 /****************************************************************************
12141 Following are the functions for the timer handlers
12143 *****************************************************************************/
12144 void _linked_info_dump(_adapter *padapter)
12147 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12148 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12149 HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
12150 int UndecoratedSmoothedPWDB = 0;
12152 if(padapter->bLinkInfoDump){
12154 DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter));
12156 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12158 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
12160 DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
12161 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB);
12163 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
12166 _list *phead, *plist;
12168 struct sta_info *psta=NULL;
12169 struct sta_priv *pstapriv = &padapter->stapriv;
12171 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12172 phead = &pstapriv->asoc_list;
12173 plist = get_next(phead);
12174 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12176 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
12177 plist = get_next(plist);
12179 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n",
12180 MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB);
12182 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12186 /*============ tx info ============ */
12187 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
12189 rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
12195 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12198 int ret = _SUCCESS;
12199 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12200 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12203 IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12204 AP is originator.AP does not transmit unicast packets when STA response its BAR.
12205 This case probably occur ap issue BAR after AP builds BA.
12207 Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12208 The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12210 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12211 for (i = 0; i < TID_NUM ; i++) {
12212 if (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) {
12213 if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12214 if (psta->recvreorder_ctrl[i].enable) {
12215 /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
12217 ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1);
12219 issue_del_ba(padapter, psta->hwaddr, i, 39, 0);
12220 psta->recvreorder_ctrl[i].enable = _FALSE;
12222 psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12223 rtw_reset_continual_no_rx_packet(psta, i);
12228 /* The inactivity timer is reset when MPDUs to the TID is received. */
12229 rtw_reset_continual_no_rx_packet(psta, i);
12235 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12239 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12240 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12242 #ifdef DBG_EXPIRATION_CHK
12243 DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12244 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12246 , FUNC_ADPT_ARG(padapter)
12247 , STA_RX_PKTS_DIFF_ARG(psta)
12248 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12249 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12250 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12251 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12252 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12253 , pmlmeinfo->bcn_interval*/
12257 DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12258 , padapter->xmitpriv.tx_pkts
12259 , pmlmeinfo->link_count
12263 if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12264 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12265 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12275 sta_update_last_rx_pkts(psta);
12278 record last rx data packets for every tid.
12280 for (i = 0; i < TID_NUM; i++)
12281 psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i];
12286 u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
12290 #ifdef DBG_EXPIRATION_CHK
12291 DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12292 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12294 , MAC_ARG(psta->hwaddr)
12295 , psta->rssi_stat.UndecoratedSmoothedPWDB
12296 , STA_RX_PKTS_DIFF_ARG(psta)
12297 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12298 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12299 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12300 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12301 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12302 , pmlmeinfo->bcn_interval*/
12307 if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
12308 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12309 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
12312 sta_update_last_rx_pkts(psta);
12318 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12320 if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12321 && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12327 void linked_status_chk_tdls(_adapter *padapter)
12329 struct candidate_pool {
12330 struct sta_info *psta;
12333 struct sta_priv *pstapriv = &padapter->stapriv;
12336 struct sta_info *psta;
12337 int i, num_teardown=0, num_checkalive=0;
12338 _list *plist, *phead;
12339 struct tdls_txmgmt txmgmt;
12340 struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
12341 struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
12342 u8 tdls_sta_max = _FALSE;
12344 #define ALIVE_MIN 2
12345 #define ALIVE_MAX 5
12347 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12348 _rtw_memset(checkalive, 0x00, sizeof(checkalive));
12349 _rtw_memset(teardown, 0x00, sizeof(teardown));
12351 if((padapter->tdlsinfo.link_established == _TRUE)){
12352 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12353 for(i=0; i< NUM_STA; i++)
12355 phead = &(pstapriv->sta_hash[i]);
12356 plist = get_next(phead);
12358 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12360 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12361 plist = get_next(plist);
12363 if(psta->tdls_sta_state & TDLS_LINKED_STATE)
12365 psta->alive_count++;
12366 if(psta->alive_count >= ALIVE_MIN)
12368 if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12369 if (psta->alive_count < ALIVE_MAX) {
12370 _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12371 checkalive[num_checkalive].psta = psta;
12376 _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12377 teardown[num_teardown].psta = psta;
12383 psta->alive_count = 0;
12386 psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12387 psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12389 if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
12390 tdls_sta_max = _TRUE;
12396 if (tdls_sta_max == _TRUE)
12399 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12401 if (num_checkalive > 0) {
12402 for (i = 0; i < num_checkalive; i++) {
12403 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12404 issue_tdls_dis_req(padapter, &txmgmt);
12405 issue_tdls_dis_req(padapter, &txmgmt);
12406 issue_tdls_dis_req(padapter, &txmgmt);
12410 if(num_teardown > 0)
12412 for(i=0; i< num_teardown; i++)
12414 DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12415 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12416 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12417 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12423 #endif //CONFIG_TDLS
12425 //from_timer == 1 means driver is in LPS
12426 void linked_status_chk(_adapter *padapter, u8 from_timer)
12429 struct sta_info *psta;
12430 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12431 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12432 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12433 struct sta_priv *pstapriv = &padapter->stapriv;
12434 #ifdef CONFIG_ARP_KEEP_ALIVE
12435 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12439 if (is_client_associated_to_ap(padapter))
12441 //linked infrastructure client mode
12443 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12445 int link_count_limit;
12447 #if defined(DBG_ROAMING_TEST)
12449 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12454 #ifdef CONFIG_ARP_KEEP_ALIVE
12455 if (!from_timer && pmlmepriv->bGetGateway == 1) {
12456 DBG_871X("do rtw_gw_addr_query()");
12457 if (rtw_gw_addr_query(padapter) == 0) {
12458 pmlmepriv->bGetGateway = 0;
12460 _rtw_memset(pmlmepriv->gw_ip, 0, 4);
12461 _rtw_memset(pmlmepriv->gw_mac_addr, 0, 6);
12466 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12469 link_count_limit = 3; // 8 sec
12471 link_count_limit = 15; // 32 sec
12474 #endif // CONFIG_P2P
12477 link_count_limit = 7; // 16 sec
12479 link_count_limit = 29; // 60 sec
12483 #ifdef CONFIG_TDLS_CH_SW
12484 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12486 #endif /* CONFIG_TDLS_CH_SW */
12488 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12489 linked_status_chk_tdls(padapter);
12490 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12491 #endif /* CONFIG_TDLS */
12493 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12495 bool is_p2p_enable = _FALSE;
12497 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12500 /*issue delba when ap does not tx data packet that is Broadcom ap */
12501 rtw_delba_check(padapter, psta, from_timer);
12503 if (chk_ap_is_alive(padapter, psta) == _FALSE)
12506 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12509 #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12510 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
12511 u8 backup_oper_channel=0;
12513 /* switch to correct channel of current network before issue keep-alive frames */
12514 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12515 backup_oper_channel = rtw_get_oper_ch(padapter);
12516 SelectChannel(padapter, pmlmeext->cur_channel);
12519 if (rx_chk != _SUCCESS)
12520 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12522 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12523 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12524 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12525 if (tx_chk == _SUCCESS && !is_p2p_enable)
12529 /* back to the original operation channel */
12530 if(backup_oper_channel>0)
12531 SelectChannel(padapter, backup_oper_channel);
12535 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12537 if (rx_chk != _SUCCESS) {
12538 if (pmlmeext->retry == 0) {
12539 #ifdef DBG_EXPIRATION_CHK
12540 DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12542 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12543 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12544 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12548 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
12549 #ifdef DBG_EXPIRATION_CHK
12550 DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0);
12552 tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0);
12556 if (rx_chk == _FAIL) {
12558 if (pmlmeext->retry > rx_chk_limit) {
12559 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
12560 FUNC_ADPT_ARG(padapter));
12561 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12562 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
12566 pmlmeext->retry = 0;
12569 if (tx_chk == _FAIL) {
12570 pmlmeinfo->link_count %= (link_count_limit+1);
12572 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12573 pmlmeinfo->link_count = 0;
12576 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12578 } else if (is_client_associated_to_ibss(padapter)) {
12580 _list *phead, *plist, dlist;
12582 _rtw_init_listhead(&dlist);
12584 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12586 for (i = 0; i < NUM_STA; i++) {
12588 phead = &(pstapriv->sta_hash[i]);
12589 plist = get_next(phead);
12590 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12591 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12592 plist = get_next(plist);
12594 if (is_broadcast_mac_addr(psta->hwaddr))
12597 if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
12598 psta->expire_to = pstapriv->adhoc_expire_to;
12602 if (psta->expire_to <= 0) {
12603 rtw_list_delete(&psta->list);
12604 rtw_list_insert_tail(&psta->list, &dlist);
12609 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12611 plist = get_next(&dlist);
12612 while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
12613 psta = LIST_CONTAINOR(plist, struct sta_info, list);
12614 plist = get_next(plist);
12615 rtw_list_delete(&psta->list);
12616 DBG_871X(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
12617 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->hwaddr));
12618 report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE, _FALSE);
12624 void survey_timer_hdl(_adapter *padapter)
12626 struct cmd_obj *cmd;
12627 struct sitesurvey_parm *psurveyPara;
12628 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12629 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12631 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12634 if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12635 cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12641 psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12642 if (psurveyPara == NULL) {
12644 rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12648 init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12649 rtw_enqueue_cmd(pcmdpriv, cmd);
12656 void link_timer_hdl(_adapter *padapter)
12658 //static unsigned int rx_pkt = 0;
12659 //static u64 tx_cnt = 0;
12660 //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12661 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12662 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12663 //struct sta_priv *pstapriv = &padapter->stapriv;
12666 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
12668 DBG_871X("link_timer_hdl:no beacon while connecting\n");
12669 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12670 report_join_res(padapter, -3);
12672 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
12675 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
12677 //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
12679 pmlmeinfo->state = 0;
12680 report_join_res(padapter, -1);
12685 // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
12686 // pmlmeinfo->reauth_count = 0;
12690 DBG_871X("link_timer_hdl: auth timeout and try again\n");
12691 pmlmeinfo->auth_seq = 1;
12692 issue_auth(padapter, NULL, 0);
12693 set_link_timer(pmlmeext, REAUTH_TO);
12695 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
12698 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
12700 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12701 report_join_res(padapter, -2);
12705 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
12706 issue_assocreq(padapter);
12707 set_link_timer(pmlmeext, REASSOC_TO);
12713 void addba_timer_hdl(struct sta_info *psta)
12715 #ifdef CONFIG_80211N_HT
12716 struct ht_priv *phtpriv;
12721 phtpriv = &psta->htpriv;
12723 if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
12725 if(phtpriv->candidate_tid_bitmap)
12726 phtpriv->candidate_tid_bitmap=0x0;
12729 #endif //CONFIG_80211N_HT
12732 #ifdef CONFIG_IEEE80211W
12733 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
12735 struct cmd_obj *pcmd_obj;
12738 struct sta_info *psta;
12740 struct stadel_event *pdel_sta_evt;
12741 struct C2HEvent_Header *pc2h_evt_hdr;
12742 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12743 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12745 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12746 if (pcmd_obj == NULL)
12749 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
12750 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12751 if (pevtcmd == NULL) {
12752 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12756 _rtw_init_listhead(&pcmd_obj->list);
12758 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
12759 pcmd_obj->cmdsz = cmdsz;
12760 pcmd_obj->parmbuf = pevtcmd;
12762 pcmd_obj->rsp = NULL;
12763 pcmd_obj->rspsz = 0;
12765 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
12766 pc2h_evt_hdr->len = sizeof(struct stadel_event);
12767 pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
12768 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12770 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
12771 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12772 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12775 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12777 mac_id = (int)psta->mac_id;
12781 pdel_sta_evt->mac_id = mac_id;
12783 DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
12785 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12790 void clnt_sa_query_timeout(_adapter *padapter)
12793 rtw_disassoc_cmd(padapter, 0, _TRUE);
12794 rtw_indicate_disconnect(padapter, 0, _FALSE);
12795 rtw_free_assoc_resources(padapter, 1);
12797 DBG_871X("SA query timeout client disconnect\n");
12800 void sa_query_timer_hdl(struct sta_info *psta)
12802 _adapter *padapter = psta->padapter;
12804 struct sta_priv *pstapriv = &padapter->stapriv;
12805 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12807 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
12808 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12809 clnt_sa_query_timeout(padapter);
12810 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
12811 report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID);
12814 #endif //CONFIG_IEEE80211W
12816 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
12818 return H2C_SUCCESS;
12821 #ifdef CONFIG_AUTO_AP_MODE
12822 void rtw_start_auto_ap(_adapter *adapter)
12824 DBG_871X("%s\n", __FUNCTION__);
12826 rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
12828 rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE);
12831 static int rtw_auto_ap_start_beacon(_adapter *adapter)
12836 u8 supportRate[16];
12837 int sz = 0, rateLen;
12839 u8 wireless_mode, oper_channel;
12840 u8 ssid[3] = {0}; //hidden ssid
12841 u32 ssid_len = sizeof(ssid);
12842 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
12845 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
12850 pbuf = rtw_zmalloc(len);
12858 //timestamp will be inserted by hardware
12862 //beacon interval : 2bytes
12863 *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
12869 *(u16*)ie |= cpu_to_le16(cap_ESS);
12870 *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
12871 //*(u16*)ie |= cpu_to_le16(cap_Privacy);
12876 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
12879 wireless_mode = WIRELESS_11BG_24N;
12880 rtw_set_supported_rate(supportRate, wireless_mode) ;
12881 rateLen = rtw_get_rateset_len(supportRate);
12884 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
12888 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
12893 if(check_buddy_fwstate(adapter, _FW_LINKED) &&
12894 check_buddy_fwstate(adapter, WIFI_STATION_STATE))
12896 PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
12897 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
12899 oper_channel = pbuddy_mlmeext->cur_channel;
12903 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
12905 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
12907 //ext supported rates
12910 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
12913 DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
12915 //lunch ap mode & start to issue beacon
12916 if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS)
12926 rtw_mfree(pbuf, len);
12931 #endif//CONFIG_AUTO_AP_MODE
12933 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
12936 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12937 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12938 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
12940 if(psetop->mode == Ndis802_11APMode)
12942 pmlmeinfo->state = WIFI_FW_AP_STATE;
12943 type = _HW_STATE_AP_;
12944 #ifdef CONFIG_NATIVEAP_MLME
12945 //start_ap_mode(padapter);
12948 else if(psetop->mode == Ndis802_11Infrastructure)
12950 pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
12951 pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE
12952 type = _HW_STATE_STATION_;
12954 else if(psetop->mode == Ndis802_11IBSS)
12956 type = _HW_STATE_ADHOC_;
12957 } else if (psetop->mode == Ndis802_11Monitor) {
12958 type = _HW_STATE_MONITOR_;
12962 type = _HW_STATE_NOLINK_;
12965 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
12966 //Set_NETYPE0_MSR(padapter, type);
12969 #ifdef CONFIG_AUTO_AP_MODE
12970 if(psetop->mode == Ndis802_11APMode)
12971 rtw_auto_ap_start_beacon(padapter);
12974 if (rtw_port_switch_chk(padapter) == _TRUE)
12976 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12978 if(psetop->mode == Ndis802_11APMode)
12979 adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages
12980 else if (psetop->mode == Ndis802_11Infrastructure) {
12982 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12984 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
12989 #ifdef CONFIG_BT_COEXIST
12990 if (psetop->mode == Ndis802_11APMode)
12992 // Do this after port switch to
12993 // prevent from downloading rsvd page to wrong port
12994 rtw_btcoex_MediaStatusNotify(padapter, 1); //connect
12996 #endif // CONFIG_BT_COEXIST
12998 return H2C_SUCCESS;
13002 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
13004 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13005 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13006 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13007 WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network;
13008 struct createbss_parm *parm = (struct createbss_parm *)pbuf;
13009 u8 ret = H2C_SUCCESS;
13012 #ifdef CONFIG_AP_MODE
13013 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
13014 start_bss_network(padapter, parm);
13019 /* below is for ad-hoc master */
13021 rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
13022 rtw_joinbss_reset(padapter);
13024 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13025 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13026 pmlmeinfo->ERP_enable = 0;
13027 pmlmeinfo->WMM_enable = 0;
13028 pmlmeinfo->HT_enable = 0;
13029 pmlmeinfo->HT_caps_enable = 0;
13030 pmlmeinfo->HT_info_enable = 0;
13031 pmlmeinfo->agg_enable_bitmap = 0;
13032 pmlmeinfo->candidate_tid_bitmap = 0;
13034 //config the initial gain under linking, need to write the BB registers
13035 //initialgain = 0x1E;
13036 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13038 //disable dynamic functions, such as high power, DIG
13039 rtw_phydm_ability_backup(padapter);
13040 rtw_phydm_func_disable_all(padapter);
13042 //cancel link timer
13043 _cancel_timer_ex(&pmlmeext->link_timer);
13046 flush_all_cam_entry(padapter);
13048 pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
13049 _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13050 pnetwork->IELength = pdev_network->IELength;
13052 if (pnetwork->IELength > MAX_IE_SZ) {
13053 ret = H2C_PARAMETERS_ERROR;
13054 goto ibss_post_hdl;
13057 _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
13058 start_create_ibss(padapter);
13061 ret = H2C_PARAMETERS_ERROR;
13065 rtw_create_ibss_post_hdl(padapter, ret);
13071 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13074 PNDIS_802_11_VARIABLE_IEs pIE;
13075 struct registry_priv *pregpriv = &padapter->registrypriv;
13076 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13077 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13078 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13079 #ifdef CONFIG_ANTENNA_DIVERSITY
13080 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
13081 #endif //CONFIG_ANTENNA_DIVERSITY
13085 u8 u_ch, u_bw, u_offset;
13088 //check already connecting to AP or not
13089 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
13091 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13093 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13095 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13098 flush_all_cam_entry(padapter);
13100 _cancel_timer_ex(&pmlmeext->link_timer);
13102 //set MSR to nolink -> infra. mode
13103 //Set_MSR(padapter, _HW_STATE_NOLINK_);
13104 Set_MSR(padapter, _HW_STATE_STATION_);
13107 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13110 #ifdef CONFIG_ANTENNA_DIVERSITY
13111 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13114 #ifdef CONFIG_WAPI_SUPPORT
13115 rtw_wapi_clear_all_cam_entry(padapter);
13118 rtw_joinbss_reset(padapter);
13120 pmlmeinfo->ERP_enable = 0;
13121 pmlmeinfo->WMM_enable = 0;
13122 pmlmeinfo->HT_enable = 0;
13123 pmlmeinfo->HT_caps_enable = 0;
13124 pmlmeinfo->HT_info_enable = 0;
13125 pmlmeinfo->agg_enable_bitmap = 0;
13126 pmlmeinfo->candidate_tid_bitmap = 0;
13127 pmlmeinfo->bwmode_updated = _FALSE;
13128 //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
13129 pmlmeinfo->VHT_enable = 0;
13131 _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13132 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13134 if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
13135 return H2C_PARAMETERS_ERROR;
13137 if (pnetwork->IELength < 2) {
13138 report_join_res(padapter, (-4));
13139 return H2C_SUCCESS;
13141 _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
13143 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13145 //Check AP vendor to move rtw_joinbss_cmd()
13146 //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
13148 //sizeof(NDIS_802_11_FIXED_IEs)
13149 for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13150 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13152 switch (pIE->ElementID)
13154 case _VENDOR_SPECIFIC_IE_://Get WMM IE.
13155 if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
13157 WMM_param_handler(padapter, pIE);
13161 #ifdef CONFIG_80211N_HT
13162 case _HT_CAPABILITY_IE_: //Get HT Cap IE.
13163 pmlmeinfo->HT_caps_enable = 1;
13166 case _HT_EXTRA_INFO_IE_: //Get HT Info IE.
13167 pmlmeinfo->HT_info_enable = 1;
13169 #endif /* CONFIG_80211N_HT */
13171 #ifdef CONFIG_80211AC_VHT
13172 case EID_VHTCapability://Get VHT Cap IE.
13173 pmlmeinfo->VHT_enable = 1;
13176 case EID_VHTOperation://Get VHT Operation IE.
13178 #endif /* CONFIG_80211AC_VHT */
13183 i += (pIE->Length + 2);
13186 rtw_bss_get_chbw(pnetwork
13187 , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13189 rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13192 if (padapter->registrypriv.wifi_spec) {
13193 // for WiFi test, follow WMM test plan spec
13194 acparm = 0x002F431C; // VO
13195 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13196 acparm = 0x005E541C; // VI
13197 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13198 acparm = 0x0000A525; // BE
13199 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13200 acparm = 0x0000A549; // BK
13201 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13203 // for WiFi test, mixed mode with intel STA under bg mode throughput issue
13204 if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
13205 acparm = 0x00004320;
13206 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13210 acparm = 0x002F3217; // VO
13211 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13212 acparm = 0x005E4317; // VI
13213 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13214 acparm = 0x00105320; // BE
13215 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13216 acparm = 0x0000A444; // BK
13217 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13221 /* check channel, bandwidth, offset and switch */
13222 if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
13223 report_join_res(padapter, (-4));
13224 return H2C_SUCCESS;
13227 //disable dynamic functions, such as high power, DIG
13228 /*rtw_phydm_func_disable_all(padapter);*/
13230 //config the initial gain under linking, need to write the BB registers
13231 //initialgain = 0x1E;
13232 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13234 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
13236 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13238 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13240 set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
13243 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13245 //cancel link timer
13246 _cancel_timer_ex(&pmlmeext->link_timer);
13248 start_clnt_join(padapter);
13250 return H2C_SUCCESS;
13254 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
13256 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
13257 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13258 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13259 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13262 if (is_client_associated_to_ap(padapter))
13265 if(padapter->mlmepriv.handle_dfs == _FALSE)
13266 #endif //CONFIG_DFS
13267 #ifdef CONFIG_PLATFORM_ROCKCHIPS
13268 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
13269 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13271 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
13272 #endif //CONFIG_PLATFORM_ROCKCHIPS
13276 if( padapter->mlmepriv.handle_dfs == _TRUE )
13277 padapter->mlmepriv.handle_dfs = _FALSE;
13278 #endif //CONFIG_DFS
13280 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13284 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13287 rtw_mlmeext_disconnect(padapter);
13289 rtw_free_uc_swdec_pending_queue(padapter);
13291 return H2C_SUCCESS;
13294 static const char * const _scan_state_str[] = {
13297 "SCAN_PS_ANNC_WAIT",
13304 "SCAN_SW_ANTDIV_BL",
13305 "SCAN_TO_P2P_LISTEN",
13311 const char *scan_state_str(u8 state)
13313 state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
13314 return _scan_state_str[state];
13317 static bool scan_abort_hdl(_adapter *adapter)
13319 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13320 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13321 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13323 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13327 if (pmlmeext->scan_abort == _TRUE) {
13329 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
13330 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
13331 ss->channel_idx = 3;
13332 DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
13334 , pwdinfo->find_phase_state_exchange_cnt
13339 ss->channel_idx = ss->ch_num;
13340 DBG_871X("%s idx:%d\n", __FUNCTION__
13344 pmlmeext->scan_abort = _FALSE;
13351 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13353 /* interval larger than this is treated as backgroud scan */
13354 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13355 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13358 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13359 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13361 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13362 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13365 #define SCAN_SPARSE_CH_NUM_INVALID 255
13367 static u8 token = 255;
13369 bool busy_traffic = _FALSE;
13370 bool miracast_enabled = _FALSE;
13371 bool bg_scan = _FALSE;
13372 u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13373 u8 scan_division_num;
13374 u8 ret_num = ch_num;
13375 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13376 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13378 if (regsty->wifi_spec)
13381 /* assume ch_num > 6 is normal scan */
13385 if (mlmeext->last_scan_time == 0)
13386 mlmeext->last_scan_time = rtw_get_current_time();
13388 interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13390 if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE
13391 #ifdef CONFIG_CONCURRENT_MODE
13392 || (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
13395 busy_traffic = _TRUE;
13397 if (is_miracast_enabled(adapter)
13398 #ifdef CONFIG_CONCURRENT_MODE
13399 || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter))
13402 miracast_enabled = _TRUE;
13404 if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13407 /* max_allow_ch by conditions*/
13409 #if RTW_SCAN_SPARSE_MIRACAST
13410 if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13411 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13414 #if RTW_SCAN_SPARSE_BG
13415 if (bg_scan == _TRUE)
13416 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13420 if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13424 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0);
13425 token = (token + 1) % scan_division_num;
13428 DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token);
13430 for (i = 0; i < ch_num; i++) {
13431 if (ch[i].hw_value && (i % scan_division_num) == token
13434 _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13439 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13442 mlmeext->last_scan_time = rtw_get_current_time();
13449 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13450 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13453 int scan_ch_num = 0;
13455 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13458 _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
13460 /* acquire channels from in */
13462 for (i=0;i<in_num;i++) {
13465 DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13467 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
13468 && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
13469 && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE
13472 if (j >= out_num) {
13473 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13474 FUNC_ADPT_ARG(padapter), out_num);
13478 _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13480 if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13481 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13489 /* if out is empty, use channel_set as default */
13491 for (i=0;i<pmlmeext->max_chan_nums;i++) {
13494 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
13496 if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) {
13498 if (j >= out_num) {
13499 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13500 FUNC_ADPT_ARG(padapter), out_num);
13504 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
13506 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
13507 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13515 j = rtw_scan_sparse(padapter, out, j);
13520 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
13522 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
13526 ss->channel_idx = 0;
13527 #ifdef CONFIG_SCAN_BACKOP
13530 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
13531 ss->is_sw_antdiv_bl_scan = 0;
13534 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13535 if (parm->ssid[i].SsidLength) {
13536 _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
13537 ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
13539 ss->ssid[i].SsidLength = 0;
13543 ss->ch_num = rtw_scan_ch_decision(adapter
13544 , ss->ch, RTW_CHANNEL_SCAN_AMOUNT
13545 , parm->ch, parm->ch_num
13548 ss->scan_mode = parm->scan_mode;
13551 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
13555 RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
13556 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13557 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
13558 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13561 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13564 /* handle scan abort request */
13565 scan_abort_hdl(padapter);
13568 if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
13569 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
13570 scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
13572 scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
13573 scan_type = SCAN_ACTIVE;
13574 } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
13576 * Commented by Albert 2011/06/03
13577 * The driver is in the find phase, it should go through the social channel.
13581 scan_ch = pwdinfo->social_chan[ss->channel_idx];
13582 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch);
13583 if (ch_set_idx >= 0)
13584 scan_type = pmlmeext->channel_set[ch_set_idx].ScanType;
13586 scan_type = SCAN_ACTIVE;
13588 #endif /* CONFIG_P2P */
13590 struct rtw_ieee80211_channel *ch;
13592 if (ss->channel_idx < ss->ch_num) {
13593 ch = &ss->ch[ss->channel_idx];
13594 scan_ch = ch->hw_value;
13595 scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
13599 if (scan_ch != 0) {
13600 next_state = SCAN_PROCESS;
13601 #ifdef CONFIG_SCAN_BACKOP
13607 u8 backop_flags = 0;
13609 rtw_dev_iface_status(padapter, &sta_num, &ld_sta_num, NULL, &ap_num, &ld_ap_num);
13611 if ((ld_sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN))
13612 || (sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL))
13614 backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext);
13617 if ((ld_ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN))
13618 || (ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL))
13620 backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext);
13623 if (backop_flags) {
13624 if (ss->scan_cnt < ss->scan_cnt_max) {
13627 mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
13628 next_state = SCAN_BACKING_OP;
13632 #endif /* CONFIG_SCAN_BACKOP */
13633 } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
13634 /* go p2p listen */
13635 next_state = SCAN_TO_P2P_LISTEN;
13637 #ifdef CONFIG_ANTENNA_DIVERSITY
13638 } else if (rtw_hal_antdiv_before_linked(padapter)) {
13639 /* go sw antdiv before link */
13640 next_state = SCAN_SW_ANTDIV_BL;
13643 next_state = SCAN_COMPLETE;
13645 #if defined(DBG_SCAN_SW_ANTDIV_BL)
13647 /* for SCAN_SW_ANTDIV_BL state testing */
13648 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13650 bool is_linked = _FALSE;
13652 for (i = 0; i < dvobj->iface_nums; i++) {
13653 if (rtw_linked_check(dvobj->padapters[i]))
13658 static bool fake_sw_antdiv_bl_state = 0;
13660 if (fake_sw_antdiv_bl_state == 0) {
13661 next_state = SCAN_SW_ANTDIV_BL;
13662 fake_sw_antdiv_bl_state = 1;
13664 fake_sw_antdiv_bl_state = 0;
13668 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
13671 #ifdef CONFIG_SCAN_BACKOP
13672 if (next_state != SCAN_PROCESS)
13677 #ifdef DBG_FIXED_CHAN
13678 if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
13679 scan_ch = pmlmeext->fixed_chan;
13690 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
13692 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13693 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13696 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
13699 if (survey_channel != 0) {
13700 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
13702 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13703 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
13704 ACS_OP acs_op = ACS_RESET;
13706 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
13707 rtw_set_acs_channel(padapter, survey_channel);
13708 #ifdef DBG_AUTO_CHNL_SEL_NHM
13709 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n",
13710 ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
13715 if (ScanType == SCAN_ACTIVE) {
13717 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
13718 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
13720 issue_probereq_p2p(padapter, NULL);
13721 issue_probereq_p2p(padapter, NULL);
13722 issue_probereq_p2p(padapter, NULL);
13724 #endif /* CONFIG_P2P */
13728 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13729 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
13730 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13731 if (padapter->registrypriv.wifi_spec)
13732 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13734 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
13735 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13739 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
13740 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13741 if (padapter->registrypriv.wifi_spec)
13742 issue_probereq(padapter, NULL, NULL);
13744 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
13745 issue_probereq(padapter, NULL, NULL);
13750 /* channel number is 0 or this channel is not valid. */
13757 void survey_done_set_ch_bw(_adapter *padapter)
13759 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13760 u8 cur_channel = 0;
13764 if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
13766 DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
13767 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13770 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13774 for (i = 0; i < dvobj->iface_nums; i++) {
13775 iface = dvobj->padapters[i];
13779 #ifdef CONFIG_IOCTL_CFG80211
13780 if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
13784 if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
13785 cur_channel = iface->wdinfo.listen_channel;
13786 cur_bwmode = CHANNEL_WIDTH_20;
13787 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13789 DBG_871X(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
13790 FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
13794 #endif /* CONFIG_P2P */
13796 if (cur_channel == 0) {
13797 cur_channel = pmlmeext->cur_channel;
13798 cur_bwmode = pmlmeext->cur_bwmode;
13799 cur_ch_offset = pmlmeext->cur_ch_offset;
13801 DBG_871X(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
13802 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13806 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
13810 * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
13811 * @dvobj: the dvobj to check
13812 * @ps: power saving or not
13814 * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
13816 u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps)
13822 for (i = 0; i < dvobj->iface_nums; i++) {
13823 adapter = dvobj->padapters[i];
13828 if (is_client_associated_to_ap(adapter) == _TRUE) {
13829 /* TODO: TDLS peers */
13830 issue_nulldata(adapter, NULL, 1, 3, 500);
13834 if (is_client_associated_to_ap(adapter) == _TRUE) {
13835 /* TODO: TDLS peers */
13836 issue_nulldata(adapter, NULL, 0, 3, 500);
13845 void sitesurvey_set_igi(_adapter *adapter, bool enter)
13849 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13854 #ifdef CONFIG_IOCTL_CFG80211
13855 if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211)
13858 #endif /* CONFIG_IOCTL_CFG80211 */
13859 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
13862 #endif /* CONFIG_P2P */
13865 igi = 0xff; /* restore RX GAIN */
13868 rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
13871 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
13873 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
13874 struct dvobj_priv *dvobj = padapter->dvobj;
13875 struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
13876 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13877 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13878 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13882 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13885 #ifdef DBG_CHECK_FW_PS_STATE
13886 if (rtw_fw_ps_state(padapter) == _FAIL) {
13887 DBG_871X("scan without leave 32k\n");
13888 pdbgpriv->dbg_scan_pwr_state_cnt++;
13890 #endif /* DBG_CHECK_FW_PS_STATE */
13892 /* increase channel idx */
13893 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
13896 /* update scan state to next state (assigned by previous cmd hdl) */
13897 if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
13898 mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
13900 operation_by_state:
13901 switch (mlmeext_scan_state(pmlmeext)) {
13905 * SW parameter initialization
13908 sitesurvey_res_reset(padapter, pparm);
13909 mlmeext_set_scan_state(pmlmeext, SCAN_START);
13910 goto operation_by_state;
13914 * prepare to leave operating channel
13917 /* apply rx ampdu setting */
13918 if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
13919 || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID
13921 rtw_rx_ampdu_apply(padapter);
13924 /* clear HW TX queue before scan */
13925 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
13927 /* power save state announcement */
13928 if (sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)) {
13929 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
13930 mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
13931 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
13933 mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
13934 goto operation_by_state;
13941 * HW register and DM setting for enter scan
13944 /* config the initial gain under scanning */
13945 sitesurvey_set_igi(padapter, 1);
13947 /* disable dynamic functions, such as high power, DIG */
13948 rtw_phydm_ability_backup(padapter);
13949 rtw_phydm_func_for_offchannel(padapter);
13950 /* set MSR to no link state */
13951 Set_MSR(padapter, _HW_STATE_NOLINK_);
13952 val8 = 1; /* under site survey */
13953 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
13955 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
13956 goto operation_by_state;
13961 RT_SCAN_TYPE scan_type;
13965 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13966 if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) {
13967 ACS_OP acs_op = ACS_SELECT;
13969 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
13973 next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
13974 if (next_state != SCAN_PROCESS) {
13975 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13976 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
13977 rtw_set_acs_channel(padapter, 0);
13978 #ifdef DBG_AUTO_CHNL_SEL_NHM
13979 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
13984 mlmeext_set_scan_state(pmlmeext, next_state);
13985 goto operation_by_state;
13988 /* still SCAN_PROCESS state */
13991 DBG_871X(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
13992 , FUNC_ADPT_ARG(padapter)
13993 , mlmeext_scan_state_str(pmlmeext)
13995 , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
13996 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
13997 , scan_type?'A':'P', ss->scan_mode?'A':'P'
13998 , ss->ssid[0].SsidLength?'S':' '
14001 DBG_871X(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n"
14002 , FUNC_ADPT_ARG(padapter)
14003 , mlmeext_scan_state_str(pmlmeext)
14006 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14007 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14008 , ss->ssid[0].SsidLength?'S':' '
14010 #endif /* CONFIG_P2P */
14012 #ifdef DBG_FIXED_CHAN
14013 if (pmlmeext->fixed_chan != 0xff)
14014 DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
14017 site_survey(padapter, scan_ch, scan_type);
14019 #if defined(CONFIG_ATMEL_RC_PATCH)
14020 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
14025 scan_ms = ss->scan_ch_ms;
14028 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14029 if (ss->is_sw_antdiv_bl_scan)
14030 scan_ms = scan_ms/2;
14033 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14035 struct noise_info info;
14037 info.bPauseDIG = _FALSE;
14039 info.max_time = scan_ms/2;
14040 info.chan = scan_ch;
14041 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
14045 set_survey_timer(pmlmeext, scan_ms);
14049 #ifdef CONFIG_SCAN_BACKOP
14050 case SCAN_BACKING_OP:
14052 u8 back_ch, back_bw, back_ch_offset;
14054 if (rtw_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
14058 DBG_871X(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
14059 , FUNC_ADPT_ARG(padapter)
14060 , mlmeext_scan_state_str(pmlmeext)
14061 , back_ch, back_bw, back_ch_offset
14062 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14065 set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
14067 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14068 val8 = 0; /* survey done */
14069 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14071 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14072 sitesurvey_set_igi(padapter, 0);
14073 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14076 mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
14077 ss->backop_time = rtw_get_current_time();
14079 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME)) {
14083 for (i = 0; i < dvobj->iface_nums; i++) {
14084 if (!dvobj->padapters[i])
14087 rtw_os_xmit_schedule(dvobj->padapters[i]);
14091 goto operation_by_state;
14095 if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
14096 || pmlmeext->scan_abort
14098 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
14099 goto operation_by_state;
14101 set_survey_timer(pmlmeext, 50);
14104 case SCAN_LEAVING_OP:
14106 * prepare to leave operating channel
14109 /* clear HW TX queue before scan */
14110 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14112 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
14113 && sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)
14115 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14116 mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
14117 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14119 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
14120 goto operation_by_state;
14125 case SCAN_LEAVE_OP:
14127 * HW register and DM setting for enter scan
14130 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14131 /* config the initial gain under scanning */
14132 sitesurvey_set_igi(padapter, 1);
14135 /* set MSR to no link state */
14136 Set_MSR(padapter, _HW_STATE_NOLINK_);
14137 val8 = 1; //under site survey
14138 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14140 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14141 goto operation_by_state;
14143 #endif /* CONFIG_SCAN_BACKOP */
14145 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14146 case SCAN_SW_ANTDIV_BL:
14149 * For SW antenna diversity before link, it needs to switch to another antenna and scan again.
14150 * It compares the scan result and select better one to do connection.
14153 ss->channel_idx = 0;
14154 ss->is_sw_antdiv_bl_scan = 1;
14156 mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
14157 set_survey_timer(pmlmeext, ss->scan_ch_ms);
14162 case SCAN_TO_P2P_LISTEN:
14164 * Set the P2P State to the listen state of find phase
14165 * and set the current channel to the listen channel
14167 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14168 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
14170 /* turn on phy-dynamic functions */
14171 rtw_phydm_ability_restore(padapter);
14173 sitesurvey_set_igi(padapter, 0);
14175 mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
14176 _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
14179 case SCAN_P2P_LISTEN:
14180 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14181 ss->channel_idx = 0;
14182 goto operation_by_state;
14183 #endif /* CONFIG_P2P */
14185 case SCAN_COMPLETE:
14187 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14188 || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14190 #ifdef CONFIG_CONCURRENT_MODE
14191 if (pwdinfo->driver_interface == DRIVER_WEXT) {
14192 if (check_buddy_fwstate(padapter, _FW_LINKED))
14193 _set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
14195 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14197 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14200 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
14201 #endif /* CONFIG_P2P */
14203 /* switch channel */
14204 survey_done_set_ch_bw(padapter);
14207 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14208 val8 = 0; /* survey done */
14209 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14211 /* turn on phy-dynamic functions */
14212 rtw_phydm_ability_restore(padapter);
14214 sitesurvey_set_igi(padapter, 0);
14216 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14218 /* apply rx ampdu setting */
14219 rtw_rx_ampdu_apply(padapter);
14221 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
14223 report_surveydone_event(padapter);
14225 issue_action_BSSCoexistPacket(padapter);
14226 issue_action_BSSCoexistPacket(padapter);
14227 issue_action_BSSCoexistPacket(padapter);
14230 return H2C_SUCCESS;
14233 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
14235 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
14236 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14237 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14239 if (pparm->mode < 4)
14241 pmlmeinfo->auth_algo = pparm->mode;
14244 return H2C_SUCCESS;
14247 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
14251 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
14252 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14253 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14254 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14255 struct set_stakey_parm sta_pparm;
14256 struct security_priv *psecuritypriv = &padapter->securitypriv;
14260 //main tx key for wep.
14262 pmlmeinfo->key_index = pparm->keyid;
14264 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used);
14269 if (cam_id > 3) /* not default key, searched by A2 */
14270 addr = get_bssid(&padapter->mlmepriv);
14274 #ifdef DYNAMIC_CAMID_ALLOC
14275 /* cam entry searched is pairwise key */
14276 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
14279 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
14280 , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
14282 /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
14283 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14284 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14286 /* clear group key */
14287 while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
14288 DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
14289 clear_cam_entry(padapter, camid_clr);
14290 rtw_camid_free(padapter, camid_clr);
14297 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
14298 DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
14299 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
14300 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
14302 #ifdef DYNAMIC_CAMID_ALLOC
14303 if (cam_id >=0 && cam_id <=3)
14304 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE);
14306 /* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
14307 if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC) && is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm)) {
14308 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
14310 sta_pparm.algorithm = pparm->algorithm;
14311 sta_pparm.keyid = pparm->keyid;
14312 _rtw_memcpy(sta_pparm.key, pparm->key, 16);
14313 _rtw_memcpy(sta_pparm.addr, get_bssid(pmlmepriv), ETH_ALEN);
14314 set_stakey_hdl(padapter, (u8 *) &sta_pparm);
14318 //allow multicast packets to driver
14319 rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
14321 return H2C_SUCCESS;
14324 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
14329 u8 ret = H2C_SUCCESS;
14330 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14331 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14332 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
14333 struct sta_priv *pstapriv = &padapter->stapriv;
14334 struct sta_info *psta;
14336 if(pparm->algorithm == _NO_PRIVACY_)
14339 psta = rtw_get_stainfo(pstapriv, pparm->addr);
14341 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
14342 ret = H2C_REJECTED;
14346 pmlmeinfo->enc_algo = pparm->algorithm;
14347 cam_id = rtw_camid_alloc(padapter, psta, 0, &used);
14351 #ifdef DYNAMIC_CAMID_ALLOC
14352 /* cam entry searched is group key */
14353 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
14356 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
14357 , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
14359 /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
14360 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14361 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14363 /* clear group key */
14364 while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
14365 DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
14366 clear_cam_entry(padapter, camid_clr);
14367 rtw_camid_free(padapter, camid_clr);
14373 if(pparm->algorithm == _NO_PRIVACY_) {
14374 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
14375 DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
14376 clear_cam_entry(padapter, cam_id);
14377 rtw_camid_free(padapter,cam_id);
14380 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
14381 cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
14382 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
14383 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
14385 ret = H2C_SUCCESS_RSP;
14391 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
14393 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
14394 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14395 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14397 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
14400 return H2C_SUCCESS;
14402 #ifdef CONFIG_80211N_HT
14403 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
14404 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
14406 //pmlmeinfo->ADDBA_retry_count = 0;
14407 //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
14408 //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
14409 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14410 //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
14411 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14414 else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
14415 (psta->htpriv.ht_option==_TRUE) &&
14416 (psta->htpriv.ampdu_enable==_TRUE) )
14418 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14419 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14424 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
14426 #endif //CONFIG_80211N_HT
14427 return H2C_SUCCESS;
14431 u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
14433 struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
14434 u8 ret = _TRUE, i = 0, try_cnt = 3, wait_ms = 50;
14435 struct recv_reorder_ctrl *preorder_ctrl;
14436 struct sta_priv *pstapriv = &padapter->stapriv;
14437 struct sta_info *psta;
14439 psta = rtw_get_stainfo(pstapriv, pparm->addr);
14443 preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
14444 ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
14446 #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
14447 /* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
14448 if (pparm->status == 0) {
14449 preorder_ctrl->indicate_seq = pparm->start_seq;
14451 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __func__, __LINE__,
14452 preorder_ctrl->indicate_seq, pparm->start_seq);
14456 preorder_ctrl->indicate_seq = 0xffff;
14460 * status = 0 means accept this addba req
14461 * status = 37 means reject this addba req
14463 if (pparm->status == 0) {
14464 preorder_ctrl->enable = _TRUE;
14465 preorder_ctrl->ampdu_size = pparm->size;
14466 } else if (pparm->status == 37)
14467 preorder_ctrl->enable = _FALSE;
14470 return H2C_SUCCESS;
14473 u8 chk_bmc_sleepq_cmd(_adapter* padapter)
14475 struct cmd_obj *ph2c;
14476 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14481 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14487 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
14489 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14498 u8 set_tx_beacon_cmd(_adapter* padapter)
14500 struct cmd_obj *ph2c;
14501 struct Tx_Beacon_param *ptxBeacon_parm;
14502 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14503 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14504 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14510 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14516 if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
14518 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
14523 _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
14525 len_diff = update_hidden_ssid(
14526 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
14527 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
14528 , pmlmeinfo->hidden_ssid_mode
14530 ptxBeacon_parm->network.IELength += len_diff;
14532 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
14534 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14545 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
14547 u8 evt_code, evt_seq;
14550 void (*event_callback)(_adapter *dev, u8 *pbuf);
14551 struct evt_priv *pevt_priv = &(padapter->evtpriv);
14554 goto _abort_event_;
14556 peventbuf = (uint*)pbuf;
14557 evt_sz = (u16)(*peventbuf&0xffff);
14558 evt_seq = (u8)((*peventbuf>>24)&0x7f);
14559 evt_code = (u8)((*peventbuf>>16)&0xff);
14562 #ifdef CHECK_EVENT_SEQ
14563 // checking event sequence...
14564 if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
14566 RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("Evetn Seq Error! %d vs %d\n", (evt_seq & 0x7f), (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)));
14568 pevt_priv->event_seq = (evt_seq+1)&0x7f;
14570 goto _abort_event_;
14574 // checking if event code is valid
14575 if (evt_code >= MAX_C2HEVT)
14577 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
14578 goto _abort_event_;
14581 // checking if event size match the event parm size
14582 if ((wlanevents[evt_code].parmsize != 0) &&
14583 (wlanevents[evt_code].parmsize != evt_sz))
14586 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
14587 evt_code, wlanevents[evt_code].parmsize, evt_sz));
14588 goto _abort_event_;
14592 ATOMIC_INC(&pevt_priv->event_seq);
14598 event_callback = wlanevents[evt_code].event_callback;
14599 event_callback(padapter, (u8*)peventbuf);
14601 pevt_priv->evt_done_cnt++;
14608 return H2C_SUCCESS;
14612 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
14615 return H2C_PARAMETERS_ERROR;
14617 return H2C_SUCCESS;
14620 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
14622 #ifdef CONFIG_AP_MODE
14624 struct sta_info *psta_bmc;
14625 _list *xmitframe_plist, *xmitframe_phead;
14626 struct xmit_frame *pxmitframe=NULL;
14627 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
14628 struct sta_priv *pstapriv = &padapter->stapriv;
14631 psta_bmc = rtw_get_bcmc_stainfo(padapter);
14633 return H2C_SUCCESS;
14635 if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
14637 #ifndef CONFIG_PCI_HCI
14638 rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
14640 //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14641 _enter_critical_bh(&pxmitpriv->lock, &irqL);
14643 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
14644 xmitframe_plist = get_next(xmitframe_phead);
14646 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
14648 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
14650 xmitframe_plist = get_next(xmitframe_plist);
14652 rtw_list_delete(&pxmitframe->list);
14654 psta_bmc->sleepq_len--;
14655 if(psta_bmc->sleepq_len>0)
14656 pxmitframe->attrib.mdata = 1;
14658 pxmitframe->attrib.mdata = 0;
14660 pxmitframe->attrib.triggered=1;
14662 if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
14663 pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ
14666 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14667 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
14669 rtw_os_xmit_complete(padapter, pxmitframe);
14671 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14673 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
14676 //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14677 _exit_critical_bh(&pxmitpriv->lock, &irqL);
14679 if (rtw_get_intf_type(padapter) != RTW_PCIE) {
14680 /* check hi queue and bmc_sleepq */
14681 rtw_chk_hi_queue_cmd(padapter);
14686 return H2C_SUCCESS;
14689 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
14691 if(send_beacon(padapter)==_FAIL)
14693 DBG_871X("issue_beacon, fail!\n");
14694 return H2C_PARAMETERS_ERROR;
14698 if (padapter->registrypriv.wifi_spec == 1)
14699 return H2C_SUCCESS;
14701 /* tx bc/mc frames after update TIM */
14702 chk_bmc_sleepq_hdl(padapter, NULL);
14704 return H2C_SUCCESS;
14708 * according to channel
14709 * add/remove WLAN_BSSID_EX.IEs's ERP ie
14710 * set WLAN_BSSID_EX.SupportedRates
14711 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
14713 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
14715 u8 network_type,rate_len, total_rate_len,remainder_rate_len;
14716 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
14717 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14721 network_type = WIRELESS_11A;
14722 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
14723 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
14725 network_type = WIRELESS_11BG;
14726 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
14727 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
14730 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
14732 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
14734 if(total_rate_len > 8)
14737 remainder_rate_len = total_rate_len - 8;
14741 rate_len = total_rate_len;
14742 remainder_rate_len = 0;
14745 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
14747 if(remainder_rate_len)
14749 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
14753 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
14756 pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
14759 #ifdef CONFIG_CONCURRENT_MODE
14760 sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
14762 PADAPTER pbuddy_adapter;
14763 struct mlme_ext_priv *pbuddy_mlmeext;
14764 struct mlme_ext_info *pbuddy_mlmeinfo;
14766 if(padapter == NULL)
14769 pbuddy_adapter = padapter->pbuddy_adapter;
14771 if(pbuddy_adapter == NULL)
14775 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
14776 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
14778 if((pbuddy_mlmeinfo->state&0x03) == state)
14784 #endif /* CONFIG_CONCURRENT_MODE */
14786 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
14788 #define DUMP_ADAPTERS_STATUS 0
14790 struct dvobj_priv *dvobj;
14792 struct mlme_priv *mlme;
14793 struct mlme_ext_priv *mlmeext;
14794 u8 u_ch, u_offset, u_bw;
14797 dvobj = adapter_to_dvobj(adapter);
14799 if (DUMP_ADAPTERS_STATUS) {
14800 DBG_871X(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
14801 dump_adapters_status(RTW_DBGDUMP , dvobj);
14804 if (join_res >= 0) {
14805 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14806 dump_adapters_status(RTW_DBGDUMP , dvobj);
14810 for (i = 0; i < dvobj->iface_nums; i++) {
14811 iface = dvobj->padapters[i];
14812 mlme = &iface->mlmepriv;
14813 mlmeext = &iface->mlmeextpriv;
14815 if (!iface || iface == adapter)
14818 if (check_fwstate(mlme, WIFI_AP_STATE)
14819 && check_fwstate(mlme, WIFI_ASOC_STATE)
14821 bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
14822 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14824 if (is_grouped == _FALSE) {
14825 /* handle AP which need to switch ch setting */
14827 /* restore original bw, adjust bw by registry setting on target ch */
14828 mlmeext->cur_bwmode = mlme->ori_bw;
14829 mlmeext->cur_channel = u_ch;
14830 rtw_adjust_chbw(iface
14831 , mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
14833 rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
14834 , &u_ch, &u_bw, &u_offset);
14836 rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
14837 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14839 _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
14841 rtw_start_bss_hdl_after_chbw_decided(iface);
14844 update_beacon(iface, 0, NULL, _TRUE);
14847 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14850 #ifdef CONFIG_DFS_MASTER
14851 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED);
14854 for (i = 0; i < dvobj->iface_nums; i++) {
14855 iface = dvobj->padapters[i];
14856 mlme = &iface->mlmepriv;
14857 mlmeext = &iface->mlmeextpriv;
14859 if (!iface || iface == adapter)
14862 if (check_fwstate(mlme, WIFI_AP_STATE)
14863 && check_fwstate(mlme, WIFI_ASOC_STATE))
14864 update_beacon(iface, 0, NULL, _TRUE);
14866 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14868 #ifdef CONFIG_DFS_MASTER
14869 rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED);
14873 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
14874 set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
14876 if (DUMP_ADAPTERS_STATUS) {
14877 DBG_871X(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
14878 dump_adapters_status(RTW_DBGDUMP , dvobj);
14882 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
14884 bool chbw_allow = _TRUE;
14885 bool connect_allow = _TRUE;
14886 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14887 u8 cur_ch, cur_bw, cur_ch_offset;
14888 u8 u_ch, u_offset, u_bw;
14890 u_ch = cur_ch = pmlmeext->cur_channel;
14891 u_bw = cur_bw = pmlmeext->cur_bwmode;
14892 u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
14894 if (!ch || !bw || !offset) {
14895 connect_allow = _FALSE;
14901 connect_allow = _FALSE;
14902 DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n"
14903 , FUNC_ADPT_ARG(adapter), cur_ch);
14907 DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14909 #ifdef CONFIG_CONCURRENT_MODE
14911 struct dvobj_priv *dvobj;
14913 struct mlme_priv *mlme;
14914 struct mlme_ext_priv *mlmeext;
14922 dvobj = adapter_to_dvobj(adapter);
14924 rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num);
14925 DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n"
14926 , FUNC_ADPT_ARG(adapter), ld_sta_num, ap_num);
14928 if (!ld_sta_num && !ap_num) {
14929 /* consider linking STA? */
14930 goto connect_allow_hdl;
14933 if (rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14934 dump_adapters_status(RTW_DBGDUMP , dvobj);
14937 DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
14938 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14941 chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
14942 , u_ch, u_bw, u_offset);
14944 DBG_871X(FUNC_ADPT_FMT" chbw_allow:%d\n"
14945 , FUNC_ADPT_ARG(adapter), chbw_allow);
14947 if (chbw_allow == _TRUE) {
14948 rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
14949 rtw_warn_on(cur_ch != pmlmeext->cur_channel);
14950 rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
14951 rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
14952 goto connect_allow_hdl;
14955 /* chbw_allow is _FALSE, connect allow? */
14956 for (i = 0; i < dvobj->iface_nums; i++) {
14957 iface = dvobj->padapters[i];
14958 mlme = &iface->mlmepriv;
14959 mlmeext = &iface->mlmeextpriv;
14961 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
14962 if (check_fwstate(mlme, WIFI_STATION_STATE)
14963 && check_fwstate(mlme, WIFI_ASOC_STATE)
14964 #if defined(CONFIG_P2P)
14965 && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
14968 connect_allow = _FALSE;
14971 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
14973 DBG_871X(FUNC_ADPT_FMT" connect_allow:%d\n"
14974 , FUNC_ADPT_ARG(adapter), connect_allow);
14976 if (connect_allow == _FALSE)
14980 /* connect_allow == _TRUE */
14982 #ifdef CONFIG_DFS_MASTER
14983 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING);
14986 if (chbw_allow == _FALSE) {
14989 u_offset = cur_ch_offset;
14991 for (i = 0; i < dvobj->iface_nums; i++) {
14992 iface = dvobj->padapters[i];
14993 mlme = &iface->mlmepriv;
14994 mlmeext = &iface->mlmeextpriv;
14996 if (!iface || iface == adapter)
14999 if (check_fwstate(mlme, WIFI_AP_STATE)
15000 && check_fwstate(mlme, WIFI_ASOC_STATE)
15002 #ifdef CONFIG_SPCT_CH_SWITCH
15004 rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
15007 rtw_sta_flush(iface, _FALSE);
15009 rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
15010 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15011 } else if (check_fwstate(mlme, WIFI_STATION_STATE)
15012 && check_fwstate(mlme, WIFI_ASOC_STATE)
15014 rtw_disassoc_cmd(iface, 500, _FALSE);
15015 rtw_indicate_disconnect(iface, 0, _FALSE);
15016 rtw_free_assoc_resources(iface, 1);
15021 #endif /* CONFIG_CONCURRENT_MODE */
15025 if (connect_allow == _TRUE) {
15026 DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15029 *offset = u_offset;
15032 return connect_allow == _TRUE ? _SUCCESS : _FAIL;
15035 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
15036 int _rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
15038 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15040 struct mlme_ext_priv *mlmeext;
15043 u8 bw_ret = CHANNEL_WIDTH_20;
15044 u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15048 if (bw) *bw = CHANNEL_WIDTH_20;
15049 if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15051 for (i = 0; i<dvobj->iface_nums; i++) {
15052 iface = dvobj->padapters[i];
15053 mlmeext = &iface->mlmeextpriv;
15055 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
15058 if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
15061 if (include_self == _FALSE && adapter == iface)
15065 ch_ret = mlmeext->cur_channel;
15066 bw_ret = mlmeext->cur_bwmode;
15067 offset_ret = mlmeext->cur_ch_offset;
15072 if (ch_ret != mlmeext->cur_channel) {
15077 if (bw_ret < mlmeext->cur_bwmode) {
15078 bw_ret = mlmeext->cur_bwmode;
15079 offset_ret = mlmeext->cur_ch_offset;
15080 } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
15089 if (ch) *ch = ch_ret;
15090 if (bw) *bw = bw_ret;
15091 if (offset) *offset = offset_ret;
15097 inline int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15099 return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 1);
15102 inline int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15104 return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 0);
15107 void _rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15108 , u8 *ap_num, u8 *ld_ap_num, bool include_self)
15110 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15112 struct mlme_ext_priv *mlmeext;
15113 struct mlme_ext_info *mlmeextinfo;
15115 u8 sta_num_ret = 0;
15116 u8 ld_sta_num_ret = 0;
15117 u8 lg_sta_num_ret = 0;
15119 u8 ld_ap_num_ret = 0;
15132 for (i = 0; i < dvobj->iface_nums; i++) {
15133 iface = dvobj->padapters[i];
15135 if (include_self == _FALSE && iface == adapter)
15138 mlmeext = &iface->mlmeextpriv;
15140 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
15142 if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
15144 if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
15148 if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
15149 && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
15152 if (iface->stapriv.asoc_sta_count > 2)
15158 *sta_num = sta_num_ret;
15160 *ld_sta_num = ld_sta_num_ret;
15162 *lg_sta_num = lg_sta_num_ret;
15164 *ap_num = ap_num_ret;
15166 *ld_ap_num = ld_ap_num_ret;
15169 inline void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15170 , u8 *ap_num, u8 *ld_ap_num)
15172 return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 1);
15175 inline void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15176 , u8 *ap_num, u8 *ld_ap_num)
15178 return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 0);
15181 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
15183 struct set_ch_parm *set_ch_parm;
15184 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
15185 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15188 return H2C_PARAMETERS_ERROR;
15190 set_ch_parm = (struct set_ch_parm *)pbuf;
15192 DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
15193 FUNC_NDEV_ARG(padapter->pnetdev),
15194 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
15196 pmlmeext->cur_channel = set_ch_parm->ch;
15197 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
15198 pmlmeext->cur_bwmode = set_ch_parm->bw;
15200 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
15202 return H2C_SUCCESS;
15205 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
15207 struct SetChannelPlan_param *setChannelPlan_param;
15208 struct mlme_priv *mlme = &padapter->mlmepriv;
15209 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15212 return H2C_PARAMETERS_ERROR;
15214 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
15216 if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) {
15217 return H2C_PARAMETERS_ERROR;
15220 mlme->country_ent = setChannelPlan_param->country_ent;
15221 mlme->ChannelPlan = setChannelPlan_param->channel_plan;
15223 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
15224 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
15226 rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE);
15228 #ifdef CONFIG_IOCTL_CFG80211
15229 rtw_reg_notify_by_driver(padapter);
15230 #endif //CONFIG_IOCTL_CFG80211
15232 return H2C_SUCCESS;
15235 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
15237 struct LedBlink_param *ledBlink_param;
15240 return H2C_PARAMETERS_ERROR;
15242 ledBlink_param = (struct LedBlink_param *)pbuf;
15244 #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
15245 BlinkHandler((PLED_DATA)ledBlink_param->pLed);
15248 return H2C_SUCCESS;
15251 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
15254 struct SetChannelSwitch_param *setChannelSwitch_param;
15256 u8 gval8 = 0x00, sval8 = 0xff;
15259 return H2C_PARAMETERS_ERROR;
15261 setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
15262 new_ch_no = setChannelSwitch_param->new_ch_no;
15264 rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15266 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
15268 DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
15269 SelectChannel(padapter, new_ch_no);
15271 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15273 rtw_disassoc_cmd(padapter, 0, _FALSE);
15274 rtw_indicate_disconnect(padapter, 0, _FALSE);
15275 rtw_free_assoc_resources(padapter, 1);
15276 rtw_free_network_queue(padapter, _TRUE);
15278 if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
15279 DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
15282 return H2C_SUCCESS;
15284 return H2C_REJECTED;
15285 #endif //CONFIG_DFS
15289 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
15293 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15294 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
15295 #ifdef CONFIG_TDLS_CH_SW
15296 struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
15298 struct TDLSoption_param *TDLSoption;
15299 struct sta_info *ptdls_sta = NULL;
15300 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15301 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
15302 u8 survey_channel, i, min, option;
15303 struct tdls_txmgmt txmgmt;
15304 u32 setchtime, resp_sleep = 0, wait_time;
15305 u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15310 return H2C_PARAMETERS_ERROR;
15312 TDLSoption = (struct TDLSoption_param *)pbuf;
15313 option = TDLSoption->option;
15315 if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
15316 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
15317 if (ptdls_sta == NULL) {
15318 return H2C_REJECTED;
15321 if (!(option == TDLS_RS_RCR))
15322 return H2C_REJECTED;
15325 //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15326 //DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
15329 case TDLS_ESTABLISHED:
15331 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
15332 /* So we can receive all kinds of data frames. */
15335 //leave ALL PS when TDLS is established
15336 rtw_pwr_wakeup(padapter);
15338 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
15339 DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
15341 /* Set TDLS sta rate. */
15342 /* Update station supportRate */
15343 rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
15344 if (pmlmeext->cur_channel > 14) {
15345 if (ptdls_sta->ra_mask & 0xffff000)
15346 sta_band |= WIRELESS_11_5N ;
15348 if (ptdls_sta->ra_mask & 0xff0)
15349 sta_band |= WIRELESS_11A;
15352 #ifdef CONFIG_80211AC_VHT
15353 if (ptdls_sta->vhtpriv.vht_option)
15354 sta_band = WIRELESS_11_5AC;
15358 if (ptdls_sta->ra_mask & 0xffff000)
15359 sta_band |= WIRELESS_11_24N;
15361 if (ptdls_sta->ra_mask & 0xff0)
15362 sta_band |= WIRELESS_11G;
15364 if (ptdls_sta->ra_mask & 0x0f)
15365 sta_band |= WIRELESS_11B;
15367 ptdls_sta->wireless_mode = sta_band;
15368 ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta);
15369 set_sta_rate(padapter, ptdls_sta);
15370 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
15372 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE);
15375 case TDLS_ISSUE_PTI:
15376 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
15377 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
15378 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
15380 #ifdef CONFIG_TDLS_CH_SW
15381 case TDLS_CH_SW_RESP:
15382 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15383 txmgmt.status_code = 0;
15384 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15386 issue_nulldata(padapter, NULL, 1, 3, 3);
15388 DBG_871X("[TDLS ] issue tdls channel switch response\n");
15389 ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
15391 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
15392 /* then we just SelectChannel to AP's channel*/
15393 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
15394 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
15398 if (ret == _SUCCESS)
15399 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_OFF_CHNL);
15401 DBG_871X("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
15404 case TDLS_CH_SW_PREPARE:
15405 pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
15407 /* to collect IQK info of off-chnl */
15409 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15410 set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
15412 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15414 /* switch back to base-chnl */
15415 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
15417 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
15419 pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
15422 case TDLS_CH_SW_START:
15423 rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
15425 case TDLS_CH_SW_TO_OFF_CHNL:
15426 issue_nulldata(padapter, NULL, 1, 3, 3);
15428 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15429 _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) / 1000);
15431 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num,
15432 pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
15433 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15434 if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
15435 if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 1, 3) == _FAIL)
15436 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15441 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15442 _cancel_timer(&ptdls_sta->ch_sw_timer, &bcancelled);
15447 case TDLS_CH_SW_END:
15448 case TDLS_CH_SW_END_TO_BASE_CHNL:
15449 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15450 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
15451 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
15452 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
15454 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
15455 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
15458 if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
15459 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15462 case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
15463 case TDLS_CH_SW_TO_BASE_CHNL:
15464 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
15466 if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
15467 if (ptdls_sta != NULL) {
15468 /* Send unsolicited channel switch rsp. to peer */
15469 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15470 txmgmt.status_code = 0;
15471 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15472 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
15476 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel,
15477 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
15478 issue_nulldata(padapter, NULL, 0, 3, 3);
15479 /* set ch sw monitor timer for responder */
15480 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15481 _set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
15487 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
15488 DBG_871X("[TDLS] write REG_RCR, set bit6 on\n");
15490 case TDLS_TEARDOWN_STA:
15491 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15492 txmgmt.status_code = 0;
15493 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15495 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
15497 case TDLS_TEARDOWN_STA_LOCALLY:
15498 #ifdef CONFIG_TDLS_CH_SW
15499 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
15500 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
15501 TDLS_CH_SWITCH_ON_STATE |
15502 TDLS_PEER_AT_OFF_STATE);
15503 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15504 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
15507 rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
15508 free_tdls_sta(padapter, ptdls_sta);
15512 //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15514 return H2C_SUCCESS;
15516 return H2C_REJECTED;
15517 #endif /* CONFIG_TDLS */
15521 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
15523 struct RunInThread_param *p;
15527 return H2C_PARAMETERS_ERROR;
15528 p = (struct RunInThread_param*)pbuf;
15531 p->func(p->context);
15533 return H2C_SUCCESS;
15536 u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf)
15539 struct readMAC_parm *preadmacparm = NULL;
15545 return H2C_PARAMETERS_ERROR;
15547 preadmacparm = (struct readMAC_parm *) pbuf;
15548 sz = preadmacparm->len;
15549 addr = preadmacparm->addr;
15554 value = rtw_read8(padapter, addr);
15557 value = rtw_read16(padapter, addr);
15560 value = rtw_read32(padapter, addr);
15563 DBG_871X("%s: Unknown size\n", __func__);
15566 DBG_871X("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value);
15568 return H2C_SUCCESS;