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);
896 if (!rtw_is_channel_plan_valid(ChannelPlan)) {
897 DBG_871X_LEVEL(_drv_err_, "ChannelPlan ID 0x%02X error !!!!!\n", ChannelPlan);
901 _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
903 if (IsSupported24G(padapter->registrypriv.wireless_mode))
906 if (IsSupported5G(padapter->registrypriv.wireless_mode))
910 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
911 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
913 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
915 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
916 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
918 if (RTW_CHPLAN_GLOBAL_DOAMIN == ChannelPlan
919 || RTW_CHPLAN_GLOBAL_NULL == ChannelPlan
921 /* Channel 1~11 is active, and 12~14 is passive */
922 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
923 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
924 else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
925 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
926 } else if (RTW_CHPLAN_WORLD_WIDE_13 == ChannelPlan
927 || RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan
928 || RTW_RD_2G_WORLD == Index2G
930 /* channel 12~13, passive scan */
931 if(channel_set[chanset_size].ChannelNum <= 11)
932 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
934 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
936 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
944 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
945 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
947 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
949 for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) {
951 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
952 if ( channel_set[chanset_size].ChannelNum <= 48
953 || channel_set[chanset_size].ChannelNum >= 149 )
955 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
956 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
958 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
962 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
965 #else /* CONFIG_DFS */
966 if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
967 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149
969 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
970 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
971 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
973 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
974 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
977 #endif /* CONFIG_DFS */
981 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) {
982 hal_data->Regulation2_4G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
983 hal_data->Regulation5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
985 hal_data->Regulation2_4G = RTW_ChannelPlanMap[ChannelPlan].regd;
986 hal_data->Regulation5G = RTW_ChannelPlanMap[ChannelPlan].regd;
989 DBG_871X(FUNC_ADPT_FMT" ChannelPlan ID:0x%02x, ch num:%d\n"
990 , FUNC_ADPT_ARG(padapter), ChannelPlan, chanset_size);
995 int init_mlme_ext_priv(_adapter* padapter)
998 struct registry_priv* pregistrypriv = &padapter->registrypriv;
999 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1000 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1001 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1003 // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
1004 //_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
1006 pmlmeext->padapter = padapter;
1008 //fill_fwpriv(padapter, &(pmlmeext->fwpriv));
1010 init_mlme_ext_priv_value(padapter);
1011 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1013 init_mlme_ext_timer(padapter);
1015 #ifdef CONFIG_AP_MODE
1016 init_mlme_ap_info(padapter);
1019 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
1020 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
1021 pmlmeext->last_scan_time = 0;
1022 pmlmeext->mlmeext_init = _TRUE;
1025 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
1026 pmlmeext->active_keep_alive_check = _TRUE;
1028 pmlmeext->active_keep_alive_check = _FALSE;
1031 #ifdef DBG_FIXED_CHAN
1032 pmlmeext->fixed_chan = 0xFF;
1039 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
1041 _adapter *padapter = pmlmeext->padapter;
1046 if (rtw_is_drv_stopped(padapter)) {
1047 _cancel_timer_ex(&pmlmeext->survey_timer);
1048 _cancel_timer_ex(&pmlmeext->link_timer);
1049 //_cancel_timer_ex(&pmlmeext->ADDBA_timer);
1053 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
1054 { // if the channel is same, return 0. else return channel differential
1058 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
1062 if(padapter->mlmeextpriv.cur_channel >= channel)
1064 return (padapter->mlmeextpriv.cur_channel - channel);
1068 return (channel-padapter->mlmeextpriv.cur_channel);
1077 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1079 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1080 u8 *pframe = precv_frame->u.hdr.rx_data;
1084 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1085 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1086 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1091 ptable->func(padapter, precv_frame);
1096 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1099 struct mlme_handler *ptable;
1100 #ifdef CONFIG_AP_MODE
1101 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1102 #endif //CONFIG_AP_MODE
1103 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
1104 u8 *pframe = precv_frame->u.hdr.rx_data;
1105 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
1106 struct dvobj_priv *psdpriv = padapter->dvobj;
1107 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1109 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1110 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
1111 GetFrameType(pframe), GetFrameSubType(pframe)));
1116 pbuf = GetAddr1Ptr(pframe);
1117 DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1118 pbuf = GetAddr2Ptr(pframe);
1119 DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1120 pbuf = GetAddr3Ptr(pframe);
1121 DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
1125 if (GetFrameType(pframe) != WIFI_MGT_TYPE)
1127 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
1131 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
1132 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1133 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1138 ptable = mlme_sta_tbl;
1140 index = GetFrameSubType(pframe) >> 4;
1143 if((index << 4)==WIFI_ACTION){
1144 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1145 if (*(pframe+24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe+25) == TDLS_DISCOVERY_RESPONSE) {
1146 DBG_871X("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(GetAddr2Ptr(pframe)));
1147 On_TDLS_Dis_Rsp(padapter, precv_frame);
1150 #endif //CONFIG_TDLS
1152 if (index >= (sizeof(mlme_sta_tbl) /sizeof(struct mlme_handler)))
1154 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
1162 if (GetRetry(pframe))
1164 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
1166 /* drop the duplicate management frame */
1167 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
1168 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1172 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1176 if(GetRetry(pframe))
1178 //RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
1183 #ifdef CONFIG_AP_MODE
1184 switch (GetFrameSubType(pframe))
1187 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1188 ptable->func = &OnAuth;
1190 ptable->func = &OnAuthClient;
1193 case WIFI_REASSOCREQ:
1194 _mgt_dispatcher(padapter, ptable, precv_frame);
1195 #ifdef CONFIG_HOSTAPD_MLME
1196 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1197 rtw_hostapd_mlme_rx(padapter, precv_frame);
1201 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1203 #ifdef CONFIG_HOSTAPD_MLME
1204 rtw_hostapd_mlme_rx(padapter, precv_frame);
1206 _mgt_dispatcher(padapter, ptable, precv_frame);
1210 _mgt_dispatcher(padapter, ptable, precv_frame);
1213 _mgt_dispatcher(padapter, ptable, precv_frame);
1216 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1217 _mgt_dispatcher(padapter, ptable, precv_frame);
1220 _mgt_dispatcher(padapter, ptable, precv_frame);
1221 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1222 rtw_hostapd_mlme_rx(padapter, precv_frame);
1227 _mgt_dispatcher(padapter, ptable, precv_frame);
1234 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1236 bool response = _TRUE;
1238 #ifdef CONFIG_IOCTL_CFG80211
1239 if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
1241 if(padapter->cfg80211_wdinfo.is_ro_ch == _FALSE
1242 || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1243 || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1244 || padapter->mlmepriv.wps_probe_resp_ie == NULL
1245 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
1248 #ifdef CONFIG_DEBUG_CFG80211
1249 DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p, ",
1250 adapter_wdev_data(padapter)->p2p_enabled,
1251 padapter->mlmepriv.wps_probe_resp_ie,
1252 padapter->mlmepriv.p2p_probe_resp_ie);
1253 DBG_871X("is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n",
1254 padapter->cfg80211_wdinfo.is_ro_ch,
1255 rtw_get_oper_ch(padapter),
1256 padapter->wdinfo.listen_channel);
1262 #endif //CONFIG_IOCTL_CFG80211
1263 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1265 // do nothing if the device name is empty
1266 if ( !padapter->wdinfo.device_name_len )
1272 if (response == _TRUE)
1273 issue_probersp_p2p( padapter, da);
1280 /****************************************************************************
1282 Following are the callback functions for each subtype of the management frames
1284 *****************************************************************************/
1286 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1290 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1291 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1292 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1293 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1294 u8 *pframe = precv_frame->u.hdr.rx_data;
1295 uint len = precv_frame->u.hdr.len;
1296 u8 is_valid_p2p_probereq = _FALSE;
1298 #ifdef CONFIG_ATMEL_RC_PATCH
1299 u8 *target_ie=NULL, *wps_ie=NULL;
1301 uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1302 struct sta_info *psta;
1303 struct sta_priv *pstapriv = &padapter->stapriv;
1308 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1309 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1310 u8 wifi_test_chk_rate = 1;
1312 #ifdef CONFIG_IOCTL_CFG80211
1313 if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1314 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1315 && (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1317 rtw_cfg80211_rx_probe_request(padapter, pframe, len);
1320 #endif /* CONFIG_IOCTL_CFG80211 */
1322 if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1323 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
1324 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1325 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1326 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1329 // Commented by Albert 2011/03/17
1330 // mcs_rate = 0 -> CCK 1M rate
1331 // mcs_rate = 1 -> CCK 2M rate
1332 // mcs_rate = 2 -> CCK 5.5M rate
1333 // mcs_rate = 3 -> CCK 11M rate
1334 // In the P2P mode, the driver should not support the CCK rate
1336 // Commented by Kurt 2012/10/16
1337 // IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
1338 if (padapter->registrypriv.wifi_spec == 1)
1340 if ( pattrib->data_rate <= 3 )
1342 wifi_test_chk_rate = 0;
1346 if( wifi_test_chk_rate == 1 )
1348 if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
1350 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
1353 if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
1354 report_survey_event(padapter, precv_frame);
1356 p2p_listen_state_process( padapter, get_sa(pframe));
1361 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1372 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1377 if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
1378 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
1384 //DBG_871X("+OnProbeReq\n");
1387 #ifdef CONFIG_ATMEL_RC_PATCH
1388 if ((wps_ie = rtw_get_wps_ie(
1389 pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1390 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1391 NULL, &wps_ielen))) {
1393 target_ie = rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1395 if ((target_ie && (target_ielen == 4)) && (_TRUE ==_rtw_memcmp((void *)target_ie, "Ozmo",4 ))) {
1396 //psta->flag_atmel_rc = 1;
1397 unsigned char *sa_addr = get_sa(pframe);
1398 printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n",
1399 __func__, *sa_addr, *(sa_addr+1), *(sa_addr+2), *(sa_addr+3), *(sa_addr+4), *(sa_addr+5));
1400 _rtw_memcpy( pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1405 #ifdef CONFIG_AUTO_AP_MODE
1406 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1407 pmlmepriv->cur_network.join_res == _TRUE)
1410 struct sta_info *psta;
1411 u8 *mac_addr, *peer_addr;
1412 struct sta_priv *pstapriv = &padapter->stapriv;
1413 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
1414 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
1416 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1417 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1419 if(!p || ielen !=14)
1420 goto _non_rc_device;
1422 if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
1423 goto _non_rc_device;
1425 if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
1427 DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1428 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
1430 goto _non_rc_device;
1433 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
1436 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1439 // allocate a new one
1440 DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
1441 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1445 DBG_871X(" Exceed the upper limit of supported clients...\n");
1449 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1450 if (rtw_is_list_empty(&psta->asoc_list))
1452 psta->expire_to = pstapriv->expire_to;
1453 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1454 pstapriv->asoc_list_cnt++;
1456 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1458 //generate pairing ID
1459 mac_addr = adapter_mac_addr(padapter);
1460 peer_addr = psta->hwaddr;
1461 psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
1463 //update peer stainfo
1468 /* get a unique AID */
1469 if (psta->aid > 0) {
1470 DBG_871X("old AID %d\n", psta->aid);
1472 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1473 if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1476 if (psta->aid > pstapriv->max_num_sta) {
1478 DBG_871X("no room for more AIDs\n");
1481 pstapriv->sta_aid[psta->aid - 1] = psta;
1482 DBG_871X("allocate new AID = (%d)\n", psta->aid);
1486 psta->qos_option = 1;
1487 psta->bw_mode = CHANNEL_WIDTH_20;
1488 psta->ieee8021x_blocked = _FALSE;
1489 #ifdef CONFIG_80211N_HT
1490 psta->htpriv.ht_option = _TRUE;
1491 psta->htpriv.ampdu_enable = _FALSE;
1492 psta->htpriv.sgi_20m = _FALSE;
1493 psta->htpriv.sgi_40m = _FALSE;
1494 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1495 psta->htpriv.agg_enable_bitmap = 0x0;//reset
1496 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
1499 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1501 _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1503 _enter_critical_bh(&psta->lock, &irqL);
1504 psta->state |= _FW_LINKED;
1505 _exit_critical_bh(&psta->lock, &irqL);
1507 report_add_sta_event(padapter, psta->hwaddr);
1511 issue_probersp(padapter, get_sa(pframe), _FALSE);
1521 #endif //CONFIG_AUTO_AP_MODE
1524 #ifdef CONFIG_CONCURRENT_MODE
1525 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1526 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1528 //don't process probe req
1533 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1534 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1537 //check (wildcard) SSID
1540 if(is_valid_p2p_probereq == _TRUE)
1542 goto _issue_probersp;
1545 if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1546 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1553 if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1554 pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1556 //DBG_871X("+issue_probersp during ap mode\n");
1557 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
1566 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1568 struct sta_info *psta;
1569 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1570 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1571 struct sta_priv *pstapriv = &padapter->stapriv;
1572 u8 *pframe = precv_frame->u.hdr.rx_data;
1574 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1579 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
1581 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
1583 if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1585 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
1587 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1588 issue_p2p_provision_request( padapter,
1589 pwdinfo->tx_prov_disc_info.ssid.Ssid,
1590 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1591 pwdinfo->tx_prov_disc_info.peerDevAddr );
1593 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
1595 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1596 issue_p2p_provision_request( padapter,
1599 pwdinfo->tx_prov_disc_info.peerDevAddr );
1605 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
1607 if ( _TRUE == pwdinfo->nego_req_info.benable )
1609 DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
1610 if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1612 pwdinfo->nego_req_info.benable = _FALSE;
1613 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
1617 else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
1619 if ( _TRUE == pwdinfo->invitereq_info.benable )
1621 DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
1622 if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
1624 pwdinfo->invitereq_info.benable = _FALSE;
1625 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
1632 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1633 report_survey_event(padapter, precv_frame);
1634 #ifdef CONFIG_CONCURRENT_MODE
1635 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1640 #if 0 //move to validate_recv_mgnt_frame
1641 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1643 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1645 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1647 psta->sta_stats.rx_mgnt_pkts++;
1657 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1659 struct sta_info *psta;
1660 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1661 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1662 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1663 struct sta_priv *pstapriv = &padapter->stapriv;
1664 u8 *pframe = precv_frame->u.hdr.rx_data;
1665 uint len = precv_frame->u.hdr.len;
1666 WLAN_BSSID_EX *pbss;
1671 struct sta_info *ptdls_sta;
1672 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1673 #ifdef CONFIG_TDLS_CH_SW
1674 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
1676 #endif /* CONFIG_TDLS */
1678 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1679 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_);
1680 if ((p != NULL) && (ielen > 0))
1682 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
1684 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
1685 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)));
1686 *(p + 1) = ielen - 1;
1691 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1692 report_survey_event(padapter, precv_frame);
1693 #ifdef CONFIG_CONCURRENT_MODE
1694 report_survey_event(padapter->pbuddy_adapter, precv_frame);
1699 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1701 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1703 //we should update current network before auth, or some IE is wrong
1704 pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1706 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1707 struct beacon_keys recv_beacon;
1709 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1710 rtw_get_bcn_info(&(pmlmepriv->cur_network));
1713 if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1714 DBG_871X("%s: beacon keys ready\n", __func__);
1715 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1716 &recv_beacon, sizeof(recv_beacon));
1717 pmlmepriv->new_beacon_cnts = 0;
1720 DBG_871X_LEVEL(_drv_err_, "%s: get beacon keys failed\n", __func__);
1721 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1722 pmlmepriv->new_beacon_cnts = 0;
1725 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1728 //check the vendor of the assoc AP
1729 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
1732 update_TSF(pmlmeext, pframe, len);
1734 //reset for adaptive_early_32k
1735 pmlmeext->adaptive_tsf_done = _FALSE;
1736 pmlmeext->DrvBcnEarly = 0xff;
1737 pmlmeext->DrvBcnTimeOut = 0xff;
1738 pmlmeext->bcn_cnt = 0;
1739 _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1740 _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1742 #ifdef CONFIG_P2P_PS
1743 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1744 #endif //CONFIG_P2P_PS
1746 #if defined(CONFIG_P2P)&&defined(CONFIG_CONCURRENT_MODE)
1747 if (padapter->registrypriv.wifi_spec) {
1748 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1749 if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE) {
1750 DBG_871X_LEVEL(_drv_always_, "no issue auth, P2P cross-connect does not permit\n ");
1755 #endif // CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE
1758 start_clnt_auth(padapter);
1763 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1765 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1767 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1768 //Merge from 8712 FW code
1769 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
1770 { // join wrong channel, deauth and reconnect
1771 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1773 report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE);
1774 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1777 #endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
1779 ret = rtw_check_bcn_info(padapter, pframe, len);
1781 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1782 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0);
1785 //update WMM, ERP in the beacon
1786 //todo: the timer is used instead of the number of the beacon received
1787 if ((sta_rx_pkts(psta) & 0xf) == 0)
1789 //DBG_871X("update_bcn_info\n");
1790 update_beacon_info(padapter, pframe, len, psta);
1793 adaptive_early_32k(pmlmeext, pframe, len);
1796 #ifdef CONFIG_TDLS_CH_SW
1797 if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE)
1799 /* Send TDLS Channel Switch Request when receiving Beacon */
1800 if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
1801 && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1802 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1803 if (ptdls_sta != NULL) {
1804 if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE) {
1805 _set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
1811 #endif /* CONFIG_TDLS */
1814 process_csa_ie(padapter, pframe, len); //channel switch announcement
1817 #ifdef CONFIG_P2P_PS
1818 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1819 #endif //CONFIG_P2P_PS
1821 if (pmlmeext->en_hw_update_tsf)
1822 rtw_enable_hw_update_tsf_cmd(padapter);
1824 #if 0 //move to validate_recv_mgnt_frame
1825 psta->sta_stats.rx_mgnt_pkts++;
1829 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
1834 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1837 * update WMM, ERP in the beacon
1838 * todo: the timer is used instead of the number of the beacon received
1840 if ((sta_rx_pkts(psta) & 0xf) == 0)
1841 update_beacon_info(padapter, pframe, len, psta);
1843 if (pmlmeext->en_hw_update_tsf)
1844 rtw_enable_hw_update_tsf_cmd(padapter);
1847 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);
1848 if (rate_num == 0) {
1849 DBG_871X(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
1850 goto _END_ONBEACON_;
1853 psta = rtw_alloc_stainfo(pstapriv, GetAddr2Ptr(pframe));
1855 DBG_871X(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
1856 goto _END_ONBEACON_;
1859 psta->expire_to = pstapriv->adhoc_expire_to;
1861 _rtw_memcpy(psta->bssrateset, rate_set, rate_num);
1862 psta->bssratelen = rate_num;
1865 update_TSF(pmlmeext, pframe, len);
1867 //report sta add event
1868 report_add_sta_event(padapter, GetAddr2Ptr(pframe));
1879 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1881 #ifdef CONFIG_AP_MODE
1883 unsigned int auth_mode, seq, ie_len;
1884 unsigned char *sa, *p;
1887 static struct sta_info stat;
1888 struct sta_info *pstat=NULL;
1889 struct sta_priv *pstapriv = &padapter->stapriv;
1890 struct security_priv *psecuritypriv = &padapter->securitypriv;
1891 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1892 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1893 u8 *pframe = precv_frame->u.hdr.rx_data;
1894 uint len = precv_frame->u.hdr.len;
1898 #ifdef CONFIG_CONCURRENT_MODE
1899 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1900 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1902 //don't process auth request;
1905 #endif //CONFIG_CONCURRENT_MODE
1907 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1910 DBG_871X("+OnAuth\n");
1912 sa = GetAddr2Ptr(pframe);
1914 auth_mode = psecuritypriv->dot11AuthAlgrthm;
1916 if (GetPrivacy(pframe))
1919 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
1921 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
1922 prxattrib->encrypt = _WEP40_;
1924 iv = pframe+prxattrib->hdrlen;
1925 prxattrib->key_index = ((iv[3]>>6)&0x3);
1927 prxattrib->iv_len = 4;
1928 prxattrib->icv_len = 4;
1930 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
1935 algorithm = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
1936 seq = le16_to_cpu(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
1938 DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
1940 if (auth_mode == 2 &&
1941 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1942 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1945 if ((algorithm > 0 && auth_mode == 0) || // rx a shared-key auth but shared not enabled
1946 (algorithm == 0 && auth_mode == 1) ) // rx a open-system auth but shared-key is enabled
1948 DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1949 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1951 status = _STATS_NO_SUPP_ALG_;
1957 phead = &priv->wlan_acl_list;
1958 plist = phead->next;
1960 if (acl_mode == 1) // 1: positive check, only those on acl_list can be connected.
1965 while(plist != phead)
1967 paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
1968 plist = plist->next;
1969 if (!memcmp((void *)sa, paclnode->addr, 6)) {
1970 if (paclnode->mode & 2) { // deny
1981 if (res != SUCCESS) {
1982 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
1986 if(rtw_access_ctrl(padapter, sa) == _FALSE)
1988 status = _STATS_UNABLE_HANDLE_STA_;
1993 pstat = rtw_get_stainfo(pstapriv, sa);
1997 // allocate a new one
1998 DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
1999 pstat = rtw_alloc_stainfo(pstapriv, sa);
2002 DBG_871X(" Exceed the upper limit of supported clients...\n");
2003 status = _STATS_UNABLE_HANDLE_STA_;
2007 pstat->state = WIFI_FW_AUTH_NULL;
2008 pstat->auth_seq = 0;
2011 //pstat->capability = 0;
2013 #ifdef CONFIG_IEEE80211W
2014 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2015 #endif /* CONFIG_IEEE80211W */
2018 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2019 if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
2020 rtw_list_delete(&pstat->asoc_list);
2021 pstapriv->asoc_list_cnt--;
2022 if (pstat->expire_to > 0)
2023 ;/* TODO: STA re_auth within expire_to */
2025 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2028 ; /* TODO: STA re_auth and auth timeout */
2033 #ifdef CONFIG_IEEE80211W
2034 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2035 #endif /* CONFIG_IEEE80211W */
2037 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2038 if (rtw_is_list_empty(&pstat->auth_list)) {
2040 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2041 pstapriv->auth_list_cnt++;
2043 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2046 if (pstat->auth_seq == 0)
2047 pstat->expire_to = pstapriv->auth_to;
2050 if ((pstat->auth_seq + 1) != seq)
2052 DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2053 seq, pstat->auth_seq+1);
2054 status = _STATS_OUT_OF_AUTH_SEQ_;
2058 if (algorithm==0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3))
2062 #ifdef CONFIG_IEEE80211W
2063 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2064 #endif /* CONFIG_IEEE80211W */
2066 pstat->state &= ~WIFI_FW_AUTH_NULL;
2067 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2068 pstat->expire_to = pstapriv->assoc_to;
2070 pstat->authalg = algorithm;
2074 DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2075 seq, pstat->auth_seq+1);
2076 status = _STATS_OUT_OF_AUTH_SEQ_;
2080 else // shared system or auto authentication
2084 //prepare for the challenging txt...
2086 //get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
2087 _rtw_memset((void *)pstat->chg_txt, 78, 128);
2088 #ifdef CONFIG_IEEE80211W
2089 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2090 #endif /* CONFIG_IEEE80211W */
2092 pstat->state &= ~WIFI_FW_AUTH_NULL;
2093 pstat->state |= WIFI_FW_AUTH_STATE;
2095 pstat->authalg = algorithm;
2096 pstat->auth_seq = 2;
2100 //checking for challenging txt...
2101 DBG_871X("checking for challenging txt...\n");
2103 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2104 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2106 if((p==NULL) || (ie_len<=0))
2108 DBG_871X("auth rejected because challenge failure!(1)\n");
2109 status = _STATS_CHALLENGE_FAIL_;
2113 if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
2115 #ifdef CONFIG_IEEE80211W
2116 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2117 #endif /* CONFIG_IEEE80211W */
2119 pstat->state &= (~WIFI_FW_AUTH_STATE);
2120 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2121 /* challenging txt is correct... */
2122 pstat->expire_to = pstapriv->assoc_to;
2127 DBG_871X("auth rejected because challenge failure!\n");
2128 status = _STATS_CHALLENGE_FAIL_;
2134 DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2135 seq, pstat->auth_seq+1);
2136 status = _STATS_OUT_OF_AUTH_SEQ_;
2142 // Now, we are going to issue_auth...
2143 pstat->auth_seq = seq + 1;
2145 #ifdef CONFIG_NATIVEAP_MLME
2146 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2149 if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2150 pstat->auth_seq = 0;
2158 rtw_free_stainfo(padapter , pstat);
2161 _rtw_memset((char *)pstat, '\0', sizeof(stat));
2162 pstat->auth_seq = 2;
2163 _rtw_memcpy(pstat->hwaddr, sa, 6);
2165 #ifdef CONFIG_NATIVEAP_MLME
2166 issue_auth(padapter, pstat, (unsigned short)status);
2174 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2176 unsigned int seq, len, status, algthm, offset;
2178 unsigned int go2asoc = 0;
2179 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2180 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2181 u8 *pframe = precv_frame->u.hdr.rx_data;
2182 uint pkt_len = precv_frame->u.hdr.len;
2184 DBG_871X("%s\n", __FUNCTION__);
2186 //check A1 matches or not
2187 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2190 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2193 offset = (GetPrivacy(pframe))? 4: 0;
2195 algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2196 seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2197 status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2201 DBG_871X("clnt auth fail, status: %d\n", status);
2202 if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
2204 if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2205 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2207 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2208 //pmlmeinfo->reauth_count = 0;
2211 set_link_timer(pmlmeext, 1);
2217 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2219 // legendary shared system
2220 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2221 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2225 //DBG_871X("marc: no challenge text?\n");
2229 _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2230 pmlmeinfo->auth_seq = 3;
2231 issue_auth(padapter, NULL, 0);
2232 set_link_timer(pmlmeext, REAUTH_TO);
2244 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2255 // this is also illegal
2256 //DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
2262 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n");
2263 start_clnt_assoc(padapter);
2269 //pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
2275 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2277 #ifdef CONFIG_AP_MODE
2279 u16 capab_info, listen_interval;
2280 struct rtw_ieee802_11_elems elems;
2281 struct sta_info *pstat;
2282 unsigned char reassoc, *p, *pos, *wpa_ie;
2283 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2284 int i, ie_len, wpa_ie_len, left;
2287 unsigned short status = _STATS_SUCCESSFUL_;
2288 unsigned short frame_type, ie_offset=0;
2289 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2290 struct security_priv *psecuritypriv = &padapter->securitypriv;
2291 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2292 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2293 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
2294 struct sta_priv *pstapriv = &padapter->stapriv;
2295 u8 *pframe = precv_frame->u.hdr.rx_data;
2296 uint pkt_len = precv_frame->u.hdr.len;
2298 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2299 u8 p2p_status_code = P2P_STATUS_SUCCESS;
2304 #ifdef CONFIG_CONCURRENT_MODE
2305 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
2306 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
2308 //don't process assoc request;
2311 #endif //CONFIG_CONCURRENT_MODE
2313 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2316 frame_type = GetFrameSubType(pframe);
2317 if (frame_type == WIFI_ASSOCREQ)
2320 ie_offset = _ASOCREQ_IE_OFFSET_;
2322 else // WIFI_REASSOCREQ
2325 ie_offset = _REASOCREQ_IE_OFFSET_;
2329 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2330 DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2331 "\n", reassoc, (unsigned long)pkt_len);
2335 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2336 if (pstat == (struct sta_info *)NULL)
2338 status = _RSON_CLS2_;
2339 goto asoc_class2_error;
2342 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
2343 //capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2344 //listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
2345 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
2347 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2348 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2351 DBG_871X("%s\n", __FUNCTION__);
2353 // check if this stat has been successfully authenticated/assocated
2354 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
2356 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
2358 status = _RSON_CLS2_;
2359 goto asoc_class2_error;
2363 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2364 pstat->state |= WIFI_FW_ASSOC_STATE;
2369 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2370 pstat->state |= WIFI_FW_ASSOC_STATE;
2374 #if 0// todo:tkip_countermeasures
2375 if (hapd->tkip_countermeasures) {
2376 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2381 pstat->capability = capab_info;
2384 //check listen_interval
2385 if (listen_interval > hapd->conf->max_listen_interval) {
2386 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2387 HOSTAPD_LEVEL_DEBUG,
2388 "Too large Listen Interval (%d)",
2390 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2394 pstat->listen_interval = listen_interval;
2397 //now parse all ieee802_11 ie to point to elems
2398 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2400 DBG_871X("STA " MAC_FMT " sent invalid association request\n",
2401 MAC_ARG(pstat->hwaddr));
2402 status = _STATS_FAILURE_;
2403 goto OnAssocReqFail;
2407 // now we should check all the fields...
2409 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2410 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2413 status = _STATS_FAILURE_;
2416 if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
2417 status = _STATS_FAILURE_;
2420 // check if ssid match
2421 if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2422 status = _STATS_FAILURE_;
2424 if (ie_len != cur->Ssid.SsidLength)
2425 status = _STATS_FAILURE_;
2428 if(_STATS_SUCCESSFUL_ != status)
2429 goto OnAssocReqFail;
2431 rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, rate_set, &rate_num);
2432 if (rate_num == 0) {
2433 DBG_871X(FUNC_ADPT_FMT" RX assoc-req with no supported rate\n", FUNC_ADPT_ARG(padapter));
2434 status = _STATS_FAILURE_;
2435 goto OnAssocReqFail;
2437 _rtw_memcpy(pstat->bssrateset, rate_set, rate_num);
2438 pstat->bssratelen = rate_num;
2439 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2442 pstat->dot8021xalg = 0;
2444 pstat->wpa_group_cipher = 0;
2445 pstat->wpa2_group_cipher = 0;
2446 pstat->wpa_pairwise_cipher = 0;
2447 pstat->wpa2_pairwise_cipher = 0;
2448 _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2449 if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2451 int group_cipher=0, pairwise_cipher=0;
2453 wpa_ie = elems.rsn_ie;
2454 wpa_ie_len = elems.rsn_ie_len;
2456 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2458 pstat->dot8021xalg = 1;//psk, todo:802.1x
2459 pstat->wpa_psk |= BIT(1);
2461 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
2462 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
2464 if(!pstat->wpa2_group_cipher)
2465 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2467 if(!pstat->wpa2_pairwise_cipher)
2468 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2472 status = WLAN_STATUS_INVALID_IE;
2475 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2477 int group_cipher=0, pairwise_cipher=0;
2479 wpa_ie = elems.wpa_ie;
2480 wpa_ie_len = elems.wpa_ie_len;
2482 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2484 pstat->dot8021xalg = 1;//psk, todo:802.1x
2485 pstat->wpa_psk |= BIT(0);
2487 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
2488 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
2490 if(!pstat->wpa_group_cipher)
2491 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2493 if(!pstat->wpa_pairwise_cipher)
2494 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2499 status = WLAN_STATUS_INVALID_IE;
2507 if(_STATS_SUCCESSFUL_ != status)
2508 goto OnAssocReqFail;
2510 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2511 //if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
2512 if(wpa_ie == NULL) {
2514 DBG_871X("STA included WPS IE in "
2515 "(Re)Association Request - assume WPS is "
2517 pstat->flags |= WLAN_STA_WPS;
2518 //wpabuf_free(sta->wps_ie);
2519 //sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
2520 // elems.wps_ie_len - 4);
2522 DBG_871X("STA did not include WPA/RSN IE "
2523 "in (Re)Association Request - possible WPS "
2525 pstat->flags |= WLAN_STA_MAYBE_WPS;
2529 // AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
2530 // that the selected registrar of AP is _FLASE
2531 if((psecuritypriv->wpa_psk >0)
2532 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
2534 if(pmlmepriv->wps_beacon_ie)
2536 u8 selected_registrar = 0;
2538 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2540 if(!selected_registrar)
2542 DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2544 status = _STATS_UNABLE_HANDLE_STA_;
2546 goto OnAssocReqFail;
2556 if(psecuritypriv->wpa_psk == 0)
2558 DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
2559 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2561 status = WLAN_STATUS_INVALID_IE;
2563 goto OnAssocReqFail;
2568 DBG_871X("STA included WPS IE in "
2569 "(Re)Association Request - WPS is "
2571 pstat->flags |= WLAN_STA_WPS;
2576 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
2581 _rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
2586 // check if there is WMM IE & support WWM-PS
2587 pstat->flags &= ~WLAN_STA_WME;
2588 pstat->qos_option = 0;
2589 pstat->qos_info = 0;
2590 pstat->has_legacy_ac = _TRUE;
2591 pstat->uapsd_vo = 0;
2592 pstat->uapsd_vi = 0;
2593 pstat->uapsd_be = 0;
2594 pstat->uapsd_bk = 0;
2595 if (pmlmepriv->qospriv.qos_option)
2597 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
2600 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2602 if (_rtw_memcmp(p+2, WMM_IE, 6)) {
2604 pstat->flags |= WLAN_STA_WME;
2606 pstat->qos_option = 1;
2607 pstat->qos_info = *(p+8);
2609 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
2611 if((pstat->qos_info&0xf) !=0xf)
2612 pstat->has_legacy_ac = _TRUE;
2614 pstat->has_legacy_ac = _FALSE;
2616 if(pstat->qos_info&0xf)
2618 if(pstat->qos_info&BIT(0))
2619 pstat->uapsd_vo = BIT(0)|BIT(1);
2621 pstat->uapsd_vo = 0;
2623 if(pstat->qos_info&BIT(1))
2624 pstat->uapsd_vi = BIT(0)|BIT(1);
2626 pstat->uapsd_vi = 0;
2628 if(pstat->qos_info&BIT(2))
2629 pstat->uapsd_bk = BIT(0)|BIT(1);
2631 pstat->uapsd_bk = 0;
2633 if(pstat->qos_info&BIT(3))
2634 pstat->uapsd_be = BIT(0)|BIT(1);
2636 pstat->uapsd_be = 0;
2651 #ifdef CONFIG_80211N_HT
2652 if (pmlmepriv->htpriv.ht_option == _FALSE)
2655 /* save HT capabilities in the sta object */
2656 _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2657 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
2659 pstat->flags |= WLAN_STA_HT;
2661 pstat->flags |= WLAN_STA_WME;
2663 _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
2666 pstat->flags &= ~WLAN_STA_HT;
2669 if ((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT)) {
2671 status = _STATS_FAILURE_;
2672 goto OnAssocReqFail;
2674 #endif /* CONFIG_80211N_HT */
2676 #ifdef CONFIG_80211AC_VHT
2677 if (pmlmepriv->vhtpriv.vht_option == _FALSE)
2678 goto bypass_vht_chk;
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;
2699 if ((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags&WLAN_STA_VHT)) {
2701 status = _STATS_FAILURE_;
2702 goto OnAssocReqFail;
2704 #endif /* CONFIG_80211AC_VHT */
2706 if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
2707 ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
2708 (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2710 DBG_871X("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr));
2712 pstat->flags &= ~WLAN_STA_HT;
2713 pstat->flags &= ~WLAN_STA_VHT;
2714 /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2715 * goto OnAssocReqFail;
2721 //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
2722 pstat->flags |= WLAN_STA_NONERP;
2723 for (i = 0; i < pstat->bssratelen; i++) {
2724 if ((pstat->bssrateset[i] & 0x7f) > 22) {
2725 pstat->flags &= ~WLAN_STA_NONERP;
2730 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2731 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2733 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2737 if (status != _STATS_SUCCESSFUL_)
2738 goto OnAssocReqFail;
2741 pstat->is_p2p_device = _FALSE;
2742 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2744 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
2746 pstat->is_p2p_device = _TRUE;
2747 if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
2749 pstat->p2p_status_code = p2p_status_code;
2750 status = _STATS_CAP_FAIL_;
2751 goto OnAssocReqFail;
2755 rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
2758 pstat->p2p_status_code = p2p_status_code;
2761 //TODO: identify_proprietary_vendor_ie();
2762 // Realtek proprietary IE
2763 // identify if this is Broadcom sta
2764 // identify if this is ralink sta
2765 // Customer proprietary IE
2769 /* get a unique AID */
2770 if (pstat->aid > 0) {
2771 DBG_871X(" old AID %d\n", pstat->aid);
2773 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2774 if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2775 if (pstat->aid > pstapriv->max_num_sta) {
2778 DBG_871X(" no room for more AIDs\n");
2780 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2782 goto OnAssocReqFail;
2786 pstapriv->sta_aid[pstat->aid - 1] = pstat;
2787 DBG_871X("allocate new AID = (%d)\n", pstat->aid);
2795 pstat->state &= (~WIFI_FW_ASSOC_STATE);
2796 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2797 /* DBG_871X("==================%s, %d, (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2798 , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */
2799 #ifdef CONFIG_IEEE80211W
2800 if (pstat->bpairwise_key_installed != _TRUE)
2801 #endif /* CONFIG_IEEE80211W */
2803 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2804 if (!rtw_is_list_empty(&pstat->auth_list)) {
2805 rtw_list_delete(&pstat->auth_list);
2806 pstapriv->auth_list_cnt--;
2808 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2810 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2811 if (rtw_is_list_empty(&pstat->asoc_list)) {
2812 pstat->expire_to = pstapriv->expire_to;
2813 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2814 pstapriv->asoc_list_cnt++;
2816 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2819 // now the station is qualified to join our BSS...
2820 if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
2822 #ifdef CONFIG_NATIVEAP_MLME
2823 #ifdef CONFIG_IEEE80211W
2824 if (pstat->bpairwise_key_installed != _TRUE)
2825 #endif /* CONFIG_IEEE80211W */
2827 /* .1 bss_cap_update & sta_info_update */
2828 bss_cap_update_on_sta_join(padapter, pstat);
2829 sta_info_update(padapter, pstat);
2831 #ifdef CONFIG_IEEE80211W
2832 if (pstat->bpairwise_key_installed == _TRUE)
2833 status = _STATS_REFUSED_TEMPORARILY_;
2834 #endif /* CONFIG_IEEE80211W */
2835 //.2 issue assoc rsp before notify station join event.
2836 if (frame_type == WIFI_ASSOCREQ)
2837 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2839 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2841 #ifdef CONFIG_IOCTL_CFG80211
2842 _enter_critical_bh(&pstat->lock, &irqL);
2843 if(pstat->passoc_req)
2845 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2846 pstat->passoc_req = NULL;
2847 pstat->assoc_req_len = 0;
2850 pstat->passoc_req = rtw_zmalloc(pkt_len);
2851 if(pstat->passoc_req)
2853 _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2854 pstat->assoc_req_len = pkt_len;
2856 _exit_critical_bh(&pstat->lock, &irqL);
2857 #endif //CONFIG_IOCTL_CFG80211
2858 #ifdef CONFIG_IEEE80211W
2859 if (pstat->bpairwise_key_installed != _TRUE)
2860 #endif /* CONFIG_IEEE80211W */
2862 /* .3-(1) report sta add event */
2863 report_add_sta_event(padapter, pstat->hwaddr);
2865 #ifdef CONFIG_IEEE80211W
2866 if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) {
2867 DBG_871X(MAC_FMT"\n", MAC_ARG(pstat->hwaddr));
2868 issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY);
2870 #endif /* CONFIG_IEEE80211W */
2871 #endif //CONFIG_NATIVEAP_MLME
2878 #ifdef CONFIG_NATIVEAP_MLME
2879 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
2887 #ifdef CONFIG_NATIVEAP_MLME
2889 if (frame_type == WIFI_ASSOCREQ)
2890 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2892 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2896 #endif /* CONFIG_AP_MODE */
2902 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2906 unsigned short status;
2907 PNDIS_802_11_VARIABLE_IEs pIE;
2908 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2909 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2910 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2911 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
2912 u8 *pframe = precv_frame->u.hdr.rx_data;
2913 uint pkt_len = precv_frame->u.hdr.len;
2914 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
2916 DBG_871X("%s\n", __FUNCTION__);
2918 //check A1 matches or not
2919 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2922 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2925 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2928 _cancel_timer_ex(&pmlmeext->link_timer);
2931 if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2933 DBG_871X("assoc reject, status code: %d\n", status);
2934 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2936 goto report_assoc_result;
2940 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2943 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2946 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2948 //following are moved to join event callback function
2949 //to handle HT, WMM, rate adaptive, update MAC reg
2950 //for not to handle the synchronous IO in the tasklet
2951 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2953 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2955 switch (pIE->ElementID)
2957 case _VENDOR_SPECIFIC_IE_:
2958 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) //WMM
2960 WMM_param_handler(padapter, pIE);
2962 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2963 else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4)) //WFD
2965 rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
2970 #ifdef CONFIG_WAPI_SUPPORT
2976 case _HT_CAPABILITY_IE_: //HT caps
2977 HT_caps_handler(padapter, pIE);
2980 case _HT_EXTRA_INFO_IE_: //HT info
2981 HT_info_handler(padapter, pIE);
2984 #ifdef CONFIG_80211AC_VHT
2985 case EID_VHTCapability:
2986 VHT_caps_handler(padapter, pIE);
2989 case EID_VHTOperation:
2990 VHT_operation_handler(padapter, pIE);
2995 ERP_IE_handler(padapter, pIE);
2999 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
3000 padapter->tdlsinfo.ap_prohibited = _TRUE;
3001 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
3002 padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
3004 #endif /* CONFIG_TDLS */
3009 i += (pIE->Length + 2);
3012 #ifdef CONFIG_WAPI_SUPPORT
3013 rtw_wapi_on_assoc_ok(padapter, pIE);
3016 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3017 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3019 //Update Basic Rate Table for spec, 2010-12-28 , by thomas
3020 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3022 report_assoc_result:
3024 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3026 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3029 report_join_res(padapter, res);
3034 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
3036 unsigned short reason;
3037 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3038 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3039 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3040 u8 *pframe = precv_frame->u.hdr.rx_data;
3042 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3046 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3049 DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3052 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3054 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3055 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3059 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3061 rtw_lock_rx_suspend_timeout(8000);
3063 #ifdef CONFIG_AP_MODE
3064 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3067 struct sta_info *psta;
3068 struct sta_priv *pstapriv = &padapter->stapriv;
3070 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3071 //rtw_free_stainfo(padapter, psta);
3072 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3074 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3075 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3077 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3080 u8 updated = _FALSE;
3082 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3083 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3085 rtw_list_delete(&psta->asoc_list);
3086 pstapriv->asoc_list_cnt--;
3087 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3090 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3092 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3101 int ignore_received_deauth = 0;
3103 // Commented by Albert 20130604
3104 // Before sending the auth frame to start the STA/GC mode connection with AP/GO,
3105 // we will send the deauth first.
3106 // However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
3107 // Added the following code to avoid this case.
3108 if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
3109 ( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
3111 if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
3113 ignore_received_deauth = 1;
3114 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3116 ignore_received_deauth = 1;
3120 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3121 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe), ignore_received_deauth);
3123 if ( 0 == ignore_received_deauth )
3125 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3128 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3133 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3135 unsigned short reason;
3136 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3137 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3138 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3139 u8 *pframe = precv_frame->u.hdr.rx_data;
3141 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
3145 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3148 DBG_871X(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3151 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
3153 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
3154 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
3158 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3160 rtw_lock_rx_suspend_timeout(8000);
3162 #ifdef CONFIG_AP_MODE
3163 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3166 struct sta_info *psta;
3167 struct sta_priv *pstapriv = &padapter->stapriv;
3169 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3170 //rtw_free_stainfo(padapter, psta);
3171 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
3173 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3174 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3176 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3179 u8 updated = _FALSE;
3181 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3182 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
3184 rtw_list_delete(&psta->asoc_list);
3185 pstapriv->asoc_list_cnt--;
3186 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3189 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3191 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3199 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3200 , FUNC_ADPT_ARG(padapter), reason, GetAddr2Ptr(pframe));
3202 receive_disconnect(padapter, GetAddr2Ptr(pframe), reason);
3204 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3209 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3211 DBG_871X("%s\n", __FUNCTION__);
3215 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3217 unsigned int ret = _FAIL;
3218 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3219 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
3221 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3226 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3228 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3231 struct ieee80211_info_element *ie;
3233 DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3234 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
3236 for_each_ie(ie, ies, ies_len) {
3237 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3238 ch_switch_mode = ie->data[0];
3240 ch_switch_cnt = ie->data[2];
3241 DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3242 ch_switch_mode, ch, ch_switch_cnt);
3244 else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3245 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3246 DBG_871X("ch_offset:%d\n", ch_offset);
3253 if (ch_offset == -1)
3254 bwmode = mlmeext->cur_bwmode;
3256 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3257 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3259 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3262 * 1. the decision of channel switching
3263 * 2. things after channel switching
3266 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
3273 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3275 unsigned int ret = _FAIL;
3276 struct sta_info *psta = NULL;
3277 struct sta_priv *pstapriv = &padapter->stapriv;
3278 u8 *pframe = precv_frame->u.hdr.rx_data;
3279 uint frame_len = precv_frame->u.hdr.len;
3280 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3284 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3286 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3291 category = frame_body[0];
3292 if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3295 action = frame_body[1];
3297 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3298 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3299 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3300 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3302 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3303 #ifdef CONFIG_SPCT_CH_SWITCH
3304 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
3305 frame_len-(frame_body-pframe)-2);
3316 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3321 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3327 * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3328 * @adapter: the adapter to get target RX AMPDU buffer size
3330 * Returns: the target RX AMPDU buffer size
3332 u8 rtw_rx_ampdu_size(_adapter *adapter)
3335 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3337 if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID) {
3338 size = adapter->fix_rx_ampdu_size;
3342 #ifdef CONFIG_BT_COEXIST
3343 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3344 size = rtw_btcoex_GetAMPDUSize(adapter);
3350 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3351 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3352 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3354 size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3358 /* default value based on max_rx_ampdu_factor */
3359 if (adapter->driver_rx_ampdu_factor != 0xFF)
3360 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3362 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3364 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3366 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3368 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3370 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3384 * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3385 * @adapter: the adapter to get the permission if RX AMPDU should be set up
3387 * Returns: accept or not
3389 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3393 if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3394 accept = adapter->fix_rx_ampdu_accept;
3398 #ifdef CONFIG_BT_COEXIST
3399 if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3406 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3407 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3408 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3410 accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3414 /* default value for other cases */
3415 accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3422 * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3423 * @adapter: the adapter to set target RX AMPDU buffer size
3424 * @size: the target RX AMPDU buffer size to set
3425 * @reason: reason for the target RX AMPDU buffer size setting
3427 * Returns: whether the target RX AMPDU buffer size is changed
3429 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3431 bool is_adj = _FALSE;
3432 struct mlme_ext_priv *mlmeext;
3433 struct mlme_ext_info *mlmeinfo;
3435 mlmeext = &adapter->mlmeextpriv;
3436 mlmeinfo = &mlmeext->mlmext_info;
3438 if (reason == RX_AMPDU_DRV_FIXED) {
3439 if (adapter->fix_rx_ampdu_size != size) {
3440 adapter->fix_rx_ampdu_size = size;
3442 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3444 } else if (reason == RX_AMPDU_DRV_SCAN) {
3445 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3447 if (ss->rx_ampdu_size != size) {
3448 ss->rx_ampdu_size = size;
3450 DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3458 * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3459 * @adapter: the adapter to set if RX AMPDU should be set up
3460 * @accept: if RX AMPDU should be set up
3461 * @reason: reason for the permission if RX AMPDU should be set up
3463 * Returns: whether the permission if RX AMPDU should be set up is changed
3465 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3467 bool is_adj = _FALSE;
3468 struct mlme_ext_priv *mlmeext;
3469 struct mlme_ext_info *mlmeinfo;
3471 mlmeext = &adapter->mlmeextpriv;
3472 mlmeinfo = &mlmeext->mlmext_info;
3474 if (reason == RX_AMPDU_DRV_FIXED) {
3475 if (adapter->fix_rx_ampdu_accept != accept) {
3476 adapter->fix_rx_ampdu_accept = accept;
3478 DBG_871X(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3480 } else if (reason == RX_AMPDU_DRV_SCAN) {
3481 if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3482 adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3484 DBG_871X(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3492 * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3493 * @adapter: the adapter to which @sta belongs
3494 * @sta: the sta to be checked
3495 * @tid: the tid to be checked
3496 * @accept: the target permission if RX AMPDU should be set up
3497 * @size: the target RX AMPDU buffer size
3501 * 1: canceled by no permission
3502 * 2: canceled by different buffer size
3503 * 3: canceled by potential mismatched status
3505 * Blocking function, may sleep
3507 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3510 struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3512 if (reorder_ctl->enable == _FALSE) {
3513 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3514 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3520 if (accept == _FALSE) {
3521 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3523 } else if (reorder_ctl->ampdu_size != size) {
3524 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3533 * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3534 * @adapter: the adapter to which @sta belongs
3535 * @sta: the sta to be checked
3536 * @accept: the target permission if RX AMPDU should be set up
3537 * @size: the target RX AMPDU buffer size
3539 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3541 * Blocking function, may sleep
3543 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3548 for (i = 0; i < TID_NUM; i++) {
3549 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3557 * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3558 * @adapter: the adapter to be applied
3560 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3562 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3565 struct mlme_ext_priv *mlmeext;
3566 struct sta_info *sta;
3567 u8 accept = rtw_rx_ampdu_is_accept(adapter);
3568 u8 size = rtw_rx_ampdu_size(adapter);
3570 mlmeext = &adapter->mlmeextpriv;
3572 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3573 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3575 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3577 } else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3579 _list *phead, *plist;
3581 char peers[NUM_STA];
3582 struct sta_priv *pstapriv = &adapter->stapriv;
3585 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3587 phead = &pstapriv->asoc_list;
3588 plist = get_next(phead);
3590 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3593 sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3594 plist = get_next(plist);
3596 stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3597 if (stainfo_offset_valid(stainfo_offset))
3598 peers[peer_num++] = stainfo_offset;
3601 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3603 for (i = 0; i < peer_num; i++) {
3604 sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3606 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, size);
3613 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3616 struct sta_info *psta=NULL;
3617 struct recv_reorder_ctrl *preorder_ctrl;
3618 unsigned char *frame_body;
3619 unsigned char category, action;
3620 unsigned short tid, status, reason_code = 0;
3621 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3622 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3623 u8 *pframe = precv_frame->u.hdr.rx_data;
3624 struct sta_priv *pstapriv = &padapter->stapriv;
3625 #ifdef CONFIG_80211N_HT
3627 DBG_871X("%s\n", __FUNCTION__);
3629 //check RA matches or not
3630 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3634 //check A1 matches or not
3635 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3639 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3640 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3643 addr = GetAddr2Ptr(pframe);
3644 psta = rtw_get_stainfo(pstapriv, addr);
3649 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3651 category = frame_body[0];
3652 if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
3655 if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3656 (psta->htpriv.ht_option==_TRUE) &&
3657 (psta->htpriv.ampdu_enable==_TRUE))
3659 DBG_871X("Recv [%s] from direc link\n", __FUNCTION__);
3662 #endif //CONFIG_TDLS
3663 if (!pmlmeinfo->HT_enable)
3668 action = frame_body[1];
3669 DBG_871X("%s, action=%d\n", __FUNCTION__, action);
3672 case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
3674 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3675 //process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
3676 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
3680 case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
3682 //status = frame_body[3] | (frame_body[4] << 8); //endian issue
3683 status = RTW_GET_LE16(&frame_body[3]);
3684 tid = ((frame_body[5] >> 2) & 0x7);
3688 DBG_871X("agg_enable for TID=%d\n", tid);
3689 psta->htpriv.agg_enable_bitmap |= 1 << tid;
3690 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3694 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3697 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
3699 DBG_871X("%s alive check - rx ADDBA response\n", __func__);
3700 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3701 psta->expire_to = pstapriv->expire_to;
3702 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3705 //DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
3708 case RTW_WLAN_ACTION_DELBA: //DELBA
3709 if ((frame_body[3] & BIT(3)) == 0)
3711 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3712 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3714 //reason_code = frame_body[4] | (frame_body[5] << 8);
3715 reason_code = RTW_GET_LE16(&frame_body[4]);
3717 else if((frame_body[3] & BIT(3)) == BIT(3))
3719 tid = (frame_body[3] >> 4) & 0x0F;
3721 preorder_ctrl = &psta->recvreorder_ctrl[tid];
3722 preorder_ctrl->enable = _FALSE;
3723 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3726 DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
3727 //todo: how to notify the host while receiving DELETE BA
3734 #endif //CONFIG_80211N_HT
3740 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
3744 for (i = 0; i < channel_list.reg_classes; i++) {
3745 cnt += channel_list.reg_class[i].channels;
3751 static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
3759 for( i = 0; i < pmlmeext->max_chan_nums; i++ )
3761 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
3765 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
3767 // Just include the channel 36, 40, 44, 48 channels for 5G low
3770 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
3772 // Just include the channel 149, 153, 157, 161 channels for 5G high
3778 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
3781 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3782 u8 action = P2P_PUB_ACTION_ACTION;
3783 u32 p2poui = cpu_to_be32(P2POUI);
3784 u8 oui_subtype = P2P_GO_NEGO_REQ;
3785 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3786 u8 wpsielen = 0, p2pielen = 0, i;
3787 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3788 u16 len_channellist_attr = 0;
3793 struct xmit_frame *pmgntframe;
3794 struct pkt_attrib *pattrib;
3795 unsigned char *pframe;
3796 struct rtw_ieee80211_hdr *pwlanhdr;
3797 unsigned short *fctrl;
3798 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3799 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3800 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3801 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3804 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3809 DBG_871X( "[%s] In\n", __FUNCTION__ );
3811 pattrib = &pmgntframe->attrib;
3812 update_mgntframe_attrib(padapter, pattrib);
3814 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3816 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3817 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3819 fctrl = &(pwlanhdr->frame_ctl);
3822 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3823 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3824 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3826 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3827 pmlmeext->mgnt_seq++;
3828 SetFrameSubType(pframe, WIFI_ACTION);
3830 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3831 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3833 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3834 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3835 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3836 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3837 pwdinfo->negotiation_dialog_token = 1; // Initialize the dialog value
3838 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3845 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3850 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3854 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3858 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
3860 // Device Password ID
3862 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3866 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3871 if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
3873 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3875 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
3877 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3879 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
3881 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3886 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3893 p2pie[ p2pielen++ ] = 0x50;
3894 p2pie[ p2pielen++ ] = 0x6F;
3895 p2pie[ p2pielen++ ] = 0x9A;
3896 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
3898 // Commented by Albert 20110306
3899 // According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
3900 // 1. P2P Capability
3901 // 2. Group Owner Intent
3902 // 3. Configuration Timeout
3903 // 4. Listen Channel
3904 // 5. Extended Listen Timing
3905 // 6. Intended P2P Interface Address
3907 // 8. P2P Device Info
3908 // 9. Operating Channel
3913 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3916 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3920 // Device Capability Bitmap, 1 byte
3921 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3923 // Group Capability Bitmap, 1 byte
3924 if ( pwdinfo->persistent_supported )
3926 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3930 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3934 // Group Owner Intent
3936 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3939 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3943 // Todo the tie breaker bit.
3944 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) & 0xFE );
3946 // Configuration Timeout
3948 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3951 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3955 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
3956 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
3961 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
3964 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3969 p2pie[ p2pielen++ ] = 'X';
3970 p2pie[ p2pielen++ ] = 'X';
3972 // The third byte should be set to 0x04.
3973 // Described in the "Operating Channel Attribute" section.
3974 p2pie[ p2pielen++ ] = 0x04;
3977 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
3980 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listening channel number
3983 // Extended Listen Timing ATTR
3985 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
3988 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
3992 // Availability Period
3993 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
3996 // Availability Interval
3997 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
4001 // Intended P2P Interface Address
4003 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4006 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4010 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4011 p2pielen += ETH_ALEN;
4016 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4019 // Country String(3)
4020 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4021 // + number of channels in all classes
4022 len_channellist_attr = 3
4023 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
4024 + get_reg_classes_full_count(pmlmeext->channel_list);
4026 #ifdef CONFIG_CONCURRENT_MODE
4027 if (check_buddy_fwstate(padapter , _FW_LINKED)
4028 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4030 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4034 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4038 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4045 p2pie[ p2pielen++ ] = 'X';
4046 p2pie[ p2pielen++ ] = 'X';
4048 // The third byte should be set to 0x04.
4049 // Described in the "Operating Channel Attribute" section.
4050 p2pie[ p2pielen++ ] = 0x04;
4052 // Channel Entry List
4054 #ifdef CONFIG_CONCURRENT_MODE
4055 if (check_buddy_fwstate(padapter , _FW_LINKED)
4056 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4058 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4059 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4062 if ( pbuddy_mlmeext->cur_channel > 14 )
4064 if ( pbuddy_mlmeext->cur_channel >= 149 )
4066 p2pie[ p2pielen++ ] = 0x7c;
4070 p2pie[ p2pielen++ ] = 0x73;
4075 p2pie[ p2pielen++ ] = 0x51;
4078 // Number of Channels
4079 // Just support 1 channel and this channel is AP's channel
4080 p2pie[ p2pielen++ ] = 1;
4083 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4088 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4090 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4092 // Number of Channels
4093 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4096 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4097 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4101 #else // CONFIG_CONCURRENT_MODE
4104 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4106 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4108 // Number of Channels
4109 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4112 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4113 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4117 #endif // CONFIG_CONCURRENT_MODE
4121 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4124 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4125 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4126 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4130 // P2P Device Address
4131 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4132 p2pielen += ETH_ALEN;
4135 // This field should be big endian. Noted by P2P specification.
4137 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4141 // Primary Device Type
4143 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4147 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4151 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4154 // Number of Secondary Device Types
4155 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4159 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4163 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4167 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4168 p2pielen += pwdinfo->device_name_len;
4171 // Operating Channel
4173 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4176 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4181 p2pie[ p2pielen++ ] = 'X';
4182 p2pie[ p2pielen++ ] = 'X';
4184 // The third byte should be set to 0x04.
4185 // Described in the "Operating Channel Attribute" section.
4186 p2pie[ p2pielen++ ] = 0x04;
4189 if ( pwdinfo->operating_channel <= 14 )
4192 p2pie[ p2pielen++ ] = 0x51;
4194 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4197 p2pie[ p2pielen++ ] = 0x73;
4202 p2pie[ p2pielen++ ] = 0x7c;
4206 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4208 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4211 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4213 pattrib->pktlen += wfdielen;
4216 pattrib->last_txcmdsz = pattrib->pktlen;
4218 dump_mgntframe(padapter, pmgntframe);
4225 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
4228 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4229 u8 action = P2P_PUB_ACTION_ACTION;
4230 u32 p2poui = cpu_to_be32(P2POUI);
4231 u8 oui_subtype = P2P_GO_NEGO_RESP;
4232 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4235 u16 wps_devicepassword_id = 0x0000;
4236 uint wps_devicepassword_id_len = 0;
4237 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4238 u16 len_channellist_attr = 0;
4240 struct xmit_frame *pmgntframe;
4241 struct pkt_attrib *pattrib;
4242 unsigned char *pframe;
4243 struct rtw_ieee80211_hdr *pwlanhdr;
4244 unsigned short *fctrl;
4245 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4246 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4247 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4248 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4254 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4259 DBG_871X( "[%s] In, result = %d\n", __FUNCTION__, result );
4261 pattrib = &pmgntframe->attrib;
4262 update_mgntframe_attrib(padapter, pattrib);
4264 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4266 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4267 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4269 fctrl = &(pwlanhdr->frame_ctl);
4272 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4273 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4274 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4276 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4277 pmlmeext->mgnt_seq++;
4278 SetFrameSubType(pframe, WIFI_ACTION);
4280 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4281 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4283 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4284 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4285 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4286 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4287 pwdinfo->negotiation_dialog_token = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
4288 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4290 // Commented by Albert 20110328
4291 // Try to get the device password ID from the WPS IE of group negotiation request frame
4292 // WiFi Direct test plan 5.1.15
4293 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4294 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4295 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4297 _rtw_memset( wpsie, 0x00, 255 );
4303 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4308 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4312 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4316 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
4318 // Device Password ID
4320 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4324 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4328 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4330 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
4332 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4334 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
4338 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
4342 // Commented by Kurt 20120113
4343 // If some device wants to do p2p handshake without sending prov_disc_req
4344 // We have to get peer_req_cm from here.
4345 if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
4347 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
4349 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
4351 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
4353 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
4357 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
4361 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4368 p2pie[ p2pielen++ ] = 0x50;
4369 p2pie[ p2pielen++ ] = 0x6F;
4370 p2pie[ p2pielen++ ] = 0x9A;
4371 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4373 // Commented by Albert 20100908
4374 // According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
4376 // 2. P2P Capability
4377 // 3. Group Owner Intent
4378 // 4. Configuration Timeout
4379 // 5. Operating Channel
4380 // 6. Intended P2P Interface Address
4383 // 9. Group ID ( Only GO )
4390 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4393 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4397 p2pie[ p2pielen++ ] = result;
4401 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4404 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4408 // Device Capability Bitmap, 1 byte
4410 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4412 // Commented by Albert 2011/03/08
4413 // According to the P2P specification
4414 // if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
4415 p2pie[ p2pielen++ ] = 0;
4419 // Be group owner or meet the error case
4420 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4423 // Group Capability Bitmap, 1 byte
4424 if ( pwdinfo->persistent_supported )
4426 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4430 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4433 // Group Owner Intent
4435 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
4438 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4442 if ( pwdinfo->peer_intent & 0x01 )
4444 // Peer's tie breaker bit is 1, our tie breaker bit should be 0
4445 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
4449 // Peer's tie breaker bit is 0, our tie breaker bit should be 1
4450 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
4454 // Configuration Timeout
4456 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4459 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4463 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
4464 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
4466 // Operating Channel
4468 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4471 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4476 p2pie[ p2pielen++ ] = 'X';
4477 p2pie[ p2pielen++ ] = 'X';
4479 // The third byte should be set to 0x04.
4480 // Described in the "Operating Channel Attribute" section.
4481 p2pie[ p2pielen++ ] = 0x04;
4484 if ( pwdinfo->operating_channel <= 14 )
4487 p2pie[ p2pielen++ ] = 0x51;
4489 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4492 p2pie[ p2pielen++ ] = 0x73;
4497 p2pie[ p2pielen++ ] = 0x7c;
4501 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
4503 // Intended P2P Interface Address
4505 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
4508 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4512 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4513 p2pielen += ETH_ALEN;
4517 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4519 // Country String(3)
4520 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
4521 // + number of channels in all classes
4522 len_channellist_attr = 3
4523 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4524 + get_reg_classes_full_count(pmlmeext->channel_list);
4526 #ifdef CONFIG_CONCURRENT_MODE
4527 if (check_buddy_fwstate(padapter , _FW_LINKED)
4528 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4530 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4534 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4538 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4545 p2pie[ p2pielen++ ] = 'X';
4546 p2pie[ p2pielen++ ] = 'X';
4548 // The third byte should be set to 0x04.
4549 // Described in the "Operating Channel Attribute" section.
4550 p2pie[ p2pielen++ ] = 0x04;
4552 // Channel Entry List
4554 #ifdef CONFIG_CONCURRENT_MODE
4555 if (check_buddy_fwstate(padapter , _FW_LINKED)
4556 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4558 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4559 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4562 if ( pbuddy_mlmeext->cur_channel > 14 )
4564 if ( pbuddy_mlmeext->cur_channel >= 149 )
4566 p2pie[ p2pielen++ ] = 0x7c;
4570 p2pie[ p2pielen++ ] = 0x73;
4575 p2pie[ p2pielen++ ] = 0x51;
4578 // Number of Channels
4579 // Just support 1 channel and this channel is AP's channel
4580 p2pie[ p2pielen++ ] = 1;
4583 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4588 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4590 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4592 // Number of Channels
4593 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4596 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4597 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4601 #else // CONFIG_CONCURRENT_MODE
4604 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4606 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4608 // Number of Channels
4609 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4612 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4613 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4617 #endif // CONFIG_CONCURRENT_MODE
4622 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4625 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4626 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4627 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4631 // P2P Device Address
4632 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4633 p2pielen += ETH_ALEN;
4636 // This field should be big endian. Noted by P2P specification.
4638 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4642 // Primary Device Type
4644 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4648 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
4652 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4655 // Number of Secondary Device Types
4656 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
4660 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4664 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
4668 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
4669 p2pielen += pwdinfo->device_name_len;
4671 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4673 // Group ID Attribute
4675 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4678 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4682 // p2P Device Address
4683 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4684 p2pielen += ETH_ALEN;
4687 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4688 p2pielen += pwdinfo->nego_ssidlen;
4692 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4695 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4697 pattrib->pktlen += wfdielen;
4700 pattrib->last_txcmdsz = pattrib->pktlen;
4702 dump_mgntframe(padapter, pmgntframe);
4708 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
4711 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4712 u8 action = P2P_PUB_ACTION_ACTION;
4713 u32 p2poui = cpu_to_be32(P2POUI);
4714 u8 oui_subtype = P2P_GO_NEGO_CONF;
4715 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4716 u8 wpsielen = 0, p2pielen = 0;
4718 struct xmit_frame *pmgntframe;
4719 struct pkt_attrib *pattrib;
4720 unsigned char *pframe;
4721 struct rtw_ieee80211_hdr *pwlanhdr;
4722 unsigned short *fctrl;
4723 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4724 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4725 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4726 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
4731 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4736 DBG_871X( "[%s] In\n", __FUNCTION__ );
4738 pattrib = &pmgntframe->attrib;
4739 update_mgntframe_attrib(padapter, pattrib);
4741 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4743 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4744 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4746 fctrl = &(pwlanhdr->frame_ctl);
4749 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4750 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4751 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4753 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4754 pmlmeext->mgnt_seq++;
4755 SetFrameSubType(pframe, WIFI_ACTION);
4757 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4758 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4760 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4761 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4762 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4763 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4764 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4772 p2pie[ p2pielen++ ] = 0x50;
4773 p2pie[ p2pielen++ ] = 0x6F;
4774 p2pie[ p2pielen++ ] = 0x9A;
4775 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4777 // Commented by Albert 20110306
4778 // According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
4780 // 2. P2P Capability
4781 // 3. Operating Channel
4783 // 5. Group ID ( if this WiFi is GO )
4787 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4790 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4794 p2pie[ p2pielen++ ] = result;
4798 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4801 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4805 // Device Capability Bitmap, 1 byte
4806 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4808 // Group Capability Bitmap, 1 byte
4809 if ( pwdinfo->persistent_supported )
4811 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4815 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
4819 // Operating Channel
4821 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4824 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4829 p2pie[ p2pielen++ ] = 'X';
4830 p2pie[ p2pielen++ ] = 'X';
4832 // The third byte should be set to 0x04.
4833 // Described in the "Operating Channel Attribute" section.
4834 p2pie[ p2pielen++ ] = 0x04;
4837 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4839 if ( pwdinfo->peer_operating_ch <= 14 )
4842 p2pie[ p2pielen++ ] = 0x51;
4844 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4847 p2pie[ p2pielen++ ] = 0x73;
4852 p2pie[ p2pielen++ ] = 0x7c;
4855 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4859 if ( pwdinfo->operating_channel <= 14 )
4862 p2pie[ p2pielen++ ] = 0x51;
4864 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4867 p2pie[ p2pielen++ ] = 0x73;
4872 p2pie[ p2pielen++ ] = 0x7c;
4876 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4882 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4884 *(u16*) ( p2pie + p2pielen ) = 6;
4888 p2pie[ p2pielen++ ] = 'X';
4889 p2pie[ p2pielen++ ] = 'X';
4891 // The third byte should be set to 0x04.
4892 // Described in the "Operating Channel Attribute" section.
4893 p2pie[ p2pielen++ ] = 0x04;
4896 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
4898 if ( pwdinfo->peer_operating_ch <= 14 )
4901 p2pie[ p2pielen++ ] = 0x51;
4903 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
4906 p2pie[ p2pielen++ ] = 0x73;
4911 p2pie[ p2pielen++ ] = 0x7c;
4913 p2pie[ p2pielen++ ] = 1;
4914 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
4918 if ( pwdinfo->operating_channel <= 14 )
4921 p2pie[ p2pielen++ ] = 0x51;
4923 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
4926 p2pie[ p2pielen++ ] = 0x73;
4931 p2pie[ p2pielen++ ] = 0x7c;
4935 p2pie[ p2pielen++ ] = 1;
4936 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
4939 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4941 // Group ID Attribute
4943 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
4946 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
4950 // p2P Device Address
4951 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
4952 p2pielen += ETH_ALEN;
4955 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
4956 p2pielen += pwdinfo->nego_ssidlen;
4959 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4962 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4964 pattrib->pktlen += wfdielen;
4967 pattrib->last_txcmdsz = pattrib->pktlen;
4969 dump_mgntframe(padapter, pmgntframe);
4975 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
4978 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4979 u8 action = P2P_PUB_ACTION_ACTION;
4980 u32 p2poui = cpu_to_be32(P2POUI);
4981 u8 oui_subtype = P2P_INVIT_REQ;
4982 u8 p2pie[ 255 ] = { 0x00 };
4985 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4986 u16 len_channellist_attr = 0;
4990 #ifdef CONFIG_CONCURRENT_MODE
4991 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4992 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4993 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4994 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4997 struct xmit_frame *pmgntframe;
4998 struct pkt_attrib *pattrib;
4999 unsigned char *pframe;
5000 struct rtw_ieee80211_hdr *pwlanhdr;
5001 unsigned short *fctrl;
5002 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5003 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5004 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5005 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
5008 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5014 pattrib = &pmgntframe->attrib;
5015 update_mgntframe_attrib(padapter, pattrib);
5017 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5019 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5020 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5022 fctrl = &(pwlanhdr->frame_ctl);
5025 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5026 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5027 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5029 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5030 pmlmeext->mgnt_seq++;
5031 SetFrameSubType(pframe, WIFI_ACTION);
5033 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5034 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5036 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5037 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5038 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5039 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5040 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5046 p2pie[ p2pielen++ ] = 0x50;
5047 p2pie[ p2pielen++ ] = 0x6F;
5048 p2pie[ p2pielen++ ] = 0x9A;
5049 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
5051 // Commented by Albert 20101011
5052 // According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
5053 // 1. Configuration Timeout
5054 // 2. Invitation Flags
5055 // 3. Operating Channel ( Only GO )
5056 // 4. P2P Group BSSID ( Should be included if I am the GO )
5059 // 7. P2P Device Info
5061 // Configuration Timeout
5063 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5066 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5070 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
5071 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
5075 p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
5078 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5082 p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
5085 // Operating Channel
5087 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5090 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5095 p2pie[ p2pielen++ ] = 'X';
5096 p2pie[ p2pielen++ ] = 'X';
5098 // The third byte should be set to 0x04.
5099 // Described in the "Operating Channel Attribute" section.
5100 p2pie[ p2pielen++ ] = 0x04;
5103 if ( pwdinfo->invitereq_info.operating_ch <= 14 )
5104 p2pie[ p2pielen++ ] = 0x51;
5105 else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
5106 p2pie[ p2pielen++ ] = 0x73;
5108 p2pie[ p2pielen++ ] = 0x7c;
5111 p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; // operating channel number
5113 if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
5117 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5120 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5124 // P2P Device Address for GO
5125 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5126 p2pielen += ETH_ALEN;
5131 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5135 // Country String(3)
5136 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5137 // + number of channels in all classes
5138 len_channellist_attr = 3
5139 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5140 + get_reg_classes_full_count(pmlmeext->channel_list);
5142 #ifdef CONFIG_CONCURRENT_MODE
5143 if (check_buddy_fwstate(padapter , _FW_LINKED)
5144 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5146 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5150 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5154 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5161 p2pie[ p2pielen++ ] = 'X';
5162 p2pie[ p2pielen++ ] = 'X';
5164 // The third byte should be set to 0x04.
5165 // Described in the "Operating Channel Attribute" section.
5166 p2pie[ p2pielen++ ] = 0x04;
5168 // Channel Entry List
5169 #ifdef CONFIG_CONCURRENT_MODE
5170 if (check_buddy_fwstate(padapter, _FW_LINKED)
5171 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5173 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5174 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5177 if ( pbuddy_mlmeext->cur_channel > 14 )
5179 if ( pbuddy_mlmeext->cur_channel >= 149 )
5181 p2pie[ p2pielen++ ] = 0x7c;
5185 p2pie[ p2pielen++ ] = 0x73;
5190 p2pie[ p2pielen++ ] = 0x51;
5193 // Number of Channels
5194 // Just support 1 channel and this channel is AP's channel
5195 p2pie[ p2pielen++ ] = 1;
5198 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5203 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5205 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5207 // Number of Channels
5208 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5211 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5212 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5216 #else // CONFIG_CONCURRENT_MODE
5219 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5221 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5223 // Number of Channels
5224 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5227 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5228 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5232 #endif // CONFIG_CONCURRENT_MODE
5237 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
5240 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
5244 // P2P Device Address for GO
5245 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
5246 p2pielen += ETH_ALEN;
5249 _rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
5250 p2pielen += pwdinfo->invitereq_info.ssidlen;
5255 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
5258 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
5259 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
5260 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
5264 // P2P Device Address
5265 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5266 p2pielen += ETH_ALEN;
5269 // This field should be big endian. Noted by P2P specification.
5270 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
5273 // Primary Device Type
5275 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
5279 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
5283 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
5286 // Number of Secondary Device Types
5287 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
5291 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
5295 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
5299 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
5300 p2pielen += pwdinfo->device_name_len;
5302 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5305 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5307 pattrib->pktlen += wfdielen;
5310 pattrib->last_txcmdsz = pattrib->pktlen;
5312 dump_mgntframe(padapter, pmgntframe);
5318 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
5321 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5322 u8 action = P2P_PUB_ACTION_ACTION;
5323 u32 p2poui = cpu_to_be32(P2POUI);
5324 u8 oui_subtype = P2P_INVIT_RESP;
5325 u8 p2pie[ 255 ] = { 0x00 };
5327 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5328 u16 len_channellist_attr = 0;
5329 #ifdef CONFIG_CONCURRENT_MODE
5330 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5331 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5332 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5333 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5339 struct xmit_frame *pmgntframe;
5340 struct pkt_attrib *pattrib;
5341 unsigned char *pframe;
5342 struct rtw_ieee80211_hdr *pwlanhdr;
5343 unsigned short *fctrl;
5344 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5345 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5346 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5347 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
5350 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5356 pattrib = &pmgntframe->attrib;
5357 update_mgntframe_attrib(padapter, pattrib);
5359 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5361 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5362 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5364 fctrl = &(pwlanhdr->frame_ctl);
5367 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5368 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5369 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5371 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5372 pmlmeext->mgnt_seq++;
5373 SetFrameSubType(pframe, WIFI_ACTION);
5375 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5376 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5378 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5379 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5380 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5381 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5382 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5388 p2pie[ p2pielen++ ] = 0x50;
5389 p2pie[ p2pielen++ ] = 0x6F;
5390 p2pie[ p2pielen++ ] = 0x9A;
5391 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
5393 // Commented by Albert 20101005
5394 // According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
5396 // 2. Configuration Timeout
5397 // 3. Operating Channel ( Only GO )
5398 // 4. P2P Group BSSID ( Only GO )
5403 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
5406 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
5410 // When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
5411 // Sent the event receiving the P2P Invitation Req frame to DMP UI.
5412 // DMP had to compare the MAC address to find out the profile.
5413 // So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
5414 // If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
5415 // to NB to rebuild the persistent group.
5416 p2pie[ p2pielen++ ] = status_code;
5418 // Configuration Timeout
5420 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
5423 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
5427 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P GO
5428 p2pie[ p2pielen++ ] = 200; // 2 seconds needed to be the P2P Client
5430 if( status_code == P2P_STATUS_SUCCESS )
5432 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
5434 // The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
5435 // In this case, the P2P Invitation response frame should carry the two more P2P attributes.
5436 // First one is operating channel attribute.
5437 // Second one is P2P Group BSSID attribute.
5439 // Operating Channel
5441 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
5444 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5449 p2pie[ p2pielen++ ] = 'X';
5450 p2pie[ p2pielen++ ] = 'X';
5452 // The third byte should be set to 0x04.
5453 // Described in the "Operating Channel Attribute" section.
5454 p2pie[ p2pielen++ ] = 0x04;
5457 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
5460 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
5465 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
5468 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
5472 // P2P Device Address for GO
5473 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5474 p2pielen += ETH_ALEN;
5480 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
5483 // Country String(3)
5484 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
5485 // + number of channels in all classes
5486 len_channellist_attr = 3
5487 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5488 + get_reg_classes_full_count(pmlmeext->channel_list);
5490 #ifdef CONFIG_CONCURRENT_MODE
5491 if (check_buddy_fwstate(padapter, _FW_LINKED)
5492 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5494 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
5498 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5502 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
5509 p2pie[ p2pielen++ ] = 'X';
5510 p2pie[ p2pielen++ ] = 'X';
5512 // The third byte should be set to 0x04.
5513 // Described in the "Operating Channel Attribute" section.
5514 p2pie[ p2pielen++ ] = 0x04;
5516 // Channel Entry List
5517 #ifdef CONFIG_CONCURRENT_MODE
5518 if (check_buddy_fwstate(padapter , _FW_LINKED)
5519 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5521 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5522 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5525 if ( pbuddy_mlmeext->cur_channel > 14 )
5527 if ( pbuddy_mlmeext->cur_channel >= 149 )
5529 p2pie[ p2pielen++ ] = 0x7c;
5533 p2pie[ p2pielen++ ] = 0x73;
5538 p2pie[ p2pielen++ ] = 0x51;
5541 // Number of Channels
5542 // Just support 1 channel and this channel is AP's channel
5543 p2pie[ p2pielen++ ] = 1;
5546 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
5551 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5553 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5555 // Number of Channels
5556 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5559 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5560 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5564 #else // CONFIG_CONCURRENT_MODE
5567 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5569 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5571 // Number of Channels
5572 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5575 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
5576 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5580 #endif // CONFIG_CONCURRENT_MODE
5583 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5586 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5588 pattrib->pktlen += wfdielen;
5591 pattrib->last_txcmdsz = pattrib->pktlen;
5593 dump_mgntframe(padapter, pmgntframe);
5599 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
5601 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5602 u8 action = P2P_PUB_ACTION_ACTION;
5604 u32 p2poui = cpu_to_be32(P2POUI);
5605 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
5606 u8 wpsie[ 100 ] = { 0x00 };
5613 struct xmit_frame *pmgntframe;
5614 struct pkt_attrib *pattrib;
5615 unsigned char *pframe;
5616 struct rtw_ieee80211_hdr *pwlanhdr;
5617 unsigned short *fctrl;
5618 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5619 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5620 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5621 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5624 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5629 DBG_871X( "[%s] In\n", __FUNCTION__ );
5631 pattrib = &pmgntframe->attrib;
5632 update_mgntframe_attrib(padapter, pattrib);
5634 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5636 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5637 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5639 fctrl = &(pwlanhdr->frame_ctl);
5642 _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5643 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5644 _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5646 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5647 pmlmeext->mgnt_seq++;
5648 SetFrameSubType(pframe, WIFI_ACTION);
5650 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5651 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5653 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5654 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5655 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5656 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5657 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5659 p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
5662 pattrib->pktlen += p2pielen;
5666 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5671 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5675 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5679 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5683 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
5687 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
5691 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
5694 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
5698 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5700 pattrib->pktlen += wfdielen;
5703 pattrib->last_txcmdsz = pattrib->pktlen;
5705 dump_mgntframe(padapter, pmgntframe);
5712 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
5714 u8 i, match_result = 0;
5716 DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5717 peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
5719 for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
5721 DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5722 profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
5723 if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
5726 DBG_871X( "[%s] Match!\n", __FUNCTION__ );
5731 return (match_result );
5734 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5736 struct xmit_frame *pmgntframe;
5737 struct pkt_attrib *pattrib;
5738 unsigned char *pframe;
5739 struct rtw_ieee80211_hdr *pwlanhdr;
5740 unsigned short *fctrl;
5742 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5743 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5744 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5745 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5746 //WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5747 u16 beacon_interval = 100;
5749 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5750 u8 wpsie[255] = { 0x00 };
5751 u32 wpsielen = 0, p2pielen = 0;
5755 #ifdef CONFIG_INTEL_WIDI
5756 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5757 #endif //CONFIG_INTEL_WIDI
5759 //DBG_871X("%s\n", __FUNCTION__);
5761 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5767 pattrib = &pmgntframe->attrib;
5768 update_mgntframe_attrib(padapter, pattrib);
5770 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5772 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5773 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5775 mac = adapter_mac_addr(padapter);
5777 fctrl = &(pwlanhdr->frame_ctl);
5779 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5780 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5782 // Use the device address for BSSID field.
5783 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5785 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5786 pmlmeext->mgnt_seq++;
5787 SetFrameSubType(fctrl, WIFI_PROBERSP);
5789 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5790 pattrib->pktlen = pattrib->hdrlen;
5791 pframe += pattrib->hdrlen;
5793 //timestamp will be inserted by hardware
5795 pattrib->pktlen += 8;
5797 // beacon interval: 2 bytes
5798 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5800 pattrib->pktlen += 2;
5802 // capability info: 2 bytes
5803 // ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
5804 capInfo |= cap_ShortPremble;
5805 capInfo |= cap_ShortSlot;
5807 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5809 pattrib->pktlen += 2;
5813 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5815 // supported rates...
5816 // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5817 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5820 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5822 #ifdef CONFIG_IOCTL_CFG80211
5823 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
5825 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
5828 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5829 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5830 pframe += pmlmepriv->wps_probe_resp_ie_len;
5833 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5834 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5835 pframe += pmlmepriv->p2p_probe_resp_ie_len;
5839 #endif //CONFIG_IOCTL_CFG80211
5843 // Noted by Albert 20100907
5844 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
5848 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
5853 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
5857 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5861 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
5863 #ifdef CONFIG_INTEL_WIDI
5864 // Commented by Kurt
5865 // Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
5866 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5867 || pmlmepriv->num_p2p_sdt != 0 )
5870 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
5874 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
5879 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
5883 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
5886 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
5889 if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
5892 _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
5893 wpsielen += L2SDTA_SERVICE_VE_LEN;
5896 #endif //CONFIG_INTEL_WIDI
5898 // WiFi Simple Config State
5900 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
5904 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5908 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; // Not Configured.
5912 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
5916 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5920 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5924 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
5928 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
5932 if (pwdinfo->external_uuid == 0) {
5933 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
5934 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5936 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
5942 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
5946 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
5950 _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
5955 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
5959 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
5963 _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
5968 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
5972 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
5976 wpsie[ wpsielen++ ] = 0x31; // character 1
5980 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
5984 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
5988 _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
5989 wpsielen += ETH_ALEN;
5991 // Primary Device Type
5993 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
5997 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6002 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
6006 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6010 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
6015 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6019 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6023 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6024 wpsielen += pwdinfo->device_name_len;
6028 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6032 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6036 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6040 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6043 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6045 pattrib->pktlen += p2pielen;
6049 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6051 pattrib->pktlen += wfdielen;
6054 pattrib->last_txcmdsz = pattrib->pktlen;
6057 dump_mgntframe(padapter, pmgntframe);
6063 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6066 struct xmit_frame *pmgntframe;
6067 struct pkt_attrib *pattrib;
6068 unsigned char *pframe;
6069 struct rtw_ieee80211_hdr *pwlanhdr;
6070 unsigned short *fctrl;
6072 unsigned char bssrate[NumRates];
6073 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6074 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6075 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6076 int bssrate_len = 0;
6077 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6078 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6079 u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
6080 u16 wpsielen = 0, p2pielen = 0;
6085 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6088 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6094 pattrib = &pmgntframe->attrib;
6095 update_mgntframe_attrib(padapter, pattrib);
6098 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6100 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6101 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6103 mac = adapter_mac_addr(padapter);
6105 fctrl = &(pwlanhdr->frame_ctl);
6109 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6110 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6112 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
6114 // This two flags will be set when this is only the P2P client mode.
6115 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6116 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6120 // broadcast probe request frame
6121 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6122 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6125 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6127 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6128 pmlmeext->mgnt_seq++;
6129 SetFrameSubType(pframe, WIFI_PROBEREQ);
6131 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6132 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6134 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6136 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6140 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6142 // Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
6143 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6145 #ifdef CONFIG_IOCTL_CFG80211
6146 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
6148 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
6151 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6152 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6153 pframe += pmlmepriv->wps_probe_req_ie_len;
6156 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6157 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6158 pframe += pmlmepriv->p2p_probe_req_ie_len;
6162 #endif //CONFIG_IOCTL_CFG80211
6166 // Noted by Albert 20110221
6167 // According to the WPS specification, all the WPS attribute is presented by Big Endian.
6171 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
6176 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
6180 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
6184 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
6186 if( pmlmepriv->wps_probe_req_ie == NULL )
6190 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
6194 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
6198 if (pwdinfo->external_uuid == 0) {
6199 _rtw_memset( wpsie + wpsielen, 0x0, 16 );
6200 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6202 _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
6208 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
6212 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6216 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
6222 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6226 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
6230 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
6231 wpsielen += pwdinfo->device_name_len;
6233 // Primary Device Type
6235 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6239 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
6244 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
6248 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
6252 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
6255 // Device Password ID
6257 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
6261 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
6265 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); // Registrar-specified
6268 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
6272 p2pie[ p2pielen++ ] = 0x50;
6273 p2pie[ p2pielen++ ] = 0x6F;
6274 p2pie[ p2pielen++ ] = 0x9A;
6275 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
6277 // Commented by Albert 20110221
6278 // According to the P2P Specification, the probe request frame should contain 5 P2P attributes
6279 // 1. P2P Capability
6280 // 2. P2P Device ID if this probe request wants to find the specific P2P device
6281 // 3. Listen Channel
6282 // 4. Extended Listen Timing
6283 // 5. Operating Channel if this WiFi is working as the group owner now
6287 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
6290 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
6294 // Device Capability Bitmap, 1 byte
6295 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
6297 // Group Capability Bitmap, 1 byte
6298 if ( pwdinfo->persistent_supported )
6299 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6301 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
6305 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
6308 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6313 p2pie[ p2pielen++ ] = 'X';
6314 p2pie[ p2pielen++ ] = 'X';
6316 // The third byte should be set to 0x04.
6317 // Described in the "Operating Channel Attribute" section.
6318 p2pie[ p2pielen++ ] = 0x04;
6321 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
6324 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; // listen channel
6327 // Extended Listen Timing
6329 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
6332 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
6336 // Availability Period
6337 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6340 // Availability Interval
6341 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
6344 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
6346 // Operating Channel (if this WiFi is working as the group owner now)
6348 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
6351 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
6356 p2pie[ p2pielen++ ] = 'X';
6357 p2pie[ p2pielen++ ] = 'X';
6359 // The third byte should be set to 0x04.
6360 // Described in the "Operating Channel Attribute" section.
6361 p2pie[ p2pielen++ ] = 0x04;
6364 p2pie[ p2pielen++ ] = 0x51; // Copy from SD7
6367 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // operating channel number
6371 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
6376 wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6378 pattrib->pktlen += wfdielen;
6381 pattrib->last_txcmdsz = pattrib->pktlen;
6383 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6386 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6388 dump_mgntframe(padapter, pmgntframe);
6396 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6398 _issue_probereq_p2p(adapter, da, _FALSE);
6402 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6403 * 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
6404 * try_cnt means the maximal TX count to try
6406 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6410 u32 start = rtw_get_current_time();
6414 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
6418 if (RTW_CANNOT_RUN(adapter))
6421 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6422 rtw_msleep_os(wait_ms);
6424 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6428 #ifndef DBG_XMIT_ACK
6433 if (try_cnt && wait_ms) {
6435 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6436 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6437 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6439 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6440 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6441 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6449 s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
6451 _adapter *adapter = rframe->u.hdr.adapter;
6452 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6453 u8 *frame = rframe->u.hdr.rx_data;
6454 u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num&0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
6455 u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
6457 if (GetRetry(frame)) {
6458 if ((seq_ctrl == mlmeext->action_public_rxseq)
6459 && (token == mlmeext->action_public_dialog_token)
6461 DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6462 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6467 /* TODO: per sta seq & token */
6468 mlmeext->action_public_rxseq = seq_ctrl;
6469 mlmeext->action_public_dialog_token = token;
6474 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6476 _adapter *padapter = precv_frame->u.hdr.adapter;
6477 u8 *pframe = precv_frame->u.hdr.rx_data;
6478 uint len = precv_frame->u.hdr.len;
6482 u32 p2p_ielen, wps_ielen;
6483 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6484 u8 result = P2P_STATUS_SUCCESS;
6485 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6486 u8 *merged_p2pie = NULL;
6487 u32 merged_p2p_ielen= 0;
6490 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6493 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
6494 #ifdef CONFIG_IOCTL_CFG80211
6495 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6497 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
6500 #endif //CONFIG_IOCTL_CFG80211
6502 // Do nothing if the driver doesn't enable the P2P function.
6503 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6506 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6508 switch( frame_body[ 6 ] )//OUI Subtype
6510 case P2P_GO_NEGO_REQ:
6512 DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6513 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
6515 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6517 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6520 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6522 // Commented by Albert 20110526
6523 // In this case, this means the previous nego fail doesn't be reset yet.
6524 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6525 // Restore the previous p2p state
6526 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6527 DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
6529 #ifdef CONFIG_CONCURRENT_MODE
6530 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
6532 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6534 #endif // CONFIG_CONCURRENT_MODE
6536 // Commented by Kurt 20110902
6537 //Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6538 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6539 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6541 // Commented by Kurt 20120113
6542 // Get peer_dev_addr here if peer doesn't issue prov_disc frame.
6543 if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) )
6544 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6546 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
6547 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
6548 #ifdef CONFIG_INTEL_WIDI
6549 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6550 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6551 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6552 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6554 #endif //CONFIG_INTEL_WIDI
6556 // Commented by Albert 20110718
6557 // No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
6558 #ifdef CONFIG_CONCURRENT_MODE
6559 // Commented by Albert 20120107
6560 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6561 #else // CONFIG_CONCURRENT_MODE
6562 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6563 #endif // CONFIG_CONCURRENT_MODE
6566 case P2P_GO_NEGO_RESP:
6568 DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6570 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6572 // Commented by Albert 20110425
6573 // The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
6574 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6575 pwdinfo->nego_req_info.benable = _FALSE;
6576 result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
6577 issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
6578 if ( P2P_STATUS_SUCCESS == result )
6580 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6582 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6583 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6584 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6585 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6586 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6587 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6588 pwdinfo->p2p_info.scan_op_ch_only = 1;
6589 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6593 // Reset the dialog token for group negotiation frames.
6594 pwdinfo->negotiation_dialog_token = 1;
6596 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6598 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6603 DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6608 case P2P_GO_NEGO_CONF:
6610 DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6611 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
6612 if ( P2P_STATUS_SUCCESS == result )
6614 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
6616 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
6617 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6618 pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
6619 pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
6620 pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
6621 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6622 pwdinfo->p2p_info.scan_op_ch_only = 1;
6623 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
6630 // Added by Albert 2010/10/05
6631 // Received the P2P Invite Request frame.
6633 DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
6634 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6636 // Parse the necessary information from the P2P Invitation Request frame.
6637 // For example: The MAC address of sending this P2P Invitation Request frame.
6638 u32 attr_contentlen = 0;
6639 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6640 struct group_id_info group_id;
6641 u8 invitation_flag = 0;
6644 merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6646 merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); // 2 is for EID and Length
6647 if (merged_p2pie == NULL)
6649 DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
6652 _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
6654 merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6656 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6657 if ( attr_contentlen )
6660 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6661 // Commented by Albert 20120510
6662 // Copy to the pwdinfo->p2p_peer_interface_addr.
6663 // So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
6664 // #> iwpriv wlan0 p2p_get peer_ifa
6665 // After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
6667 if ( attr_contentlen )
6669 DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6670 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6671 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6672 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
6675 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
6677 // Re-invoke the persistent group.
6679 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6680 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6681 if ( attr_contentlen )
6683 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6685 // The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
6686 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
6687 rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
6688 status_code = P2P_STATUS_SUCCESS;
6692 // The p2p device sending this p2p invitation request wants to be the persistent GO.
6693 if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
6695 u8 operatingch_info[5] = { 0x00 };
6696 if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
6698 if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
6700 // The operating channel is acceptable for this device.
6701 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
6702 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6703 pwdinfo->rx_invitereq_info.operation_ch[1]= 1; //Check whether GO is operating in channel 1;
6704 pwdinfo->rx_invitereq_info.operation_ch[2]= 6; //Check whether GO is operating in channel 6;
6705 pwdinfo->rx_invitereq_info.operation_ch[3]= 11; //Check whether GO is operating in channel 11;
6706 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
6707 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6708 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
6709 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6710 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6711 status_code = P2P_STATUS_SUCCESS;
6715 // The operating channel isn't supported by this device.
6716 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6717 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
6718 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6719 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6724 // Commented by Albert 20121130
6725 // Intel will use the different P2P IE to store the operating channel information
6726 // Workaround for Intel WiDi 3.5
6727 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
6728 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6729 status_code = P2P_STATUS_SUCCESS;
6734 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6735 #ifdef CONFIG_INTEL_WIDI
6736 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6737 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6738 #endif //CONFIG_INTEL_WIDI
6740 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6746 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6747 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6752 // Received the invitation to join a P2P group.
6754 _rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
6755 rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
6756 if ( attr_contentlen )
6758 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN))
6760 // In this case, the GO can't be myself.
6761 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
6762 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6766 // The p2p device sending this p2p invitation request wants to join an existing P2P group
6767 // Commented by Albert 2012/06/28
6768 // In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
6769 // The peer device address should be the destination address for the provisioning discovery request.
6770 // Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
6771 // The peer interface address should be the address for WPS mac address
6772 _rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
6773 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
6774 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
6775 status_code = P2P_STATUS_SUCCESS;
6780 DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
6781 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6787 DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
6788 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6791 DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
6793 pwdinfo->inviteresp_info.token = frame_body[ 7 ];
6794 issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
6795 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
6797 #ifdef CONFIG_INTEL_WIDI
6798 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6799 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6800 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6801 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6803 #endif //CONFIG_INTEL_WIDI
6806 case P2P_INVIT_RESP:
6808 u8 attr_content = 0x00;
6809 u32 attr_contentlen = 0;
6811 DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
6812 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6813 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
6815 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6817 if ( attr_contentlen == 1 )
6819 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
6820 pwdinfo->invitereq_info.benable = _FALSE;
6822 if ( attr_content == P2P_STATUS_SUCCESS )
6824 if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6825 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
6827 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6829 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
6833 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6834 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6839 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6840 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6845 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6846 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
6849 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
6851 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
6855 case P2P_DEVDISC_REQ:
6857 process_p2p_devdisc_req(pwdinfo, pframe, len);
6861 case P2P_DEVDISC_RESP:
6863 process_p2p_devdisc_resp(pwdinfo, pframe, len);
6867 case P2P_PROVISION_DISC_REQ:
6868 DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
6869 process_p2p_provdisc_req(pwdinfo, pframe, len);
6870 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
6873 //Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
6874 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6875 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6877 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6878 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6879 #ifdef CONFIG_INTEL_WIDI
6880 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6881 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6882 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6883 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6885 #endif //CONFIG_INTEL_WIDI
6888 case P2P_PROVISION_DISC_RESP:
6889 // Commented by Albert 20110707
6890 // Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
6891 DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
6892 // Commented by Albert 20110426
6893 // The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
6894 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6895 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6896 process_p2p_provdisc_resp(pwdinfo, pframe);
6897 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6908 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6914 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6916 unsigned int ret = _FAIL;
6917 u8 *pframe = precv_frame->u.hdr.rx_data;
6918 uint frame_len = precv_frame->u.hdr.len;
6919 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6921 if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6922 if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
6925 if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
6926 rtw_rframe_del_wfd_ie(precv_frame, 8);
6928 ret = on_action_public_p2p(precv_frame);
6935 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6937 unsigned int ret = _FAIL;
6938 u8 *pframe = precv_frame->u.hdr.rx_data;
6939 uint frame_len = precv_frame->u.hdr.len;
6940 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6942 _adapter *adapter = precv_frame->u.hdr.adapter;
6946 token = frame_body[2];
6948 if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
6951 #ifdef CONFIG_IOCTL_CFG80211
6952 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
6953 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
6962 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6964 unsigned int ret = _FAIL;
6965 u8 *pframe = precv_frame->u.hdr.rx_data;
6966 uint frame_len = precv_frame->u.hdr.len;
6967 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6968 u8 category, action;
6970 /* check RA matches or not */
6971 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6974 category = frame_body[0];
6975 if (category != RTW_WLAN_CATEGORY_PUBLIC)
6978 action = frame_body[1];
6980 case ACT_PUBLIC_BSSCOEXIST:
6981 #ifdef CONFIG_80211N_HT
6982 #ifdef CONFIG_AP_MODE
6983 /*20/40 BSS Coexistence Management frame is a Public Action frame*/
6984 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6985 rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6986 #endif /*CONFIG_AP_MODE*/
6987 #endif /*CONFIG_80211N_HT*/
6989 case ACT_PUBLIC_VENDOR:
6990 ret = on_action_public_vendor(precv_frame);
6993 ret = on_action_public_default(precv_frame, action);
7001 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7003 u8 *pframe = precv_frame->u.hdr.rx_data;
7004 uint frame_len = precv_frame->u.hdr.len;
7005 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7006 u8 category, action;
7008 /* check RA matches or not */
7009 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7012 category = frame_body[0];
7013 if (category != RTW_WLAN_CATEGORY_HT)
7016 action = frame_body[1];
7018 case RTW_WLAN_ACTION_HT_SM_PS:
7019 #ifdef CONFIG_80211N_HT
7020 #ifdef CONFIG_AP_MODE
7021 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7022 rtw_process_ht_action_smps(padapter, GetAddr2Ptr(pframe), frame_body[2]);
7023 #endif /*CONFIG_AP_MODE*/
7024 #endif /*CONFIG_80211N_HT*/
7026 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7027 #ifdef CONFIG_BEAMFORMING
7028 /*DBG_871X("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7029 beamforming_get_report_frame(padapter, precv_frame);
7030 #endif /*CONFIG_BEAMFORMING*/
7041 #ifdef CONFIG_IEEE80211W
7042 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7044 u8 *pframe = precv_frame->u.hdr.rx_data;
7045 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7046 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7047 struct sta_info *psta;
7048 struct sta_priv *pstapriv = &padapter->stapriv;
7049 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7053 DBG_871X("OnAction_sa_query\n");
7055 switch (pframe[WLAN_HDR_A3_LEN+1])
7057 case 0: //SA Query req
7058 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7059 DBG_871X("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7060 , pframe[WLAN_HDR_A3_LEN+1], tid, pframe[WLAN_HDR_A3_LEN+2], pframe[WLAN_HDR_A3_LEN+3]);
7061 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7064 case 1: //SA Query rsp
7065 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
7067 _cancel_timer_ex(&psta->dot11w_expire_timer);
7069 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(u16));
7070 DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], tid);
7078 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7079 for(pp=0;pp< pattrib->pkt_len; pp++)
7080 printk(" %02x ", pframe[pp]);
7086 #endif //CONFIG_IEEE80211W
7088 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7093 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7095 #ifdef CONFIG_80211AC_VHT
7096 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
7097 u8 *pframe = precv_frame->u.hdr.rx_data;
7098 uint frame_len = precv_frame->u.hdr.len;
7099 struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7100 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7101 u8 category, action;
7102 struct sta_info *psta = NULL;
7104 /* check RA matches or not */
7105 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7108 category = frame_body[0];
7109 if(category != RTW_WLAN_CATEGORY_VHT)
7112 action = frame_body[1];
7114 case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7115 #ifdef CONFIG_BEAMFORMING
7116 /*DBG_871X("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7117 beamforming_get_report_frame(padapter, precv_frame);
7118 #endif /*CONFIG_BEAMFORMING*/
7120 case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7121 // CategoryCode(1) + ActionCode(1) + OpModeNotification(1)
7122 //DBG_871X("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n");
7123 psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7125 rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7132 #endif //CONFIG_80211AC_VHT
7137 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7141 u8 category, OUI_Subtype, dialogToken=0;
7142 u8 *pframe = precv_frame->u.hdr.rx_data;
7143 uint len = precv_frame->u.hdr.len;
7144 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
7146 //check RA matches or not
7147 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7150 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7152 category = frame_body[0];
7153 if(category != RTW_WLAN_CATEGORY_P2P)
7156 if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
7159 #ifdef CONFIG_IOCTL_CFG80211
7160 if (adapter_wdev_data(padapter)->p2p_enabled
7161 && pwdinfo->driver_interface == DRIVER_CFG80211
7163 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
7167 #endif //CONFIG_IOCTL_CFG80211
7169 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7170 OUI_Subtype = frame_body[5];
7171 dialogToken = frame_body[6];
7175 case P2P_NOTICE_OF_ABSENCE:
7179 case P2P_PRESENCE_REQUEST:
7181 process_p2p_presence_req(pwdinfo, pframe, len);
7185 case P2P_PRESENCE_RESPONSE:
7189 case P2P_GO_DISC_REQUEST:
7204 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7207 unsigned char category;
7208 struct action_handler *ptable;
7209 unsigned char *frame_body;
7210 u8 *pframe = precv_frame->u.hdr.rx_data;
7212 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7214 category = frame_body[0];
7216 for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
7218 ptable = &OnAction_tbl[i];
7220 if(category == ptable->num)
7221 ptable->func(padapter, precv_frame);
7229 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7232 //DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
7236 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7238 struct xmit_frame *pmgntframe;
7239 struct xmit_buf *pxmitbuf;
7242 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7244 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7246 if (pmgntframe == NULL) {
7247 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7251 if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
7252 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7253 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7258 pmgntframe->frame_tag = MGNT_FRAMETAG;
7259 pmgntframe->pxmitbuf = pxmitbuf;
7260 pmgntframe->buf_addr = pxmitbuf->pbuf;
7261 pxmitbuf->priv_data = pmgntframe;
7268 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7270 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7273 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7275 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7279 /****************************************************************************
7281 Following are some TX fuctions for WiFi MLME
7283 *****************************************************************************/
7285 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7287 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7289 pmlmeext->tx_rate = rate;
7290 //DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
7294 void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7296 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7298 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7299 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7300 struct sta_info *psta = NULL;
7301 struct sta_priv *pstapriv = &padapter->stapriv;
7302 struct sta_info *pbcmc_sta = NULL;
7304 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7305 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7307 pattrib->hdrlen = 24;
7308 pattrib->nr_frags = 1;
7309 pattrib->priority = 7;
7312 pattrib->mac_id = pbcmc_sta->mac_id;
7314 pattrib->mac_id = 0;
7315 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7317 pattrib->qsel = QSLT_MGNT;
7319 pattrib->pktlen = 0;
7321 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7322 wireless_mode = WIRELESS_11B;
7324 wireless_mode = WIRELESS_11G;
7326 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7327 #ifdef CONFIG_80211AC_VHT
7328 if (pHalData->rf_type == RF_1T1R)
7329 pattrib->raid = RATEID_IDX_VHT_1SS;
7330 else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
7331 pattrib->raid = RATEID_IDX_VHT_2SS;
7332 else if (pHalData->rf_type == RF_3T3R)
7333 pattrib->raid = RATEID_IDX_VHT_3SS;
7335 pattrib->raid = RATEID_IDX_BGN_40M_1SS;
7338 #ifdef CONFIG_80211AC_VHT
7339 pattrib->rate = MGN_VHT1SS_MCS9;
7341 pattrib->rate = MGN_MCS7;
7344 pattrib->encrypt = _NO_PRIVACY_;
7345 pattrib->bswenc = _FALSE;
7347 pattrib->qos_en = _FALSE;
7349 pattrib->bwmode = CHANNEL_WIDTH_20;
7350 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7351 pattrib->sgi = _FALSE;
7353 pattrib->seqnum = pmlmeext->mgnt_seq;
7355 pattrib->retry_ctrl = _TRUE;
7357 pattrib->mbssid = 0;
7358 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7363 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7366 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7367 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7368 struct sta_info *psta = NULL;
7369 struct sta_priv *pstapriv = &padapter->stapriv;
7370 struct sta_info *pbcmc_sta = NULL;
7371 //_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
7373 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7375 pattrib->hdrlen = 24;
7376 pattrib->nr_frags = 1;
7377 pattrib->priority = 7;
7380 pattrib->mac_id = pbcmc_sta->mac_id;
7382 pattrib->mac_id = 0;
7383 DBG_871X("mgmt use mac_id 0 will affect RA\n");
7385 pattrib->qsel = QSLT_MGNT;
7387 pattrib->pktlen = 0;
7389 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7390 wireless_mode = WIRELESS_11B;
7392 wireless_mode = WIRELESS_11G;
7393 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7394 pattrib->rate = pmlmeext->tx_rate;
7396 pattrib->encrypt = _NO_PRIVACY_;
7397 pattrib->bswenc = _FALSE;
7399 pattrib->qos_en = _FALSE;
7400 pattrib->ht_en = _FALSE;
7401 pattrib->bwmode = CHANNEL_WIDTH_20;
7402 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7403 pattrib->sgi = _FALSE;
7405 pattrib->seqnum = pmlmeext->mgnt_seq;
7407 pattrib->retry_ctrl = _TRUE;
7409 pattrib->mbssid = 0;
7410 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7412 #ifdef CONFIG_BEAMFORMING
7413 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7415 update_attrib_txbf_info(padapter, pattrib, psta);
7420 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7423 struct pkt_attrib *pattrib = &pmgntframe->attrib;
7425 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7427 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7428 _rtw_memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
7431 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7433 if (RTW_CANNOT_RUN(padapter)) {
7434 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7435 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7439 rtw_hal_mgnt_xmit(padapter, pmgntframe);
7442 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7446 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7447 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7448 struct submit_ctx sctx;
7450 if (RTW_CANNOT_RUN(padapter)) {
7451 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7452 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7456 rtw_sctx_init(&sctx, timeout_ms);
7457 pxmitbuf->sctx = &sctx;
7459 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7461 if (ret == _SUCCESS)
7462 ret = rtw_sctx_wait(&sctx, __func__);
7464 _enter_critical(&pxmitpriv->lock_sctx, &irqL);
7465 pxmitbuf->sctx = NULL;
7466 _exit_critical(&pxmitpriv->lock_sctx, &irqL);
7471 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7473 #ifdef CONFIG_XMIT_ACK
7474 static u8 seq_no = 0;
7476 u32 timeout_ms = 500;// 500ms
7477 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7478 #ifdef CONFIG_CONCURRENT_MODE
7479 if (padapter->pbuddy_adapter && !padapter->isprimary)
7480 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7483 if (RTW_CANNOT_RUN(padapter)) {
7484 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7485 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7489 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7490 pxmitpriv->ack_tx = _TRUE;
7491 pxmitpriv->seq_no = seq_no++;
7492 pmgntframe->ack_report = 1;
7493 rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7494 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7495 #ifdef CONFIG_XMIT_ACK_POLLING
7496 ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7498 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7502 pxmitpriv->ack_tx = _FALSE;
7503 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7506 #else //!CONFIG_XMIT_ACK
7507 dump_mgntframe(padapter, pmgntframe);
7510 #endif //!CONFIG_XMIT_ACK
7513 s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7515 #ifdef CONFIG_XMIT_ACK
7516 static u8 seq_no = 0;
7518 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7519 #ifdef CONFIG_CONCURRENT_MODE
7520 if (padapter->pbuddy_adapter && !padapter->isprimary)
7521 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
7524 if (RTW_CANNOT_RUN(padapter)) {
7525 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7526 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7530 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7531 pxmitpriv->ack_tx = _TRUE;
7532 pxmitpriv->seq_no = seq_no++;
7533 pmgntframe->ack_report = 1;
7534 rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7535 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
7536 #ifdef CONFIG_XMIT_ACK_POLLING
7537 ret = rtw_ack_tx_polling(pxmitpriv, timeout_ms);
7539 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7543 pxmitpriv->ack_tx = _FALSE;
7544 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7547 #else //!CONFIG_XMIT_ACK
7548 dump_mgntframe(padapter, pmgntframe);
7551 #endif //!CONFIG_XMIT_ACK
7554 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7560 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
7562 //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
7564 if(ssid_ie && ssid_len_ori>0)
7566 switch(hidden_ssid_mode)
7570 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7573 remain_len = ies_len -(next_ie-ies);
7576 _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
7577 len_diff -= ssid_len_ori;
7582 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7592 void issue_beacon(_adapter *padapter, int timeout_ms)
7594 struct xmit_frame *pmgntframe;
7595 struct pkt_attrib *pattrib;
7596 unsigned char *pframe;
7597 struct rtw_ieee80211_hdr *pwlanhdr;
7598 unsigned short *fctrl;
7599 unsigned int rate_len;
7600 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7601 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7603 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7604 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7605 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7606 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7607 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7608 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7610 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7614 //DBG_871X("%s\n", __FUNCTION__);
7616 #ifdef CONFIG_BCN_ICF
7617 if ((pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv)) == NULL)
7619 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7622 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7625 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7626 _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7627 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7630 pattrib = &pmgntframe->attrib;
7631 update_mgntframe_attrib(padapter, pattrib);
7632 pattrib->qsel = QSLT_BEACON;
7633 #ifdef CONFIG_CONCURRENT_MODE
7634 if(padapter->iface_type == IFACE_PORT1)
7635 pattrib->mbssid = 1;
7638 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7640 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7641 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7644 fctrl = &(pwlanhdr->frame_ctl);
7647 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7648 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7649 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7651 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7652 //pmlmeext->mgnt_seq++;
7653 SetFrameSubType(pframe, WIFI_BEACON);
7655 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7656 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
7658 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7660 //DBG_871X("ie len=%d\n", cur_network->IELength);
7662 // for P2P : Primary Device Type & Device Name
7663 u32 wpsielen=0, insert_len=0;
7665 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
7667 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
7669 uint wps_offset, remainder_ielen;
7670 u8 *premainder_ie, *pframe_wscie;
7672 wps_offset = (uint)(wpsie - cur_network->IEs);
7674 premainder_ie = wpsie + wpsielen;
7676 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7678 #ifdef CONFIG_IOCTL_CFG80211
7679 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7681 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
7683 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7684 pframe += wps_offset;
7685 pattrib->pktlen += wps_offset;
7687 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7688 pframe += pmlmepriv->wps_beacon_ie_len;
7689 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7691 //copy remainder_ie to pframe
7692 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7693 pframe += remainder_ielen;
7694 pattrib->pktlen += remainder_ielen;
7698 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7699 pframe += cur_network->IELength;
7700 pattrib->pktlen += cur_network->IELength;
7704 #endif //CONFIG_IOCTL_CFG80211
7706 pframe_wscie = pframe + wps_offset;
7707 _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
7708 pframe += (wps_offset + wpsielen);
7709 pattrib->pktlen += (wps_offset + wpsielen);
7711 //now pframe is end of wsc ie, insert Primary Device Type & Device Name
7712 // Primary Device Type
7714 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
7718 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
7723 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7727 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
7731 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7737 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7741 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
7745 _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
7746 insert_len += pwdinfo->device_name_len;
7749 //update wsc ie length
7750 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
7752 //pframe move to end
7754 pattrib->pktlen += insert_len;
7756 //copy remainder_ie to pframe
7757 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7758 pframe += remainder_ielen;
7759 pattrib->pktlen += remainder_ielen;
7766 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7767 len_diff = update_hidden_ssid(
7768 pframe+_BEACON_IE_OFFSET_
7769 , cur_network->IELength-_BEACON_IE_OFFSET_
7770 , pmlmeinfo->hidden_ssid_mode
7772 pframe += (cur_network->IELength+len_diff);
7773 pattrib->pktlen += (cur_network->IELength+len_diff);
7780 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
7781 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
7782 if (wps_ie && wps_ielen>0) {
7783 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
7786 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7788 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7792 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
7795 #ifdef CONFIG_IOCTL_CFG80211
7796 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
7798 len = pmlmepriv->p2p_beacon_ie_len;
7799 if(pmlmepriv->p2p_beacon_ie && len>0)
7800 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7803 #endif //CONFIG_IOCTL_CFG80211
7805 len = build_beacon_p2p_ie(pwdinfo, pframe);
7809 pattrib->pktlen += len;
7812 len = rtw_append_beacon_wfd_ie(padapter, pframe);
7814 pattrib->pktlen += len;
7823 //below for ad-hoc mode
7825 //timestamp will be inserted by hardware
7827 pattrib->pktlen += 8;
7829 // beacon interval: 2 bytes
7831 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7834 pattrib->pktlen += 2;
7836 // capability info: 2 bytes
7838 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7841 pattrib->pktlen += 2;
7844 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7846 // supported rates...
7847 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7848 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7851 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7853 //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
7857 // IBSS Parameter Set...
7858 //ATIMWindow = cur->Configuration.ATIMWindow;
7860 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7863 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7867 // EXTERNDED SUPPORTED RATE
7870 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7878 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7879 pmlmepriv->update_bcn = _FALSE;
7881 _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7882 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7884 if ((pattrib->pktlen + TXDESC_SIZE) > 512)
7886 DBG_871X("beacon frame too large\n");
7890 pattrib->last_txcmdsz = pattrib->pktlen;
7892 //DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
7894 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7896 dump_mgntframe(padapter, pmgntframe);
7900 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7902 struct xmit_frame *pmgntframe;
7903 struct pkt_attrib *pattrib;
7904 unsigned char *pframe;
7905 struct rtw_ieee80211_hdr *pwlanhdr;
7906 unsigned short *fctrl;
7907 unsigned char *mac, *bssid;
7908 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7909 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7912 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7913 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7914 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7915 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7916 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7917 unsigned int rate_len;
7919 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7925 //DBG_871X("%s\n", __FUNCTION__);
7930 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
7933 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7935 DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
7941 pattrib = &pmgntframe->attrib;
7942 update_mgntframe_attrib(padapter, pattrib);
7944 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7946 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7947 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7949 mac = adapter_mac_addr(padapter);
7950 bssid = cur_network->MacAddress;
7952 fctrl = &(pwlanhdr->frame_ctl);
7954 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7955 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7956 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7958 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7959 pmlmeext->mgnt_seq++;
7960 SetFrameSubType(fctrl, WIFI_PROBERSP);
7962 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7963 pattrib->pktlen = pattrib->hdrlen;
7964 pframe += pattrib->hdrlen;
7967 if(cur_network->IELength>MAX_IE_SZ)
7970 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7971 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7973 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
7975 //inerset & update wps_probe_resp_ie
7976 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
7978 uint wps_offset, remainder_ielen;
7981 wps_offset = (uint)(pwps_ie - cur_network->IEs);
7983 premainder_ie = pwps_ie + wps_ielen;
7985 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
7987 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7988 pframe += wps_offset;
7989 pattrib->pktlen += wps_offset;
7991 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
7992 if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
7994 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
7995 pframe += wps_ielen+2;
7996 pattrib->pktlen += wps_ielen+2;
7999 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
8001 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8002 pframe += remainder_ielen;
8003 pattrib->pktlen += remainder_ielen;
8008 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8009 pframe += cur_network->IELength;
8010 pattrib->pktlen += cur_network->IELength;
8013 /* retrieve SSID IE from cur_network->Ssid */
8017 sint ssid_ielen_diff;
8019 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
8021 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
8022 (pframe-ies)-_FIXED_IE_LENGTH_);
8024 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
8026 if (ssid_ie && cur_network->Ssid.SsidLength) {
8027 uint remainder_ielen;
8029 remainder_ie = ssid_ie+2;
8030 remainder_ielen = (pframe-remainder_ie);
8032 if (remainder_ielen > MAX_IE_SZ) {
8033 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
8034 remainder_ielen = MAX_IE_SZ;
8037 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
8038 _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
8039 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
8040 _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8042 pframe += ssid_ielen_diff;
8043 pattrib->pktlen += ssid_ielen_diff;
8051 //timestamp will be inserted by hardware
8053 pattrib->pktlen += 8;
8055 // beacon interval: 2 bytes
8057 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8060 pattrib->pktlen += 2;
8062 // capability info: 2 bytes
8064 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8067 pattrib->pktlen += 2;
8069 //below for ad-hoc mode
8072 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8074 // supported rates...
8075 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8076 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8079 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8081 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
8085 // IBSS Parameter Set...
8086 //ATIMWindow = cur->Configuration.ATIMWindow;
8088 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8091 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8095 // EXTERNDED SUPPORTED RATE
8098 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8107 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8108 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8109 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec))
8112 #ifdef CONFIG_IOCTL_CFG80211
8113 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
8115 //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
8116 len = pmlmepriv->p2p_go_probe_resp_ie_len;
8117 if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
8118 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8121 #endif //CONFIG_IOCTL_CFG80211
8123 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8127 pattrib->pktlen += len;
8130 len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8132 pattrib->pktlen += len;
8138 #ifdef CONFIG_AUTO_AP_MODE
8140 struct sta_info *psta;
8141 struct sta_priv *pstapriv = &padapter->stapriv;
8143 DBG_871X("(%s)\n", __FUNCTION__);
8146 psta = rtw_get_stainfo(pstapriv, da);
8147 if (psta && psta->isrc && psta->pid>0)
8149 u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
8150 u8 RC_INFO[14] = {0};
8151 //EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
8152 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8154 DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8155 psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
8157 //append vendor specific ie
8158 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8159 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8160 _rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
8161 _rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
8163 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8166 #endif //CONFIG_AUTO_AP_MODE
8169 pattrib->last_txcmdsz = pattrib->pktlen;
8172 dump_mgntframe(padapter, pmgntframe);
8178 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
8181 struct xmit_frame *pmgntframe;
8182 struct pkt_attrib *pattrib;
8183 unsigned char *pframe;
8184 struct rtw_ieee80211_hdr *pwlanhdr;
8185 unsigned short *fctrl;
8187 unsigned char bssrate[NumRates];
8188 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8189 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8190 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8191 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8192 int bssrate_len = 0;
8193 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8195 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8198 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8204 pattrib = &pmgntframe->attrib;
8205 update_mgntframe_attrib(padapter, pattrib);
8208 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8210 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8211 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8213 mac = adapter_mac_addr(padapter);
8215 fctrl = &(pwlanhdr->frame_ctl);
8220 // unicast probe request frame
8221 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8222 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8226 // broadcast probe request frame
8227 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8228 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8231 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8233 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8234 pmlmeext->mgnt_seq++;
8235 SetFrameSubType(pframe, WIFI_PROBEREQ);
8237 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
8238 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
8241 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8243 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8245 get_rate_set(padapter, bssrate, &bssrate_len);
8247 if (bssrate_len > 8)
8249 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8250 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8254 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8258 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8261 //add wps_ie for wps2.0
8262 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
8264 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8265 pframe += pmlmepriv->wps_probe_req_ie_len;
8266 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8267 //pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
8271 pattrib->last_txcmdsz = pattrib->pktlen;
8273 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
8276 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8278 dump_mgntframe(padapter, pmgntframe);
8286 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
8288 _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8292 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8293 * 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
8294 * try_cnt means the maximal TX count to try
8296 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
8297 int try_cnt, int wait_ms)
8301 u32 start = rtw_get_current_time();
8303 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8308 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms>0?_TRUE:_FALSE);
8312 if (RTW_CANNOT_RUN(padapter))
8315 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
8316 rtw_msleep_os(wait_ms);
8318 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
8322 #ifndef DBG_XMIT_ACK
8327 if (try_cnt && wait_ms) {
8329 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8330 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8331 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8333 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8334 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8335 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
8341 // if psta == NULL, indiate we are station(client) now...
8342 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8344 struct xmit_frame *pmgntframe;
8345 struct pkt_attrib *pattrib;
8346 unsigned char *pframe;
8347 struct rtw_ieee80211_hdr *pwlanhdr;
8348 unsigned short *fctrl;
8350 unsigned short val16;
8351 int use_shared_key = 0;
8352 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8353 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8354 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8356 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8359 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8365 pattrib = &pmgntframe->attrib;
8366 update_mgntframe_attrib(padapter, pattrib);
8368 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8370 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8371 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8373 fctrl = &(pwlanhdr->frame_ctl);
8376 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8377 pmlmeext->mgnt_seq++;
8378 SetFrameSubType(pframe, WIFI_AUTH);
8380 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8381 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8384 if(psta)// for AP mode
8386 #ifdef CONFIG_NATIVEAP_MLME
8388 _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
8389 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8390 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8393 // setting auth algo number
8394 val16 = (u16)psta->authalg;
8396 if(status != _STATS_SUCCESSFUL_)
8400 val16 = cpu_to_le16(val16);
8404 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8406 // setting auth seq number
8407 val16 =(u16)psta->auth_seq;
8408 val16 = cpu_to_le16(val16);
8409 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8411 // setting status code...
8413 val16 = cpu_to_le16(val16);
8414 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8416 // added challenging text...
8417 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8419 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8425 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8426 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8427 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8429 // setting auth algo number
8430 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
8432 val16 = cpu_to_le16(val16);
8435 //DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
8437 //setting IV for auth seq #3
8438 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8440 //DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
8441 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8442 val32 = cpu_to_le32(val32);
8443 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8445 pattrib->iv_len = 4;
8448 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8450 // setting auth seq number
8451 val16 = pmlmeinfo->auth_seq;
8452 val16 = cpu_to_le16(val16);
8453 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8456 // setting status code...
8458 val16 = cpu_to_le16(val16);
8459 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8461 // then checking to see if sending challenging text...
8462 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
8464 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8468 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8470 pattrib->encrypt = _WEP40_;
8472 pattrib->icv_len = 4;
8474 pattrib->pktlen += pattrib->icv_len;
8480 pattrib->last_txcmdsz = pattrib->pktlen;
8482 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8483 DBG_871X("%s\n", __FUNCTION__);
8484 dump_mgntframe(padapter, pmgntframe);
8490 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8492 #ifdef CONFIG_AP_MODE
8493 struct xmit_frame *pmgntframe;
8494 struct rtw_ieee80211_hdr *pwlanhdr;
8495 struct pkt_attrib *pattrib;
8496 unsigned char *pbuf, *pframe;
8497 unsigned short val, ie_status;
8498 unsigned short *fctrl;
8499 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8500 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8501 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8502 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8503 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8504 u8 *ie = pnetwork->IEs;
8506 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8513 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8516 DBG_871X("%s\n", __FUNCTION__);
8518 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8524 pattrib = &pmgntframe->attrib;
8525 update_mgntframe_attrib(padapter, pattrib);
8528 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8530 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8531 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8533 fctrl = &(pwlanhdr->frame_ctl);
8536 _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
8537 _rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8538 _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8541 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8542 pmlmeext->mgnt_seq++;
8543 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8544 SetFrameSubType(pwlanhdr, pkt_type);
8548 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8549 pattrib->pktlen += pattrib->hdrlen;
8550 pframe += pattrib->hdrlen;
8553 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8555 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8557 ie_status = cpu_to_le16(status);
8558 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8560 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
8561 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8563 if (pstat->bssratelen <= 8)
8565 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8569 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8570 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
8573 #ifdef CONFIG_IEEE80211W
8574 if (status == _STATS_REFUSED_TEMPORARILY_) {
8576 u32 timeout_interval = 3000;
8577 /* Association Comeback time */
8578 timeout_itvl[0] = 0x03;
8579 timeout_interval = cpu_to_le32(timeout_interval);
8580 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
8581 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8583 #endif /* CONFIG_IEEE80211W */
8585 #ifdef CONFIG_80211N_HT
8586 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
8590 //FILL HT CAP INFO IE
8591 //p = hostapd_eid_ht_capabilities_info(hapd, p);
8592 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8593 if(pbuf && ie_len>0)
8595 _rtw_memcpy(pframe, pbuf, ie_len+2);
8596 pframe += (ie_len+2);
8597 pattrib->pktlen +=(ie_len+2);
8600 //FILL HT ADD INFO IE
8601 //p = hostapd_eid_ht_operation(hapd, p);
8602 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8603 if(pbuf && ie_len>0)
8605 _rtw_memcpy(pframe, pbuf, ie_len+2);
8606 pframe += (ie_len+2);
8607 pattrib->pktlen +=(ie_len+2);
8613 /*adding EXT_CAPAB_IE */
8614 if (pmlmepriv->ext_capab_ie_len > 0) {
8617 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8618 if (pbuf && ie_len > 0) {
8619 _rtw_memcpy(pframe, pbuf, ie_len+2);
8620 pframe += (ie_len+2);
8621 pattrib->pktlen += (ie_len+2);
8625 #ifdef CONFIG_80211AC_VHT
8626 if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8627 && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8628 && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP))
8633 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8634 if(pbuf && ie_len>0)
8636 _rtw_memcpy(pframe, pbuf, ie_len+2);
8637 pframe += (ie_len+2);
8638 pattrib->pktlen +=(ie_len+2);
8641 //FILL VHT OPERATION IE
8642 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8643 if(pbuf && ie_len>0)
8645 _rtw_memcpy(pframe, pbuf, ie_len+2);
8646 pframe += (ie_len+2);
8647 pattrib->pktlen +=(ie_len+2);
8650 #endif //CONFIG_80211AC_VHT
8653 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
8656 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
8658 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
8660 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
8661 if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
8663 _rtw_memcpy(pframe, pbuf, ie_len+2);
8664 pframe += (ie_len+2);
8665 pattrib->pktlen +=(ie_len+2);
8670 if ((pbuf == NULL) || (ie_len == 0))
8679 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8681 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8684 //add WPS IE ie for wps 2.0
8685 if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
8687 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8689 pframe += pmlmepriv->wps_assoc_resp_ie_len;
8690 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8694 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
8697 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
8699 if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
8700 len = pmlmepriv->p2p_assoc_resp_ie_len;
8701 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
8704 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8707 pattrib->pktlen += len;
8711 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8712 wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
8714 pattrib->pktlen += wfdielen;
8718 #endif /* CONFIG_P2P */
8720 pattrib->last_txcmdsz = pattrib->pktlen;
8722 dump_mgntframe(padapter, pmgntframe);
8727 void issue_assocreq(_adapter *padapter)
8730 struct xmit_frame *pmgntframe;
8731 struct pkt_attrib *pattrib;
8732 unsigned char *pframe, *p;
8733 struct rtw_ieee80211_hdr *pwlanhdr;
8734 unsigned short *fctrl;
8735 unsigned short val16;
8736 unsigned int i, j, ie_len, index=0;
8737 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8738 PNDIS_802_11_VARIABLE_IEs pIE;
8739 struct registry_priv *pregpriv = &padapter->registrypriv;
8740 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8741 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8742 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8743 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8744 int bssrate_len = 0, sta_bssrate_len = 0;
8745 u8 vs_ie_length = 0;
8747 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8748 u8 p2pie[ 255 ] = { 0x00 };
8759 u8 pow_cap_ele[2] = { 0x00 };
8760 u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
8763 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
8766 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8770 pattrib = &pmgntframe->attrib;
8771 update_mgntframe_attrib(padapter, pattrib);
8774 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8776 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8777 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8779 fctrl = &(pwlanhdr->frame_ctl);
8781 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8782 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8783 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8785 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8786 pmlmeext->mgnt_seq++;
8787 SetFrameSubType(pframe, WIFI_ASSOCREQ);
8789 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8790 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8795 _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8796 cap |= cap_SpecMgmt;
8797 _rtw_memcpy(pframe, &cap, 2);
8799 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8803 pattrib->pktlen += 2;
8806 //todo: listen interval for power saving
8807 val16 = cpu_to_le16(3);
8808 _rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
8810 pattrib->pktlen += 2;
8813 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8817 if(pmlmeext->cur_channel > 14)
8819 pow_cap_ele[0] = 13; // Minimum transmit power capability
8820 pow_cap_ele[1] = 21; // Maximum transmit power capability
8821 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8823 //supported channels
8825 if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
8827 sup_ch[0] = 1; //First channel number
8828 sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel
8832 sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8833 sup_ch[idx_5g++] = 1;
8837 while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
8838 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8842 //supported rate & extended supported rate
8844 #if 1 // Check if the AP's supported rates are also supported by STA.
8845 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8846 //DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
8848 if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
8850 sta_bssrate_len = 4;
8854 //for (i = 0; i < sta_bssrate_len; i++) {
8855 // DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
8858 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8859 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8860 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8864 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8865 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
8868 // Check if the AP's supported rates are also supported by STA.
8869 for (j=0; j < sta_bssrate_len; j++) {
8870 // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8871 if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
8872 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
8873 //DBG_871X("match i = %d, j=%d\n", i, j);
8876 //DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
8880 if (j == sta_bssrate_len) {
8881 // the rate is not supported by STA
8882 DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8884 // the rate is supported by STA
8885 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8889 bssrate_len = index;
8890 DBG_871X("bssrate_len = %d\n", bssrate_len);
8892 #else // Check if the AP's supported rates are also supported by STA.
8894 get_rate_set(padapter, bssrate, &bssrate_len);
8896 for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8897 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
8899 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
8902 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8905 #endif // Check if the AP's supported rates are also supported by STA.
8907 if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8908 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8909 rtw_free_xmitframe(pxmitpriv, pmgntframe);
8910 goto exit; //don't connect to AP if no joint supported rate
8914 if (bssrate_len > 8)
8916 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8917 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8919 else if (bssrate_len > 0)
8921 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8923 DBG_871X("%s: Connect to AP without 11b and 11g data rate!\n",__FUNCTION__);
8926 //vendor specific IE, such as WPA, WMM, WPS
8927 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
8929 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8931 switch (pIE->ElementID)
8933 case _VENDOR_SPECIFIC_IE_:
8934 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8935 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8936 (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8938 vs_ie_length = pIE->Length;
8939 if((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4)))
8941 //Commented by Kurt 20110629
8942 //In some older APs, WPS handshake
8943 //would be fail if we append vender extensions informations to AP
8948 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8953 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8955 #ifdef CONFIG_80211N_HT
8956 case EID_HTCapability:
8957 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8958 if (!(is_ap_in_tkip(padapter)))
8960 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8962 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8964 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8969 case EID_EXTCapability:
8970 if(padapter->mlmepriv.htpriv.ht_option==_TRUE) {
8971 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8974 #endif //CONFIG_80211N_HT
8975 #ifdef CONFIG_80211AC_VHT
8976 case EID_VHTCapability:
8977 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8978 pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
8982 case EID_OpModeNotification:
8983 if (padapter->mlmepriv.vhtpriv.vht_option ==_TRUE) {
8984 pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
8987 #endif // CONFIG_80211AC_VHT
8992 i += (pIE->Length + 2);
8995 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8997 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
9001 #ifdef CONFIG_WAPI_SUPPORT
9002 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
9008 #ifdef CONFIG_IOCTL_CFG80211
9009 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
9011 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
9013 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
9014 pframe += pmlmepriv->p2p_assoc_req_ie_len;
9015 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
9019 #endif //CONFIG_IOCTL_CFG80211
9021 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
9023 // Should add the P2P IE in the association request frame.
9027 p2pie[ p2pielen++ ] = 0x50;
9028 p2pie[ p2pielen++ ] = 0x6F;
9029 p2pie[ p2pielen++ ] = 0x9A;
9030 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
9032 // Commented by Albert 20101109
9033 // According to the P2P Specification, the association request frame should contain 3 P2P attributes
9034 // 1. P2P Capability
9035 // 2. Extended Listen Timing
9037 // Commented by Albert 20110516
9042 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
9045 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
9049 // Device Capability Bitmap, 1 byte
9050 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
9052 // Group Capability Bitmap, 1 byte
9053 if ( pwdinfo->persistent_supported )
9054 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9056 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
9058 // Extended Listen Timing
9060 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
9063 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
9067 // Availability Period
9068 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9071 // Availability Interval
9072 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
9077 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
9080 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
9081 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
9082 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
9086 // P2P Device Address
9087 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9088 p2pielen += ETH_ALEN;
9091 // This field should be big endian. Noted by P2P specification.
9092 if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
9093 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
9095 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
9099 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
9104 // Primary Device Type
9106 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
9110 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
9114 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
9117 // Number of Secondary Device Types
9118 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
9122 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
9126 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
9130 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
9131 p2pielen += pwdinfo->device_name_len;
9135 p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
9138 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
9142 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Device Address
9143 p2pielen += ETH_ALEN;
9145 p2pie[ p2pielen++ ] = 1; // P2P Interface Address Count
9147 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); // P2P Interface Address List
9148 p2pielen += ETH_ALEN;
9150 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
9157 wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
9159 pattrib->pktlen += wfdielen;
9162 pattrib->last_txcmdsz = pattrib->pktlen;
9163 dump_mgntframe(padapter, pmgntframe);
9168 if (ret == _SUCCESS)
9169 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9171 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9176 //when wait_ack is ture, this function shoule be called at process context
9177 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9180 struct xmit_frame *pmgntframe;
9181 struct pkt_attrib *pattrib;
9182 unsigned char *pframe;
9183 struct rtw_ieee80211_hdr *pwlanhdr;
9184 unsigned short *fctrl;
9185 struct xmit_priv *pxmitpriv;
9186 struct mlme_ext_priv *pmlmeext;
9187 struct mlme_ext_info *pmlmeinfo;
9189 //DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
9194 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9197 pxmitpriv = &(padapter->xmitpriv);
9198 pmlmeext = &(padapter->mlmeextpriv);
9199 pmlmeinfo = &(pmlmeext->mlmext_info);
9201 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9207 pattrib = &pmgntframe->attrib;
9208 update_mgntframe_attrib(padapter, pattrib);
9209 pattrib->retry_ctrl = _FALSE;
9211 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9213 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9214 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9216 fctrl = &(pwlanhdr->frame_ctl);
9219 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9223 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9233 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9234 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9235 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9237 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9238 pmlmeext->mgnt_seq++;
9239 SetFrameSubType(pframe, WIFI_DATA_NULL);
9241 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9242 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9244 pattrib->last_txcmdsz = pattrib->pktlen;
9248 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9252 dump_mgntframe(padapter, pmgntframe);
9261 * [IMPORTANT] Don't call this function in interrupt context
9263 * When wait_ms > 0, this function should be called at process context
9264 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9265 * 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
9266 * try_cnt means the maximal TX count to try
9267 * da == NULL for station mode
9269 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9273 u32 start = rtw_get_current_time();
9274 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9275 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9276 struct sta_info *psta;
9278 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9281 /* da == NULL, assum it's null data for sta to ap*/
9283 da = get_my_bssid(&(pmlmeinfo->network));
9285 psta = rtw_get_stainfo(&padapter->stapriv, da);
9288 rtw_hal_macid_sleep(padapter, psta->mac_id);
9290 rtw_hal_macid_wakeup(padapter, psta->mac_id);
9292 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
9293 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
9298 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
9302 if (RTW_CANNOT_RUN(padapter))
9305 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9306 rtw_msleep_os(wait_ms);
9308 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9312 #ifndef DBG_XMIT_ACK
9317 if (try_cnt && wait_ms) {
9319 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9320 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9321 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9323 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9324 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9325 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9332 * [IMPORTANT] This function run in interrupt context
9334 * The null data packet would be sent without power bit,
9335 * and not guarantee success.
9337 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
9340 struct mlme_ext_priv *pmlmeext;
9341 struct mlme_ext_info *pmlmeinfo;
9344 pmlmeext = &padapter->mlmeextpriv;
9345 pmlmeinfo = &pmlmeext->mlmext_info;
9347 /* da == NULL, assum it's null data for sta to ap*/
9349 da = get_my_bssid(&(pmlmeinfo->network));
9351 ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
9356 //when wait_ack is ture, this function shoule be called at process context
9357 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
9360 struct xmit_frame *pmgntframe;
9361 struct pkt_attrib *pattrib;
9362 unsigned char *pframe;
9363 struct rtw_ieee80211_hdr *pwlanhdr;
9364 unsigned short *fctrl, *qc;
9365 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9366 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9367 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9369 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9372 DBG_871X("%s\n", __FUNCTION__);
9374 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9380 pattrib = &pmgntframe->attrib;
9381 update_mgntframe_attrib(padapter, pattrib);
9383 pattrib->hdrlen +=2;
9384 pattrib->qos_en = _TRUE;
9386 pattrib->ack_policy = 0;
9389 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9391 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9392 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9394 fctrl = &(pwlanhdr->frame_ctl);
9397 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9401 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9409 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9411 SetPriority(qc, tid);
9413 SetEOSP(qc, pattrib->eosp);
9415 SetAckpolicy(qc, pattrib->ack_policy);
9417 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9418 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9419 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9421 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9422 pmlmeext->mgnt_seq++;
9423 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
9425 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9426 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9428 pattrib->last_txcmdsz = pattrib->pktlen;
9432 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9436 dump_mgntframe(padapter, pmgntframe);
9445 * when wait_ms >0 , this function should be called at process context
9446 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9447 * 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
9448 * try_cnt means the maximal TX count to try
9449 * da == NULL for station mode
9451 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
9455 u32 start = rtw_get_current_time();
9456 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9457 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9459 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9462 /* da == NULL, assum it's null data for sta to ap*/
9464 da = get_my_bssid(&(pmlmeinfo->network));
9468 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
9472 if (RTW_CANNOT_RUN(padapter))
9475 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9476 rtw_msleep_os(wait_ms);
9478 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9482 #ifndef DBG_XMIT_ACK
9487 if (try_cnt && wait_ms) {
9489 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9490 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9491 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9493 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9494 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9495 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9501 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9503 struct xmit_frame *pmgntframe;
9504 struct pkt_attrib *pattrib;
9505 unsigned char *pframe;
9506 struct rtw_ieee80211_hdr *pwlanhdr;
9507 unsigned short *fctrl;
9508 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9509 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9510 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9513 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
9516 //DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9519 if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
9521 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
9522 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
9526 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9529 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9535 pattrib = &pmgntframe->attrib;
9536 update_mgntframe_attrib(padapter, pattrib);
9537 pattrib->retry_ctrl = _FALSE;
9538 pattrib->key_type = key_type;
9539 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9541 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9542 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9544 fctrl = &(pwlanhdr->frame_ctl);
9547 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9548 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9549 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9551 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9552 pmlmeext->mgnt_seq++;
9553 SetFrameSubType(pframe, WIFI_DEAUTH);
9555 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9556 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9558 reason = cpu_to_le16(reason);
9559 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9561 pattrib->last_txcmdsz = pattrib->pktlen;
9566 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9570 dump_mgntframe(padapter, pmgntframe);
9578 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9580 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9581 return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9584 #ifdef CONFIG_IEEE80211W
9585 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9587 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9588 return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9590 #endif /* CONFIG_IEEE80211W */
9593 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9594 * 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
9595 * try_cnt means the maximal TX count to try
9597 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9602 u32 start = rtw_get_current_time();
9604 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9609 ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE:_FALSE, IEEE80211W_RIGHT_KEY);
9613 if (RTW_CANNOT_RUN(padapter))
9616 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
9617 rtw_msleep_os(wait_ms);
9619 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
9623 #ifndef DBG_XMIT_ACK
9628 if (try_cnt && wait_ms) {
9630 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9631 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9632 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9634 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9635 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9636 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
9642 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9645 _list *plist, *phead;
9646 struct xmit_frame *pmgntframe;
9647 struct pkt_attrib *pattrib;
9648 unsigned char *pframe;
9649 struct rtw_ieee80211_hdr *pwlanhdr;
9650 unsigned short *fctrl;
9651 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9652 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9653 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9654 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9656 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9659 DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9660 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9662 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9666 pattrib = &pmgntframe->attrib;
9667 update_mgntframe_attrib(padapter, pattrib);
9669 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9671 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9672 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9674 fctrl = &(pwlanhdr->frame_ctl);
9677 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9678 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9679 _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9681 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9682 pmlmeext->mgnt_seq++;
9683 SetFrameSubType(pframe, WIFI_ACTION);
9685 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9686 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9688 /* category, action */
9690 u8 category, action;
9691 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9692 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9694 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9695 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9698 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9699 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9700 hal_ch_offset_to_secondary_ch_offset(ch_offset));
9702 pattrib->last_txcmdsz = pattrib->pktlen;
9704 dump_mgntframe(padapter, pmgntframe);
9708 #ifdef CONFIG_IEEE80211W
9709 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9711 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
9713 struct xmit_frame *pmgntframe;
9714 struct pkt_attrib *pattrib;
9716 struct rtw_ieee80211_hdr *pwlanhdr;
9718 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9719 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9720 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9721 struct sta_info *psta;
9722 struct sta_priv *pstapriv = &padapter->stapriv;
9723 struct registry_priv *pregpriv = &padapter->registrypriv;
9724 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9726 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9729 DBG_871X("%s, %04x\n", __FUNCTION__, tid);
9731 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9733 DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9738 pattrib = &pmgntframe->attrib;
9739 update_mgntframe_attrib(padapter, pattrib);
9740 pattrib->key_type = key_type;
9741 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9743 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9744 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9746 fctrl = &(pwlanhdr->frame_ctl);
9750 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9752 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9753 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9754 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9756 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9757 pmlmeext->mgnt_seq++;
9758 SetFrameSubType(pframe, WIFI_ACTION);
9760 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9761 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9763 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9764 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9768 case 0: //SA Query req
9769 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9770 pmlmeext->sa_query_seq++;
9771 /* send sa query request to AP, AP should reply sa query response in 1 second */
9772 if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9773 psta = rtw_get_stainfo(pstapriv, raddr);
9775 /* DBG_871X("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9776 _set_timer(&psta->dot11w_expire_timer, 1000);
9781 case 1: //SA Query rsp
9782 tid = cpu_to_le16(tid);
9783 /* DBG_871X("rtw_set_fixed_ie, %04x\n", tid); */
9784 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9790 pattrib->last_txcmdsz = pattrib->pktlen;
9792 dump_mgntframe(padapter, pmgntframe);
9794 #endif //CONFIG_IEEE80211W
9797 * issue_action_ba - internal function to TX Block Ack action frame
9798 * @padapter: the adapter to TX
9799 * @raddr: receiver address
9800 * @action: Block Ack Action
9802 * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9803 * @status: status/reason code. used by ADDBA_RESP, DELBA
9804 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9805 * @wait_ack: used xmit ack
9808 * _SUCCESS: No xmit ack is used or acked
9809 * _FAIL: not acked when using xmit ack
9811 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9812 , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9815 u8 category = RTW_WLAN_CATEGORY_BACK;
9818 u16 BA_timeout_value;
9819 u16 BA_starting_seqctrl;
9820 struct xmit_frame *pmgntframe;
9821 struct pkt_attrib *pattrib;
9823 struct rtw_ieee80211_hdr *pwlanhdr;
9825 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9826 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9827 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9828 struct sta_info *psta;
9829 struct sta_priv *pstapriv = &padapter->stapriv;
9830 struct registry_priv *pregpriv = &padapter->registrypriv;
9832 #ifdef CONFIG_80211N_HT
9834 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
9837 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
9841 pattrib = &pmgntframe->attrib;
9842 update_mgntframe_attrib(padapter, pattrib);
9844 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9846 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9847 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9849 fctrl = &(pwlanhdr->frame_ctl);
9852 //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9853 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9854 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9855 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9857 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9858 pmlmeext->mgnt_seq++;
9859 SetFrameSubType(pframe, WIFI_ACTION);
9861 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9862 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9864 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9865 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9871 case RTW_WLAN_ACTION_ADDBA_REQ:
9873 pmlmeinfo->dialogToken++;
9874 } while (pmlmeinfo->dialogToken == 0);
9875 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9877 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9878 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9880 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9883 BA_para_set = cpu_to_le16(BA_para_set);
9884 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9886 //BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
9887 BA_timeout_value = 5000;//~ 5ms
9888 BA_timeout_value = cpu_to_le16(BA_timeout_value);
9889 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9891 //if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
9892 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
9894 start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07]&0xfff) + 1;
9896 DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9898 psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9900 BA_starting_seqctrl = start_seq << 4;
9903 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9904 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9907 case RTW_WLAN_ACTION_ADDBA_RESP:
9908 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9909 status = cpu_to_le16(status);
9910 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9912 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9914 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9915 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9917 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9918 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9920 if (!padapter->registrypriv.wifi_spec) {
9921 if(pregpriv->ampdu_amsdu==0)//disabled
9922 BA_para_set &= ~BIT(0);
9923 else if(pregpriv->ampdu_amsdu==1)//enabled
9924 BA_para_set |= BIT(0);
9927 BA_para_set = cpu_to_le16(BA_para_set);
9929 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9930 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9933 case RTW_WLAN_ACTION_DELBA:
9935 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9936 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9938 BA_para_set = cpu_to_le16(BA_para_set);
9939 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9940 status = cpu_to_le16(status);
9941 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9948 pattrib->last_txcmdsz = pattrib->pktlen;
9951 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9953 dump_mgntframe(padapter, pmgntframe);
9958 #endif //CONFIG_80211N_HT
9963 * issue_addba_req - TX ADDBA_REQ
9964 * @adapter: the adapter to TX
9965 * @ra: receiver address
9968 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
9970 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
9977 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
9978 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
9983 * issue_addba_rsp - TX ADDBA_RESP
9984 * @adapter: the adapter to TX
9985 * @ra: receiver address
9987 * @status: status code
9988 * @size: the announced AMPDU buffer size
9990 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
9992 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
9999 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
10000 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
10004 * issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
10005 * @adapter: the adapter to TX
10006 * @ra: receiver address
10008 * @status: status code
10009 * @size: the announced AMPDU buffer size
10010 * @try_cnt: the maximal TX count to try
10011 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10012 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10014 inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
10018 u32 start = rtw_get_current_time();
10020 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
10024 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10034 if (RTW_CANNOT_RUN(adapter))
10037 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10038 rtw_msleep_os(wait_ms);
10040 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10042 if (ret != _FAIL) {
10044 #ifndef DBG_XMIT_ACK
10049 if (try_cnt && wait_ms) {
10050 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u%s, %d/%d in %u ms\n"
10051 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid
10052 , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10060 * issue_del_ba - TX DELBA
10061 * @adapter: the adapter to TX
10062 * @ra: receiver address
10064 * @reason: reason code
10065 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10067 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10069 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10076 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10077 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10081 * issue_del_ba_ex - TX DELBA with xmit ack options
10082 * @adapter: the adapter to TX
10083 * @ra: receiver address
10085 * @reason: reason code
10086 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10087 * @try_cnt: the maximal TX count to try
10088 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10089 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10091 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10092 , int try_cnt, int wait_ms)
10096 u32 start = rtw_get_current_time();
10098 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(adapter)))
10102 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10107 , wait_ms > 0?_TRUE:_FALSE
10112 if (RTW_CANNOT_RUN(adapter))
10115 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10116 rtw_msleep_os(wait_ms);
10118 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10120 if (ret != _FAIL) {
10122 #ifndef DBG_XMIT_ACK
10127 if (try_cnt && wait_ms) {
10128 DBG_871X(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
10129 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
10130 , ret == _SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10136 static void issue_action_BSSCoexistPacket(_adapter *padapter)
10139 _list *plist, *phead;
10140 unsigned char category, action;
10141 struct xmit_frame *pmgntframe;
10142 struct pkt_attrib *pattrib;
10143 unsigned char *pframe;
10144 struct rtw_ieee80211_hdr *pwlanhdr;
10145 unsigned short *fctrl;
10146 struct wlan_network *pnetwork = NULL;
10147 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10148 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10149 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10150 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10151 _queue *queue = &(pmlmepriv->scanned_queue);
10152 u8 InfoContent[16] = {0};
10154 #ifdef CONFIG_80211N_HT
10155 if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
10158 if(_TRUE == pmlmeinfo->bwmode_updated)
10161 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10164 DBG_871X("%s\n", __FUNCTION__);
10167 category = RTW_WLAN_CATEGORY_PUBLIC;
10168 action = ACT_PUBLIC_BSSCOEXIST;
10170 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10176 pattrib = &pmgntframe->attrib;
10177 update_mgntframe_attrib(padapter, pattrib);
10179 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10181 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10182 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10184 fctrl = &(pwlanhdr->frame_ctl);
10187 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10188 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10189 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10191 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10192 pmlmeext->mgnt_seq++;
10193 SetFrameSubType(pframe, WIFI_ACTION);
10195 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10196 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10198 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10199 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10203 if(pmlmepriv->num_FortyMHzIntolerant>0)
10207 iedata |= BIT(2);//20 MHz BSS Width Request
10209 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
10215 _rtw_memset(ICS, 0, sizeof(ICS));
10216 if(pmlmepriv->num_sta_no_ht>0)
10220 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10222 phead = get_list_head(queue);
10223 plist = get_next(phead);
10229 WLAN_BSSID_EX *pbss_network;
10231 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
10234 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
10236 plist = get_next(plist);
10238 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10240 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10241 if((p==NULL) || (len==0))//non-HT
10243 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
10246 ICS[0][pbss_network->Configuration.DSConfig]=1;
10254 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10263 InfoContent[k] = i;
10264 //SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
10273 InfoContent[k] = j; //channel number
10274 //SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
10280 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10290 pattrib->last_txcmdsz = pattrib->pktlen;
10292 dump_mgntframe(padapter, pmgntframe);
10293 #endif //CONFIG_80211N_HT
10296 // Spatial Multiplexing Powersave (SMPS) action frame
10297 int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack)
10301 unsigned char category = RTW_WLAN_CATEGORY_HT;
10302 u8 action = RTW_WLAN_ACTION_HT_SM_PS;
10303 u8 sm_power_control=0;
10304 struct xmit_frame *pmgntframe;
10305 struct pkt_attrib *pattrib;
10306 unsigned char *pframe;
10307 struct rtw_ieee80211_hdr *pwlanhdr;
10308 unsigned short *fctrl;
10309 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10310 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10311 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10314 if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DISABLED)
10316 sm_power_control = sm_power_control & ~(BIT(0)); // SM Power Save Enable = 0 SM Power Save Disable
10318 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_STATIC)
10320 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
10321 sm_power_control = sm_power_control & ~(BIT(1)); // SM Mode = 0 Static Mode
10323 else if(NewMimoPsMode==WLAN_HT_CAP_SM_PS_DYNAMIC)
10325 sm_power_control = sm_power_control | BIT(0); // SM Power Save Enable = 1 SM Power Save Enable
10326 sm_power_control = sm_power_control | BIT(1); // SM Mode = 1 Dynamic Mode
10331 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10334 DBG_871X("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode );
10336 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
10340 pattrib = &pmgntframe->attrib;
10341 update_mgntframe_attrib(padapter, pattrib);
10343 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10345 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10346 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10348 fctrl = &(pwlanhdr->frame_ctl);
10351 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10352 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10353 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10355 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10356 pmlmeext->mgnt_seq++;
10357 SetFrameSubType(pframe, WIFI_ACTION);
10359 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10360 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10362 /* category, action */
10363 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10364 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10366 pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10368 pattrib->last_txcmdsz = pattrib->pktlen;
10372 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10376 dump_mgntframe(padapter, pmgntframe);
10380 if (ret != _SUCCESS)
10381 DBG_8192C("%s, ack to\n", __func__);
10387 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10388 * 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
10389 * try_cnt means the maximal TX count to try
10391 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10395 u32 start = rtw_get_current_time();
10397 if (rtw_rfctl_is_tx_blocked_by_cac(adapter_to_rfctl(padapter)))
10401 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms>0?_TRUE:_FALSE );
10405 if (RTW_CANNOT_RUN(padapter))
10408 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
10409 rtw_msleep_os(wait_ms);
10411 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
10413 if (ret != _FAIL) {
10415 #ifndef DBG_XMIT_ACK
10420 if (try_cnt && wait_ms) {
10422 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10423 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10424 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10426 DBG_871X(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10427 FUNC_ADPT_ARG(padapter),
10428 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
10435 int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode )
10437 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10438 return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE );
10442 * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10443 * @adapter: the adapter to which @sta belongs
10444 * @initiator: if we are the initiator of AMPDU association
10445 * @sta: the sta to be checked
10446 * @tid: the tid to be checked
10447 * @force: cancel and send DELBA even when no AMPDU association is setup
10448 * @wait_ack: send delba with xmit ack (valid when initiator == 0)
10451 * _FAIL if sta is NULL
10452 * when initiator is 1, always _SUCCESS
10453 * when initiator is 0, _SUCCESS if DELBA is acked
10455 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10456 , u8 force, int wait_ack)
10458 int ret = _SUCCESS;
10465 if (initiator == 0) {
10467 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10468 u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10470 sta->recvreorder_ctrl[tid].enable = _FALSE;
10471 sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10473 if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10476 ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
10478 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10480 if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10481 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10483 } else if (initiator == 1) {
10485 #ifdef CONFIG_80211N_HT
10486 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10487 sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10488 sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10489 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10498 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10501 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10504 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10507 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10510 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10512 struct sta_priv *pstapriv = &padapter->stapriv;
10513 struct sta_info *psta = NULL;
10514 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10515 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10518 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
10519 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10522 psta = rtw_get_stainfo(pstapriv, addr);
10527 DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR");
10528 if (initiator == 1) /* originator */
10529 DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10532 for (tid = 0; tid < TID_NUM; tid++)
10533 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10538 unsigned int send_beacon(_adapter *padapter)
10540 u8 bxmitok = _FALSE;
10543 #if defined(CONFIG_PCI_HCI) && defined(RTL8814AE_SW_BCN)
10544 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10546 //#ifdef CONFIG_CONCURRENT_MODE
10547 //struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10548 //struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10549 //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
10550 //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
10553 #ifdef CONFIG_PCI_HCI
10554 //DBG_871X("%s\n", __FUNCTION__);
10556 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10558 /* 8192EE Port select for Beacon DL */
10559 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10561 issue_beacon(padapter, 0);
10563 #ifdef RTL8814AE_SW_BCN
10564 if (pHalData->bCorrectBCN != 0)
10565 DBG_871X("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
10566 pHalData->bCorrectBCN = 1;
10572 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10573 u32 start = rtw_get_current_time();
10575 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10576 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10578 issue_beacon(padapter, 100);
10582 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10584 } while ((poll%10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10586 } while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter));
10588 if (RTW_CANNOT_RUN(padapter))
10592 if(_FALSE == bxmitok)
10594 DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10599 u32 passing_time = rtw_get_passing_time_ms(start);
10601 if(passing_time > 100 || issue > 3)
10602 DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10604 // DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10606 rtw_hal_fw_correct_bcn(padapter);
10615 /****************************************************************************
10617 Following are some utitity fuctions for WiFi MLME
10619 *****************************************************************************/
10621 BOOLEAN IsLegal5GChannel(
10622 IN PADAPTER Adapter,
10627 u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
10628 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
10629 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
10631 for(i=0;i<sizeof(Channel_5G);i++)
10632 if(channel == Channel_5G[i])
10637 //collect bss info from Beacon and Probe request/response frames.
10638 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10643 u16 val16, subtype;
10644 u8 *pframe = precv_frame->u.hdr.rx_data;
10645 u32 packet_len = precv_frame->u.hdr.len;
10647 struct registry_priv *pregistrypriv = &padapter->registrypriv;
10648 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10649 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10651 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10653 if (len > MAX_IE_SZ)
10655 //DBG_871X("IE too long for survey event\n");
10659 _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10661 subtype = GetFrameSubType(pframe);
10663 if(subtype==WIFI_BEACON) {
10664 bssid->Reserved[0] = 1;
10665 ie_offset = _BEACON_IE_OFFSET_;
10667 // FIXME : more type
10668 if (subtype == WIFI_PROBERSP) {
10669 ie_offset = _PROBERSP_IE_OFFSET_;
10670 bssid->Reserved[0] = 3;
10672 else if (subtype == WIFI_PROBEREQ) {
10673 ie_offset = _PROBEREQ_IE_OFFSET_;
10674 bssid->Reserved[0] = 2;
10677 bssid->Reserved[0] = 0;
10678 ie_offset = _FIXED_IE_LENGTH_;
10682 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10684 //below is to copy the information element
10685 bssid->IELength = len;
10686 _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10688 //get the signal strength
10689 //bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
10690 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
10691 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
10692 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
10693 #ifdef CONFIG_ANTENNA_DIVERSITY
10694 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
10698 if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
10700 DBG_871X("marc: cannot find SSID for survey event\n");
10706 if (len > NDIS_802_11_LENGTH_SSID)
10708 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10711 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10712 bssid->Ssid.SsidLength = *(p + 1);
10716 bssid->Ssid.SsidLength = 0;
10719 _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10721 //checking rate info...
10723 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10726 if (len > NDIS_802_11_LENGTH_RATES_EX)
10728 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10731 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10735 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10738 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
10740 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10743 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10748 if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10750 bssid->NetworkTypeInUse = Ndis802_11DS;
10755 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10759 if (subtype == WIFI_PROBEREQ)
10763 // Set Listion Channel
10764 if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen)))
10766 u32 attr_contentlen = 0;
10767 u8 listen_ch[5] = { 0x00 };
10769 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10770 bssid->Configuration.DSConfig = listen_ch[4];
10772 { // use current channel
10773 bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10774 DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10778 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10779 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10780 bssid->Privacy = 1;
10783 #endif //CONFIG_P2P
10785 if (bssid->IELength < 12)
10788 // Checking for DSConfig
10789 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10791 bssid->Configuration.DSConfig = 0;
10792 bssid->Configuration.Length = 0;
10796 bssid->Configuration.DSConfig = *(p + 2);
10799 {// In 5G, some ap do not have DSSET IE
10800 // checking HT info for channel
10801 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10804 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10805 bssid->Configuration.DSConfig = HT_info->primary_channel;
10808 { // use current channel
10809 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
10813 _rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
10814 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
10816 val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
10818 if (val16 & BIT(0))
10820 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10821 _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
10825 bssid->InfrastructureMode = Ndis802_11IBSS;
10826 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10829 if (val16 & BIT(4))
10830 bssid->Privacy = 1;
10832 bssid->Privacy = 0;
10834 bssid->Configuration.ATIMWindow = 0;
10836 //20/40 BSS Coexistence check
10837 if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
10839 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10840 #ifdef CONFIG_80211N_HT
10841 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10844 struct HT_caps_element *pHT_caps;
10845 pHT_caps = (struct HT_caps_element *)(p + 2);
10847 if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
10849 pmlmepriv->num_FortyMHzIntolerant++;
10854 pmlmepriv->num_sta_no_ht++;
10856 #endif //CONFIG_80211N_HT
10860 #ifdef CONFIG_INTEL_WIDI
10861 //process_intel_widi_query_or_tigger(padapter, bssid);
10862 if(process_intel_widi_query_or_tigger(padapter, bssid))
10866 #endif // CONFIG_INTEL_WIDI
10868 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10869 if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10870 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10871 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10872 , rtw_get_oper_ch(padapter)
10873 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10878 // mark bss info receving from nearby channel as SignalQuality 101
10879 if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10881 bssid->PhyInfo.SignalQuality= 101;
10887 void start_create_ibss(_adapter* padapter)
10889 unsigned short caps;
10892 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10893 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10894 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10896 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10897 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10899 //update wireless mode
10900 update_wireless_mode(padapter);
10902 //udpate capability
10903 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10904 update_capinfo(padapter, caps);
10905 if(caps&cap_IBSS)//adhoc master
10907 //set_opmode_cmd(padapter, adhoc);//removed
10910 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10913 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10916 //SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
10917 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10920 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10922 beacon_timing_control(padapter);
10924 //set msr to WIFI_FW_ADHOC_STATE
10925 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10926 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10929 if(send_beacon(padapter)==_FAIL)
10931 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
10933 report_join_res(padapter, -1);
10934 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10938 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10940 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10942 report_join_res(padapter, 1);
10943 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10944 rtw_indicate_connect(padapter);
10949 DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
10952 //update bc/mc sta_info
10953 update_bmc_sta(padapter);
10957 void start_clnt_join(_adapter* padapter)
10959 unsigned short caps;
10961 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10962 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10963 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10964 int beacon_timeout;
10965 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
10967 //update wireless mode
10968 update_wireless_mode(padapter);
10970 //udpate capability
10971 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10972 update_capinfo(padapter, caps);
10974 //check if sta is ASIX peer and fix IOT issue if it is.
10975 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
10976 u8 iot_flag = _TRUE;
10977 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10982 Set_MSR(padapter, WIFI_FW_STATION_STATE);
10984 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
10986 #ifdef CONFIG_WAPI_SUPPORT
10987 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
10989 //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
10993 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10995 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10996 // Because of AP's not receiving deauth before
10997 // AP may: 1)not response auth or 2)deauth us after link is complete
10998 // issue deauth before issuing auth to deal with the situation
11000 // Commented by Albert 2012/07/21
11001 // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
11004 _queue *queue = &(padapter->mlmepriv.scanned_queue);
11005 _list *head = get_list_head(queue);
11006 _list *pos = get_next(head);
11007 struct wlan_network *scanned = NULL;
11010 bool has_p2p_ie = _FALSE;
11012 _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11014 for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
11016 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
11018 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
11019 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
11021 ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
11022 if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
11023 has_p2p_ie = _TRUE;
11028 _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11030 if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
11031 #endif /* CONFIG_P2P */
11032 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
11033 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
11035 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11037 //here wait for receiving the beacon to start auth
11038 //and enable a timer
11039 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11040 set_link_timer(pmlmeext, beacon_timeout);
11041 _set_timer( &padapter->mlmepriv.assoc_timer,
11042 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
11044 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11046 else if (caps&cap_IBSS) //adhoc client
11048 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11051 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11053 beacon_timing_control(padapter);
11055 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11057 report_join_res(padapter, 1);
11061 //DBG_871X("marc: invalid cap:%x\n", caps);
11067 void start_clnt_auth(_adapter* padapter)
11069 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11070 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11072 _cancel_timer_ex(&pmlmeext->link_timer);
11074 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
11075 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
11077 pmlmeinfo->auth_seq = 1;
11078 pmlmeinfo->reauth_count = 0;
11079 pmlmeinfo->reassoc_count = 0;
11080 pmlmeinfo->link_count = 0;
11081 pmlmeext->retry = 0;
11084 DBG_871X_LEVEL(_drv_always_, "start auth\n");
11085 issue_auth(padapter, NULL, 0);
11087 set_link_timer(pmlmeext, REAUTH_TO);
11092 void start_clnt_assoc(_adapter* padapter)
11094 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11095 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11097 _cancel_timer_ex(&pmlmeext->link_timer);
11099 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
11100 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
11102 issue_assocreq(padapter);
11104 set_link_timer(pmlmeext, REASSOC_TO);
11107 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
11109 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11110 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11112 if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
11115 DBG_871X("%s\n", __FUNCTION__);
11117 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
11119 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11121 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11122 report_del_sta_event(padapter, MacAddr, reason, _TRUE);
11125 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
11127 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11128 report_join_res(padapter, -2);
11130 DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
11136 #ifdef CONFIG_80211D
11137 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
11139 struct registry_priv *pregistrypriv;
11140 struct mlme_ext_priv *pmlmeext;
11141 RT_CHANNEL_INFO *chplan_new;
11146 pregistrypriv = &padapter->registrypriv;
11147 pmlmeext = &padapter->mlmeextpriv;
11149 // Adjust channel plan by AP Country IE
11150 if (pregistrypriv->enable80211d &&
11151 (!pmlmeext->update_channel_plan_by_ap_done))
11155 RT_CHANNEL_PLAN chplan_ap;
11156 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
11158 u8 fcn; // first channel number
11159 u8 noc; // number of channel
11162 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11164 if (len < 6) return;
11170 _rtw_memset(country, 0, 4);
11171 _rtw_memcpy(country, p, 3);
11173 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11174 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
11177 while ((ie - p) >= 3)
11183 for (j = 0; j < noc; j++)
11185 if (fcn <= 14) channel = fcn + j; // 2.4 GHz
11186 else channel = fcn + j*4; // 5 GHz
11188 chplan_ap.Channel[i++] = channel;
11193 #ifdef CONFIG_DEBUG_RTL871X
11195 DBG_871X("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11196 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
11198 DBG_8192C("%02d,", chplan_ap.Channel[i]);
11204 _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
11205 #ifdef CONFIG_DEBUG_RTL871X
11207 DBG_871X("%s: STA channel plan {", __FUNCTION__);
11208 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11210 DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
11216 _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
11217 chplan_new = pmlmeext->channel_set;
11220 if (pregistrypriv->wireless_mode & WIRELESS_11G)
11223 if ((i == MAX_CHANNEL_NUM) ||
11224 (chplan_sta[i].ChannelNum == 0) ||
11225 (chplan_sta[i].ChannelNum > 14))
11228 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11231 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11233 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11234 chplan_new[k].ScanType = SCAN_ACTIVE;
11239 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11241 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11242 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11243 chplan_new[k].ScanType = SCAN_PASSIVE;
11247 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11249 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11250 chplan_new[k].ScanType = SCAN_ACTIVE;
11256 // change AP not support channel to Passive scan
11257 while ((i < MAX_CHANNEL_NUM) &&
11258 (chplan_sta[i].ChannelNum != 0) &&
11259 (chplan_sta[i].ChannelNum <= 14))
11261 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11262 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11263 chplan_new[k].ScanType = SCAN_PASSIVE;
11268 // add channel AP supported
11269 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11271 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11272 chplan_new[k].ScanType = SCAN_ACTIVE;
11279 // keep original STA 2.4G channel plan
11280 while ((i < MAX_CHANNEL_NUM) &&
11281 (chplan_sta[i].ChannelNum != 0) &&
11282 (chplan_sta[i].ChannelNum <= 14))
11284 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11285 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11290 // skip AP 2.4G channel plan
11291 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11297 if (pregistrypriv->wireless_mode & WIRELESS_11A)
11300 if ((i >= MAX_CHANNEL_NUM) ||
11301 (chplan_sta[i].ChannelNum == 0))
11304 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11307 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
11309 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11310 chplan_new[k].ScanType = SCAN_ACTIVE;
11315 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
11317 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11318 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11319 chplan_new[k].ScanType = SCAN_PASSIVE;
11323 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
11325 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11326 chplan_new[k].ScanType = SCAN_ACTIVE;
11332 // change AP not support channel to Passive scan
11333 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11335 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11336 // chplan_new[k].ScanType = chplan_sta[i].ScanType;
11337 chplan_new[k].ScanType = SCAN_PASSIVE;
11342 // add channel AP supported
11343 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
11345 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11346 chplan_new[k].ScanType = SCAN_ACTIVE;
11353 // keep original STA 5G channel plan
11354 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
11356 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11357 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11363 pmlmeext->update_channel_plan_by_ap_done = 1;
11365 #ifdef CONFIG_DEBUG_RTL871X
11367 DBG_871X("%s: new STA channel plan {", __FUNCTION__);
11368 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11370 DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
11377 // recover the right channel index
11378 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11380 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
11382 if (chplan_new[k].ChannelNum == channel) {
11383 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11384 ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11385 __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
11386 pmlmeext->sitesurvey_res.channel_idx = k;
11394 // If channel is used by AP, set channel scan type to active
11395 channel = bssid->Configuration.DSConfig;
11396 chplan_new = pmlmeext->channel_set;
11398 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
11400 if (chplan_new[i].ChannelNum == channel)
11402 if (chplan_new[i].ScanType == SCAN_PASSIVE)
11404 //5G Bnad 2, 3 (DFS) doesn't change to active scan
11405 if(channel >= 52 && channel <= 144)
11408 chplan_new[i].ScanType = SCAN_ACTIVE;
11409 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
11410 ("%s: change channel %d scan type from passive to active\n",
11411 __FUNCTION__, channel));
11420 /****************************************************************************
11422 Following are the functions to report events
11424 *****************************************************************************/
11426 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11428 struct cmd_obj *pcmd_obj;
11431 struct survey_event *psurvey_evt;
11432 struct C2HEvent_Header *pc2h_evt_hdr;
11433 struct mlme_ext_priv *pmlmeext;
11434 struct cmd_priv *pcmdpriv;
11435 //u8 *pframe = precv_frame->u.hdr.rx_data;
11436 //uint len = precv_frame->u.hdr.len;
11441 pmlmeext = &padapter->mlmeextpriv;
11442 pcmdpriv = &padapter->cmdpriv;
11445 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11450 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11451 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11453 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11457 _rtw_init_listhead(&pcmd_obj->list);
11459 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11460 pcmd_obj->cmdsz = cmdsz;
11461 pcmd_obj->parmbuf = pevtcmd;
11463 pcmd_obj->rsp = NULL;
11464 pcmd_obj->rspsz = 0;
11466 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11467 pc2h_evt_hdr->len = sizeof(struct survey_event);
11468 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11469 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11471 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11473 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
11475 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11476 rtw_mfree((u8 *)pevtcmd, cmdsz);
11480 #ifdef CONFIG_80211D
11481 process_80211d(padapter, &psurvey_evt->bss);
11484 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11486 pmlmeext->sitesurvey_res.bss_cnt++;
11492 void report_surveydone_event(_adapter *padapter)
11494 struct cmd_obj *pcmd_obj;
11497 struct surveydone_event *psurveydone_evt;
11498 struct C2HEvent_Header *pc2h_evt_hdr;
11499 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11500 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11502 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11507 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11508 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11510 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11514 _rtw_init_listhead(&pcmd_obj->list);
11516 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11517 pcmd_obj->cmdsz = cmdsz;
11518 pcmd_obj->parmbuf = pevtcmd;
11520 pcmd_obj->rsp = NULL;
11521 pcmd_obj->rspsz = 0;
11523 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11524 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11525 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11526 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11528 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11529 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11531 DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11533 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11539 void report_join_res(_adapter *padapter, int res)
11541 struct cmd_obj *pcmd_obj;
11544 struct joinbss_event *pjoinbss_evt;
11545 struct C2HEvent_Header *pc2h_evt_hdr;
11546 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11547 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11548 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11550 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11555 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11556 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11558 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11562 _rtw_init_listhead(&pcmd_obj->list);
11564 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11565 pcmd_obj->cmdsz = cmdsz;
11566 pcmd_obj->parmbuf = pevtcmd;
11568 pcmd_obj->rsp = NULL;
11569 pcmd_obj->rspsz = 0;
11571 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11572 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11573 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11574 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11576 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11577 _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11578 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
11580 DBG_871X("report_join_res(%d)\n", res);
11583 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11586 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11592 void report_wmm_edca_update(_adapter *padapter)
11594 struct cmd_obj *pcmd_obj;
11597 struct wmm_event *pwmm_event;
11598 struct C2HEvent_Header *pc2h_evt_hdr;
11599 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11600 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11601 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11603 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11608 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11609 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11611 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11615 _rtw_init_listhead(&pcmd_obj->list);
11617 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11618 pcmd_obj->cmdsz = cmdsz;
11619 pcmd_obj->parmbuf = pevtcmd;
11621 pcmd_obj->rsp = NULL;
11622 pcmd_obj->rspsz = 0;
11624 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11625 pc2h_evt_hdr->len = sizeof(struct wmm_event);
11626 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11627 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11629 pwmm_event = (struct wmm_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11630 pwmm_event->wmm =0;
11632 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11638 void report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue)
11640 struct cmd_obj *pcmd_obj;
11643 struct sta_info *psta;
11645 struct stadel_event *pdel_sta_evt;
11646 struct C2HEvent_Header *pc2h_evt_hdr;
11647 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11648 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11651 /* prepare cmd parameter */
11652 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11653 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11654 if (pevtcmd == NULL) {
11659 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11660 pc2h_evt_hdr->len = sizeof(struct stadel_event);
11661 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11662 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11664 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11665 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11666 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
11667 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11669 mac_id = (int)psta->mac_id;
11672 pdel_sta_evt->mac_id = mac_id;
11676 rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11677 rtw_mfree(pevtcmd, cmdsz);
11679 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11680 if (pcmd_obj == NULL) {
11681 rtw_mfree(pevtcmd, cmdsz);
11686 _rtw_init_listhead(&pcmd_obj->list);
11687 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11688 pcmd_obj->cmdsz = cmdsz;
11689 pcmd_obj->parmbuf = pevtcmd;
11691 pcmd_obj->rsp = NULL;
11692 pcmd_obj->rspsz = 0;
11694 res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11699 DBG_871X(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11700 , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11705 void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
11707 struct cmd_obj *pcmd_obj;
11710 struct stassoc_event *padd_sta_evt;
11711 struct C2HEvent_Header *pc2h_evt_hdr;
11712 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11713 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11715 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11720 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11721 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
11723 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11727 _rtw_init_listhead(&pcmd_obj->list);
11729 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11730 pcmd_obj->cmdsz = cmdsz;
11731 pcmd_obj->parmbuf = pevtcmd;
11733 pcmd_obj->rsp = NULL;
11734 pcmd_obj->rspsz = 0;
11736 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
11737 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11738 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11739 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11741 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
11742 _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11744 DBG_871X("report_add_sta_event: add STA\n");
11746 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11752 bool rtw_port_switch_chk(_adapter *adapter)
11754 bool switch_needed = _FALSE;
11755 #ifdef CONFIG_CONCURRENT_MODE
11756 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11757 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11758 struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11759 _adapter *if_port0 = NULL;
11760 _adapter *if_port1 = NULL;
11761 struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11762 struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11765 for (i = 0; i < dvobj->iface_nums; i++) {
11766 if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0) {
11767 if_port0 = dvobj->padapters[i];
11768 if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11770 else if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT1) {
11771 if_port1 = dvobj->padapters[i];
11772 if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11776 if (if_port0 == NULL) {
11781 if (if_port1 == NULL) {
11786 #ifdef DBG_RUNTIME_PORT_SWITCH
11787 DBG_871X(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11788 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11789 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11790 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11791 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11792 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11793 #endif /* DBG_RUNTIME_PORT_SWITCH */
11795 #ifdef CONFIG_WOWLAN
11796 /* WOWLAN interface(primary, for now) should be port0 */
11797 if (pwrctl->wowlan_mode == _TRUE) {
11798 if(!is_primary_adapter(if_port0)) {
11799 DBG_871X("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11800 switch_needed = _TRUE;
11804 #endif /* CONFIG_WOWLAN */
11806 /* AP should use port0 for ctl frame's ack */
11807 if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11808 DBG_871X("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11809 switch_needed = _TRUE;
11813 /* GC should use port0 for p2p ps */
11814 if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11815 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11816 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11817 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11819 DBG_871X("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11820 switch_needed = _TRUE;
11824 /* port1 linked, but port0 not linked */
11825 if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11826 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11827 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11829 DBG_871X("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11830 switch_needed = _TRUE;
11835 #ifdef DBG_RUNTIME_PORT_SWITCH
11836 DBG_871X(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11837 #endif /* DBG_RUNTIME_PORT_SWITCH */
11838 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11839 #endif /* CONFIG_CONCURRENT_MODE */
11840 return switch_needed;
11843 /****************************************************************************
11845 Following are the event callback functions
11847 *****************************************************************************/
11849 //for sta/adhoc mode
11850 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11853 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11854 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11855 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11858 VCS_update(padapter, psta);
11860 #ifdef CONFIG_80211N_HT
11862 if(pmlmepriv->htpriv.ht_option)
11864 psta->htpriv.ht_option = _TRUE;
11866 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11868 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
11870 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11871 psta->htpriv.sgi_20m = _TRUE;
11873 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11874 psta->htpriv.sgi_40m = _TRUE;
11876 psta->qos_option = _TRUE;
11878 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11879 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11880 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11882 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11885 #endif //CONFIG_80211N_HT
11887 #ifdef CONFIG_80211N_HT
11888 psta->htpriv.ht_option = _FALSE;
11890 psta->htpriv.ampdu_enable = _FALSE;
11892 psta->htpriv.sgi_20m = _FALSE;
11893 psta->htpriv.sgi_40m = _FALSE;
11894 #endif //CONFIG_80211N_HT
11895 psta->qos_option = _FALSE;
11899 #ifdef CONFIG_80211N_HT
11900 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11902 psta->htpriv.agg_enable_bitmap = 0x0;//reset
11903 psta->htpriv.candidate_tid_bitmap = 0x0;//reset
11904 #endif //CONFIG_80211N_HT
11906 psta->bw_mode = pmlmeext->cur_bwmode;
11909 if(pmlmepriv->qospriv.qos_option)
11910 psta->qos_option = _TRUE;
11912 #ifdef CONFIG_80211AC_VHT
11913 _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11914 #endif //CONFIG_80211AC_VHT
11916 update_ldpc_stbc_cap(psta);
11918 _enter_critical_bh(&psta->lock, &irqL);
11919 psta->state = _FW_LINKED;
11920 _exit_critical_bh(&psta->lock, &irqL);
11924 static void rtw_mlmeext_disconnect(_adapter *padapter)
11926 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11927 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11928 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11929 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11930 u8 state_backup = (pmlmeinfo->state&0x03);
11931 u8 ASIX_ID[]= {0x00, 0x0E, 0xC6};
11933 //set_opmode_cmd(padapter, infra_client_with_mlme);
11935 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11936 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11938 //set MSR to no link state -> infra. mode
11939 Set_MSR(padapter, _HW_STATE_STATION_);
11941 //check if sta is ASIX peer and fix IOT issue if it is.
11942 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) ,ASIX_ID ,3)) {
11943 u8 iot_flag = _FALSE;
11944 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11946 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11948 if(state_backup == WIFI_FW_STATION_STATE)
11950 if (rtw_port_switch_chk(padapter) == _TRUE) {
11951 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11954 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11956 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11962 /* switch to the 20M Hz mode after disconnect */
11963 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11964 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11966 #ifdef CONFIG_FCS_MODE
11967 if (EN_FCS(padapter))
11968 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11971 #ifdef CONFIG_DFS_MASTER
11972 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
11973 rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);
11974 else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
11975 rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED);
11981 if (rtw_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
11982 set_channel_bwmode(padapter, ch, offset, bw);
11985 flush_all_cam_entry(padapter);
11987 _cancel_timer_ex(&pmlmeext->link_timer);
11989 //pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE;
11990 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11991 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11994 padapter->tdlsinfo.ap_prohibited = _FALSE;
11996 /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11997 if (padapter->registrypriv.wifi_spec == 1)
11999 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
12001 #endif /* CONFIG_TDLS */
12005 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
12007 struct sta_info *psta, *psta_bmc;
12008 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12009 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12010 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
12011 struct sta_priv *pstapriv = &padapter->stapriv;
12013 #ifdef CONFIG_ARP_KEEP_ALIVE
12014 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12016 struct security_priv *psecuritypriv = &padapter->securitypriv;
12021 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12022 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12024 goto exit_mlmeext_joinbss_event_callback;
12026 #ifdef CONFIG_ARP_KEEP_ALIVE
12027 pmlmepriv->bGetGateway = 1;
12030 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
12032 //update bc/mc sta_info
12033 update_bmc_sta(padapter);
12037 //turn on dynamic functions
12038 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12040 // update IOT-releated issue
12041 update_IOT_info(padapter);
12043 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12046 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12048 //udpate capability
12049 update_capinfo(padapter, pmlmeinfo->capability);
12051 //WMM, Update EDCA param
12052 WMMOnAssocRsp(padapter);
12055 HTOnAssocRsp(padapter);
12057 #ifdef CONFIG_80211AC_VHT
12059 VHTOnAssocRsp(padapter);
12062 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12063 if (psta) //only for infra. mode
12065 //DBG_871X("set_sta_rate\n");
12067 psta->wireless_mode = pmlmeext->cur_wireless_mode;
12069 //set per sta rate after updating HT cap.
12070 set_sta_rate(padapter, psta);
12072 rtw_sta_media_status_rpt(padapter, psta, 1);
12074 /* wakeup macid after join bss successfully to ensure
12075 the subsequent data frames can be sent out normally */
12076 rtw_hal_macid_wakeup(padapter, psta->mac_id);
12079 #ifndef CONFIG_IOCTL_CFG80211
12080 if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12081 rtw_sec_restore_wep_key(padapter);
12082 #endif /* CONFIG_IOCTL_CFG80211 */
12084 if (rtw_port_switch_chk(padapter) == _TRUE)
12085 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12088 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12090 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12093 correct_TSF(padapter, pmlmeext);
12095 //set_link_timer(pmlmeext, DISCONNECT_TO);
12099 if(get_iface_type(padapter) == IFACE_PORT0)
12100 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
12103 #ifdef CONFIG_BEAMFORMING
12105 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12106 #endif/*CONFIG_BEAMFORMING*/
12108 exit_mlmeext_joinbss_event_callback:
12110 rtw_join_done_chk_ch(padapter, join_res);
12112 DBG_871X("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12115 //currently only adhoc mode will go here
12116 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12118 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12119 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12122 DBG_871X("%s\n", __FUNCTION__);
12124 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
12126 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)//adhoc master or sta_count>1
12133 //update_TSF(pmlmeext, pframe, len);
12136 correct_TSF(padapter, pmlmeext);
12139 if (send_beacon(padapter) == _FAIL)
12142 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12146 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12149 //update adhoc sta_info
12150 update_sta_info(padapter, psta);
12152 rtw_hal_update_sta_rate_mask(padapter, psta);
12154 // ToDo: HT for Ad-hoc
12155 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12156 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
12159 Update_RA_Entry(padapter, psta);
12162 void mlmeext_sta_del_event_callback(_adapter *padapter)
12164 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12165 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12167 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12169 rtw_mlmeext_disconnect(padapter);
12174 /****************************************************************************
12176 Following are the functions for the timer handlers
12178 *****************************************************************************/
12179 void _linked_info_dump(_adapter *padapter)
12182 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12183 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12184 HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
12185 int UndecoratedSmoothedPWDB = 0;
12187 if(padapter->bLinkInfoDump){
12189 DBG_871X("\n============["ADPT_FMT"] linked status check ===================\n",ADPT_ARG(padapter));
12191 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
12193 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
12195 DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n",
12196 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress),UndecoratedSmoothedPWDB);
12198 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
12201 _list *phead, *plist;
12203 struct sta_info *psta=NULL;
12204 struct sta_priv *pstapriv = &padapter->stapriv;
12206 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12207 phead = &pstapriv->asoc_list;
12208 plist = get_next(phead);
12209 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12211 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
12212 plist = get_next(plist);
12214 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n",
12215 MAC_ARG(psta->hwaddr),psta->rssi_stat.UndecoratedSmoothedPWDB);
12217 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12221 /*============ tx info ============ */
12222 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
12224 rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
12230 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12233 int ret = _SUCCESS;
12234 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12235 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12238 IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12239 AP is originator.AP does not transmit unicast packets when STA response its BAR.
12240 This case probably occur ap issue BAR after AP builds BA.
12242 Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12243 The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12245 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12246 for (i = 0; i < TID_NUM ; i++) {
12247 if (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) {
12248 if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12249 if (psta->recvreorder_ctrl[i].enable) {
12250 /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
12252 ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1);
12254 issue_del_ba(padapter, psta->hwaddr, i, 39, 0);
12255 psta->recvreorder_ctrl[i].enable = _FALSE;
12257 psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12258 rtw_reset_continual_no_rx_packet(psta, i);
12263 /* The inactivity timer is reset when MPDUs to the TID is received. */
12264 rtw_reset_continual_no_rx_packet(psta, i);
12270 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12274 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12275 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12277 #ifdef DBG_EXPIRATION_CHK
12278 DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12279 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12281 , FUNC_ADPT_ARG(padapter)
12282 , STA_RX_PKTS_DIFF_ARG(psta)
12283 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12284 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12285 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12286 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12287 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12288 , pmlmeinfo->bcn_interval*/
12292 DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12293 , padapter->xmitpriv.tx_pkts
12294 , pmlmeinfo->link_count
12298 if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12299 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12300 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12310 sta_update_last_rx_pkts(psta);
12313 record last rx data packets for every tid.
12315 for (i = 0; i < TID_NUM; i++)
12316 psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i];
12321 u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
12325 #ifdef DBG_EXPIRATION_CHK
12326 DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12327 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12329 , MAC_ARG(psta->hwaddr)
12330 , psta->rssi_stat.UndecoratedSmoothedPWDB
12331 , STA_RX_PKTS_DIFF_ARG(psta)
12332 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12333 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12334 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12335 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12336 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12337 , pmlmeinfo->bcn_interval*/
12342 if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
12343 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12344 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
12347 sta_update_last_rx_pkts(psta);
12353 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12355 if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12356 && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12362 void linked_status_chk_tdls(_adapter *padapter)
12364 struct candidate_pool {
12365 struct sta_info *psta;
12368 struct sta_priv *pstapriv = &padapter->stapriv;
12371 struct sta_info *psta;
12372 int i, num_teardown=0, num_checkalive=0;
12373 _list *plist, *phead;
12374 struct tdls_txmgmt txmgmt;
12375 struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
12376 struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
12377 u8 tdls_sta_max = _FALSE;
12379 #define ALIVE_MIN 2
12380 #define ALIVE_MAX 5
12382 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12383 _rtw_memset(checkalive, 0x00, sizeof(checkalive));
12384 _rtw_memset(teardown, 0x00, sizeof(teardown));
12386 if((padapter->tdlsinfo.link_established == _TRUE)){
12387 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12388 for(i=0; i< NUM_STA; i++)
12390 phead = &(pstapriv->sta_hash[i]);
12391 plist = get_next(phead);
12393 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
12395 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12396 plist = get_next(plist);
12398 if(psta->tdls_sta_state & TDLS_LINKED_STATE)
12400 psta->alive_count++;
12401 if(psta->alive_count >= ALIVE_MIN)
12403 if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12404 if (psta->alive_count < ALIVE_MAX) {
12405 _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12406 checkalive[num_checkalive].psta = psta;
12411 _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12412 teardown[num_teardown].psta = psta;
12418 psta->alive_count = 0;
12421 psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12422 psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12424 if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
12425 tdls_sta_max = _TRUE;
12431 if (tdls_sta_max == _TRUE)
12434 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12436 if (num_checkalive > 0) {
12437 for (i = 0; i < num_checkalive; i++) {
12438 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12439 issue_tdls_dis_req(padapter, &txmgmt);
12440 issue_tdls_dis_req(padapter, &txmgmt);
12441 issue_tdls_dis_req(padapter, &txmgmt);
12445 if(num_teardown > 0)
12447 for(i=0; i< num_teardown; i++)
12449 DBG_871X("[%s %d] Send teardown to "MAC_FMT" \n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12450 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12451 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12452 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12458 #endif //CONFIG_TDLS
12460 //from_timer == 1 means driver is in LPS
12461 void linked_status_chk(_adapter *padapter, u8 from_timer)
12464 struct sta_info *psta;
12465 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12466 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12467 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12468 struct sta_priv *pstapriv = &padapter->stapriv;
12469 #ifdef CONFIG_ARP_KEEP_ALIVE
12470 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12474 if (is_client_associated_to_ap(padapter))
12476 //linked infrastructure client mode
12478 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12480 int link_count_limit;
12482 #if defined(DBG_ROAMING_TEST)
12484 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12489 #ifdef CONFIG_ARP_KEEP_ALIVE
12490 if (!from_timer && pmlmepriv->bGetGateway == 1) {
12491 DBG_871X("do rtw_gw_addr_query()");
12492 if (rtw_gw_addr_query(padapter) == 0) {
12493 pmlmepriv->bGetGateway = 0;
12495 _rtw_memset(pmlmepriv->gw_ip, 0, 4);
12496 _rtw_memset(pmlmepriv->gw_mac_addr, 0, 6);
12501 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
12504 link_count_limit = 3; // 8 sec
12506 link_count_limit = 15; // 32 sec
12509 #endif // CONFIG_P2P
12512 link_count_limit = 7; // 16 sec
12514 link_count_limit = 29; // 60 sec
12518 #ifdef CONFIG_TDLS_CH_SW
12519 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12521 #endif /* CONFIG_TDLS_CH_SW */
12523 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12524 linked_status_chk_tdls(padapter);
12525 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12526 #endif /* CONFIG_TDLS */
12528 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
12530 bool is_p2p_enable = _FALSE;
12532 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12535 /*issue delba when ap does not tx data packet that is Broadcom ap */
12536 rtw_delba_check(padapter, psta, from_timer);
12538 if (chk_ap_is_alive(padapter, psta) == _FALSE)
12541 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12544 #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12545 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
12546 u8 backup_oper_channel=0;
12548 /* switch to correct channel of current network before issue keep-alive frames */
12549 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12550 backup_oper_channel = rtw_get_oper_ch(padapter);
12551 SelectChannel(padapter, pmlmeext->cur_channel);
12554 if (rx_chk != _SUCCESS)
12555 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12557 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12558 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12559 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12560 if (tx_chk == _SUCCESS && !is_p2p_enable)
12564 /* back to the original operation channel */
12565 if(backup_oper_channel>0)
12566 SelectChannel(padapter, backup_oper_channel);
12570 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12572 if (rx_chk != _SUCCESS) {
12573 if (pmlmeext->retry == 0) {
12574 #ifdef DBG_EXPIRATION_CHK
12575 DBG_871X("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12577 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12578 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12579 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12583 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) {
12584 #ifdef DBG_EXPIRATION_CHK
12585 DBG_871X("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer?1:0);
12587 tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer?1:0);
12591 if (rx_chk == _FAIL) {
12593 if (pmlmeext->retry > rx_chk_limit) {
12594 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
12595 FUNC_ADPT_ARG(padapter));
12596 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12597 , WLAN_REASON_EXPIRATION_CHK);
12601 pmlmeext->retry = 0;
12604 if (tx_chk == _FAIL) {
12605 pmlmeinfo->link_count %= (link_count_limit+1);
12607 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12608 pmlmeinfo->link_count = 0;
12611 } //end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL)
12613 } else if (is_client_associated_to_ibss(padapter)) {
12615 _list *phead, *plist, dlist;
12617 _rtw_init_listhead(&dlist);
12619 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12621 for (i = 0; i < NUM_STA; i++) {
12623 phead = &(pstapriv->sta_hash[i]);
12624 plist = get_next(phead);
12625 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12626 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12627 plist = get_next(plist);
12629 if (is_broadcast_mac_addr(psta->hwaddr))
12632 if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
12633 psta->expire_to = pstapriv->adhoc_expire_to;
12637 if (psta->expire_to <= 0) {
12638 rtw_list_delete(&psta->list);
12639 rtw_list_insert_tail(&psta->list, &dlist);
12644 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12646 plist = get_next(&dlist);
12647 while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
12648 psta = LIST_CONTAINOR(plist, struct sta_info, list);
12649 plist = get_next(plist);
12650 rtw_list_delete(&psta->list);
12651 DBG_871X(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
12652 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->hwaddr));
12653 report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE);
12659 void survey_timer_hdl(_adapter *padapter)
12661 struct cmd_obj *cmd;
12662 struct sitesurvey_parm *psurveyPara;
12663 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12664 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12666 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
12669 if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12670 cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12676 psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12677 if (psurveyPara == NULL) {
12679 rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12683 init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12684 rtw_enqueue_cmd(pcmdpriv, cmd);
12691 void link_timer_hdl(_adapter *padapter)
12693 //static unsigned int rx_pkt = 0;
12694 //static u64 tx_cnt = 0;
12695 //struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12696 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12697 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12698 //struct sta_priv *pstapriv = &padapter->stapriv;
12701 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
12703 DBG_871X("link_timer_hdl:no beacon while connecting\n");
12704 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12705 report_join_res(padapter, -3);
12707 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
12710 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
12712 //if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto)
12714 pmlmeinfo->state = 0;
12715 report_join_res(padapter, -1);
12720 // pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
12721 // pmlmeinfo->reauth_count = 0;
12725 DBG_871X("link_timer_hdl: auth timeout and try again\n");
12726 pmlmeinfo->auth_seq = 1;
12727 issue_auth(padapter, NULL, 0);
12728 set_link_timer(pmlmeext, REAUTH_TO);
12730 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
12733 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
12735 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12736 report_join_res(padapter, -2);
12740 DBG_871X("link_timer_hdl: assoc timeout and try again\n");
12741 issue_assocreq(padapter);
12742 set_link_timer(pmlmeext, REASSOC_TO);
12748 void addba_timer_hdl(struct sta_info *psta)
12750 #ifdef CONFIG_80211N_HT
12751 struct ht_priv *phtpriv;
12756 phtpriv = &psta->htpriv;
12758 if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
12760 if(phtpriv->candidate_tid_bitmap)
12761 phtpriv->candidate_tid_bitmap=0x0;
12764 #endif //CONFIG_80211N_HT
12767 #ifdef CONFIG_IEEE80211W
12768 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
12770 struct cmd_obj *pcmd_obj;
12773 struct sta_info *psta;
12775 struct stadel_event *pdel_sta_evt;
12776 struct C2HEvent_Header *pc2h_evt_hdr;
12777 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12778 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12780 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12781 if (pcmd_obj == NULL)
12784 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
12785 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12786 if (pevtcmd == NULL) {
12787 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12791 _rtw_init_listhead(&pcmd_obj->list);
12793 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
12794 pcmd_obj->cmdsz = cmdsz;
12795 pcmd_obj->parmbuf = pevtcmd;
12797 pcmd_obj->rsp = NULL;
12798 pcmd_obj->rspsz = 0;
12800 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
12801 pc2h_evt_hdr->len = sizeof(struct stadel_event);
12802 pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
12803 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12805 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
12806 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12807 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12810 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12812 mac_id = (int)psta->mac_id;
12816 pdel_sta_evt->mac_id = mac_id;
12818 DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
12820 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12825 void clnt_sa_query_timeout(_adapter *padapter)
12828 rtw_disassoc_cmd(padapter, 0, _TRUE);
12829 rtw_indicate_disconnect(padapter);
12830 rtw_free_assoc_resources(padapter, 1);
12832 DBG_871X("SA query timeout client disconnect\n");
12835 void sa_query_timer_hdl(struct sta_info *psta)
12837 _adapter *padapter = psta->padapter;
12839 struct sta_priv *pstapriv = &padapter->stapriv;
12840 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12842 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
12843 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12844 clnt_sa_query_timeout(padapter);
12845 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
12846 report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID);
12849 #endif //CONFIG_IEEE80211W
12851 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
12853 return H2C_SUCCESS;
12856 #ifdef CONFIG_AUTO_AP_MODE
12857 void rtw_start_auto_ap(_adapter *adapter)
12859 DBG_871X("%s\n", __FUNCTION__);
12861 rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
12863 rtw_setopmode_cmd(adapter, Ndis802_11APMode,_TRUE);
12866 static int rtw_auto_ap_start_beacon(_adapter *adapter)
12871 u8 supportRate[16];
12872 int sz = 0, rateLen;
12874 u8 wireless_mode, oper_channel;
12875 u8 ssid[3] = {0}; //hidden ssid
12876 u32 ssid_len = sizeof(ssid);
12877 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
12880 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
12885 pbuf = rtw_zmalloc(len);
12893 //timestamp will be inserted by hardware
12897 //beacon interval : 2bytes
12898 *(u16*)ie = cpu_to_le16((u16)100);//BCN_INTERVAL=100;
12904 *(u16*)ie |= cpu_to_le16(cap_ESS);
12905 *(u16*)ie |= cpu_to_le16(cap_ShortPremble);
12906 //*(u16*)ie |= cpu_to_le16(cap_Privacy);
12911 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
12914 wireless_mode = WIRELESS_11BG_24N;
12915 rtw_set_supported_rate(supportRate, wireless_mode) ;
12916 rateLen = rtw_get_rateset_len(supportRate);
12919 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
12923 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
12928 if(check_buddy_fwstate(adapter, _FW_LINKED) &&
12929 check_buddy_fwstate(adapter, WIFI_STATION_STATE))
12931 PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
12932 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
12934 oper_channel = pbuddy_mlmeext->cur_channel;
12938 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
12940 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
12942 //ext supported rates
12945 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
12948 DBG_871X("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
12950 //lunch ap mode & start to issue beacon
12951 if(rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS)
12961 rtw_mfree(pbuf, len);
12966 #endif//CONFIG_AUTO_AP_MODE
12968 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
12971 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12972 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12973 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
12975 if(psetop->mode == Ndis802_11APMode)
12977 pmlmeinfo->state = WIFI_FW_AP_STATE;
12978 type = _HW_STATE_AP_;
12979 #ifdef CONFIG_NATIVEAP_MLME
12980 //start_ap_mode(padapter);
12983 else if(psetop->mode == Ndis802_11Infrastructure)
12985 pmlmeinfo->state &= ~(BIT(0)|BIT(1));// clear state
12986 pmlmeinfo->state |= WIFI_FW_STATION_STATE;//set to STATION_STATE
12987 type = _HW_STATE_STATION_;
12989 else if(psetop->mode == Ndis802_11IBSS)
12991 type = _HW_STATE_ADHOC_;
12992 } else if (psetop->mode == Ndis802_11Monitor) {
12993 type = _HW_STATE_MONITOR_;
12997 type = _HW_STATE_NOLINK_;
13000 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
13001 //Set_NETYPE0_MSR(padapter, type);
13004 #ifdef CONFIG_AUTO_AP_MODE
13005 if(psetop->mode == Ndis802_11APMode)
13006 rtw_auto_ap_start_beacon(padapter);
13009 if (rtw_port_switch_chk(padapter) == _TRUE)
13011 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
13013 if(psetop->mode == Ndis802_11APMode)
13014 adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; //ap mode won't dowload rsvd pages
13015 else if (psetop->mode == Ndis802_11Infrastructure) {
13017 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
13019 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
13024 #ifdef CONFIG_BT_COEXIST
13025 if (psetop->mode == Ndis802_11APMode)
13027 // Do this after port switch to
13028 // prevent from downloading rsvd page to wrong port
13029 rtw_btcoex_MediaStatusNotify(padapter, 1); //connect
13031 #endif // CONFIG_BT_COEXIST
13033 return H2C_SUCCESS;
13037 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
13039 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13040 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13041 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13042 WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network;
13043 struct createbss_parm *parm = (struct createbss_parm *)pbuf;
13044 u8 ret = H2C_SUCCESS;
13047 #ifdef CONFIG_AP_MODE
13048 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
13049 start_bss_network(padapter, parm);
13054 /* below is for ad-hoc master */
13056 rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
13057 rtw_joinbss_reset(padapter);
13059 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13060 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13061 pmlmeinfo->ERP_enable = 0;
13062 pmlmeinfo->WMM_enable = 0;
13063 pmlmeinfo->HT_enable = 0;
13064 pmlmeinfo->HT_caps_enable = 0;
13065 pmlmeinfo->HT_info_enable = 0;
13066 pmlmeinfo->agg_enable_bitmap = 0;
13067 pmlmeinfo->candidate_tid_bitmap = 0;
13069 //config the initial gain under linking, need to write the BB registers
13070 //initialgain = 0x1E;
13071 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13073 //disable dynamic functions, such as high power, DIG
13074 rtw_phydm_ability_backup(padapter);
13075 rtw_phydm_func_disable_all(padapter);
13077 //cancel link timer
13078 _cancel_timer_ex(&pmlmeext->link_timer);
13081 flush_all_cam_entry(padapter);
13083 pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
13084 _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13085 pnetwork->IELength = pdev_network->IELength;
13087 if (pnetwork->IELength > MAX_IE_SZ) {
13088 ret = H2C_PARAMETERS_ERROR;
13089 goto ibss_post_hdl;
13092 _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
13093 start_create_ibss(padapter);
13096 ret = H2C_PARAMETERS_ERROR;
13100 rtw_create_ibss_post_hdl(padapter, ret);
13106 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13109 PNDIS_802_11_VARIABLE_IEs pIE;
13110 struct registry_priv *pregpriv = &padapter->registrypriv;
13111 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13112 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13113 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13114 #ifdef CONFIG_ANTENNA_DIVERSITY
13115 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
13116 #endif //CONFIG_ANTENNA_DIVERSITY
13120 u8 u_ch, u_bw, u_offset;
13123 //check already connecting to AP or not
13124 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
13126 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13128 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13130 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13133 flush_all_cam_entry(padapter);
13135 _cancel_timer_ex(&pmlmeext->link_timer);
13137 //set MSR to nolink -> infra. mode
13138 //Set_MSR(padapter, _HW_STATE_NOLINK_);
13139 Set_MSR(padapter, _HW_STATE_STATION_);
13142 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13145 #ifdef CONFIG_ANTENNA_DIVERSITY
13146 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13149 #ifdef CONFIG_WAPI_SUPPORT
13150 rtw_wapi_clear_all_cam_entry(padapter);
13153 rtw_joinbss_reset(padapter);
13155 pmlmeinfo->ERP_enable = 0;
13156 pmlmeinfo->WMM_enable = 0;
13157 pmlmeinfo->HT_enable = 0;
13158 pmlmeinfo->HT_caps_enable = 0;
13159 pmlmeinfo->HT_info_enable = 0;
13160 pmlmeinfo->agg_enable_bitmap = 0;
13161 pmlmeinfo->candidate_tid_bitmap = 0;
13162 pmlmeinfo->bwmode_updated = _FALSE;
13163 //pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX;
13164 pmlmeinfo->VHT_enable = 0;
13166 _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13167 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13169 if(pnetwork->IELength>MAX_IE_SZ)//Check pbuf->IELength
13170 return H2C_PARAMETERS_ERROR;
13172 if (pnetwork->IELength < 2) {
13173 report_join_res(padapter, (-4));
13174 return H2C_SUCCESS;
13176 _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
13178 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13180 //Check AP vendor to move rtw_joinbss_cmd()
13181 //pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
13183 //sizeof(NDIS_802_11_FIXED_IEs)
13184 for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13185 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13187 switch (pIE->ElementID)
13189 case _VENDOR_SPECIFIC_IE_://Get WMM IE.
13190 if ( _rtw_memcmp(pIE->data, WMM_OUI, 4) )
13192 WMM_param_handler(padapter, pIE);
13196 #ifdef CONFIG_80211N_HT
13197 case _HT_CAPABILITY_IE_: //Get HT Cap IE.
13198 pmlmeinfo->HT_caps_enable = 1;
13201 case _HT_EXTRA_INFO_IE_: //Get HT Info IE.
13202 pmlmeinfo->HT_info_enable = 1;
13204 #endif /* CONFIG_80211N_HT */
13206 #ifdef CONFIG_80211AC_VHT
13207 case EID_VHTCapability://Get VHT Cap IE.
13208 pmlmeinfo->VHT_enable = 1;
13211 case EID_VHTOperation://Get VHT Operation IE.
13213 #endif /* CONFIG_80211AC_VHT */
13218 i += (pIE->Length + 2);
13221 rtw_bss_get_chbw(pnetwork
13222 , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13224 rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13227 if (padapter->registrypriv.wifi_spec) {
13228 // for WiFi test, follow WMM test plan spec
13229 acparm = 0x002F431C; // VO
13230 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13231 acparm = 0x005E541C; // VI
13232 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13233 acparm = 0x0000A525; // BE
13234 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13235 acparm = 0x0000A549; // BK
13236 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13238 // for WiFi test, mixed mode with intel STA under bg mode throughput issue
13239 if (padapter->mlmepriv.htpriv.ht_option == _FALSE){
13240 acparm = 0x00004320;
13241 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13245 acparm = 0x002F3217; // VO
13246 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13247 acparm = 0x005E4317; // VI
13248 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13249 acparm = 0x00105320; // BE
13250 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13251 acparm = 0x0000A444; // BK
13252 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13256 /* check channel, bandwidth, offset and switch */
13257 if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
13258 report_join_res(padapter, (-4));
13259 return H2C_SUCCESS;
13262 //disable dynamic functions, such as high power, DIG
13263 /*rtw_phydm_func_disable_all(padapter);*/
13265 //config the initial gain under linking, need to write the BB registers
13266 //initialgain = 0x1E;
13267 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13269 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
13271 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13273 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13275 set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
13278 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13280 //cancel link timer
13281 _cancel_timer_ex(&pmlmeext->link_timer);
13283 start_clnt_join(padapter);
13285 return H2C_SUCCESS;
13289 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
13291 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
13292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13293 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13294 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
13297 if (is_client_associated_to_ap(padapter))
13300 if(padapter->mlmepriv.handle_dfs == _FALSE)
13301 #endif //CONFIG_DFS
13302 #ifdef CONFIG_PLATFORM_ROCKCHIPS
13303 //To avoid connecting to AP fail during resume process, change retry count from 5 to 1
13304 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13306 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
13307 #endif //CONFIG_PLATFORM_ROCKCHIPS
13311 if( padapter->mlmepriv.handle_dfs == _TRUE )
13312 padapter->mlmepriv.handle_dfs = _FALSE;
13313 #endif //CONFIG_DFS
13315 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
13319 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13322 rtw_mlmeext_disconnect(padapter);
13324 rtw_free_uc_swdec_pending_queue(padapter);
13326 return H2C_SUCCESS;
13329 static const char * const _scan_state_str[] = {
13332 "SCAN_PS_ANNC_WAIT",
13339 "SCAN_SW_ANTDIV_BL",
13340 "SCAN_TO_P2P_LISTEN",
13346 const char *scan_state_str(u8 state)
13348 state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
13349 return _scan_state_str[state];
13352 static bool scan_abort_hdl(_adapter *adapter)
13354 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13355 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13356 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13358 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13362 if (pmlmeext->scan_abort == _TRUE) {
13364 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
13365 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
13366 ss->channel_idx = 3;
13367 DBG_871X("%s idx:%d, cnt:%u\n", __FUNCTION__
13369 , pwdinfo->find_phase_state_exchange_cnt
13374 ss->channel_idx = ss->ch_num;
13375 DBG_871X("%s idx:%d\n", __FUNCTION__
13379 pmlmeext->scan_abort = _FALSE;
13386 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13388 /* interval larger than this is treated as backgroud scan */
13389 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13390 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13393 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13394 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13396 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13397 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13400 #define SCAN_SPARSE_CH_NUM_INVALID 255
13402 static u8 token = 255;
13404 bool busy_traffic = _FALSE;
13405 bool miracast_enabled = _FALSE;
13406 bool bg_scan = _FALSE;
13407 u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13408 u8 scan_division_num;
13409 u8 ret_num = ch_num;
13410 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13411 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13413 if (regsty->wifi_spec)
13416 /* assume ch_num > 6 is normal scan */
13420 if (mlmeext->last_scan_time == 0)
13421 mlmeext->last_scan_time = rtw_get_current_time();
13423 interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13425 if (adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE
13426 #ifdef CONFIG_CONCURRENT_MODE
13427 || (adapter->pbuddy_adapter && adapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE)
13430 busy_traffic = _TRUE;
13432 if (is_miracast_enabled(adapter)
13433 #ifdef CONFIG_CONCURRENT_MODE
13434 || (adapter->pbuddy_adapter && is_miracast_enabled(adapter->pbuddy_adapter))
13437 miracast_enabled = _TRUE;
13439 if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13442 /* max_allow_ch by conditions*/
13444 #if RTW_SCAN_SPARSE_MIRACAST
13445 if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13446 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13449 #if RTW_SCAN_SPARSE_BG
13450 if (bg_scan == _TRUE)
13451 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13455 if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13459 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch)?1:0);
13460 token = (token + 1) % scan_division_num;
13463 DBG_871X("scan_division_num:%u, token:%u\n", scan_division_num, token);
13465 for (i = 0; i < ch_num; i++) {
13466 if (ch[i].hw_value && (i % scan_division_num) == token
13469 _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13474 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13477 mlmeext->last_scan_time = rtw_get_current_time();
13484 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13485 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13488 int scan_ch_num = 0;
13490 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13493 _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
13495 /* acquire channels from in */
13497 for (i=0;i<in_num;i++) {
13500 DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13502 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
13503 && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
13504 && rtw_mlme_band_check(padapter, in[i].hw_value) == _TRUE
13507 if (j >= out_num) {
13508 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13509 FUNC_ADPT_ARG(padapter), out_num);
13513 _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13515 if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13516 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13524 /* if out is empty, use channel_set as default */
13526 for (i=0;i<pmlmeext->max_chan_nums;i++) {
13529 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum);
13531 if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum) == _TRUE) {
13533 if (j >= out_num) {
13534 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n",
13535 FUNC_ADPT_ARG(padapter), out_num);
13539 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
13541 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
13542 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13550 j = rtw_scan_sparse(padapter, out, j);
13555 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
13557 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
13561 ss->channel_idx = 0;
13562 #ifdef CONFIG_SCAN_BACKOP
13565 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
13566 ss->is_sw_antdiv_bl_scan = 0;
13569 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13570 if (parm->ssid[i].SsidLength) {
13571 _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
13572 ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
13574 ss->ssid[i].SsidLength = 0;
13578 ss->ch_num = rtw_scan_ch_decision(adapter
13579 , ss->ch, RTW_CHANNEL_SCAN_AMOUNT
13580 , parm->ch, parm->ch_num
13583 ss->scan_mode = parm->scan_mode;
13586 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
13590 RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
13591 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13592 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
13593 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13596 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13599 /* handle scan abort request */
13600 scan_abort_hdl(padapter);
13603 if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
13604 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
13605 scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
13607 scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
13608 scan_type = SCAN_ACTIVE;
13609 } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
13611 * Commented by Albert 2011/06/03
13612 * The driver is in the find phase, it should go through the social channel.
13616 scan_ch = pwdinfo->social_chan[ss->channel_idx];
13617 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch);
13618 if (ch_set_idx >= 0)
13619 scan_type = pmlmeext->channel_set[ch_set_idx].ScanType;
13621 scan_type = SCAN_ACTIVE;
13623 #endif /* CONFIG_P2P */
13625 struct rtw_ieee80211_channel *ch;
13627 if (ss->channel_idx < ss->ch_num) {
13628 ch = &ss->ch[ss->channel_idx];
13629 scan_ch = ch->hw_value;
13630 scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
13634 if (scan_ch != 0) {
13635 next_state = SCAN_PROCESS;
13636 #ifdef CONFIG_SCAN_BACKOP
13642 u8 backop_flags = 0;
13644 rtw_dev_iface_status(padapter, &sta_num, &ld_sta_num, NULL, &ap_num, &ld_ap_num);
13646 if ((ld_sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN))
13647 || (sta_num > 0 && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL))
13649 backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext);
13652 if ((ld_ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN))
13653 || (ap_num > 0 && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL))
13655 backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext);
13658 if (backop_flags) {
13659 if (ss->scan_cnt < ss->scan_cnt_max) {
13662 mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
13663 next_state = SCAN_BACKING_OP;
13667 #endif /* CONFIG_SCAN_BACKOP */
13668 } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
13669 /* go p2p listen */
13670 next_state = SCAN_TO_P2P_LISTEN;
13672 #ifdef CONFIG_ANTENNA_DIVERSITY
13673 } else if (rtw_hal_antdiv_before_linked(padapter)) {
13674 /* go sw antdiv before link */
13675 next_state = SCAN_SW_ANTDIV_BL;
13678 next_state = SCAN_COMPLETE;
13680 #if defined(DBG_SCAN_SW_ANTDIV_BL)
13682 /* for SCAN_SW_ANTDIV_BL state testing */
13683 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13685 bool is_linked = _FALSE;
13687 for (i = 0; i < dvobj->iface_nums; i++) {
13688 if (rtw_linked_check(dvobj->padapters[i]))
13693 static bool fake_sw_antdiv_bl_state = 0;
13695 if (fake_sw_antdiv_bl_state == 0) {
13696 next_state = SCAN_SW_ANTDIV_BL;
13697 fake_sw_antdiv_bl_state = 1;
13699 fake_sw_antdiv_bl_state = 0;
13703 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
13706 #ifdef CONFIG_SCAN_BACKOP
13707 if (next_state != SCAN_PROCESS)
13712 #ifdef DBG_FIXED_CHAN
13713 if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
13714 scan_ch = pmlmeext->fixed_chan;
13725 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
13727 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13728 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13731 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
13734 if (survey_channel != 0) {
13735 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
13737 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13738 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
13739 ACS_OP acs_op = ACS_RESET;
13741 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
13742 rtw_set_acs_channel(padapter, survey_channel);
13743 #ifdef DBG_AUTO_CHNL_SEL_NHM
13744 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n",
13745 ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
13750 if (ScanType == SCAN_ACTIVE) {
13752 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
13753 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
13755 issue_probereq_p2p(padapter, NULL);
13756 issue_probereq_p2p(padapter, NULL);
13757 issue_probereq_p2p(padapter, NULL);
13759 #endif /* CONFIG_P2P */
13763 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13764 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
13765 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13766 if (padapter->registrypriv.wifi_spec)
13767 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13769 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
13770 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13774 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
13775 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13776 if (padapter->registrypriv.wifi_spec)
13777 issue_probereq(padapter, NULL, NULL);
13779 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
13780 issue_probereq(padapter, NULL, NULL);
13785 /* channel number is 0 or this channel is not valid. */
13792 void survey_done_set_ch_bw(_adapter *padapter)
13794 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13795 u8 cur_channel = 0;
13799 if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
13801 DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
13802 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13805 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13809 for (i = 0; i < dvobj->iface_nums; i++) {
13810 iface = dvobj->padapters[i];
13814 #ifdef CONFIG_IOCTL_CFG80211
13815 if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
13819 if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
13820 cur_channel = iface->wdinfo.listen_channel;
13821 cur_bwmode = CHANNEL_WIDTH_20;
13822 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13824 DBG_871X(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
13825 FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
13829 #endif /* CONFIG_P2P */
13831 if (cur_channel == 0) {
13832 cur_channel = pmlmeext->cur_channel;
13833 cur_bwmode = pmlmeext->cur_bwmode;
13834 cur_ch_offset = pmlmeext->cur_ch_offset;
13836 DBG_871X(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
13837 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
13841 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
13845 * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
13846 * @dvobj: the dvobj to check
13847 * @ps: power saving or not
13849 * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
13851 u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps)
13857 for (i = 0; i < dvobj->iface_nums; i++) {
13858 adapter = dvobj->padapters[i];
13863 if (is_client_associated_to_ap(adapter) == _TRUE) {
13864 /* TODO: TDLS peers */
13865 issue_nulldata(adapter, NULL, 1, 3, 500);
13869 if (is_client_associated_to_ap(adapter) == _TRUE) {
13870 /* TODO: TDLS peers */
13871 issue_nulldata(adapter, NULL, 0, 3, 500);
13880 void sitesurvey_set_igi(_adapter *adapter, bool enter)
13884 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13889 #ifdef CONFIG_IOCTL_CFG80211
13890 if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211)
13893 #endif /* CONFIG_IOCTL_CFG80211 */
13894 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
13897 #endif /* CONFIG_P2P */
13900 igi = 0xff; /* restore RX GAIN */
13903 rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
13906 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
13908 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
13909 struct dvobj_priv *dvobj = padapter->dvobj;
13910 struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
13911 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13912 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13913 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13917 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13920 #ifdef DBG_CHECK_FW_PS_STATE
13921 if (rtw_fw_ps_state(padapter) == _FAIL) {
13922 DBG_871X("scan without leave 32k\n");
13923 pdbgpriv->dbg_scan_pwr_state_cnt++;
13925 #endif /* DBG_CHECK_FW_PS_STATE */
13927 /* increase channel idx */
13928 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
13931 /* update scan state to next state (assigned by previous cmd hdl) */
13932 if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
13933 mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
13935 operation_by_state:
13936 switch (mlmeext_scan_state(pmlmeext)) {
13940 * SW parameter initialization
13943 sitesurvey_res_reset(padapter, pparm);
13944 mlmeext_set_scan_state(pmlmeext, SCAN_START);
13945 goto operation_by_state;
13949 * prepare to leave operating channel
13952 /* apply rx ampdu setting */
13953 if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
13954 || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID
13956 rtw_rx_ampdu_apply(padapter);
13959 /* clear HW TX queue before scan */
13960 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
13962 /* power save state announcement */
13963 if (sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)) {
13964 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
13965 mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
13966 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
13968 mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
13969 goto operation_by_state;
13976 * HW register and DM setting for enter scan
13979 /* config the initial gain under scanning */
13980 sitesurvey_set_igi(padapter, 1);
13982 /* disable dynamic functions, such as high power, DIG */
13983 rtw_phydm_ability_backup(padapter);
13984 rtw_phydm_func_for_offchannel(padapter);
13985 /* set MSR to no link state */
13986 Set_MSR(padapter, _HW_STATE_NOLINK_);
13987 val8 = 1; /* under site survey */
13988 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
13990 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
13991 goto operation_by_state;
13996 RT_SCAN_TYPE scan_type;
14000 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14001 if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) {
14002 ACS_OP acs_op = ACS_SELECT;
14004 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
14008 next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
14009 if (next_state != SCAN_PROCESS) {
14010 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14011 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
14012 rtw_set_acs_channel(padapter, 0);
14013 #ifdef DBG_AUTO_CHNL_SEL_NHM
14014 DBG_871X("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
14019 mlmeext_set_scan_state(pmlmeext, next_state);
14020 goto operation_by_state;
14023 /* still SCAN_PROCESS state */
14026 DBG_871X(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
14027 , FUNC_ADPT_ARG(padapter)
14028 , mlmeext_scan_state_str(pmlmeext)
14030 , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
14031 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14032 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14033 , ss->ssid[0].SsidLength?'S':' '
14036 DBG_871X(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n"
14037 , FUNC_ADPT_ARG(padapter)
14038 , mlmeext_scan_state_str(pmlmeext)
14041 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14042 , scan_type?'A':'P', ss->scan_mode?'A':'P'
14043 , ss->ssid[0].SsidLength?'S':' '
14045 #endif /* CONFIG_P2P */
14047 #ifdef DBG_FIXED_CHAN
14048 if (pmlmeext->fixed_chan != 0xff)
14049 DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
14052 site_survey(padapter, scan_ch, scan_type);
14054 #if defined(CONFIG_ATMEL_RC_PATCH)
14055 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
14060 scan_ms = ss->scan_ch_ms;
14063 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14064 if (ss->is_sw_antdiv_bl_scan)
14065 scan_ms = scan_ms/2;
14068 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14070 struct noise_info info;
14072 info.bPauseDIG = _FALSE;
14074 info.max_time = scan_ms/2;
14075 info.chan = scan_ch;
14076 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
14080 set_survey_timer(pmlmeext, scan_ms);
14084 #ifdef CONFIG_SCAN_BACKOP
14085 case SCAN_BACKING_OP:
14087 u8 back_ch, back_bw, back_ch_offset;
14089 if (rtw_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
14093 DBG_871X(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
14094 , FUNC_ADPT_ARG(padapter)
14095 , mlmeext_scan_state_str(pmlmeext)
14096 , back_ch, back_bw, back_ch_offset
14097 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14100 set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
14102 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14103 val8 = 0; /* survey done */
14104 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14106 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14107 sitesurvey_set_igi(padapter, 0);
14108 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14111 mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
14112 ss->backop_time = rtw_get_current_time();
14114 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME)) {
14118 for (i = 0; i < dvobj->iface_nums; i++) {
14119 if (!dvobj->padapters[i])
14122 rtw_os_xmit_schedule(dvobj->padapters[i]);
14126 goto operation_by_state;
14130 if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
14131 || pmlmeext->scan_abort
14133 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
14134 goto operation_by_state;
14136 set_survey_timer(pmlmeext, 50);
14139 case SCAN_LEAVING_OP:
14141 * prepare to leave operating channel
14144 /* clear HW TX queue before scan */
14145 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14147 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
14148 && sitesurvey_ps_annc(adapter_to_dvobj(padapter), 1)
14150 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14151 mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
14152 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14154 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
14155 goto operation_by_state;
14160 case SCAN_LEAVE_OP:
14162 * HW register and DM setting for enter scan
14165 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14166 /* config the initial gain under scanning */
14167 sitesurvey_set_igi(padapter, 1);
14170 /* set MSR to no link state */
14171 Set_MSR(padapter, _HW_STATE_NOLINK_);
14172 val8 = 1; //under site survey
14173 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14175 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14176 goto operation_by_state;
14178 #endif /* CONFIG_SCAN_BACKOP */
14180 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14181 case SCAN_SW_ANTDIV_BL:
14184 * For SW antenna diversity before link, it needs to switch to another antenna and scan again.
14185 * It compares the scan result and select better one to do connection.
14188 ss->channel_idx = 0;
14189 ss->is_sw_antdiv_bl_scan = 1;
14191 mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
14192 set_survey_timer(pmlmeext, ss->scan_ch_ms);
14197 case SCAN_TO_P2P_LISTEN:
14199 * Set the P2P State to the listen state of find phase
14200 * and set the current channel to the listen channel
14202 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14203 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
14205 /* turn on phy-dynamic functions */
14206 rtw_phydm_ability_restore(padapter);
14208 sitesurvey_set_igi(padapter, 0);
14210 mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
14211 _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
14214 case SCAN_P2P_LISTEN:
14215 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14216 ss->channel_idx = 0;
14217 goto operation_by_state;
14218 #endif /* CONFIG_P2P */
14220 case SCAN_COMPLETE:
14222 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14223 || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14225 #ifdef CONFIG_CONCURRENT_MODE
14226 if (pwdinfo->driver_interface == DRIVER_WEXT) {
14227 if (check_buddy_fwstate(padapter, _FW_LINKED))
14228 _set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
14230 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14232 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14235 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
14236 #endif /* CONFIG_P2P */
14238 /* switch channel */
14239 survey_done_set_ch_bw(padapter);
14242 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
14243 val8 = 0; /* survey done */
14244 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14246 /* turn on phy-dynamic functions */
14247 rtw_phydm_ability_restore(padapter);
14249 sitesurvey_set_igi(padapter, 0);
14251 sitesurvey_ps_annc(adapter_to_dvobj(padapter), 0);
14253 /* apply rx ampdu setting */
14254 rtw_rx_ampdu_apply(padapter);
14256 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
14258 report_surveydone_event(padapter);
14260 issue_action_BSSCoexistPacket(padapter);
14261 issue_action_BSSCoexistPacket(padapter);
14262 issue_action_BSSCoexistPacket(padapter);
14265 return H2C_SUCCESS;
14268 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
14270 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
14271 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14272 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14274 if (pparm->mode < 4)
14276 pmlmeinfo->auth_algo = pparm->mode;
14279 return H2C_SUCCESS;
14282 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
14286 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
14287 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14288 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14289 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14290 struct set_stakey_parm sta_pparm;
14291 struct security_priv *psecuritypriv = &padapter->securitypriv;
14295 //main tx key for wep.
14297 pmlmeinfo->key_index = pparm->keyid;
14299 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used);
14304 if (cam_id > 3) /* not default key, searched by A2 */
14305 addr = get_bssid(&padapter->mlmepriv);
14309 #ifdef DYNAMIC_CAMID_ALLOC
14310 /* cam entry searched is pairwise key */
14311 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
14314 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
14315 , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
14317 /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
14318 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14319 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14321 /* clear group key */
14322 while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
14323 DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
14324 clear_cam_entry(padapter, camid_clr);
14325 rtw_camid_free(padapter, camid_clr);
14332 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
14333 DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
14334 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
14335 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
14337 #ifdef DYNAMIC_CAMID_ALLOC
14338 if (cam_id >=0 && cam_id <=3)
14339 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8*)_TRUE);
14341 /* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
14342 if (_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC) && is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm)) {
14343 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
14345 sta_pparm.algorithm = pparm->algorithm;
14346 sta_pparm.keyid = pparm->keyid;
14347 _rtw_memcpy(sta_pparm.key, pparm->key, 16);
14348 _rtw_memcpy(sta_pparm.addr, get_bssid(pmlmepriv), ETH_ALEN);
14349 set_stakey_hdl(padapter, (u8 *) &sta_pparm);
14353 //allow multicast packets to driver
14354 rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
14356 return H2C_SUCCESS;
14359 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
14364 u8 ret = H2C_SUCCESS;
14365 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14366 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14367 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
14368 struct sta_priv *pstapriv = &padapter->stapriv;
14369 struct sta_info *psta;
14371 if(pparm->algorithm == _NO_PRIVACY_)
14374 psta = rtw_get_stainfo(pstapriv, pparm->addr);
14376 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
14377 ret = H2C_REJECTED;
14381 pmlmeinfo->enc_algo = pparm->algorithm;
14382 cam_id = rtw_camid_alloc(padapter, psta, 0, &used);
14386 #ifdef DYNAMIC_CAMID_ALLOC
14387 /* cam entry searched is group key */
14388 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
14391 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
14392 , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
14394 /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
14395 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14396 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14398 /* clear group key */
14399 while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
14400 DBG_871X_LEVEL(_drv_always_, "clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
14401 clear_cam_entry(padapter, camid_clr);
14402 rtw_camid_free(padapter, camid_clr);
14408 if(pparm->algorithm == _NO_PRIVACY_) {
14409 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
14410 DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
14411 clear_cam_entry(padapter, cam_id);
14412 rtw_camid_free(padapter,cam_id);
14415 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
14416 cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
14417 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
14418 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
14420 ret = H2C_SUCCESS_RSP;
14426 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
14428 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
14429 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14430 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14432 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
14435 return H2C_SUCCESS;
14437 #ifdef CONFIG_80211N_HT
14438 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
14439 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
14441 //pmlmeinfo->ADDBA_retry_count = 0;
14442 //pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);
14443 //psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid);
14444 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14445 //_set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO);
14446 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14449 else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
14450 (psta->htpriv.ht_option==_TRUE) &&
14451 (psta->htpriv.ampdu_enable==_TRUE) )
14453 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14454 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14459 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
14461 #endif //CONFIG_80211N_HT
14462 return H2C_SUCCESS;
14466 u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
14468 struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
14469 u8 ret = _TRUE, i = 0, try_cnt = 3, wait_ms = 50;
14470 struct recv_reorder_ctrl *preorder_ctrl;
14471 struct sta_priv *pstapriv = &padapter->stapriv;
14472 struct sta_info *psta;
14474 psta = rtw_get_stainfo(pstapriv, pparm->addr);
14478 preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
14479 ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
14481 #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
14482 /* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
14483 if (pparm->status == 0) {
14484 preorder_ctrl->indicate_seq = pparm->start_seq;
14486 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __func__, __LINE__,
14487 preorder_ctrl->indicate_seq, pparm->start_seq);
14491 preorder_ctrl->indicate_seq = 0xffff;
14495 * status = 0 means accept this addba req
14496 * status = 37 means reject this addba req
14498 if (pparm->status == 0) {
14499 preorder_ctrl->enable = _TRUE;
14500 preorder_ctrl->ampdu_size = pparm->size;
14501 } else if (pparm->status == 37)
14502 preorder_ctrl->enable = _FALSE;
14505 return H2C_SUCCESS;
14508 u8 chk_bmc_sleepq_cmd(_adapter* padapter)
14510 struct cmd_obj *ph2c;
14511 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14516 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14522 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
14524 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14533 u8 set_tx_beacon_cmd(_adapter* padapter)
14535 struct cmd_obj *ph2c;
14536 struct Tx_Beacon_param *ptxBeacon_parm;
14537 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14538 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14539 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14545 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
14551 if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
14553 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
14558 _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
14560 len_diff = update_hidden_ssid(
14561 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
14562 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
14563 , pmlmeinfo->hidden_ssid_mode
14565 ptxBeacon_parm->network.IELength += len_diff;
14567 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
14569 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14580 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
14582 u8 evt_code, evt_seq;
14585 void (*event_callback)(_adapter *dev, u8 *pbuf);
14586 struct evt_priv *pevt_priv = &(padapter->evtpriv);
14589 goto _abort_event_;
14591 peventbuf = (uint*)pbuf;
14592 evt_sz = (u16)(*peventbuf&0xffff);
14593 evt_seq = (u8)((*peventbuf>>24)&0x7f);
14594 evt_code = (u8)((*peventbuf>>16)&0xff);
14597 #ifdef CHECK_EVENT_SEQ
14598 // checking event sequence...
14599 if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
14601 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)));
14603 pevt_priv->event_seq = (evt_seq+1)&0x7f;
14605 goto _abort_event_;
14609 // checking if event code is valid
14610 if (evt_code >= MAX_C2HEVT)
14612 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
14613 goto _abort_event_;
14616 // checking if event size match the event parm size
14617 if ((wlanevents[evt_code].parmsize != 0) &&
14618 (wlanevents[evt_code].parmsize != evt_sz))
14621 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
14622 evt_code, wlanevents[evt_code].parmsize, evt_sz));
14623 goto _abort_event_;
14627 ATOMIC_INC(&pevt_priv->event_seq);
14633 event_callback = wlanevents[evt_code].event_callback;
14634 event_callback(padapter, (u8*)peventbuf);
14636 pevt_priv->evt_done_cnt++;
14643 return H2C_SUCCESS;
14647 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
14650 return H2C_PARAMETERS_ERROR;
14652 return H2C_SUCCESS;
14655 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
14657 #ifdef CONFIG_AP_MODE
14659 struct sta_info *psta_bmc;
14660 _list *xmitframe_plist, *xmitframe_phead;
14661 struct xmit_frame *pxmitframe=NULL;
14662 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
14663 struct sta_priv *pstapriv = &padapter->stapriv;
14666 psta_bmc = rtw_get_bcmc_stainfo(padapter);
14668 return H2C_SUCCESS;
14670 if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
14672 #ifndef CONFIG_PCI_HCI
14673 rtw_msleep_os(10);// 10ms, ATIM(HIQ) Windows
14675 //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14676 _enter_critical_bh(&pxmitpriv->lock, &irqL);
14678 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
14679 xmitframe_plist = get_next(xmitframe_phead);
14681 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
14683 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
14685 xmitframe_plist = get_next(xmitframe_plist);
14687 rtw_list_delete(&pxmitframe->list);
14689 psta_bmc->sleepq_len--;
14690 if(psta_bmc->sleepq_len>0)
14691 pxmitframe->attrib.mdata = 1;
14693 pxmitframe->attrib.mdata = 0;
14695 pxmitframe->attrib.triggered=1;
14697 if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
14698 pxmitframe->attrib.qsel = QSLT_HIGH;//HIQ
14701 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14702 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
14704 rtw_os_xmit_complete(padapter, pxmitframe);
14706 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14708 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
14711 //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
14712 _exit_critical_bh(&pxmitpriv->lock, &irqL);
14714 if (rtw_get_intf_type(padapter) != RTW_PCIE) {
14715 /* check hi queue and bmc_sleepq */
14716 rtw_chk_hi_queue_cmd(padapter);
14721 return H2C_SUCCESS;
14724 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
14726 if(send_beacon(padapter)==_FAIL)
14728 DBG_871X("issue_beacon, fail!\n");
14729 return H2C_PARAMETERS_ERROR;
14733 if (padapter->registrypriv.wifi_spec == 1)
14734 return H2C_SUCCESS;
14736 /* tx bc/mc frames after update TIM */
14737 chk_bmc_sleepq_hdl(padapter, NULL);
14739 return H2C_SUCCESS;
14743 * according to channel
14744 * add/remove WLAN_BSSID_EX.IEs's ERP ie
14745 * set WLAN_BSSID_EX.SupportedRates
14746 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
14748 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
14750 u8 network_type,rate_len, total_rate_len,remainder_rate_len;
14751 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
14752 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14756 network_type = WIRELESS_11A;
14757 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
14758 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
14760 network_type = WIRELESS_11BG;
14761 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
14762 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
14765 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
14767 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
14769 if(total_rate_len > 8)
14772 remainder_rate_len = total_rate_len - 8;
14776 rate_len = total_rate_len;
14777 remainder_rate_len = 0;
14780 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
14782 if(remainder_rate_len)
14784 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
14788 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
14791 pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
14794 #ifdef CONFIG_CONCURRENT_MODE
14795 sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
14797 PADAPTER pbuddy_adapter;
14798 struct mlme_ext_priv *pbuddy_mlmeext;
14799 struct mlme_ext_info *pbuddy_mlmeinfo;
14801 if(padapter == NULL)
14804 pbuddy_adapter = padapter->pbuddy_adapter;
14806 if(pbuddy_adapter == NULL)
14810 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
14811 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
14813 if((pbuddy_mlmeinfo->state&0x03) == state)
14819 #endif /* CONFIG_CONCURRENT_MODE */
14821 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
14823 #define DUMP_ADAPTERS_STATUS 0
14825 struct dvobj_priv *dvobj;
14827 struct mlme_priv *mlme;
14828 struct mlme_ext_priv *mlmeext;
14829 u8 u_ch, u_offset, u_bw;
14832 dvobj = adapter_to_dvobj(adapter);
14834 if (DUMP_ADAPTERS_STATUS) {
14835 DBG_871X(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
14836 dump_adapters_status(RTW_DBGDUMP , dvobj);
14839 if (join_res >= 0) {
14840 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14841 dump_adapters_status(RTW_DBGDUMP , dvobj);
14845 for (i = 0; i < dvobj->iface_nums; i++) {
14846 iface = dvobj->padapters[i];
14847 mlme = &iface->mlmepriv;
14848 mlmeext = &iface->mlmeextpriv;
14850 if (!iface || iface == adapter)
14853 if (check_fwstate(mlme, WIFI_AP_STATE)
14854 && check_fwstate(mlme, WIFI_ASOC_STATE)
14856 bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
14857 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14859 if (is_grouped == _FALSE) {
14860 /* handle AP which need to switch ch setting */
14862 /* restore original bw, adjust bw by registry setting on target ch */
14863 mlmeext->cur_bwmode = mlme->ori_bw;
14864 mlmeext->cur_channel = u_ch;
14865 rtw_adjust_chbw(iface
14866 , mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
14868 rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
14869 , &u_ch, &u_bw, &u_offset);
14871 rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
14872 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
14874 _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
14876 rtw_start_bss_hdl_after_chbw_decided(iface);
14879 update_beacon(iface, 0, NULL, _TRUE);
14882 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14885 #ifdef CONFIG_DFS_MASTER
14886 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED);
14889 for (i = 0; i < dvobj->iface_nums; i++) {
14890 iface = dvobj->padapters[i];
14891 mlme = &iface->mlmepriv;
14892 mlmeext = &iface->mlmeextpriv;
14894 if (!iface || iface == adapter)
14897 if (check_fwstate(mlme, WIFI_AP_STATE)
14898 && check_fwstate(mlme, WIFI_ASOC_STATE))
14899 update_beacon(iface, 0, NULL, _TRUE);
14901 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
14903 #ifdef CONFIG_DFS_MASTER
14904 rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED);
14908 if (rtw_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
14909 set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
14911 if (DUMP_ADAPTERS_STATUS) {
14912 DBG_871X(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
14913 dump_adapters_status(RTW_DBGDUMP , dvobj);
14917 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
14919 bool chbw_allow = _TRUE;
14920 bool connect_allow = _TRUE;
14921 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14922 u8 cur_ch, cur_bw, cur_ch_offset;
14923 u8 u_ch, u_offset, u_bw;
14925 u_ch = cur_ch = pmlmeext->cur_channel;
14926 u_bw = cur_bw = pmlmeext->cur_bwmode;
14927 u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
14929 if (!ch || !bw || !offset) {
14930 connect_allow = _FALSE;
14936 connect_allow = _FALSE;
14937 DBG_871X_LEVEL(_drv_err_, FUNC_ADPT_FMT" cur_ch:%u\n"
14938 , FUNC_ADPT_ARG(adapter), cur_ch);
14942 DBG_871X(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14944 #ifdef CONFIG_CONCURRENT_MODE
14946 struct dvobj_priv *dvobj;
14948 struct mlme_priv *mlme;
14949 struct mlme_ext_priv *mlmeext;
14957 dvobj = adapter_to_dvobj(adapter);
14959 rtw_dev_iface_status_no_self(adapter, &sta_num, &ld_sta_num, &lg_sta_num, &ap_num, &ld_ap_num);
14960 DBG_871X(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n"
14961 , FUNC_ADPT_ARG(adapter), ld_sta_num, ap_num);
14963 if (!ld_sta_num && !ap_num) {
14964 /* consider linking STA? */
14965 goto connect_allow_hdl;
14968 if (rtw_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
14969 dump_adapters_status(RTW_DBGDUMP , dvobj);
14972 DBG_871X(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
14973 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
14976 chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
14977 , u_ch, u_bw, u_offset);
14979 DBG_871X(FUNC_ADPT_FMT" chbw_allow:%d\n"
14980 , FUNC_ADPT_ARG(adapter), chbw_allow);
14982 if (chbw_allow == _TRUE) {
14983 rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
14984 rtw_warn_on(cur_ch != pmlmeext->cur_channel);
14985 rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
14986 rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
14987 goto connect_allow_hdl;
14990 /* chbw_allow is _FALSE, connect allow? */
14991 for (i = 0; i < dvobj->iface_nums; i++) {
14992 iface = dvobj->padapters[i];
14993 mlme = &iface->mlmepriv;
14994 mlmeext = &iface->mlmeextpriv;
14996 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
14997 if (check_fwstate(mlme, WIFI_STATION_STATE)
14998 && check_fwstate(mlme, WIFI_ASOC_STATE)
14999 #if defined(CONFIG_P2P)
15000 && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
15003 connect_allow = _FALSE;
15006 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
15008 DBG_871X(FUNC_ADPT_FMT" connect_allow:%d\n"
15009 , FUNC_ADPT_ARG(adapter), connect_allow);
15011 if (connect_allow == _FALSE)
15015 /* connect_allow == _TRUE */
15017 #ifdef CONFIG_DFS_MASTER
15018 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING);
15021 if (chbw_allow == _FALSE) {
15024 u_offset = cur_ch_offset;
15026 for (i = 0; i < dvobj->iface_nums; i++) {
15027 iface = dvobj->padapters[i];
15028 mlme = &iface->mlmepriv;
15029 mlmeext = &iface->mlmeextpriv;
15031 if (!iface || iface == adapter)
15034 if (check_fwstate(mlme, WIFI_AP_STATE)
15035 && check_fwstate(mlme, WIFI_ASOC_STATE)
15037 #ifdef CONFIG_SPCT_CH_SWITCH
15039 rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
15042 rtw_sta_flush(iface, _FALSE);
15044 rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
15045 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15046 } else if (check_fwstate(mlme, WIFI_STATION_STATE)
15047 && check_fwstate(mlme, WIFI_ASOC_STATE)
15049 rtw_disassoc_cmd(iface, 500, _FALSE);
15050 rtw_indicate_disconnect(iface);
15051 rtw_free_assoc_resources(iface, 1);
15056 #endif /* CONFIG_CONCURRENT_MODE */
15060 if (connect_allow == _TRUE) {
15061 DBG_871X(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15064 *offset = u_offset;
15067 return connect_allow == _TRUE ? _SUCCESS : _FAIL;
15070 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
15071 int _rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
15073 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15075 struct mlme_ext_priv *mlmeext;
15078 u8 bw_ret = CHANNEL_WIDTH_20;
15079 u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15083 if (bw) *bw = CHANNEL_WIDTH_20;
15084 if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15086 for (i = 0; i<dvobj->iface_nums; i++) {
15087 iface = dvobj->padapters[i];
15088 mlmeext = &iface->mlmeextpriv;
15090 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
15093 if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
15096 if (include_self == _FALSE && adapter == iface)
15100 ch_ret = mlmeext->cur_channel;
15101 bw_ret = mlmeext->cur_bwmode;
15102 offset_ret = mlmeext->cur_ch_offset;
15107 if (ch_ret != mlmeext->cur_channel) {
15112 if (bw_ret < mlmeext->cur_bwmode) {
15113 bw_ret = mlmeext->cur_bwmode;
15114 offset_ret = mlmeext->cur_ch_offset;
15115 } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
15124 if (ch) *ch = ch_ret;
15125 if (bw) *bw = bw_ret;
15126 if (offset) *offset = offset_ret;
15132 inline int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15134 return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 1);
15137 inline int rtw_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15139 return _rtw_get_ch_setting_union(adapter, ch, bw, offset, 0);
15142 void _rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15143 , u8 *ap_num, u8 *ld_ap_num, bool include_self)
15145 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15147 struct mlme_ext_priv *mlmeext;
15148 struct mlme_ext_info *mlmeextinfo;
15150 u8 sta_num_ret = 0;
15151 u8 ld_sta_num_ret = 0;
15152 u8 lg_sta_num_ret = 0;
15154 u8 ld_ap_num_ret = 0;
15167 for (i = 0; i < dvobj->iface_nums; i++) {
15168 iface = dvobj->padapters[i];
15170 if (include_self == _FALSE && iface == adapter)
15173 mlmeext = &iface->mlmeextpriv;
15175 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
15177 if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
15179 if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
15183 if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
15184 && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
15187 if (iface->stapriv.asoc_sta_count > 2)
15193 *sta_num = sta_num_ret;
15195 *ld_sta_num = ld_sta_num_ret;
15197 *lg_sta_num = lg_sta_num_ret;
15199 *ap_num = ap_num_ret;
15201 *ld_ap_num = ld_ap_num_ret;
15204 inline void rtw_dev_iface_status(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15205 , u8 *ap_num, u8 *ld_ap_num)
15207 return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 1);
15210 inline void rtw_dev_iface_status_no_self(_adapter *adapter, u8 *sta_num, u8 *ld_sta_num, u8 *lg_sta_num
15211 , u8 *ap_num, u8 *ld_ap_num)
15213 return _rtw_dev_iface_status(adapter, sta_num, ld_sta_num, lg_sta_num, ap_num, ld_ap_num, 0);
15216 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
15218 struct set_ch_parm *set_ch_parm;
15219 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
15220 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15223 return H2C_PARAMETERS_ERROR;
15225 set_ch_parm = (struct set_ch_parm *)pbuf;
15227 DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
15228 FUNC_NDEV_ARG(padapter->pnetdev),
15229 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
15231 pmlmeext->cur_channel = set_ch_parm->ch;
15232 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
15233 pmlmeext->cur_bwmode = set_ch_parm->bw;
15235 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
15237 return H2C_SUCCESS;
15240 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
15242 struct SetChannelPlan_param *setChannelPlan_param;
15243 struct mlme_priv *mlme = &padapter->mlmepriv;
15244 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15247 return H2C_PARAMETERS_ERROR;
15249 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
15251 if(!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan)) {
15252 return H2C_PARAMETERS_ERROR;
15255 mlme->country_ent = setChannelPlan_param->country_ent;
15256 mlme->ChannelPlan = setChannelPlan_param->channel_plan;
15258 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
15259 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
15261 rtw_hal_set_odm_var(padapter,HAL_ODM_REGULATION,NULL,_TRUE);
15263 #ifdef CONFIG_IOCTL_CFG80211
15264 rtw_reg_notify_by_driver(padapter);
15265 #endif //CONFIG_IOCTL_CFG80211
15267 return H2C_SUCCESS;
15270 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
15272 struct LedBlink_param *ledBlink_param;
15275 return H2C_PARAMETERS_ERROR;
15277 ledBlink_param = (struct LedBlink_param *)pbuf;
15279 #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
15280 BlinkHandler((PLED_DATA)ledBlink_param->pLed);
15283 return H2C_SUCCESS;
15286 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
15289 struct SetChannelSwitch_param *setChannelSwitch_param;
15291 u8 gval8 = 0x00, sval8 = 0xff;
15294 return H2C_PARAMETERS_ERROR;
15296 setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
15297 new_ch_no = setChannelSwitch_param->new_ch_no;
15299 rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15301 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
15303 DBG_871X("DFS detected! Swiching channel to %d!\n", new_ch_no);
15304 SelectChannel(padapter, new_ch_no);
15306 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15308 rtw_disassoc_cmd(padapter, 0, _FALSE);
15309 rtw_indicate_disconnect(padapter);
15310 rtw_free_assoc_resources(padapter, 1);
15311 rtw_free_network_queue(padapter, _TRUE);
15313 if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
15314 DBG_871X("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
15317 return H2C_SUCCESS;
15319 return H2C_REJECTED;
15320 #endif //CONFIG_DFS
15324 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
15328 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15329 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
15330 #ifdef CONFIG_TDLS_CH_SW
15331 struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
15333 struct TDLSoption_param *TDLSoption;
15334 struct sta_info *ptdls_sta = NULL;
15335 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15336 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
15337 u8 survey_channel, i, min, option;
15338 struct tdls_txmgmt txmgmt;
15339 u32 setchtime, resp_sleep = 0, wait_time;
15340 u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15345 return H2C_PARAMETERS_ERROR;
15347 TDLSoption = (struct TDLSoption_param *)pbuf;
15348 option = TDLSoption->option;
15350 if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
15351 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
15352 if (ptdls_sta == NULL) {
15353 return H2C_REJECTED;
15356 if (!(option == TDLS_RS_RCR))
15357 return H2C_REJECTED;
15360 //_enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15361 //DBG_871X("[%s] option:%d\n", __FUNCTION__, option);
15364 case TDLS_ESTABLISHED:
15366 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
15367 /* So we can receive all kinds of data frames. */
15370 //leave ALL PS when TDLS is established
15371 rtw_pwr_wakeup(padapter);
15373 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
15374 DBG_871X("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
15376 /* Set TDLS sta rate. */
15377 /* Update station supportRate */
15378 rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
15379 if (pmlmeext->cur_channel > 14) {
15380 if (ptdls_sta->ra_mask & 0xffff000)
15381 sta_band |= WIRELESS_11_5N ;
15383 if (ptdls_sta->ra_mask & 0xff0)
15384 sta_band |= WIRELESS_11A;
15387 #ifdef CONFIG_80211AC_VHT
15388 if (ptdls_sta->vhtpriv.vht_option)
15389 sta_band = WIRELESS_11_5AC;
15393 if (ptdls_sta->ra_mask & 0xffff000)
15394 sta_band |= WIRELESS_11_24N;
15396 if (ptdls_sta->ra_mask & 0xff0)
15397 sta_band |= WIRELESS_11G;
15399 if (ptdls_sta->ra_mask & 0x0f)
15400 sta_band |= WIRELESS_11B;
15402 ptdls_sta->wireless_mode = sta_band;
15403 ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter,ptdls_sta);
15404 set_sta_rate(padapter, ptdls_sta);
15405 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
15407 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta,_TRUE);
15410 case TDLS_ISSUE_PTI:
15411 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
15412 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
15413 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
15415 #ifdef CONFIG_TDLS_CH_SW
15416 case TDLS_CH_SW_RESP:
15417 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15418 txmgmt.status_code = 0;
15419 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15421 issue_nulldata(padapter, NULL, 1, 3, 3);
15423 DBG_871X("[TDLS ] issue tdls channel switch response\n");
15424 ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
15426 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
15427 /* then we just SelectChannel to AP's channel*/
15428 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
15429 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
15433 if (ret == _SUCCESS)
15434 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_OFF_CHNL);
15436 DBG_871X("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
15439 case TDLS_CH_SW_PREPARE:
15440 pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
15442 /* to collect IQK info of off-chnl */
15444 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15445 set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
15447 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15449 /* switch back to base-chnl */
15450 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
15452 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
15454 pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
15457 case TDLS_CH_SW_START:
15458 rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
15460 case TDLS_CH_SW_TO_OFF_CHNL:
15461 issue_nulldata(padapter, NULL, 1, 3, 3);
15463 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15464 _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) /1000);
15466 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num,
15467 pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
15468 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15469 if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
15470 if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 1, 3) == _FAIL)
15471 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15477 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15478 _cancel_timer(&ptdls_sta->ch_sw_timer,&bcancelled);
15483 case TDLS_CH_SW_END:
15484 case TDLS_CH_SW_END_TO_BASE_CHNL:
15485 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15486 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
15487 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
15488 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
15490 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
15491 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
15494 if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
15495 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15498 case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
15499 case TDLS_CH_SW_TO_BASE_CHNL:
15500 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
15502 if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
15503 if (ptdls_sta != NULL) {
15504 /* Send unsolicited channel switch rsp. to peer */
15505 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15506 txmgmt.status_code = 0;
15507 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15508 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
15512 if (rtw_tdls_do_ch_sw(padapter, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel,
15513 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
15514 issue_nulldata(padapter, NULL, 0, 3, 3);
15515 /* set ch sw monitor timer for responder */
15516 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15517 _set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
15523 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
15524 DBG_871X("[TDLS] wirte REG_RCR, set bit6 on\n");
15526 case TDLS_TEAR_STA:
15527 #ifdef CONFIG_TDLS_CH_SW
15528 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
15529 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
15530 TDLS_CH_SWITCH_ON_STATE |
15531 TDLS_PEER_AT_OFF_STATE);
15532 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15533 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
15536 rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
15537 free_tdls_sta(padapter, ptdls_sta);
15541 //_exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
15543 return H2C_SUCCESS;
15545 return H2C_REJECTED;
15546 #endif /* CONFIG_TDLS */
15550 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
15552 struct RunInThread_param *p;
15556 return H2C_PARAMETERS_ERROR;
15557 p = (struct RunInThread_param*)pbuf;
15560 p->func(p->context);
15562 return H2C_SUCCESS;
15565 u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf)
15568 struct readMAC_parm *preadmacparm = NULL;
15574 return H2C_PARAMETERS_ERROR;
15576 preadmacparm = (struct readMAC_parm *) pbuf;
15577 sz = preadmacparm->len;
15578 addr = preadmacparm->addr;
15583 value = rtw_read8(padapter, addr);
15586 value = rtw_read16(padapter, addr);
15589 value = rtw_read32(padapter, addr);
15592 DBG_871X("%s: Unknown size\n", __func__);
15595 DBG_871X("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value);
15597 return H2C_SUCCESS;